// 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); }
// 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); } }
public override void OnSave(ConfigNode node) { // save current version node.AddValue("version", current_version); ConfigNode kerbals_node = node.AddNode("kerbals"); foreach(var p in kerbals) { kerbal_data kd = p.Value; ConfigNode kerbal_node = kerbals_node.AddNode(p.Key.Replace(" ", "___")); kerbal_node.AddValue("temperature", kd.temperature); kerbal_node.AddValue("starved", kd.starved); kerbal_node.AddValue("deprived", kd.deprived); kerbal_node.AddValue("stressed", kd.stressed); kerbal_node.AddValue("radiation", kd.radiation); kerbal_node.AddValue("time_since_food", kd.time_since_food); kerbal_node.AddValue("msg_freezing", kd.msg_freezing); kerbal_node.AddValue("msg_burning", kd.msg_burning); kerbal_node.AddValue("msg_starved", kd.msg_starved); kerbal_node.AddValue("msg_deprived", kd.msg_deprived); kerbal_node.AddValue("msg_stressed", kd.msg_stressed); kerbal_node.AddValue("msg_radiation", kd.msg_radiation); kerbal_node.AddValue("resque", kd.resque); kerbal_node.AddValue("disabled", kd.disabled); } ConfigNode vessels_node = node.AddNode("vessels"); foreach(var p in vessels) { vessel_data vd = p.Value; ConfigNode vessel_node = vessels_node.AddNode(p.Key.ToString()); vessel_node.AddValue("msg_ec", vd.msg_ec); vessel_node.AddValue("msg_food", vd.msg_food); vessel_node.AddValue("msg_oxygen", vd.msg_oxygen); vessel_node.AddValue("msg_signal", vd.msg_signal); vessel_node.AddValue("msg_belt", vd.msg_belt); vessel_node.AddValue("cfg_ec", vd.cfg_ec); vessel_node.AddValue("cfg_supply", vd.cfg_supply); vessel_node.AddValue("cfg_malfunction", vd.cfg_malfunction); vessel_node.AddValue("cfg_signal", vd.cfg_signal); vessel_node.AddValue("notes", vd.notes.Replace("\n", "$NEWLINE")); vessel_node.AddValue("group", vd.group); } ConfigNode bodies_node = node.AddNode("bodies"); foreach(var p in bodies) { body_data bd = p.Value; ConfigNode body_node = bodies_node.AddNode(p.Key.Replace(" ", "___")); body_node.AddValue("storm_time", bd.storm_time); body_node.AddValue("storm_age", bd.storm_age); body_node.AddValue("storm_state", bd.storm_state); body_node.AddValue("msg_storm", bd.msg_storm); } ConfigNode notifications_node = node.AddNode("notifications"); notifications_node.AddValue("next_death_report", notifications.next_death_report.ToString()); notifications_node.AddValue("next_tutorial", notifications.next_tutorial.ToString()); notifications_node.AddValue("death_counter", notifications.death_counter.ToString()); notifications_node.AddValue("last_death_counter", notifications.last_death_counter.ToString()); notifications_node.AddValue("first_belt_crossing", notifications.first_belt_crossing.ToString()); notifications_node.AddValue("first_signal_loss", notifications.first_signal_loss.ToString()); notifications_node.AddValue("first_malfunction", notifications.first_malfunction.ToString()); }
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; 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.temperature = Convert.ToDouble( kerbal_node.GetValue("temperature") ); kd.starved = Convert.ToDouble( kerbal_node.GetValue("starved") ); kd.deprived = Convert.ToDouble( kerbal_node.GetValue("deprived") ); kd.stressed = Convert.ToDouble( kerbal_node.GetValue("stressed") ); kd.radiation = Convert.ToDouble( kerbal_node.GetValue("radiation") ); kd.time_since_food = Convert.ToDouble( kerbal_node.GetValue("time_since_food") ); kd.msg_freezing = Convert.ToUInt32( kerbal_node.GetValue("msg_freezing") ); kd.msg_burning = Convert.ToUInt32( kerbal_node.GetValue("msg_burning") ); kd.msg_starved = Convert.ToUInt32( kerbal_node.GetValue("msg_starved") ); kd.msg_deprived = Convert.ToUInt32( kerbal_node.GetValue("msg_deprived") ); kd.msg_stressed = Convert.ToUInt32( kerbal_node.GetValue("msg_stressed") ); kd.msg_radiation = Convert.ToUInt32( kerbal_node.GetValue("msg_radiation") ); kd.resque = Convert.ToUInt32( kerbal_node.GetValue("resque") ); kd.disabled = Convert.ToUInt32( kerbal_node.GetValue("disabled") ); 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_ec = Convert.ToUInt32( vessel_node.GetValue("msg_ec") ); vd.msg_food = Convert.ToUInt32( vessel_node.GetValue("msg_food") ); vd.msg_oxygen = Convert.ToUInt32( vessel_node.GetValue("msg_oxygen") ); vd.msg_signal = Convert.ToUInt32( vessel_node.GetValue("msg_signal") ); vd.msg_belt = Convert.ToUInt32( vessel_node.GetValue("msg_belt") ); vd.cfg_ec = Convert.ToUInt32( vessel_node.GetValue("cfg_ec") ); vd.cfg_supply = Convert.ToUInt32( vessel_node.GetValue("cfg_supply") ); vd.cfg_malfunction = Convert.ToUInt32( vessel_node.GetValue("cfg_malfunction") ); vd.cfg_signal = Convert.ToUInt32( vessel_node.GetValue("cfg_signal") ); vd.notes = vessel_node.GetValue("notes").Replace("$NEWLINE", "\n"); vd.group = string.CompareOrdinal(version, "0.9.9.0") > 0 ? vessel_node.GetValue("group") : "NONE"; 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 = Convert.ToDouble( body_node.GetValue("storm_time") ); bd.storm_age = Convert.ToDouble( body_node.GetValue("storm_age") ); bd.storm_state = Convert.ToUInt32( body_node.GetValue("storm_state") ); bd.msg_storm = Convert.ToUInt32( body_node.GetValue("msg_storm") ); bodies.Add(body_node.name.Replace("___", " "), bd); } } notifications = new notification_data(); if (node.HasNode("notifications")) { ConfigNode notifications_node = node.GetNode("notifications"); notifications.next_death_report = Convert.ToUInt32( notifications_node.GetValue("next_death_report") ); notifications.next_tutorial = Convert.ToUInt32( notifications_node.GetValue("next_tutorial") ); notifications.death_counter = Convert.ToUInt32( notifications_node.GetValue("death_counter") ); notifications.last_death_counter = Convert.ToUInt32( notifications_node.GetValue("last_death_counter") ); notifications.first_belt_crossing = Convert.ToUInt32( notifications_node.GetValue("first_belt_crossing") ); notifications.first_signal_loss = Convert.ToUInt32( notifications_node.GetValue("first_signal_loss") ); notifications.first_malfunction = Convert.ToUInt32( notifications_node.GetValue("first_malfunction") ); } // if an old savegame was imported, log some debug info if (version != current_version) Lib.Log("savegame converted from version " + version); }
// 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; } } }
public override void OnLoad(ConfigNode node) { // reset caches to deal with minor issues on flight revert and scene changes Engine.ResetCache(); // 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 if (string.CompareOrdinal(version, "0.9.9.5") < 0) { Lib.Log("loading save from unsupported version " + version); kerbals.Clear(); vessels.Clear(); bodies.Clear(); landmarks = new landmarks_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); kd.entertainment = Lib.ConfigValue(kerbal_node, "entertainment", 1.0); kd.shielding = Lib.ConfigValue(kerbal_node, "shielding", 0.0); kd.space_name = Lib.ConfigValue(kerbal_node, "space_name", ""); kd.eva_dead = Lib.ConfigValue(kerbal_node, "eva_dead", false); kd.has_helmet = Lib.ConfigValue(kerbal_node, "has_helmet", false); if (kerbal_node.HasNode("kmon")) { 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); vd.cfg_highlights = Lib.ConfigValue(vessel_node, "cfg_highlights", 1u); vd.cfg_showlink = Lib.ConfigValue(vessel_node, "cfg_showlink", 0u); vd.storm_time = Lib.ConfigValue(vessel_node, "storm_time", 0.0); vd.storm_age = Lib.ConfigValue(vessel_node, "storm_age", 0.0); vd.storm_state = Lib.ConfigValue(vessel_node, "storm_state", 0u); vd.group = Lib.ConfigValue(vessel_node, "group", "NONE"); if (vessel_node.HasNode("vmon")) { 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); } } foreach(string s in vessel_node.GetValues("scansat_id")) { vd.scansat_id.Add(Lib.Parse.ToUInt(s)); } if (vessel_node.HasNode("computer")) { vd.computer = new Computer(vessel_node.GetNode("computer")); } // import old notes into new computer system else if (string.CompareOrdinal(version, "1.1.1.0") < 0) { vd.computer.files["doc/notes"].content = Lib.ConfigValue(vessel_node, "notes", "").Replace("$NEWLINE", "\n"); } 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); } } landmarks = new landmarks_data(); if (node.HasNode("landmarks")) { ConfigNode landmarks_node = node.GetNode("landmarks"); landmarks.belt_crossing = Lib.ConfigValue(landmarks_node, "belt_crossing", 0u); landmarks.manned_orbit = Lib.ConfigValue(landmarks_node, "manned_orbit", 0u); landmarks.space_harvest = Lib.ConfigValue(landmarks_node, "space_harvest", 0u); } // import old notifications data into new landmark system else if (string.CompareOrdinal(version, "1.1.2.0") < 0) { if (node.HasNode("notifications")) { ConfigNode n_node = node.GetNode("notifications"); landmarks.belt_crossing = Lib.ConfigValue(n_node, "first_belt_crossing", 0u); landmarks.manned_orbit = Lib.ConfigValue(n_node, "manned_orbit_contract", 0u); landmarks.space_harvest = Lib.ConfigValue(n_node, "first_space_harvest", 0u); } } // if an old savegame was imported, log some debug info if (version != current_version) Lib.Log("savegame converted from version " + version); }
public override void OnSave(ConfigNode node) { // save current version node.AddValue("version", current_version); ConfigNode kerbals_node = node.AddNode("kerbals"); foreach(var p in kerbals) { kerbal_data kd = p.Value; ConfigNode kerbal_node = kerbals_node.AddNode(p.Key.Replace(" ", "___")); kerbal_node.AddValue("resque", kd.resque); kerbal_node.AddValue("disabled", kd.disabled); kerbal_node.AddValue("living_space", kd.living_space); kerbal_node.AddValue("entertainment", kd.entertainment); kerbal_node.AddValue("shielding", kd.shielding); kerbal_node.AddValue("space_name", kd.space_name); kerbal_node.AddValue("eva_dead", kd.eva_dead); kerbal_node.AddValue("has_helmet", kd.has_helmet); var kmon_node = kerbal_node.AddNode("kmon"); foreach(var q in kd.kmon) { var kmon_subnode = kmon_node.AddNode(q.Key); kmon_subnode.AddValue("problem", q.Value.problem); kmon_subnode.AddValue("message", q.Value.message); kmon_subnode.AddValue("time_since", q.Value.time_since); } } ConfigNode vessels_node = node.AddNode("vessels"); foreach(var p in vessels) { vessel_data vd = p.Value; ConfigNode vessel_node = vessels_node.AddNode(p.Key.ToString()); vessel_node.AddValue("msg_signal", vd.msg_signal); vessel_node.AddValue("msg_belt", vd.msg_belt); vessel_node.AddValue("cfg_ec", vd.cfg_ec); vessel_node.AddValue("cfg_supply", vd.cfg_supply); vessel_node.AddValue("cfg_signal", vd.cfg_signal); vessel_node.AddValue("cfg_malfunction", vd.cfg_malfunction); vessel_node.AddValue("cfg_storm", vd.cfg_storm); vessel_node.AddValue("cfg_highlights", vd.cfg_highlights); vessel_node.AddValue("cfg_showlink", vd.cfg_showlink); vessel_node.AddValue("storm_time", vd.storm_time); vessel_node.AddValue("storm_age", vd.storm_age); vessel_node.AddValue("storm_state", vd.storm_state); vessel_node.AddValue("group", vd.group); var vmon_node = vessel_node.AddNode("vmon"); foreach(var q in vd.vmon) { var vmon_subnode = vmon_node.AddNode(q.Key); vmon_subnode.AddValue("message", q.Value.message); } foreach(uint id in vd.scansat_id) { vessel_node.AddValue("scansat_id", id.ToString()); } ConfigNode computer_node = vessel_node.AddNode("computer"); vd.computer.save(computer_node); } ConfigNode bodies_node = node.AddNode("bodies"); foreach(var p in bodies) { body_data bd = p.Value; ConfigNode body_node = bodies_node.AddNode(p.Key.Replace(" ", "___")); body_node.AddValue("storm_time", bd.storm_time); body_node.AddValue("storm_age", bd.storm_age); body_node.AddValue("storm_state", bd.storm_state); body_node.AddValue("msg_storm", bd.msg_storm); } ConfigNode landmarks_node = node.AddNode("landmarks"); landmarks_node.AddValue("belt_crossing", landmarks.belt_crossing); landmarks_node.AddValue("manned_orbit", landmarks.manned_orbit); landmarks_node.AddValue("space_harvest", landmarks.space_harvest); }
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; } }
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); }
public override void OnSave(ConfigNode node) { // save current version node.AddValue("version", current_version); ConfigNode kerbals_node = node.AddNode("kerbals"); foreach(var p in kerbals) { kerbal_data kd = p.Value; ConfigNode kerbal_node = kerbals_node.AddNode(p.Key.Replace(" ", "___")); kerbal_node.AddValue("resque", kd.resque); kerbal_node.AddValue("disabled", kd.disabled); kerbal_node.AddValue("living_space", kd.living_space); kerbal_node.AddValue("entertainment", kd.entertainment); kerbal_node.AddValue("shielding", kd.shielding); kerbal_node.AddValue("space_name", kd.space_name); var kmon_node = kerbal_node.AddNode("kmon"); foreach(var q in kd.kmon) { var kmon_subnode = kmon_node.AddNode(q.Key); kmon_subnode.AddValue("problem", q.Value.problem); kmon_subnode.AddValue("message", q.Value.message); kmon_subnode.AddValue("time_since", q.Value.time_since); } } ConfigNode vessels_node = node.AddNode("vessels"); foreach(var p in vessels) { vessel_data vd = p.Value; ConfigNode vessel_node = vessels_node.AddNode(p.Key.ToString()); vessel_node.AddValue("msg_signal", vd.msg_signal); vessel_node.AddValue("msg_belt", vd.msg_belt); vessel_node.AddValue("cfg_ec", vd.cfg_ec); vessel_node.AddValue("cfg_supply", vd.cfg_supply); vessel_node.AddValue("cfg_signal", vd.cfg_signal); vessel_node.AddValue("cfg_malfunction", vd.cfg_malfunction); vessel_node.AddValue("cfg_storm", vd.cfg_storm); vessel_node.AddValue("cfg_highlights", vd.cfg_highlights); vessel_node.AddValue("cfg_showlink", vd.cfg_showlink); vessel_node.AddValue("notes", vd.notes.Replace("\n", "$NEWLINE")); vessel_node.AddValue("group", vd.group); var vmon_node = vessel_node.AddNode("vmon"); foreach(var q in vd.vmon) { var vmon_subnode = vmon_node.AddNode(q.Key); vmon_subnode.AddValue("message", q.Value.message); } foreach(uint id in vd.scansat_id) { vessel_node.AddValue("scansat_id", id.ToString()); } } ConfigNode bodies_node = node.AddNode("bodies"); foreach(var p in bodies) { body_data bd = p.Value; ConfigNode body_node = bodies_node.AddNode(p.Key.Replace(" ", "___")); body_node.AddValue("storm_time", bd.storm_time); body_node.AddValue("storm_age", bd.storm_age); body_node.AddValue("storm_state", bd.storm_state); body_node.AddValue("msg_storm", bd.msg_storm); } ConfigNode notifications_node = node.AddNode("notifications"); notifications_node.AddValue("next_death_report", notifications.next_death_report.ToString()); notifications_node.AddValue("next_tutorial", notifications.next_tutorial.ToString()); notifications_node.AddValue("death_counter", notifications.death_counter.ToString()); notifications_node.AddValue("last_death_counter", notifications.last_death_counter.ToString()); notifications_node.AddValue("first_belt_crossing", notifications.first_belt_crossing.ToString()); notifications_node.AddValue("first_signal_loss", notifications.first_signal_loss.ToString()); notifications_node.AddValue("first_malfunction", notifications.first_malfunction.ToString()); }