Prev: B6DD Up: Map Next: B742
B6ED: 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, from DEC_DZ_AND_UPDATE_UVZ and its entry points and from the player's legs (MOVE_PLAYER). It takes the step 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 (ADJ_DU_FOR_OUT_OF_BOUNDS and its neighbours are the walls; ADJ_DU_FOR_OBJ_INTERSECT, ADJ_DV_FOR_OBJ_INTERSECT and ADJ_DZ_FOR_OBJ_INTERSECT the objects), with more done when two things meet in Z (ADJ_DZ_FOR_OBJ_INTERSECT).
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 is what 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 B6ED BIT 1,(IX+$07) not while already set; and ignore ourself while we work
B6F1 RET NZ
B6F2 SET 1,(IX+$07)
B6F6 LD A,(IX+$0C) clear the three "stopped" bits
B6F9 AND $F8
B6FB LD (IX+$0C),A
B6FE LD L,$00 dV and dU count as zero while Z is tested
B700 LD C,L
B701 LD A,(IX+$0B) H = dZ; nothing to do if zero
B704 AND A
B705 LD H,A
B706 JR Z,ADJ_FOR_OUT_OF_BOUNDS_0
B708 CALL ADJ_DZ_FOR_OUT_OF_BOUNDS the floor first; nothing left means no objects to test
B70B LD A,H
B70C AND A
B70D JR Z,ADJ_FOR_OUT_OF_BOUNDS_0
B70F CALL ADJ_DZ_FOR_OBJ_INTERSECT then the other objects
ADJ_FOR_OUT_OF_BOUNDS_0 B712 LD A,(IX+$09) C = dU; nothing to do if zero
B715 AND A
B716 LD C,A
B717 JR Z,ADJ_FOR_OUT_OF_BOUNDS_1
B719 CALL ADJ_DU_FOR_OUT_OF_BOUNDS the walls first; nothing left means no objects to test
B71C LD A,C
B71D AND A
B71E JR Z,ADJ_FOR_OUT_OF_BOUNDS_1
B720 CALL ADJ_DU_FOR_OBJ_INTERSECT then the other objects
ADJ_FOR_OUT_OF_BOUNDS_1 B723 LD A,(IX+$0A) L = dV; nothing to do if zero
B726 AND A
B727 LD L,A
B728 JR Z,ADJ_FOR_OUT_OF_BOUNDS_2
B72A CALL ADJ_DV_FOR_OUT_OF_BOUNDS the walls first; nothing left means no objects to test
B72D LD A,L
B72E AND A
B72F JR Z,ADJ_FOR_OUT_OF_BOUNDS_2
B731 CALL ADJ_DV_FOR_OBJ_INTERSECT then the other objects
ADJ_FOR_OUT_OF_BOUNDS_2 B734 LD (IX+$09),C the three moves as cut
B737 LD (IX+$0A),L
B73A LD (IX+$0B),H
B73D RES 1,(IX+$07) other objects' scans may find us again
B741 RET
Prev: B6DD Up: Map Next: B742