Beispiel #1
0
 // return time left until CME is over
 public static double TimeLeftCME(CelestialBody body)
 {
   if (body.flightGlobalsIndex == 0) return 0.0;
   if (!DB.Ready()) return 0.0;
   body_data bd = DB.BodyData(Lib.PlanetarySystem(body).name);
   return Math.Max(0.0, bd.storm_time - bd.storm_age);
 }
Beispiel #2
0
  // return true if a storm just ended
  // used to avoid sending 'signal is back' messages en-masse after the storm is over
  // - delta_time: time between calls to this function
  public static bool JustEnded(Vessel v, double delta_time)
  {
    if (!DB.Ready()) return false;

    // if in interplanetary space
    if (v.mainBody.flightGlobalsIndex == 0)
    {
      return DB.VesselData(v.id).storm_age < delta_time * 2.0;
    }
    // if inside a planetary system
    else
    {
      return DB.BodyData(Lib.PlanetarySystem(v.mainBody).name).storm_age < delta_time * 2.0;
    }
  }
Beispiel #3
0
  // return true if a storm is in progress
  public static bool InProgress(Vessel v)
  {
    if (!DB.Ready()) return false;

    // if in interplanetary space
    if (v.mainBody.flightGlobalsIndex == 0)
    {
      return DB.VesselData(v.id).storm_state == 2;
    }
    // if inside a planetary system
    else
    {
      return DB.BodyData(Lib.PlanetarySystem(v.mainBody).name).storm_state == 2;
    }
  }
Beispiel #4
0
  // return time left until CME is over
  public static double TimeLeftCME(Vessel v)
  {
    if (!DB.Ready()) return 0.0;

    // if in interplanetary space
    if (v.mainBody.flightGlobalsIndex == 0)
    {
      vessel_data vd = DB.VesselData(v.id);
      return TimeLeftCME(vd.storm_time, vd.storm_age);
    }
    // if inside a planetary system
    else
    {
      body_data bd = DB.BodyData(Lib.PlanetarySystem(v.mainBody).name);
      return TimeLeftCME(bd.storm_time, bd.storm_age);
    }
  }
Beispiel #5
0
  // called every simulation tick
  public void FixedUpdate()
  {
    // do nothing if paused
    if (Lib.IsPaused()) return;

    // avoid case when DB isn't ready for whatever reason
    if (!DB.Ready()) return;

    // do nothing in the editors and the menus
    if (!Lib.SceneIsGame()) return;

    // for each celestial body
    foreach(CelestialBody body in FlightGlobals.Bodies)
    {
      // skip the sun
      if (body.flightGlobalsIndex == 0) continue;

      // skip moons
      if (body.referenceBody.flightGlobalsIndex != 0) continue;

      // get body data
      body_data bd = DB.BodyData(body.name);

      // generate storm time if necessary
      if (bd.storm_time <= double.Epsilon)
      {
        bd.storm_time = Settings.StormMinTime + (Settings.StormMaxTime - Settings.StormMinTime) * Lib.RandomDouble();
      }

      // accumulate age
      bd.storm_age += TimeWarp.fixedDeltaTime * storm_frequency(body);

      // if storm is over
      if (bd.storm_age > bd.storm_time)
      {
        bd.storm_age = 0.0;
        bd.storm_time = 0.0;
        bd.storm_state = 0;

      }
      // if storm is in progress
      else if (bd.storm_age > bd.storm_time - Settings.StormDuration)
      {
        bd.storm_state = 2;
      }
      // if storm is incoming
      else if (bd.storm_age > bd.storm_time - Settings.StormDuration  - time_to_impact(body))
      {
        bd.storm_state = 1;
      }

      // send messages
      // note: separed from state management to support the case when the user enter the SOI of a body under storm or about to be hit
      if (bd.msg_storm < 2 && bd.storm_state == 2)
      {
        if (body_is_relevant(body))
        {
          Message.Post(Severity.danger, "The coronal mass ejection hit <b>" + body.name + "</b> system",
            "Storm duration: " + Lib.HumanReadableDuration(TimeLeftCME(body)));
        }
        bd.msg_storm = 2;
      }
      else if (bd.msg_storm < 1 && bd.storm_state == 1)
      {
        if (body_is_relevant(body))
        {
          Message.Post(Severity.warning, "Our observatories report a coronal mass ejection directed toward <b>" + body.name + "</b> system",
            "Time to impact: " + Lib.HumanReadableDuration(TimeBeforeCME(body)));
        }
        bd.msg_storm = 1;
      }
      else if (bd.msg_storm > 1 && bd.storm_state == 0)
      {
        if (body_is_relevant(body))
        {
          Message.Post(Severity.relax, "The solar storm at <b>" + body.name + "</b> system is over");
        }
        bd.msg_storm = 0;
      }
    }
  }
Beispiel #6
0
 // return true if a storm just ended
 // used to avoid sending 'signal is back' messages en-masse after the storm is over
 // - delta_time: time between calls to this function
 public static bool JustEnded(CelestialBody body, double delta_time)
 {
   if (body.flightGlobalsIndex == 0) return false;
   return DB.Ready() && DB.BodyData(Lib.PlanetarySystem(body).name).storm_age < TimeWarp.deltaTime * 2.0;
 }
Beispiel #7
0
 // return true if a storm is in progress
 public static bool InProgress(CelestialBody body)
 {
   if (body.flightGlobalsIndex == 0) return false;
   return DB.Ready() && DB.BodyData(Lib.PlanetarySystem(body).name).storm_state == 2;
 }
Beispiel #8
0
  public void update(CelestialBody body, double elapsed_s)
  {
    // do nothing if storms are disabled
    if (Settings.StormDuration <= double.Epsilon) return;

    // skip the sun
    if (body.flightGlobalsIndex == 0) return;

    // skip moons
    // note: referenceBody is never null here
    if (body.referenceBody.flightGlobalsIndex != 0) return;

    // get body data
    body_data bd = DB.BodyData(body.name);

    // generate storm time if necessary
    if (bd.storm_time <= double.Epsilon)
    {
      bd.storm_time = Settings.StormMinTime + (Settings.StormMaxTime - Settings.StormMinTime) * Lib.RandomDouble();
    }

    // accumulate age
    bd.storm_age += elapsed_s * storm_frequency(body.orbit.semiMajorAxis);

    // if storm is over
    if (bd.storm_age > bd.storm_time)
    {
      bd.storm_age = 0.0;
      bd.storm_time = 0.0;
      bd.storm_state = 0;
    }
    // if storm is in progress
    else if (bd.storm_age > bd.storm_time - Settings.StormDuration)
    {
      bd.storm_state = 2;
    }
    // if storm is incoming
    else if (bd.storm_age > bd.storm_time - Settings.StormDuration  - time_to_impact(body.orbit.semiMajorAxis))
    {
      bd.storm_state = 1;
    }

    // send messages
    // note: separed from state management to support the case when the user enter the SOI of a body under storm or about to be hit
    if (bd.msg_storm < 2 && bd.storm_state == 2)
    {
      if (body_is_relevant(body))
      {
        Message.Post(Severity.danger, Lib.BuildString("The coronal mass ejection hit <b>", body.name, "</b> system"),
          Lib.BuildString("Storm duration: ", Lib.HumanReadableDuration(TimeLeftCME(bd.storm_time, bd.storm_age))));
      }
      bd.msg_storm = 2;
    }
    else if (bd.msg_storm < 1 && bd.storm_state == 1)
    {
      if (body_is_relevant(body))
      {
        Message.Post(Severity.warning, Lib.BuildString("Our observatories report a coronal mass ejection directed toward <b>", body.name, "</b> system"),
          Lib.BuildString("Time to impact: ", Lib.HumanReadableDuration(TimeBeforeCME(bd.storm_time, bd.storm_age))));
      }
      bd.msg_storm = 1;
    }
    else if (bd.msg_storm > 1 && bd.storm_state == 0)
    {
      if (body_is_relevant(body))
      {
        Message.Post(Severity.relax, Lib.BuildString("The solar storm at <b>", body.name, "</b> system is over"));
      }
      bd.msg_storm = 0;
    }
  }