Desert uses two memory addresses to register the position of the player(the X and the Y), so each verb have to check the right address. Here you have the code.
;--- Movement -----------------------------
North_Cmd
; Y has reached de limit
ldx player_y
cpx #$f
beq PR_No_Exit
inx
stx player_y
jmp Reduce_Water_Life
South_Cmd
; Y has reached de limit
ldx player_y
; Cero
beq PR_No_Exit
dex
stx player_y
jmp Reduce_Water_Life
East_Cmd
; X has reached de limit
ldx player_x
cpx #$f
beq PR_No_Exit
inx
stx player_x
jmp Reduce_Water_Life
West_Cmd
; Y has reached de limit
ldx player_x
; Cero
beq PR_No_Exit
dex
stx player_x
jmp Reduce_Water_Life
PR_No_Exit
lda #str_no_exit
jsr PRTSTR
rts
There is little more to say.
Executing the actions so verbs are similar to Pursuing Tom Ram. Here you have some examples.
CPlayer can only drink if she is in an oasis or she carries a filled flask. You have both checks in the code.
Drink_Cmd
lda current_loc_type
cmp #OASIS_LOC
bne @Check_Flask
;jsr Print_Ok
jmp @Drink
@Check_Flask
ldy #F_FLASK
jsr read_flag_y
beq JMP_Print_You_Cannot
ldy #F_FILL_FLASK
jsr read_flag_y
beq JMP_Print_You_Cannot
ldy #F_FILL_FLASK
jsr clear_flag_y
;jsr Print_Ok
@Drink
jsr Set_Initial_Water
JSR PrintWater
rts
JMP_Print_You_Cannot
jmp Print_You_Cannot
A similar command is Fill, because player can only fill a flask if she has one and she is in the oasis. Code is not here but you can get it in the repository.
Take command uses a chain. You saw the chains in the guide about Pursing Tom Ram.
;--- Take Command ---------------
Take_Cmd
; Take Idol
lda current_loc_type
cmp #IDOL_LOC
bne @Take_Flask
ldy #F_IDOL
jsr read_flag_y
bne Invalid_Take
ldy #F_IDOL
jsr set_flag_y
jsr Print_Ok
rts
@Take_Flask
lda current_loc_type
cmp #FLASK_LOC
bne @Take_Compass
ldy #F_FLASK
jsr read_flag_y
bne Invalid_Take
ldy #F_FLASK
jsr set_flag_y
;jsr Print_Ok
lda #str_take_flask
jsr PRTSTR
rts
@Take_Compass
lda current_loc_type
cmp #COMPASS_LOC
bne @Take_Ankh
ldy #F_COMPASS
jsr read_flag_y
bne Invalid_Take
ldy #F_COMPASS
jsr set_flag_y
;jsr Print_Ok
lda #str_take_compass
jsr PRTSTR
rts
@Take_Ankh
lda current_loc_type
;sta mem_mon
;sta mem_mon+1
cmp #ANKH_LOC
bne Invalid_Take ; No more items
ldy #F_ANKH
jsr read_flag_y
bne Invalid_Take
ldy #F_ANKH
jsr set_flag_y
jsr Print_Ok
rts
Invalid_Take
jsr Print_You_Cannot
rts
Finally, some code depends on the player carrying an object. One example is the flask. Another example is the compass and the command Guide.
;--- Guide command --------------
Guide_Cmd
; Check if you have compass
ldy #F_COMPASS
jsr read_flag_y
beq Invalid_Take
lda #str_compas_point
jsr PRTSTR
lda player_y
;sta mem_mon
sec
sbc #DESTINATION_Y
;sta mem_mon+1
beq @Check_X
bcc @Y_Minus
; X is bigger, go south
lda #str_south
jsr PRTSTR
jmp @Check_X
@Y_Minus
lda #str_north
jsr PRTSTR
@Check_X
lda player_x
;sta mem_mon
sec
sbc #DESTINATION_X
;sta mem_mon+1
beq @End
bcc @X_Minus
; Y is bigger,
lda #str_west
jsr PRTSTR
rts
@X_Minus
lda #str_east
jsr PRTSTR
@End
rts
Guide command is long because the command has to check where the player is, where the city is and generate the right message. The key action is to subtract the position of the city and the player, once for x axis (so you can print easo or west), and another one for y axis (so you can print up or down).
For example, take a second look to this piece of code
sec
sbc #DESTINATION_Y
;sta mem_mon+1
beq @Check_X
If the result of sbc (subtraction) is bigger to 0, the player is at the west of the city, so he have to move to the west. You may search the part of the code where the west is printed.
The Temple is a special location. If the player finds the temple and have the Ankh (an Egyptian cross), he may enter using the command Enter. While player remains in the temple she can sleep, to recover life, drink or fill, like an oasis and exit the temple.
One more thing, if player is in the temple, the loc prints a message saying than player is in the temple (not lost in desert).
First task, how do I know if player is in the temple? When player enters the temple, I move the X coordinate to a value outside the map. With this value, I know when the player is in the temple.
;--- Enter_Cmd ----------------
Enter_Cmd
; Chaek you are in temple LOC
lda current_loc_type
cmp #TEMPLE_LOC
bne Print_You_Cannot ; No more items
; Chack you have the Ankh
ldy #F_ANKH
jsr read_flag_y
beq Print_You_Cannot
; Move to a special loc
lda #$10
sta player_x
sta player_y
; Temple is like an Oasis
lda #OASIS_LOC
sta current_loc_type
jsr Loc_Temple
rts
If player is in temple, a specific location message is printed. See the code at PrintLOC subroutine.
PrintLOC
; check if player is in the temple
lda player_x
cmp #$10
bne @Not_in_Temple
jsr Loc_Temple
jmp MainLoop
@Not_in_Temple
; other code
Loc_Temple
jsr CLRS
jsr PrintStats
lda #str_in_the_temple
jsr PRTSTR
rts
There is no Exit verb to exit the temple. Instead, the player has to move to go back to the desert location of the temple. I have to write a specific subroutine to move player when she is in the temple an goes to any cardinal point. This is the code.
;-------------
ExecuteCommand
;lda verb_index ; already loaded
lda player_x
; check if player is in the temple
cmp #$10
bne @Jump_to_Cmd
; Player is in temple
lda verb_index
; check if is a movement verb
sec
sbc #$4
bcs @Jump_to_Cmd
; It is a movement verb
; I place the player in the temple loc
lda #TEMPLE_X
sta player_x
lda #TEMPLE_Y
sta player_y
; Repeat main loop
jmp LocLoop