// return read-only list of recyclers in a vessel public static List<Recycler> GetRecyclers(Vessel v, string resource_name="") { if (v.loaded) { var ret = v.FindPartModulesImplementing<Recycler>(); if (resource_name.Length > 0) ret = ret.FindAll(k => k.resource_name == resource_name); return ret == null ? new List<Recycler>() : ret; } else { List<Recycler> ret = new List<Recycler>(); foreach(ProtoPartSnapshot part in v.protoVessel.protoPartSnapshots) { foreach(ProtoPartModuleSnapshot module in part.modules) { if (module.moduleName == "Recycler") { Recycler recycler = new Recycler(); recycler.is_enabled = Lib.GetProtoValue<bool>(module, "is_enabled"); recycler.resource_name = Lib.GetProtoValue<string>(module, "resource_name"); recycler.waste_name = Lib.GetProtoValue<string>(module, "waste_name"); recycler.ec_rate = Lib.GetProtoValue<double>(module, "ec_rate"); recycler.waste_rate = Lib.GetProtoValue<double>(module, "waste_rate"); recycler.waste_ratio = Lib.GetProtoValue<double>(module, "waste_ratio"); recycler.display_name = Lib.GetProtoValue<string>(module, "display_name"); recycler.filter_name = Lib.GetProtoValue<string>(module, "filter_name"); recycler.filter_rate = Lib.GetProtoValue<double>(module, "filter_rate"); if (resource_name.Length == 0 || recycler.resource_name == resource_name) ret.Add(recycler); } } } return ret; } }
// implement recycler mechanics for unloaded vessels public static void BackgroundUpdate(Vessel vessel, ProtoPartModuleSnapshot m, Recycler recycler, vessel_resources resources, double elapsed_s) { if (Lib.Proto.GetBool(m, "is_enabled")) { // recycle EC+waste+filter into resource resource_recipe recipe = new resource_recipe(resource_recipe.scrubber_priority); recipe.Input(recycler.waste_name, recycler.waste_rate * elapsed_s); recipe.Input("ElectricCharge", recycler.ec_rate * elapsed_s); if (recycler.filter_name.Length > 0 && recycler.filter_rate > double.Epsilon) { recipe.Input(recycler.filter_name, recycler.filter_rate * elapsed_s); } recipe.Output(recycler.resource_name, recycler.waste_rate * recycler.waste_ratio * Lib.Proto.GetDouble(m, "efficiency", 1.0) * elapsed_s); resources.Transform(recipe); } }
public static void update(Vessel v, vessel_info vi, vessel_data vd, vessel_resources resources, double elapsed_s) { // get most used resource handlers resource_info ec = resources.Info(v, "ElectricCharge"); // for each part foreach (ProtoPartSnapshot p in v.protoVessel.protoPartSnapshots) { // a part can contain multiple resource converters int converter_index = 0; // get part prefab (required for module properties) Part part_prefab = PartLoader.getPartInfoByName(p.partName).partPrefab; // for each module foreach (ProtoPartModuleSnapshot m in p.modules) { // get the module prefab PartModule module_prefab = Lib.FindModule(part_prefab, m.moduleName); // if the prefab doesn't contain this module, skip it if (!module_prefab) { continue; } // process modules switch (m.moduleName) { case "Reliability": Reliability.BackgroundUpdate(v, m, module_prefab as Reliability, elapsed_s); break; case "Scrubber": Scrubber.BackgroundUpdate(v, m, module_prefab as Scrubber, vi, resources, elapsed_s); break; case "Recycler": Recycler.BackgroundUpdate(v, m, module_prefab as Recycler, resources, elapsed_s); break; case "Greenhouse": Greenhouse.BackgroundUpdate(v, p, m, module_prefab as Greenhouse, vi, resources, elapsed_s); break; case "GravityRing": GravityRing.BackgroundUpdate(v, p, m, module_prefab as GravityRing, resources, elapsed_s); break; case "Emitter": Emitter.BackgroundUpdate(v, p, m, module_prefab as Emitter, ec, elapsed_s); break; case "ModuleCommand": ProcessCommand(v, p, m, module_prefab as ModuleCommand, resources, elapsed_s); break; case "ModuleDeployableSolarPanel": ProcessPanel(v, p, m, module_prefab as ModuleDeployableSolarPanel, vi, ec, elapsed_s); break; case "ModuleGenerator": ProcessGenerator(v, p, m, module_prefab as ModuleGenerator, resources, elapsed_s); break; case "ModuleResourceConverter": case "ModuleKPBSConverter": case "FissionReactor": ProcessConverter(v, p, m, part_prefab, converter_index++, resources, elapsed_s); break; case "ModuleResourceHarvester": ProcessHarvester(v, p, m, module_prefab as ModuleResourceHarvester, resources, elapsed_s); break; case "ModuleAsteroidDrill": ProcessAsteroidDrill(v, p, m, module_prefab as ModuleAsteroidDrill, resources, elapsed_s); break; case "ModuleScienceConverter": ProcessLab(v, p, m, module_prefab as ModuleScienceConverter, ec, elapsed_s); break; case "ModuleLight": case "ModuleColoredLensLight": case "ModuleMultiPointSurfaceLight": ProcessLight(v, p, m, module_prefab as ModuleLight, ec, elapsed_s); break; case "SCANsat": case "ModuleSCANresourceScanner": ProcessScanner(v, p, m, module_prefab, part_prefab, vd, ec, elapsed_s); break; case "ModuleCurvedSolarPanel": ProcessCurvedPanel(v, p, m, module_prefab, part_prefab, vi, ec, elapsed_s); break; case "FissionGenerator": ProcessFissionGenerator(v, p, m, module_prefab, ec, elapsed_s); break; case "ModuleRadioisotopeGenerator": ProcessRadioisotopeGenerator(v, p, m, module_prefab, ec, elapsed_s); break; case "ModuleCryoTank": ProcessCryoTank(v, p, m, module_prefab, resources, elapsed_s); break; } } } }
// draw a vessel in the monitor // - return: 1 if vessel wasn't skipped uint render_vessel(Vessel v) { // avoid case when DB isn't ready for whatever reason if (!DB.Ready()) return 0; // skip invalid vessels if (!Lib.IsVessel(v)) return 0; // skip resque missions if (Lib.IsResqueMission(v)) return 0; // skip dead eva kerbals if (EVA.IsDead(v)) return 0; // get vessel info from cache vessel_info vi = Cache.VesselInfo(v); // get vessel data from the db vessel_data vd = DB.VesselData(v.id); // skip filtered vessels if (filtered() && vd.group != filter) return 0; // get vessel crew List<ProtoCrewMember> crew = v.loaded ? v.GetVesselCrew() : v.protoVessel.GetVesselCrew(); // get vessel name string vessel_name = v.isEVA ? crew[0].name : v.vesselName; // get body name string body_name = v.mainBody.name.ToUpper(); // get list of recyclers List<Scrubber> scrubbers = Scrubber.GetScrubbers(v); List<Recycler> recyclers = Recycler.GetRecyclers(v); // get list of greenhouses List<Greenhouse> greenhouses = Greenhouse.GetGreenhouses(v); // store problems icons & tooltips List<Texture> problem_icons = new List<Texture>(); List<string> problem_tooltips = new List<string>(); // detect problems problem_sunlight(vi, ref problem_icons, ref problem_tooltips); problem_storm(v, ref problem_icons, ref problem_tooltips); if (crew.Count > 0) { problem_kerbals(crew, ref problem_icons, ref problem_tooltips); problem_radiation(vi, ref problem_icons, ref problem_tooltips); problem_recyclers(v, scrubbers, recyclers, ref problem_icons, ref problem_tooltips); } problem_greenhouses(v, greenhouses, ref problem_icons, ref problem_tooltips); // choose problem icon const UInt64 problem_icon_time = 3; Texture problem_icon = icon_empty; if (problem_icons.Count > 0) { UInt64 problem_index = (Convert.ToUInt64(Time.realtimeSinceStartup) / problem_icon_time) % (UInt64)(problem_icons.Count); problem_icon = problem_icons[(int)problem_index]; } // generate problem tooltips string problem_tooltip = String.Join("\n", problem_tooltips.ToArray()); // render vessel name & icons GUILayout.BeginHorizontal(row_style); GUILayout.Label(new GUIContent("<b>" + Lib.Epsilon(vessel_name, 20) + "</b>", vessel_name.Length > 20 ? vessel_name : ""), name_style); GUILayout.Label(new GUIContent(Lib.Epsilon(body_name, 8), body_name.Length > 8 ? body_name : ""), body_style); GUILayout.Label(new GUIContent(problem_icon, problem_tooltip), icon_style); GUILayout.Label(indicator_ec(v), icon_style); if (Kerbalism.supply_rules.Count > 0) GUILayout.Label(indicator_supplies(v, vi), icon_style); if (Kerbalism.features.malfunction) GUILayout.Label(indicator_reliability(v), icon_style); if (Kerbalism.features.signal) GUILayout.Label(indicator_signal(v), icon_style); GUILayout.EndHorizontal(); if (Lib.IsClicked(1)) Info.Toggle(v); // remember last vessel clicked if (Lib.IsClicked()) last_clicked_id = v.id; // render vessel config if (configured_id == v.id) render_config(v); // spacing between vessels GUILayout.Space(10.0f); // signal that the vessel wasn't skipped for whatever reason return 1; }
public vessel_info(Vessel v, uint vessel_id, UInt64 inc) { // NOTE: anything used here can't in turn use cache, unless you know what you are doing // associate with an unique incremental id this.inc = inc; // determine if this is a valid vessel is_vessel = Lib.IsVessel(v); if (!is_vessel) return; // determine if this is a resque mission vessel is_resque = Lib.IsResqueMission(v); if (is_resque) return; // dead EVA are not valid vessels if (v.isEVA && EVA.KerbalData(v).eva_dead) return; // shortcut for common tests is_valid = true; // generate id once id = vessel_id; // calculate crew info for the vessel crew_count = Lib.CrewCount(v); crew_capacity = Lib.CrewCapacity(v); // get vessel position once position = Lib.VesselPosition(v); // determine if in sunlight, calculate sun direction and distance sunlight = Sim.RaytraceBody(v, position, FlightGlobals.Bodies[0], out sun_dir, out sun_dist) ? 1.0 : 0.0; // if the orbit length vs simulation step is lower than an acceptable threshold, use discrete sun visibility if (v.mainBody.flightGlobalsIndex != 0) { double orbit_period = Sim.OrbitalPeriod(v); if (orbit_period / Kerbalism.elapsed_s < 16.0) sunlight = 1.0 - Sim.ShadowPeriod(v) / orbit_period; } // calculate environment stuff atmo_factor = Sim.AtmosphereFactor(v.mainBody, position, sun_dir); gamma_transparency = Sim.GammaTransparency(v.mainBody, v.altitude); breathable = Sim.Breathable(v); landed = Lib.Landed(v); // calculate temperature at vessel position temperature = Sim.Temperature(v, position, sunlight, atmo_factor, out solar_flux, out albedo_flux, out body_flux, out total_flux); // calculate radiation radiation = Radiation.Compute(v, position, gamma_transparency, sunlight, out blackout, out inside_pause, out inside_belt); // calculate malfunction stuff max_malfunction = Reliability.MaxMalfunction(v); avg_quality = Reliability.AverageQuality(v); // calculate signal info antenna = new antenna_data(v); avoid_inf_recursion.Add(v.id); link = Signal.Link(v, position, antenna, blackout, avoid_inf_recursion); avoid_inf_recursion.Remove(v.id); // partial data about modules, used by vessel info/monitor scrubbers = Scrubber.PartialData(v); recyclers = Recycler.PartialData(v); greenhouses = Greenhouse.PartialData(v); // woot relativity time_dilation = Sim.TimeDilation(v); }
public RecyclerDevice(Recycler recycler) { this.recycler = recycler; }