Ejemplo n.º 1
0
        void SetOrbitHere(Entity entity, PositionDB positionDB, WarpMovingDB moveDB, DateTime atDateTime)
        {
            //propulsionDB.CurrentVectorMS = new Vector3(0, 0, 0);

            double targetSOI = OrbitProcessor.GetSOI_m(moveDB.TargetEntity);

            Entity targetEntity;

            if (moveDB.TargetEntity.GetDataBlob <PositionDB>().GetDistanceTo_m(positionDB) > targetSOI)
            {
                targetEntity = moveDB.TargetEntity.GetDataBlob <OrbitDB>().Parent; //TODO: it's concevable we could be in another SOI not the parent (ie we could be in a target's moon's SOI)
            }
            else
            {
                targetEntity = moveDB.TargetEntity;
            }
            OrbitDB targetOrbit = targetEntity.GetDataBlob <OrbitDB>();


            Vector3 insertionVector_m = OrbitProcessor.GetOrbitalInsertionVector_m(moveDB.SavedNewtonionVector, targetOrbit, atDateTime);

            positionDB.SetParent(targetEntity);

            if (moveDB.ExpendDeltaV.Length() != 0)
            {
                NewtonThrustCommand.CreateCommand(entity.FactionOwner, entity, entity.StarSysDateTime, moveDB.ExpendDeltaV);
                entity.RemoveDataBlob <WarpMovingDB>();
                moveDB.IsAtTarget = true;
            }
            else
            {
                OrbitDB newOrbit = OrbitDB.FromVelocity_m(targetEntity, entity, insertionVector_m, atDateTime);
                entity.RemoveDataBlob <WarpMovingDB>();


                if (newOrbit.Apoapsis < targetSOI) //furtherst point within soi, normal orbit
                {
                    entity.SetDataBlob(newOrbit);
                }
                else if (newOrbit.Periapsis > targetSOI) //closest point outside soi
                {
                    //find who's SOI we are in, and create an orbit around that.
                    targetEntity = OrbitProcessor.FindSOIForPosition((StarSystem)entity.Manager, positionDB.AbsolutePosition_m);
                    newOrbit     = OrbitDB.FromVelocity_m(targetEntity, entity, insertionVector_m, atDateTime);
                    entity.SetDataBlob(newOrbit);
                }
                else //closest point inside soi, but furtherest point outside. make a newtonion trajectory.
                {
                    var newtmove = new NewtonMoveDB(targetEntity, insertionVector_m);
                    entity.SetDataBlob(newtmove);
                }

                positionDB.SetParent(targetEntity);
                moveDB.IsAtTarget = true;
            }
        }
Ejemplo n.º 2
0
        void SetOrbitHere(Entity entity, PropulsionAbilityDB propulsionDB, PositionDB positionDB, TranslateMoveDB moveDB, DateTime atDateTime)
        {
            propulsionDB.CurrentVectorMS = new Vector3(0, 0, 0);

            double targetSOI = OrbitProcessor.GetSOI(moveDB.TargetEntity);

            Entity targetEntity;

            if (moveDB.TargetEntity.GetDataBlob <PositionDB>().GetDistanceTo(positionDB) > targetSOI)
            {
                targetEntity = moveDB.TargetEntity.GetDataBlob <OrbitDB>().Parent; //TODO: it's concevable we could be in another SOI not the parent (ie we could be in a target's moon's SOI)
            }
            else
            {
                targetEntity = moveDB.TargetEntity;
            }
            OrbitDB targetOrbit         = targetEntity.GetDataBlob <OrbitDB>();
            var     orbitalVector       = OrbitProcessor.GetOrbitalVector(targetOrbit, atDateTime);
            var     insertionVector2d   = OrbitProcessor.GetOrbitalInsertionVector(moveDB.SavedNewtonionVector_AU, targetOrbit, atDateTime);
            Vector3 parentOrbitalVector = new Vector3(orbitalVector.X, orbitalVector.Y, 0);
            Vector3 insertionVector     = new Vector3(insertionVector2d.X, insertionVector2d.Y, 0);

            insertionVector             += moveDB.ExpendDeltaV_AU; //TODO: only use it if we have it.
            propulsionDB.RemainingDV_MS -= (float)Distance.AuToMt(moveDB.ExpendDeltaV_AU).Length();
            OrbitDB newOrbit = OrbitDB.FromVector(targetEntity, entity, insertionVector, atDateTime);

            if (newOrbit.Periapsis > targetSOI)
            {
                //TODO: find who's SOI we're currently in and create an orbit for that;
            }
            if (newOrbit.Apoapsis > targetSOI)
            {
                //TODO: change orbit to new parent at SOI change
            }

            positionDB.SetParent(targetEntity);
            moveDB.IsAtTarget = true;
            entity.RemoveDataBlob <TranslateMoveDB>();
            entity.SetDataBlob(newOrbit);
            newOrbit.SetParent(targetEntity);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// This was designed so that fast moving objects will get interpolated a lot more than slow moving objects
        /// so fast moving objects shouldn't loose positional acuracy when close to a planet,
        /// and slow moving objects won't have processor time wasted on them by calulcating too often.
        /// However this seems to be unstable and looses energy, unsure why. currently set it to just itterate/interpolate every second.
        /// so currently will be using more time to get through this than neccisary.
        /// </summary>
        /// <param name="entity">Entity.</param>
        /// <param name="deltaSeconds">Delta seconds.</param>
        public static void NewtonMove(Entity entity, int deltaSeconds)
        {
            NewtonMoveDB          newtonMoveDB = entity.GetDataBlob <NewtonMoveDB>();
            NewtonThrustAbilityDB newtonThrust = entity.GetDataBlob <NewtonThrustAbilityDB>();
            PositionDB            positionDB   = entity.GetDataBlob <PositionDB>();
            double mass_Kg       = entity.GetDataBlob <MassVolumeDB>().Mass;
            double parentMass_kg = newtonMoveDB.ParentMass;

            var      manager        = entity.Manager;
            DateTime dateTimeFrom   = newtonMoveDB.LastProcessDateTime;
            DateTime dateTimeNow    = manager.ManagerSubpulses.StarSysDateTime;
            DateTime dateTimeFuture = dateTimeNow + TimeSpan.FromSeconds(deltaSeconds);
            double   deltaT         = (dateTimeFuture - dateTimeFrom).TotalSeconds;

            double secondsToItterate = deltaT;

            while (secondsToItterate > 0)
            {
                //double timeStep = Math.Max(secondsToItterate / speed_kms, 1);
                //timeStep = Math.Min(timeStep, secondsToItterate);
                double timeStepInSeconds  = 1;//because the above seems unstable and looses energy.
                double distanceToParent_m = positionDB.GetDistanceTo_m(newtonMoveDB.SOIParent.GetDataBlob <PositionDB>());

                distanceToParent_m = Math.Max(distanceToParent_m, 0.1); //don't let the distance be 0 (once collision is in this will likely never happen anyway)

                double  gravForce       = GameConstants.Science.GravitationalConstant * (mass_Kg * parentMass_kg / Math.Pow(distanceToParent_m, 2));
                Vector3 gravForceVector = gravForce * -Vector3.Normalise(positionDB.RelativePosition_m);

                Vector3 totalDVFromGrav = (gravForceVector / mass_Kg) * timeStepInSeconds;

                double maxAccelFromThrust1 = newtonThrust.ExhaustVelocity * Math.Log(mass_Kg / (mass_Kg - newtonThrust.FuelBurnRate)); //per second
                double maxAccelFromThrust  = newtonThrust.ThrustInNewtons / mass_Kg;                                                   //per second


                Vector3 manuverDV = newtonMoveDB.DeltaVForManuver_m;                      //how much dv needed to complete the manuver.

                double dryMass = mass_Kg - newtonThrust.FuelBurnRate * timeStepInSeconds; //how much our ship weighs after a timestep of fuel is used.
                //how much dv can we get in this timestep.
                double deltaVThisStep = OrbitMath.TsiolkovskyRocketEquation(mass_Kg, dryMass, newtonThrust.ExhaustVelocity);
                deltaVThisStep = Math.Min(manuverDV.Length(), deltaVThisStep);  //don't use more Dv than what is called for.
                deltaVThisStep = Math.Min(newtonThrust.DeltaV, deltaVThisStep); //check we've got the deltaV to spend.

                Vector3 totalDVFromThrust = Vector3.Normalise(manuverDV) * deltaVThisStep;

                //remove the deltaV we're expending from the max (TODO: Remove fuel from cargo, change mass of ship)
                newtonThrust.DeltaV -= deltaVThisStep;
                //remove the vectorDV from the amount needed to fully complete the manuver.
                newtonMoveDB.DeltaVForManuver_m -= totalDVFromThrust;



                Vector3 totalDV     = totalDVFromGrav + totalDVFromThrust;
                Vector3 newVelocity = totalDV + newtonMoveDB.CurrentVector_ms;

                newtonMoveDB.CurrentVector_ms = newVelocity;
                Vector3 deltaPos = (newtonMoveDB.CurrentVector_ms + newVelocity) / 2 * timeStepInSeconds;

                positionDB.RelativePosition_m += deltaPos;

                double sOIRadius = OrbitProcessor.GetSOI_m(newtonMoveDB.SOIParent);



                if (positionDB.RelativePosition_m.Length() >= sOIRadius)
                {
                    Entity  newParent;
                    Vector3 parentRalitiveVector;
                    //if our parent is a regular kepler object (normaly this is the case)
                    if (newtonMoveDB.SOIParent.HasDataBlob <OrbitDB>())
                    {
                        var orbitDB = newtonMoveDB.SOIParent.GetDataBlob <OrbitDB>();
                        newParent = orbitDB.Parent;
                        var parentVelocity = OrbitProcessor.InstantaneousOrbitalVelocityVector_m(orbitDB, entity.StarSysDateTime);
                        parentRalitiveVector = newtonMoveDB.CurrentVector_ms + parentVelocity;
                    }
                    else //if (newtonMoveDB.SOIParent.HasDataBlob<NewtonMoveDB>())
                    {   //this will pretty much never happen.
                        newParent = newtonMoveDB.SOIParent.GetDataBlob <NewtonMoveDB>().SOIParent;
                        var parentVelocity = newtonMoveDB.SOIParent.GetDataBlob <NewtonMoveDB>().CurrentVector_ms;
                        parentRalitiveVector = newtonMoveDB.CurrentVector_ms + parentVelocity;
                    }
                    parentMass_kg = newParent.GetDataBlob <MassVolumeDB>().Mass;

                    Vector3 posRalitiveToNewParent = positionDB.AbsolutePosition_m - newParent.GetDataBlob <PositionDB>().AbsolutePosition_m;


                    var    dateTime = dateTimeNow + TimeSpan.FromSeconds(deltaSeconds - secondsToItterate);
                    double sgp      = GMath.StandardGravitationalParameter(parentMass_kg + mass_Kg);
                    var    kE       = OrbitMath.KeplerFromPositionAndVelocity(sgp, posRalitiveToNewParent, parentRalitiveVector, dateTime);

                    positionDB.SetParent(newParent);
                    newtonMoveDB.ParentMass       = parentMass_kg;
                    newtonMoveDB.SOIParent        = newParent;
                    newtonMoveDB.CurrentVector_ms = parentRalitiveVector;
                }

                if (newtonMoveDB.DeltaVForManuver_m.Length() <= 0) //if we've completed the manuver.
                {
                    var    dateTime = dateTimeNow + TimeSpan.FromSeconds(deltaSeconds - secondsToItterate);
                    double sgp      = GMath.StandardGravitationalParameter(parentMass_kg + mass_Kg);

                    KeplerElements kE = OrbitMath.KeplerFromPositionAndVelocity(sgp, positionDB.RelativePosition_m, newtonMoveDB.CurrentVector_ms, dateTime);

                    var parentEntity = Entity.GetSOIParentEntity(entity, positionDB);

                    if (kE.Eccentricity < 1) //if we're going to end up in a regular orbit around our new parent
                    {
                        var newOrbit = OrbitDB.FromKeplerElements(
                            parentEntity,
                            mass_Kg,
                            kE,
                            dateTime);
                        entity.RemoveDataBlob <NewtonMoveDB>();
                        entity.SetDataBlob(newOrbit);
                        positionDB.SetParent(parentEntity);
                        var newPos = OrbitProcessor.GetPosition_m(newOrbit, dateTime);
                        positionDB.RelativePosition_m = newPos;
                    }
                    break;
                }

                secondsToItterate -= timeStepInSeconds;
            }
            newtonMoveDB.LastProcessDateTime = dateTimeFuture;
        }
Ejemplo n.º 4
0
        /// <summary>
        /// process PropulsionDB movement for a single system
        /// </summary>
        /// <param name="manager">the system to process</param>
        /// <param name="deltaSeconds">amount of time in seconds</param>
        internal static void Process(EntityManager manager, int deltaSeconds)
        {
            OrderProcessor.ProcessSystem(manager);
            foreach (Entity shipEntity in manager.GetAllEntitiesWithDataBlob <PropulsionDB>())
            {
                PositionDB   positionDB   = shipEntity.GetDataBlob <PositionDB>();
                PropulsionDB propulsionDB = shipEntity.GetDataBlob <PropulsionDB>();


                Queue <BaseOrder> orders = shipEntity.GetDataBlob <ShipInfoDB>().Orders;

                if (orders.Count > 0)
                {
                    if (orders.Peek().OrderType == orderType.MOVETO)
                    {
                        // Check to see if we will overtake the target

                        MoveOrder order   = (MoveOrder)orders.Peek();
                        Vector4   shipPos = positionDB.AbsolutePosition;
                        Vector4   targetPos;
                        Vector4   currentSpeed = shipEntity.GetDataBlob <PropulsionDB>().CurrentSpeed;
                        Vector4   nextTPos     = shipPos + (currentSpeed * deltaSeconds);
                        Vector4   newPos       = shipPos;
                        Vector4   deltaVecToTarget;
                        Vector4   deltaVecToNextT;

                        double distanceToTarget;
                        double distanceToNextTPos;

                        double speedDelta;
                        double distanceDelta;
                        double newDistanceDelta;
                        double fuelMaxDistanceAU;

                        double currentSpeedLength = currentSpeed.Length();

                        CargoStorageDB            storedResources = shipEntity.GetDataBlob <CargoStorageDB>();
                        Dictionary <Guid, double> fuelUsePerMeter = propulsionDB.FuelUsePerKM;
                        int maxKMeters = CalcMaxFuelDistance(shipEntity);

                        if (order.PositionTarget == null)
                        {
                            targetPos = order.Target.GetDataBlob <PositionDB>().AbsolutePosition;
                        }
                        else
                        {
                            targetPos = order.PositionTarget.AbsolutePosition;
                        }

                        deltaVecToTarget = shipPos - targetPos;

                        distanceToTarget = deltaVecToTarget.Length();  //in au


                        deltaVecToNextT   = shipPos - nextTPos;
                        fuelMaxDistanceAU = GameConstants.Units.KmPerAu * maxKMeters;


                        distanceToNextTPos = deltaVecToNextT.Length();
                        if (fuelMaxDistanceAU < distanceToNextTPos)
                        {
                            newDistanceDelta = fuelMaxDistanceAU;
                            double percent = fuelMaxDistanceAU / distanceToNextTPos;
                            newPos = nextTPos + deltaVecToNextT * percent;
                            Event usedAllFuel = new Event(manager.ManagerSubpulses.SystemLocalDateTime, "Used all Fuel", shipEntity.GetDataBlob <OwnedDB>().ObjectOwner, shipEntity);
                            usedAllFuel.EventType = EventType.FuelExhausted;
                            manager.Game.EventLog.AddEvent(usedAllFuel);
                        }
                        else
                        {
                            newDistanceDelta = distanceToNextTPos;
                            newPos           = nextTPos;
                        }



                        if (distanceToTarget < newDistanceDelta) // moving would overtake target, just go directly to target
                        {
                            newDistanceDelta          = distanceToTarget;
                            propulsionDB.CurrentSpeed = new Vector4(0, 0, 0, 0);
                            newPos = targetPos;
                            if (order.Target != null && order.Target.HasDataBlob <SystemBodyInfoDB>())
                            {
                                positionDB.SetParent(order.Target);
                            }
                            if (order.Target != null)
                            {
                                if (order.Target.HasDataBlob <SystemBodyInfoDB>())  // Set position to the target body
                                {
                                    positionDB.SetParent(order.Target);
                                }
                            }

                            else // We arrived, get rid of the order
                            {
                                shipEntity.GetDataBlob <ShipInfoDB>().Orders.Dequeue();
                            }
                        }
                        positionDB.AbsolutePosition = newPos;
                        int kMetersMoved = (int)(newDistanceDelta * GameConstants.Units.KmPerAu);
                        Dictionary <Guid, int> fuelAmounts = new Dictionary <Guid, int>();
                        foreach (var item in propulsionDB.FuelUsePerKM)
                        {
                            fuelAmounts.Add(item.Key, (int)item.Value * kMetersMoved);
                        }
                        StorageSpaceProcessor.RemoveResources(storedResources, fuelAmounts);
                    }
                }
            }
        }
Ejemplo n.º 5
0
        /// <summary>
        /// This was designed so that fast moving objects will get interpolated a lot more than slow moving objects
        /// so fast moving objects shouldn't loose positional acuracy when close to a planet,
        /// and slow moving objects won't have processor time wasted on them by calulcating too often.
        /// However this seems to be unstable and looses energy, unsure why. currently set it to just itterate/interpolate every second.
        /// so currently will be using more time to get through this than neccisary.
        /// </summary>
        /// <param name="entity">Entity.</param>
        /// <param name="deltaSeconds">Delta seconds.</param>
        public static void NewtonMove(Entity entity, int deltaSeconds)
        {
            NewtonMoveDB newtonMoveDB  = entity.GetDataBlob <NewtonMoveDB>();
            PositionDB   positionDB    = entity.GetDataBlob <PositionDB>();
            double       Mass_Kg       = entity.GetDataBlob <MassVolumeDB>().Mass;
            double       ParentMass_kg = newtonMoveDB.ParentMass;

            var      manager        = entity.Manager;
            DateTime dateTimeFrom   = newtonMoveDB.LastProcessDateTime;
            DateTime dateTimeNow    = manager.ManagerSubpulses.StarSysDateTime;
            DateTime dateTimeFuture = dateTimeNow + TimeSpan.FromSeconds(deltaSeconds);
            double   deltaT         = (dateTimeFuture - dateTimeFrom).TotalSeconds;

            double secondsToItterate = deltaT;

            while (secondsToItterate > 0)
            {
                double speed_kms = newtonMoveDB.CurrentVector_kms.Length();


                //double timeStep = Math.Max(secondsToItterate / speed_kms, 1);
                //timeStep = Math.Min(timeStep, secondsToItterate);
                double timeStep           = 1;//because the above seems unstable and looses energy.
                double distanceToParent_m = Distance.AuToMt(positionDB.GetDistanceTo(newtonMoveDB.SOIParent.GetDataBlob <PositionDB>()));

                distanceToParent_m = Math.Max(distanceToParent_m, 0.1); //don't let the distance be 0 (once collision is in this will likely never happen anyway)

                double  gravForce       = GameConstants.Science.GravitationalConstant * (Mass_Kg * ParentMass_kg / Math.Pow(distanceToParent_m, 2));
                Vector3 gravForceVector = gravForce * -Vector3.Normalise(positionDB.RelativePosition_AU);
                double  distance        = Distance.AuToKm(positionDB.RelativePosition_AU).Length();
                Vector3 totalForce      = gravForceVector + newtonMoveDB.ThrustVector;

                Vector3 acceleration_mps = totalForce / Mass_Kg;
                Vector3 newVelocity      = (acceleration_mps * timeStep * 0.001) + newtonMoveDB.CurrentVector_kms;

                newtonMoveDB.CurrentVector_kms = newVelocity;
                Vector3 deltaPos = (newtonMoveDB.CurrentVector_kms + newVelocity) / 2 * timeStep;
                //Vector4 deltaPos = newtonMoveDB.CurrentVector_kms * timeStep;

                positionDB.RelativePosition_AU += Distance.KmToAU(deltaPos);

                double sOIRadius_AU = OrbitProcessor.GetSOI(newtonMoveDB.SOIParent);

                if (positionDB.RelativePosition_AU.Length() >= sOIRadius_AU)
                {
                    Entity  newParent;
                    Vector3 parentRalitiveVector;
                    //if our parent is a regular kepler object (normaly this is the case)
                    if (newtonMoveDB.SOIParent.HasDataBlob <OrbitDB>())
                    {
                        var orbitDB = newtonMoveDB.SOIParent.GetDataBlob <OrbitDB>();
                        newParent = orbitDB.Parent;
                        var parentVelocity = OrbitProcessor.InstantaneousOrbitalVelocityVector(orbitDB, entity.Manager.ManagerSubpulses.StarSysDateTime);
                        parentRalitiveVector = Distance.KmToAU(newtonMoveDB.CurrentVector_kms) + parentVelocity;
                        var pvlen = Distance.AuToKm(parentVelocity.Length());
                        var vlen  = newtonMoveDB.CurrentVector_kms.Length();
                        var rvlen = Distance.AuToKm(parentRalitiveVector.Length());
                    }
                    else //if (newtonMoveDB.SOIParent.HasDataBlob<NewtonMoveDB>())
                    {   //this will pretty much never happen.
                        newParent = newtonMoveDB.SOIParent.GetDataBlob <NewtonMoveDB>().SOIParent;
                        var parentVelocity = newtonMoveDB.SOIParent.GetDataBlob <NewtonMoveDB>().CurrentVector_kms;
                        parentRalitiveVector = Distance.KmToAU(newtonMoveDB.CurrentVector_kms + parentVelocity);
                    }
                    double  newParentMass          = newParent.GetDataBlob <MassVolumeDB>().Mass;
                    double  sgp                    = GameConstants.Science.GravitationalConstant * (newParentMass + Mass_Kg) / 3.347928976e33;
                    Vector3 posRalitiveToNewParent = positionDB.AbsolutePosition_AU - newParent.GetDataBlob <PositionDB>().AbsolutePosition_AU;

                    var dateTime = dateTimeNow + TimeSpan.FromSeconds(deltaSeconds - secondsToItterate);
                    var kE       = OrbitMath.KeplerFromPositionAndVelocity(sgp, posRalitiveToNewParent, parentRalitiveVector, dateTime);

                    if (kE.Eccentricity < 1) //if we're going to end up in a regular orbit around our new parent
                    {
                        /*
                         * var newOrbit = OrbitDB.FromKeplerElements(
                         *  newParent,
                         *  newParentMass,
                         *  Mass_Kg,
                         *  kE,
                         *  dateTime);
                         */
                        var newOrbit = OrbitDB.FromVector(newParent, entity, parentRalitiveVector, dateTime);
                        entity.RemoveDataBlob <NewtonMoveDB>();
                        entity.SetDataBlob(newOrbit);
                        positionDB.SetParent(newParent);
                        var currentPos = Distance.AuToKm(positionDB.RelativePosition_AU);
                        var newPos     = OrbitProcessor.GetPosition_AU(newOrbit, dateTime);
                        var newPosKM   = Distance.AuToKm(newPos);
                        positionDB.RelativePosition_AU = newPos;
                        break;
                    }
                    else //else we're in a hyperbolic trajectory around our new parent, so just coninue the newtonion move.
                    {
                        positionDB.SetParent(newParent);
                        newtonMoveDB.ParentMass = newParentMass;
                        newtonMoveDB.SOIParent  = newParent;
                    }
                }
                secondsToItterate -= timeStep;
            }
            newtonMoveDB.LastProcessDateTime = dateTimeFuture;
        }
Ejemplo n.º 6
0
        // sets the speed of the ship to the maximum speed allowed in the direction of the target.
        // Returns true if the destination has been reached or the target no longer exists.
        public override bool processOrder()
        {
            double speedMultiplier = 1.0; //was this just for debugging? if so we should remove it, if not, then maybe move it to game settings?

            double     minimumDistance = 1000.0;
            PositionDB currentPosition = Owner.GetDataBlob <PositionDB>();
            PositionDB targetPosition = null;
            double     AUSpeed, kmSpeed;

            kmSpeed = Owner.GetDataBlob <PropulsionDB>().MaximumSpeed *speedMultiplier;
            AUSpeed = Distance.KmToAU(kmSpeed);

            currentPosition.SetParent(null);

            if (PositionTarget != null)
            {
                // just head straight towards the target position
                targetPosition = PositionTarget;

                // Assume that 1000 is extremely close,
                if (Distance.AuToKm(distanceBetweenPositions(currentPosition, targetPosition)) <= minimumDistance)
                {
                    setPositionToTarget(Owner, targetPosition);
                    Owner.GetDataBlob <PropulsionDB>().CurrentSpeed = new Vector4(0, 0, 0, 0);
                    return(true);
                }
                else
                {
                    Owner.GetDataBlob <PropulsionDB>().CurrentSpeed = getSpeed(currentPosition, targetPosition, kmSpeed);
                    return(false);
                }
            }
            else if (Target == null || Target == Entity.InvalidEntity) // Target no longer exists
            {
                return(true);
            }
            else
            {
                targetPosition = Target.GetDataBlob <PositionDB>();

                // Assume that 1000 is extremely close,
                if (Distance.AuToKm(distanceBetweenPositions(currentPosition, targetPosition)) <= minimumDistance)
                {
                    setPositionToTarget(Owner, targetPosition);

                    currentPosition.SetParent(Target);

                    return(true);
                }



                if (Target.HasDataBlob <OrbitDB>())
                {
                    if (Target.GetDataBlob <OrbitDB>().IsStationary)
                    {
                        // just head straight towards the target position
                        targetPosition = Target.GetDataBlob <PositionDB>();
                        Owner.GetDataBlob <PropulsionDB>().CurrentSpeed = getSpeed(currentPosition, targetPosition, kmSpeed);
                    }
                    else
                    {
                        // TODO: Figure out an intercept based on OrbitProcessor.GetPosition
                        // for now, just head straight towards the target position

                        targetPosition = Target.GetDataBlob <PositionDB>();
                        Owner.GetDataBlob <PropulsionDB>().CurrentSpeed = getSpeed(currentPosition, targetPosition, kmSpeed);
                        return(false);
                    }
                }

                else if (Target.HasDataBlob <PropulsionDB>())
                {
                    if (Target.GetDataBlob <PropulsionDB>().MaximumSpeed >= Owner.GetDataBlob <PropulsionDB>().MaximumSpeed)
                    // Target is faster than our ship, and cannot intercept
                    {
                        // Just head in a straight line
                        targetPosition = Target.GetDataBlob <PositionDB>();
                        Owner.GetDataBlob <PropulsionDB>().CurrentSpeed = getSpeed(currentPosition, targetPosition, kmSpeed);
                    }
                    else
                    {
                        // Calculate an intercept
                        targetPosition = Target.GetDataBlob <PositionDB>();
                        Vector4 targetPos  = new Vector4(targetPosition.X, targetPosition.Y, targetPosition.Z, 0);
                        Vector4 currentPos = new Vector4(currentPosition.X, currentPosition.Y, currentPosition.Z, 0);
                        targetPos      = Find_collision_point(targetPos, Target.GetDataBlob <PropulsionDB>().CurrentSpeed, currentPos, AUSpeed);
                        targetPosition = new PositionDB(targetPos, targetPosition.SystemGuid);
                        Owner.GetDataBlob <PropulsionDB>().CurrentSpeed = getSpeed(currentPosition, targetPosition, kmSpeed);
                    }
                }
            }


            return(false);
        }