Beispiel #1
0
        public bool CanMove(Level level, Direction dir)
        {
            // Recursive movement ability checking
            var targetPos = _entity.Position + Utils.MoveDelta(dir);

            foreach (var entityInTargetPos in level.GetActiveEntitiesAt(targetPos))
            {
                // If we collide with object in a target position and an object can be pushed
                // Then recursively check whether it has some space to move
                if (CollisionConfig.ObjectsCollide(_entity.ObjectType, entityInTargetPos.ObjectType))
                {
                    if (CollisionConfig.CanPush(
                            _entity.ObjectType,
                            entityInTargetPos.ObjectType))
                    {
                        var movable = entityInTargetPos.GetComponent <Movable>();
                        if (movable != null)
                        {
                            return(movable.CanMove(level, dir));
                        }
                    }
                    return(false);
                }
            }

            // No obstacles or no collisions
            return(true);
        }
Beispiel #2
0
        public IEnumerable <IChange> DoMove(Level level, Direction moveDirection, bool updateOrientation, MovementType movementType)
        {
            var canMove = CanMove(level, moveDirection);

            // Update logical position
            var targetPos = _entity.Position + Utils.MoveDelta(moveDirection);

            // Move neighbor movable (push)
            foreach (var entityInTargetPos in level.GetActiveEntitiesAt(targetPos))
            {
                // If current object collides with target object
                if (CollisionConfig.ObjectsCollide(_entity.ObjectType, entityInTargetPos.ObjectType))
                {
                    level.DispatchEarly(new CollisionEvent(
                                            target: entityInTargetPos.Id,
                                            sourceId: _entity.Id,
                                            direction: Utils.AbsoluteDirectionToRelative(Utils.RevertDirection(moveDirection), entityInTargetPos.Orientation)));
                    level.DispatchEarly(new CollisionEvent(
                                            target: _entity.Id,
                                            sourceId: entityInTargetPos.Id,
                                            direction: Utils.AbsoluteDirectionToRelative(moveDirection, _entity.Orientation)));

                    // Push (collidable only)
                    if (canMove && CollisionConfig.CanPush(
                            _entity.ObjectType,
                            entityInTargetPos.ObjectType))
                    {
                        var movable = entityInTargetPos.GetComponent <Movable>();
                        if (movable != null)
                        {
                            foreach (var change in movable.DoMove(level, moveDirection, false, MovementType.Pushed))
                            {
                                yield return(change);
                            }
                        }
                    }
                }

                if (CollisionConfig.ObjectsHit(_entity.ObjectType, entityInTargetPos.ObjectType))
                {
                    level.DispatchEarly(new HitCommand(
                                            target: entityInTargetPos.Id,
                                            sourceId: _entity.Id,
                                            direction: Utils.AbsoluteDirectionToRelative(Utils.RevertDirection(moveDirection), entityInTargetPos.Orientation)));
                    level.DispatchEarly(new HitCommand(
                                            target: _entity.Id,
                                            sourceId: entityInTargetPos.Id,
                                            direction: Utils.AbsoluteDirectionToRelative(moveDirection, _entity.Orientation)));
                }
            }

            if (!canMove)
            {
                yield break;
            }

            if (!_entity.IsActive)
            {
                yield break;
            }

            // Finally, move self
            targetPos = _entity.Position + Utils.MoveDelta(moveDirection);
            var targetOrientation = _entity.Orientation;

            if (updateOrientation)
            {
                targetOrientation = moveDirection;
            }

            // Effects
            SoundManager.Instance.Play(MoveSound);

            var selfMove = new MoveChange(_entity.Id)
            {
                OriginalOrientation = _entity.Orientation,
                OriginalPosition    = _entity.Position,
                TargetOrientation   = targetOrientation,
                TargetPosition      = targetPos,
                MovementType        = movementType
            };

            _entity.MoveTo(targetPos, targetOrientation, movementType);
            yield return(selfMove);
        }