/// <summary>
        /// Do all the launch things.
        /// </summary>
        /// <param name="transferList"></param>
        /// <returns></returns>
        protected bool DoLaunchTasks(List <OrbitalLogisticsTransferRequest> transferList)
        {
            if (transferList.Contains(this))
            {
                return(false);
            }

            // Deduct the resources from the origin vessel
            double deductedAmount;

            foreach (var request in ResourceRequests)
            {
                deductedAmount         = Origin.ExchangeResources(request.ResourceDefinition, -request.TransferAmount);
                request.TransferAmount = Math.Abs(deductedAmount);
            }

            // Since the mass and fuel required won't change after launch, cache them
            //   to prevent running the calculations repeatedly
            Status     = DeliveryStatus.PreLaunch; // TotalMass and CalculateFuelUnits will return cached values if Status is not PreLaunch
            _mass      = TotalMass();
            _fuelUnits = CalculateFuelUnits();

            // Perform other launch tasks
            DoFinalLaunchTasks(transferList);

            return(true);
        }
예제 #2
0
        /// <summary>
        /// Executes the resource transfers between the source and destination vessels.
        /// </summary>
        public IEnumerator Deliver()
        {
            // If either vessel no longer exists, fail.
            if (Origin == null || Destination == null)
            {
                Status = DeliveryStatus.Failed;
                yield break;
            }

            // If the vessels are no longer in the same SoI, fail.
            if (Origin.mainBody != Destination.mainBody)
            {
                Status = DeliveryStatus.Failed;
                yield break;
            }

            // If either of the vessels is no longer in an allowed situation, fail.
            if (Origin.protoVessel.situation != (Origin.protoVessel.situation & ALLOWED_SITUATIONS) ||
                Destination.protoVessel.situation != (Destination.protoVessel.situation & ALLOWED_SITUATIONS))
            {
                Status = DeliveryStatus.Failed;
                yield break;
            }

            // Exchange resources between origin and destination vessels
            bool   deliveredAll = true;
            double deliveredAmount;
            double precisionTolerance;

            foreach (var request in ResourceRequests)
            {
                // If transfer was cancelled, return resources to origin vessel
                if (Status == DeliveryStatus.Returning)
                {
                    deliveredAmount = Origin.ExchangeResources(request.ResourceDefinition, request.TransferAmount);
                }
                // Otherwise, deliver resources to destination vessel
                else
                {
                    deliveredAmount = Destination.ExchangeResources(request.ResourceDefinition, request.TransferAmount);
                }

                // Because with floating point math, 1 minus 1 doesn't necessarily equal 0.  ^_^
                precisionTolerance = Math.Abs(request.TransferAmount) * 0.001;
                deliveredAll      &= Math.Abs(request.TransferAmount - Math.Abs(deliveredAmount)) <= precisionTolerance;

                yield return(null);
            }

            if (Status == DeliveryStatus.Returning)
            {
                Status = DeliveryStatus.Cancelled;
            }
            else
            {
                Status = deliveredAll ? DeliveryStatus.Delivered : DeliveryStatus.Partial;
            }
        }
        /// <summary>
        /// Executes the resource transfers between the source and destination vessels.
        /// </summary>
        public IEnumerator Deliver()
        {
            // If either vessel no longer exists, fail.
            if (Origin == null || Destination == null)
            {
                Status        = DeliveryStatus.Failed;
                StatusMessage = "The origin or destination vessel no longer exists.";
                yield break;
            }

            // If the vessels are no longer in the same SoI, fail.
            if (Origin.mainBody != Destination.mainBody)
            {
                Status        = DeliveryStatus.Failed;
                StatusMessage = "The origin and destination vessels are no longer in the same sphere of influence.";
                yield break;
            }

            // If either of the vessels is no longer in an allowed situation, fail.
            if (Origin.protoVessel.situation != (Origin.protoVessel.situation & ALLOWED_SITUATIONS) ||
                Destination.protoVessel.situation != (Destination.protoVessel.situation & ALLOWED_SITUATIONS))
            {
                Status        = DeliveryStatus.Failed;
                StatusMessage = "The origin or destination vessel is no longer in an allowed situation for logistics transfers.";
                yield break;
            }

            // If the destination no longer has the OrbLog module it had when the transfer was initiated, fail.
            var whoHasTheDestinationOrbLogModule = ModuleOrbitalLogistics.FindVesselByOrbLogModuleId(_destinationModuleId);

            if (Destination != whoHasTheDestinationOrbLogModule)
            {
                Status        = DeliveryStatus.Failed;
                StatusMessage = "The target logistics module could not be found on the destination vessel.";
                yield break;
            }

            // Exchange resources between origin and destination vessels
            bool   deliveredAll = true;
            double deliveredAmount;
            double precisionTolerance;

            foreach (var request in ResourceRequests)
            {
                // If transfer was cancelled, return resources to origin vessel
                if (Status == DeliveryStatus.Returning)
                {
                    deliveredAmount = Origin.ExchangeResources(request.ResourceDefinition, request.TransferAmount);
                }
                // Otherwise, deliver resources to destination vessel
                else
                {
                    deliveredAmount = Destination.ExchangeResources(request.ResourceDefinition, request.TransferAmount);
                }

                // Because with floating point math, 1 minus 1 doesn't necessarily equal 0.  ^_^
                precisionTolerance = Math.Abs(request.TransferAmount) * 0.001;
                deliveredAll      &= Math.Abs(request.TransferAmount - Math.Abs(deliveredAmount)) <= precisionTolerance;

                yield return(null);
            }

            if (Status == DeliveryStatus.Returning)
            {
                Status = DeliveryStatus.Cancelled;
            }
            else
            {
                if (deliveredAll)
                {
                    Status = DeliveryStatus.Delivered;
                }
                else
                {
                    Status        = DeliveryStatus.Partial;
                    StatusMessage = "The destination vessel did not have enough available storage for the delivery.";
                }
            }
        }