// 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);
  }
Exemple #3
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);
    }
  }
Exemple #4
0
  // 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);
    }
  }
Exemple #5
0
  // 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);
  }