shithub: pokered

Download patch

ref: 1ee9fb408c47c3a15a38b1bb407d86ed1a5d2fcc
parent: 1a987d1e1ab96ca9553d4253c72858057332a03a
parent: 4cfcc2f589d07e0b038a0ca4b31123152b93dbe1
author: Daniel Harding <corrnondacqb@yahoo.com>
date: Sun Aug 30 16:40:32 EDT 2015

Merge pull request #116 from YamaArashi/master

Misc changes

--- a/constants/misc_constants.asm
+++ b/constants/misc_constants.asm
@@ -10,6 +10,9 @@
 MONS_PER_BOX EQU 20
 NUM_BOXES    EQU 12
 
+BAG_ITEM_CAPACITY EQU 20
+PC_ITEM_CAPACITY  EQU 50
+
 HOF_MON           EQU $10
 HOF_TEAM          EQU PARTY_LENGTH * HOF_MON
 HOF_TEAM_CAPACITY EQU 50
@@ -168,6 +171,11 @@
 
 ; D733 flags
 BIT_TEST_BATTLE EQU 0
+
+; battle type constants
+BATTLE_TYPE_NORMAL  EQU 0
+BATTLE_TYPE_OLD_MAN EQU 1
+BATTLE_TYPE_SAFARI  EQU 2
 
 ; serial
 
--- a/engine/battle/core.asm
+++ b/engine/battle/core.asm
@@ -1584,7 +1584,7 @@
 	call IsGhostBattle
 	jp z, .canEscape ; jump if it's a ghost battle
 	ld a, [W_BATTLETYPE]
-	cp $2
+	cp BATTLE_TYPE_SAFARI
 	jp z, .canEscape ; jump if it's a safari battle
 	ld a, [wLinkState]
 	cp LINK_STATE_BATTLING
@@ -2094,7 +2094,7 @@
 	call SaveScreenTilesToBuffer1
 .nonstandardbattle
 	ld a, [W_BATTLETYPE]
-	cp $2 ; safari
+	cp BATTLE_TYPE_SAFARI
 	ld a, BATTLE_MENU_TEMPLATE
 	jr nz, .menuselected
 	ld a, SAFARI_BATTLE_MENU_TEMPLATE
@@ -2144,7 +2144,7 @@
 	jr .rightColumn
 .leftColumn ; put cursor in left column of menu
 	ld a, [W_BATTLETYPE]
-	cp $2
+	cp BATTLE_TYPE_SAFARI
 	ld a, " "
 	jr z, .safariLeftColumn
 ; put cursor in left column for normal battle menu (i.e. when it's not a Safari battle)
@@ -2177,7 +2177,7 @@
 	jr .AButtonPressed ; the A button was pressed
 .rightColumn ; put cursor in right column of menu
 	ld a, [W_BATTLETYPE]
-	cp $2
+	cp BATTLE_TYPE_SAFARI
 	ld a, " "
 	jr z, .safariRightColumn
 ; put cursor in right column for normal battle menu (i.e. when it's not a Safari battle)
@@ -2214,7 +2214,7 @@
 .AButtonPressed
 	call PlaceUnfilledArrowMenuCursor
 	ld a, [W_BATTLETYPE]
-	cp $2 ; is it a Safari battle?
+	cp BATTLE_TYPE_SAFARI
 	ld a, [wCurrentMenuItem]
 	ld [wBattleAndStartSavedMenuItem], a
 	jr z, .handleMenuSelection
@@ -2236,7 +2236,7 @@
 	jr nz, .upperLeftMenuItemWasNotSelected
 ; the upper left menu item was selected
 	ld a, [W_BATTLETYPE]
-	cp $2
+	cp BATTLE_TYPE_SAFARI
 	jr z, .throwSafariBallWasSelected
 ; the "FIGHT" menu was selected
 	xor a
@@ -2264,7 +2264,7 @@
 .notLinkBattle
 	call SaveScreenTilesToBuffer2
 	ld a, [W_BATTLETYPE]
-	cp $2 ; is it a safari battle?
+	cp BATTLE_TYPE_SAFARI
 	jr nz, BagWasSelected
 
 ; bait was selected
@@ -2333,7 +2333,7 @@
 	xor a
 	ld [wCurrentMenuItem], a
 	ld a, [W_BATTLETYPE]
-	cp $2 ; is it a safari battle?
+	cp BATTLE_TYPE_SAFARI
 	jr z, .checkIfMonCaptured
 
 	ld a, [wActionResultOrTookBattleTurn]
@@ -2355,7 +2355,7 @@
 	jr nz, .returnAfterCapturingMon
 
 	ld a, [W_BATTLETYPE]
-	cp $2 ; is it a safari battle?
+	cp BATTLE_TYPE_SAFARI
 	jr z, .returnAfterUsingItem_NoCapture
 ; not a safari battle
 	call LoadScreenTilesFromBuffer1
@@ -2386,7 +2386,7 @@
 ; party menu or rock was selected
 	call SaveScreenTilesToBuffer2
 	ld a, [W_BATTLETYPE]
-	cp $2 ; is it a safari battle?
+	cp BATTLE_TYPE_SAFARI
 	jr nz, .partyMenuWasSelected
 ; safari battle
 	ld a, SAFARI_ROCK
--- a/engine/battle/init_battle_variables.asm
+++ b/engine/battle/init_battle_variables.asm
@@ -32,7 +32,7 @@
 	jr c, .notSafariBattle
 	cp SAFARI_ZONE_REST_HOUSE_1
 	jr nc, .notSafariBattle
-	ld a, $2 ; safari battle
+	ld a, BATTLE_TYPE_SAFARI
 	ld [W_BATTLETYPE], a
 .notSafariBattle
 	jpab PlayBattleMusic
--- a/engine/hidden_object_functions17.asm
+++ b/engine/hidden_object_functions17.asm
@@ -95,23 +95,23 @@
 	ld hl, LinkCableHelpText1
 	call PrintText
 	xor a
-	ld [W_ANIMATIONID], a
+	ld [wMenuItemOffset], a ; not used
 	ld [wCurrentMenuItem], a
 	ld [wLastMenuItem], a
 	ld a, A_BUTTON | B_BUTTON
 	ld [wMenuWatchedKeys], a
-	ld a, $3
+	ld a, 3
 	ld [wMaxMenuItem], a
-	ld a, $2
+	ld a, 2
 	ld [wTopMenuItemY], a
-	ld a, $1
+	ld a, 1
 	ld [wTopMenuItemX], a
 .linkHelpLoop
 	ld hl, wd730
 	set 6, [hl]
 	coord hl, 0, 0
-	ld b, $8
-	ld c, $d
+	ld b, 8
+	ld c, 13
 	call TextBoxBorder
 	coord hl, 2, 2
 	ld de, HowToLinkText
@@ -122,13 +122,13 @@
 	bit 1, a ; pressed b
 	jr nz, .exit
 	ld a, [wCurrentMenuItem]
-	cp $3 ; pressed a on "STOP READING"
+	cp 3 ; pressed a on "STOP READING"
 	jr z, .exit
 	ld hl, wd730
 	res 6, [hl]
 	ld hl, LinkCableInfoTexts
 	add a
-	ld d, $0
+	ld d, 0
 	ld e, a
 	add hl, de
 	ld a, [hli]
@@ -179,16 +179,16 @@
 	ld hl, ViridianSchoolBlackboardText1
 	call PrintText
 	xor a
-	ld [W_ANIMATIONID], a
+	ld [wMenuItemOffset], a
 	ld [wCurrentMenuItem], a
 	ld [wLastMenuItem], a
 	ld a, D_LEFT | D_RIGHT | A_BUTTON | B_BUTTON
 	ld [wMenuWatchedKeys], a
-	ld a, $2
+	ld a, 2
 	ld [wMaxMenuItem], a
-	ld a, $2
+	ld a, 2
 	ld [wTopMenuItemY], a
-	ld a, $1
+	ld a, 1
 	ld [wTopMenuItemX], a
 .blackboardLoop
 	ld hl, wd730
@@ -210,34 +210,34 @@
 	bit 4, a ; pressed right
 	jr z, .didNotPressRight
 	; move cursor to right column
-	ld a, $2
+	ld a, 2
 	ld [wMaxMenuItem], a
-	ld a, $2
+	ld a, 2
 	ld [wTopMenuItemY], a
-	ld a, $6
+	ld a, 6
 	ld [wTopMenuItemX], a
-	ld a, $3
-	ld [W_ANIMATIONID], a
+	ld a, 3 ; in the the right column, use an offset to prevent overlap
+	ld [wMenuItemOffset], a
 	jr .blackboardLoop
 .didNotPressRight
 	bit 5, a ; pressed left
 	jr z, .didNotPressLeftOrRight
 	; move cursor to left column
-	ld a, $2
+	ld a, 2
 	ld [wMaxMenuItem], a
-	ld a, $2
+	ld a, 2
 	ld [wTopMenuItemY], a
-	ld a, $1
+	ld a, 1
 	ld [wTopMenuItemX], a
 	xor a
-	ld [W_ANIMATIONID], a
+	ld [wMenuItemOffset], a
 	jr .blackboardLoop
 .didNotPressLeftOrRight
 	ld a, [wCurrentMenuItem]
 	ld b, a
-	ld a, [W_ANIMATIONID]
+	ld a, [wMenuItemOffset]
 	add b
-	cp $5 ; cursor is pointing to "QUIT"
+	cp 5 ; cursor is pointing to "QUIT"
 	jr z, .exitBlackboard
 	; we must have pressed a on a status condition
 	; so print the text
@@ -245,7 +245,7 @@
 	res 6, [hl]
 	ld hl, ViridianBlackboardStatusPointers
 	add a
-	ld d, $0
+	ld d, 0
 	ld e, a
 	add hl, de
 	ld a, [hli]
--- a/engine/hidden_object_functions7.asm
+++ b/engine/hidden_object_functions7.asm
@@ -147,7 +147,7 @@
 	ld h, [hl]
 	ld l, a
 	call PrintText
-	ld a, $1
+	ld a, 1
 	ld [wDoNotWaitForButtonPressAfterDisplayingText], a
 	call CinnabarGymQuiz_1ea92
 	jp TextScriptEnd
@@ -391,23 +391,23 @@
 	ld hl, BillsHousePokemonListText1
 	call PrintText
 	xor a
-	ld [W_ANIMATIONID], a
+	ld [wMenuItemOffset], a ; not used
 	ld [wCurrentMenuItem], a
 	ld [wLastMenuItem], a
 	ld a, A_BUTTON | B_BUTTON
 	ld [wMenuWatchedKeys], a
-	ld a, $4
+	ld a, 4
 	ld [wMaxMenuItem], a
-	ld a, $2
+	ld a, 2
 	ld [wTopMenuItemY], a
-	ld a, $1
+	ld a, 1
 	ld [wTopMenuItemX], a
 .billsPokemonLoop
 	ld hl, wd730
 	set 6, [hl]
 	coord hl, 0, 0
-	ld b, $a
-	ld c, $9
+	ld b, 10
+	ld c, 9
 	call TextBoxBorder
 	coord hl, 2, 2
 	ld de, BillsMonListText
--- a/engine/items/items.asm
+++ b/engine/items/items.asm
@@ -101,87 +101,130 @@
 	dw ItemUsePPRestore  ; MAX_ELIXER
 
 ItemUseBall: ; d687 (3:5687)
+
+; Balls can't be used out of battle.
 	ld a,[W_ISINBATTLE]
 	and a
-	jp z,ItemUseNotTime ; not in battle
+	jp z,ItemUseNotTime
+
+; Balls can't catch trainers' Pokémon.
 	dec a
 	jp nz,ThrowBallAtTrainerMon
+
+; If this is for the old man battle, skip checking if the party & box are full.
 	ld a,[W_BATTLETYPE]
 	dec a
-	jr z,.UseBall
-	ld a,[wPartyCount]	;is Party full?
+	jr z,.canUseBall
+
+	ld a,[wPartyCount] ; is party full?
 	cp a,PARTY_LENGTH
-	jr nz,.UseBall
-	ld a,[W_NUMINBOX]	;is Box full?
+	jr nz,.canUseBall
+	ld a,[W_NUMINBOX] ; is box full?
 	cp a,MONS_PER_BOX
 	jp z,BoxFullCannotThrowBall
-.UseBall
-;ok, you can use a ball
+
+.canUseBall
 	xor a
 	ld [wCapturedMonSpecies],a
+
 	ld a,[W_BATTLETYPE]
-	cp a,2		;SafariBattle
+	cp a,BATTLE_TYPE_SAFARI
 	jr nz,.skipSafariZoneCode
+
 .safariZone
-	; remove a Safari Ball from inventory
 	ld hl,W_NUMSAFARIBALLS
-	dec [hl]
+	dec [hl] ; remove a Safari Ball
+
 .skipSafariZoneCode
 	call RunDefaultPaletteCommand
-	ld a,$43
-	ld [wd11e],a
-	call LoadScreenTilesFromBuffer1	;restore screenBuffer from Backup
+
+	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 b,$10 ; can't be caught value
+	jp z,.setAnimData
+
 	ld a,[W_BATTLETYPE]
 	dec a
 	jr nz,.notOldManBattle
+
 .oldManBattle
 	ld hl,W_GRASSRATE
 	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)
-	jp .BallSuccess
+	call CopyData ; save the player's name in the Wild Monster data (part of the Cinnabar Island Missingno. glitch)
+	jp .captured
+
 .notOldManBattle
+; 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,[W_CURMAP]
 	cp a,POKEMONTOWER_6
 	jr nz,.loop
 	ld a,[wEnemyMonSpecies2]
 	cp a,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
+	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
+
+; Get the item ID.
 	ld hl,wcf91
 	ld a,[hl]
+
+; The Master Ball always succeeds.
 	cp a,MASTER_BALL
-	jp z,.BallSuccess
+	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
+	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
-	ld a,150	;get only numbers <= 150 for Ultra Ball
+
+; If it's an Ultra/Safari Ball and Rand1 is greater than 150, try again.
+	ld a,150
 	cp b
 	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 a, 1 << FRZ | SLP	;is frozen and/or asleep?
+	jr z,.skipAilmentValueSubtraction ; no ailments
+	and a, 1 << FRZ | SLP
 	ld c,12
 	jr z,.notFrozenOrAsleep
 	ld c,25
@@ -188,10 +231,13 @@
 .notFrozenOrAsleep
 	ld a,b
 	sub c
-	jp c,.BallSuccess
+	jp c,.captured
 	ld b,a
-.noAilments
-	push bc		;save RANDOM number
+
+.skipAilmentValueSubtraction
+	push bc	; save (Rand1 - Status)
+
+; Calculate MaxHP * 255.
 	xor a
 	ld [H_MULTIPLICAND],a
 	ld hl,wEnemyMonMaxHP
@@ -201,121 +247,178 @@
 	ld [H_MULTIPLICAND + 2],a
 	ld a,255
 	ld [H_MULTIPLIER],a
-	call Multiply	; MaxHP * 255
+	call Multiply
+
+; Determine BallFactor. It's 8 for Great Balls and 12 for the others.
 	ld a,[wcf91]
 	cp a,GREAT_BALL
-	ld a,12		;any other BallFactor
-	jr nz,.next7
+	ld a,12
+	jr nz,.skip1
 	ld a,8
-.next7
+
+.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
+	ld b,4 ; number of bytes in dividend
 	call Divide
+
+; 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]
-
-; 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.
 	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
+
+.skip2
+; Let W = ((MaxHP * 255) / BallFactor) / max(HP / 4, 1). Calculate W.
 	ld [H_DIVISOR],a
 	ld b,4
-	call Divide	; ((MaxHP * 255) / BallFactor) / (CurHP / 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
+	jr z,.skip3
 	ld a,255
 	ld [H_QUOTIENT + 3],a
-.next9
-	pop bc
-	ld a,[wEnemyMonCatchRate]	;enemy: Catch Rate
+
+.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
+	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
+	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
-.next10
+	jr c,.failedToCapture
+
+.captured
+	jr .skipShakeCalculations
+
+.failedToCapture
 	ld a,[H_QUOTIENT + 3]
-	ld [wd11e],a
+	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 a,[wEnemyMonCatchRate]
 	ld [H_MULTIPLICAND + 2],a
 	ld a,100
 	ld [H_MULTIPLIER],a
-	call Multiply	; CatchRate * 100
+	call Multiply
+
+; Determine BallFactor2.
+; Poké Ball:         BallFactor2 = 255
+; Great Ball:        BallFactor2 = 200
+; Ultra/Safari Ball: BallFactor2 = 150
 	ld a,[wcf91]
 	ld b,255
 	cp a,POKE_BALL
-	jr z,.next11
+	jr z,.skip4
 	ld b,200
 	cp a,GREAT_BALL
-	jr z,.next11
+	jr z,.skip4
 	ld b,150
 	cp a,ULTRA_BALL
-	jr z,.next11
-.next11
+	jr z,.skip4
+
+.skip4
+; Let Y = (CatchRate * 100) / BallFactor2. Calculate Y.
 	ld a,b
 	ld [H_DIVISOR],a
 	ld b,4
 	call Divide
+
+; 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 b,$63 ; 3 shakes
+	jr nz,.setAnimData
+
+; Calculate X * Y.
+	ld a,[wPokeBallCaptureCalcTemp]
 	ld [H_MULTIPLIER],a
 	call Multiply
+
+; 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 a, 1 << FRZ | SLP
 	ld b,5
-	jr z,.next14
+	jr z,.addAilmentValue
 	ld b,10
-.next14
+
+.addAilmentValue
+; If the Pokémon has a status ailment, add Status2.
 	ld a,[H_QUOTIENT + 3]
 	add b
 	ld [H_QUOTIENT + 3],a
-.next13
+
+.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,.next12
+	jr c,.setAnimData
 	cp a,30
 	ld b,$61
-	jr c,.next12
+	jr c,.setAnimData
 	cp a,70
 	ld b,$62
-	jr c,.next12
+	jr c,.setAnimData
 	ld b,$63
-.next12
+
+.setAnimData
 	ld a,b
 	ld [wPokeBallAnimData],a
-.BallSuccess2
+
+.skipShakeCalculations
 	ld c,20
 	call DelayFrames
+
+; Do the animation.
 	ld a,TOSS_ANIM
 	ld [W_ANIMATIONID],a
 	xor a
@@ -331,38 +434,53 @@
 	ld [wcf91],a
 	pop af
 	ld [wWhichPokemon],a
+
+; Determine the message to display from the animation.
 	ld a,[wPokeBallAnimData]
 	cp a,$10
 	ld hl,ItemUseBallText00
-	jp z,.printText0
+	jp z,.printMessage
 	cp a,$20
 	ld hl,ItemUseBallText01
-	jp z,.printText0
+	jp z,.printMessage
 	cp a,$61
 	ld hl,ItemUseBallText02
-	jp z,.printText0
+	jp z,.printMessage
 	cp a,$62
 	ld hl,ItemUseBallText03
-	jp z,.printText0
+	jp z,.printMessage
 	cp a,$63
 	ld hl,ItemUseBallText04
-	jp z,.printText0
-	ld hl,wEnemyMonHP	;current HP
+	jp z,.printMessage
+
+; Save current HP.
+	ld hl,wEnemyMonHP
 	ld a,[hli]
 	push af
 	ld a,[hli]
-	push af		;backup currentHP...
+	push af
+
+; Save status ailment.
 	inc hl
 	ld a,[hl]
-	push af		;...and status ailments
+	push af
+
 	push hl
+
+; 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,W_ENEMYBATTSTATUS3
 	bit Transformed,[hl]
-	jr z,.next15
-	ld a,$4c
+	jr z,.notTransformed
+	ld a,DITTO
 	ld [wEnemyMonSpecies2],a
-	jr .next16
-.next15
+	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]
@@ -369,7 +487,8 @@
 	ld [hli],a
 	ld a,[wEnemyMonDVs + 1]
 	ld [hl],a
-.next16
+
+.skip6
 	ld a,[wcf91]
 	push af
 	ld a,[wEnemyMonSpecies2]
@@ -387,15 +506,18 @@
 	ld [hld],a
 	pop af
 	ld [hl],a
-	ld a,[wEnemyMonSpecies]	;enemy
+	ld a,[wEnemyMonSpecies]
 	ld [wCapturedMonSpecies],a
 	ld [wcf91],a
 	ld [wd11e],a
 	ld a,[W_BATTLETYPE]
-	dec a
-	jr z,.printText1
+	dec a ; is this the old man battle?
+	jr z,.oldManCaughtMon ; if so, don't give the player the caught Pokémon
+
 	ld hl,ItemUseBallText05
 	call PrintText
+
+; Add the caught Pokémon to the Pokédex.
 	predef IndexToPokedex
 	ld a,[wd11e]
 	dec a
@@ -411,46 +533,56 @@
 	ld b,FLAG_SET
 	predef FlagActionPredef
 	pop af
-	and a
-	jr nz,.checkParty
+
+	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 a,[wEnemyMonSpecies]
 	ld [wd11e],a
 	predef ShowPokedexData
-.checkParty
+
+.skipShowingPokedexData
 	ld a,[wPartyCount]
-	cp a,PARTY_LENGTH		;is party full?
+	cp a,PARTY_LENGTH ; is party full?
 	jr z,.sendToBox
 	xor a ; PLAYER_PARTY_DATA
 	ld [wMonDataLocation],a
 	call ClearSprites
-	call AddPartyMon	;add mon to Party
-	jr .End
+	call AddPartyMon
+	jr .done
+
 .sendToBox
 	call ClearSprites
 	call SendNewMonToBox
 	ld hl,ItemUseBallText07
 	CheckEvent EVENT_MET_BILL
-	jr nz,.sendToBox2
+	jr nz,.printTransferredToPCText
 	ld hl,ItemUseBallText08
-.sendToBox2
+.printTransferredToPCText
 	call PrintText
-	jr .End
-.printText1
+	jr .done
+
+.oldManCaughtMon
 	ld hl,ItemUseBallText05
-.printText0
+
+.printMessage
 	call PrintText
 	call ClearSprites
-.End
+
+.done
 	ld a,[W_BATTLETYPE]
-	and a
-	ret nz
+	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
+
 ItemUseBallText00: ; d937 (3:5937)
 ;"It dodged the thrown ball!"
 ;"This pokemon can't be caught"
@@ -769,10 +901,10 @@
 	ld hl,W_PLAYERBATTSTATUS3
 	res BadlyPoisoned,[hl] ; heal Toxic status
 	pop hl
-	ld bc,30
+	ld bc,wPartyMon1Stats - wPartyMon1Status
 	add hl,bc ; hl now points to party stats
-	ld de,wBattleMonMaxHP
-	ld bc,10
+	ld de,wBattleMonStats
+	ld bc,NUM_STATS * 2
 	call CopyData ; copy party stats to in-battle stat data
 	predef DoubleOrHalveSelectedStats
 	jp .doneHealing
@@ -827,7 +959,7 @@
 .compareCurrentHPToMaxHP
 	push hl
 	push bc
-	ld bc,32
+	ld bc,wPartyMon1MaxHP - (wPartyMon1HP + 1)
 	add hl,bc ; hl now points to max HP
 	pop bc
 	ld a,[hli]
@@ -859,7 +991,7 @@
 	ld [wChannelSoundIDs + CH4],a
 	push hl
 	push de
-	ld bc,32
+	ld bc,wPartyMon1MaxHP - (wPartyMon1HP + 1)
 	add hl,bc ; hl now points to max HP
 	ld a,[hli]
 	ld [wHPBarMaxHP+1],a
@@ -892,7 +1024,7 @@
 	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
+	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]
@@ -971,7 +1103,7 @@
 	inc hl
 	ld d,h
 	ld e,l ; de now points to current HP
-	ld hl,33
+	ld hl,(wPartyMon1MaxHP + 1) - (wPartyMon1HP + 1)
 	add hl,de ; hl now points to max HP
 	ld a,[wcf91]
 	cp a,REVIVE
@@ -1018,7 +1150,7 @@
 	ld a,[wcf91]
 	cp a,FULL_RESTORE
 	jr nz,.updateInBattleData
-	ld bc,-31
+	ld bc,wPartyMon1Status - (wPartyMon1MaxHP + 1)
 	add hl,bc
 	xor a
 	ld [hl],a ; remove the status ailment in the party data
@@ -1041,7 +1173,7 @@
 	ld [wBattleMonStatus],a ; remove the status ailment in the in-battle pokemon data
 .calculateHPBarCoords
 	ld hl,wOAMBuffer + $90
-	ld bc,2 * 20
+	ld bc,2 * SCREEN_WIDTH
 	inc d
 .calculateHPBarCoordsLoop
 	add hl,bc
@@ -1121,7 +1253,7 @@
 	ld a,[hl]
 	ld [wd0b5],a
 	ld [wd11e],a
-	ld bc,33
+	ld bc,wPartyMon1Level - wPartyMon1
 	add hl,bc ; hl now points to level
 	ld a,[hl] ; a = level
 	ld [W_CURENEMYLVL],a ; store level
@@ -1138,7 +1270,7 @@
 	push hl
 	sub a,HP_UP
 	add a
-	ld bc,17
+	ld bc,wPartyMon1HPExp - wPartyMon1
 	add hl,bc
 	add l
 	ld l,a
@@ -1186,17 +1318,17 @@
 	call PrintText
 	jp GBPalWhiteOut
 .recalculateStats
-	ld bc,34
+	ld bc,wPartyMon1Stats - wPartyMon1
 	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 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
+	ld bc,wPartyMon1Level - wPartyMon1
 	add hl,bc ; hl now points to level
 	ld a,[hl] ; a = level
 	cp a, MAX_LEVEL
@@ -1210,8 +1342,8 @@
 	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
@@ -1226,7 +1358,7 @@
 	push af
 	push de
 	push hl
-	ld bc,34
+	ld bc,wPartyMon1MaxHP - wPartyMon1
 	add hl,bc ; hl now points to MSB of max HP
 	ld a,[hli]
 	ld b,a
@@ -1236,8 +1368,8 @@
 	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
@@ -1246,8 +1378,8 @@
 	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 de,(wPartyMon1HP + 1) - wPartyMon1MaxHP
+	add hl,de ; hl now points to LSB of current HP
 	ld a,[hl]
 	add c
 	ld [hld],a
@@ -1421,7 +1553,7 @@
 	xor a
 	ld [wUnusedD71F],a
 	call GetTileAndCoordsInFrontOfPlayer
-	ld a,[GetTileAndCoordsInFrontOfPlayer] ; $4586
+	ld a,[GetTileAndCoordsInFrontOfPlayer]
 	cp a,$18
 	jr nz,.next0
 	ld hl,CardKeyTable1
--- a/engine/menu/main_menu.asm
+++ b/engine/menu/main_menu.asm
@@ -20,7 +20,7 @@
 	ld [hli],a
 	ld [hli],a
 	ld [hl],a
-	ld [W_ANIMATIONID],a
+	ld [wDefaultMap],a
 	ld hl,wd72e
 	res 6,[hl]
 	call ClearScreen
@@ -269,7 +269,7 @@
 	call DelayFrames
 	ld hl, wd732
 	res 1, [hl]
-	ld a, [W_ANIMATIONID]
+	ld a, [wDefaultMap]
 	ld [wDestinationMap], a
 	call SpecialWarpIn
 	ld c, 20
--- a/engine/menu/naming_screen.asm
+++ b/engine/menu/naming_screen.asm
@@ -166,7 +166,7 @@
 	call RunDefaultPaletteCommand
 	call GBPalNormal
 	xor a
-	ld [W_SUBANIMTRANSFORM], a
+	ld [wAnimCounter], a
 	ld hl, wd730
 	res 6, [hl]
 	ld a, [W_ISINBATTLE]
--- a/engine/menu/start_sub_menus.asm
+++ b/engine/menu/start_sub_menus.asm
@@ -160,7 +160,7 @@
 .surf
 	bit 4,a ; does the player have the Soul Badge?
 	jp z,.newBadgeRequired
-	callba CheckForForcedBikeSurf
+	callba IsSurfingAllowed
 	ld hl,wd728
 	bit 1,[hl]
 	res 1,[hl]
--- a/engine/oak_speech.asm
+++ b/engine/oak_speech.asm
@@ -48,7 +48,7 @@
 	ld a,1
 	ld [wItemQuantity],a
 	call AddItemToInventory  ; give one potion
-	ld a,[W_ANIMATIONID]
+	ld a,[wDefaultMap]
 	ld [wDestinationMap],a
 	call SpecialWarpIn
 	xor a
--- a/engine/overworld/movement.asm
+++ b/engine/overworld/movement.asm
@@ -133,8 +133,8 @@
 	ld l, a
 	inc l
 	ld a, [hl]        ; c1x1
-	bit 7, a
-	jp nz, InitializeSpriteFacingDirection  ; c1x1 >= $80
+	bit 7, a ; is the face player flag set?
+	jp nz, MakeNPCFacePlayer
 	ld b, a
 	ld a, [wFontLoaded]
 	bit 0, a
@@ -400,10 +400,15 @@
 	ld [hl], $0             ; c1x8 = 0 (walk animation frame)
 	jp UpdateSpriteImage
 
-InitializeSpriteFacingDirection: ; 507f (1:507f)
+MakeNPCFacePlayer: ; 507f (1:507f)
+; Make an NPC face the player if the player has spoken to him or her.
+
+; Check if the behaviour of the NPC facing the player when spoken to is
+; disabled. This is only done when rubbing the S.S. Anne captain's back.
 	ld a, [wd72d]
 	bit 5, a
 	jr nz, notYetMoving
+
 	res 7, [hl]
 	ld a, [wPlayerDirection]
 	bit PLAYER_DIR_BIT_UP, a
--- a/engine/town_map.asm
+++ b/engine/town_map.asm
@@ -444,8 +444,12 @@
 
 WriteTownMapSpriteOAM: ; 71279 (1c:5279)
 	push hl
+
+; Subtract 4 from c (X coord) and 4 from b (Y coord). However, the carry from c
+; is added to b, so the net result is that only 3 is subtracted from b.
 	lb hl, -4, -4
-	add hl, bc ; subtract 4 from c (X coord) and 4 from b (Y coord)
+	add hl, bc
+
 	ld b, h
 	ld c, l
 	pop hl
@@ -469,7 +473,7 @@
 	xor a
 	ld [hli], a
 	inc d
-	ld a, $8
+	ld a, 8
 	add c
 	ld c, a
 	dec e
@@ -476,7 +480,7 @@
 	jr nz, .innerLoop
 	pop bc
 	pop de
-	ld a, $8
+	ld a, 8
 	add b
 	ld b, a
 	dec d
--- a/home.asm
+++ b/home.asm
@@ -3167,7 +3167,7 @@
 
 LoadScreenTilesFromBuffer2:: ; 3701 (0:3701)
 	call LoadScreenTilesFromBuffer2DisableBGTransfer
-	ld a, $1
+	ld a, 1
 	ld [H_AUTOBGTRANSFERENABLED], a
 	ret
 
@@ -3177,7 +3177,7 @@
 	ld [H_AUTOBGTRANSFERENABLED], a
 	ld hl, wTileMapBackup2
 	coord de, 0, 0
-	ld bc, $168
+	ld bc, SCREEN_WIDTH * SCREEN_HEIGHT
 	call CopyData
 	ret
 
@@ -3194,7 +3194,7 @@
 	coord de, 0, 0
 	ld bc, SCREEN_WIDTH * SCREEN_HEIGHT
 	call CopyData
-	ld a, $1
+	ld a, 1
 	ld [H_AUTOBGTRANSFERENABLED], a
 	ret
 
--- a/home/overworld.asm
+++ b/home/overworld.asm
@@ -1190,8 +1190,8 @@
 	ld a,l
 	and a,$f0
 	inc a
-	ld l,a
-	set 7,[hl]
+	ld l,a ; hl = $c1x1
+	set 7,[hl] ; set flag to make the sprite face the player
 	ld a,e
 	ld [hSpriteIndexOrTextID],a
 	ret
--- a/main.asm
+++ b/main.asm
@@ -548,7 +548,7 @@
 	ld [W_OBTAINEDBADGES], a
 
 	ld hl, W_FLAGS_D733
-	set 0, [hl]
+	set BIT_TEST_BATTLE, [hl]
 
 	; Reset the party.
 	ld hl, wPartyCount
@@ -668,7 +668,7 @@
 	xor a
 	jr .done
 .notFirstMap
-	ld a, [wLastMap]
+	ld a, [wLastMap] ; this value is overwritten before it's ever read
 	ld hl, wd732
 	bit 4, [hl] ; used dungeon warp (jumped down hole/waterfall)?
 	jr nz, .usedDunegonWarp
@@ -2751,12 +2751,15 @@
 	TX_FAR _CanMoveBouldersText
 	db "@"
 
-CheckForForcedBikeSurf: ; cdc0 (3:4dc0)
+IsSurfingAllowed: ; cdc0 (3:4dc0)
+; Returns whether surfing is allowed in bit 1 of wd728.
+; Surfing isn't allowed on the Cycling Road or in the lowest level of the
+; Seafoam Islands before the current has been slowed with boulders.
 	ld hl, wd728
 	set 1, [hl]
 	ld a, [wd732]
 	bit 5, a
-	jr nz, .asm_cdec
+	jr nz, .forcedToRideBike
 	ld a, [W_CURMAP]
 	cp SEAFOAM_ISLANDS_5
 	ret nz
@@ -2769,7 +2772,7 @@
 	res 1, [hl]
 	ld hl, CurrentTooFastText
 	jp PrintText
-.asm_cdec
+.forcedToRideBike
 	ld hl, wd728
 	res 1, [hl]
 	ld hl, CyclingIsFunText
@@ -2799,7 +2802,7 @@
 	push de
 	push hl
 	push hl
-	ld d,50 ; PC box can hold 50 items
+	ld d,PC_ITEM_CAPACITY ; how many items the PC can hold
 	ld a,wNumBagItems & $FF
 	cp l
 	jr nz,.checkIfInventoryFull
@@ -2807,7 +2810,7 @@
 	cp h
 	jr nz,.checkIfInventoryFull
 ; if the destination is the bag
-	ld d,20 ; bag can hold 20 items
+	ld d,BAG_ITEM_CAPACITY ; how many items the bag can hold
 .checkIfInventoryFull
 	ld a,[hl]
 	sub d
--- a/scripts/halloffameroom.asm
+++ b/scripts/halloffameroom.asm
@@ -47,11 +47,11 @@
 	ld [wLastBlackoutMap], a
 	callba SaveSAVtoSRAM
 	ld b, 5
-.asm_5a4ff
+.delayLoop
 	ld c, 600 / 5
 	call DelayFrames
 	dec b
-	jr nz, .asm_5a4ff
+	jr nz, .delayLoop
 	call WaitForTextScrollButtonPress
 	jp Init
 
--- a/scripts/viridiancity.asm
+++ b/scripts/viridiancity.asm
@@ -71,7 +71,7 @@
 	ld [wListScrollOffset], a
 
 	; set up battle for Old Man
-	ld a, $1
+	ld a, BATTLE_TYPE_OLD_MAN
 	ld [W_BATTLETYPE], a
 	ld a, 5
 	ld [W_CURENEMYLVL], a
--- a/wram.asm
+++ b/wram.asm
@@ -50,6 +50,7 @@
 \1Moves::      ds NUM_MOVES
 \1DVs::        ds 2
 \1Level::      db
+\1Stats::
 \1MaxHP::      dw
 \1Attack::     dw
 \1Defense::    dw
@@ -1746,6 +1747,11 @@
 
 	ds 1
 
+wDefaultMap:: ; d07c
+; the map you will start at when the debug bit is set
+
+wMenuItemOffset:: ; d07c
+
 W_ANIMATIONID:: ; d07c
 ; ID number of the current battle animation
 	ds 1
@@ -1789,7 +1795,7 @@
 ; counts the number of subentries left in the current subanimation
 	ds 1
 
-wSaveFileStatus::
+wSaveFileStatus:: ; d088
 ; 1 = no save file or save file is corrupted
 ; 2 = save file exists and no corruption has been detected
 	ds 1
@@ -2068,6 +2074,8 @@
 ; which will be the first mon sent out.
 	ds 1
 
+wPokeBallCaptureCalcTemp:: ; d11e
+
 ; lower nybble: number of shakes
 ; upper nybble: number of animations to play
 wPokeBallAnimData:: ; d11e
@@ -2277,7 +2285,7 @@
 	ds 1
 wBagItems:: ; d31e
 ; item, quantity
-	ds 20 * 2
+	ds BAG_ITEM_CAPACITY * 2
 	ds 1 ; end
 
 wPlayerMoney:: ; d347
@@ -2590,7 +2598,7 @@
 	ds 1
 wBoxItems:: ; d53b
 ; item, quantity
-	ds 50 * 2
+	ds PC_ITEM_CAPACITY * 2
 	ds 1 ; end
 
 wCurrentBoxNum:: ; d5a0
@@ -2921,8 +2929,14 @@
 
 	ds 8
 
-wd728::
+wd728:: ; d728
 ; bit 0: using Strength outside of battle
+; bit 1: set by IsSurfingAllowed when surfing's allowed, but the caller resets it after checking the result
+; bit 3: received Old Rod
+; bit 4: received Good Rod
+; bit 5: received Super Rod
+; bit 6: gave one of the Saffron guards a drink
+; bit 7: set by ItemUseCardKey, which is leftover code from a previous implementation of the Card Key
 	ds 1
 
 	ds 1
@@ -2936,16 +2950,36 @@
 
 wd72c:: ; d72c
 ; bit 0: if not set, the 3 minimum steps between random battles have passed
+; bit 1: prevent audio fade out
 	ds 1
 
-wd72d:: ds 1 ; misc temp flags? (in some scripts, bit 6 and 7 set after a special battle (e.g. gym leaders) has been won)
-             ; also used as a start menu flag
+wd72d:: ; d72d
+; This variable is used for temporary flags and as the destination map when
+; warping to the Trade Center or Colosseum.
+; bit 0: sprite facing directions have been initialised in the Trade Center
+; bit 3: do scripted warp (used to warp back to Lavender Town from the top of the pokemon tower)
+; bit 4: on a dungeon warp
+; bit 5: don't make NPCs face the player when spoken to
+; Bits 6 and 7 are set by scripts when starting major battles in the storyline,
+; but they do not appear to affect anything. Bit 6 is reset after all battles
+; and bit 7 is reset after trainer battles (but it's only set before trainer
+; battles anyway).
+	ds 1
 
-wd72e::
+wd72e:: ; d72e
+; bit 0: the player has received Lapras in the Silph Co. building
+; bit 1: set in various places, but doesn't appear to have an effect
+; bit 2: the player has healed pokemon at a pokemon center at least once
+; bit 3: the player has a received a pokemon from Prof. Oak
+; bit 4: disable battles
+; bit 5: set when a battle ends and when the player blacks out in the overworld due to poison
+; bit 6: using the link feature
 ; bit 7: set if scripted NPC movement has been initialised
-	ds 2 ; more temp misc flags, used with npc movement, main menu and other stuff
+	ds 1
 
-wd730::
+	ds 1
+
+wd730:: ; d730
 ; bit 0: NPC sprite being moved by script
 ; bit 5: ignore joypad input
 ; bit 6: print text with no delay between each letter
@@ -2970,6 +3004,9 @@
 
 W_FLAGS_D733:: ; d733
 ; bit 0: running a test battle
+; bit 1: prevent music from changing when entering new map
+; bit 2: skip the joypad check in CheckWarpsNoCollision (used for the forced warp down the waterfall in the Seafoam Islands)
+; bit 3: trainer wants to battle
 ; bit 4: use variable [W_CURMAPSCRIPT] instead of the provided index for next frame's map script (used to start battle when talking to trainers)
 ; bit 7: used fly out of battle
 	ds 1