| Routines

25118: Control the sniper while active

The address of this interruptible subcommand routine is placed into bytes 14 and 15 of the sniper's buffer by the routine at 25307. It controls the sniper from the moment he appears until he hides again.
Input
H | 227 (sniper)
25118 | LD L,2 | A=sniper's y-coordinate
25120 | LD A,(HL)
25121 | LD L,17 | Point HL at byte 17 of the sniper's buffer
25123 | INC (HL) | Is it zero (meaning the sniper has not fired recently)?
25124 | DEC (HL)
25125 | JR Z,25128 | Jump if so
25127 | DEC (HL) | Otherwise decrement byte 17
25128 | DEC L | L=16
25129 | CP 50 | The sniper's y-coordinate is 50 when he's inactive
25131 | JR NZ,25168 | Jump if the sniper is currently active
The sniper is currently inactive.
25133 | DEC (HL) | Decrement byte 16 of the sniper's buffer
25134 | JP Z,62084 | Terminate this subcommand if byte 16 is now 0
25137 | CALL 26328 | Is the sniper on screen at least 8 x-coordinates away from Sam?
25140 | NOP |
25141 | JP NZ,62084 | Terminate this subcommand if not
25144 | INC L | Point HL at byte 2 of the sniper's buffer
25145 | LD (HL),37 | Set the sniper's y-coordinate to 37 (out of sight, but ready to emerge)
25147 | LD A,(58881) | A=Sam's x-coordinate
25150 | DEC L | L=1
25151 | SUB (HL) | Subtract the sniper's x-coordinate
25152 | CCF | Compute the appropriate animatory state for the sniper: 54 if he's to the right of Sam, 182 if he's to the left
25153 | LD A,108
25155 | RRA
25156 | DEC HL | Set the sniper's animatory state
25157 | LD (HL),A
This entry point is used by the routine at 28646.
25158 | LD L,2 | Collect the sniper's x- and y-coordinates in DE
25160 | LD D,(HL)
25161 | DEC HL
25162 | LD E,(HL)
25163 | DEC HL | A=sniper's animatory state
25164 | LD A,(HL)
25165 | JP 26224 | Update the sniper's sprite tile references
The sniper is currently active (his y-coordinate is 34-37).
25168 | LD A,(57014) | Collect the sprite tile reference for tile 7 of animatory states 54/182; this will be 235 if the sniper is firing, or 0, 110, 111 or 113 otherwise
25171 | CP H | Is the sniper firing?
25172 | JP NC,28646 | If so, make the firing sound effect
25175 | LD A,(32767) | A=y-coordinate of the topmost row of the play area on screen
25178 | CP 20 | Is the sidewalk on screen?
25180 | JR NZ,25193 | If not, deactivate the sniper and terminate this subcommand
25182 | DEC (HL) | Decrement byte 16 of the sniper's buffer
25183 | JR NZ,25210 | Jump unless byte 16 is now zero
Byte 16 of the sniper's buffer has been decremented to zero. The apparent intention here is to make the sniper duck out of sight and terminate this subcommand; however, if the sniper is not already out of sight, he will duck briefly but remain in view, and byte 16 will be decremented to 255 on the next pass through this routine. This is a bug.
25185 | CALL 59848 | Update the SRB for the sniper's current animatory state and location
25188 | LD A,D | A=sniper's y-coordinate
25189 | CP 37 | Is the sniper currently out of sight?
25191 | JR NZ,25202 | Jump if not to make him duck
25193 | LD L,15 | Remove the address of this routine from bytes 14 and 15 of the sniper's buffer
25195 | LD (HL),0
25197 | LD L,2 | Set the sniper's y-coordinate to 50 (inactive)
25199 | LD (HL),50
25201 | RET |
The sniper is in the process of ducking.
25202 | INC D | D=sniper's next y-coordinate (35-37)
25203 | LD L,0 | Point HL at byte 0 of the sniper's buffer
25205 | LD A,(HL) | A=sniper's animatory state
25206 | AND A | Reset the carry flag to indicate that the sniper is not firing
25207 | JP 26224 | Update the sniper's sprite tile references
Byte 16 of the sniper's buffer is not zero.
25210 | CALL 26328 | Compare the sniper's coordinates with Sam's
25213 | JR Z,25227 | Jump if the sniper is on screen and at least 8 x-coordinates away from Sam
25215 | JR NC,25193 | Terminate this subcommand if the sniper if off screen
25217 | CALL 59848 | Update the SRB for the sniper's current animatory state and location
25220 | LD A,D | A=sniper's y-coordinate
25221 | CP 37 | Has the sniper already ducked out of sight?
25223 | JR NZ,25202 | Jump if not to make the sniper continue ducking
25225 | JR 25197 | Deactivate the sniper
The sniper is on screen and at least 8 x-coordinates away from Sam. If he's already popped his head out far enough (his y-coordinate is 34 or 35), he can consider shooting; otherwise he'll need to emerge a little further first.
25227 | LD L,2 | Point HL at byte 2 of the sniper's buffer
25229 | LD A,(HL) | A=sniper's y-coordinate
25230 | CP 36 | Is at least half of the sniper visible?
25232 | JR C,25240 | Jump if so
25234 | CALL 59848 | Update the SRB for the sniper's current animatory state and location
25237 | DEC D | D=sniper's next y-coordinate (35 or 36)
25238 | JR 25206 | Jump back to update the sniper's sprite tile references
At least half of the sniper is visible (his y-coordinate is 34 or 35), which means he can shoot.
25240 | LD L,16 | Collect byte 16 of the sniper's buffer
25242 | LD A,(HL)
25243 | AND 3 | Is bit 0 or bit 1 set?
25245 | JR NZ,25263 | Jump if so
25247 | CALL 61823 | Get a random number in A
25250 | CP 160 | Should the sniper consider shooting?
25252 | JR C,25263 | Jump if so (5 times out of 8)
25254 | CALL 59848 | Update the SRB for the sniper's current animatory state and location
25257 | LD A,D | A=sniper's y-coordinate (34 or 35)
25258 | XOR 1 | Toggle between 34 and 35
25260 | LD D,A | D=sniper's next y-coordinate (35 or 34)
25261 | JR 25203 | Jump back to update the sniper's sprite tile references
The sniper will consider shooting.
25263 | LD A,(58884) | A=Sam's z-coordinate
25266 | RRCA | Is Sam indoors?
25267 | RET C | Return if so
25268 | LD A,(32764) | Collect Sam's status flags from 32764
25271 | AND 129 | Is Sam falling from a building or being carried?
25273 | RET NZ | Return if so
25274 | LD L,17 | Collect byte 17 of the sniper's buffer
25276 | LD A,(HL)
25277 | AND A | Has the sniper fired recently?
25278 | RET NZ | Return if so
25279 | CALL 61823 | Get a random number in A
25282 | CP 84 | Should the sniper continue to consider shooting?
25284 | RET NC | Return if not (21 times out of 64)
25285 | LD DE,32706 | Point DE at the third byte of bullet buffer 1 (at 32704)
25288 | LD A,(DE) | Pick this up in A
25289 | AND A | Is bullet buffer 1 in use?
25290 | JR Z,25297 | Jump if not
25292 | LD E,198 | Point DE at the third byte of bullet buffer 2 (at 32708)
25294 | LD A,(DE) | Pick this up in A
25295 | AND A | Is bullet buffer 2 in use?
25296 | RET NZ | Return if so
The sniper has decided to shoot, and a bullet buffer is available.
25297 | LD (HL),12 | Place 12 into byte 17 of the sniper's buffer (indicating that he's just fired)
25299 | CALL 59848 | Update the SRB for the sniper's current animatory state and location
25302 | SCF | Set the carry flag to indicate that the sniper is firing
25303 | JP 26224 | Update the sniper's sprite tile references and initialise a bullet