summaryrefslogtreecommitdiff
path: root/engine/items/items.asm
diff options
context:
space:
mode:
Diffstat (limited to 'engine/items/items.asm')
-rwxr-xr-xengine/items/items.asm793
1 files changed, 459 insertions, 334 deletions
diff --git a/engine/items/items.asm b/engine/items/items.asm
index 96dd0a00..e3fe4655 100755
--- a/engine/items/items.asm
+++ b/engine/items/items.asm
@@ -101,240 +101,341 @@ ItemUsePtrTable: ; d307 (3:5307)
dw ItemUsePPRestore ; MAX_ELIXER
ItemUseBall: ; d3ad (3:53ad)
- ld a, [wIsInBattle]
+
+; Balls can't be used out of battle.
+ ld a,[wIsInBattle]
and a
- jp z, ItemUseNotTime ; not in battle
+ jp z,ItemUseNotTime
+
+; Balls can't catch trainers' Pokémon.
dec a
- jp nz, ThrowBallAtTrainerMon
- ld a, [wBattleType]
- cp $1
- jr z, .UseBall
- cp $4 ; pikachu battle?
- jr z, .UseBall
- ld a, [wPartyCount] ;is Party full?
- cp PARTY_LENGTH
- jr nz, .UseBall
- ld a, [wNumInBox] ;is Box full?
- cp MONS_PER_BOX
- jp z, BoxFullCannotThrowBall
-.UseBall
-;ok, you can use a ball
+ jp nz,ThrowBallAtTrainerMon
+
+; If this is for the old man battle, skip checking if the party & box are full.
+ ld a,[wBattleType]
+ cp BATTLE_TYPE_OLD_MAN
+ jr z,.canUseBall
+ cp BATTLE_TYPE_PIKACHU
+ jr z,.canUseBall
+
+ ld a,[wPartyCount] ; is party full?
+ cp a,PARTY_LENGTH
+ jr nz,.canUseBall
+ ld a,[wNumInBox] ; is box full?
+ cp a,MONS_PER_BOX
+ jp z,BoxFullCannotThrowBall
+
+.canUseBall
xor a
- ld [wCapturedMonSpecies], a
- ld a, [wBattleType]
- cp 2 ;SafariBattle
- jr nz, .skipSafariZoneCode
+ ld [wCapturedMonSpecies],a
+
+ ld a,[wBattleType]
+ cp a,BATTLE_TYPE_SAFARI
+ jr nz,.skipSafariZoneCode
+
.safariZone
- ; remove a Safari Ball from inventory
- ld hl, wNumSafariBalls
- dec [hl]
+ ld hl,wNumSafariBalls
+ dec [hl] ; remove a Safari Ball
+
.skipSafariZoneCode
call RunDefaultPaletteCommand
- ld a, $43
- ld [wd11e], a
- call LoadScreenTilesFromBuffer1 ;restore screenBuffer from Backup
- ld hl, ItemUseText00
+
+ ld a,$43 ; successful capture value
+ ld [wPokeBallAnimData],a
+
+ call LoadScreenTilesFromBuffer1
+ ld hl,ItemUseText00
call PrintText
+
+; 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.
callab IsGhostBattle
- ld b, $10
- jp z, .next12
- ld a, [wBattleType]
- cp $1
- jr z, .oldManBattle
- cp $4
- jr z, .oldManBattle ; pikachu battle technically old man battle
+ ld b,$10 ; can't be caught value
+ jp z,.setAnimData
+
+ ld a,[wBattleType]
+ cp BATTLE_TYPE_OLD_MAN
+ jr z,.oldManBattle
+ cp BATTLE_TYPE_PIKACHU
+ jr z,.oldManBattle ; pikachu battle technically old man battle
jr .notOldManBattle
.oldManBattle
- ld hl, wGrassRate
- ld de, wPlayerName
- ld bc, NAME_LENGTH
- call CopyData ; save the player's name in the Wild Monster data
+ ld hl,wGrassRate
+ ld de,wPlayerName
+ ld bc,NAME_LENGTH
+ call CopyData ; save the player's name in the Wild Monster data (part of the Cinnabar Island Missingno. glitch)
ld a, [wBattleType]
- cp MASTER_BALL
- jp nz, .BallSuccess
- ld a, $1
+ cp BATTLE_TYPE_OLD_MAN
+ jp nz,.captured
+ ld a,$1
ld [wCapturedMonSpecies], a
CheckEvent EVENT_02F
ld b, $63
- jp nz, .next12
- jp .BallSuccess
-
+ jp nz,.setAnimData
+ jp .captured
.notOldManBattle
- ld a, [wCurMap]
- cp POKEMONTOWER_6
- jr nz, .loop
- ld a, [wEnemyMonSpecies2]
- cp MAROWAK
- ld b, $10
- jp z, .next12
-; if not fighting ghost Marowak, loop until a random number in the current
-; pokeball's allowed range is found
+; 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 a,POKEMONTOWER_6
+ jr nz,.loop
+ ld a,[wEnemyMonSpecies2]
+ cp a,MAROWAK
+ ld b,$10 ; can't be caught value
+ jp z,.setAnimData
+
+; 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
- ld hl, wcf91
+ ld b,a
+
+; Get the item ID.
+ ld hl,wcf91
.asm_d54a
- ld a, [hl]
- cp MASTER_BALL
- jp z, .BallSuccess
- cp POKE_BALL
- jr z, .checkForAilments
- ld a, 200
+ ld a,[hl]
+
+; The Master Ball always succeeds.
+ cp a,MASTER_BALL
+ jp z,.captured
+
+; Anything will do for the basic Poké Ball.
+ cp a,POKE_BALL
+ jr z,.checkForAilments
+
+; If it's a Great/Ultra/Safari Ball and Rand1 is greater than 200, try again.
+ ld a,200
cp b
- jr c, .loop ;get only numbers <= 200 for Great Ball
- ld a, [hl]
- cp GREAT_BALL
- jr z, .checkForAilments
- ld a, 150 ;get only numbers <= 150 for Ultra Ball
+ jr c,.loop
+
+; Less than or equal to 200 is good enough for a Great Ball.
+ ld a,[hl]
+ cp a,GREAT_BALL
+ jr z,.checkForAilments
+
+; If it's an Ultra/Safari Ball and Rand1 is greater than 150, try again.
+ ld a,150
cp b
- jr c, .loop
+ jr c,.loop
+
.checkForAilments
-; pokemon can be caught more easily with any (primary) status ailment
-; Frozen/Asleep pokemon are relatively even easier to catch
-; for Frozen/Asleep pokemon, any random number from 0-24 ensures a catch.
-; for the others, a random number from 0-11 ensures a catch.
- ld a, [wEnemyMonStatus] ;status ailments
+; 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]
and a
- jr z, .noAilments
- and 1 << FRZ | SLP ;is frozen and/or asleep?
- ld c, 12
- jr z, .notFrozenOrAsleep
- ld c, 25
+ jr z,.skipAilmentValueSubtraction ; no ailments
+ and a, 1 << FRZ | SLP
+ ld c,12
+ jr z,.notFrozenOrAsleep
+ ld c,25
.notFrozenOrAsleep
ld a, b
sub c
- jp c, .BallSuccess
- ld b, a
-.noAilments
- push bc ;save RANDOM number
+ jp c,.captured
+ ld b,a
+
+.skipAilmentValueSubtraction
+ push bc ; save (Rand1 - Status)
+
+; Calculate MaxHP * 255.
xor a
- ld [H_MULTIPLICAND], a
- ld hl, wEnemyMonMaxHP
- ld a, [hli]
- ld [H_MULTIPLICAND + 1], a
- ld a, [hl]
- ld [H_MULTIPLICAND + 2], a
- ld a, 255
- ld [H_MULTIPLIER], a
- call Multiply ; MaxHP * 255
- ld a, [wcf91]
+ ld [H_MULTIPLICAND],a
+ ld hl,wEnemyMonMaxHP
+ ld a,[hli]
+ ld [H_MULTIPLICAND + 1],a
+ ld a,[hl]
+ ld [H_MULTIPLICAND + 2],a
+ ld a,255
+ ld [H_MULTIPLIER],a
+ call Multiply
+
+; Determine BallFactor. It's 8 for Great Balls and 12 for the others.
+ ld a,[wcf91]
cp GREAT_BALL
- ld a, 12 ;any other BallFactor
- jr nz, .next7
- ld a, 8
-.next7
- ld [H_DIVISOR], a
- ld b, 4 ; number of bytes in dividend
+ ld a,12
+ jr nz,.skip1
+ ld a,8
+
+.skip1
+; Note that the results of all division operations are floored.
+
+; Calculate (MaxHP * 255) / BallFactor.
+ ld [H_DIVISOR],a
+ ld b,4 ; number of bytes in dividend
call Divide
- ld hl, wEnemyMonHP
- ld a, [hli]
- ld b, a
- ld a, [hl]
-; explanation: we have a 16-bit value equal to [b << 8 | a].
-; This number is divided by 4. The result is 8 bit (reg. a).
-; Always bigger than zero.
+; 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]
srl b
rr a
srl b
- rr a ; a = current HP / 4
+ rr a
and a
- jr nz, .next8
+ jr nz,.skip2
inc a
-.next8
- ld [H_DIVISOR], a
- ld b, 4
- call Divide ; ((MaxHP * 255) / BallFactor) / (CurHP / 4)
- ld a, [H_QUOTIENT + 2]
+
+.skip2
+
+; Let W = ((MaxHP * 255) / BallFactor) / max(HP / 4, 1). Calculate W.
+ ld [H_DIVISOR],a
+ ld b,4
+ call Divide
+
+; If W > 255, store 255 in [H_QUOTIENT + 3].
+; Let X = min(W, 255) = [H_QUOTIENT + 3].
+ ld a,[H_QUOTIENT + 2]
and a
- jr z, .next9
- ld a, 255
- ld [H_QUOTIENT + 3], a
-.next9
- pop bc
- ld a, [wEnemyMonCatchRate] ;enemy: Catch Rate
+ jr z,.skip3
+ ld a,255
+ ld [H_QUOTIENT + 3],a
+
+.skip3
+ pop bc ; b = Rand1 - Status
+
+; If Rand1 - Status > CatchRate, the ball fails to capture the Pokémon.
+ ld a,[wEnemyMonCatchRate]
cp b
- jr c, .next10
- ld a, [H_QUOTIENT + 2]
+ jr c,.failedToCapture
+
+; If W > 255, the ball captures the Pokémon.
+ ld a,[H_QUOTIENT + 2]
and a
- jr nz, .BallSuccess ; if ((MaxHP * 255) / BallFactor) / (CurHP / 4) > 0x255, automatic success
- call Random
- ld b, a
- ld a, [H_QUOTIENT + 3]
+ jr nz,.captured
+
+ call Random ; Let this random number be called Rand2.
+
+; If Rand2 > X, the ball fails to capture the Pokémon.
+ ld b,a
+ ld a,[H_QUOTIENT + 3]
cp b
- jr c, .next10
-.BallSuccess
- jr .BallSuccess2
+ jr c,.failedToCapture
-.next10
- ld a, [H_QUOTIENT + 3]
- ld [wd11e], a
+.captured
+ jr .skipShakeCalculations
+
+.failedToCapture
+ ld a,[H_QUOTIENT + 3]
+ ld [wPokeBallCaptureCalcTemp],a ; Save X.
+
+; Calculate CatchRate * 100.
xor a
- ld [H_MULTIPLICAND], a
- ld [H_MULTIPLICAND + 1], a
- ld a, [wEnemyMonCatchRate] ;enemy: Catch Rate
- ld [H_MULTIPLICAND + 2], a
- ld a, 100
- ld [H_MULTIPLIER], a
- call Multiply ; CatchRate * 100
- ld a, [wcf91]
- ld b, 255
+ ld [H_MULTIPLICAND],a
+ ld [H_MULTIPLICAND + 1],a
+ ld a,[wEnemyMonCatchRate]
+ ld [H_MULTIPLICAND + 2],a
+ ld a,100
+ ld [H_MULTIPLIER],a
+ 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, .next11
- ld b, 200
+ jr z,.skip4
+ ld b,200
cp GREAT_BALL
- jr z, .next11
- ld b, 150
+ jr z,.skip4
+ ld b,150
cp ULTRA_BALL
- jr z, .next11
-.next11
- ld a, b
- ld [H_DIVISOR], a
- ld b, 4
+ jr z,.skip4
+
+.skip4
+
+; Let Y = (CatchRate * 100) / BallFactor2. Calculate Y.
+ ld a,b
+ ld [H_DIVISOR],a
+ ld b,4
call Divide
- ld a, [H_QUOTIENT + 2]
+
+; If Y > 255, there are 3 shakes.
+; Note that this shouldn't be possible.
+; The maximum value of Y is (255 * 100) / 150 = 170.
+ ld a,[H_QUOTIENT + 2]
and a
- ld b, $63
- jr nz, .next12
- ld a, [wd11e]
- ld [H_MULTIPLIER], a
+ ld b,$63 ; 3 shakes
+ jr nz,.setAnimData
+
+; Calculate X * Y.
+ ld a,[wPokeBallCaptureCalcTemp]
+ ld [H_MULTIPLIER],a
call Multiply
- ld a, 255
- ld [H_DIVISOR], a
- ld b, 4
+
+; Calculate (X * Y) / 255.
+ ld a,255
+ ld [H_DIVISOR],a
+ ld b,4
call Divide
- ld a, [wEnemyMonStatus] ;status ailments
+
+; Determine Status2.
+; no status ailment: Status2 = 0
+; Burn/Paralysis/Poison: Status2 = 5
+; Freeze/Sleep: Status2 = 10
+ ld a,[wEnemyMonStatus]
and a
- jr z, .next13
+ jr z,.skip5
and 1 << FRZ | SLP
- ld b, 5
- jr z, .next14
- ld b, 10
-.next14
- ld a, [H_QUOTIENT + 3]
+ ld b,5
+ jr z,.addAilmentValue
+ ld b,10
+
+.addAilmentValue
+; If the Pokémon has a status ailment, add Status2.
+ ld a,[H_QUOTIENT + 3]
add b
- ld [H_QUOTIENT + 3], a
-.next13
- ld a, [H_QUOTIENT + 3]
- cp 10
- ld b, $20
- jr c, .next12
- cp 30
- ld b, $61
- jr c, .next12
- cp 70
- ld b, $62
- jr c, .next12
- ld b, $63
-.next12
- ld a, b
- ld [wPokeBallAnimData], a
-.BallSuccess2
- ld c, 20
+ ld [H_QUOTIENT + 3],a
+
+.skip5
+; Finally determine the number of shakes.
+; Let Z = ((X * Y) / 255) + Status2 = [H_QUOTIENT + 3].
+; 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
+ ld a,[H_QUOTIENT + 3]
+ cp a,10
+ ld b,$20
+ jr c,.setAnimData
+ cp a,30
+ ld b,$61
+ jr c,.setAnimData
+ cp a,70
+ ld b,$62
+ jr c,.setAnimData
+ ld b,$63
+
+.setAnimData
+ ld a,b
+ ld [wPokeBallAnimData],a
+
+.skipShakeCalculations
+ ld c,20
call DelayFrames
- ld a, TOSS_ANIM
- ld [wAnimationID], a
+
+; Do the animation.
+ ld a,TOSS_ANIM
+ ld [wAnimationID],a
xor a
ld [H_WHOSETURN], a
ld [wAnimationType], a
@@ -347,48 +448,63 @@ ItemUseBall: ; d3ad (3:53ad)
pop af
ld [wcf91], a
pop af
- ld [wWhichPokemon], a
- ld a, [wPokeBallAnimData]
- cp $10
- ld hl, ItemUseBallText00
- jp z, .printText0
- cp $20
- ld hl, ItemUseBallText01
- jp z, .printText0
- cp $61
- ld hl, ItemUseBallText02
- jp z, .printText0
- cp $62
- ld hl, ItemUseBallText03
- jp z, .printText0
- cp $63
- ld hl, ItemUseBallText04
- jp z, .printText0
- ld hl, wEnemyMonHP ;current HP
- ld a, [hli]
+ ld [wWhichPokemon],a
+
+; Determine the message to display from the animation.
+ ld a,[wPokeBallAnimData]
+ cp a,$10
+ ld hl,ItemUseBallText00
+ jp z,.printMessage
+ cp a,$20
+ ld hl,ItemUseBallText01
+ jp z,.printMessage
+ cp a,$61
+ ld hl,ItemUseBallText02
+ jp z,.printMessage
+ cp a,$62
+ ld hl,ItemUseBallText03
+ jp z,.printMessage
+ cp a,$63
+ ld hl,ItemUseBallText04
+ jp z,.printMessage
+
+; Save current HP.
+ ld hl,wEnemyMonHP
+ ld a,[hli]
push af
- ld a, [hli]
- push af ;backup currentHP...
+ ld a,[hli]
+ push af
+
+; Save status ailment.
inc hl
- ld a, [hl]
- push af ;...and status ailments
+ ld a,[hl]
+ push af
+
push hl
- ld hl, wEnemyBattleStatus3
- bit Transformed, [hl]
- jr z, .next15
- ld a, $4c
- ld [wEnemyMonSpecies2], a
- jr .next16
-
-.next15
- set Transformed, [hl]
- ld hl, wTransformedEnemyMonOriginalDVs
- ld a, [wEnemyMonDVs]
- ld [hli], a
- ld a, [wEnemyMonDVs + 1]
- ld [hl], a
-.next16
- ld a, [wcf91]
+
+; 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
+ jr .skip6
+
+.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
+
+.skip6
+ ld a,[wcf91]
push af
ld a, [wEnemyMonSpecies2]
ld [wcf91], a
@@ -404,18 +520,20 @@ ItemUseBall: ; d3ad (3:53ad)
pop af
ld [hld], a
pop af
- ld [hl], a
- ld a, [wEnemyMonSpecies] ;enemy
- ld [wCapturedMonSpecies], a
- ld [wcf91], a
- ld [wd11e], a
- ld a, [wBattleType]
- cp $1
- jp z, .printText1 ; just barely out of reach for a relative jump
- cp $4
- jr z, .printText1
- ld hl, ItemUseBallText05
+ ld [hl],a
+ ld a,[wEnemyMonSpecies]
+ ld [wCapturedMonSpecies],a
+ ld [wcf91],a
+ ld [wd11e],a
+ ld a,[wBattleType]
+ cp BATTLE_TYPE_OLD_MAN ; is this the old man battle?
+ jp z,.oldManCaughtMon ; if so, don't give the player the caught Pokémon
+ cp BATTLE_TYPE_PIKACHU
+ jr z,.oldManCaughtMon ; same with Pikachu battle
+ ld hl,ItemUseBallText05
call PrintText
+
+; Add the caught Pokémon to the Pokédex.
predef IndexToPokedex
ld a, [wd11e]
dec a
@@ -431,51 +549,58 @@ ItemUseBall: ; d3ad (3:53ad)
ld b, FLAG_SET
predef FlagActionPredef
pop af
- and a
- jr nz, .checkParty
- ld hl, ItemUseBallText06
+
+ and a ; was the Pokémon already in the Pokédex?
+ jr nz,.skipShowingPokedexData ; if so, don't show the Pokédex data
+
+ ld hl,ItemUseBallText06
call PrintText
call ClearSprites
- ld a, [wEnemyMonSpecies] ;caught mon_ID
- ld [wd11e], a
+ ld a,[wEnemyMonSpecies]
+ ld [wd11e],a
predef ShowPokedexData
-.checkParty
+
+.skipShowingPokedexData
ld a, $1
ld [wd49c], a
ld a, $85
ld [wPikachuMood], a
- ld a, [wPartyCount]
- cp PARTY_LENGTH ;is party full?
- jr z, .sendToBox
+ ld a,[wPartyCount]
+ cp PARTY_LENGTH ; is party full?
+ jr z,.sendToBox
xor a ; PLAYER_PARTY_DATA
ld [wMonDataLocation], a
call ClearSprites
ld hl, .emptyString
call PrintText
- call AddPartyMon ;add mon to Party
- jr .End
+ call AddPartyMon
+ jr .done
.sendToBox
call ClearSprites
call SendNewMonToBox
- ld hl, ItemUseBallText07
+ ld hl,ItemUseBallText07
CheckEvent EVENT_MET_BILL
- jr nz, .sendToBox2
- ld hl, ItemUseBallText08
-.sendToBox2
+ jr nz,.printTransferredToPCText
+ ld hl,ItemUseBallText08
+.printTransferredToPCText
call PrintText
- jr .End
+ jr .done
+
+.oldManCaughtMon
+ ld hl,ItemUseBallText05
-.printText1
- ld hl, ItemUseBallText05
-.printText0
+.printMessage
call PrintText
call ClearSprites
-.End
- ld a, [wBattleType]
- and a
- ret nz
- ld hl, wNumBagItems
+
+.done
+ ld a,[wBattleType]
+ 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
inc a
ld [wItemQuantity], a
jp RemoveItemFromInventory
@@ -839,9 +964,9 @@ ItemUseMedicine: ; d8ae (3:58ae)
jr nc, .healHP ; if it's a Full Restore or one of the potions
; fall through if it's one of the status-specifc healing items
.cureStatusAilment
- ld bc, 4
- add hl, bc ; hl now points to status
- ld a, [wcf91]
+ ld bc,wPartyMon1Status - wPartyMon1
+ add hl,bc ; hl now points to status
+ ld a,[wcf91]
lb bc, ANTIDOTE_MSG, 1 << PSN
cp ANTIDOTE
jr z, .checkMonStatus
@@ -877,10 +1002,10 @@ ItemUseMedicine: ; d8ae (3:58ae)
ld hl, wPlayerBattleStatus3
res BadlyPoisoned, [hl] ; heal Toxic status
pop hl
- ld bc, 30
- add hl, bc ; hl now points to party stats
- ld de, wBattleMonMaxHP
- ld bc, 10
+ ld bc,wPartyMon1Stats - wPartyMon1Status
+ add hl,bc ; hl now points to party stats
+ ld de,wBattleMonStats
+ ld bc,NUM_STATS * 2
call CopyData ; copy party stats to in-battle stat data
predef DoubleOrHalveSelectedStats
jp .doneHealing
@@ -952,8 +1077,8 @@ ItemUseMedicine: ; d8ae (3:58ae)
.compareCurrentHPToMaxHP
push hl
push bc
- ld bc, 32
- add hl, bc ; hl now points to max HP
+ ld bc,wPartyMon1MaxHP - (wPartyMon1HP + 1)
+ add hl,bc ; hl now points to max HP
pop bc
ld a, [hli]
cp b
@@ -985,13 +1110,13 @@ ItemUseMedicine: ; d8ae (3:58ae)
ld [wChannelSoundIDs + CH4], a
push hl
push de
- ld bc, 32
- 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]
+ 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]
and a ; using Softboiled?
jp z, .notUsingSoftboiled2
; if using softboiled
@@ -1018,8 +1143,8 @@ ItemUseMedicine: ; d8ae (3:58ae)
ld [H_DIVISOR], a
ld b, 2 ; number of bytes
call Divide ; get 1/5 of max HP of pokemon that used Softboiled
- ld bc, wPartyMon1HP - wPartyMon1MaxHP
- add hl, bc ; hl now points to LSB of current 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
; subtract 1/5 of max HP from current HP of pokemon that used Softboiled
ld a, [H_QUOTIENT + 3]
push af
@@ -1096,16 +1221,16 @@ ItemUseMedicine: ; d8ae (3:58ae)
.noCarry
push de
inc hl
- ld d, h
- ld e, l ; de now points to current HP
- ld hl, 33
- 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]
+ 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 a,REVIVE
+ jr z,.setCurrentHPToHalfMaxHP
+ ld a,[hld]
+ ld b,a
+ ld a,[de]
sub b
dec de
ld b, [hl]
@@ -1144,11 +1269,11 @@ ItemUseMedicine: ; d8ae (3:58ae)
ld [wHPBarNewHP], a
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, -31
- add hl, bc
+ ld a,[wcf91]
+ cp a,FULL_RESTORE
+ jr nz,.updateInBattleData
+ ld bc,wPartyMon1Status - (wPartyMon1MaxHP + 1)
+ add hl,bc
xor a
ld [hl], a ; remove the status ailment in the party data
.updateInBattleData
@@ -1169,8 +1294,8 @@ ItemUseMedicine: ; d8ae (3:58ae)
xor a
ld [wBattleMonStatus], a ; remove the status ailment in the in-battle pokemon data
.calculateHPBarCoords
- ld hl, wOAMBuffer + $90
- ld bc, 2 * 20
+ ld hl,wOAMBuffer + $90
+ ld bc,2 * SCREEN_WIDTH
inc d
.calculateHPBarCoordsLoop
add hl, bc
@@ -1252,13 +1377,13 @@ ItemUseMedicine: ; d8ae (3:58ae)
.useVitamin
push hl
- ld a, [hl]
- ld [wd0b5], a
- ld [wd11e], a
- ld bc, 33
- add hl, bc ; hl now points to level
- ld a, [hl] ; a = level
- ld [wCurEnemyLVL], a ; store level
+ 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
call GetMonHeader
push de
ld a, d
@@ -1272,8 +1397,8 @@ ItemUseMedicine: ; d8ae (3:58ae)
push hl
sub HP_UP
add a
- ld bc, 17
- add hl, bc
+ ld bc,wPartyMon1HPExp - wPartyMon1
+ add hl,bc
add l
ld l, a
jr nc, .noCarry2
@@ -1323,21 +1448,21 @@ ItemUseMedicine: ; d8ae (3:58ae)
jp GBPalWhiteOut
.recalculateStats
- ld bc, 34
- add hl, bc
- ld d, h
- ld e, l ; de now points to stats
- ld bc, -18
- add hl, bc ; hl now points to byte 3 of experience
- ld b, 1
+ 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
jp CalcStats ; recalculate stats
.useRareCandy
push hl
- ld bc, 33
- 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
+ ld bc,wPartyMon1Level - wPartyMon1
+ add hl,bc ; hl now points to level
+ ld a,[hl] ; a = level
+ cp a, MAX_LEVEL
+ jr z,.vitaminNoEffect ; can't raise level above 100
inc a
ld [hl], a ; store incremented level
ld [wCurEnemyLVL], a
@@ -1347,8 +1472,8 @@ ItemUseMedicine: ; d8ae (3:58ae)
callab CalcExperience ; calculate experience for next level and store it at $ff96
pop de
pop hl
- ld bc, -19
- add hl, bc ; hl now points to experience
+ ld bc,wPartyMon1Exp - wPartyMon1Level
+ add hl,bc ; hl now points to MSB of experience
; update experience to minimum for new level
ld a, [hExperience]
ld [hli], a
@@ -1363,18 +1488,18 @@ ItemUseMedicine: ; d8ae (3:58ae)
push af
push de
push hl
- ld bc, 34
- add hl, bc ; hl now points to MSB of max HP
- ld a, [hli]
- ld b, a
- ld c, [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]
pop hl
push bc
push hl
call .recalculateStats
pop hl
- ld bc, 35 ; hl now points to LSB of max HP
- add hl, bc
+ ld bc,(wPartyMon1MaxHP + 1) - wPartyMon1
+ add hl,bc ; hl now points to LSB of max HP
pop bc
ld a, [hld]
sub c
@@ -1383,9 +1508,9 @@ ItemUseMedicine: ; d8ae (3:58ae)
sbc b
ld b, a ; bc = the amount of max HP gained from leveling up
; add the amount gained to the current HP
- ld de, -32
- add hl, de ; hl now points to MSB of current HP
- ld a, [hl]
+ ld de,(wPartyMon1HP + 1) - wPartyMon1MaxHP
+ add hl,de ; hl now points to LSB of current HP
+ ld a,[hl]
add c
ld [hld], a
ld a, [hl]
@@ -1575,10 +1700,10 @@ ItemUseCardKey: ; de57 (3:de57)
xor a
ld [wUnusedD71F], a
call GetTileAndCoordsInFrontOfPlayer
- ld a, [GetTileAndCoordsInFrontOfPlayer] ; $4586
- cp $18
- jr nz, .next0
- ld hl, CardKeyTable1
+ ld a,[GetTileAndCoordsInFrontOfPlayer]
+ cp a,$18
+ jr nz,.next0
+ ld hl,CardKeyTable1
jr .next1
.next0
@@ -2153,12 +2278,12 @@ ItemUsePPRestore: ; e1f7 (3:61f7)
cp ETHER
jr nc, .useEther ; if Ether or Max Ether
.usePPUp
- ld bc, 21
- add hl, bc
- ld a, [hl] ; move PP
- cp 3 << 6 ; have 3 PP Ups already been used?
- jr c, .PPNotMaxedOut
- ld hl, PPMaxedOutText
+ ld bc,wPartyMon1PP - wPartyMon1Moves
+ add hl,bc
+ ld a,[hl] ; move PP
+ cp a,3 << 6 ; have 3 PP Ups already been used?
+ jr c,.PPNotMaxedOut
+ ld hl,PPMaxedOutText
call PrintText
jr .chooseMove