// execute the recipe public bool Execute(Vessel v, vessel_resources resources) { // determine worst input ratio // - pure input recipes can just underflow double worst_input = left; if (outputs.Count > 0) { for (int i = 0; i < inputs.Count; ++i) { entry e = inputs[i]; resource_info res = resources.Info(v, e.name); worst_input = Lib.Clamp((res.amount + res.deferred) * e.inv_quantity, 0.0, worst_input); } } // determine worst output ratio // - pure output recipes can just overflow double worst_output = left; if (inputs.Count > 0) { for (int i = 0; i < outputs.Count; ++i) { entry e = outputs[i]; if (!e.dump) // ignore outputs that can dump overboard { resource_info res = resources.Info(v, e.name); worst_output = Lib.Clamp((res.capacity - (res.amount + res.deferred)) * e.inv_quantity, 0.0, worst_output); } } } // determine worst-io double worst_io = Math.Min(worst_input, worst_output); // consume inputs for (int i = 0; i < inputs.Count; ++i) { entry e = inputs[i]; resources.Consume(v, e.name, e.quantity * worst_io); } // produce outputs for (int i = 0; i < outputs.Count; ++i) { entry e = outputs[i]; resources.Produce(v, e.name, e.quantity * worst_io); } // update amount left to execute left -= worst_io; // the recipe was executed, at least partially return(worst_io > double.Epsilon); }
public void update(Vessel v, vessel_info vi, vessel_data vd, vessel_resources resources, double elapsed_s) { // do nothing if signal mechanic is disabled if (!Kerbalism.features.signal) { return; } // get link data link_data link = vi.link; // consume relay ec // note: this is the only way to do it with new signal and resource systems if (vi.antenna.relay_range > 0.0) { foreach (Vessel w in FlightGlobals.Vessels) { vessel_info wi = Cache.VesselInfo(w); if (wi.is_valid) { if (wi.link.path.Contains(v)) { resources.Consume(v, "ElectricCharge", vi.antenna.relay_cost * elapsed_s); break; } } } } // maintain and send messages // - do nothing if db isn't ready // - do not send messages for vessels without an antenna if (link.status != link_status.no_antenna) { if (vd.msg_signal < 1 && !link.linked) { vd.msg_signal = 1; if (vd.cfg_signal == 1 && !vi.blackout) //< do not send message during storms { Message.Post(Severity.warning, Lib.BuildString("Signal lost with <b>", v.vesselName, "</b>"), vi.crew_count == 0 && Settings.RemoteControlLink ? "Remote control disabled" : "Data transmission disabled"); } } else if (vd.msg_signal > 0 && link.linked) { vd.msg_signal = 0; if (vd.cfg_signal == 1 && !Storm.JustEnded(v, elapsed_s)) //< do not send messages after a storm { var path = link.path; Message.Post(Severity.relax, Lib.BuildString("<b>", v.vesselName, "</b> signal is back"), path.Count == 0 ? "We got a direct link with the space center" : Lib.BuildString("Relayed by <b>", path[path.Count - 1].vesselName, "</b>")); } } } }
static void ProcessCommand(Vessel v, ProtoPartSnapshot p, ProtoPartModuleSnapshot m, ModuleCommand command, vessel_resources resources, double elapsed_s) { // do not consume if this is a MCM with no crew // rationale: for consistency, the game doesn't consume resources for MCM without crew in loaded vessels // this make some sense: you left a vessel with some battery and nobody on board, you expect it to not consume EC if (command.minimumCrew == 0 || p.protoModuleCrew.Count > 0) { // for each input resource foreach (ModuleResource ir in command.resHandler.inputResources) { // consume the resource resources.Consume(v, ir.name, ir.rate * elapsed_s); } } }
public virtual void FixedUpdate() { if (FixGame(thisModule)) { return; } hasEC = ResourceCache.Info(part.vessel, "ElectricCharge").amount > double.Epsilon; if (GetIsActive()) { part.ModulesOnUpdate(); // get resource cache vessel_resources resources = ResourceCache.Get(part.vessel); resources.Consume(part.vessel, "ElectricCharge", actualECCost * Kerbalism.elapsed_s); } else { actualECCost = 0; } }
// consume EC for transmission, and transmit science data public static void update(Vessel v, vessel_info vi, VesselData vd, vessel_resources resources, double elapsed_s) { // hard-coded transmission buffer size in Mb const double buffer_capacity = 8.0; // do nothing if science system is disabled if (!Features.Science) { return; } // avoid corner-case when RnD isn't live during scene changes // - this avoid losing science if the buffer reach threshold during a scene change if (HighLogic.CurrentGame.Mode != Game.Modes.SANDBOX && ResearchAndDevelopment.Instance == null) { return; } // get connection info ConnectionInfo conn = vi.connection; // consume ec if data is transmitted or relayed if (vi.transmitting.Length > 0 || vi.relaying.Length > 0) { resources.Consume(v, "ElectricCharge", conn.cost * elapsed_s); } // get filename of data being downloaded string filename = vi.transmitting; // if some data is being downloaded // - avoid cornercase at scene changes if (filename.Length > 0 && vd.drive.files.ContainsKey(filename)) { // get file File file = vd.drive.files[filename]; // determine how much data is transmitted double transmitted = Math.Min(file.size, conn.rate * elapsed_s); // consume data in the file file.size -= transmitted; // accumulate in the buffer file.buff += transmitted; // if buffer is full, or file was transmitted completely if (file.size <= double.Epsilon || file.buff > buffer_capacity) { // collect the science data Science.credit(filename, file.buff, true, v.protoVessel); // reset the buffer file.buff = 0.0; } // if file was transmitted completely if (file.size <= double.Epsilon) { // remove the file vd.drive.files.Remove(filename); // inform the user Message.Post ( Lib.BuildString("<color=cyan><b>DATA RECEIVED</b></color>\nTransmission of <b>", Science.experiment(filename).name, "</b> completed"), Lib.TextVariant("Our researchers will jump on it right now", "The checksum is correct, data must be valid") ); } } }