Prev: 57276 Up: Map Next: 57401
57293: Check for events/collisions
Used by the routines at 51854, 52118, 52263, 52338, 52513, 52582, 52616, 53323, 53526, 53714, 54393 and 54429.
Input
C Collision/event type, e.g.:
0 = Collision with Maroc, e.g.:
creature missile hitting Maroc (53533) or Maroc moving through an open doorway (51737)
1 = Door opening/closing (51854)
3 = Check for creature being destroyed (e.g. by missile/sword)
5 = Servant picking up an object (52582)
15 = Item being collected by Maroc (checked at 52338)
136 = Check for Maroc entering portal door in room 81 54429
137 = Maroc has destroyed Avelach with Caliburn (52270)
253 = Check if Maroc is touching a (stationary) energy-restoring object - from 54415
254 = Check if Maroc is touching a (stationary) energy-draining object - from 54401
D Horizontal (X) position (in pixels) for graphic, e.g. servant, door
E Vertical (Y) position (in pixels), e.g. servant, door
Check for a variety of collisions, or 'instances of items touching other items':
  • Servant picks up an object
  • Servant uses an object on another object/creature
  • Servant gives an item to a warlock
  • Servant touches an open door handle
  • Maroc's missile/bolt collides with a creature
  • Maroc touches an object that restores/drains energy
  • Creature missile hits Maroc
  • Creature closes a door (touches the handle of an open door)
example of an event - using an item to open a chest
The routine returns the A register containing 0 (no collision) or 1 (collision has taken place):
57293 LD A,(60115) Graphic's horizontal position, in pixels, starting from screen pixel column 8 (halfway into left decorative border)
57296 LD D,A
57297 LD A,(60114) Graphic's vertical position, in pixels, from top of playing area
57300 LD E,A
Horizontal (D) and vertical (E) pixel co-ordinates either identified in the previous 4 instructions, or pre-loaded prior to a CALL directly here (e.g. 55355 for servant checks)
57301 LD A,(60116) This byte indicates whether the item is in the current view horizontally (0), off-screen to the right (1), or offscreen to the left (255)
57304 CP 0 If it's NOT zero, it's off-screen so no collision action needs checking. Jump to the end of this routine (setting no collision/energy drain flag to zero)
57306 JR NZ,57398
57308 LD A,C Retrieve the value from the C register from the previous routine - this is the collision/event check value to test
57309 CP 0 0 tests for a collision with Maroc - e.g. the servant and Maroc's backpack (placing/retrieving items)
57311 JR Z,57319
57313 CP 1 Collision value 1 = Opening/closing doors interactions
57315 JR Z,57319
57317 JR 57340 All other sorts of event/collision
CHECK FOR COLLISIONS WITH MAROC'S SPRITE.
This could be the servant (for object manipulation) or Maroc opening a door.
57319 LD A,120 120 (in pixels) is roughly 1 character/8 pixels to the right of the centre of the screen - Maroc's horizontal central point
57321 SUB D Subtract the graphic's horizontal (X) position
57322 CP 16 If the difference is <= 16 pixels, the other room item is (horizontally) close enough to Maroc
57324 JR NC,57340 Collision NOT within horizontal 'hit box'. Skip next few instructions
57326 LD A,(60097) Collision IS within horizontal 'hit box'. Get Maroc's vertical (Y-axis) screen position
57329 ADD A,8 Maroc's central point/backpack is on the lower part of his graphic, so move down 8 pixels...
57331 SUB E Subtract the graphic's vertical (Y) position
57332 CP 16 If the difference is <=16 pixels, Maroc is (vertically) close enough
57334 JR NC,57340 Collision NOT within horizontal 'hit box'. Skip next couple of instructions
Positive collision with Maroc confirmed
57336 LD A,1 Positive collision - set flag (A register) to 1
57338 JR 57400 Jump straight to RET
CHECK FOR OTHER COLLISIONS/EVENTS
Jump from 57317 if the collision type in the C register is NOT 0 ir 1 (all other event matches/collisions).
This might be checking for collision with energy restoring (253) or draining (254) objects, or for an item acting on another (matching) item, such as a key and a chest.
57340 LD A,C Retrieve the type-of-collision value to test/check
57341 CP 0 Is it 0?
57343 JR Z,57398 If so, that check's done, so can skip to the end (setting collision flag to zero)
57345 LD B,253 253 = value to test for energy-replenishing objects
However, this test won't match because of the AND 3 in a few instructions at 57368.
Explicit event checks for both energy-draining (C=254) and energy-restoring (C=253) objects are CALLed in the routine at 54393
57347 LD HL,(60268) Pointer to room item event table at 32691.
57350 CP 4 Check if type-of-collision value >= 4
57352 JR NC,57357
57354 LD B,C If < 4, store the type-of-collision value in B register
57355 LD C,0 ...and set C register to 0
57357 LD A,(HL) Get first byte from data table (at 32691)
57358 INC HL (...and move the pointer along)
57359 CP 255 Is there data to check in this set (255 = end-of-data)?
57361 JR Z,57398 If not, skip to the end of this routine, setting collision/energy drain flag to zero
57363 LD A,(HL) Get the (second) byte in the set
57364 INC HL (...and move the pointer along)
57365 CP C Check collision test value vs object/item collision type (second byte in set at 32691) to see if it matches
57366 JR Z,57373 If so, jump to check Maroc's 'hit boxes' for a collision
Check door-, spell- or creature-related interactions. For example:
  • goblins have a creature event value - for items acting on them - of 3
  • missiles 2-7 in the table at 27868 have bits 0 & 1 of their event byte set (value = 3)
  • similarly Caliburn (30907) and the animated sabre (31331) have bits 0-1 of their event byte set (value = 3)
By just filtering these two bits, we can set/determine which items or spells will cause a positive event/collision on goblins.
57368 AND 3 This filters bits 0-1 (values 1-3)
57370 CP B If no match for this, continue to check the event table at 32691
57371 JR NZ,57394
Check X/Y co-ordinates for collision
First, an X (horizontal) co-ordinate check:
57373 LD A,(HL) Get item's horizontal pixel co-ordinate (byte 3 of item set at 32691)
57374 INC HL (...and move the pointer along)
57375 ADD A,8 The collision check is a 16-pixel horizontal collision area, so adding 8 is an offset which gives it an 8-pixel-each-side collision box
57377 SUB D Subtract the horizontal pixel co-ordinate of the 'acting item'
57378 CP 16 Is the difference within the 16 pixel 'hit box' threshold (8 pixels left/right of target co-ordinates)?
57380 JR NC,57395 If not, no need to check vertical co-ordinates
Y (vertical) co-ordinate check:
57382 LD A,(HL) Get item's vertical pixel co-ordinate (byte 4 of item set at 32691)
57383 ADD A,8 The collision check is a 16-pixel vertical collision area, so adding 8 is an offset which gives it an 8-pixel-each-side collision box
57385 SUB E Subtract the vertical pixel co-ordinate of the 'acting item' (e.g. servant)
57386 CP 16 Is the difference within the 16 pixel 'hit box' threshold (8 pixels left/right of target co-ordinates)
57388 JR NC,57395 If not, jump to set negative collision flag (0) in A register
POSITIVE COLLISION
57390 LD A,1 Set collision flag (A register) to 1 - collision has taken place with this item.
57392 JR 57400 Jump straight to RET and deal with it
No positive collision found for this object - move to next item and continue checks:
57394 INC HL Jumps from 57371...
57395 INC HL ...and from 57395, that advance the address pointer to the next data set (at 32691).
57396 JR 57357
NEGATIVE COLLISION - Set collision flag (A register) to 0 - no collision has taken place with any on-screen objects.
57398 LD A,0
Routine returns with A register either set to 1 (collision) or 0 (no collision)
57400 RET
Prev: 57276 Up: Map Next: 57401