Prev: C426 Up: Map Next: C497
C442: Cut a move short against the room and the other objects
Used by the routines at DEC_DZ_AND_UPDATE_UVZ and MOVE_PLAYER.
Every moving object's move comes through here: the robot's from MOVE_PLAYER, everything else's from DEC_DZ_AND_UPDATE_UVZ. It takes the steps in U, V and Z (+$09 to +$0B) and shortens each where the object would otherwise end up below the floor, through a wall, or inside another object, then writes them back. The code is Knight Lore's and Pentagram's.
The axes are done one at a time, Z first, then U, then V, and each test counts the moves already accepted on the earlier axes and the later ones as zero. That is what lets a blocked move slide: walking diagonally into a wall keeps the part of the move that runs along it.
While it works, bit 1 of +$07 is set, which makes the object scans (IS_OBJECT_NOT_IGNORED) pass over the object itself; found already set, it returns at once. Bits 0-2 of +$0C are cleared at the start and set for each axis whose move was cut.
Input
IX the object
ADJ_FOR_OUT_OF_BOUNDS C442 BIT 1,(IX+$07) Not while already set; and ignore ourself while we work
C446 RET NZ
C447 SET 1,(IX+$07)
C44B LD A,(IX+$0C) Clear the three "stopped" bits
C44E AND $F8
C450 LD (IX+$0C),A
C453 LD L,$00 dV and dU count as zero while Z is tested
C455 LD C,L
C456 LD A,(IX+$0B) H = dZ; nothing to do if zero
C459 AND A
C45A LD H,A
C45B JR Z,ADJ_FOR_OUT_OF_BOUNDS_0
C45D CALL ADJ_DZ_FOR_OUT_OF_BOUNDS The floor first; nothing left means no objects to test
C460 LD A,H
C461 AND A
C462 JR Z,ADJ_FOR_OUT_OF_BOUNDS_0
C464 CALL ADJ_DZ_FOR_OBJ_INTERSECT Then the other objects
ADJ_FOR_OUT_OF_BOUNDS_0 C467 LD A,(IX+$09) C = dU; nothing to do if zero
C46A AND A
C46B LD C,A
C46C JR Z,ADJ_FOR_OUT_OF_BOUNDS_1
C46E CALL ADJ_DU_FOR_OUT_OF_BOUNDS The walls first; nothing left means no objects to test
C471 LD A,C
C472 AND A
C473 JR Z,ADJ_FOR_OUT_OF_BOUNDS_1
C475 CALL ADJ_DU_FOR_OBJ_INTERSECT Then the other objects
ADJ_FOR_OUT_OF_BOUNDS_1 C478 LD A,(IX+$0A) L = dV; nothing to do if zero
C47B AND A
C47C LD L,A
C47D JR Z,ADJ_FOR_OUT_OF_BOUNDS_2
C47F CALL ADJ_DV_FOR_OUT_OF_BOUNDS The walls first; nothing left means no objects to test
C482 LD A,L
C483 AND A
C484 JR Z,ADJ_FOR_OUT_OF_BOUNDS_2
C486 CALL ADJ_DV_FOR_OBJ_INTERSECT Then the other objects
ADJ_FOR_OUT_OF_BOUNDS_2 C489 LD (IX+$09),C The three moves as cut
C48C LD (IX+$0A),L
C48F LD (IX+$0B),H
C492 RES 1,(IX+$07) Other objects' scans may find us again
C496 RET
Prev: C426 Up: Map Next: C497