public static Part LoadPartSnapshot(Vessel vessel, ConfigNode node, Vector3 position, Quaternion rotation) { ConfigNode node_copy = new ConfigNode(); node.CopyTo(node_copy); node_copy.RemoveValues("kas_total_mass"); ProtoPartSnapshot snapshot = new ProtoPartSnapshot(node_copy, null, HighLogic.CurrentGame); if (HighLogic.CurrentGame.flightState.ContainsFlightID(snapshot.flightID)) snapshot.flightID = ShipConstruction.GetUniqueFlightID(HighLogic.CurrentGame.flightState); snapshot.parentIdx = 0; snapshot.position = position; snapshot.rotation = rotation; snapshot.stageIndex = 0; snapshot.defaultInverseStage = 0; snapshot.seqOverride = -1; snapshot.inStageIndex = -1; snapshot.attachMode = (int)AttachModes.SRF_ATTACH; snapshot.attached = true; snapshot.connected = true; snapshot.flagURL = vessel.rootPart.flagURL; // Save properties that may be messed up by new colliders RigidbodyInertia rb_backup = new RigidbodyInertia(vessel.rootPart.rb); Part new_part = snapshot.Load(vessel, false); vessel.Parts.Add(new_part); if (vessel.packed) { GameEvents.onVesselWasModified.Fire(vessel); } else { // Request initialization as nonphysical to prevent explosions new_part.physicalSignificance = Part.PhysicalSignificance.NONE; // Disable all sub-objects with colliders List<Collider> re_enable = new List<Collider>(); foreach (var collider in new_part.GetComponentsInChildren<Collider>()) { if (collider.gameObject.activeSelf) { re_enable.Add(collider); collider.gameObject.SetActive(false); } } new_part.StartCoroutine(WaitAndUnpack(new_part, re_enable)); } rb_backup.Restore(vessel.rootPart.rb); return new_part; }
public static ConfigNode PartSnapshot(Part part) { ConfigNode node = new ConfigNode("PART"); ProtoPartSnapshot snapshot = null; try { // Seems fine with a null vessel in 0.23 if some empty lists are allocated below snapshot = new ProtoPartSnapshot(part, null); } catch { // workaround for command module KIS_Shared.DebugWarning("Error during part snapshot, spawning part for snapshot (workaround for command module)"); Part p = (Part)UnityEngine.Object.Instantiate(part.partInfo.partPrefab); p.gameObject.SetActive(true); p.name = part.partInfo.name; p.InitializeModules(); snapshot = new ProtoPartSnapshot(p, null); UnityEngine.Object.Destroy(p.gameObject); } snapshot.attachNodes = new List<AttachNodeSnapshot>(); snapshot.srfAttachNode = new AttachNodeSnapshot("attach,-1"); snapshot.symLinks = new List<ProtoPartSnapshot>(); snapshot.symLinkIdxs = new List<int>(); snapshot.Save(node); // Prune unimportant data node.RemoveValues("parent"); node.RemoveValues("position"); node.RemoveValues("rotation"); node.RemoveValues("istg"); node.RemoveValues("dstg"); node.RemoveValues("sqor"); node.RemoveValues("sidx"); node.RemoveValues("attm"); node.RemoveValues("srfN"); node.RemoveValues("attN"); node.RemoveValues("connected"); node.RemoveValues("attached"); node.RemoveValues("flag"); node.RemoveNodes("ACTIONS"); // Remove modules that are not in prefab since they won't load anyway var module_nodes = node.GetNodes("MODULE"); var prefab_modules = part.partInfo.partPrefab.GetComponents<PartModule>(); node.RemoveNodes("MODULE"); for (int i = 0; i < prefab_modules.Length && i < module_nodes.Length; i++) { var module = module_nodes[i]; var name = module.GetValue("name") ?? ""; node.AddNode(module); if (name == "KASModuleContainer") { // Containers get to keep their contents module.RemoveNodes("EVENTS"); } else if (name.StartsWith("KASModule")) { // Prune the state of the KAS modules completely module.ClearData(); module.AddValue("name", name); continue; } module.RemoveNodes("ACTIONS"); } return node; }
public static ConfigNode SavePartSnapshot(Part part) { // Seems fine with a null vessel in 0.23 if some empty lists are allocated below ProtoPartSnapshot snapshot = new ProtoPartSnapshot(part, null); ConfigNode node = new ConfigNode("CONTENT_PART"); snapshot.attachNodes = new List<AttachNodeSnapshot>(); snapshot.srfAttachNode = new AttachNodeSnapshot("attach,-1"); snapshot.symLinks = new List<ProtoPartSnapshot>(); snapshot.symLinkIdxs = new List<int>(); snapshot.Save(node); node.AddValue("kas_total_mass", part.mass+part.GetResourceMass()); // Prune unimportant data node.RemoveValues("parent"); node.RemoveValues("position"); node.RemoveValues("rotation"); node.RemoveValues("istg"); node.RemoveValues("dstg"); node.RemoveValues("sqor"); node.RemoveValues("sidx"); node.RemoveValues("attm"); node.RemoveValues("srfN"); node.RemoveValues("attN"); node.RemoveValues("connected"); node.RemoveValues("attached"); node.RemoveValues("flag"); node.RemoveNodes("ACTIONS"); // Remove modules that are not in prefab since they won't load anyway var module_nodes = node.GetNodes("MODULE"); var prefab_modules = part.partInfo.partPrefab.GetComponents<PartModule>(); node.RemoveNodes("MODULE"); for (int i = 0; i < prefab_modules.Length && i < module_nodes.Length; i++) { var module = module_nodes[i]; var name = module.GetValue("name") ?? ""; node.AddNode(module); if (name == "KASModuleContainer") { // Containers get to keep their contents module.RemoveNodes("EVENTS"); } else if (name.StartsWith("KASModule")) { // Prune the state of the KAS modules completely module.ClearData(); module.AddValue("name", name); continue; } module.RemoveNodes("ACTIONS"); } return node; }
/// <summary> /// Merges global and local config nodes for an engine layout<para/> /// Local node values have priority if they are present; any non-specified local values are defaulted /// to the global value /// </summary> /// <param name="global"></param> /// <param name="local"></param> /// <returns></returns> private ConfigNode mergeNodes(ConfigNode global, ConfigNode local) { ConfigNode output = new ConfigNode("MOUNT"); global.CopyTo(output); if (local.HasValue("canAdjustSize")) { output.RemoveValues("canAdjustSize"); output.AddValue("canAdjustSize", local.GetBoolValue("canAdjustSize")); } if (local.HasValue("size")) { output.RemoveValues("size"); output.AddValue("size", local.GetFloatValue("size")); } if (local.HasValue("minSize")) { output.RemoveValues("minSize"); output.AddValue("minSize", local.GetFloatValue("minSize")); } if (local.HasValue("maxSize")) { output.RemoveValues("maxSize"); output.AddValue("maxSize", local.GetFloatValue("maxSize")); } if (local.HasValue("engineSpacing")) { output.RemoveValues("engineSpacing"); output.AddValue("engineSpacing", local.GetFloatValue("engineSpacing")); } if (local.HasValue("rotateEngines")) { output.RemoveValues("rotateEngines"); output.AddValue("rotateEngines", local.GetStringValue("rotateEngines")); } return output; }
// unnecesary save/load. config is static so it will be initialised as you pass through the space center, and there is no way to change options in the editor scene // may resolve errors reported by Hodo public override void OnSave(ConfigNode node) { node.RemoveValues("mirrorTexturing"); node.AddValue("mirrorTexturing", isMirrored); if (WPDebug.logEvents) DebugLogWithID("OnSave", "Invoked"); try { if(HighLogic.LoadedSceneIsFlight) vesselList.FirstOrDefault(vs => vs.vessel == vessel).isUpdated = false; WingProceduralManager.SaveConfigs(); } catch { Debug.Log("B9 PWings - Failed to save settings"); } }
public static ProtoPartSnapshot LoadProtoPartSnapshot(ConfigNode node) { ConfigNode node_copy = new ConfigNode(); node.CopyTo(node_copy); node_copy.RemoveValues("kas_total_mass"); node_copy.RemoveValues("kas_total_cost"); return new ProtoPartSnapshot(node_copy, null, HighLogic.CurrentGame); }
private static void InsertValue(ConfigNode newNode, int index, string name, string value) { string[] oldValues = newNode.GetValues(name); if (index < oldValues.Length) { newNode.RemoveValues(name); int i = 0; for (; i < index; ++i) newNode.AddValue(name, oldValues[i]); newNode.AddValue(name, value); for (; i < oldValues.Length; ++i) newNode.AddValue(name, oldValues[i]); return; } newNode.AddValue(name, value); }