Prev: CB29 Up: Map Next: CB6A
CB45: Cut a move short against the room and the other objects
Used by the routines at dec_dZ_and_update_XYZ and move_player_apply.
Every moving object's move comes through here, the player's from move_player_apply and everyone else's from dec_dZ_and_update_XYZ. It takes dX, dY and dZ from the record and shortens each where the object would otherwise end up inside the floor, a wall, or another object, then writes them back.
The axes are done one at a time, Z first, then X, then Y, and each test uses the moves already accepted on the earlier axes (the later ones count 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 the object's +$07 is set, which is what makes the object scans (is_object_not_ignored) pass over the object itself; found already set, it means the object is not to be moved this way at all. 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 CB45 BIT 1,(IX+$07) not for objects marked to be ignored; and ignore ourself while we work
CB49 RET NZ
CB4A SET 1,(IX+$07)
CB4E LD A,(IX+$0C) clear the three "stopped" bits
CB51 AND $F8
CB53 LD (IX+$0C),A
CB56 LD L,$00 dY and dX count as zero while Z is tested
CB58 LD C,L
CB59 LD A,(IX+$0B) H = dZ; nothing to do if zero
CB5C AND A
CB5D LD H,A
CB5E JR Z,dZ_ok
CB60 CALL adj_dZ_for_out_of_bounds the floor first; nothing left means no objects to test
CB63 LD A,H
CB64 AND A
CB65 JR Z,dZ_ok
CB67 CALL adj_dZ_for_obj_intersect then the other objects
Prev: CB29 Up: Map Next: CB6A