コード例 #1
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 (batteries.UseBatteries)
            {
                // Process fuel cells before batteries
                if (fuelCells.Use &&
                    ((angle > 90) ||
                     (batteries.ECPerSecondGenerated - fuelCells.OutputValue <= 0) ||
                     (batteries.CurrentEC < batteries.MaxUsedEC)))       // Night, not enough solar power or we need to recharge batteries
                {
                    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)
            {
                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") + ". " + Localizer.Format("#LOC_BV_Warning_NotEnoughFuel"), 5f).color = Color.red;
                }

                NotifyNotEnoughFuel();
                State = VesselState.Idle;
            }
        }
コード例 #2
0
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="v"></param>
        /// <param name="module"></param>
        internal RoverController(Vessel v, ConfigNode module) : base(v, module)
        {
            // Load values from config if it isn't the first run of the mod (we are reseting vessel on the first run)
            if (!Configuration.FirstRun)
            {
                averageSpeed        = double.Parse(BVModule.GetValue("averageSpeed") != null ? BVModule.GetValue("averageSpeed") : "0");
                averageSpeedAtNight = double.Parse(BVModule.GetValue("averageSpeedAtNight") != null ? BVModule.GetValue("averageSpeedAtNight") : "0");
                manned = bool.Parse(BVModule.GetValue("manned") != null ? BVModule.GetValue("manned") : "false");
                vesselHeightFromTerrain = double.Parse(BVModule.GetValue("vesselHeightFromTerrain") != null ? BVModule.GetValue("vesselHeightFromTerrain") : "0");
            }

            speedMultiplier          = 1.0;
            angle                    = 0;
            maxSpeedBase             = 0;
            wheelsPercentualModifier = 0;
            crewSpeedBonus           = 0;
        }
コード例 #3
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 shipPos    = vessel.mainBody.position - vessel.GetWorldPos3D();
            Vector3d toMainStar = vessel.mainBody.position - FlightGlobals.Bodies[mainStarIndex].position;

            angle = Vector3d.Angle(shipPos, 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 propellant amout available

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

            if (!CheatOptions.InfinitePropellant)
            {
                for (int i = 0; i < propellants.Count; i++)
                {
                    propellants[i].CurrentAmountUsed += propellants[i].FuelFlow * deltaT * speedMultiplier * speedMultiplier; // If speed is reduced, then thrust and subsequently fuel flow are reduced by square (from drag equation)
                    if (propellants[i].CurrentAmountUsed > propellants[i].MaximumAmountAvailable)
                    {
                        deltaTOver = Math.Max(deltaTOver, (propellants[i].CurrentAmountUsed - propellants[i].MaximumAmountAvailable) / (propellants[i].FuelFlow * speedMultiplier * speedMultiplier));
                    }
                }
                if (deltaTOver > 0)
                {
                    deltaT -= deltaTOver;
                    // Reduce the amount of used propellants
                    for (int i = 0; i < propellants.Count; i++)
                    {
                        propellants[i].CurrentAmountUsed -= propellants[i].FuelFlow * deltaTOver * speedMultiplier * speedMultiplier;
                    }
                }
            }

            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 ship, we don't have enough of propellant
            if (deltaTOver > 0)
            {
                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") + ". " + Localizer.Format("#LOC_BV_Warning_NotEnoughFuel"), 5f).color = Color.red;
                }

                NotifyNotEnoughFuel();
                State = VesselState.Idle;
            }
        }