예제 #1
0
        void fromEVA(GameEvents.FromToAction <Part, Part> data)
        {
            // use Hydrazine instead of MonoPropellant if RealFuel is installed
            string monoprop_name = detected_mods.RealFuels ? "Hydrazine" : "MonoPropellant";

            // get any leftover EVA Fuel from EVA vessel
            double monoprop = data.from.Resources.list[0].amount;

            // add the leftover monoprop back to the pod
            data.to.RequestResource(monoprop_name, -monoprop);

            // manage resources in rules
            foreach (Rule r in rules)
            {
                if (r.resource_name.Length == 0 || r.on_eva <= double.Epsilon)
                {
                    continue;
                }
                double leftover = ResourceCache.Info(data.from.vessel, r.resource_name).amount;
                data.to.RequestResource(r.resource_name, -leftover);
            }

            // merge EVA computer files into vessel
            Computer a = DB.VesselData(data.from.vessel.id).computer;
            Computer b = DB.VesselData(data.to.vessel.id).computer;

            b.merge(a);

            // forget vessel data
            DB.ForgetVessel(data.from.vessel.id);

            // purge vessel from resource cache
            ResourceCache.Purge(data.from.vessel.id);

            // execute script on vessel computer
            if (DB.Ready())
            {
                DB.VesselData(data.to.vessel.id).computer.execute("run", "auto/eva_in", string.Empty, data.to.vessel);
            }

            // mute messages for a couple seconds to avoid warning messages from the vessel resource amounts
            Message.MuteInternal();
            base.StartCoroutine(CallbackUtil.DelayedCallback(2.0f, Message.UnmuteInternal));

            // if vessel info is open, switch to the vessel
            if (Info.IsOpen())
            {
                Info.Open(data.to.vessel);
            }
        }
예제 #2
0
        void toEVA(GameEvents.FromToAction <Part, Part> data)
        {
            // use Hydrazine instead of MonoPropellant if RealFuel is installed
            string monoprop_name = detected_mods.RealFuels ? "Hydrazine" : "MonoPropellant";

            // determine if inside breathable atmosphere
            // note: the user can force the helmet + oxygen by pressing shift when going on eva
            bool breathable = Sim.Breathable(data.from.vessel) && !(Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift));

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

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

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

            // get monoprop from the vessel
            monoprop = data.from.RequestResource(monoprop_name, monoprop);

            // transfer monoprop to the EVA kerbal
            data.to.RequestResource("EVA Propellant", -monoprop);

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

            // manage resources from rules
            foreach (Rule r in rules)
            {
                if (r.resource_name.Length == 0 || r.on_eva <= double.Epsilon)
                {
                    continue;
                }

                // determine amount to take, never more that his own share
                double amount = Math.Min(ResourceCache.Info(data.from.vessel, r.resource_name).amount / tot_crew, r.on_eva);

                // deal with breathable modifier
                if (breathable && r.modifier.Contains("breathable"))
                {
                    continue;
                }

                // remove resource from the vessel
                amount = data.from.RequestResource(r.resource_name, amount);

                // create new resource in the eva kerbal
                Lib.SetupResource(data.to, r.resource_name, amount, r.on_eva);
            }

            // 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
            EVA.KerbalData(data.to.vessel).has_helmet = !breathable;

            // execute script on vessel computer
            if (DB.Ready())
            {
                DB.VesselData(data.from.vessel.id).computer.execute("run", "auto/eva_out", string.Empty, data.from.vessel);
            }

            // mute messages for a couple seconds to avoid warning messages from the vessel resource amounts
            Message.MuteInternal();
            base.StartCoroutine(CallbackUtil.DelayedCallback(2.0f, Message.UnmuteInternal));

            // if vessel info is open, switch to the eva kerbal
            // note: for a single tick, the EVA vessel is not valid (sun_dist is zero)
            // this make IsVessel() return false, that in turn close the vessel info instantly
            // for this reason, we wait a small amount of time before switching the info window
            if (Info.IsOpen())
            {
                Info.Open(data.to.vessel);
            }
        }
예제 #3
0
  public override void OnLoad(ConfigNode node)
  {
    // get version of the savegame
    // note: if there isn't a version this is either a new game, or the first public release (that didn't have versioning)
    string version = node.HasValue("version") ? node.GetValue("version") : node.HasNode("kerbals") ? "0.9.9.0" : current_version;

    // this is an unsupported version, attempt a total clean up and pray
    // note: currently unused
    if (string.CompareOrdinal(version, "0.9.9.0") < 0)
    {
      Lib.Log("loading save from unsupported version " + version);
      kerbals.Clear();
      vessels.Clear();
      bodies.Clear();
      notifications = new notification_data();
      return;
    }


    kerbals.Clear();
    if (node.HasNode("kerbals"))
    {
      ConfigNode kerbals_node = node.GetNode("kerbals");
      foreach(ConfigNode kerbal_node in kerbals_node.GetNodes())
      {
        kerbal_data kd = new kerbal_data();
        kd.resque          = Lib.ConfigValue(kerbal_node, "resque", 1u);
        kd.disabled        = Lib.ConfigValue(kerbal_node, "disabled", 0u);
        kd.living_space    = Lib.ConfigValue(kerbal_node, "living_space", 1.0); // since 0.9.9.4
        kd.entertainment   = Lib.ConfigValue(kerbal_node, "entertainment", 1.0); // since 0.9.9.4
        kd.shielding       = Lib.ConfigValue(kerbal_node, "shielding", 0.0); // since 0.9.9.4
        kd.space_name      = Lib.ConfigValue(kerbal_node, "space_name", ""); // since 0.9.9.4
        kd.kmon = new Dictionary<string, kmon_data>();
        if (kerbal_node.HasNode("kmon")) // since 0.9.9.5
        {
          foreach(var cfg in kerbal_node.GetNode("kmon").GetNodes())
          {
            kmon_data kmon = new kmon_data();
            kmon.problem = Lib.ConfigValue(cfg, "problem", 0.0);
            kmon.message = Lib.ConfigValue(cfg, "message", 0u);
            kmon.time_since = Lib.ConfigValue(cfg, "time_since", 0.0);
            kd.kmon.Add(cfg.name, kmon);
          }
        }
        kerbals.Add(kerbal_node.name.Replace("___", " "), kd);
      }
    }

    vessels.Clear();
    if (node.HasNode("vessels"))
    {
      ConfigNode vessels_node = node.GetNode("vessels");
      foreach(ConfigNode vessel_node in vessels_node.GetNodes())
      {
        vessel_data vd = new vessel_data();
        vd.msg_signal      = Lib.ConfigValue(vessel_node, "msg_signal", 0u);
        vd.msg_belt        = Lib.ConfigValue(vessel_node, "msg_belt", 0u);
        vd.cfg_ec          = Lib.ConfigValue(vessel_node, "cfg_ec", 1u);
        vd.cfg_supply      = Lib.ConfigValue(vessel_node, "cfg_supply", 1u);
        vd.cfg_signal      = Lib.ConfigValue(vessel_node, "cfg_signal", 1u);
        vd.cfg_malfunction = Lib.ConfigValue(vessel_node, "cfg_malfunction", 1u);
        vd.cfg_storm       = Lib.ConfigValue(vessel_node, "cfg_storm", 1u); // since 0.9.9.5
        vd.cfg_highlights  = Lib.ConfigValue(vessel_node, "cfg_highlights", 1u); // since 0.9.9.5
        vd.cfg_showlink    = Lib.ConfigValue(vessel_node, "cfg_showlink", 0u); // since 0.9.9.8
        vd.notes           = Lib.ConfigValue(vessel_node, "notes", "").Replace("$NEWLINE", "\n"); // since 0.9.9.1
        vd.group           = Lib.ConfigValue(vessel_node, "group", "NONE"); // since 0.9.9.1
        vd.vmon = new Dictionary<string, vmon_data>();
        if (vessel_node.HasNode("vmon")) // since 0.9.9.5
        {
          foreach(var cfg in vessel_node.GetNode("vmon").GetNodes())
          {
            vmon_data vmon = new vmon_data();
            vmon.message = Lib.ConfigValue(cfg, "message", 0u);
            vd.vmon.Add(cfg.name, vmon);
          }
        }
        vd.scansat_id = new List<uint>();
        foreach(string s in vessel_node.GetValues("scansat_id")) // since 0.9.9.5
        {
          vd.scansat_id.Add(Convert.ToUInt32(s));
        }
        vessels.Add(new Guid(vessel_node.name), vd);
      }
    }

    bodies.Clear();
    if (node.HasNode("bodies"))
    {
      ConfigNode bodies_node = node.GetNode("bodies");
      foreach(ConfigNode body_node in bodies_node.GetNodes())
      {
        body_data bd = new body_data();
        bd.storm_time  = Lib.ConfigValue(body_node, "storm_time", 0.0);
        bd.storm_age   = Lib.ConfigValue(body_node, "storm_age", 0.0);
        bd.storm_state = Lib.ConfigValue(body_node, "storm_state", 0u);
        bd.msg_storm   = Lib.ConfigValue(body_node, "msg_storm", 0u);
        bodies.Add(body_node.name.Replace("___", " "), bd);
      }
    }

    notifications = new notification_data();
    if (node.HasNode("notifications"))
    {
      ConfigNode n_node = node.GetNode("notifications");
      notifications.next_death_report   = Lib.ConfigValue(n_node, "next_death_report", 0u);
      notifications.next_tutorial       = Lib.ConfigValue(n_node, "next_tutorial", 0u);
      notifications.death_counter       = Lib.ConfigValue(n_node, "death_counter", 0u);
      notifications.last_death_counter  = Lib.ConfigValue(n_node, "last_death_counter", 0u);
      notifications.first_belt_crossing = Lib.ConfigValue(n_node, "first_belt_crossing", 0u);
      notifications.first_signal_loss   = Lib.ConfigValue(n_node, "first_signal_loss", 0u);
      notifications.first_malfunction   = Lib.ConfigValue(n_node, "first_malfunction", 0u);
    }


    // versions before 0.9.9.5 used a different structure to remember message sent
    // mute the message system for a few seconds to avoid the user being bombarded by messages
    if (string.CompareOrdinal(version, "0.9.9.5") < 0)
    {
      Message.MuteInternal();
      base.StartCoroutine(CallbackUtil.DelayedCallback(10.0f, Message.UnmuteInternal));
    }


    // versions before 0.9.9.5 didn't have profiles, and didn't use CRP food/oxygen values
    // scale all amounts of them in existing vessels, to not break savegames
    if (string.CompareOrdinal(version, "0.9.9.5") < 0)
    {
      foreach(Vessel v in FlightGlobals.Vessels.FindAll(k => !k.loaded))
      {
        foreach(var part in v.protoVessel.protoPartSnapshots)
        {
          var food = part.resources.Find(k => k.resourceName == "Food");
          if (food != null)
          {
            food.resourceValues.SetValue("amount", (Lib.ConfigValue(food.resourceValues, "amount", 0.0f) * 10.0f).ToString());
            food.resourceValues.SetValue("maxAmount", (Lib.ConfigValue(food.resourceValues, "maxAmount", 0.0f) * 10.0f).ToString());
          }

          var oxygen = part.resources.Find(k => k.resourceName == "Oxygen");
          if (oxygen != null)
          {
            oxygen.resourceValues.SetValue("amount", (Lib.ConfigValue(oxygen.resourceValues, "amount", 0.0f) * 1000.0f).ToString());
            oxygen.resourceValues.SetValue("maxAmount", (Lib.ConfigValue(oxygen.resourceValues, "maxAmount", 0.0f) * 1000.0f).ToString());
          }
        }
      }
    }


    // if an old savegame was imported, log some debug info
    if (version != current_version) Lib.Log("savegame converted from version " + version);
  }