/// <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; } }
/// <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; } }