Beispiel #1
0
  // 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);
    }
  }
Beispiel #2
0
  // implement scrubber mechanics
  public void FixedUpdate()
  {
    // do nothing in the editor
    if (HighLogic.LoadedSceneIsEditor) return;

    // deduce quality from technological level if necessary
    // note: done at prelaunch to avoid problems with start()/load() and the tech tree being not consistent
    if (vessel.situation == Vessel.Situations.PRELAUNCH) efficiency = DeduceEfficiency();

    // if for some reason efficiency wasn't set, default to 50%
    // note: for example, resque vessels never get to 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(this.vessel))
    {
      // produce oxygen from the intake
      this.part.RequestResource("Oxygen", -Settings.IntakeOxygenRate * elapsed_s);

      // set status
      Status = "Intake";
    }
    // if outside breathable atmosphere and enabled
    else if (is_enabled)
    {
      // recycle CO2+EC into oxygen
      double co2_required = co2_rate * elapsed_s;
      double co2 = this.part.RequestResource("CO2", co2_required);
      double ec_required = ec_rate * elapsed_s * (co2 / co2_required);
      double ec = this.part.RequestResource("ElectricCharge", ec_required);
      this.part.RequestResource("Oxygen", -co2 * efficiency);

      // set status
      Status = co2 <= double.Epsilon ? "No CO2" : ec <= double.Epsilon ? "No Power" : "Running";
    }
    // if outside breathable atmosphere and disabled
    else
    {
      // set status
      Status = "Off";
    }

    // add efficiency to status
    Status += " (Efficiency: " + (efficiency * 100.0).ToString("F0") + "%)";
  }
Beispiel #3
0
  GUIContent indicator_supplies(Vessel v, List<Scrubber> scrubbers, List<Greenhouse> greenhouses)
  {
    // get food & oxygen info
    double food_amount = Lib.GetResourceAmount(v, "Food");
    double food_capacity = Lib.GetResourceCapacity(v, "Food");
    double food_level = food_capacity > 0.0 ? food_amount / food_capacity : 1.0;
    double oxygen_amount = Lib.GetResourceAmount(v, "Oxygen");
    double oxygen_capacity = Lib.GetResourceCapacity(v, "Oxygen");
    double oxygen_level = oxygen_capacity > 0.0 ? oxygen_amount / oxygen_capacity : 1.0;
    double level = Math.Min(food_level, oxygen_level);

    // store the icon and tooltip
    GUIContent state = new GUIContent();

    // choose an icon
    if (level <= Settings.ResourceDangerThreshold) state.image = icon_supplies_danger;
    else if (level <= Settings.ResourceWarningThreshold) state.image = icon_supplies_warning;
    else state.image = icon_supplies_nominal;

    // if there is someone on board
    List<string> tooltips = new List<string>();
    int crew_count = Lib.CrewCount(v);
    if (crew_count > 0)
    {
      // get oxygen recycled by scrubbers
      double oxygen_recycled = 0.0;
      double ec_left = Lib.GetResourceAmount(v, "ElectricCharge");
      double co2_left = Lib.GetResourceAmount(v, "CO2");
      foreach(Scrubber scrubber in scrubbers)
      {
        if (scrubber.is_enabled)
        {
          double co2_consumed = Math.Max(co2_left, scrubber.co2_rate);
          ec_left -= scrubber.ec_rate;
          co2_left -= co2_consumed;
          if (ec_left > -double.Epsilon && co2_left > -double.Epsilon) oxygen_recycled += co2_consumed * scrubber.efficiency;
          else break;
        }
      }

      // calculate time until depletion for food
      double food_consumption = (double)crew_count * Settings.FoodPerMeal / Settings.MealFrequency;
      if (food_capacity > double.Epsilon && food_consumption > double.Epsilon)
      {
        double food_depletion = food_amount / food_consumption;
        tooltips.Add(food_amount / food_capacity > Settings.ResourceDangerThreshold
          ? "Food: <b>" + (food_level * 100.0).ToString("F0") + "%, </b>deplete in <b>" + Lib.HumanReadableDuration(food_depletion) + "</b>"
          : "Food: <b>depleted</b>");
      }

      // calculate time until depletion for oxygen
      double oxygen_consumption = !LifeSupport.BreathableAtmosphere(v) ? (double)crew_count * Settings.OxygenPerSecond - oxygen_recycled : 0.0;
      if (oxygen_capacity > double.Epsilon && oxygen_consumption > double.Epsilon)
      {
        double oxygen_depletion = oxygen_amount / oxygen_consumption;
        tooltips.Add(oxygen_amount / oxygen_capacity > Settings.ResourceDangerThreshold
          ? "Oxygen: <b>" + (oxygen_level * 100.0).ToString("F0") + "%, </b>deplete in <b>" + Lib.HumanReadableDuration(oxygen_depletion) + "</b>"
          : "Oxygen: <b>depleted</b>");
      }
    }
    state.tooltip = string.Join("\n", tooltips.ToArray());
    return state;
  }
Beispiel #4
0
        void toEVA(GameEvents.FromToAction <Part, Part> data)
        {
            // determine if inside breathable atmosphere
            bool breathable = LifeSupport.BreathableAtmosphere(data.from.vessel);

            // get total crew in the origin vessel
            double tot_crew = (double)data.from.vessel.GetVesselCrew().Count + 1.0;

            // add resource definitions to EVA vessel part
            Lib.SetupResource(data.to, "ElectricCharge", 0.0, Settings.ElectricChargeOnEVA);
            if (!breathable)
            {
                Lib.SetupResource(data.to, "Oxygen", 0.0, Settings.OxygenOnEVA);
            }


            // determine how much MonoPropellant to get
            // note: never more that the 'share' of this kerbal
            double monoprop = Math.Min(Lib.GetResourceAmount(data.from.vessel, "MonoPropellant") / tot_crew, Settings.MonoPropellantOnEVA);

            // determine how much ElectricCharge to get
            // note: never more that the 'share' of this kerbal
            // note: always keep half the ec in the vessel
            double ec = Math.Min(Lib.GetResourceAmount(data.from.vessel, "ElectricCharge") / (tot_crew * 2.0), Settings.ElectricChargeOnEVA);


            // EVA vessels start with 5 units of eva fuel, remove them
            data.to.RequestResource("EVA Propellant", 5.0);

            // transfer monoprop
            data.to.RequestResource("EVA Propellant", -data.from.RequestResource("MonoPropellant", monoprop));

            // transfer ec
            data.to.RequestResource("ElectricCharge", -data.from.RequestResource("ElectricCharge", ec));


            // if outside breathable atmosphere
            if (!breathable)
            {
                // determine how much Oxygen to get
                // note: never more that the 'share' of this kerbal
                double oxygen = Math.Min(Lib.GetResourceAmount(data.from.vessel, "Oxygen") / tot_crew, Settings.OxygenOnEVA);

                // transfer oxygen
                data.to.RequestResource("Oxygen", -data.from.RequestResource("Oxygen", oxygen));
            }


            // get KerbalEVA
            KerbalEVA kerbal = data.to.FindModuleImplementing <KerbalEVA>();

            // turn off headlamp light, to avoid stock bug that show the light for a split second when going on eva
            EVA.SetHeadlamp(kerbal, false);
            EVA.SetFlares(kerbal, false);

            // remove the helmet if inside breathable atmosphere
            // note: done in EVA::FixedUpdate(), but also done here avoid 'popping' of the helmet when going on eva
            EVA.SetHelmet(kerbal, !breathable);

            // remember if the kerbal has an helmet in the EVA module
            data.to.FindModuleImplementing <EVA>().has_helmet = !breathable;


            // show warning if there isn't monoprop in the eva suit
            if (monoprop <= double.Epsilon && !Lib.Landed(data.from.vessel))
            {
                Message.Post(Severity.danger, "There isn't any <b>MonoPropellant</b> in the EVA suit", "Don't let the ladder go!");
            }
        }