// show warning message when a vessel cross a radiation belt public static void beltWarnings(Vessel v, vessel_info vi, vessel_data vd) { // if there is a radiation rule if (Kerbalism.rad_rule != null) { // we only show the warning for manned vessels, or for all vessels the first time its crossed bool must_warn = vi.crew_count > 0 || DB.Landmarks().belt_crossing == 0; // show the message if (vi.inside_belt && vd.msg_belt < 1 && must_warn) { Message.Post(Lib.BuildString("<b>", v.vesselName, "</b> is crossing <i>", v.mainBody.bodyName, " radiation belt</i>"), "Exposed to extreme radiation"); vd.msg_belt = 1; } else if (!vi.inside_belt && vd.msg_belt > 0) { // no message after crossing the belt vd.msg_belt = 0; } } // record first belt crossing if (vi.inside_belt) { DB.Landmarks().belt_crossing = 1; } }
public override bool MeetRequirements() { // stop checking when requirements are met if (!meet_requirements) { meet_requirements = (Kerbalism.ec_rule != null || Kerbalism.supply_rules.Count > 0) // some resource-related life support rule is present && ProgressTracking.Instance != null && ProgressTracking.Instance.celestialBodyHome.orbit.IsComplete // first orbit completed && DB.Ready() && DB.Landmarks().manned_orbit== 0; // contract never completed } return meet_requirements; }
public override bool MeetRequirements() { // stop checking when requirements are met if (!meet_requirements) { meet_requirements = PartLoader.getPartInfoByName("Greenhouse") != null // greenhouse part is present && Lib.TechReady() && Lib.HasTech("scienceTech") // greenhouse unlocked && DB.Ready() && DB.Landmarks().space_harvest == 0; // greenhouse never harvested in space before } return meet_requirements; }
public override bool MeetRequirements() { // stop checking when requirements are met if (!meet_requirements) { meet_requirements = Kerbalism.rad_rule != null // a radiation rule is present && ProgressTracking.Instance != null && ProgressTracking.Instance.reachSpace.IsComplete // first suborbit flight completed && DB.Ready() && DB.Landmarks().belt_crossing == 0; // belt never crossed before } return meet_requirements; }
protected override void OnUpdate() { foreach(Vessel v in FlightGlobals.Vessels) { vessel_info vi = Cache.VesselInfo(v); if (!vi.is_valid) continue; bool manned = v.loaded ? v.GetCrewCount() > 0 : v.protoVessel.GetVesselCrew().Count > 0; bool in_orbit = Sim.Apoapsis(v) > v.mainBody.atmosphereDepth && Sim.Periapsis(v) > v.mainBody.atmosphereDepth; bool for_30days = v.missionTime > 60.0 * 60.0 * Lib.HoursInDay() * 30.0; if (manned && in_orbit && for_30days && DB.Ready()) { base.SetComplete(); DB.Landmarks().manned_orbit = 1; //< remember that contract was completed break; } } }
public void EmergencyHarvest() { // calculate reduced harvest size double reduced_harvest = harvest_size * growth * 0.5; // produce reduced quantity of food, proportional to current growth ResourceCache.Produce(vessel, resource_name, reduced_harvest); // reset growth growth = 0.0; // show message Message.Post(Lib.BuildString("On <color=FFFFFF>", vessel.vesselName, "</color> an emergency harved produced <color=FFFFFF>", reduced_harvest.ToString("F0"), " ", resource_name, "</color>")); // record first harvest if (!Lib.Landed(vessel) && DB.Ready()) DB.Landmarks().space_harvest = 1; }
protected override void OnUpdate() { if (DB.Ready() && DB.Landmarks().space_harvest == 1) base.SetComplete(); }
protected override void OnUpdate() { if (DB.Ready() && DB.Landmarks().belt_crossing == 1) base.SetComplete(); }
// implement greenhouse mechanics for unloaded vessels public static void BackgroundUpdate(Vessel vessel, ProtoPartSnapshot p, ProtoPartModuleSnapshot m, Greenhouse greenhouse, vessel_info info, vessel_resources resources, double elapsed_s) { // get protomodule data bool door_opened = Lib.Proto.GetBool(m, "door_opened"); double growth = Lib.Proto.GetDouble(m, "growth"); float lamps = Lib.Proto.GetFloat(m, "lamps"); double lighting = Lib.Proto.GetDouble(m, "lighting"); // if lamp is on if (lamps > float.Epsilon) { // get resource handler resource_info ec = resources.Info(vessel, "ElectricCharge"); // consume ec ec.Consume(greenhouse.ec_rate * lamps * elapsed_s * Reliability.Penalty(p, "Greenhouse", 2.0)); // shut down the light if there isn't enough ec // note: comparing against amount at previous simulation step if (ec.amount <= double.Epsilon) lamps = 0.0f; } // determine lighting conditions // note: we ignore sun direction for gameplay reasons: else the user must reorient the greenhouse as the planets dance over time // - natural light depend on: distance from sun, direct sunlight, door status // - artificial light depend on: lamps tweakable and ec available, door status lighting = info.solar_flux / Sim.SolarFluxAtHome() * (door_opened ? 1.0 : 0.0) + lamps; // if can use waste, and there is some lighting double waste_perc = 0.0; if (greenhouse.waste_name.Length > 0 && lighting > double.Epsilon) { // get resource handler resource_info waste = resources.Info(vessel, greenhouse.waste_name); // consume waste waste.Consume(greenhouse.waste_rate * elapsed_s); // determine waste bonus // note: comparing against amount from previous simulation step waste_perc = Math.Min(waste.amount / greenhouse.waste_rate, 1.0); } // determine growth bonus double growth_bonus = greenhouse.soil_bonus * (info.landed ? 1.0 : 0.0) + greenhouse.waste_bonus * waste_perc; // grow the crop double growing = greenhouse.growth_rate * (1.0 + growth_bonus) * lighting; growth += elapsed_s * growing; // if it is harvest time if (growth >= 1.0) { // reset growth growth = 0.0; // produce food resources.Produce(vessel, greenhouse.resource_name, greenhouse.harvest_size); // show a message to the user Message.Post(Lib.BuildString("On <color=FFFFFF>", vessel.vesselName, "</color> the crop harvest produced <color=FFFFFF>", greenhouse.harvest_size.ToString("F0"), " ", greenhouse.resource_name, "</color>")); // record first space harvest if (!info.landed && DB.Ready()) DB.Landmarks().space_harvest = 1; } // store data Lib.Proto.Set(m, "growth", growth); Lib.Proto.Set(m, "lamps", lamps); Lib.Proto.Set(m, "lighting", lighting); Lib.Proto.Set(m, "growth_diff", growing); }
// implement greenhouse mechanics public void FixedUpdate() { // set emissive intensity from lamp tweakable if (emissive_object.Length > 0) { foreach(var rdr in part.GetComponentsInChildren<UnityEngine.Renderer>()) { if (rdr.name == emissive_object) { rdr.material.SetColor("_EmissiveColor", new Color(lamps, lamps, lamps, 1.0f)); break; } } } // do nothing else in the editor if (HighLogic.LoadedSceneIsEditor) return; // get vessel info from the cache vessel_info vi = Cache.VesselInfo(vessel); // do nothing if vessel is invalid if (!vi.is_valid) return; // get resource cache vessel_resources resources = ResourceCache.Get(vessel); // get elapsed time double elapsed_s = Kerbalism.elapsed_s * vi.time_dilation; // when the greenhouse is assembled using KIS, the growth field is set to NaN // at that point it remain NaN forever, so we fix it // also, a report indicated -infinity in growth if (double.IsNaN(growth) || double.IsInfinity(growth)) growth = 0.0; // if lamp is on if (lamps > float.Epsilon) { // get resource handler resource_info ec = resources.Info(vessel, "ElectricCharge"); // consume ec ec.Consume(ec_rate * lamps * elapsed_s); // shut down the light if there isn't enough ec // note: comparing against amount at previous simulation step if (ec.amount <= double.Epsilon) lamps = 0.0f; } // determine lighting conditions // note: we ignore sun direction for gameplay reasons: else the user must reorient the greenhouse as the planets dance over time lighting = vi.solar_flux / Sim.SolarFluxAtHome() * (door_opened ? 1.0 : 0.0) + lamps; // if can use waste, and there is some lighting double waste_perc = 0.0; if (waste_name.Length > 0 && waste_rate > double.Epsilon && lighting > double.Epsilon) { // get resource handler resource_info waste = resources.Info(vessel, waste_name); // consume waste waste.Consume(waste_rate * elapsed_s); // determine waste bonus // note: comparing against amount from previous simulation step waste_perc = Math.Min(waste.amount / waste_rate, 1.0); } // determine growth bonus double growth_bonus = soil_bonus * (vi.landed ? 1.0 : 0.0) + waste_bonus * waste_perc; // grow the crop growing = growth_rate * (1.0 + growth_bonus) * lighting; growth += elapsed_s * growing; // if it is harvest time if (growth >= 1.0) { // reset growth growth = 0.0; // produce food resources.Produce(vessel, resource_name, harvest_size); // show a message to the user Message.Post(Lib.BuildString("On <color=FFFFFF>", vessel.vesselName, "</color> the crop harvest produced <color=FFFFFF>", harvest_size.ToString("F0"), " ", resource_name, "</color>")); // record first space harvest if (!vi.landed && DB.Ready()) DB.Landmarks().space_harvest = 1; } // set rmb ui status GrowthStatus = Lib.HumanReadablePerc(growth); LightStatus = Lib.HumanReadablePerc(lighting); WasteStatus = Lib.HumanReadablePerc(waste_perc); SoilStatus = vi.landed ? "yes" : "no"; TTAStatus = Lib.HumanReadableDuration(growing > double.Epsilon ? (1.0 - growth) / growing : 0.0); // enable/disable emergency harvest Events["EmergencyHarvest"].active = (growth >= 0.5); }