예제 #1
0
        /// <summary>
        /// Deduct used amount from resource tanks
        /// </summary>
        internal void ProcessResources()
        {
            // Leave resource processing to Kerbalism if it is there
            if (DetectKerbalism.Found())
            {
                return;
            }

            IResourceBroker broker = new ResourceBroker();

            if (fuelCells.Use)
            {
                var iList = fuelCells.InputResources;
                for (int i = 0; i < iList.Count; i++)
                {
                    iList[i].MaximumAmountAvailable -= broker.RequestResource(vessel.rootPart, iList[i].Name, iList[i].CurrentAmountUsed, 1, ResourceFlowMode.ALL_VESSEL);
                    iList[i].CurrentAmountUsed       = 0;
                }
            }

            for (int i = 0; i < propellants.Count; i++)
            {
                propellants[i].MaximumAmountAvailable -= broker.RequestResource(vessel.rootPart, propellants[i].Name, propellants[i].CurrentAmountUsed, 1, ResourceFlowMode.ALL_VESSEL);
                propellants[i].CurrentAmountUsed       = 0;
            }
        }
예제 #2
0
        /// <summary>
        /// Update vessel
        /// </summary>
        /// <param name="currentTime"></param>
        internal override void Update(double currentTime)
        {
            if (vessel == null)
            {
                return;
            }
            if (vessel.isActiveVessel)
            {
                lastTimeUpdated = 0;
                if (active)
                {
                    ScreenMessages.PostScreenMessage(Localizer.Format("#LOC_BV_AutopilotActive"), 10f).color = Color.red;
                }
                return;
            }

            if (!active || vessel.loaded)
            {
                return;
            }

            // If we don't know the last time of update, then set it and wait for the next update cycle
            if (lastTimeUpdated == 0)
            {
                State           = VesselState.Idle;
                lastTimeUpdated = currentTime;
                BVModule.SetValue("lastTimeUpdated", currentTime.ToString());
                return;
            }

            Vector3d roverPos   = vessel.mainBody.position - vessel.GetWorldPos3D();
            Vector3d toMainStar = vessel.mainBody.position - FlightGlobals.Bodies[mainStarIndex].position;

            angle = Vector3d.Angle(roverPos, toMainStar); // Angle between rover and the main star

            // Speed penalties at twighlight and at night
            if ((angle > 90) && manned) // night
            {
                speedMultiplier = 0.25;
            }
            else if ((angle > 85) && manned) // twilight
            {
                speedMultiplier = 0.5;
            }
            else if ((angle > 80) && manned) // twilight
            {
                speedMultiplier = 0.75;
            }
            else // day
            {
                speedMultiplier = 1.0;
            }

            double deltaT     = currentTime - lastTimeUpdated; // Time delta from the last update
            double deltaTOver = 0;                             // deltaT which is calculated from a value over the maximum resource amout available

            // Compute increase or decrease in EC from the last update
            if (!CheatOptions.InfiniteElectricity && batteries.UseBatteries && !DetectKerbalism.Found())
            {
                // Process fuel cells before batteries
                if (!CheatOptions.InfinitePropellant &&
                    fuelCells.Use &&
                    ((angle > 90) ||
                     (batteries.ECPerSecondGenerated - fuelCells.OutputValue <= 0) ||
                     (batteries.CurrentEC < batteries.MaxUsedEC)))     // Night, not enough solar power or we need to recharge batteries
                {
                    if (!((angle > 90) && (batteries.CurrentEC == 0))) // Don't use fuel cells, if it's night and current EC of batteries is zero. This means, that there isn't enough power to recharge them and fuel is wasted.
                    {
                        var iList = fuelCells.InputResources;
                        for (int i = 0; i < iList.Count; i++)
                        {
                            iList[i].CurrentAmountUsed += iList[i].Ratio * deltaT;
                            if (iList[i].CurrentAmountUsed > iList[i].MaximumAmountAvailable)
                            {
                                deltaTOver = Math.Max(deltaTOver, (iList[i].CurrentAmountUsed - iList[i].MaximumAmountAvailable) / iList[i].Ratio);
                            }
                        }
                        if (deltaTOver > 0)
                        {
                            deltaT -= deltaTOver;
                            // Reduce the amount of used resources
                            for (int i = 0; i < iList.Count; i++)
                            {
                                iList[i].CurrentAmountUsed -= iList[i].Ratio * deltaTOver;
                            }
                        }
                    }
                }

                if (angle <= 90) // day
                {
                    batteries.CurrentEC = Math.Min(batteries.CurrentEC + batteries.ECPerSecondGenerated * deltaT, batteries.MaxUsedEC);
                }
                else // night
                {
                    batteries.CurrentEC = Math.Max(batteries.CurrentEC - batteries.ECPerSecondConsumed * deltaT, 0);
                }
            }

            // No moving at night, if there isn't enough power
            if ((angle > 90) && (averageSpeedAtNight == 0.0) && !(batteries.UseBatteries && (batteries.CurrentEC > 0)))
            {
                State           = VesselState.AwaitingSunlight;
                lastTimeUpdated = currentTime;
                BVModule.SetValue("lastTimeUpdated", currentTime.ToString());
                return;
            }

            double deltaS = AverageSpeed * deltaT; // Distance delta from the last update

            distanceTravelled += deltaS;

            if (distanceTravelled >= distanceToTarget) // We reached the target
            {
                if (!MoveSafely(targetLatitude, targetLongitude))
                {
                    distanceTravelled -= deltaS;
                }
                else
                {
                    distanceTravelled = distanceToTarget;

                    active  = false;
                    arrived = true;
                    BVModule.SetValue("active", "False");
                    BVModule.SetValue("arrived", "True");
                    BVModule.SetValue("distanceTravelled", distanceToTarget.ToString());
                    BVModule.SetValue("pathEncoded", "");

                    // Dewarp
                    if (Configuration.AutomaticDewarp)
                    {
                        if (TimeWarp.CurrentRate > 3) // Instant drop to 50x warp
                        {
                            TimeWarp.SetRate(3, true);
                        }
                        if (TimeWarp.CurrentRate > 0) // Gradual drop out of warp
                        {
                            TimeWarp.SetRate(0, false);
                        }
                        ScreenMessages.PostScreenMessage(vessel.vesselName + " " + Localizer.Format("#LOC_BV_VesselArrived") + " " + vessel.mainBody.bodyDisplayName.Replace("^N", ""), 5f);
                    }

                    NotifyArrival();
                }
                State = VesselState.Idle;
            }
            else
            {
                try                                                                                          // There is sometimes null ref exception during scene change
                {
                    int    step      = Convert.ToInt32(Math.Floor(distanceTravelled / PathFinder.StepSize)); // In which step of the path we are
                    double remainder = distanceTravelled % PathFinder.StepSize;                              // Current remaining distance from the current step
                    double bearing   = 0;

                    if (step < path.Count - 1)
                    {
                        bearing = GeoUtils.InitialBearing( // Bearing to the next step from previous step
                            path[step].latitude,
                            path[step].longitude,
                            path[step + 1].latitude,
                            path[step + 1].longitude
                            );
                    }
                    else
                    {
                        bearing = GeoUtils.InitialBearing( // Bearing to the target from previous step
                            path[step].latitude,
                            path[step].longitude,
                            targetLatitude,
                            targetLongitude
                            );
                    }

                    // Compute new coordinates, we are moving from the current step, distance is "remainder"
                    double[] newCoordinates = GeoUtils.GetLatitudeLongitude(
                        path[step].latitude,
                        path[step].longitude,
                        bearing,
                        remainder,
                        vessel.mainBody.Radius
                        );

                    // Move
                    if (!MoveSafely(newCoordinates[0], newCoordinates[1]))
                    {
                        distanceTravelled -= deltaS;
                        State              = VesselState.Idle;
                    }
                    else
                    {
                        State = VesselState.Moving;
                    }
                }
                catch { }
            }

            Save(currentTime);

            // Stop the rover, we don't have enough of fuel
            if (deltaTOver > 0 ||  (!CheatOptions.InfiniteElectricity && batteries.UseBatteries && batteries.CurrentEC <= 0.1))
            {
                active  = false;
                arrived = true;
                BVModule.SetValue("active", "False");
                BVModule.SetValue("arrived", "True");
                BVModule.SetValue("pathEncoded", "");

                // Dewarp
                if (Configuration.AutomaticDewarp)
                {
                    if (TimeWarp.CurrentRate > 3) // Instant drop to 50x warp
                    {
                        TimeWarp.SetRate(3, true);
                    }
                    if (TimeWarp.CurrentRate > 0) // Gradual drop out of warp
                    {
                        TimeWarp.SetRate(0, false);
                    }
                    ScreenMessages.PostScreenMessage(vessel.vesselName + " " + Localizer.Format("#LOC_BV_Warning_Stopped") + ".", 5f).color = Color.red;
                }

                if (!CheatOptions.InfiniteElectricity && batteries.UseBatteries && batteries.CurrentEC <= 0.1)
                {
                    NotifyBatteryEmpty();
                }
                else
                {
                    NotifyNotEnoughFuel();
                }

                State = VesselState.Idle;
            }
        }