public override void StartCommand(DHUI_FlightController _flightController, Transform _leader, Transform _drone)
        {
            base.StartCommand(_flightController, _leader, _drone);

            startPosition = _leader.position;
            startRotation = _leader.rotation;

            // If we are landing on the floor, the targeted positions are the given position projected onto the floor.
            if (floorLanding)
            {
                targetPosition.y = _flightController.GetFloorHeight();
            }

            touchDownHeight = targetPosition.y + _flightController.GetTriggerHeight_TouchDown();
            shutOffHeight   = targetPosition.y + flightController.GetTriggerHeight_ShutOff();


            target_TouchDownTrigger.rotation   = targetRotation;
            target_TouchDownTrigger.position   = targetPosition;
            target_TouchDownTrigger.position.y = touchDownHeight;

            time = Vector3.Distance(startPosition, target_TouchDownTrigger.position) / landingSpeed;

            currentState = LandingState.MoveTo;
        }
 private void Wait()
 {
     if (DroneReachedTargetTranslation() || (drone.position.y <= touchDownHeight && floorLanding) || Time.time >= waitingStartTime + waitingTimeout)
     {
         currentState = LandingState.TouchDown;
     }
 }
示例#3
0
        //TODO Add properties to the constructor


        public void RequestLanding()
        {
            LandingState = LandingState.Waiting;
            LandingLogger.LogLandingRequest(this);
            Mediator.EnqueueLandingRequest(this);
            // Passing this to the mediator is the key of this pattern!
        }
示例#4
0
    virtual protected void InitState()
    {
        State idleState       = new IdleState();
        State moveState       = new MoveState();
        State attackState     = new AttackState();
        State runState        = new RunState();
        State findTargetState = new FindTargetState();
        State takeOffState    = new TakeOffState();
        State landingState    = new LandingState();

        idleState.Init(this);
        moveState.Init(this);
        attackState.Init(this);
        runState.Init(this);
        findTargetState.Init(this);
        takeOffState.Init(this);
        landingState.Init(this);

        _stateDic.Add(eState.IDLE, idleState);
        _stateDic.Add(eState.MOVE, moveState);
        _stateDic.Add(eState.RUN, runState);
        _stateDic.Add(eState.ATTACK, attackState);
        _stateDic.Add(eState.FIND_TARGET, findTargetState);
        _stateDic.Add(eState.TAKE_OFF, takeOffState);
        _stateDic.Add(eState.LANDING, landingState);
    }
 private void TouchDown()
 {
     flightController.TrySetFlightState(DHUI_FlightController.FlightState.TouchDown);
     leader.position = drone.position;
     if (drone.position.y <= shutOffHeight)
     {
         currentState = LandingState.ShutOff;
     }
 }
 private void ShutOff()
 {
     leader.position = drone.position;
     DHUI_FlightController.FlightState newState = flightController.TrySetFlightState(DHUI_FlightController.FlightState.Parked);
     if (newState == DHUI_FlightController.FlightState.Parked)
     {
         currentState = LandingState.Done;
     }
     else
     {
         Debug.LogWarning("<b>DHUI</b> | FlightCommand_LandAt | Trying to Park drone, but shut off gets rejected. See other warnings and errors.");
     }
 }
    public void OnNodeEntered(LandingNode landingNode, IDirectable directable)
    {
        LandingState state = GetLandingState(directable);

        state.OnEnteredGate(landingNode.id);

        if (landingNode.id == _landingNodes.Count - 1)
        {
            if (state.isValid)
            {
                int index = UnityEngine.Random.Range(0, _tailsHooks.Length);
                _tailsHooks[index].LandDirectable(directable);
            }

            //directable.OnLandingAttempted(state.isValid && !state.hitWall, this);
            _landingStates.Remove(state);
        }
    }
    private LandingState GetLandingState(IDirectable directable)
    {
        for (int i = 0; i < _landingStates.Count; i++)
        {
            if (_landingStates[i].target == directable)
            {
                if (_landingStates[i].timeout < Time.timeSinceLevelLoad)
                {
                    _landingStates.RemoveAt(i);
                    break;
                }
                return(_landingStates[i]);
            }
        }
        LandingState landingState = new LandingState();

        landingState.target  = directable;
        landingState.timeout = _landingTimeout + Time.timeSinceLevelLoad;
        _landingStates.Add(landingState);
        return(landingState);
    }
        private void Move()
        {
            if (drone.position.y <= touchDownHeight && floorLanding)
            {
                currentState = LandingState.TouchDown;
                return;
            }

            float timeSinceStart = Time.time - startTime;
            float fraction       = timeSinceStart / time;

            if (fraction < 1)
            {
                leader.position = Vector3.Lerp(startPosition, target_TouchDownTrigger.position, fraction);
                leader.rotation = Quaternion.Slerp(startRotation, target_TouchDownTrigger.rotation, fraction);
            }
            else
            {
                leader.position  = target_TouchDownTrigger.position;
                leader.rotation  = target_TouchDownTrigger.rotation;
                currentState     = LandingState.WaitForDrone;
                waitingStartTime = Time.time;
            }
        }
示例#10
0
		public FlyToGrid(Mover mover, AllNavigationSettings navSet, string targetGrid,
			AttachedGrid.AttachmentKind allowedAttachment = AttachedGrid.AttachmentKind.Permanent)
			: base(mover, navSet)
		{
			this.m_logger = new Logger(GetType().Name, m_controlBlock.CubeBlock, () => m_landingState.ToString());
			this.m_targetBlock = m_navSet.Settings_Current.DestinationBlock;
			string blockName = m_targetBlock == null ? null : m_targetBlock.BlockName;
			this.m_gridFinder = new GridFinder(m_navSet, m_mover.Block, targetGrid, blockName, allowedAttachment);
			this.m_contBlock = m_navSet.Settings_Commands.NavigationBlock;

			PseudoBlock landingBlock = m_navSet.Settings_Current.LandingBlock;
			m_navBlock = landingBlock ?? m_navSet.Settings_Current.NavigationBlock;

			if (landingBlock != null)
			{
				if (landingBlock.Block is IMyFunctionalBlock)
					m_landingState = LandingState.Approach;
				else
				{
					m_logger.debugLog("landingBlock is not functional, player error? : " + landingBlock.Block.DisplayNameText, "FlyToGrid()", Logger.severity.INFO);
					m_landingState = LandingState.None;
				}

				if (m_targetBlock == null)
				{
					if (!(landingBlock.Block is IMyLandingGear))
					{
						m_logger.debugLog("cannot land block without a target", "FlyToGrid()", Logger.severity.INFO);
						m_landingState = LandingState.None;
					}
					else
					{
						m_logger.debugLog("golden retriever mode enabled", "FlyToGrid()", Logger.severity.INFO);
						m_landGearWithoutTargetBlock = true;
					}
				}
				else if (landingBlock.Block is Ingame.IMyShipConnector)
				{
					m_gridFinder.BlockCondition = block => {
						Ingame.IMyShipConnector connector = block as Ingame.IMyShipConnector;
						return connector != null && (!connector.IsConnected || connector.OtherConnector == m_navBlock.Block);
					};
					m_landingDirection = m_targetBlock.Forward ?? Base6Directions.GetFlippedDirection(landingBlock.Block.GetFaceDirection()[0]);
				}
				else if (landingBlock.Block is IMyShipMergeBlock)
				{
					m_gridFinder.BlockCondition = block => block is IMyShipMergeBlock;
					m_landingDirection = m_targetBlock.Forward ?? Base6Directions.GetFlippedDirection(landingBlock.Block.GetFaceDirection()[0]);
					(landingBlock.Block as IMyShipMergeBlock).BeforeMerge += MergeBlock_BeforeMerge;
				}
				else if (m_targetBlock.Forward.HasValue)
					m_landingDirection = m_targetBlock.Forward.Value;
				else
				{
					m_logger.debugLog("Player failed to specify landing direction and it could not be determined.", "FlyToGrid()", Logger.severity.INFO);
					m_landingState = LandingState.None;
				}

				if (m_landingState != LandingState.None)
				{
					float minDestRadius = m_controlBlock.CubeGrid.GetLongestDim() * 5f;
					if (m_navSet.Settings_Current.DestinationRadius < minDestRadius)
					{
						m_logger.debugLog("Increasing DestinationRadius from " + m_navSet.Settings_Current.DestinationRadius + " to " + minDestRadius, "FlyToGrid()", Logger.severity.DEBUG);
						m_navSet.Settings_Task_NavRot.DestinationRadius = minDestRadius;
					}

					new UnLander(mover, navSet, landingBlock);

					m_landingHalfSize = landingBlock.Block.GetLengthInDirection(landingBlock.Block.LocalMatrix.GetClosestDirection(landingBlock.LocalMatrix.Forward)) * 0.5f;
					m_logger.debugLog("m_landing direction: " + m_landingDirection + ", m_landingBlockSize: " + m_landingHalfSize, "FlyToGrid()");
				}
			}

			m_navSet.Settings_Task_NavMove.NavigatorMover = this;
		}
示例#11
0
		/// <summary>
		/// Subpart of Mover() that runs when ship is inside destination radius.
		/// </summary>
		private void Move_Land()
		{
			if (IsLocked())
			{
				m_logger.debugLog("Attached!", "Move_Land()", Logger.severity.INFO);
				m_navSet.OnTaskComplete_NavRot();
				m_mover.StopMove(false);
				m_mover.StopRotate();
				return;
			}

			switch (m_landingState)
			{
				case LandingState.None:
					{
						if (m_navSet.Settings_Current.Stay_In_Formation)
						{
							m_logger.debugLog("Maintaining relative position to target", "Move_Land()");
							m_mover.CalcMove(m_navBlock, m_navBlock.WorldPosition, m_gridFinder.Grid.GetLinearVelocity());
						}
						else
						{
							m_logger.debugLog("Arrived at target", "Move_Land()", Logger.severity.INFO);
							m_navSet.OnTaskComplete_NavMove();
							m_mover.StopMove();
							m_mover.StopRotate();
						}
						return;
					}
				case LandingState.Approach:
					{
						m_navSet.Settings_Task_NavRot.NavigatorRotator = this;
						m_navSet.Settings_Task_NavRot.NavigationBlock = m_navBlock;
						if (m_landGearWithoutTargetBlock)
						{
							m_landingState = LandingState.Catch;
							goto case LandingState.Catch;
						}
						else
						{
							m_landingState = LandingState.Holding;
							goto case LandingState.Holding;
						}
					}
				case LandingState.Holding:
					{
						if (m_gridFinder.Block != null)
						{
							m_logger.debugLog("Have a block, starting landing sequence", "Move_Land()", Logger.severity.DEBUG);
							m_landingState = LandingState.LineUp;
							return;
						}

						Vector3 destination = m_targetPosition;
						Vector3 directAway = m_navBlockPos - destination;
						if (directAway.LengthSquared() < 1)
						{
							destination = m_gridFinder.Grid.Entity.WorldAABB.Center;
							directAway = m_navBlockPos - destination;
						}
						Vector3D targetPosition = destination + Vector3.Normalize(directAway) * m_navSet.Settings_Current.DestinationRadius;

						m_logger.debugLog("destination: " + destination + ", directAway: " + Vector3.Normalize(directAway) + ", DestinationRadius: " + m_navSet.Settings_Current.DestinationRadius + ", targetPosition: " + targetPosition, "Move_Land()");

						m_mover.CalcMove(m_navBlock, targetPosition, m_gridFinder.Grid.GetLinearVelocity());

						return;
					}
				case LandingState.LineUp:
					{
						if (m_gridFinder.Block == null)
						{
							m_logger.debugLog("lost block", "Move_Land()");
							m_landingState = LandingState.Holding;
							return;
						}

						if (m_navSet.Settings_Current.Distance < 10f)
						{
							m_logger.debugLog("Reached line: " + m_navSet.Settings_Current.Distance, "Move_Land()");
							m_landingState = LandingState.Landing;
							return;
						}

						// move to line from target block outwards
						Vector3D landFaceVector = GetLandingFaceVector();
						Line destinationLine = new Line(m_targetPosition + landFaceVector * 20, m_targetPosition + landFaceVector * 1000);
						Vector3D closestPoint = destinationLine.ClosestPoint(m_navBlockPos);

						//m_logger.debugLog("Flying to closest point on line between " + destinationLine.From + " and " + destinationLine.To + " which is " + closestPoint, "Move_Land()");
						m_mover.CalcMove(m_navBlock, closestPoint, m_gridFinder.Grid.GetLinearVelocity());

						return;
					}
				case LandingState.Landing:
					{
						if (m_gridFinder.Block == null)
						{
							m_logger.debugLog("lost block", "Move_Land()");
							m_landingState = LandingState.Holding;
							return;
						}

						if (m_navSet.Settings_Current.DistanceAngle > 0.1f)
						{
							m_logger.debugLog("waiting for direction to match", "Move_Land()");
							m_mover.CalcMove(m_navBlock, m_navBlockPos, m_gridFinder.Grid.GetLinearVelocity(), true);
							return;
						}

						// the autopilot was sometimes freaking out and running away when it got really close
						if (m_navSet.DistanceLessThan(1f))
							m_navSet.Settings_Task_NavMove.DestinationEntity = m_gridFinder.Grid.Entity;

						LockConnector();

						float distanceBetween = m_gridFinder.Block.GetLengthInDirection(m_landingDirection) * 0.5f + m_landingHalfSize;
						m_logger.debugLog("moving to " + (m_targetPosition + GetLandingFaceVector() * distanceBetween) + ", distance: " + m_navSet.Settings_Current.Distance, "Move_Land()");
						m_mover.CalcMove(m_navBlock, m_targetPosition + GetLandingFaceVector() * distanceBetween, m_gridFinder.Grid.GetLinearVelocity(), true);
						return;
					}
				case LandingState.Catch:
					{
						if (m_navSet.Settings_Current.DistanceAngle > 0.1f)
						{
							m_logger.debugLog("waiting for direction to match", "Move_Land()");
							m_mover.CalcMove(m_navBlock, m_navBlockPos, m_gridFinder.Grid.GetLinearVelocity(), true);
							return;
						}

						m_logger.debugLog("moving to " + m_targetPosition, "Move_Land()");
						m_mover.CalcMove(m_navBlock, m_targetPosition, m_gridFinder.Grid.GetLinearVelocity(), true);
						return;
					}
			}
		}
示例#12
0
		public override void Move()
		{
			m_logger.debugLog(m_gridFinder == null, "m_gridFinder == null", "Move()", Logger.severity.FATAL);
			m_logger.debugLog(m_navSet == null, "m_navSet == null", "Move()", Logger.severity.FATAL);
			m_logger.debugLog(m_mover == null, "m_mover == null", "Move()", Logger.severity.FATAL);
			m_logger.debugLog(m_navBlock == null, "m_navBlock == null", "Move()", Logger.severity.FATAL);

			m_gridFinder.Update();

			if (m_gridFinder.Grid == null)
			{
				m_mover.StopMove();

				// only timeout if (Grid == null), ship could simply be waiting its turn
				if (DateTime.UtcNow > m_searchTimeoutAt)
				{
					m_logger.debugLog("Search timed out", "Move()", Logger.severity.INFO);
					m_navSet.OnTaskComplete_NavMove();
					m_mover.StopMove();
					m_mover.StopRotate();
					return;
				}

				if (m_landingState > LandingState.Approach)
				{
					m_logger.debugLog("Decreasing landing state from " + m_landingState + " to " + LandingState.Approach, "Move()", Logger.severity.DEBUG);
					m_landingState = LandingState.Approach;
				}

				return;
			}
			else
			{
				m_navBlockPos = m_navBlock.WorldPosition;
				m_targetPosition = m_gridFinder.GetPosition(m_navBlockPos, m_navSet.Settings_Current.DestinationOffset);

				if (m_gridFinder.Block != null && m_landingState != LandingState.Landing)
					m_navSet.Settings_Task_NavMove.DestinationEntity = m_gridFinder.Block;
				m_searchTimeoutAt = DateTime.UtcNow + SearchTimeout;

				float destRadius = m_navSet.Settings_Current.DestinationRadius; destRadius *= destRadius;
				if (m_landingState > LandingState.Approach || Vector3.DistanceSquared(m_navBlockPos, m_targetPosition) < destRadius)
				{
					m_logger.debugLog(m_landingState > LandingState.Approach, "m_landingState > LandingState.Approach", "Move()");
					m_logger.debugLog(m_navSet.Settings_Current.Distance < m_navSet.Settings_Current.DestinationRadius,
						"Distance < DestinationRadius, Distance: " + m_navSet.Settings_Current.Distance + ", DestinationRadius: " + m_navSet.Settings_Current.DestinationRadius, "Move()");

					Move_Land();
					return;
				}

				// set destination to be short of grid so pathfinder knows we will not hit it
				Vector3 targetToNav = m_navBlockPos - m_targetPosition;
				targetToNav.Normalize();
				float adjustment = m_navSet.Settings_Current.DestinationRadius * 0.5f;
				Vector3 destination = m_targetPosition + targetToNav * adjustment;

				m_logger.debugLog("m_targetPosition: " + m_targetPosition + ", moved by " + adjustment + " to " + destination + ", velocity: " + m_gridFinder.Grid.GetLinearVelocity(), "Move()");
				m_mover.CalcMove(m_navBlock, destination, m_gridFinder.Grid.GetLinearVelocity());
				m_navSet.Settings_Current.Distance += adjustment;
			}
		}
示例#13
0
 public async Task Land(Runaway whereTo)
 {
     this.LandingState = LandingState.Landing;
     var   timeToLand = (int)whereTo.Length / 175;
     await timeToLand;
 }
    /// <summary>
    /// Initialize controlling state machine
    /// </summary>
    private void InitializeStateMachine()
    {
        Debug.Log("Init state machine");

        // States
        IdleState idleState = new IdleState();
        idleState.Parent = this;
        mStateMachine.AddState(idleState);

        SkiState skiState = new SkiState();
        skiState.Parent = this;
        mStateMachine.AddState(skiState);

        CrouchState crouchState = new CrouchState();
        crouchState.Parent = this;
        mStateMachine.AddState(crouchState);

        JumpState jumpState = new JumpState();
        jumpState.Parent = this;
        mStateMachine.AddState(jumpState);

        InAirState inAirState = new InAirState();
        inAirState.Parent = this;
        mStateMachine.AddState(inAirState);

        LandingState landState = new LandingState();
        landState.Parent = this;
        mStateMachine.AddState(landState);

        FallDownState fallDownState = new FallDownState();
        fallDownState.Parent = this;
        mStateMachine.AddState(fallDownState);
        // Transitions ///////////////////

        // Grounded states
        mStateMachine.AddTransition( CharacterEvents.To_Ski, idleState, skiState);
        mStateMachine.AddTransition( CharacterEvents.To_Idle, skiState, idleState);

        // Jump / Land states
        mStateMachine.AddTransition( CharacterEvents.To_Crouch, skiState, crouchState);
        mStateMachine.AddTransition( CharacterEvents.To_Jump, crouchState, jumpState);
        mStateMachine.AddTransition( CharacterEvents.To_InAir, jumpState, inAirState);
        mStateMachine.AddTransition( CharacterEvents.To_Landing, inAirState, landState);
        mStateMachine.AddTransition( CharacterEvents.To_Ski, landState, skiState);

        // Ramp states
        mStateMachine.AddTransition( CharacterEvents.To_InAir, skiState, inAirState);

        // for initialization
        mStateMachine.AddTransition( CharacterEvents.To_InAir, idleState, inAirState);

        // for fall down
        mStateMachine.AddTransition( CharacterEvents.To_FallDown, idleState, fallDownState);
        mStateMachine.AddTransition( CharacterEvents.To_FallDown, skiState, fallDownState);
        mStateMachine.AddTransition( CharacterEvents.To_FallDown, crouchState, fallDownState);

        // character starts in a spawn in state
        mStateMachine.StartState = idleState;

        mStateMachine.Activate(null);

        DeactivateRagdoll();
    }
 public LandingEventArgs(LandingState currentLandingState, LandingState lastLandingState)
 {
     this.lastLandingState    = lastLandingState;
     this.currentLandingState = currentLandingState;
 }
示例#16
0
        public override void Move()
        {
            m_logger.debugLog(m_gridFinder == null, "m_gridFinder == null", Logger.severity.FATAL);
            m_logger.debugLog(m_navSet == null, "m_navSet == null", Logger.severity.FATAL);
            m_logger.debugLog(m_mover == null, "m_mover == null", Logger.severity.FATAL);
            m_logger.debugLog(m_navBlock == null, "m_navBlock == null", Logger.severity.FATAL);

            m_gridFinder.Update();

            if (m_gridFinder.Grid == null)
            {
                m_logger.debugLog("searching");
                m_mover.StopMove();

                // only timeout if (Grid == null), ship could simply be waiting its turn
                if (Globals.ElapsedTime > m_searchTimeoutAt)
                {
                    m_logger.debugLog("Search timed out", Logger.severity.INFO);
                    m_navSet.OnTaskComplete(m_settingLevel);
                    UnreserveTarget();
                    m_mover.StopMove();
                    m_mover.StopRotate();
                    return;
                }

                if (m_landingState > LandingState.Approach)
                {
                    m_logger.debugLog("Decreasing landing state from " + m_landingState + " to " + LandingState.Approach, Logger.severity.DEBUG);
                    m_landingState = LandingState.Approach;
                }

                return;
            }
            else
            {
                m_targetPosition = m_gridFinder.GetPosition(m_navBlock.WorldPosition, m_navSet.Settings_Current.DestinationOffset);

                if (m_gridFinder.Block != null && m_landingState < LandingState.Landing)
                    m_navSet.GetSettingsLevel(m_settingLevel).DestinationEntity = m_gridFinder.Block;
                m_searchTimeoutAt = Globals.ElapsedTime + SearchTimeout;

                if (m_landingState > LandingState.Approach || m_navBlock.Grid.WorldAABB.Distance(m_targetPosition) < m_navSet.Settings_Current.DestinationRadius)
                {
                    Move_Land();
                    return;
                }

                // set destination to be short of grid so pathfinder knows we will not hit it
                Vector3D targetToNav = m_navBlock.WorldPosition - m_targetPosition;
                targetToNav.Normalize();
                float adjustment = m_navSet.Settings_Current.DestinationRadius * 0.5f;
                Vector3D destination = m_targetPosition + targetToNav * adjustment;

                //m_logger.debugLog("m_targetPosition: " + m_targetPosition + ", moved by " + adjustment + " to " + destination + ", velocity: " + m_gridFinder.Grid.GetLinearVelocity(), "Move()");
                m_mover.CalcMove(m_navBlock, destination, m_gridFinder.Grid.GetLinearVelocity());
                m_navSet.Settings_Current.Distance += adjustment;
            }
        }
示例#17
0
        /// <summary>
        /// Subpart of Mover() that runs when ship is inside destination radius.
        /// </summary>
        private void Move_Land()
        {
            if (IsLocked())
            {
                m_logger.debugLog("Attached!", Logger.severity.INFO);
                m_navSet.OnTaskComplete(m_settingLevel);
                UnreserveTarget();
                m_mover.StopMove(false);
                m_mover.StopRotate();
                if (m_navSet.Shopper != null)
                {
                    m_logger.debugLog("starting shopper");
                    m_navSet.Shopper.Start();
                }
                return;
            }

            switch (m_landingState)
            {
                case LandingState.None:
                    {
                        if (m_navSet.Settings_Current.Stay_In_Formation)
                        {
                            m_logger.debugLog("Maintaining relative position to target");
                            m_mover.CalcMove(m_navBlock, m_navBlock.WorldPosition, m_gridFinder.Grid.GetLinearVelocity());
                        }
                        else
                        {
                            if (m_navSet.DirectionMatched())
                            {
                                m_logger.debugLog("Arrived at target", Logger.severity.INFO);
                                m_navSet.OnTaskComplete(m_settingLevel);
                                UnreserveTarget();
                                m_mover.StopRotate();
                            }
                            m_mover.StopMove();
                        }
                        return;
                    }
                case LandingState.Approach:
                    {
                        m_navSet.GetSettingsLevel(m_settingLevel).NavigatorRotator = this;
                        m_navSet.GetSettingsLevel(m_settingLevel).NavigationBlock = m_navBlock;
                        if (m_landGearWithoutTargetBlock)
                        {
                            m_landingState = LandingState.Catch;
                            goto case LandingState.Catch;
                        }
                        else
                        {
                            m_landingState = LandingState.Holding;
                            goto case LandingState.Holding;
                        }
                    }
                case LandingState.Holding:
                    {
                        if (m_gridFinder.Block != null)
                        {
                            m_logger.debugLog("Have a block, starting landing sequence", Logger.severity.DEBUG);
                            m_landingState = LandingState.LineUp;
                            return;
                        }
                        m_mover.CalcMove(m_navBlock, m_navBlock.WorldPosition, m_gridFinder.Grid.GetLinearVelocity());
                        return;
                    }
                case LandingState.LineUp:
                    {
                        if (m_gridFinder.Block == null)
                        {
                            m_logger.debugLog("lost block");
                            m_landingState = LandingState.Holding;
                            return;
                        }

                        if (m_navSet.DirectionMatched())
                        {
                            if (m_navSet.Settings_Current.Distance < 1f)
                            {
                                m_logger.debugLog("Reached line: " + m_navSet.Settings_Current.Distance);
                                m_landingState = LandingState.Landing;
                                return;
                            }
                        }
                        else if (!m_mover.Pathfinder.CanRotate)
                        {
                            Vector3 destination = m_targetPosition;
                            Vector3 directAway = m_navBlock.WorldPosition - destination;
                            if (directAway.LengthSquared() < 1)
                            {
                                destination = m_gridFinder.Grid.Entity.WorldAABB.Center;
                                directAway = m_navBlock.WorldPosition - destination;
                            }
                            Vector3D targetPosition = destination + Vector3.Normalize(directAway) * m_navSet.Settings_Current.DestinationRadius;

                            m_logger.debugLog("Pathfinder cannot rotate, moving away. destination: " + destination + ", directAway: " + Vector3.Normalize(directAway) +
                                ", DestinationRadius: " + m_navSet.Settings_Current.DestinationRadius + ", targetPosition: " + targetPosition);

                            m_mover.CalcMove(m_navBlock, targetPosition, m_gridFinder.Grid.GetLinearVelocity());
                            return;
                        }
                        else if (m_navSet.Settings_Current.Distance < 1f)
                        {
                            // replace do nothing (line) or other rotator that is preventing ship from landing
                            m_navSet.Settings_Task_NavWay.NavigatorRotator = this;
                        }

                        // move to line from target block outwards
                        Vector3D landFaceVector = GetLandingFaceVector();
                        float distanceBetween = m_gridFinder.Block.GetLengthInDirection(m_landingDirection) * 0.5f + m_landingHalfSize + 1f;
                        Line destinationLine = new Line(m_targetPosition + landFaceVector * distanceBetween, m_targetPosition + landFaceVector * 1000f);
                        Vector3D closestPoint = destinationLine.ClosestPoint(m_navBlock.WorldPosition);

                        //m_logger.debugLog("Flying to closest point on line between " + destinationLine.From + " and " + destinationLine.To + " which is " + closestPoint, "Move_Land()");
                        m_mover.CalcMove(m_navBlock, closestPoint, m_gridFinder.Grid.GetLinearVelocity());

                        return;
                    }
                case LandingState.Landing:
                    {
                        if (m_gridFinder.Block == null)
                        {
                            m_logger.debugLog("lost block");
                            m_landingState = LandingState.Holding;
                            return;
                        }

                        if (m_navSet.Settings_Current.DistanceAngle > 0.1f)
                        {
                            m_logger.debugLog("waiting for direction to match");
                            m_mover.CalcMove(m_navBlock, m_navBlock.WorldPosition, m_gridFinder.Grid.GetLinearVelocity());
                            return;
                        }

                        LockConnector();

                        float distanceBetween = m_gridFinder.Block.GetLengthInDirection(m_landingDirection) * 0.5f + m_landingHalfSize + 0.1f;
                        //m_logger.debugLog("moving to " + (m_targetPosition + GetLandingFaceVector() * distanceBetween) + ", distance: " + m_navSet.Settings_Current.Distance, "Move_Land()");

                        if (m_navSet.DistanceLessThan(1f))
                        {
                            m_landingSpeedFudge += 0.0001f;
                            if (m_landingSpeedFudge > 0.1f)
                                m_landingSpeedFudge = -0.1f;
                        }

                        Vector3 fudgeDistance = m_gridFinder.Grid.GetLinearVelocity() * m_landingSpeedFudge;
                        m_mover.CalcMove(m_navBlock, m_targetPosition + GetLandingFaceVector() * distanceBetween + fudgeDistance, m_gridFinder.Grid.GetLinearVelocity(), m_landingFriend);
                        return;
                    }
                case LandingState.Catch:
                    {
                        if (m_navSet.Settings_Current.DistanceAngle > 0.1f)
                        {
                            m_logger.debugLog("waiting for direction to match");
                            m_mover.CalcMove(m_navBlock, m_navBlock.WorldPosition, m_gridFinder.Grid.GetLinearVelocity());
                            return;
                        }

                        m_logger.debugLog("moving to " + m_targetPosition);
                        m_mover.CalcMove(m_navBlock, m_targetPosition, m_gridFinder.Grid.GetLinearVelocity(), m_landingFriend);
                        return;
                    }
            }
        }