Skip to content
This repository was archived by the owner on Oct 26, 2020. It is now read-only.

Commit 110c45d

Browse files
committed
SSS: Work with 1.1.2. Add ability to convert to craft file.
1 parent 5f4de29 commit 110c45d

File tree

2 files changed

+232
-4
lines changed

2 files changed

+232
-4
lines changed

ShipSaveSplicer/Properties/AssemblyInfo.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,5 +32,5 @@
3232
// You can specify all the values or you can default the Build and Revision Numbers
3333
// by using the '*' as shown below:
3434
// [assembly: AssemblyVersion("1.0.*")]
35-
[assembly: AssemblyVersion("1.0.1.0")]
36-
[assembly: AssemblyFileVersion("1.0.1.0")]
35+
[assembly: AssemblyVersion("1.1.0.0")]
36+
[assembly: AssemblyFileVersion("1.1.0.0")]

ShipSaveSplicer/ShipSaveSplicer.cs

Lines changed: 230 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,18 @@ namespace ShipSaveSplicer
1414
public class ShipSaveSplicer : MonoBehaviour
1515
{
1616
public static ApplicationLauncherButton theButton;
17-
public static bool includeCrew = false; //currently not working when true
17+
public static bool includeCrew = false;
18+
private static bool EventAdded = false;
1819
public void Start()
1920
{
2021
//add button to the Stock toolbar
21-
AddButton();
22+
if (!EventAdded)
23+
{
24+
GameEvents.onGUIApplicationLauncherReady.Add(AddButton);
25+
EventAdded = true;
26+
}
27+
28+
//AddButton();
2229
}
2330

2431
public void OnDestroy()
@@ -50,6 +57,13 @@ public void OnClick()
5057
else
5158
includeCrew = false;
5259

60+
if (Input.GetKey(KeyCode.LeftShift))
61+
{
62+
OpenConvertWindow(); //convert ships to craft files
63+
theButton.SetFalse();
64+
return;
65+
}
66+
5367
//get the selected craft
5468
Vessel selectedVessel = null;
5569

@@ -101,6 +115,135 @@ public void ExportSelectedCraft(Vessel vessel)
101115
ScreenMessages.PostScreenMessage(message);
102116
}
103117

118+
public void OpenConvertWindow()
119+
{
120+
//convert the selected vessel to a craft file and save it in the ships folder for the save
121+
string dir = KSPUtil.ApplicationRootPath + "/Ships/export/";
122+
//provide a list of all the craft we can import
123+
string[] files = System.IO.Directory.GetFiles(dir);
124+
int count = files.Length;
125+
126+
DialogGUIBase[] options = new DialogGUIBase[count + 1];
127+
for (int i = 0; i < count; i++)
128+
{
129+
int select = i;
130+
options[i] = new DialogGUIButton(files[i].Split('/').Last(), () => { ConvertVessel(files[select]); });
131+
}
132+
options[count] = new DialogGUIButton("Close", Dummy);
133+
string msg = "Select a vessel to convert to a .craft file.";
134+
135+
MultiOptionDialog a = new MultiOptionDialog(msg, "Convert Vessel to .craft", null, options);
136+
PopupDialog.SpawnPopupDialog(new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), a, false, HighLogic.UISkin);
137+
}
138+
139+
public void ConvertVessel(string name)
140+
{
141+
if (System.IO.File.Exists(name))
142+
{
143+
ConfigNode storedNode = ConfigNode.Load(name);
144+
145+
ConfigNode vesselNode = storedNode.GetNode("VESSEL");
146+
147+
List<string> invalidParts = InvalidParts(vesselNode);
148+
if (invalidParts.Count > 0) //contains invalid parts and can't be loaded
149+
{
150+
string msg = "The selected vessel cannot be converted because it contains the following invalid parts (perhaps you removed a mod?):\n";
151+
foreach (string invalid in invalidParts)
152+
msg += " " + invalid + "\n";
153+
PopupDialog.SpawnPopupDialog(new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), "Missing Parts", msg, "Ok", false, HighLogic.UISkin);
154+
return;
155+
}
156+
//clear out all crew on vessel
157+
foreach (ConfigNode partNode in vesselNode.GetNodes("PART"))
158+
{
159+
if (partNode.HasValue("crew"))
160+
{
161+
partNode.RemoveValues("crew");
162+
}
163+
}
164+
165+
VesselToCraftFile(vesselNode);
166+
167+
}
168+
}
169+
170+
public void VesselToCraftFile(ConfigNode VesselNode)
171+
{
172+
//This code is taken from InflightShipSave by Claw, using the CC-BY-NC-SA license.
173+
//This code thus is licensed under the same license, despite the GPLv3 license covering original KCT code
174+
//See https://github.com/ClawKSP/InflightShipSave
175+
176+
ProtoVessel VesselToSave = HighLogic.CurrentGame.AddVessel(VesselNode);
177+
if (VesselToSave.vesselRef == null)
178+
{
179+
Debug.LogError("Vessel reference is null!");
180+
return;
181+
}
182+
183+
try
184+
{
185+
string ShipName = VesselToSave.vesselName;
186+
// Debug.LogWarning("Saving: " + ShipName);
187+
188+
//Vessel FromFlight = FlightGlobals.Vessels.Find(v => v.id == VesselToSave.vesselID);
189+
try
190+
{
191+
VesselToSave.vesselRef.Load();
192+
}
193+
catch (Exception ex)
194+
{
195+
Debug.LogException(ex);
196+
Debug.Log("Attempting to continue.");
197+
}
198+
199+
ShipConstruct ConstructToSave = new ShipConstruct(ShipName, "", VesselToSave.vesselRef.Parts[0]);
200+
Quaternion OriginalRotation = VesselToSave.vesselRef.vesselTransform.rotation;
201+
Vector3 OriginalPosition = VesselToSave.vesselRef.vesselTransform.position;
202+
203+
VesselToSave.vesselRef.SetRotation(new Quaternion(0, 0, 0, 1));
204+
Vector3 ShipSize = ShipConstruction.CalculateCraftSize(ConstructToSave);
205+
VesselToSave.vesselRef.SetPosition(new Vector3(0, ShipSize.y + 2, 0));
206+
207+
208+
ConfigNode CN = new ConfigNode("ShipConstruct");
209+
CN = ConstructToSave.SaveShip();
210+
//SanitizeShipNode(CN);
211+
CleanEditorNodes(CN);
212+
213+
//VesselToSave.rotation = OriginalRotation;
214+
//VesselToSave.position = OriginalPosition;
215+
216+
if (ConstructToSave.shipFacility == EditorFacility.SPH)
217+
{
218+
CN.Save(UrlDir.ApplicationRootPath + "saves/" + HighLogic.SaveFolder
219+
+ "/Ships/SPH/" + ShipName + "_Rescued.craft");
220+
221+
ScreenMessage message = new ScreenMessage(ShipName + " converted to " + UrlDir.ApplicationRootPath + "saves/" + HighLogic.SaveFolder
222+
+ "/Ships/SPH/" + ShipName + "_Rescued.craft", 6, ScreenMessageStyle.UPPER_CENTER);
223+
ScreenMessages.PostScreenMessage(message);
224+
}
225+
else
226+
{
227+
CN.Save(UrlDir.ApplicationRootPath + "saves/" + HighLogic.SaveFolder
228+
+ "/Ships/VAB/" + ShipName + "_Rescued.craft");
229+
230+
ScreenMessage message = new ScreenMessage(ShipName + " converted to " + UrlDir.ApplicationRootPath + "saves/" + HighLogic.SaveFolder
231+
+ "/Ships/VAB/" + ShipName + "_Rescued.craft", 6, ScreenMessageStyle.UPPER_CENTER);
232+
ScreenMessages.PostScreenMessage(message);
233+
}
234+
}
235+
catch (Exception e)
236+
{
237+
Debug.LogException(e);
238+
}
239+
finally
240+
{
241+
HighLogic.CurrentGame.DestroyVessel(VesselToSave.vesselRef);
242+
VesselToSave.vesselRef.Die();
243+
}
244+
//End of Claw's code. Thanks Claw!
245+
}
246+
104247
public void OpenImportWindow()
105248
{
106249
string dir = KSPUtil.ApplicationRootPath + "/Ships/export/";
@@ -271,6 +414,91 @@ public string PartNameFromNode(ConfigNode part)
271414
name = part.GetValue("name");
272415
return name;
273416
}
417+
418+
/* The following is directly from Claw's InflightShipSave and credit goes to the original author */
419+
private void CleanEditorNodes(ConfigNode CN)
420+
{
421+
422+
CN.SetValue("EngineIgnited", "False");
423+
CN.SetValue("currentThrottle", "0");
424+
CN.SetValue("Staged", "False");
425+
CN.SetValue("sensorActive", "False");
426+
CN.SetValue("throttle", "0");
427+
CN.SetValue("generatorIsActive", "False");
428+
CN.SetValue("persistentState", "STOWED");
429+
430+
string ModuleName = CN.GetValue("name");
431+
432+
// Turn off or remove specific things
433+
if ("ModuleScienceExperiment" == ModuleName)
434+
{
435+
CN.RemoveNodes("ScienceData");
436+
}
437+
else if ("ModuleScienceExperiment" == ModuleName)
438+
{
439+
CN.SetValue("Inoperable", "False");
440+
CN.RemoveNodes("ScienceData");
441+
}
442+
else if ("Log" == ModuleName)
443+
{
444+
CN.ClearValues();
445+
}
446+
447+
448+
for (int IndexNodes = 0; IndexNodes < CN.nodes.Count; IndexNodes++)
449+
{
450+
CleanEditorNodes(CN.nodes[IndexNodes]);
451+
}
452+
}
453+
454+
private void PristineNodes(ConfigNode CN)
455+
{
456+
if (null == CN) { return; }
457+
458+
if ("PART" == CN.name)
459+
{
460+
string PartName = ((CN.GetValue("part")).Split('_'))[0];
461+
462+
Debug.LogWarning("PART: " + PartName);
463+
464+
Part NewPart = PartLoader.getPartInfoByName(PartName).partPrefab;
465+
ConfigNode NewPartCN = new ConfigNode();
466+
Debug.LogWarning("New Part: " + NewPart.name);
467+
468+
NewPart.InitializeModules();
469+
470+
CN.ClearNodes();
471+
472+
// EVENTS, ACTIONS, PARTDATA, MODULE, RESOURCE
473+
474+
475+
NewPart.Events.OnSave(CN.AddNode("EVENTS"));
476+
477+
NewPart.Actions.OnSave(CN.AddNode("ACTIONS"));
478+
479+
NewPart.OnSave(CN.AddNode("PARTDATA"));
480+
481+
for (int IndexModules = 0; IndexModules < NewPart.Modules.Count; IndexModules++)
482+
{
483+
NewPart.Modules[IndexModules].Save(CN.AddNode("MODULE"));
484+
}
485+
486+
for (int IndexResources = 0; IndexResources < NewPart.Resources.Count; IndexResources++)
487+
{
488+
NewPart.Resources[IndexResources].Save(CN.AddNode("RESOURCE"));
489+
}
490+
491+
//CN.AddNode(CompiledNodes);
492+
493+
return;
494+
}
495+
for (int IndexNodes = 0; IndexNodes < CN.nodes.Count; IndexNodes++)
496+
{
497+
PristineNodes(CN.nodes[IndexNodes]);
498+
}
499+
}
500+
501+
274502
}
275503
}
276504
/*

0 commit comments

Comments
 (0)