summaryrefslogtreecommitdiff
path: root/engine/overworld/events.asm
diff options
context:
space:
mode:
Diffstat (limited to 'engine/overworld/events.asm')
-rw-r--r--engine/overworld/events.asm853
1 files changed, 690 insertions, 163 deletions
diff --git a/engine/overworld/events.asm b/engine/overworld/events.asm
index cc2c8c574..e4defbc2b 100644
--- a/engine/overworld/events.asm
+++ b/engine/overworld/events.asm
@@ -3,7 +3,7 @@ INCLUDE "constants.asm"
SECTION "Events", ROMX
-OverworldLoop:: ; 966b0
+OverworldLoop::
xor a
ld [wMapStatus], a
.loop
@@ -21,99 +21,83 @@ OverworldLoop:: ; 966b0
dw EnterMap
dw HandleMap
dw .done
-; 966cb
-DisableEvents: ; 966cb
+DisableEvents:
xor a
ld [wScriptFlags3], a
ret
-; 966d0
-EnableEvents:: ; 966d0
+EnableEvents::
ld a, $ff
ld [wScriptFlags3], a
ret
-; 966d6
-CheckBit5_ScriptFlags3: ; 966d6
+CheckBit5_ScriptFlags3:
ld hl, wScriptFlags3
bit 5, [hl]
ret
-; 966dc
-DisableWarpsConnxns: ; 966dc
+DisableWarpsConnxns:
ld hl, wScriptFlags3
res 2, [hl]
ret
-; 966e2
-DisableCoordEvents: ; 966e2
+DisableCoordEvents:
ld hl, wScriptFlags3
res 1, [hl]
ret
-; 966e8
-DisableStepCount: ; 966e8
+DisableStepCount:
ld hl, wScriptFlags3
res 0, [hl]
ret
-; 966ee
-DisableWildEncounters: ; 966ee
+DisableWildEncounters:
ld hl, wScriptFlags3
res 4, [hl]
ret
-; 966f4
-EnableWarpsConnxns: ; 966f4
+EnableWarpsConnxns:
ld hl, wScriptFlags3
set 2, [hl]
ret
-; 966fa
-EnableCoordEvents: ; 966fa
+EnableCoordEvents:
ld hl, wScriptFlags3
set 1, [hl]
ret
-; 96700
-EnableStepCount: ; 96700
+EnableStepCount:
ld hl, wScriptFlags3
set 0, [hl]
ret
-; 96706
-EnableWildEncounters: ; 96706
+EnableWildEncounters:
ld hl, wScriptFlags3
set 4, [hl]
ret
-; 9670c
-CheckWarpConnxnScriptFlag: ; 9670c
+CheckWarpConnxnScriptFlag:
ld hl, wScriptFlags3
bit 2, [hl]
ret
-; 96712
-CheckCoordEventScriptFlag: ; 96712
+CheckCoordEventScriptFlag:
ld hl, wScriptFlags3
bit 1, [hl]
ret
-; 96718
-CheckStepCountScriptFlag: ; 96718
+CheckStepCountScriptFlag:
ld hl, wScriptFlags3
bit 0, [hl]
ret
-; 9671e
-CheckWildEncountersScriptFlag: ; 9671e
+CheckWildEncountersScriptFlag:
ld hl, wScriptFlags3
bit 4, [hl]
ret
-; 96724
-StartMap: ; 96724
+StartMap:
xor a
ld [wScriptVar], a
xor a
@@ -123,7 +107,7 @@ StartMap: ; 96724
call ByteFill
farcall InitCallReceiveDelay
call ClearJoypad
-EnterMap: ; 9673e
+EnterMap:
xor a
ld [wXYComparePointer], a
ld [wXYComparePointer + 1], a
@@ -149,15 +133,13 @@ EnterMap: ; 9673e
ld a, 2 ; HandleMap
ld [wMapStatus], a
ret
-; 9676d
-UnusedWait30Frames: ; 9676d
+UnusedWait30Frames:
ld c, 30
call DelayFrames
ret
-; 96773
-HandleMap: ; 96773
+HandleMap:
call ResetOverworldDelay
call HandleMapTimeAndJoypad
farcall HandleCmdQueue ; no need to farcall
@@ -173,9 +155,8 @@ HandleMap: ; 96773
call HandleMapBackground
call CheckPlayerState
ret
-; 96795
-MapEvents: ; 96795
+MapEvents:
ld a, [wMapEventStatus]
ld hl, .jumps
rst JumpTable
@@ -184,39 +165,33 @@ MapEvents: ; 96795
.jumps
dw .events
dw .no_events
-; 967a1
-.events ; 967a1
+.events
call PlayerEvents
call DisableEvents
farcall ScriptEvents
ret
-; 967ae
-.no_events ; 967ae
+.no_events
ret
-; 967af
-MaxOverworldDelay: ; 967af
+MaxOverworldDelay:
db 2
-; 967b0
-ResetOverworldDelay: ; 967b0
+ResetOverworldDelay:
ld a, [MaxOverworldDelay]
ld [wOverworldDelay], a
ret
-; 967b7
-NextOverworldFrame: ; 967b7
+NextOverworldFrame:
ld a, [wOverworldDelay]
and a
ret z
ld c, a
call DelayFrames
ret
-; 967c1
-HandleMapTimeAndJoypad: ; 967c1
+HandleMapTimeAndJoypad:
ld a, [wMapEventStatus]
cp 1 ; no events
ret z
@@ -225,23 +200,20 @@ HandleMapTimeAndJoypad: ; 967c1
call GetJoypad
call TimeOfDayPals
ret
-; 967d1
-HandleMapObjects: ; 967d1
+HandleMapObjects:
farcall HandleNPCStep ; engine/map_objects.asm
farcall _HandlePlayerStep
call _CheckObjectEnteringVisibleRange
ret
-; 967e1
-HandleMapBackground: ; 967e1
+HandleMapBackground:
farcall _UpdateSprites
farcall ScrollScreen
farcall PlaceMapNameSign
ret
-; 967f4
-CheckPlayerState: ; 967f4
+CheckPlayerState:
ld a, [wPlayerStepFlags]
bit 5, a ; in the middle of step
jr z, .events
@@ -259,17 +231,15 @@ CheckPlayerState: ; 967f4
ld a, 1 ; no events
ld [wMapEventStatus], a
ret
-; 96812
-_CheckObjectEnteringVisibleRange: ; 96812
+_CheckObjectEnteringVisibleRange:
ld hl, wPlayerStepFlags
bit 6, [hl]
ret z
farcall CheckObjectEnteringVisibleRange
ret
-; 9681f
-PlayerEvents: ; 9681f
+PlayerEvents:
xor a
; If there's already a player event, don't interrupt it.
ld a, [wScriptRunning]
@@ -318,9 +288,8 @@ PlayerEvents: ; 9681f
.ok2
scf
ret
-; 96867
-CheckTrainerBattle3: ; 96867
+CheckTrainerBattle3:
nop
nop
call CheckTrainerBattle2
@@ -333,9 +302,8 @@ CheckTrainerBattle3: ; 96867
.nope
xor a
ret
-; 96874
-CheckTileEvent: ; 96874
+CheckTileEvent:
; Check for warps, coord events, or wild battles.
call CheckWarpConnxnScriptFlag
@@ -399,9 +367,8 @@ CheckTileEvent: ; 96874
call GetMapScriptsBank
call CallScript
ret
-; 968c7
-CheckWildEncounterCooldown:: ; 968c7
+CheckWildEncounterCooldown::
ld hl, wWildEncounterCooldown
ld a, [hl]
and a
@@ -410,35 +377,30 @@ CheckWildEncounterCooldown:: ; 968c7
ret z
scf
ret
-; 968d1
-SetUpFiveStepWildEncounterCooldown: ; 968d1
+SetUpFiveStepWildEncounterCooldown:
ld a, 5
ld [wWildEncounterCooldown], a
ret
-; 968d7
-ret_968d7: ; 968d7
+ret_968d7:
ret
-;968d8
-SetMinTwoStepWildEncounterCooldown: ; 968d8
+SetMinTwoStepWildEncounterCooldown:
ld a, [wWildEncounterCooldown]
cp 2
ret nc
ld a, 2
ld [wWildEncounterCooldown], a
ret
-; 968e4
-Dummy_CheckScriptFlags3Bit5: ; 968e4
+Dummy_CheckScriptFlags3Bit5:
call CheckBit5_ScriptFlags3
ret z
call ret_2f3e
ret
-; 968ec
-RunSceneScript: ; 968ec
+RunSceneScript:
ld a, [wCurrMapSceneScriptCount]
and a
jr z, .nope
@@ -485,9 +447,8 @@ endr
.nope
xor a
ret
-; 9693a
-CheckTimeEvents: ; 9693a
+CheckTimeEvents:
ld a, [wLinkMode]
and a
jr nz, .nothing
@@ -517,16 +478,13 @@ CheckTimeEvents: ; 9693a
call CallScript
scf
ret
-; 96970
-.unused ; 96970
+.unused
ld a, 8
scf
ret
-; 96974
-
-OWPlayerInput: ; 96974
+OWPlayerInput:
call PlayerMovement
ret c
and a
@@ -552,9 +510,8 @@ OWPlayerInput: ; 96974
pop af
scf
ret
-; 96999
-CheckAPressOW: ; 96999
+CheckAPressOW:
ld a, [hJoyPressed]
and A_BUTTON
ret z
@@ -566,17 +523,15 @@ CheckAPressOW: ; 96999
ret c
xor a
ret
-; 969ac
-PlayTalkObject: ; 969ac
+PlayTalkObject:
push de
ld de, SFX_READ_TEXT_2
call PlaySFX
pop de
ret
-; 969b5
-TryObjectEvent: ; 969b5
+TryObjectEvent:
farcall CheckFacingObject
jr c, .IsObject
xor a
@@ -627,9 +582,8 @@ TryObjectEvent: ; 969b5
dbw OBJECTTYPE_5, .five
dbw OBJECTTYPE_6, .six
db -1
-; 96a04
-.script ; 96a04
+.script
ld hl, MAPOBJECT_SCRIPT_POINTER
add hl, bc
ld a, [hli]
@@ -638,9 +592,8 @@ TryObjectEvent: ; 969b5
call GetMapScriptsBank
call CallScript
ret
-; 96a12
-.itemball ; 96a12
+.itemball
ld hl, MAPOBJECT_SCRIPT_POINTER
add hl, bc
ld a, [hli]
@@ -653,36 +606,30 @@ TryObjectEvent: ; 969b5
ld a, PLAYEREVENT_ITEMBALL
scf
ret
-; 96a29
-.trainer ; 96a29
+.trainer
call TalkToTrainer
ld a, PLAYEREVENT_TALKTOTRAINER
scf
ret
-; 96a30
-.three ; 96a30
+.three
xor a
ret
-; 96a32
-.four ; 96a32
+.four
xor a
ret
-; 96a34
-.five ; 96a34
+.five
xor a
ret
-; 96a36
-.six ; 96a36
+.six
xor a
ret
-; 96a38
-TryBGEvent: ; 96a38
+TryBGEvent:
call CheckFacingBGEvent
jr c, .is_bg_event
xor a
@@ -704,7 +651,6 @@ TryBGEvent: ; 96a38
dw .ifnotset
dw .itemifset
dw .copy
-; 96a59
.up
ld b, OW_UP
@@ -784,9 +730,8 @@ TryBGEvent: ; 96a38
.dontread
xor a
ret
-; 96ad8
-CheckBGEventFlag: ; 96ad8
+CheckBGEventFlag:
ld hl, wEngineBuffer4
ld a, [hli]
ld h, [hl]
@@ -802,16 +747,14 @@ CheckBGEventFlag: ; 96ad8
and a
pop hl
ret
-; 96af0
-PlayerMovement: ; 96af0
+PlayerMovement:
farcall DoPlayerMovement
ld a, c
ld hl, .pointers
rst JumpTable
ld a, c
ret
-; 96afd
.pointers
dw .zero
@@ -824,34 +767,30 @@ PlayerMovement: ; 96af0
dw .seven
.zero
-.four ; 96b0d
+.four
xor a
ld c, a
ret
-; 96b10
-.seven ; 96b10
+.seven
call ret_968d7 ; mobile
xor a
ld c, a
ret
-; 96b16
-.one ; 96b16
+.one
ld a, 5
ld c, a
scf
ret
-; 96b1b
-.two ; 96b1b
+.two
ld a, 9
ld c, a
scf
ret
-; 96b20
-.three ; 96b20
+.three
; force the player to move in some direction
ld a, BANK(Script_ForcedMovement)
ld hl, Script_ForcedMovement
@@ -860,17 +799,15 @@ PlayerMovement: ; 96af0
ld c, a
scf
ret
-; 96b2b
.five
-.six ; 96b2b
+.six
ld a, -1
ld c, a
and a
ret
-; 96b30
-CheckMenuOW: ; 96b30
+CheckMenuOW:
xor a
ld [hMenuReturn], a
ld [hMenuReturn + 1], a
@@ -899,36 +836,30 @@ CheckMenuOW: ; 96b30
call CallScript
scf
ret
-; 96b58
-StartMenuScript: ; 96b58
+StartMenuScript:
callasm StartMenu
jump StartMenuCallback
-; 96b5f
-SelectMenuScript: ; 96b5f
+SelectMenuScript:
callasm SelectMenu
jump SelectMenuCallback
-; 96b66
StartMenuCallback:
-SelectMenuCallback: ; 96b66
+SelectMenuCallback:
copybytetovar hMenuReturn
ifequal HMENURETURN_SCRIPT, .Script
ifequal HMENURETURN_ASM, .Asm
end
-; 96b72
-.Script: ; 96b72
+.Script:
ptjump wQueuedScriptBank
-; 96b75
-.Asm: ; 96b75
+.Asm:
ptcallasm wQueuedScriptBank
end
-; 96b79
-CountStep: ; 96b79
+CountStep:
; Don't count steps in link communication rooms.
ld a, [wLinkMode]
and a
@@ -993,16 +924,14 @@ CountStep: ; 96b79
ld a, 8
scf
ret
-; 96bd3
; unused
-.unreferenced ; 96bd3
+.unreferenced
ld a, 7
scf
ret
-; 96bd7
-DoRepelStep: ; 96bd7
+DoRepelStep:
ld a, [wRepelEffect]
and a
ret z
@@ -1016,9 +945,8 @@ DoRepelStep: ; 96bd7
call CallScript
scf
ret
-; 96beb
-DoPlayerEvent: ; 96beb
+DoPlayerEvent:
ld a, [wScriptRunning]
and a
ret z
@@ -1042,9 +970,8 @@ DoPlayerEvent: ; 96beb
ld a, [hl]
ld [wScriptPos + 1], a
ret
-; 96c0c
-PlayerEventScriptPointers: ; 96c0c
+PlayerEventScriptPointers:
dba Invalid_0x96c2d ; 0
dba SeenByTrainerScript ; 1
dba TalkToTrainerScript ; 2
@@ -1056,56 +983,656 @@ PlayerEventScriptPointers: ; 96c0c
dba HatchEggScript ; 8
dba ChangeDirectionScript ; 9
dba Invalid_0x96c2d ; 10
-; 96c2d
-Invalid_0x96c2d: ; 96c2d
+Invalid_0x96c2d:
end
-; 96c2e
; unused
end
-; 96c2f
-HatchEggScript: ; 96c2f
+HatchEggScript:
callasm OverworldHatchEgg
end
-; 96c34
-WarpToNewMapScript: ; 96c34
+WarpToNewMapScript:
warpsound
newloadmap MAPSETUP_DOOR
end
-; 96c38
-FallIntoMapScript: ; 96c38
+FallIntoMapScript:
newloadmap MAPSETUP_FALL
playsound SFX_KINESIS
applymovement PLAYER, MovementData_0x96c48
playsound SFX_STRENGTH
scall LandAfterPitfallScript
end
-; 96c48
-MovementData_0x96c48: ; 96c48
+MovementData_0x96c48:
skyfall
step_end
-; 96c4a
-LandAfterPitfallScript: ; 96c4a
+LandAfterPitfallScript:
earthquake 16
end
-; 96c4d
EdgeWarpScript: ; 4
reloadandreturn MAPSETUP_CONNECTION
-; 96c4f
ChangeDirectionScript: ; 9
deactivatefacing 3
callasm EnableWildEncounters
end
-; 96c56
INCLUDE "engine/overworld/scripting.asm"
-INCLUDE "engine/overworld/events_2.asm"
+WarpToSpawnPoint::
+ ld hl, wStatusFlags2
+ res STATUSFLAGS2_SAFARI_GAME_F, [hl]
+ res STATUSFLAGS2_BUG_CONTEST_TIMER_F, [hl]
+ ret
+
+RunMemScript::
+; If there is no script here, we don't need to be here.
+ ld a, [wMapReentryScriptQueueFlag]
+ and a
+ ret z
+; Execute the script at (wMapReentryScriptBank):(wMapReentryScriptAddress).
+ ld hl, wMapReentryScriptAddress
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ ld a, [wMapReentryScriptBank]
+ call CallScript
+ scf
+; Clear the buffer for the next script.
+ push af
+ xor a
+ ld hl, wMapReentryScriptQueueFlag
+ ld bc, 8
+ call ByteFill
+ pop af
+ ret
+
+LoadScriptBDE::
+; If there's already a script here, don't overwrite.
+ ld hl, wMapReentryScriptQueueFlag
+ ld a, [hl]
+ and a
+ ret nz
+; Set the flag
+ ld [hl], 1
+ inc hl
+; Load the script pointer b:de into (wMapReentryScriptBank):(wMapReentryScriptAddress)
+ ld [hl], b
+ inc hl
+ ld [hl], e
+ inc hl
+ ld [hl], d
+ scf
+ ret
+
+TryTileCollisionEvent::
+ call GetFacingTileCoord
+ ld [wEngineBuffer1], a
+ ld c, a
+ farcall CheckFacingTileForStdScript
+ jr c, .done
+
+ call CheckCutTreeTile
+ jr nz, .whirlpool
+ farcall TryCutOW
+ jr .done
+
+.whirlpool
+ ld a, [wEngineBuffer1]
+ call CheckWhirlpoolTile
+ jr nz, .waterfall
+ farcall TryWhirlpoolOW
+ jr .done
+
+.waterfall
+ ld a, [wEngineBuffer1]
+ call CheckWaterfallTile
+ jr nz, .headbutt
+ farcall TryWaterfallOW
+ jr .done
+
+.headbutt
+ ld a, [wEngineBuffer1]
+ call CheckHeadbuttTreeTile
+ jr nz, .surf
+ farcall TryHeadbuttOW
+ jr c, .done
+ jr .noevent
+
+.surf
+ farcall TrySurfOW
+ jr nc, .noevent
+ jr .done
+
+.noevent
+ xor a
+ ret
+
+.done
+ call PlayClickSFX
+ ld a, $ff
+ scf
+ ret
+
+RandomEncounter::
+; Random encounter
+
+ call CheckWildEncounterCooldown
+ jr c, .nope
+ call CanUseSweetScent
+ jr nc, .nope
+ ld hl, wStatusFlags2
+ bit STATUSFLAGS2_BUG_CONTEST_TIMER_F, [hl]
+ jr nz, .bug_contest
+ farcall TryWildEncounter
+ jr nz, .nope
+ jr .ok
+
+.bug_contest
+ call _TryWildEncounter_BugContest
+ jr nc, .nope
+ jr .ok_bug_contest
+
+.nope
+ ld a, 1
+ and a
+ ret
+
+.ok
+ ld a, BANK(WildBattleScript)
+ ld hl, WildBattleScript
+ jr .done
+
+.ok_bug_contest
+ ld a, BANK(BugCatchingContestBattleScript)
+ ld hl, BugCatchingContestBattleScript
+ jr .done
+
+.done
+ call CallScript
+ scf
+ ret
+
+WildBattleScript:
+ randomwildmon
+ startbattle
+ reloadmapafterbattle
+ end
+
+CanUseSweetScent::
+ ld hl, wStatusFlags
+ bit STATUSFLAGS_NO_WILD_ENCOUNTERS_F, [hl]
+ jr nz, .no
+ ld a, [wEnvironment]
+ cp CAVE
+ jr z, .ice_check
+ cp DUNGEON
+ jr z, .ice_check
+ farcall CheckGrassCollision
+ jr nc, .no
+
+.ice_check
+ ld a, [wPlayerStandingTile]
+ call CheckIceTile
+ jr z, .no
+ scf
+ ret
+
+.no
+ and a
+ ret
+
+_TryWildEncounter_BugContest:
+ call TryWildEncounter_BugContest
+ ret nc
+ call ChooseWildEncounter_BugContest
+ farcall CheckRepelEffect
+ ret
+
+ChooseWildEncounter_BugContest::
+; Pick a random mon out of ContestMons.
+
+.loop
+ call Random
+ cp 100 << 1
+ jr nc, .loop
+ srl a
+
+ ld hl, ContestMons
+ ld de, 4
+.CheckMon:
+ sub [hl]
+ jr c, .GotMon
+ add hl, de
+ jr .CheckMon
+
+.GotMon:
+ inc hl
+
+; Species
+ ld a, [hli]
+ ld [wTempWildMonSpecies], a
+
+; Min level
+ ld a, [hli]
+ ld d, a
+
+; Max level
+ ld a, [hl]
+
+ sub d
+ jr nz, .RandomLevel
+
+; If min and max are the same.
+ ld a, d
+ jr .GotLevel
+
+.RandomLevel:
+; Get a random level between the min and max.
+ ld c, a
+ inc c
+ call Random
+ ld a, [hRandomAdd]
+ call SimpleDivide
+ add d
+
+.GotLevel:
+ ld [wCurPartyLevel], a
+
+ xor a
+ ret
+
+TryWildEncounter_BugContest:
+ ld a, [wPlayerStandingTile]
+ call CheckSuperTallGrassTile
+ ld b, 40 percent
+ jr z, .ok
+ ld b, 20 percent
+
+.ok
+ farcall ApplyMusicEffectOnEncounterRate
+ farcall ApplyCleanseTagEffectOnEncounterRate
+ call Random
+ ld a, [hRandomAdd]
+ cp b
+ ret c
+ ld a, 1
+ and a
+ ret
+
+INCLUDE "data/wild/bug_contest_mons.asm"
+
+DoBikeStep::
+ nop
+ nop
+ ; If the bike shop owner doesn't have our number, or
+ ; if we've already gotten the call, we don't have to
+ ; be here.
+ ld hl, wStatusFlags2
+ bit STATUSFLAGS2_BIKE_SHOP_CALL_F, [hl]
+ jr z, .NoCall
+
+ ; If we're not on the bike, we don't have to be here.
+ ld a, [wPlayerState]
+ cp PLAYER_BIKE
+ jr nz, .NoCall
+
+ ; If we're not in an area of phone service, we don't
+ ; have to be here.
+ call GetMapPhoneService
+ and a
+ jr nz, .NoCall
+
+ ; Check the bike step count and check whether we've
+ ; taken 65536 of them yet.
+ ld hl, wBikeStep
+ ld a, [hli]
+ ld d, a
+ ld e, [hl]
+ cp 255
+ jr nz, .increment
+ ld a, e
+ cp 255
+ jr z, .dont_increment
+
+.increment
+ inc de
+ ld [hl], e
+ dec hl
+ ld [hl], d
+
+.dont_increment
+ ; If we've taken at least 1024 steps, have the bike
+ ; shop owner try to call us.
+ ld a, d
+ cp HIGH(1024)
+ jr c, .NoCall
+
+ ; If a call has already been queued, don't overwrite
+ ; that call.
+ ld a, [wSpecialPhoneCallID]
+ and a
+ jr nz, .NoCall
+
+ ; Queue the call.
+ ld a, SPECIALCALL_BIKESHOP
+ ld [wSpecialPhoneCallID], a
+ xor a
+ ld [wSpecialPhoneCallID + 1], a
+ ld hl, wStatusFlags2
+ res STATUSFLAGS2_BIKE_SHOP_CALL_F, [hl]
+ scf
+ ret
+
+.NoCall:
+ xor a
+ ret
+
+ClearCmdQueue::
+ ld hl, wCmdQueue
+ ld de, CMDQUEUE_ENTRY_SIZE
+ ld c, CMDQUEUE_CAPACITY
+ xor a
+.loop
+ ld [hl], a
+ add hl, de
+ dec c
+ jr nz, .loop
+ ret
+
+HandleCmdQueue::
+ ld hl, wCmdQueue
+ xor a
+.loop
+ ld [hMapObjectIndexBuffer], a
+ ld a, [hl]
+ and a
+ jr z, .skip
+ push hl
+ ld b, h
+ ld c, l
+ call HandleQueuedCommand
+ pop hl
+
+.skip
+ ld de, CMDQUEUE_ENTRY_SIZE
+ add hl, de
+ ld a, [hMapObjectIndexBuffer]
+ inc a
+ cp CMDQUEUE_CAPACITY
+ jr nz, .loop
+ ret
+
+Unreferenced_GetNthCmdQueueEntry:
+ ld hl, wCmdQueue
+ ld bc, CMDQUEUE_ENTRY_SIZE
+ call AddNTimes
+ ld b, h
+ ld c, l
+ ret
+
+WriteCmdQueue::
+ push bc
+ push de
+ call .GetNextEmptyEntry
+ ld d, h
+ ld e, l
+ pop hl
+ pop bc
+ ret c
+ ld a, b
+ ld bc, CMDQUEUE_ENTRY_SIZE - 1
+ call FarCopyBytes
+ xor a
+ ld [hl], a
+ ret
+
+.GetNextEmptyEntry:
+ ld hl, wCmdQueue
+ ld de, CMDQUEUE_ENTRY_SIZE
+ ld c, CMDQUEUE_CAPACITY
+.loop
+ ld a, [hl]
+ and a
+ jr z, .done
+ add hl, de
+ dec c
+ jr nz, .loop
+ scf
+ ret
+
+.done
+ ld a, CMDQUEUE_CAPACITY
+ sub c
+ and a
+ ret
+
+DelCmdQueue::
+ ld hl, wCmdQueue
+ ld de, CMDQUEUE_ENTRY_SIZE
+ ld c, CMDQUEUE_CAPACITY
+.loop
+ ld a, [hl]
+ cp b
+ jr z, .done
+ add hl, de
+ dec c
+ jr nz, .loop
+ and a
+ ret
+
+.done
+ xor a
+ ld [hl], a
+ scf
+ ret
+
+_DelCmdQueue:
+ ld hl, CMDQUEUE_TYPE
+ add hl, bc
+ ld [hl], 0
+ ret
+
+HandleQueuedCommand:
+ ld hl, CMDQUEUE_TYPE
+ add hl, bc
+ ld a, [hl]
+ cp NUM_CMDQUEUE_TYPES
+ jr c, .okay
+ xor a
+
+.okay
+ ld e, a
+ ld d, 0
+ ld hl, .Jumptable
+ add hl, de
+ add hl, de
+ add hl, de
+ ld a, [hli]
+ push af
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ pop af
+ rst FarCall
+ ret
+
+.Jumptable:
+ dba CmdQueue_Null
+ dba CmdQueue_Null2
+ dba CmdQueue_StoneTable
+ dba CmdQueue_Type3
+ dba CmdQueue_Type4
+
+CmdQueueAnonymousJumptable:
+ ld hl, CMDQUEUE_05
+ add hl, bc
+ ld a, [hl]
+ pop hl
+ rst JumpTable
+ ret
+
+CmdQueueAnonJT_Increment:
+ ld hl, CMDQUEUE_05
+ add hl, bc
+ inc [hl]
+ ret
+
+CmdQueueAnonJT_Decrement:
+ ld hl, CMDQUEUE_05
+ add hl, bc
+ dec [hl]
+ ret
+
+CmdQueue_Null:
+ ret
+
+CmdQueue_Null2:
+ call ret_2f3e
+ ret
+
+CmdQueue_Type4:
+ call CmdQueueAnonymousJumptable
+ ; anonymous dw
+ dw .zero
+ dw .one
+
+.zero
+ ld a, [hSCY]
+ ld hl, 4
+ add hl, bc
+ ld [hl], a
+ call CmdQueueAnonJT_Increment
+.one
+ ld hl, 1
+ add hl, bc
+ ld a, [hl]
+ dec a
+ ld [hl], a
+ jr z, .finish
+ and $1
+ jr z, .add
+ ld hl, 2
+ add hl, bc
+ ld a, [hSCY]
+ sub [hl]
+ ld [hSCY], a
+ ret
+
+.add
+ ld hl, 2
+ add hl, bc
+ ld a, [hSCY]
+ add [hl]
+ ld [hSCY], a
+ ret
+
+.finish
+ ld hl, 4
+ add hl, bc
+ ld a, [hl]
+ ld [hSCY], a
+ call _DelCmdQueue
+ ret
+
+CmdQueue_Type3:
+ call CmdQueueAnonymousJumptable
+ ; anonymous dw
+ dw .zero
+ dw .one
+ dw .two
+
+.zero
+ call .IsPlayerFacingDown
+ jr z, .PlayerNotFacingDown
+ call CmdQueueAnonJT_Increment
+.one
+ call .IsPlayerFacingDown
+ jr z, .PlayerNotFacingDown
+ call CmdQueueAnonJT_Increment
+
+ ld hl, 2
+ add hl, bc
+ ld a, [hl]
+ ld [wd173], a
+ ret
+
+.two
+ call .IsPlayerFacingDown
+ jr z, .PlayerNotFacingDown
+ call CmdQueueAnonJT_Decrement
+
+ ld hl, 3
+ add hl, bc
+ ld a, [hl]
+ ld [wd173], a
+ ret
+
+.PlayerNotFacingDown:
+ ld a, $7f
+ ld [wd173], a
+ ld hl, 5
+ add hl, bc
+ ld [hl], 0
+ ret
+
+.IsPlayerFacingDown:
+ push bc
+ ld bc, wPlayerStruct
+ call GetSpriteDirection
+ and a
+ pop bc
+ ret
+
+CmdQueue_StoneTable:
+ ld de, wPlayerStruct
+ ld a, NUM_OBJECT_STRUCTS
+.loop
+ push af
+
+ ld hl, OBJECT_SPRITE
+ add hl, de
+ ld a, [hl]
+ and a
+ jr z, .next
+
+ ld hl, OBJECT_MOVEMENTTYPE
+ add hl, de
+ ld a, [hl]
+ cp SPRITEMOVEDATA_STRENGTH_BOULDER
+ jr nz, .next
+
+ ld hl, OBJECT_NEXT_TILE
+ add hl, de
+ ld a, [hl]
+ call CheckPitTile
+ jr nz, .next
+
+ ld hl, OBJECT_DIRECTION_WALKING
+ add hl, de
+ ld a, [hl]
+ cp STANDING
+ jr nz, .next
+ call HandleStoneQueue
+ jr c, .fall_down_hole
+
+.next
+ ld hl, OBJECT_STRUCT_LENGTH
+ add hl, de
+ ld d, h
+ ld e, l
+
+ pop af
+ dec a
+ jr nz, .loop
+ ret
+
+.fall_down_hole
+ pop af
+ ret