// implement gravity ring mechanics for unloaded vessels public static void BackgroundUpdate(Vessel vessel, uint flight_id) { // get time elapsed from last update double elapsed_s = TimeWarp.fixedDeltaTime; // get data ProtoPartModuleSnapshot m = Lib.GetProtoModule(vessel, flight_id, "GravityRing"); double entertainment_rate = Lib.GetProtoValue<double>(m, "entertainment_rate"); double ec_rate = Lib.GetProtoValue<double>(m, "ec_rate"); float speed = Lib.GetProtoValue<float>(m, "speed"); // consume ec double ec_light_perc = 0.0; if (speed > float.Epsilon) { double ec_light_required = ec_rate * elapsed_s * speed; double ec_light = Lib.RequestResource(vessel, "ElectricCharge", ec_light_required); ec_light_perc = ec_light / ec_light_required; // if there isn't enough ec if (ec_light <= double.Epsilon) { // reset speed speed = 0.0f; } } // set entertainment double rate = 1.0 + (entertainment_rate - 1.0) * speed; // write back data Lib.SetProtoValue(m, "speed", speed); Lib.SetProtoValue(m, "rate", rate); }
// implement malfunction mechanics for unloaded vessels public static void BackgroundUpdate(Vessel vessel, uint flight_id) { // get data ProtoPartModuleSnapshot m = Lib.GetProtoModule(vessel, flight_id, "Malfunction"); uint malfunctions = Lib.GetProtoValue<uint>(m, "malfunctions"); double min_lifetime = Lib.GetProtoValue<double>(m, "min_lifetime"); double max_lifetime = Lib.GetProtoValue<double>(m, "max_lifetime"); double lifetime = Lib.GetProtoValue<double>(m, "lifetime"); double age = Lib.GetProtoValue<double>(m, "age"); double quality = Lib.GetProtoValue<double>(m, "quality"); string malfunction_msg = m.moduleValues.GetValue("malfunction_msg"); // if for some reason quality wasn't set, default to 1.0 (but don't save it) // note: for example, resque vessels failure get background update without prelaunch if (quality <= double.Epsilon) quality = 1.0; // generate lifetime if necessary if (lifetime <= double.Epsilon) { lifetime = min_lifetime + (max_lifetime - min_lifetime) * Lib.RandomDouble(); } // accumulate age age += TimeWarp.fixedDeltaTime * AgingCurve(age, min_lifetime, max_lifetime) / quality; // save data // note: done before checking for malfunction because proto Break change data again Lib.SetProtoValue<double>(m, "lifetime", lifetime); Lib.SetProtoValue<double>(m, "age", age); // check age and malfunction if needed if (age > lifetime) Break(vessel, m); }
// implement scrubber mechanics for unloaded vessels public static void BackgroundUpdate(Vessel vessel, uint flight_id) { // get data ProtoPartModuleSnapshot m = Lib.GetProtoModule(vessel, flight_id, "Scrubber"); bool is_enabled = Lib.GetProtoValue<bool>(m, "is_enabled"); double ec_rate = Lib.GetProtoValue<double>(m, "ec_rate"); double co2_rate = Lib.GetProtoValue<double>(m, "co2_rate"); double efficiency = Lib.GetProtoValue<double>(m, "efficiency"); // if for some reason efficiency wasn't set, default to 50% // note: for example, resque vessels scrubbers get background update without prelaunch if (efficiency <= double.Epsilon) efficiency = 0.5; // get time elapsed from last update double elapsed_s = TimeWarp.fixedDeltaTime; // if inside breathable atmosphere if (LifeSupport.BreathableAtmosphere(vessel)) { // produce oxygen from the intake Lib.RequestResource(vessel, "Oxygen", -Settings.IntakeOxygenRate * elapsed_s); } // if outside breathable atmosphere and enabled else if (is_enabled) { // recycle CO2+EC into oxygen double co2_required = co2_rate * elapsed_s; double co2 = Lib.RequestResource(vessel, "CO2", co2_required); double ec_required = ec_rate * elapsed_s * (co2 / co2_required); double ec = Lib.RequestResource(vessel, "ElectricCharge", ec_required); Lib.RequestResource(vessel, "Oxygen", -co2 * efficiency); } }
// implement recycler mechanics for unloaded vessels public static void BackgroundUpdate(Vessel vessel, uint flight_id) { // get data ProtoPartModuleSnapshot m = Lib.GetProtoModule(vessel, flight_id, "Recycler"); bool is_enabled = Lib.GetProtoValue<bool>(m, "is_enabled"); string resource_name = Lib.GetProtoValue<string>(m, "resource_name"); string waste_name = Lib.GetProtoValue<string>(m, "waste_name"); double ec_rate = Lib.GetProtoValue<double>(m, "ec_rate"); double waste_rate = Lib.GetProtoValue<double>(m, "waste_rate"); double waste_ratio = Lib.GetProtoValue<double>(m, "waste_ratio"); string filter_name = Lib.GetProtoValue<string>(m, "filter_name"); double filter_rate = Lib.GetProtoValue<double>(m, "filter_rate"); if (is_enabled) { // calculate worst required resource percentual double worst_input = 1.0; double waste_required = waste_rate * TimeWarp.fixedDeltaTime; double waste_amount = Lib.GetResourceAmount(vessel, waste_name); worst_input = Math.Min(worst_input, waste_amount / waste_required); double ec_required = ec_rate * TimeWarp.fixedDeltaTime; double ec_amount = Lib.GetResourceAmount(vessel, "ElectricCharge"); worst_input = Math.Min(worst_input, ec_amount / ec_required); double filter_required = filter_rate * TimeWarp.fixedDeltaTime; if (filter_name.Length > 0 && filter_rate > 0.0) { double filter_amount = Lib.GetResourceAmount(vessel, filter_name); worst_input = Math.Min(worst_input, filter_amount / filter_required); } // recycle EC+waste+filter into resource Lib.RequestResource(vessel, waste_name, waste_required * worst_input); Lib.RequestResource(vessel, "ElectricCharge", ec_required * worst_input); Lib.RequestResource(vessel, filter_name, filter_required * worst_input); Lib.RequestResource(vessel, resource_name, -waste_required * worst_input * waste_ratio); } }
// implement greenhouse mechanics for unloaded vessels public static void BackgroundUpdate(Vessel vessel, uint flight_id) { // get data ProtoPartModuleSnapshot m = Lib.GetProtoModule(vessel, flight_id, "Greenhouse"); double ec_rate = Lib.GetProtoValue<double>(m, "ec_rate"); double waste_rate = Lib.GetProtoValue<double>(m, "waste_rate"); double harvest_size = Lib.GetProtoValue<double>(m, "harvest_size"); double growth_rate = Lib.GetProtoValue<double>(m, "growth_rate"); bool door_opened = Lib.GetProtoValue<bool>(m, "door_opened"); double growth = Lib.GetProtoValue<double>(m, "growth"); float lamps = Lib.GetProtoValue<float>(m, "lamps"); double lighting = Lib.GetProtoValue<double>(m, "lighting"); // get time elapsed from last update double elapsed_s = TimeWarp.fixedDeltaTime; // consume ec for lighting double ec_light_perc = 0.0; if (lamps > float.Epsilon) { double ec_light_required = ec_rate * elapsed_s * lamps; double ec_light = Lib.RequestResource(vessel, "ElectricCharge", ec_light_required); ec_light_perc = ec_light / ec_light_required; // if there isn't enough ec for lighting if (ec_light <= double.Epsilon) { // shut down the light lamps = 0.0f; } } // get vessel info from the cache vessel_info info = Cache.VesselInfo(vessel); // 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 = NaturalLighting(info.sun_dist) * (info.sunlight ? 1.0 : 0.0) * (door_opened ? 1.0 : 0.0) + lamps * ec_light_perc * (door_opened ? 1.0 : 1.0 + Settings.GreenhouseDoorBonus); // consume waste double waste_required = waste_rate * elapsed_s; double waste = Lib.RequestResource(vessel, "Waste", waste_required); double waste_perc = waste / waste_required; // determine growth bonus double growth_bonus = 0.0; growth_bonus += Settings.GreenhouseSoilBonus * (Lib.Landed(vessel) ? 1.0 : 0.0); growth_bonus += Settings.GreenhouseWasteBonus * waste_perc; // grow the crop growth += elapsed_s * (growth_rate * (1.0 + growth_bonus)) * lighting; // if it is harvest time if (growth >= 1.0) { // reset growth growth = 0.0; // produce food Lib.RequestResource(vessel, "Food", -harvest_size); // show a message to the user Message.Post("On <color=FFFFFF>" + vessel.vesselName + "</color> the crop harvest produced <color=FFFFFF>" + harvest_size.ToString("F0") + " Food</color>"); } // store data Lib.SetProtoValue(m, "growth", growth); Lib.SetProtoValue(m, "lighting", lighting); Lib.SetProtoValue(m, "lamps", lamps); }