protected void setup_resource_transfer(ConstructionKitInfo target) { target_kit = null; //this.Log("res: target_kit: complete {}, check {}", target.Complete, check_target_kit(target));//debug if (check_target_kit(target)) { target_kit = target; } else { return; } host_resources = new VesselResources(vessel); kit_resources = target_kit.Kit.ConstructResources; transfer_list.NewTransfer(host_resources, kit_resources); if (transfer_list.Count > 0) { resources_window.Show(true); resources_window.TransferAction = delegate { double dM, dC; transfer_list.TransferResources(host_resources, kit_resources, out dM, out dC); target_kit.Kit.ResourcesMass += (float)dM; target_kit.Kit.ResourcesCost += (float)dC; }; } else { resources_window.TransferAction = null; host_resources = null; kit_resources = null; target_kit = null; } }
/// <summary> /// Recycle vessel whenever recovered /// </summary> /// <param name="pv">the vessel</param> private void onRecovered(ProtoVessel pv) { if (HighLogic.LoadedScene.Equals(GameScenes.TRACKSTATION) && settings.difficulty != 0 && (pv.situation.Equals(Vessel.Situations.LANDED) || pv.situation.Equals(Vessel.Situations.SPLASHED))) { VesselResources res = new VesselResources(pv.vesselRef); recycledName = pv.vesselName; recycledCost = res.recyclable(pv.situation.Equals(Vessel.Situations.LANDED)); print("*MC* Craft " + recycledName + " recovered for " + recycledCost); showRecycleWindow = true; manager.recycleVessel(pv.vesselRef, recycledCost); } pVessel = null; }
/// <summary> /// We have to account the space program for the launch /// </summary> /// <param name="r">The red component.</param> private void onLaunch(EventReport r) { // Apparently this event is even fired when we stage in orbit... // Malkuth Edit To match the actual cost of launch with Visual Cost in Display.. (almost missed this one opps) if (activeVessel != null && activeVessel.situation == Vessel.Situations.PRELAUNCH) { VesselResources res = new VesselResources(activeVessel); if (settings.difficulty != 0) { Debug.LogError("Launching vessel!"); manager.costs(res.sum()); recycled = false; } else { Debug.LogError("Launching Test vessel!"); manager.costs((res.dry()) * 6 / 100); recycled = false; } } }
//all initialization goes here instead of the constructor as documented in Unity API void update_resources() { hangarResources = new VesselResources<Vessel, Part, PartResource>(vessel); }
public override void Load(ConfigNode node) { ConfigNode vessel_node = node.GetNode("VESSEL"); ConfigNode metric_node = node.GetNode("METRIC"); ConfigNode crew_node = node.GetNode("CREW"); proto_vessel = new ProtoVessel(vessel_node, HighLogic.CurrentGame); metric = new Metric(metric_node); crew = new List<ProtoCrewMember>(); foreach(ConfigNode cn in crew_node.nodes) crew.Add(new ProtoCrewMember(HighLogic.CurrentGame.Mode, cn)); id = proto_vessel.vesselID; name = proto_vessel.vesselName; resources = new VesselResources<ProtoVessel, ProtoPartSnapshot, ProtoPartResourceSnapshot>(proto_vessel); }
public StoredVessel(Vessel vsl, bool compute_hull=false) { proto_vessel = vsl.BackupVessel(); metric = new Metric(vsl, compute_hull); id = proto_vessel.vesselID; name = proto_vessel.vesselName; crew = vsl.GetVesselCrew(); resources = new VesselResources<ProtoVessel, ProtoPartSnapshot, ProtoPartResourceSnapshot>(proto_vessel); }
// Simulate resources production/consumption for unloaded vessel public static string BackgroundUpdate(Vessel v, ProtoPartSnapshot part_snapshot, ProtoPartModuleSnapshot module_snapshot, PartModule proto_part_module, Part proto_part, Dictionary <string, double> availableResources, List <KeyValuePair <string, double> > resourceChangeRequest, double elapsed_s) { ProtoPartModuleSnapshot reactor = KSHUtils.FindPartModuleSnapshot(part_snapshot, engineModuleName); if (reactor != null) { if (Lib.Proto.GetBool(reactor, "Enabled") && Lib.Proto.GetBool(module_snapshot, "GeneratesElectricity")) { float curThrottle = Lib.Proto.GetFloat(reactor, "CurrentReactorThrottle") / 100f; float minThrottle = Lib.Proto.GetFloat(module_snapshot, "MinThrottle"); float maxThrottle = Lib.Proto.GetFloat(module_snapshot, "MaxThrottle"); float maxECGeneration = Lib.Proto.GetFloat(module_snapshot, "MaxECGeneration"); bool needToStopReactor = false; if (maxECGeneration > 0) { VesselResources resources = KERBALISM.ResourceCache.Get(v); if (!(proto_part_module as SystemHeatFissionEngineKerbalismUpdater).resourcesListParsed) { (proto_part_module as SystemHeatFissionEngineKerbalismUpdater).ParseResourcesList(proto_part); } // Mininum reactor throttle // Some input/output resources will always be consumed/produced as long as minThrottle > 0 if (minThrottle > 0) { ResourceRecipe recipe = new ResourceRecipe(KERBALISM.ResourceBroker.GetOrCreate( brokerName, KERBALISM.ResourceBroker.BrokerCategory.Converter, brokerTitle)); foreach (ResourceRatio ir in (proto_part_module as SystemHeatFissionEngineKerbalismUpdater).inputs) { recipe.AddInput(ir.ResourceName, ir.Ratio * minThrottle * elapsed_s); if (resources.GetResource(v, ir.ResourceName).Amount < double.Epsilon) { // Input resource amount is zero - stop reactor needToStopReactor = true; } } foreach (ResourceRatio or in (proto_part_module as SystemHeatFissionEngineKerbalismUpdater).outputs) { recipe.AddOutput(or.ResourceName, or.Ratio * minThrottle * elapsed_s, dump: false); if (1 - resources.GetResource(v, or.ResourceName).Level < double.Epsilon) { // Output resource is at full capacity needToStopReactor = true; Message.Post( Severity.warning, Localizer.Format( "#LOC_KerbalismSystemHeat_ReactorOutputResourceFull", or.ResourceName, v.GetDisplayName(), part_snapshot.partName) ); } } recipe.AddOutput("ElectricCharge", minThrottle * maxECGeneration * elapsed_s, dump: true); resources.AddRecipe(recipe); } if (!needToStopReactor) { if (!Lib.Proto.GetBool(reactor, "ManualControl")) { // Automatic reactor throttle mode curThrottle = maxThrottle; } curThrottle -= minThrottle; if (curThrottle > 0) { ResourceRecipe recipe = new ResourceRecipe(KERBALISM.ResourceBroker.GetOrCreate( brokerName, KERBALISM.ResourceBroker.BrokerCategory.Converter, brokerTitle)); foreach (ResourceRatio ir in (proto_part_module as SystemHeatFissionEngineKerbalismUpdater).inputs) { recipe.AddInput(ir.ResourceName, ir.Ratio * curThrottle * elapsed_s); if (resources.GetResource(v, ir.ResourceName).Amount < double.Epsilon) { // Input resource amount is zero - stop reactor needToStopReactor = true; } } foreach (ResourceRatio or in (proto_part_module as SystemHeatFissionEngineKerbalismUpdater).outputs) { recipe.AddOutput(or.ResourceName, or.Ratio * curThrottle * elapsed_s, dump: false); if (1 - resources.GetResource(v, or.ResourceName).Level < double.Epsilon) { // Output resource is at full capacity needToStopReactor = true; Message.Post( Severity.warning, Localizer.Format( "#LOC_KerbalismSystemHeat_ReactorOutputResourceFull", or.ResourceName, v.GetDisplayName(), part_snapshot.partName) ); } } recipe.AddOutput("ElectricCharge", curThrottle * maxECGeneration * elapsed_s, dump: false); resources.AddRecipe(recipe); } } } // Disable reactor if (needToStopReactor) { Lib.Proto.Set(reactor, "Enabled", false); } } else { // Reactor disabled - radiation decay mechanics if (Features.Radiation && Lib.Proto.GetBool(module_snapshot, "ReactorHasStarted") && Lib.Proto.GetDouble(module_snapshot, "ReactorStoppedTimestamp") > 0 && Lib.Proto.GetDouble(module_snapshot, "MinEmissionPercent") < 100) { ProtoPartModuleSnapshot emitter = KSHUtils.FindPartModuleSnapshot(part_snapshot, "Emitter"); if (emitter != null) { double EmitterMaxRadiation = Lib.Proto.GetDouble(module_snapshot, "EmitterMaxRadiation"); double MinEmissionPercent = Lib.Proto.GetDouble(module_snapshot, "MinEmissionPercent"); double EmissionDecayRate = Lib.Proto.GetDouble(module_snapshot, "EmissionDecayRate"); double MinRadiation = EmitterMaxRadiation * MinEmissionPercent / 100; if (EmissionDecayRate <= 0) { Lib.Proto.Set(emitter, "radiation", MinRadiation); Lib.Proto.Set(module_snapshot, "ReactorStoppedTimestamp", 0d); } else { double secondsPassed = Planetarium.GetUniversalTime() - Lib.Proto.GetDouble(module_snapshot, "ReactorStoppedTimestamp"); if (secondsPassed > 0) { double NewRadiation = EmitterMaxRadiation * (100 - secondsPassed / EmissionDecayRate) / 100; if (NewRadiation <= MinRadiation) { NewRadiation = MinRadiation; Lib.Proto.Set(module_snapshot, "ReactorStoppedTimestamp", 0d); } Lib.Proto.Set(emitter, "radiation", NewRadiation); } } } } } // Prevent resource consumption in ModuleSystemHeatFissionReactor.DoCatchup() // by setting LastUpdate to current time Lib.Proto.Set(reactor, "LastUpdateTime", Planetarium.GetUniversalTime()); return(brokerTitle); } return("ERR: no engine"); }
/// <summary> /// Draws the main mission window. /// Do not use currentMission.isDone or missionGoal.isDone(), use status instead!!! /// </summary> /// <param name="id">Identifier.</param> private void drawMainWindow(int id) { Status status = calculateStatus(currentMission, true, activeVessel); GUI.skin = HighLogic.Skin; GUILayout.BeginVertical(); GUILayout.BeginHorizontal(); GUILayout.Label("Current budget: ", styleValueYellow); GUILayout.Label(manager.budget + CurrencySuffix, (manager.budget < 0 ? styleValueRedBold : styleValueGreenBold)); GUILayout.EndHorizontal(); // Edits malkuth shows the modes that you have the plugin set to from settings .13 added the Borrowing Money mission deduction of %25 if (settings.disablePlugin == true) { GUILayout.Label("PLUGIN IS DISABLED ", styleValueYellow); } if (settings.difficulty == 0) { GUILayout.Label("Test Flight Mode ", styleValueYellow); } if (settings.difficulty == 1) { GUILayout.Label("Flight Mode ", styleValueGreen); } if (manager.budget < 0) { GUILayout.Label("In Red, Borrowing Money", styleWarning); } if (settings.difficulty == 2) { GUILayout.Label("HardCore Mode", styleValueRed); } // Show only when the loaded scene is an editor or a vessel is available and its situation is PRELAUNCH scrollPosition = GUILayout.BeginScrollView(scrollPosition); if (HighLogic.LoadedSceneIsEditor || status.onLaunchPad) { VesselResources res = new VesselResources(activeVessel); // .11 Edited malkuth shows only when in Testing Mode. Plan to add things like Delta V stats and other Helpful testing info if (settings.difficulty == 0) { GUILayout.Label("Flight Test Mode, No Missions, Cost Reduced to 6%", styleCaption); showCostValue("Flight Testing Cost:", res.dry() * 6 / 100, (res.dry() * 6 / 100 > manager.budget ? styleValueRedBold : styleValueYellow)); } else { // .11 Edited malkuth shows only when in flight mode. New Edit for .12 values only show if Price is above 0.. Little GUI cleanup that I think works better. .12 Edit Added Oxegen and Modular Fuel Cost GUILayout.Label("Flight Mode Selected, Vessel launch Full Price. Missions Available ", styleCaption); if (res.pod() > (0)) { showCostValue("Command Sections:", res.pod(), styleValueGreen); } showCostValue("Crew insurance (Launch Pad Only): ", res.crew(), styleValueGreen); if (res.ctrl() > (0)) { showCostValue("Avionics and Control:", res.ctrl(), styleValueGreen); } // NOT control surfaces. Those are AERO parts. These are SAS etc if (res.util() > (0)) { showCostValue("Utility Parts:", res.util(), styleValueGreen); } if (res.sci() > (0)) { showCostValue("Science Parts:", res.sci(), styleValueGreen); } if (res.engine() > (0)) { showCostValue("Engines And Cooling: ", res.engine(), styleValueGreen); } if (res.tank() > (0)) { showCostValue("Fuel Tank Cost: ", res.tank(), styleValueGreen); } if (res.oxylife() > (0)) { showCostValue("Oxygen Life Support: ", res.oxylife(), styleValueGreen); } if (res.LiquidOxy() > (0)) { showCostValue("LiquidOxygen fuel costs:", res.LiquidOxy(), styleValueGreen); } if (res.LiquidH() > (0)) { showCostValue("LiquidH2O:", res.LiquidH(), styleValueGreen); } if (res.liquid() > (0)) { showCostValue("Liquid fuel costs:", res.liquid(), styleValueGreen); } if (res.oxidizer() > (0)) { showCostValue("Oxidizer costs:", res.oxidizer(), styleValueGreen); } if (res.mono() > (0)) { showCostValue("Monopropellant costs:", res.mono(), styleValueGreen); } if (res.solid() > (0)) { showCostValue("Solid fuel costs:", res.solid(), styleValueGreen); } if (res.xenon() > (0)) { showCostValue("Xenon gas costs:", res.xenon(), styleValueGreen); } if (res.stru() > (0)) { showCostValue("Structural Cost:", res.stru(), styleValueGreen); } if (res.aero() > (0)) { showCostValue("Aerodynamic Cost:", res.aero(), styleValueGreen); } if (res.wet() > (0)) { showCostValue("(Total Cost Of Fuels):", res.wet(), styleCaption); } if (res.dry() > (0)) { showCostValue("(Total Cost Of Parts):", res.dry(), styleCaption); } showCostValue("Total Cost Of Vessel With All:", res.sum(), (res.sum() > manager.budget ? styleValueRedBold : styleValueYellow)); } } if (status.isClientControlled) { MissionStatus s = manager.getClientControlledMission(activeVessel); GUILayout.Label("This vessel is controlled by a client. Do not destroy this vessel! Fine: " + s.punishment + CurrencySuffix, styleWarning); GUILayout.Label("End of life in " + MathTools.formatTime(s.endOfLife - Planetarium.GetUniversalTime())); } else if (status.isOnPassiveMission) { MissionStatus s = manager.getPassiveMission(activeVessel); GUILayout.Label("This vessel is involved in a passive mission. Do not destroy this vessel! Fine: " + s.punishment + CurrencySuffix, styleWarning); GUILayout.Label("End of life in " + MathTools.formatTime(s.endOfLife - Planetarium.GetUniversalTime())); } ; if (currentMission != null) { drawMission(currentMission, status); } GUILayout.Space(30); GUILayout.EndScrollView(); if (GUILayout.Button("Configure")) { settingsWindow(!showSettingsWindow); resetCount = 0; } if (!HighLogic.LoadedSceneIsEditor && !HighLogic.LoadedSceneIsFlight && GUILayout.Button("Financing")) { financeWindow(!showFinanceWindow); resetCount = 0; } if (!HighLogic.LoadedSceneIsFlight && GUILayout.Button("KerbalNauts")) { kerbalNautsWindow(!showkerbalwindow); resetCount = 0; } // if (GUILayout.Button ("Draw landing area!", styleButton)) { // drawLandingArea = !drawLandingArea; // } if (GUILayout.Button("Select mission package")) { createFileBrowser("Select mission from package", selectMissionPackage); } if (currentPackage != null) { if (GUILayout.Button("Open browser window")) { packageWindow(true); } } if (currentMission != null) { if (GUILayout.Button("Deselect mission")) { currentMission = null; } } if (status.missionIsFinishable) { if (GUILayout.Button("Finish the mission!")) { manager.finishMission(currentMission, activeVessel, status.events); hiddenGoals = new List <MissionGoal> (); currentMission = null; } } // NK recycle from tracking station if (HighLogic.LoadedScene.Equals(GameScenes.TRACKSTATION) && pVessel != null && settings.difficulty != 0) { //print("*MC* In TS, pVessel not null"); if (pVessel.situation.Equals(Vessel.Situations.LANDED) || pVessel.situation.Equals(Vessel.Situations.SPLASHED)) { VesselResources res = new VesselResources(pVessel.vesselRef); showCostValue("Recyclable value: ", res.recyclable(pVessel.situation.Equals(Vessel.Situations.LANDED)), styleCaption); } } GUILayout.EndVertical(); GUI.DragWindow(); }
/// <summary> /// Draws the main mission window. /// Do not use currentMission.isDone or missionGoal.isDone(), use status instead!!! /// </summary> /// <param name="id">Identifier.</param> private void drawMainWindow(int id) { Status status = calculateStatus(currentMission, true, activeVessel); GUI.skin = HighLogic.Skin; GUILayout.BeginVertical(); scrollPosition = GUILayout.BeginScrollView(scrollPosition); GUILayout.BeginVertical(); GUILayout.BeginHorizontal(); GUILayout.Label("Current budget: ", styleValueName); GUILayout.Label(manager.budget + CurrencySuffix, (manager.budget < 0 ? styleValueRed : styleValueGreen)); GUILayout.EndHorizontal(); // Show only when the loaded scene is an editor or a vessel is available and its situation is PRELAUNCH if (HighLogic.LoadedSceneIsEditor || status.onLaunchPad) { VesselResources res = vesselResources; showCostValue("Liquid fuel costs:", res.liquid(), styleValueGreen); showCostValue("Oxidizer costs:", res.oxidizer(), styleValueGreen); showCostValue("Monopropellant costs:", res.mono(), styleValueGreen); showCostValue("Solid fuel costs:", res.solid(), styleValueGreen); showCostValue("Xenon gas costs:", res.xenon(), styleValueGreen); showCostValue("Liquid engines: ", res.engine(), styleValueGreen); showCostValue("Crew insurance: ", res.crew(), styleValueGreen); showCostValue("Other resource costs:", res.materials(), styleValueGreen); showCostValue("Sum:", res.sum(), (res.sum() > manager.budget ? styleValueRed : styleValueGreen)); } if (status.isClientControlled) { MissionStatus s = manager.getClientControlledMission(activeVessel); GUILayout.Label("This vessel is controlled by a client. Do not destroy this vessel! Fine: " + s.punishment + CurrencySuffix, styleWarning); GUILayout.Label("End of life in " + MathTools.formatTime(s.endOfLife - Planetarium.GetUniversalTime())); } else if (status.isOnPassiveMission) { MissionStatus s = manager.getPassiveMission(activeVessel); GUILayout.Label("This vessel is involved in a passive mission. Do not destroy this vessel! Fine: " + s.punishment + CurrencySuffix, styleWarning); GUILayout.Label("End of life in " + MathTools.formatTime(s.endOfLife - Planetarium.GetUniversalTime())); } GUILayout.Space(30); if (currentMission != null) { drawMission(currentMission, status); } else { drawPassiveMissions(manager.getActivePassiveMissions()); if (GUILayout.Button("Configure")) { settingsWindow(!showSettingsWindow); resetCount = 0; } } // if (GUILayout.Button ("Draw landing area!", styleButton)) { // drawLandingArea = !drawLandingArea; // } GUILayout.EndVertical(); GUILayout.EndScrollView(); if (GUILayout.Button("Select mission package")) { createFileBrowser("Select mission from package", selectMissionPackage); } if (currentPackage != null) { if (GUILayout.Button("Open browser window")) { packageWindow(true); } } if (currentMission != null) { if (GUILayout.Button("Deselect mission")) { currentMission = null; } } if (status.missionIsFinishable) { if (GUILayout.Button("Finish the mission!")) { manager.finishMission(currentMission, activeVessel, status.events); hiddenGoals = new List <MissionGoal> (); currentMission = null; } } else { if (status.recyclable) { VesselResources res = vesselResources; showCostValue("Recyclable value: ", res.recyclable(activeVessel.Landed), styleCaption); if (GUILayout.Button("Recycle and end flight!")) { manager.recycleVessel(activeVessel, res.recyclable(activeVessel.Landed)); FlightDriver.TerminateCurrentFlight(); FlightResultsDialog.showExitControls = true; FlightResultsDialog.Display("Vessel has been recycled!"); recycled = true; } } } GUILayout.EndVertical(); GUI.DragWindow(); }
public override void Load(ConfigNode node) { ConfigNode vessel_node = node.GetNode("VESSEL"); ConfigNode metric_node = node.GetNode("METRIC"); ConfigNode crew_node = node.GetNode("CREW"); vessel = new ProtoVessel(vessel_node, FlightDriver.FlightStateCache); metric = new Metric(metric_node); crew = new List<ProtoCrewMember>(); foreach(ConfigNode cn in crew_node.nodes) crew.Add(new ProtoCrewMember(cn)); id = vessel.vesselID; CoM = ConfigNode.ParseVector3(node.GetValue("CoM")); resources = new VesselResources<ProtoVessel, ProtoPartSnapshot, ProtoPartResourceSnapshot>(vessel); }
public StoredVessel(Vessel vsl) { vessel = vsl.BackupVessel(); metric = new Metric(vsl); id = vessel.vesselID; CoM = vsl.findLocalCenterOfMass(); crew = vsl.GetVesselCrew(); resources = new VesselResources<ProtoVessel, ProtoPartSnapshot, ProtoPartResourceSnapshot>(vessel); // fixTripLogger(); //FIXME }
/// <summary> /// Removes a vessel from the system /// </summary> public void RemoveVessel(Guid vesselId) { VesselResources.TryRemove(vesselId, out _); }
protected override void OnDisabled() { base.OnDisabled(); VesselResources.Clear(); }