private static bool onActorMoveHExact(On.Celeste.Actor.orig_MoveHExact orig, Actor self, int moveH, Collision onCollide, Solid pusher)
        {
            // fall back to vanilla if no sideways jumpthru is in the room.
            if (self.SceneAs <Level>().Tracker.CountEntities <SidewaysJumpThru>() == 0)
            {
                return(orig(self, moveH, onCollide, pusher));
            }

            Vector2 targetPosition    = self.Position + Vector2.UnitX * moveH;
            int     moveDirection     = Math.Sign(moveH);
            int     moveAmount        = 0;
            bool    movingLeftToRight = moveH > 0;

            while (moveH != 0)
            {
                bool didCollide = false;

                // check if colliding with a solid
                Solid solid = self.CollideFirst <Solid>(self.Position + Vector2.UnitX * moveDirection);
                if (solid != null)
                {
                    didCollide = true;
                }
                else
                {
                    // check if colliding with a sideways jumpthru
                    SidewaysJumpThru jumpThru = self.CollideFirstOutside <SidewaysJumpThru>(self.Position + Vector2.UnitX * moveDirection);
                    if (jumpThru != null && jumpThru.AllowLeftToRight != movingLeftToRight)
                    {
                        // there is a sideways jump-thru and we are moving in the opposite direction => collision
                        didCollide = true;
                    }
                }

                if (didCollide)
                {
                    Vector2 movementCounter = (Vector2)actorMovementCounter.GetValue(self);
                    movementCounter.X = 0f;
                    actorMovementCounter.SetValue(self, movementCounter);
                    onCollide?.Invoke(new CollisionData {
                        Direction      = Vector2.UnitX * moveDirection,
                        Moved          = Vector2.UnitX * moveAmount,
                        TargetPosition = targetPosition,
                        Hit            = solid,
                        Pusher         = pusher
                    });
                    return(true);
                }

                // continue moving
                moveAmount += moveDirection;
                moveH      -= moveDirection;
                self.X     += moveDirection;
            }
            return(false);
        }
Exemple #2
0
        private static bool onActorMoveHExact(On.Celeste.Actor.orig_MoveHExact orig, Actor self, int moveH, Collision onCollide, Solid pusher)
        {
            // fall back to vanilla if no sideways jumpthru is in the room.
            if (self.Scene == null || !RoomContainsSidewaysJumpThrus(self))
            {
                return(orig(self, moveH, onCollide, pusher));
            }

            Vector2 targetPosition    = self.Position + Vector2.UnitX * moveH;
            int     moveDirection     = Math.Sign(moveH);
            int     moveAmount        = 0;
            bool    movingLeftToRight = moveH > 0;

            while (moveH != 0)
            {
                bool didCollide = false;

                // check if colliding with a solid
                Solid solid = self.CollideFirst <Solid>(self.Position + Vector2.UnitX * moveDirection);
                if (solid != null)
                {
                    didCollide = true;
                }
                else
                {
                    didCollide = CheckCollisionWithSidewaysJumpthruWhileMoving(self, moveDirection, movingLeftToRight);
                }

                if (didCollide)
                {
                    Vector2 movementCounter = (Vector2)actorMovementCounter.GetValue(self);
                    movementCounter.X = 0f;
                    actorMovementCounter.SetValue(self, movementCounter);
                    onCollide?.Invoke(new CollisionData {
                        Direction      = Vector2.UnitX * moveDirection,
                        Moved          = Vector2.UnitX * moveAmount,
                        TargetPosition = targetPosition,
                        Hit            = solid,
                        Pusher         = pusher
                    });
                    return(true);
                }

                // continue moving
                moveAmount += moveDirection;
                moveH      -= moveDirection;
                self.X     += moveDirection;
            }
            return(false);
        }
Exemple #3
0
        static bool Actor_MoveHExact(On.Celeste.Actor.orig_MoveHExact orig, Actor self, int moveH, Collision onCollide, Solid pusher)
        {
            bool barrierWasCollidable = self.Scene.Tracker.GetEntity <MoveBlockBarrier>()?.Collidable ?? false;

            foreach (Entity barrier in self.Scene.Tracker.GetEntities <MoveBlockBarrier>())
            {
                barrier.Collidable = false;
            }

            bool result = orig(self, moveH, onCollide, pusher);

            foreach (Entity barrier in self.Scene.Tracker.GetEntities <MoveBlockBarrier>())
            {
                barrier.Collidable = barrierWasCollidable;
            }

            return(result);
        }