| Routines

F862: Deal with a stinkbomb when dropped

The address of this routine is placed into 7FD7 by the routine at 7140 when ERIC drops a stinkbomb. It creates a stinkbomb cloud and deals with it until it has dissipated, which includes checking whether MR WACKER and a closed window are nearby, and making the former set off for the latter if so.
F862 | LD HL,$7FEB | 7FEB holds the inventory flags
F865 | LD A,(HL) | Pick these up in A
F866 | AND $E0 | Keep only the stinkbomb bits (bits 5-7)
F868 | ADD A,A | Shift these bits left, losing the leftmost bit
F869 | LD C,A | Store the new stinkbomb bits in C briefly
F86A | LD A,(HL) | Pick up the inventory flags in A again
F86B | AND $1F | Discard the old stinkbomb bits
F86D | OR C | Superimpose the new stinkbomb bits
F86E | LD (HL),A | Restore the inventory flags, minus one stinkbomb
F86F | CALL $7C02 | Print the inventory
F872 | CALL $E236 | Prepare buffer 0xD5 for the stinkbomb cloud (or return to the main loop if the buffer is already in use by a stinkbomb cloud)
F875 | LD L,$00 | Point HL at byte 0x00 of ERIC's buffer
F877 | LD A,(HL) | A=ERIC's animatory state
F878 | INC L | L=0x01
F879 | RLCA | Set A to -1 if ERIC is facing left, 1 if he's facing right
F87A | SBC A,A
F87B | ADD A,A
F87C | CPL
F87D | ADD A,(HL) | Add ERIC's x-coordinate to get the x-coordinate for the stinkbomb cloud
F87E | LD E,A | Copy this to E
F87F | INC L | L=0x02
F880 | LD D,(HL) | D=ERIC's y-coordinate, which will also be the y-coordinate for the stinkbomb cloud
F881 | LD HL,$D513 | Point HL at byte 0x13 of the stinkbomb cloud's buffer
F884 | LD (HL),$1D | Initialise the counter that determines when the cloud will disappear
F886 | LD A,$47 | 0x47: stinkbomb cloud (phase 1)
F888 | CALL $7746 | Update the SRB for the stinkbomb cloud's appearance and place address F88B (below) into bytes 0x11 and 0x12 of the cloud's buffer
The address of the entry point below is placed into bytes 0x11 and 0x12 of the cloud's buffer by the instruction above.
F88B | LD L,$13 | Byte 0x13 of the cloud's buffer holds the counter that determines how much longer the cloud will stick around (which starts off at 0x1D)
F88D | DEC (HL) | Is it time for the cloud to disappear?
F88E | JP Z,$74CF | Jump if so
F891 | LD A,(HL) | Pick up the counter's value in A
F892 | CP $1C | Is it time for a teacher to give lines?
F894 | JR NZ,$F89E | Jump if not
F896 | LD A,$01 | Message 0x01: NO STINKBOMBS
This entry point is used by the routines at 5E6F, 5EC7, 5EE8 and F9AB with A holding a reprimand message number.
F898 | SUB $3E | Subtract 0x3E now (it's added back later on)
F89A | CP A | Set the zero flag to indicate that any teacher may give ERIC lines (including the one who last gave him lines)
F89B | JP $7E1A | Make any teacher within range give ERIC lines
Now deal with animating the stinkbomb cloud and checking whether it's near a window.
F89E | CALL $6430 | Toggle between cloud animation phases 1 (0x47) and 2 (0xC7) and update the SRB accordingly
F8A1 | LD L,$00 | Point HL at byte 0x00 of the cloud's buffer
F8A3 | BIT 0,(HL) | Bit 0 of the cloud's animatory state (0x47 or 0xC7) is always set, so this RET never happens
F8A5 | RET Z
F8A6 | INC L | L=0x01
F8A7 | LD A,(HL) | A=stinkbomb cloud's x-coordinate
F8A8 | CP $54 | The head's right study door is at x-coordinate 84
F8AA | RET C | Return if the cloud is to the left of this
F8AB | CP $60 | The boys' skool door is at x-coordinate 96
F8AD | RET NC | Return if the cloud is to the right of this
F8AE | INC L | L=0x02
F8AF | LD A,(HL) | A=stinkbomb cloud's y-coordinate
F8B0 | CP $11 | Is the cloud on the bottom floor?
F8B2 | RET Z | Return if so
The stinkbomb cloud is on the top floor or middle floor, somewhere between the head's right study door and the boys' skool door. Check the windows.
F8B3 | EX DE,HL | Point DE at byte 0x02 of the cloud's buffer
F8B4 | LD HL,$7FF4 | 7FF4 holds the door/window status flags
F8B7 | CP $03 | Is the cloud on the top floor?
F8B9 | JR Z,$F8C3 | Jump if so
F8BB | BIT 7,(HL) | Is the middle-floor window already open?
F8BD | RET NZ | Return if so
F8BE | LD BC,$805D | B=0x80 (middle floor window), C=93 (x-coordinate)
F8C1 | JR $F8C9 |
F8C3 | BIT 6,(HL) | Is the top-floor window already open?
F8C5 | RET NZ | Return if so
F8C6 | LD BC,$405B | B=0x40 (top-floor window), C=91 (x-coordinate)
Now B holds the identifier of a closed window on the same floor as the stinkbomb cloud, and C holds its x-coordinate. Is MR WACKER in the vicinity?
F8C9 | LD HL,$C802 | Point HL at byte 0x02 of MR WACKER's buffer
F8CC | CP (HL) | Is MR WACKER on the same floor as the stinkbomb cloud?
F8CD | RET NZ | Return if not
F8CE | DEC L | L=0x01
F8CF | DEC E | E=0x01
F8D0 | LD A,(DE) | A=x-coordinate of the stinkbomb cloud
F8D1 | SUB $03 | Return if MR WACKER is more than 2 spaces to the left of the cloud
F8D3 | CP (HL)
F8D4 | RET NC
F8D5 | ADD A,$05 | Return if MR WACKER is more than 2 spaces to the right of the cloud
F8D7 | CP (HL)
F8D8 | RET C
MR WACKER is close enough to the stinkbomb cloud to be affected by its stench. Check whether he's available for a spot of window-opening.
F8D9 | LD E,(HL) | E=MR WACKER's x-coordinate
F8DA | LD L,$12 | Is there an uninterruptible subcommand routine address in bytes 0x11 and 0x12 of MR WACKER's buffer (meaning he is otherwise occupied at the moment)?
F8DC | LD A,(HL)
F8DD | AND A
F8DE | RET NZ | Return if so
F8DF | LD L,A | L=0x00
F8E0 | LD A,(HL) | A=MR WACKER's animatory state
F8E1 | RRCA | Is MR WACKER midstride?
F8E2 | RET C | Return if so
F8E3 | RLCA | A=MR WACKER's animatory state
F8E4 | LD L,$13 | Store MR WACKER's current x-coordinate and animatory state in bytes 0x13 and 0x14 of his buffer for later retrieval
F8E6 | LD (HL),E
F8E7 | INC L
F8E8 | LD (HL),A
F8E9 | INC L | Store the x-coordinate of the window in byte 0x15
F8EA | LD (HL),C
F8EB | INC L | Byte 0x16 holds 0x80 (middle-floor window) or 0x40 (top-floor window)
F8EC | LD (HL),B
F8ED | CALL $61B4 | Update the SRB for MR WACKER's current animatory state and location
F8F0 | SET 7,A | A=animatory state of MR WACKER facing right
F8F2 | CALL $7746 | Place address F8F5 (below) into bytes 0x11 and 0x12 of MR WACKER's buffer and update his animatory state
The address of the entry point below is placed into bytes 0x11 and 0x12 of MR WACKER's buffer by the instruction above.
F8F5 | LD L,$00 | Point HL at byte 0x00 of MR WACKER's buffer
F8F7 | BIT 0,(HL) | Is MR WACKER midstride?
F8F9 | JP NZ,$63FD | Finish his stride if so
F8FC | JP $F939 | Otherwise set MR WACKER off on his journey to the window