protected void setupInfoBox() { if (infoBox != null) { return; } try { getMaxTotalFuel(); resourceBroker = new ResourceBroker(); ResourceRatio[] inputs = inputList.ToArray(); Color clr; for (int index = 0; index < inputs.Length; index++) { if (inputs[index].ResourceName == fuelGaugeResource) { infoBox = this.part.stackIcon.StageIcon.DisplayInfo(); infoBox.SetMessage(fuelGaugeResource); clr = XKCDColors.GreenYellow; //XKCDColors.BrightOlive; clr.a = 0.55f; infoBox.SetMsgTextColor(clr); clr = XKCDColors.Asparagus; clr.a = 0.5f; infoBox.SetMsgBgColor(clr); infoBox.SetProgressBarBgColor(clr); infoBox.Collapse(); break; } } } catch { } }
private static void ProcessApiModule(Vessel v, ProtoPartSnapshot p, ProtoPartModuleSnapshot m, Part part_prefab, PartModule module_prefab, VesselResources resources, Dictionary <string, double> availableResources, List <KeyValuePair <string, double> > resourceChangeRequests, double elapsed_s) { resourceChangeRequests.Clear(); try { string title = BackgroundDelegate.Instance(module_prefab).invoke(v, p, m, module_prefab, part_prefab, availableResources, resourceChangeRequests, elapsed_s); foreach (var cr in resourceChangeRequests) { if (cr.Value > 0) { resources.Produce(v, cr.Key, cr.Value * elapsed_s, ResourceBroker.GetOrCreate(title)); } else if (cr.Value < 0) { resources.Consume(v, cr.Key, -cr.Value * elapsed_s, ResourceBroker.GetOrCreate(title)); } } } catch (Exception ex) { Lib.Log("BackgroundUpdate in PartModule " + module_prefab.moduleName + " excepted: " + ex.Message + "\n" + ex.ToString()); } }
/// <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> /// Activate autopilot /// </summary> internal override bool Activate() { if (vessel.situation != Vessel.Situations.SPLASHED) { ScreenMessages.PostScreenMessage(Localizer.Format("#LOC_BV_Warning_Splashed"), 5f).color = Color.yellow; return(false); } SystemCheck(); // At least one engine must be on if (engineTestResult.maxThrustSum == 0) { ScreenMessages.PostScreenMessage(Localizer.Format("#LOC_BV_Warning_EnginesNotOnline"), 5f).color = Color.yellow; return(false); } // Get fuel amount IResourceBroker broker = new ResourceBroker(); for (int i = 0; i < propellants.Count; i++) { propellants[i].MaximumAmountAvailable = broker.AmountAvailable(vessel.rootPart, propellants[i].Name, 1, ResourceFlowMode.ALL_VESSEL); if (propellants[i].MaximumAmountAvailable == 0) { ScreenMessages.PostScreenMessage(Localizer.Format("#LOC_BV_Warning_NotEnoughFuel"), 5f).color = Color.yellow; return(false); } } // Power production if (requiredPower > (electricPower_Solar + electricPower_Other)) { // If required power is greater than total power generated, then average speed can be lowered up to 87% (square root of (1 - powerReduction)) double powerReduction = (requiredPower - (electricPower_Solar + electricPower_Other)) / requiredPower; if (powerReduction > 0.75) { ScreenMessages.PostScreenMessage(Localizer.Format("#LOC_BV_Warning_LowPowerShip"), 5f).color = Color.yellow; return(false); } } BonVoyageModule module = vessel.FindPartModuleImplementing <BonVoyageModule>(); if (module != null) { //vesselHeightFromTerrain = vessel.GetHeightFromSurface(); vesselHeightFromTerrain = 0; module.averageSpeed = averageSpeed; module.averageSpeedAtNight = averageSpeedAtNight; module.manned = manned; module.vesselHeightFromTerrain = vesselHeightFromTerrain; } return(base.Activate()); }
public OseModuleRecycler() { _queue = new WorkshopQueue(); _broker = new ResourceBroker(); _pauseTexture = WorkshopUtils.LoadTexture("Workshop/Assets/icon_pause"); _playTexture = WorkshopUtils.LoadTexture("Workshop/Assets/icon_play"); _binTexture = WorkshopUtils.LoadTexture("Workshop/Assets/icon_bin"); }
public OseModuleRecycler() { _queue = new WorkshopQueue(); _broker = new ResourceBroker(); _pauseTexture = WorkshopUtils.LoadTexture("Workshop/Assets/Icons/icon_pause"); _playTexture = WorkshopUtils.LoadTexture("Workshop/Assets/Icons/icon_play"); _binTexture = WorkshopUtils.LoadTexture("Workshop/Assets/Icons/icon_bin"); }
public override void OnStart(StartState state) { base.OnStart(state); magnetTransforms = this.part.FindModelTransforms(magnetTransformName); if (magnetTransforms != null && magnetTransforms.Length > 0) { forcePerTransform = magnetForce / magnetTransforms.Length; } resourceBroker = new ResourceBroker(); unitsPerUpdate = ecPerSec * TimeWarp.fixedDeltaTime; }
/// <summary> /// Deduct used amount from resource tanks /// </summary> internal void ProcessResources() { 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; } } }
public static void ProcessResources(Vessel v, List <KeyValuePair <string, double> > resources, string title) { ResourceBroker broker = ResourceBroker.GetOrCreate(title); foreach (var p in resources) { if (p.Value < 0) { ResourceCache.Consume(v, p.Key, -p.Value, broker); } else { ResourceCache.Produce(v, p.Key, p.Value, broker); } } }
public void UpdateResourceBrokers(Dictionary <ResourceBroker, double> brokersResAmount, Dictionary <ResourceBroker, double> ruleBrokersRate, double unsupportedBrokersRate, double elapsedSeconds) { ResourceBrokers.Clear(); foreach (KeyValuePair <ResourceBroker, double> p in ruleBrokersRate) { ResourceBroker broker = ResourceBroker.GetOrCreate(p.Key.Id + "Avg", p.Key.Category, Lib.BuildString(p.Key.Title, " (", Local.Generic_AVERAGE, ")")); ResourceBrokers.Add(new ResourceBrokerRate(broker, p.Value)); } foreach (KeyValuePair <ResourceBroker, double> p in brokersResAmount) { ResourceBrokers.Add(new ResourceBrokerRate(p.Key, p.Value / elapsedSeconds)); } if (unsupportedBrokersRate != 0.0) { ResourceBrokers.Add(new ResourceBrokerRate(ResourceBroker.Generic, unsupportedBrokersRate)); } }
public override void OnAwake() { eList = part.GetComponentsInChildren<KSPParticleEmitter>(); broker = new ResourceBroker(); if (fuelList == null) return; var fl = fuelList.Split(';'); Fuels = new PartResourceDefinition[fl.Length]; for(int i = 0; i < fl.Length; i++) { var res = PartResourceLibrary.Instance.GetDefinition(fl[i]); if (res != null) Fuels[i] = res; } CurrentFuelIndex = 0; Fuel = Fuels[CurrentFuelIndex].name; base.OnAwake(); }
public override void OnAwake() { eList = part.GetComponentsInChildren <KSPParticleEmitter>(); broker = new ResourceBroker(); var fl = fuelList.Split(';'); Fuels = new PartResourceDefinition[fl.Count()]; for (int i = 0; i < fl.Count(); i++) { var res = PartResourceLibrary.Instance.GetDefinition(fl[i]); if (res != null) { Fuels[i] = res; } } CurrentFuelIndex = 0; Fuel = Fuels[CurrentFuelIndex].name; base.OnAwake(); }
public ResourceBrokerRate(ResourceBroker broker, double amount) { this.broker = broker; this.rate = amount; }
private void SpawnExtraSupplies(float sup) { ResourceBroker.StoreResource(vessel.rootPart, "Supplies", sup, TimeWarp.deltaTime, ResourceFlowMode.ALL_VESSEL); }
public static void ProduceResource(Vessel v, string resource_name, double quantity, string title) { ResourceCache.Produce(v, resource_name, quantity, ResourceBroker.GetOrCreate(title)); }
public Rule(ConfigNode node) { name = Lib.ConfigValue(node, "name", string.Empty); title = Lib.ConfigValue(node, "title", name); input = Lib.ConfigValue(node, "input", string.Empty); output = Lib.ConfigValue(node, "output", string.Empty); interval = Lib.ConfigValue(node, "interval", 0.0); rate = Lib.ConfigValue(node, "rate", 0.0); ratio = Lib.ConfigValue(node, "ratio", 0.0); degeneration = Lib.ConfigValue(node, "degeneration", 0.0); variance = Lib.ConfigValue(node, "variance", 0.0); individuality = Lib.ConfigValue(node, "individuality", 0.0); modifiers = Lib.Tokenize(Lib.ConfigValue(node, "modifier", string.Empty), ','); breakdown = Lib.ConfigValue(node, "breakdown", false); lifetime = Lib.ConfigValue(node, "lifetime", false); warning_threshold = Lib.ConfigValue(node, "warning_threshold", 0.33); danger_threshold = Lib.ConfigValue(node, "danger_threshold", 0.66); fatal_threshold = Lib.ConfigValue(node, "fatal_threshold", 1.0); warning_message = Lib.ConfigValue(node, "warning_message", string.Empty); danger_message = Lib.ConfigValue(node, "danger_message", string.Empty); fatal_message = Lib.ConfigValue(node, "fatal_message", string.Empty); relax_message = Lib.ConfigValue(node, "relax_message", string.Empty); broker = ResourceBroker.GetOrCreate(name, ResourceBroker.BrokerCategory.Kerbal, title); if (warning_message.Length > 0 && warning_message[0] == '#') { Lib.Log("Broken translation: " + warning_message, Lib.LogLevel.Warning); } if (danger_message.Length > 0 && danger_message[0] == '#') { Lib.Log("Broken translation: " + danger_message, Lib.LogLevel.Warning); } if (fatal_message.Length > 0 && fatal_message[0] == '#') { Lib.Log("Broken translation: " + fatal_message, Lib.LogLevel.Warning); } if (relax_message.Length > 0 && relax_message[0] == '#') { Lib.Log("Broken translation: " + relax_message, Lib.LogLevel.Warning); } // check that name is specified if (name.Length == 0) { throw new Exception("skipping unnamed rule"); } // check that degeneration is not zero if (degeneration <= double.Epsilon) { throw new Exception("skipping zero degeneration rule"); } // check that resources exist if (input.Length > 0 && Lib.GetDefinition(input) == null) { throw new Exception("resource '" + input + "' doesn't exist"); } if (output.Length > 0 && Lib.GetDefinition(output) == null) { throw new Exception("resource '" + output + "' doesn't exist"); } // calculate ratio of input vs output resource if (input.Length > 0 && output.Length > 0 && ratio <= double.Epsilon) { var input_density = Lib.GetDefinition(input).density; var output_density = Lib.GetDefinition(output).density; ratio = Math.Min(input_density, output_density) > double.Epsilon ? input_density / output_density : 1.0; } }
public void FixedUpdate() { if (!HighLogic.LoadedSceneIsFlight || vessel == null || !vessel.loaded) { return; } if (vessel.isEVA) { CheckEVA(vessel); return; } if (_partCount != vessel.parts.Count) { if (_partCount > 0) { _isStatusRefreshRequired = true; } _partCount = vessel.parts.Count; } if (_isDirty) { _isDirty = false; UpdateVesselInfo(); UpdateStatus(); } var now = Planetarium.GetUniversalTime(); if (_currentCrewCount == 0) { VesselStatus.VesselName = vessel.vesselName; VesselStatus.NumCrew = vessel.GetCrewCount(); VesselStatus.CrewCap = vessel.GetCrewCapacity(); VesselStatus.LastECCheck = now; VesselStatus.LastFeeding = now; VesselStatus.LastUpdate = now; LifeSupportManager.Instance.TrackVessel(VesselStatus); LastUpdateTime = now; return; } try { bool isLongLoop = false; var offKerbin = !LifeSupportManager.IsOnKerbin(vessel); CheckVesselId(); // Check our time double deltaTime = GetDeltaTime(); bool isCatchup = deltaTime / 2 > TimeWarp.fixedDeltaTime; if (deltaTime < ResourceUtilities.FLOAT_TOLERANCE * 10) { return; } if (now >= _lastProcessingTime + _checkInterval) { isLongLoop = true; _lastProcessingTime = now; } VesselStatus.LastUpdate = now; VesselStatus.VesselName = vessel.vesselName; VesselStatus.NumCrew = vessel.GetCrewCount(); VesselStatus.CrewCap = vessel.GetCrewCapacity(); if (isLongLoop) { CheckForDeadKerbals(); } if (_currentCrewCount > 0) { //Guard clause if (_crewPart == null) { UpdateVesselInfo(); } //we will add a bit of a fudge factor for supplies var tolerance = deltaTime / 2f; //nom nom nom! ConverterResults resultSupply = Converter.ProcessRecipe(deltaTime, SupplyRecipe, _crewPart, null, 1f); ConverterResults resultEC = Converter.ProcessRecipe(deltaTime, ECRecipe, _crewPart, null, 1f); #region Long Loop - Crew if (isLongLoop) { //Ensure status is current UpdateStatus(); var habTime = LifeSupportManager.GetTotalHabTime(VesselStatus, vessel); if (_oldHabChecksum < ResourceUtilities.FLOAT_TOLERANCE) { _oldHabChecksum = LifeSupportManager.GetHabChecksum(VesselStatus, vessel); } var newHabChecksum = LifeSupportManager.GetHabChecksum(VesselStatus, vessel); if (Math.Abs(_oldHabChecksum - newHabChecksum) > ResourceUtilities.FLOAT_TOLERANCE) { Debug.Log("[USI-LS] Vessel situation changed, refreshing life support"); _isStatusRefreshRequired = true; _oldHabChecksum = newHabChecksum; } var crewRoster = vessel.GetVesselCrew(); var count = crewRoster.Count; for (int i = 0; i < count; ++i) { var crewMember = crewRoster[i]; bool isGrouchyHab = false; bool isGrouchySupplies = false; bool isGrouchyEC = false; bool isScout = crewMember.HasEffect("ExplorerSkill") && habTime >= LifeSupportScenario.Instance.settings.GetSettings().ScoutHabTime; bool isPermaHab = habTime >= LifeSupportScenario.Instance.settings.GetSettings().PermaHabTime; bool isHomeWorld = CheckIfHomeWorld() && habTime >= LifeSupportScenario.Instance.settings.GetSettings().ScoutHabTime&& vessel.LandedOrSplashed; // Get the crew member's life support stats var trackedKerbal = LifeSupportManager.Instance.FetchKerbal(crewMember); // Update life support stats if (_isStatusRefreshRequired) { trackedKerbal.TimeEnteredVessel = now; _isStatusRefreshRequired = false; LifeSupportManager.Instance.TrackKerbal(trackedKerbal); } // Update Hab effects if (!offKerbin || isScout || isHomeWorld || isPermaHab) { trackedKerbal.TimeEnteredVessel = now; trackedKerbal.LastAtHome = now; trackedKerbal.MaxOffKerbinTime = habTime + trackedKerbal.LastAtHome; } else { if (vessel.id.ToString() != trackedKerbal.CurrentVesselId) { if (vessel.id.ToString() != trackedKerbal.PreviousVesselId) { trackedKerbal.TimeEnteredVessel = now; } trackedKerbal.PreviousVesselId = trackedKerbal.CurrentVesselId; trackedKerbal.CurrentVesselId = vessel.id.ToString(); LifeSupportManager.Instance.TrackKerbal(trackedKerbal); } isGrouchyHab = CheckHabSideEffects(trackedKerbal); } // Update Supplies effects if (offKerbin && (deltaTime - resultSupply.TimeFactor > tolerance)) { isGrouchySupplies = CheckSupplySideEffects(trackedKerbal); } else if (deltaTime >= ResourceUtilities.FLOAT_TOLERANCE) { //All is well trackedKerbal.LastMeal = LastUpdateTime; VesselStatus.LastFeeding = LastUpdateTime; } // Update ElectricCharge effects if (offKerbin && (deltaTime - resultEC.TimeFactor > tolerance)) { isGrouchyEC = CheckECSideEffects(trackedKerbal); } else if (deltaTime >= ResourceUtilities.FLOAT_TOLERANCE) { //All is well trackedKerbal.LastEC = LastUpdateTime; VesselStatus.LastECCheck = LastUpdateTime; } trackedKerbal.LastUpdate = now; var isAnyGrouch = isGrouchyEC || isGrouchyHab || isGrouchySupplies; if (isGrouchyEC && !isCatchup) { ApplyEffect( trackedKerbal, crewMember, LifeSupportManager.GetNoECEffect(trackedKerbal.KerbalName), "power loss"); } else if (isGrouchySupplies && !isCatchup) { ApplyEffect( trackedKerbal, crewMember, LifeSupportManager.GetNoSupplyEffect(trackedKerbal.KerbalName), "lack of supplies"); } else if (isGrouchyHab && !isCatchup) { ApplyEffect( trackedKerbal, crewMember, LifeSupportManager.GetNoHomeEffect(trackedKerbal.KerbalName), "homesickness"); } else if (crewMember.experienceTrait.Config.Name != trackedKerbal.OldTrait && !isAnyGrouch) { RemoveGrouchiness(crewMember, trackedKerbal); } LifeSupportManager.Instance.TrackKerbal(trackedKerbal); } } #endregion - Crew var remainingSupplies = ResourceBroker.AmountAvailable( _crewPart, "Supplies", deltaTime, ResourceFlowMode.ALL_VESSEL); var remainingBattery = ResourceBroker.AmountAvailable( _crewPart, "ElectricCharge", deltaTime, ResourceFlowMode.ALL_VESSEL); var suppliesConsumption = LifeSupportScenario.Instance.settings.GetSettings().SupplyAmount; var electricityConsumption = LifeSupportScenario.Instance.settings.GetSettings().ECAmount; VesselStatus.SuppliesLeft = remainingSupplies / suppliesConsumption / _currentCrewCount / VesselStatus.RecyclerMultiplier; VesselStatus.ECLeft = remainingBattery / electricityConsumption / _currentCrewCount; } else { VesselStatus.LastECCheck = now; VesselStatus.LastFeeding = now; VesselStatus.LastUpdate = now; } LifeSupportManager.Instance.TrackVessel(VesselStatus); } catch (Exception ex) { print(string.Format("ERROR {0} IN ModuleLifeSupport", ex.Message)); } }
public Process(ConfigNode node) { name = Lib.ConfigValue(node, "name", string.Empty); title = Lib.ConfigValue(node, "title", name); broker = ResourceBroker.GetOrCreate(name, ResourceBroker.BrokerCategory.Converter, title); modifiers = Lib.Tokenize(Lib.ConfigValue(node, "modifier", string.Empty), ','); // check that name is specified if (name.Length == 0) { throw new Exception("skipping unnamed process"); } // fix for https://github.com/JadeOfMaar/RationalResources/issues/25 bool skip_resources_validity_check = Lib.ConfigValue(node, "skip_resources_validity_check", false); inputs = new Dictionary <string, double>(); foreach (string input in node.GetValues("input")) { // get parameters List <string> tok = Lib.Tokenize(input, '@'); if (tok.Count != 2) { throw new Exception("malformed input on process " + name); } string input_res = tok[0]; double input_rate = Lib.Parse.ToDouble(tok[1]); // check that resource is specified if (input_res.Length == 0) { throw new Exception("skipping resource-less process " + name); } // check that resource exist if (skip_resources_validity_check || Lib.GetDefinition(input_res) == null) { throw new Exception("resource " + input_res + " doesn't exist for process " + name); } // record input inputs[input_res] = input_rate; } outputs = new Dictionary <string, double>(); foreach (string output in node.GetValues("output")) { // get parameters List <string> tok = Lib.Tokenize(output, '@'); if (tok.Count != 2) { throw new Exception("malformed output on process " + name); } string output_res = tok[0]; double output_rate = Lib.Parse.ToDouble(tok[1]); // check that resource is specified if (output_res.Length == 0) { throw new Exception("skipping resource-less process " + name); } // check that resource exist if (skip_resources_validity_check || Lib.GetDefinition(output_res) == null) { throw new Exception("resource " + output_res + " doesn't exist for process " + name); } // record output outputs[output_res] = output_rate; } cures = new Dictionary <string, double>(); foreach (string output in node.GetValues("cures")) { // get parameters List <string> tok = Lib.Tokenize(output, '@'); if (tok.Count != 2) { throw new Exception("malformed cure on process " + name); } string cure = tok[0]; double cure_rate = Lib.Parse.ToDouble(tok[1]); // check that resource is specified if (cure.Length == 0) { throw new Exception("skipping resource-less process " + name); } // record cure cures[cure] = cure_rate; } // parse dump specs dump = new DumpSpecs(Lib.ConfigValue(node, "dump", "false"), Lib.ConfigValue(node, "dump_valve", "false")); }
/// <summary> /// Check the systems /// </summary> internal override void SystemCheck() { base.SystemCheck(); // Test stock wheels WheelTestResult testResultStockWheels = CheckStockWheels(); // Test KSPWheels WheelTestResult testResultKSPkWheels = CheckKSPWheels(); // Sum it wheelTestResult.powerRequired = testResultStockWheels.powerRequired + testResultKSPkWheels.powerRequired; wheelTestResult.maxSpeedSum = testResultStockWheels.maxSpeedSum + testResultKSPkWheels.maxSpeedSum; wheelTestResult.inTheAir = testResultStockWheels.inTheAir + testResultKSPkWheels.inTheAir; wheelTestResult.operable = testResultStockWheels.operable + testResultKSPkWheels.operable; wheelTestResult.damaged = testResultStockWheels.damaged + testResultKSPkWheels.damaged; wheelTestResult.online = testResultStockWheels.online + testResultKSPkWheels.online; wheelTestResult.maxWheelRadius = testResultStockWheels.maxWheelRadius + testResultKSPkWheels.maxWheelRadius; // Generally, moving at high speed requires less power than wheels' max consumption. Maximum required power of controller will 35% of wheels power requirement requiredPower = wheelTestResult.powerRequired / 100 * 35; // Get available EC from batteries if (batteries.UseBatteries) { batteries.MaxAvailableEC = GetAvailableEC_Batteries(); } else { batteries.MaxAvailableEC = 0; } // Get available EC from fuell cells fuelCells.OutputValue = 0; fuelCells.InputResources.Clear(); if (fuelCells.Use) { List <ModuleResourceConverter> mrc = vessel.FindPartModulesImplementing <ModuleResourceConverter>(); for (int i = 0; i < mrc.Count; i++) { double ecRatio = 0; try { var ec = mrc[i].outputList.Find(x => x.ResourceName == "ElectricCharge"); // NullArgumentException when not found ecRatio = ec.Ratio; } catch { } if (ecRatio > 0) { // Add input resources var iList = mrc[i].inputList; for (int r = 0; r < iList.Count; r++) { // Check if we have fuel for converter. If not, then continue without adding output ratio. if (!CheatOptions.InfinitePropellant && r == 0) { IResourceBroker broker = new ResourceBroker(); if (broker.AmountAvailable(vessel.rootPart, iList[r].ResourceName, 1, ResourceFlowMode.ALL_VESSEL) == 0) { break; } } var ir = fuelCells.InputResources.Find(x => x.Name == iList[r].ResourceName); if (ir == null) { ir = new Resource(); ir.Name = iList[r].ResourceName; fuelCells.InputResources.Add(ir); } ir.Ratio += iList[r].Ratio; // Add EC ration to output if (r == 0) { fuelCells.OutputValue += ecRatio; } } } } } electricPower_Other += fuelCells.OutputValue; // Cheats if (CheatOptions.InfiniteElectricity) { electricPower_Other = requiredPower; } // Manned manned = (vessel.GetCrewCount() > 0); // Pilots and Scouts (USI) increase base average speed crewSpeedBonus = 0; if (manned) { int maxPilotLevel = -1; int maxScoutLevel = -1; int maxDriverLevel = -1; List <ProtoCrewMember> crewList = vessel.GetVesselCrew(); for (int i = 0; i < crewList.Count; i++) { switch (crewList[i].trait) { case "Pilot": if (maxPilotLevel < crewList[i].experienceLevel) { maxPilotLevel = crewList[i].experienceLevel; } break; case "Scout": if (maxScoutLevel < crewList[i].experienceLevel) { maxScoutLevel = crewList[i].experienceLevel; } break; default: if (crewList[i].HasEffect("AutopilotSkill")) { if (maxDriverLevel < crewList[i].experienceLevel) { maxDriverLevel = crewList[i].experienceLevel; } } break; } } if (maxPilotLevel > 0) { crewSpeedBonus = 6 * maxPilotLevel; // up to 30% for a Pilot } else if (maxDriverLevel > 0) { crewSpeedBonus = 4 * maxDriverLevel; // up to 20% for any driver (has AutopilotSkill skill) } else if (maxScoutLevel > 0) { crewSpeedBonus = 2 * maxScoutLevel; // up to 10% for a Scout (Scouts disregard safety) } } // Average speed will vary depending on number of wheels online and crew present from 50 to 95 percent of average wheels' max speed if (wheelTestResult.online != 0) { maxSpeedBase = wheelTestResult.maxSpeedSum / wheelTestResult.online; wheelsPercentualModifier = Math.Min(70, (40 + 5 * wheelTestResult.online)); averageSpeed = maxSpeedBase * Convert.ToDouble(wheelsPercentualModifier) / 100 * (1 + Convert.ToDouble(crewSpeedBonus) / 100); } else { averageSpeed = 0; } // Unmanned rovers drive with the speed penalty based on available tech if (!manned) { averageSpeed = averageSpeed * (100 - Convert.ToDouble(GetUnmannedSpeedPenalty())) / 100; } // Base average speed at night is the same as average speed, if there is other power source. Zero otherwise. if (electricPower_Other > 0.0) { averageSpeedAtNight = averageSpeed; } else { averageSpeedAtNight = 0; } // If required power is greater then total power generated, then average speed can be lowered up to 75% if (requiredPower > (electricPower_Solar + electricPower_Other)) { double speedReduction = (requiredPower - (electricPower_Solar + electricPower_Other)) / requiredPower; if (speedReduction <= 0.75) { averageSpeed = averageSpeed * (1 - speedReduction); } } // If required power is greater then other power generated, then average speed at night can be lowered up to 75% if (requiredPower > electricPower_Other) { double speedReduction = (requiredPower - electricPower_Other) / requiredPower; if (speedReduction <= 0.75) { averageSpeedAtNight = averageSpeedAtNight * (1 - speedReduction); } else { averageSpeedAtNight = 0; } } // If we are using batteries, compute for how long and how much EC we can use if (batteries.UseBatteries) { batteries.MaxUsedEC = 0; batteries.ECPerSecondConsumed = 0; batteries.ECPerSecondGenerated = 0; // We have enough of solar power to recharge batteries if (requiredPower < (electricPower_Solar + electricPower_Other)) { batteries.ECPerSecondConsumed = Math.Max(requiredPower - electricPower_Other, 0); // If there is more other power than required power, we don't need batteries batteries.MaxUsedEC = batteries.MaxAvailableEC / 2; // We are using only half of max available EC if (batteries.ECPerSecondConsumed > 0) { double halfday = vessel.mainBody.rotationPeriod / 2; // in seconds batteries.ECPerSecondGenerated = electricPower_Solar + electricPower_Other - requiredPower; batteries.MaxUsedEC = Math.Min(batteries.MaxUsedEC, batteries.ECPerSecondConsumed * halfday); // get lesser value of MaxUsedEC and EC consumed per night batteries.MaxUsedEC = Math.Min(batteries.MaxUsedEC, batteries.ECPerSecondGenerated * halfday); // get lesser value of MaxUsedEC and max EC available for recharge during a day } } if (batteries.MaxUsedEC > 0) { batteries.CurrentEC = batteries.MaxUsedEC; // We are starting at full available capacity } else { UseBatteriesChanged(false); ScreenMessages.PostScreenMessage(Localizer.Format("#LOC_BV_Warning_CantUseBatteries") + " " + Localizer.Format("#LOC_BV_Warning_LowPowerRover") + ".", 5f).color = Color.yellow; } } }
public ResourceTransferTarget(Vessel vessel) { _broker = new ResourceBroker(); _vessel = vessel; _resources = GetResourceMetadata(vessel.parts); }
/// <summary> /// Activate autopilot /// </summary> internal override bool Activate() { if (vessel.situation != Vessel.Situations.LANDED && vessel.situation != Vessel.Situations.PRELAUNCH) { ScreenMessages.PostScreenMessage(Localizer.Format("#LOC_BV_Warning_Landed"), 5f).color = Color.yellow; return(false); } SystemCheck(); // No driving until at least 3 operable wheels are touching the ground - tricycles are allowed if ((wheelTestResult.inTheAir > 0) && (wheelTestResult.operable < 3)) { ScreenMessages.PostScreenMessage(Localizer.Format("#LOC_BV_Warning_WheelsNotTouching"), 5f).color = Color.yellow; return(false); } if (wheelTestResult.operable < 3) { ScreenMessages.PostScreenMessage(Localizer.Format("#LOC_BV_Warning_WheelsNotOperable"), 5f).color = Color.yellow; return(false); } // At least 2 wheels must be on if (wheelTestResult.online < 2) { ScreenMessages.PostScreenMessage(Localizer.Format("#LOC_BV_Warning_WheelsNotOnline"), 5f).color = Color.yellow; return(false); } // Get fuel amount if fuel cells are used if (fuelCells.Use && !CheatOptions.InfinitePropellant) { IResourceBroker broker = new ResourceBroker(); var iList = fuelCells.InputResources; for (int i = 0; i < iList.Count; i++) { iList[i].MaximumAmountAvailable = broker.AmountAvailable(vessel.rootPart, iList[i].Name, 1, ResourceFlowMode.ALL_VESSEL); if (iList[i].MaximumAmountAvailable == 0) { ScreenMessages.PostScreenMessage(Localizer.Format("#LOC_BV_Warning_NotEnoughFuel"), 5f).color = Color.yellow; return(false); } } } // Power production if (requiredPower > (electricPower_Solar + electricPower_Other)) { // If required power is greater than total power generated, then average speed can be lowered up to 75% double speedReduction = (requiredPower - (electricPower_Solar + electricPower_Other)) / requiredPower; if (speedReduction > 0.75) { ScreenMessages.PostScreenMessage(Localizer.Format("#LOC_BV_Warning_LowPowerRover"), 5f).color = Color.yellow; return(false); } } BonVoyageModule module = vessel.FindPartModuleImplementing <BonVoyageModule>(); if (module != null) { vesselHeightFromTerrain = vessel.radarAltitude; module.averageSpeed = averageSpeed; module.averageSpeedAtNight = averageSpeedAtNight; module.manned = manned; module.vesselHeightFromTerrain = vesselHeightFromTerrain; } return(base.Activate()); }
/// <summary> /// Call ResourceUpdate on all part modules that have that method /// </summary> public void ResourceUpdate(VesselResources resources, double elapsed_s) { // only do this for loaded vessels. unloaded vessels will be handled in Background.cs if (!Vessel.loaded) { return; } if (resourceUpdateDelegates == null) { resourceUpdateDelegates = new List <ResourceUpdateDelegate>(); foreach (var part in Vessel.parts) { foreach (var module in part.Modules) { if (!module.isEnabled) { continue; } var resourceUpdateDelegate = ResourceUpdateDelegate.Instance(module); if (resourceUpdateDelegate != null) { resourceUpdateDelegates.Add(resourceUpdateDelegate); } } } } if (resourceUpdateDelegates.Count == 0) { return; } List <ResourceInfo> allResources = resources.GetAllResources(Vessel); // there might be some performance to be gained by caching the list of all resource Dictionary <string, double> availableResources = new Dictionary <string, double>(); foreach (var ri in allResources) { availableResources[ri.ResourceName] = ri.Amount; } List <KeyValuePair <string, double> > resourceChangeRequests = new List <KeyValuePair <string, double> >(); foreach (var resourceUpdateDelegate in resourceUpdateDelegates) { resourceChangeRequests.Clear(); string title = resourceUpdateDelegate.invoke(availableResources, resourceChangeRequests); ResourceBroker broker = ResourceBroker.GetOrCreate(title); foreach (var rc in resourceChangeRequests) { if (rc.Value > 0) { resources.Produce(Vessel, rc.Key, rc.Value * elapsed_s, broker); } if (rc.Value < 0) { resources.Consume(Vessel, rc.Key, -rc.Value * elapsed_s, broker); } } } }