Esempio n. 1
0
  // trigger malfunction for unloaded module
  public static void Break(Vessel v, ProtoPartModuleSnapshot m)
  {
    // get data
    uint malfunctions = Lib.GetProtoValue<uint>(m, "malfunctions");
    double lifetime = Lib.GetProtoValue<double>(m, "lifetime");
    double age = Lib.GetProtoValue<double>(m, "age");
    string malfunction_msg = m.moduleValues.GetValue("malfunction_msg");

    // limit number of malfunctions per-component
    if (malfunctions >= 2u) return;

    // increase malfunction
    ++malfunctions;

    // reset age and lifetime
    age = 0.0;
    lifetime = 0.0;

    // show message
    if (DB.Ready() && DB.VesselData(v.id).cfg_malfunction == 1)
    {
      Message.Post(Severity.warning, PrepareMsg(malfunction_msg, v, malfunctions));
    }

    // record first malfunction
    if (DB.Ready()) DB.NotificationData().first_malfunction = 1;

    // save data
    Lib.SetProtoValue<uint>(m, "malfunctions", malfunctions);
    Lib.SetProtoValue<double>(m, "lifetime", lifetime);
    Lib.SetProtoValue<double>(m, "age", age);
  }
Esempio n. 2
0
        public void BuildLinks()
        {
            // clear links container
            links.Clear();

            // clear active relays container
            active_relays.Clear();

            // iterate over all vessels
            foreach (Vessel v in FlightGlobals.Vessels)
            {
                // skip invalid vessels
                if (!Lib.IsVessel(v))
                {
                    continue;
                }

                // generate and store link status
                link_data ld = ComputeLink(v, new HashSet <Guid>());
                links.Add(v.id, ld);

                // maintain and send messages
                // - do nothing if db isn't ready
                // - do not send messages for vessels without an antenna
                if (DB.Ready() && ld.status != link_status.no_antenna)
                {
                    vessel_data vd = DB.VesselData(v.id);
                    if (vd.msg_signal < 1 && !ld.linked)
                    {
                        vd.msg_signal = 1;
                        if (DB.Ready())
                        {
                            DB.NotificationData().first_signal_loss = 1; //< record first signal loss
                        }
                        if (vd.cfg_signal == 1 && !Blackout(v))          //< do not send message during storms
                        {
                            bool is_probe = (v.loaded ? v.GetCrewCount() == 0 : v.protoVessel.GetVesselCrew().Count == 0);
                            Message.Post(Severity.warning, "Signal lost with <b>" + v.vesselName + "</b>", is_probe ? "Remote control disabled" : "Data transmission disabled");
                        }
                    }
                    else if (vd.msg_signal > 0 && ld.linked)
                    {
                        vd.msg_signal = 0;
                        if (vd.cfg_signal == 1 && !Storm.JustEnded(v.mainBody, TimeWarp.deltaTime)) //< do not send messages after a storm
                        {
                            Message.Post(Severity.relax, "<b>" + v.vesselName + "</b> signal is back",
                                         ld.path.Count == 0 ? "We got a direct link with the space center" : "Relayed by <b>" + ld.path[ld.path.Count - 1] + "</b>");
                        }
                    }
                }
            }
        }
Esempio n. 3
0
  // called every frame
  public void OnGUI()
  {
    // avoid case when DB isn't ready for whatever reason
    if (!DB.Ready()) return;

    // check only when at the space center
    if (HighLogic.LoadedScene != GameScenes.SPACECENTER) return;

    // check once in a while
    float time = Time.realtimeSinceStartup;
    if (last_check + check_interval > time) return;
    last_check = time;

    // get notification data
    notification_data nd = DB.NotificationData();

    // if there are tutorials left to show
    if (nd.next_tutorial < tutorials.Length)
    {
      // check tutorial condition
      if (tutorial_condition(nd.next_tutorial))
      {
        // check if the relative feature is enabled
        if (tutorial_feature(nd.next_tutorial))
        {
          // show notification
          Entry e = tutorials[nd.next_tutorial];
          Notification(e.title, e.msg, "INFO");
        }

        // move to next tutorial
        ++nd.next_tutorial;
      }
    }

    // if there is one or more new deaths
    if (nd.death_counter > nd.last_death_counter)
    {
      // show notification
      Entry e = death_report[nd.next_death_report];
      Notification(e.title, e.msg, "ALERT");

      // move to next tutorial, cycle throwgh all of them repetatedly
      // note: done this way because modulo didn't work...
      ++nd.next_death_report;
      if (nd.next_death_report >= death_report.Length) nd.next_death_report -= (uint)death_report.Length;
    }

    // remember number of death kerbals
    nd.last_death_counter = nd.death_counter;
  }
Esempio n. 4
0
 // tutorial conditions
 private static bool tutorial_condition(uint i)
 {
   if (ProgressTracking.Instance == null) return false;
   switch(i)
   {
     case 0: return ProgressTracking.Instance.reachSpace.IsComplete;                               // 'food & oxygen'
     case 1: return ProgressTracking.Instance.celestialBodyHome.orbit.IsComplete;                  // 'electric charge'
     case 2: return DB.NotificationData().first_belt_crossing > 0;                                 // 'radiation'
     case 3:                                                                                       // 'quality of life'
       foreach(var b in ProgressTracking.Instance.celestialBodyNodes)
       {
         if (b != ProgressTracking.Instance.celestialBodyHome && b.flyBy.IsComplete) return true;
       }
       return false;
     case 4: return DB.NotificationData().first_signal_loss > 0;                                   // 'signals'
     case 5: return DB.NotificationData().first_malfunction > 0;                                   // 'malfunctions'
   }
   return false;
 }
Esempio n. 5
0
  // trigger malfunction
  public void Break()
  {
    // reset age and lifetime
    age = 0.0;
    lifetime = 0.0;

    // apply malfunction penalty immediately
    Apply(0.5);

    // increase malfunction
    ++malfunctions;

    // show message
    if (DB.Ready() && DB.VesselData(vessel.id).cfg_malfunction == 1)
    {
      Message.Post(Severity.warning, PrepareMsg(malfunction_msg, vessel, malfunctions));
    }

    // record first malfunction
    if (DB.Ready()) DB.NotificationData().first_malfunction = 1;
  }
Esempio n. 6
0
        // implement radiation mechanics
        public void FixedUpdate()
        {
            // 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;
            }

            // do nothing if paused
            if (Lib.IsPaused())
            {
                return;
            }

            // get time elapsed from last update
            double elapsed_s = TimeWarp.fixedDeltaTime;

            // for each vessel
            foreach (Vessel v in FlightGlobals.Vessels)
            {
                // skip invalid vessels
                if (!Lib.IsVessel(v))
                {
                    continue;
                }

                // skip dead eva kerbals
                if (EVA.IsDead(v))
                {
                    continue;
                }

                // get crew
                List <ProtoCrewMember> crew = v.loaded ? v.GetVesselCrew() : v.protoVessel.GetVesselCrew();

                // get crew count
                int crew_count = Lib.CrewCount(v);

                // get vessel info from the cache
                vessel_info info = Cache.VesselInfo(v);

                // get vessel data
                vessel_data vd = DB.VesselData(v.id);


                // belt warnings
                // note: we only show it for manned vesssels, but the first time we also show it for probes
                if (crew_count > 0 || DB.NotificationData().first_belt_crossing == 0)
                {
                    if (InsideBelt(v) && vd.msg_belt < 1)
                    {
                        Message.Post("<b>" + v.vesselName + "</b> is crossing <i>" + v.mainBody.bodyName + " radiation belt</i>", "Exposed to extreme radiation");
                        vd.msg_belt = 1;
                        DB.NotificationData().first_belt_crossing = 1; //< record first belt crossing
                    }
                    else if (!InsideBelt(v) && vd.msg_belt > 0)
                    {
                        // no message after crossing the belt
                        vd.msg_belt = 0;
                    }
                }


                // for each crew
                foreach (ProtoCrewMember c in crew)
                {
                    // get kerbal data
                    kerbal_data kd = DB.KerbalData(c.name);

                    // skip resque kerbals
                    if (kd.resque == 1)
                    {
                        continue;
                    }

                    // skip disabled kerbals
                    if (kd.disabled == 1)
                    {
                        continue;
                    }

                    // accumulate radiation
                    kd.radiation += info.radiation * elapsed_s;

                    // kill kerbal if necessary
                    if (kd.radiation >= Settings.RadiationFatalThreshold)
                    {
                        Message.Post(Severity.fatality, KerbalEvent.radiation, v, c);
                        Kerbalism.Kill(v, c);
                    }
                    // show warnings
                    else if (kd.radiation >= Settings.RadiationDangerThreshold && kd.msg_radiation < 2)
                    {
                        Message.Post(Severity.danger, KerbalEvent.radiation, v, c);
                        kd.msg_radiation = 2;
                    }
                    else if (kd.radiation >= Settings.RadiationWarningThreshold && kd.msg_radiation < 1)
                    {
                        Message.Post(Severity.danger, KerbalEvent.radiation, v, c);
                        kd.msg_radiation = 1;
                    }
                    // note: no recovery from radiations
                }
            }
        }
Esempio n. 7
0
 // called manually to register a death (used for eva death)
 public static void RegisterDeath()
 {
   ++DB.NotificationData().death_counter;
 }
Esempio n. 8
0
 // called by the engine when a kerbal die
 public void RegisterDeathEvent(EventReport e)
 {
   ++DB.NotificationData().death_counter;
 }