Prev: B791 Up: Map Next: B866
B7E0: Block Movement In Z
Used by the routine at BlockMovement.
Cuts down the distance that an object moves along z until it does not go through any other object. A hit along z means that the object has landed on the other one (or has bumped its head on it), so the routine also deals with the things that are done to an object that is stood on.
When an object is stopped, the two objects share their hit flags, the one underneath is marked as being stood on, and an object that can be pushed is carried along: it takes the speeds of the object it is on.
Input
H Distance to move along z
IX Object record
Output
H Distance that can be moved
Try the object against each of the objects in turn.
BlockMovementInZ B7E0 LD IY,$A76F Start with the first object record, ObjectsTable.
B7E4 LD B,$36 Set a counter in B of 36 objects.
BlockMovementInZ_Next B7E6 CALL TestObjectSolid Jump to BlockMovementInZ_NextObject if the other object is not in use, or is being moved.
B7E9 JR Z,BlockMovementInZ_NextObject
B7EB CALL TestOverlapInX Jump to BlockMovementInZ_NextObject if the objects do not overlap along x.
B7EE JR NC,BlockMovementInZ_NextObject
B7F0 CALL TestOverlapInY Jump to BlockMovementInZ_NextObject if the objects do not overlap along y.
B7F3 JR NC,BlockMovementInZ_NextObject
BlockMovementInZ_Test B7F5 CALL TestOverlapInZ Jump to BlockMovementInZ_NextObject if the objects will not overlap along z when the object has moved.
B7F8 JR NC,BlockMovementInZ_NextObject
The objects hit each other. Flag a hit along z, which also means the object is on the ground.
B7FA SET 2,(IX+$0C) Flag that the object has been stopped along z.
B7FE CALL MarkObjectBelow Call MarkObjectBelow to flag the other object if the object is a part of the player or a block of type 5B.
Flag the object if it is standing on the player.
B801 LD A,(IY+$00) Fetch the type of the other object.
B804 CP $20 Jump to BlockMovementInZ_Block if it is below 20, the first part of the player.
B806 JR C,BlockMovementInZ_Block
B808 CP $28 Jump to BlockMovementInZ_Block if it is 28 or more, which is not a part of the player.
B80A JR NC,BlockMovementInZ_Block
B80C SET 7,(IX+$17) Flag that the object is on the player.
An object that stands on a moving block is pushed by it.
BlockMovementInZ_Block B810 CP $8C Jump to BlockMovementInZ_HitFlags if the other object is below 8C, the first of the moving blocks.
B812 JR C,BlockMovementInZ_HitFlags
B814 CP $90 Call PushObjectOnBlock to push the object if the other object is a moving block, which is when it is below 90.
B816 CALL C,PushObjectOnBlock
Pass on the hit flags, and flag that the other object has something on it.
BlockMovementInZ_HitFlags B819 LD A,(IX+$0D) Fetch the hit flags of the object.
B81C RRCA Move bit 7 down to bit 6.
B81D AND %01000000 Keep only bit 6.
B81F OR (IY+$0D) Add the hit flags of the other object.
B822 LD (IY+$0D),A Write them to the other object.
B825 RLCA Move bit 5 of the hit flags of the other object up to bit 6.
B826 AND %01000000 Keep only bit 6.
B828 OR (IX+$0D) Add the hit flags of the object.
B82B LD (IX+$0D),A Write them to the object.
B82E SET 3,(IY+$0D) Flag that the other object has something on it.
Carry an object that can be pushed. It takes the speed along z of the object, and the speeds along x and y if it has none.
B832 BIT 2,(IX+$07) Jump to BlockMovementInZ_Reduce if the object cannot be pushed.
B836 JR Z,BlockMovementInZ_Reduce
B838 LD A,(IX+$0B) Give the other object the speed along z of the object.
B83B LD (IY+$0B),A
B83E LD A,(IX+$09) Jump to BlockMovementInZ_CarryY if the object is moving along x.
B841 AND A
B842 JR NZ,BlockMovementInZ_CarryY
B844 LD A,(IY+$09) Give the object the speed along x of the other object.
B847 LD (IX+$09),A
BlockMovementInZ_CarryY B84A LD A,(IX+$0A) Jump to BlockMovementInZ_Reduce if the object is moving along y.
B84D AND A
B84E JR NZ,BlockMovementInZ_Reduce
B850 LD A,(IY+$0A) Give the object the speed along y of the other object.
B853 LD (IX+$0A),A
Step the distance closer to zero while the objects still overlap.
BlockMovementInZ_Reduce B856 LD A,H Fetch the distance along z.
B857 CALL BringSpeedCloserToZero Call BringSpeedCloserToZero to step it one closer to zero.
B85A LD H,A Set the distance.
B85B RET Z Return if the distance is zero.
B85C JR BlockMovementInZ_Test Jump to BlockMovementInZ_Test to test again.
BlockMovementInZ_NextObject B85E LD DE,$0020 Move IY on to the next object record.
B861 ADD IY,DE
B863 DJNZ BlockMovementInZ_Next Decrease the counter and loop until all the objects have been tried.
B865 RET Return.
Prev: B791 Up: Map Next: B866