Beispiel #1
0
        // 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;
            }
        }
Beispiel #2
0
 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;
 }
Beispiel #3
0
 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;
 }
Beispiel #4
0
 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;
 }
Beispiel #5
0
 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;
     }
   }
 }
Beispiel #6
0
  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;
  }
Beispiel #7
0
 protected override void OnUpdate()
 {
   if (DB.Ready() && DB.Landmarks().space_harvest == 1) base.SetComplete();
 }
Beispiel #8
0
 protected override void OnUpdate()
 {
   if (DB.Ready() && DB.Landmarks().belt_crossing == 1) base.SetComplete();
 }
Beispiel #9
0
  // 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);
  }
Beispiel #10
0
  // 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);
  }