summaryrefslogtreecommitdiff
path: root/engine
diff options
context:
space:
mode:
Diffstat (limited to 'engine')
-rw-r--r--engine/bank3c.asm4
-rw-r--r--engine/bank3d.asm13
-rw-r--r--engine/battle/common_text.asm6
-rwxr-xr-xengine/battle/core.asm62
-rw-r--r--engine/battle/init_battle_variables.asm2
-rw-r--r--engine/battle/moveEffects/pay_day_effect.asm2
-rw-r--r--engine/battle/scale_sprites.asm8
-rwxr-xr-xengine/diploma_3a.asm4
-rwxr-xr-xengine/hall_of_fame.asm8
-rwxr-xr-xengine/hidden_object_functions17.asm38
-rwxr-xr-xengine/hidden_object_functions7.asm9
-rwxr-xr-xengine/items/items.asm793
-rw-r--r--engine/menu/link_menu.asm2
-rwxr-xr-xengine/menu/main_menu.asm8
-rwxr-xr-xengine/menu/naming_screen.asm2
-rwxr-xr-xengine/menu/start_sub_menus.asm6
-rwxr-xr-xengine/oak_speech.asm6
-rwxr-xr-xengine/oak_speech2.asm11
-rwxr-xr-xengine/overworld/card_key.asm2
-rwxr-xr-xengine/overworld/cinnabar_lab.asm10
-rw-r--r--engine/overworld/movement.asm14
-rw-r--r--engine/overworld/special_warps.asm2
-rwxr-xr-xengine/pikachu_pic_animation.asm6
-rwxr-xr-xengine/predefs7.asm2
-rwxr-xr-xengine/titlescreen.asm2
-rwxr-xr-xengine/town_map.asm6
26 files changed, 586 insertions, 442 deletions
diff --git a/engine/bank3c.asm b/engine/bank3c.asm
index 3683f2b1..d3bcc897 100644
--- a/engine/bank3c.asm
+++ b/engine/bank3c.asm
@@ -65,12 +65,12 @@ SetMapSpecificScriptFlagsOnMapReload: ; f02da (3c:42da)
ret
.verm_gym
- ld hl, wd126
+ ld hl, wCurrentMapScriptFlags
set 6, [hl]
ret
.in_list
- ld hl, wd126
+ ld hl, wCurrentMapScriptFlags
set 5, [hl]
ret
diff --git a/engine/bank3d.asm b/engine/bank3d.asm
index bf84e096..fbf816b6 100644
--- a/engine/bank3d.asm
+++ b/engine/bank3d.asm
@@ -456,12 +456,15 @@ Text_f5b28: ; f5b28 (3d:5b28)
TX_FAR _CanMoveBouldersText ; 2d:4193
db "@"
-CheckForForcedBikeSurf: ; f5b2d (3d:5b2d)
+IsSurfingAllowed: ; f5b2d (3d:5b2d)
+; 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_f5b59
+ jr nz, .forcedToRideBike
ld a, [wCurMap]
cp SEAFOAM_ISLANDS_5
ret nz
@@ -474,7 +477,7 @@ CheckForForcedBikeSurf: ; f5b2d (3d:5b2d)
res 1, [hl]
ld hl, CurrentTooFastText
jp PrintText
-.asm_f5b59
+.forcedToRideBike
ld hl, wd728
res 1, [hl]
ld hl, CyclingIsFunText
@@ -499,7 +502,7 @@ AddItemToInventory_: ; f5b70 (3d:5b70)
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
@@ -507,7 +510,7 @@ AddItemToInventory_: ; f5b70 (3d:5b70)
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
diff --git a/engine/battle/common_text.asm b/engine/battle/common_text.asm
index 0ca9ce96..a0c44346 100644
--- a/engine/battle/common_text.asm
+++ b/engine/battle/common_text.asm
@@ -9,8 +9,8 @@ PrintBeginningBattleText: ; f4000 (3d:4000)
jr c, .pokemonTower
.notPokemonTower
ld a,[wBattleType]
- cp $4 ; new battle type?
- jr nz,.notnewbattletype
+ cp BATTLE_TYPE_PIKACHU
+ jr nz,.notPikachuBattle
callab IsPlayerPikachuAsleepInParty
ld e,$24
jr c,.asm_f4026
@@ -18,7 +18,7 @@ PrintBeginningBattleText: ; f4000 (3d:4000)
.asm_f4026
callab PlayPikachuSoundClip
jr .continue
-.notnewbattletype
+.notPikachuBattle
ld a, [wEnemyMonSpecies2]
call PlayCry
.continue
diff --git a/engine/battle/core.asm b/engine/battle/core.asm
index 565525ea..24b3863b 100755
--- a/engine/battle/core.asm
+++ b/engine/battle/core.asm
@@ -250,9 +250,9 @@ StartBattle: ; 3c127 (f:4127)
call SaveScreenTilesToBuffer1
.checkAnyPartyAlive
ld a, [wBattleType]
- cp $3
+ cp BATTLE_TYPE_RUN
jp z, .specialBattle
- cp $4
+ cp BATTLE_TYPE_PIKACHU
jp z, .specialBattle
call AnyPartyAlive
ld a, d
@@ -1625,9 +1625,9 @@ TryRunningFromBattle: ; 3cb1e (f:4b1e)
call IsGhostBattle
jp z, .canEscape ; jump if it's a ghost battle
ld a, [wBattleType]
- cp $2
+ cp BATTLE_TYPE_SAFARI
jp z, .canEscape ; jump if it's a safari battle
- cp $3
+ cp BATTLE_TYPE_RUN
jp z, .canEscape ; hurry, get away?
ld a, [wLinkState]
cp LINK_STATE_BATTLING
@@ -1770,7 +1770,7 @@ LoadBattleMonFromParty: ; 3cc10 (f:4c10)
ld bc, NUM_MOVES
call CopyData
ld de, wBattleMonLevel
- ld bc, $b
+ ld bc, wBattleMonPP - wBattleMonLevel
call CopyData
ld a, [wBattleMonSpecies2]
ld [wd0b5], a
@@ -1814,7 +1814,7 @@ LoadEnemyMonFromParty: ; 3cc7d (f:4c7d)
ld bc, NUM_MOVES
call CopyData
ld de, wEnemyMonLevel
- ld bc, $b
+ ld bc, wEnemyMonPP - wEnemyMonLevel
call CopyData
ld a, [wEnemyMonSpecies]
ld [wd0b5], a
@@ -1990,11 +1990,11 @@ DrawPlayerHUDAndHPBar: ; 3ce25 (f:4e25)
call PlaceString
ld hl, wBattleMonSpecies
ld de, wLoadedMon
- ld bc, $c
+ ld bc, wBattleMonDVs - wBattleMonSpecies
call CopyData
ld hl, wBattleMonLevel
ld de, wLoadedMonLevel
- ld bc, $b
+ ld bc, wBattleMonPP - wBattleMonLevel
call CopyData
coord hl, 14, 8
push hl
@@ -2171,7 +2171,7 @@ DisplayBattleMenu: ; 3cf78 (f:4f78)
call SaveScreenTilesToBuffer1
.nonstandardbattle
ld a, [wBattleType]
- cp $2 ; safari
+ cp BATTLE_TYPE_SAFARI
ld a, BATTLE_MENU_TEMPLATE
jr nz, .menuselected
ld a, SAFARI_BATTLE_MENU_TEMPLATE
@@ -2179,9 +2179,9 @@ DisplayBattleMenu: ; 3cf78 (f:4f78)
ld [wTextBoxID], a
call DisplayTextBoxID
ld a, [wBattleType]
- cp $1
+ cp BATTLE_TYPE_OLD_MAN
jr z, .doSimulatedMenuInput ; simulate menu input if it's the old man or prof. oak pikachu battle
- cp $4
+ cp BATTLE_TYPE_PIKACHU
jr z, .doSimulatedMenuInput
jp .handleBattleMenuInput
; the following happens for the old man tutorial and prof. oak pikachu battle
@@ -2234,7 +2234,7 @@ DisplayBattleMenu: ; 3cf78 (f:4f78)
jr .rightColumn
.leftColumn ; put cursor in left column of menu
ld a, [wBattleType]
- 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)
@@ -2267,7 +2267,7 @@ DisplayBattleMenu: ; 3cf78 (f:4f78)
jr .AButtonPressed ; the A button was pressed
.rightColumn ; put cursor in right column of menu
ld a, [wBattleType]
- 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)
@@ -2304,10 +2304,10 @@ DisplayBattleMenu: ; 3cf78 (f:4f78)
.AButtonPressed
call PlaceUnfilledArrowMenuCursor
ld a, [wBattleType]
- cp HURRY_RUN_AWAY_BATTLE
+ cp BATTLE_TYPE_RUN
jr z, .handleUnusedBattle
ld a, [wBattleType]
- cp SAFARI_BATTLE ; is it a Safari battle?
+ cp BATTLE_TYPE_SAFARI
ld a, [wCurrentMenuItem]
ld [wBattleAndStartSavedMenuItem], a
jr z, .handleMenuSelection
@@ -2329,7 +2329,7 @@ DisplayBattleMenu: ; 3cf78 (f:4f78)
jr nz, .upperLeftMenuItemWasNotSelected
; the upper left menu item was selected
ld a, [wBattleType]
- cp $2
+ cp BATTLE_TYPE_SAFARI
jr z, .throwSafariBallWasSelected
; the "FIGHT" menu was selected
xor a
@@ -2368,7 +2368,7 @@ DisplayBattleMenu: ; 3cf78 (f:4f78)
.notLinkBattle
call SaveScreenTilesToBuffer2
ld a, [wBattleType]
- cp $2 ; is it a safari battle?
+ cp BATTLE_TYPE_SAFARI
jr nz, BagWasSelected
; bait was selected
@@ -2386,9 +2386,9 @@ BagWasSelected: ; 3d10a (f:510a)
call DrawHUDsAndHPBars
.next
ld a, [wBattleType]
- cp OLD_MAN_BATTLE ; is it the old man tutorial?
+ cp BATTLE_TYPE_OLD_MAN ; is it the old man tutorial?
jr z, .simulatedInputBattle
- cp STARTER_PIKACHU_BATTLE ; is it the prof oak battle with pikachu?
+ cp BATTLE_TYPE_PIKACHU ; is it the prof oak battle with pikachu?
jr z, .simulatedInputBattle
jr DisplayPlayerBag
.simulatedInputBattle
@@ -2441,7 +2441,7 @@ UseBagItem: ; 3c162 (f:5162)
xor a
ld [wCurrentMenuItem], a
ld a, [wBattleType]
- cp SAFARI_BATTLE ; is it a safari battle?
+ cp BATTLE_TYPE_SAFARI
jr z, .checkIfMonCaptured
ld a, [wActionResultOrTookBattleTurn]
@@ -2463,7 +2463,7 @@ UseBagItem: ; 3c162 (f:5162)
jr nz, .returnAfterCapturingMon
ld a, [wBattleType]
- cp SAFARI_BATTLE ; is it a safari battle?
+ cp BATTLE_TYPE_SAFARI
jr z, .returnAfterUsingItem_NoCapture
; not a safari battle
call LoadScreenTilesFromBuffer1
@@ -2494,7 +2494,7 @@ PartyMenuOrRockOrRun: ; 3d1cd (f:51cd)
; party menu or rock was selected
call SaveScreenTilesToBuffer2
ld a, [wBattleType]
- cp $2 ; is it a safari battle?
+ cp BATTLE_TYPE_SAFARI
jr nz, .partyMenuWasSelected
; safari battle
ld a, SAFARI_ROCK
@@ -3626,7 +3626,7 @@ CheckPlayerStatusConditions: ; 3d9c6 (f:59c6)
ld a,[wPlayerBattleStatus1]
add a ; is player confused?
jr nc,.TriedToUseDisabledMoveCheck
- ld hl,W_PLAYERCONFUSEDCOUNTER
+ ld hl,wPlayerConfusedCounter
dec [hl]
jr nz,.IsConfused
ld hl,wPlayerBattleStatus1
@@ -3764,7 +3764,7 @@ CheckPlayerStatusConditions: ; 3d9c6 (f:59c6)
and a,3
inc a
inc a ; confused for 2-5 turns
- ld [W_PLAYERCONFUSEDCOUNTER],a
+ ld [wPlayerConfusedCounter],a
pop hl ; skip DecrementPP
jp .returnToHL
@@ -6126,7 +6126,7 @@ CheckEnemyStatusConditions: ; 3ea15 (f:6a15)
ld a, [wEnemyBattleStatus1]
add a ; check if enemy mon is confused
jp nc, .checkIfTriedToUseDisabledMove
- ld hl, W_ENEMYCONFUSEDCOUNTER
+ ld hl, wEnemyConfusedCounter
dec [hl]
jr nz, .isConfused
ld hl, wEnemyBattleStatus1
@@ -6298,7 +6298,7 @@ CheckEnemyStatusConditions: ; 3ea15 (f:6a15)
and $3
inc a
inc a ; confused for 2-5 turns
- ld [W_ENEMYCONFUSEDCOUNTER], a
+ ld [wEnemyConfusedCounter], a
pop hl ; skip DecrementPP
jp .enemyReturnToHL
.checkIfUsingMultiturnMove
@@ -6576,10 +6576,10 @@ SwapPlayerAndEnemyLevels: ; 3ee07 (f:6e07)
LoadPlayerBackPic: ; 3ee18 (f:6e18)
ld a, [wBattleType]
ld de, OldManPic
- cp OLD_MAN_BATTLE ; is it the old man tutorial?
+ cp BATTLE_TYPE_OLD_MAN ; is it the old man tutorial?
jr z, .next
ld de, ProfOakPicBack
- cp STARTER_PIKACHU_BATTLE ; is it the pikachu battle at the beginning of the game?
+ cp BATTLE_TYPE_PIKACHU ; is it the pikachu battle at the beginning of the game?
jr z, .next
ld de, RedPicBack
.next
@@ -6624,7 +6624,7 @@ LoadPlayerBackPic: ; 3ee18 (f:6e18)
ld a, $0
call SwitchSRAMBankAndLatchClockData
ld hl, vSprites
- ld de, S_SPRITEBUFFER1
+ ld de, sSpriteBuffer1
ld a, [H_LOADEDROMBANK]
ld b, a
ld c, 7 * 7
@@ -8292,11 +8292,11 @@ ConfusionSideEffectSuccess: ; 3f94a (f:794a)
ld a, [H_WHOSETURN]
and a
ld hl, wEnemyBattleStatus1
- ld bc, W_ENEMYCONFUSEDCOUNTER
+ ld bc, wEnemyConfusedCounter
ld a, [wPlayerMoveEffect]
jr z, .confuseTarget
ld hl, wPlayerBattleStatus1
- ld bc, W_PLAYERCONFUSEDCOUNTER
+ ld bc, wPlayerConfusedCounter
ld a, [wEnemyMoveEffect]
.confuseTarget
bit Confused, [hl] ; is mon confused?
diff --git a/engine/battle/init_battle_variables.asm b/engine/battle/init_battle_variables.asm
index 8c43e8f8..74ea3814 100644
--- a/engine/battle/init_battle_variables.asm
+++ b/engine/battle/init_battle_variables.asm
@@ -32,7 +32,7 @@ InitBattleVariables: ; f6236 (3d:6236)
jr c, .notSafariBattle
cp SAFARI_ZONE_REST_HOUSE_1
jr nc, .notSafariBattle
- ld a, $2 ; safari battle
+ ld a, BATTLE_TYPE_SAFARI
ld [wBattleType], a
.notSafariBattle
jpab PlayBattleMusic
diff --git a/engine/battle/moveEffects/pay_day_effect.asm b/engine/battle/moveEffects/pay_day_effect.asm
index 2fa6b53f..0236e3e4 100644
--- a/engine/battle/moveEffects/pay_day_effect.asm
+++ b/engine/battle/moveEffects/pay_day_effect.asm
@@ -1,4 +1,4 @@
-PayDayEffect_ ; f6511 (3d:6511)
+PayDayEffect_: ; f6511 (3d:6511)
xor a
ld hl, wcd6d
ld [hli], a
diff --git a/engine/battle/scale_sprites.asm b/engine/battle/scale_sprites.asm
index 03495c82..c829fa13 100644
--- a/engine/battle/scale_sprites.asm
+++ b/engine/battle/scale_sprites.asm
@@ -9,12 +9,12 @@ ScaleSpriteByTwo: ; 2fd79 (b:7d79)
ret
ScaleSpriteByTwo_: ; 2fd85 (b:7d85)
- ld de, S_SPRITEBUFFER1 + (4*4*8) - 5 ; last byte of input data, last 4 rows already skipped
- ld hl, S_SPRITEBUFFER0 + SPRITEBUFFERSIZE - 1 ; end of destination buffer
+ ld de, sSpriteBuffer1 + (4*4*8) - 5 ; last byte of input data, last 4 rows already skipped
+ ld hl, sSpriteBuffer0 + SPRITEBUFFERSIZE - 1 ; end of destination buffer
call ScaleLastSpriteColumnByTwo ; last tile column is special case
call ScaleFirstThreeSpriteColumnsByTwo ; scale first 3 tile columns
- ld de, S_SPRITEBUFFER2 + (4*4*8) - 5 ; last byte of input data, last 4 rows already skipped
- ld hl, S_SPRITEBUFFER1 + SPRITEBUFFERSIZE - 1 ; end of destination buffer
+ ld de, sSpriteBuffer2 + (4*4*8) - 5 ; last byte of input data, last 4 rows already skipped
+ ld hl, sSpriteBuffer1 + SPRITEBUFFERSIZE - 1 ; end of destination buffer
call ScaleLastSpriteColumnByTwo ; last tile column is special case
ScaleFirstThreeSpriteColumnsByTwo: ; 2fd9a (b:7d9a)
diff --git a/engine/diploma_3a.asm b/engine/diploma_3a.asm
index 520d9f96..f85cc288 100755
--- a/engine/diploma_3a.asm
+++ b/engine/diploma_3a.asm
@@ -91,12 +91,12 @@ Func_e9ad3:
coord hl, 2, 15
call PlaceString
coord hl, 12, 15
- ld de, wPlayTimeHours + 1
+ ld de, wPlayTimeHours
lb bc, $40 | 1, 3
call PrintNumber
ld [hl], $16
inc hl
- ld de, wPlayTimeMinutes + 1
+ ld de, wPlayTimeMinutes
lb bc, $80 | 1, 2
call PrintNumber
ld a, [wNumSetBits]
diff --git a/engine/hall_of_fame.asm b/engine/hall_of_fame.asm
index ee138737..c8e6de3b 100755
--- a/engine/hall_of_fame.asm
+++ b/engine/hall_of_fame.asm
@@ -202,8 +202,8 @@ HoFLoadPlayerPics: ; 70390 (1c:433e)
call UncompressSpriteFromDE
ld a,$0
call SwitchSRAMBankAndLatchClockData
- ld hl, S_SPRITEBUFFER1
- ld de, S_SPRITEBUFFER0
+ ld hl, sSpriteBuffer1
+ ld de, sSpriteBuffer0
ld bc, $310
call CopyData
call PrepareRTCDataAndDisableSRAM
@@ -238,12 +238,12 @@ HoFDisplayPlayerStats: ; 703d1 (1c:43d1)
ld de, HoFPlayTimeText
call PlaceString
coord hl, 5, 7
- ld de, wPlayTimeHours + 1
+ ld de, wPlayTimeHours
lb bc, 1, 3
call PrintNumber
ld [hl], $6d
inc hl
- ld de, wPlayTimeMinutes + 1
+ ld de, wPlayTimeMinutes
lb bc, LEADING_ZEROES | 1, 2
call PrintNumber
coord hl, 1, 9
diff --git a/engine/hidden_object_functions17.asm b/engine/hidden_object_functions17.asm
index 58838434..7753cad1 100755
--- a/engine/hidden_object_functions17.asm
+++ b/engine/hidden_object_functions17.asm
@@ -1,4 +1,4 @@
-PrintRedsNESText: ; 5dbae (17:5bae)
+PrintRedSNESText: ; 5dbae (17:5bae)
call EnableAutoTextBoxDrawing
tx_pre_jump RedBedroomSNESText
@@ -11,7 +11,7 @@ OpenRedsPC: ; 5db86 (17:5b86)
tx_pre_jump RedBedroomPCText
RedBedroomPCText: ; 5db8e (17:5b8e)
- db $fc ; FuncTX_ItemStoragePC
+ TX_PLAYERS_PC
Route15GateLeftBinoculars: ; 5db8f (17:5b8f)
ld a, [wPlayerFacingDirection]
@@ -122,7 +122,7 @@ LinkCableHelp: ; 5dc29 (17:5c29)
ld hl, LinkCableHelpText1
call PrintText
xor a
- ld [wAnimationID], a
+ ld [wMenuItemOffset], a
ld [wCurrentMenuItem], a
ld [wLastMenuItem], a
ld a, A_BUTTON | B_BUTTON
@@ -205,7 +205,7 @@ ViridianSchoolBlackboard: ; 5dced (17:5ced)
ld hl, ViridianSchoolBlackboardText1
call PrintText
xor a
- ld [wAnimationID], a
+ ld [wMenuItemOffset], a
ld [wCurrentMenuItem], a
ld [wLastMenuItem], a
ld a, D_LEFT | D_RIGHT | A_BUTTON | B_BUTTON
@@ -242,8 +242,8 @@ ViridianSchoolBlackboard: ; 5dced (17:5ced)
ld [wTopMenuItemY], a
ld a, $6
ld [wTopMenuItemX], a
- ld a, $3
- ld [wAnimationID], 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
@@ -256,7 +256,7 @@ ViridianSchoolBlackboard: ; 5dced (17:5ced)
ld a, $1
ld [wTopMenuItemX], a
xor a
- ld [wAnimationID], a
+ ld [wMenuItemOffset], a
jr .blackboardLoop
.didNotPressLeftOrRight
ld a, [wCurrentMenuItem]
@@ -306,7 +306,7 @@ StatusAilmentText2: ; 5ddbb (17:5dbb)
ViridianBlackboardStatusPointers: ; 5ddcc (17:5ddc)
dw ViridianBlackboardSleepText
dw ViridianBlackboardPoisonText
- dw ViridianBlackbaordPrlzText
+ dw ViridianBlackboardPrlzText
dw ViridianBlackboardBurnText
dw ViridianBlackboardFrozenText
@@ -318,8 +318,8 @@ ViridianBlackboardPoisonText: ; 5dddb (17:5ddb)
TX_FAR _ViridianBlackboardPoisonText
db "@"
-ViridianBlackbaordPrlzText: ; 5dde0 (17:5de0)
- TX_FAR _ViridianBlackbaordPrlzText
+ViridianBlackboardPrlzText: ; 5dde0 (17:5de0)
+ TX_FAR _ViridianBlackboardPrlzText
db "@"
ViridianBlackboardBurnText: ; 5dde5 (17:5de5)
@@ -366,7 +366,7 @@ GymTrashScript: ; 5ddfc (17:5dfc)
; Next can is trying for the second switch.
SetEvent EVENT_1ST_LOCK_OPENED
callab Yellow_SampleSecondTrashCan
- tx_pre_id VermilionGymTrashSuccesText1
+ tx_pre_id VermilionGymTrashSuccessText1
jr .done
.trySecondLock
@@ -392,10 +392,10 @@ GymTrashScript: ; 5ddfc (17:5dfc)
.openSecondLock
; Completed the trash can puzzle.
SetEvent EVENT_2ND_LOCK_OPENED
- ld hl, wd126
+ ld hl, wCurrentMapScriptFlags
set 6, [hl]
- tx_pre_id VermilionGymTrashSuccesText3
+ tx_pre_id VermilionGymTrashSuccessText3
.done
jp PrintPredefTextID
@@ -425,8 +425,8 @@ GymTrashCans: ; 5de7d (17:5e7d)
db 2, 11, 13, -1, -1 ; 14
; 5dec8
-VermilionGymTrashSuccesText1: ; 5dec8 (17:5ec8)
- TX_FAR _VermilionGymTrashSuccesText1
+VermilionGymTrashSuccessText1: ; 5dec8 (17:5ec8)
+ TX_FAR _VermilionGymTrashSuccessText1
TX_ASM
call WaitForSoundToFinish
ld a, SFX_SWITCH
@@ -435,8 +435,8 @@ VermilionGymTrashSuccesText1: ; 5dec8 (17:5ec8)
jp TextScriptEnd
; unused
-VermilionGymTrashSuccesText2: ; 5dedb (17:5edb)
- TX_FAR _VermilionGymTrashSuccesText2
+VermilionGymTrashSuccessText2: ; 5dedb (17:5edb)
+ TX_FAR _VermilionGymTrashSuccessText2
db "@"
; unused
@@ -448,8 +448,8 @@ VermilionGymTrashSuccesPlaySfx: ; 5dee0 (17:5ee0)
call WaitForSoundToFinish
jp TextScriptEnd
-VermilionGymTrashSuccesText3: ; 5deef (17:5eef)
- TX_FAR _VermilionGymTrashSuccesText3
+VermilionGymTrashSuccessText3: ; 5deef (17:5eef)
+ TX_FAR _VermilionGymTrashSuccessText3
TX_ASM
call WaitForSoundToFinish
ld a, SFX_GO_INSIDE
diff --git a/engine/hidden_object_functions7.asm b/engine/hidden_object_functions7.asm
index 6e232664..4867b447 100755
--- a/engine/hidden_object_functions7.asm
+++ b/engine/hidden_object_functions7.asm
@@ -22,9 +22,10 @@ DisplayOakLabRightPoster: ; 1e2fe (7:62fe)
ld a, [wNumSetBits]
cp 2
tx_pre_id SaveOptionText
- jr c, .ownOneMon
+ jr c, .ownLessThanTwo
+ ; own two or more mon
tx_pre_id StrengthsAndWeaknessesText
-.ownOneMon
+.ownLessThanTwo
jp PrintPredefTextID
SaveOptionText: ; 1e317 (7:6317)
@@ -209,7 +210,7 @@ CinnabarGymQuiz_1ea92: ; 1e43a (7:643a)
ld a, [wCurrentMenuItem]
cp c
jr nz, .wrongAnswer
- ld hl, wd126
+ ld hl, wCurrentMapScriptFlags
set 5, [hl]
ld a, [hGymGateIndex]
ld [$ffe0], a
@@ -434,7 +435,7 @@ BillsHousePokemonList: ; 1e5dc (7:65dc)
ld hl, BillsHousePokemonListText1
call PrintText
xor a
- ld [wAnimationID], a
+ ld [wMenuItemOffset], a
ld [wCurrentMenuItem], a
ld [wLastMenuItem], a
ld a, A_BUTTON | B_BUTTON
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
diff --git a/engine/menu/link_menu.asm b/engine/menu/link_menu.asm
index becefd47..4d0beb7e 100644
--- a/engine/menu/link_menu.asm
+++ b/engine/menu/link_menu.asm
@@ -776,7 +776,7 @@ LinkMenu: ; f580c (3d:580c)
call DelayFrames
ld hl, wd732
res 1, [hl]
- ld a, [wAnimationID]
+ ld a, [wDefaultMap]
ld [wDestinationMap], a
callab SpecialWarpIn
ld c, 20
diff --git a/engine/menu/main_menu.asm b/engine/menu/main_menu.asm
index fb3fb6b9..669b2ba8 100755
--- a/engine/menu/main_menu.asm
+++ b/engine/menu/main_menu.asm
@@ -20,7 +20,7 @@ MainMenu: ; 5ba6 (1:5ba6)
ld [hli],a
ld [hli],a
ld [hl],a
- ld [wAnimationID],a
+ ld [wDefaultMap],a
ld hl,wd72e
res 6,[hl]
call ClearScreen
@@ -88,7 +88,7 @@ MainMenu: ; 5ba6 (1:5ba6)
jp .mainMenuLoop
.choseContinue
call DisplayContinueGameInfo
- ld hl,wd126
+ ld hl,wCurrentMapScriptFlags
set 5,[hl]
.inputLoop
xor a
@@ -247,12 +247,12 @@ PrintNumOwnedMons: ; 5daa (1:5daa)
jp PrintNumber
PrintPlayTime: ; 5dbd (1:5dbd)
- ld de, wPlayTimeHours + 1
+ ld de, wPlayTimeHours
lb bc, 1, 3
call PrintNumber
ld [hl], $6d
inc hl
- ld de, wPlayTimeMinutes + 1
+ ld de, wPlayTimeMinutes
lb bc, LEADING_ZEROES | 1, 2
jp PrintNumber
diff --git a/engine/menu/naming_screen.asm b/engine/menu/naming_screen.asm
index de0c696c..0eacc8f6 100755
--- a/engine/menu/naming_screen.asm
+++ b/engine/menu/naming_screen.asm
@@ -164,7 +164,7 @@ DisplayNamingScreen: ; 6307 (1:6307)
call RunDefaultPaletteCommand
call GBPalNormal
xor a
- ld [wSubAnimTransform], a
+ ld [wAnimCounter], a
ld hl, wd730
res 6, [hl]
ld a, [wIsInBattle]
diff --git a/engine/menu/start_sub_menus.asm b/engine/menu/start_sub_menus.asm
index e2491253..792903b7 100755
--- a/engine/menu/start_sub_menus.asm
+++ b/engine/menu/start_sub_menus.asm
@@ -163,7 +163,7 @@ StartMenu_Pokemon: ; 11c36 (4:5c36)
.surf ; 11d66 (4:5d66)
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]
@@ -618,12 +618,12 @@ DrawTrainerInfo: ; 1204c (4:604c)
ld c,$e3
call PrintBCDNumber
coord hl, 9, 6
- ld de,wPlayTimeHours + 1 ; hours
+ ld de,wPlayTimeHours ; hours
lb bc, LEFT_ALIGN | 1, 3
call PrintNumber
ld [hl],$d6 ; colon tile ID
inc hl
- ld de,wPlayTimeMinutes + 1 ; minutes
+ ld de,wPlayTimeMinutes ; minutes
lb bc, LEADING_ZEROES | 1, 2
jp PrintNumber
diff --git a/engine/oak_speech.asm b/engine/oak_speech.asm
index 925ff913..2726c651 100755
--- a/engine/oak_speech.asm
+++ b/engine/oak_speech.asm
@@ -56,7 +56,7 @@ OakSpeech: ; 5e85 (1:5e85)
ld a,1
ld [wItemQuantity],a
call AddItemToInventory ; give one potion
- ld a,[wAnimationID]
+ ld a,[wDefaultMap]
ld [wDestinationMap],a
call SpecialWarpIn
xor a
@@ -225,8 +225,8 @@ IntroDisplayPicCenteredOrUpperRight: ; 6010 (1:6010)
call UncompressSpriteFromDE
ld a, $0
call SwitchSRAMBankAndLatchClockData
- ld hl,S_SPRITEBUFFER1
- ld de,S_SPRITEBUFFER0
+ ld hl,sSpriteBuffer1
+ ld de,sSpriteBuffer0
ld bc,$310
call CopyData
call PrepareRTCDataAndDisableSRAM
diff --git a/engine/oak_speech2.asm b/engine/oak_speech2.asm
index 37c998a9..5eeb5ea9 100755
--- a/engine/oak_speech2.asm
+++ b/engine/oak_speech2.asm
@@ -226,9 +226,16 @@ GetDefaultName: ; 6858 (1:6858)
jp CopyData
DefaultNamesPlayerList: ; 687d (1:687d)
- db "NEW NAME@YELLOW@ASH@JACK@"
+ db "NEW NAME@"
+ db "YELLOW@"
+ db "ASH@"
+ db "JACK@"
+
DefaultNamesRivalList: ; 688d (1:688d)
- db "NEW NAME@BLUE@GARY@JOHN@"
+ db "NEW NAME@"
+ db "BLUE@"
+ db "GARY@"
+ db "JOHN@"
TextTerminator_6b20: ; 68a5 (1:68a5)
db "@"
diff --git a/engine/overworld/card_key.asm b/engine/overworld/card_key.asm
index 62d1d4fb..3560c8e8 100755
--- a/engine/overworld/card_key.asm
+++ b/engine/overworld/card_key.asm
@@ -50,7 +50,7 @@ PrintCardKeyText: ; 525d8 (14:65d8)
.replaceCardKeyDoorTileBlock
ld [wNewTileBlockID], a
predef ReplaceTileBlock
- ld hl, wd126
+ ld hl, wCurrentMapScriptFlags
set 5, [hl]
ld a, SFX_GO_INSIDE
jp PlaySound
diff --git a/engine/overworld/cinnabar_lab.asm b/engine/overworld/cinnabar_lab.asm
index f81324e0..f7c5e326 100755
--- a/engine/overworld/cinnabar_lab.asm
+++ b/engine/overworld/cinnabar_lab.asm
@@ -48,9 +48,9 @@ GiveFossilToCinnabarLab: ; 61006 (18:5006)
.choseDomeFossil
ld b, KABUTO
.fossilSelected
- ld [W_FOSSILITEM], a
+ ld [wFossilItem], a
ld a, b
- ld [W_FOSSILMON], a
+ ld [wFossilMon], a
call LoadFossilItemAndMonName
ld hl, LabFossil_610ae
call PrintText
@@ -60,7 +60,7 @@ GiveFossilToCinnabarLab: ; 61006 (18:5006)
jr nz, .cancelledGivingFossil
ld hl, LabFossil_610b3
call PrintText
- ld a, [W_FOSSILITEM]
+ ld a, [wFossilItem]
ld [hItemToRemoveID], a
callba RemoveItemByID
ld hl, LabFossil_610b8
@@ -113,11 +113,11 @@ PrintFossilsInBag: ; 610c2 (18:50c2)
; loads the names of the fossil item and the resulting mon
LoadFossilItemAndMonName: ; 610eb (18:50eb)
- ld a, [W_FOSSILMON]
+ ld a, [wFossilMon]
ld [wd11e], a
call GetMonName
call CopyStringToCF4B
- ld a, [W_FOSSILITEM]
+ ld a, [wFossilItem]
ld [wd11e], a
call GetItemName
ret
diff --git a/engine/overworld/movement.asm b/engine/overworld/movement.asm
index 5f929ce3..d69e2fbc 100644
--- a/engine/overworld/movement.asm
+++ b/engine/overworld/movement.asm
@@ -118,8 +118,8 @@ UpdateNPCSprite: ; 4e3e (1:4e3e)
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
@@ -156,7 +156,7 @@ UpdateNPCSprite: ; 4e3e (1:4e3e)
call LoadDEPlusA ; a = [wNPCMovementDirections + movement byte 1]
cp $e0
jp z, ChangeFacingDirection
- cp $ff
+ cp STAY
jr nz, .next
; reached end of wNPCMovementDirections list
ld [hl], a ; store $ff in movement byte 1, disabling scripted movement
@@ -167,7 +167,7 @@ UpdateNPCSprite: ; 4e3e (1:4e3e)
ld [wWastedByteCD3A], a
ret
.next
- cp $fe
+ cp WALK
jr nz, .asm_4ecb
; current NPC movement data is $fe. this seems buggy
ld [hl], $1 ; set movement byte 1 to $1
@@ -359,7 +359,11 @@ notYetMoving: ; 4fc5 (1:4fc5)
ld [hl], $0 ; c1x8 = 0 (walk animation frame)
jp UpdateSpriteImage
-InitializeSpriteFacingDirection: ; 4fd1 (1:4fd1)
+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
diff --git a/engine/overworld/special_warps.asm b/engine/overworld/special_warps.asm
index 29000d98..8c1b4159 100644
--- a/engine/overworld/special_warps.asm
+++ b/engine/overworld/special_warps.asm
@@ -69,7 +69,7 @@ LoadSpecialWarpData: ; 6073 (1:6073)
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
diff --git a/engine/pikachu_pic_animation.asm b/engine/pikachu_pic_animation.asm
index 1d91150e..be31e7d7 100755
--- a/engine/pikachu_pic_animation.asm
+++ b/engine/pikachu_pic_animation.asm
@@ -664,10 +664,10 @@ DecompressRequestPikaPicAnimGFX: ; fe128
jr c, .failed
ld a, b
call UncompressSpriteFromDE
- ld a, BANK(S_SPRITEBUFFER1)
+ ld a, BANK(sSpriteBuffer1)
call SwitchSRAMBankAndLatchClockData
- ld hl, S_SPRITEBUFFER1
- ld de, S_SPRITEBUFFER0
+ ld hl, sSpriteBuffer1
+ ld de, sSpriteBuffer0
ld bc, SPRITEBUFFERSIZE * 2
call CopyData
call PrepareRTCDataAndDisableSRAM
diff --git a/engine/predefs7.asm b/engine/predefs7.asm
index 9138897f..1bf4c018 100755
--- a/engine/predefs7.asm
+++ b/engine/predefs7.asm
@@ -25,7 +25,7 @@ DisplayElevatorFloorMenu: ; 1c264 (7:4264)
ld a, b
ld [wListScrollOffset], a
ret c
- ld hl, wd126
+ ld hl, wCurrentMapScriptFlags
set 7, [hl]
ld hl, wElevatorWarpMaps
ld a, [wWhichPokemon]
diff --git a/engine/titlescreen.asm b/engine/titlescreen.asm
index 74374dcf..8da93f17 100755
--- a/engine/titlescreen.asm
+++ b/engine/titlescreen.asm
@@ -362,7 +362,7 @@ IncrementResetCounter: ; 4405 (1:4405)
FillSpriteBuffer0WithAA: ; 4418 (1:4418)
xor a
call SwitchSRAMBankAndLatchClockData
- ld hl, S_SPRITEBUFFER0
+ ld hl, sSpriteBuffer0
ld bc, $20
ld a, $aa
call FillMemory
diff --git a/engine/town_map.asm b/engine/town_map.asm
index 82e24d75..47812db0 100755
--- a/engine/town_map.asm
+++ b/engine/town_map.asm
@@ -454,8 +454,12 @@ WritePlayerOrBirdSpriteOAM: ; 712f6 (1c:52f6)
WriteTownMapSpriteOAM: ; 71302 (1c:5302)
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