private static void RepairClearDocking(KmlPartDock dock1, KmlPartDock dock2) { try { KmlNode module = dock1.GetChildNode("MODULE", "ModuleDockingNode"); module.GetAttrib("state").Value = "Ready"; //module.GetAttrib("dockUId").Value = ""; KmlNode events = module.GetChildNode("EVENTS"); events.GetChildNode("Undock").GetAttrib("active").Value = "False"; events.GetChildNode("UndockSameVessel").GetAttrib("active").Value = "False"; if (dock2 != null) { module = dock2.GetChildNode("MODULE", "ModuleDockingNode"); module.GetAttrib("state").Value = "Ready"; //module.GetAttrib("dockUId").Value = ""; events = module.GetChildNode("EVENTS"); events.GetChildNode("Undock").GetAttrib("active").Value = "False"; events.GetChildNode("UndockSameVessel").GetAttrib("active").Value = "False"; } System.Windows.MessageBox.Show("Successfully reset docking to ready. Please save and reload to see the rebuilt part structure."); // TODO KmlPartDock:RepairClearDocking(): Refresh structure without save / reload } catch (NullReferenceException) { System.Windows.MessageBox.Show("Couldn't reset docking node, there are sub-nodes missing.\n" + "You should copy a MODULE node from a functional state 'Ready' part.\n"); } }
/// <summary> /// This method is called by KmlPart.BuildAttachmentStructure() after a complete vessel is read and all parts exist, /// so we can build KmlPart references from the index or UId information got from reading this part anlone. /// </summary> /// <param name="dock">The part identified as KmlPartDock</param> /// <param name="other">The other docked KmlPart (could be KmlPartDock also)</param> public static void BuildDockStructure(KmlPartDock dock, KmlPart other) { if (dock.DockUid == other.Uid) { dock.DockedPart = other; } else { Syntax.Warning(dock, "Dock part is attached to (UId " + dock.DockUid + ") but supposed to be attached to: " + other.ToString() + " (UId " + other.Uid + ")"); dock.NeedsRepair = true; } if (dock.DockType == DockTypes.Dock && dock.DockState.ToLower() == "docked (docker)") { KmlNode module = dock.GetChildNode("MODULE", "ModuleDockingNode"); if (module == null) { Syntax.Warning(dock, "Dock sub-node MODULE with name = 'ModuleDockingNode' is missing. Please copy one from functional dock part or older save file"); dock.NeedsRepair = true; } else if (module.GetChildNode("DOCKEDVESSEL") == null) { Syntax.Warning(dock, "Dock sub-sub-node DOCKEDVESSEL is missing"); dock.NeedsRepair = true; } } else if (dock.DockType == DockTypes.Grapple && dock.DockState.ToLower() == "grappled") { KmlNode module = dock.GetChildNode("MODULE", "ModuleGrappleNode"); if (module == null) { Syntax.Warning(dock, "Grapple sub-node MODULE with name = 'ModuleGrappleNode' is missing. Please copy one from functional dock part or older save file"); dock.NeedsRepair = true; } else { if (module.GetChildNode("DOCKEDVESSEL") == null) { Syntax.Warning(dock, "Grapple sub-sub-node DOCKEDVESSEL is missing"); dock.NeedsRepair = true; } if (module.GetChildNode("DOCKEDVESSEL_other") == null) { Syntax.Warning(dock, "Grapple sub-sub-node DOCKEDVESSEL_other is missing"); dock.NeedsRepair = true; } } } else if (dock.DockType == DockTypes.KasCPort) { KmlNode module = dock.GetChildNode("MODULE", "KASModuleStrut"); if (module == null) { Syntax.Warning(dock, "KAS CPort sub-node MODULE with name = 'KASModuleStrut' is missing. Please copy one from functional CPort part or older save file"); dock.NeedsRepair = true; } } }
private static void RepairDockerDockee(KmlPartDock docker, KmlPartDock dockee) { if (docker.ParentPart == dockee || dockee.ParentPart == docker) { bool dockerOk = false; bool dockeeOk = false; try { KmlNode module = docker.GetChildNode("MODULE", "ModuleDockingNode"); module.GetAttrib("state").Value = "Docked (docker)"; module.GetAttrib("dockUId").Value = dockee.Uid; KmlNode events = module.GetChildNode("EVENTS"); events.GetChildNode("Undock").GetAttrib("active").Value = "True"; events.GetChildNode("UndockSameVessel").GetAttrib("active").Value = "False"; if (module.GetChildNode("DOCKEDVESSEL") == null) { System.Windows.MessageBox.Show("Couldn't find sub-node DOCKEDVESSEL, you should try to copy it from older save files."); } else { dockerOk = true; } } catch (NullReferenceException) { System.Windows.MessageBox.Show("Couldn't fix docker node, there are sub-nodes missing.\n" + "You should copy a MODULE node from a functional 'Docked (docker)' part.\n" + "Docker should be: " + docker); } try { KmlNode module = dockee.GetChildNode("MODULE", "ModuleDockingNode"); module.GetAttrib("state").Value = "Docked (dockee)"; module.GetAttrib("dockUId").Value = docker.Uid; KmlNode events = module.GetChildNode("EVENTS"); events.GetChildNode("Undock").GetAttrib("active").Value = "False"; events.GetChildNode("UndockSameVessel").GetAttrib("active").Value = "False"; dockeeOk = true; } catch (NullReferenceException) { System.Windows.MessageBox.Show("Couldn't fix dockee node, there are sub-nodes missing.\n" + "You should copy a MODULE node from a functional 'Docked (dockee)' part.\n" + "Dockee should be: " + dockee); } if (dockerOk && dockeeOk) { System.Windows.MessageBox.Show("Successfully repaired docker-dockee. Please save and reload to see the rebuilt part structure."); // TODO KmlPartDock:RepairDockerDockee(): Refresh structure without save / reload } } else { RepairSameVesselChoose(docker, dockee); } }
/// <summary> /// After a part is completely loaded the Intentify() method is called. /// Then can be determined, if this part represents a docking port part or not, /// checking all child nodes and their attributes. /// If it doesen't need to be replaced, null is returned. /// <see cref="KML.KmlItem.Identify()"/> /// </summary> /// <returns>A KmlPortDock if this KmlPart needs to be replaced by or null otherwise</returns> protected override KmlItem Identify() { if (KmlPartDock.PartIsDock(this)) { return(new KmlPartDock(this)); } else { return(base.Identify()); } }
private static void RepairSameVesselChoose(KmlPartDock dock1, KmlPartDock dock2) { if (dock1.DockState.ToLower() == "docked (same vessel)" || dock2.DockState.ToLower() == "docked (dockee)") { RepairSameVesselDockee(dock1, dock2); } else { RepairSameVesselDockee(dock2, dock1); } }
private static void RepairSameVesselDockee(KmlPartDock same, KmlPartDock dockee) { if (same.ParentPart == dockee || dockee.ParentPart == same) { RepairDependingWhosParent(same, dockee); } else { bool sameOk = false; bool dockeeOk = false; try { KmlNode module = same.GetChildNode("MODULE", "ModuleDockingNode"); module.GetAttrib("state").Value = "Docked (same vessel)"; module.GetAttrib("dockUId").Value = dockee.Uid; KmlNode events = module.GetChildNode("EVENTS"); events.GetChildNode("Undock").GetAttrib("active").Value = "False"; events.GetChildNode("UndockSameVessel").GetAttrib("active").Value = "True"; sameOk = true; } catch (NullReferenceException) { System.Windows.MessageBox.Show("Couldn't fix same vessel docking node, there are sub-nodes missing.\n" + "You should copy a MODULE node from a functional 'Docked (same vessel)' part.\n" + "Same vessel dock should be: " + same); } try { KmlNode module = dockee.GetChildNode("MODULE", "ModuleDockingNode"); module.GetAttrib("state").Value = "Docked (dockee)"; module.GetAttrib("dockUId").Value = same.Uid; KmlNode events = module.GetChildNode("EVENTS"); events.GetChildNode("Undock").GetAttrib("active").Value = "False"; events.GetChildNode("UndockSameVessel").GetAttrib("active").Value = "False"; dockeeOk = true; } catch (NullReferenceException) { System.Windows.MessageBox.Show("Couldn't fix dockee node, there are sub-nodes missing.\n" + "You should copy a MODULE node from a functional 'Docked (dockee)' part.\n" + "Dockee should be: " + dockee); } if (sameOk && dockeeOk) { System.Windows.MessageBox.Show("Successfully repaired same vessel docking. Please save and reload to see the rebuilt part structure."); // TODO KmlPartDock:RepairDockerDockee(): Refresh structure without save / reload } } }
private static void RepairDependingWhosParent(KmlPartDock dock1, KmlPartDock dock2) { if (dock1.ParentPart == dock2) { RepairDockerDockee(dock1, dock2); } else if (dock2.ParentPart == dock1) { RepairDockerDockee(dock2, dock1); } else { RepairSameVesselChoose(dock1, dock2); } }
private void DockRepair_Click(object sender, RoutedEventArgs e) { KmlPartDock dock = (sender as MenuItem).DataContext as KmlPartDock; dock.Repair(); DlgMessage.ShowAndClear(Syntax.Messages); // Refresh view IGuiManager manager = GuiTabsManager.GetCurrent().VesselsManager; if (dock.Parent is KmlVessel && dock.Parent == manager.GetSelectedItem()) { manager.Select(dock.Parent); } }
private static void RepairDockerChoose(KmlPartDock dock1, KmlPartDock dock2) { if (dock1.DockState.ToLower() == "docked (docker)" && dock2.DockState.ToLower() == "docked (docker)" || dock1.DockState.ToLower() == "docked (dockee)" && dock2.DockState.ToLower() == "docked (dockee)") { RepairDependingWhosParent(dock1, dock2); } else if (dock1.DockState.ToLower() == "docked (docker)" || dock2.DockState.ToLower() == "docked (dockee)") { RepairDockerDockee(dock1, dock2); } else { RepairDockerDockee(dock2, dock1); } }
private static void RepairClearDocking(KmlPartDock dock1, KmlPartDock dock2) { try { KmlNode module = dock1.GetChildNode("MODULE", "ModuleDockingNode"); module.GetAttrib("state").Value = "Ready"; //module.GetAttrib("dockUId").Value = ""; KmlNode events = module.GetChildNode("EVENTS"); events.GetChildNode("Undock").GetAttrib("active").Value = "False"; events.GetChildNode("UndockSameVessel").GetAttrib("active").Value = "False"; Syntax.Info(dock1, "Successfully reset docking to ready"); } catch (NullReferenceException) { Syntax.Warning(dock1, "Couldn't reset docking node, there are sub-nodes missing.\n" + "You should copy a MODULE node from a functional state 'Ready' part.\n"); } if (dock2 != null) { try { KmlNode module = dock2.GetChildNode("MODULE", "ModuleDockingNode"); module.GetAttrib("state").Value = "Ready"; //module.GetAttrib("dockUId").Value = ""; KmlNode events = module.GetChildNode("EVENTS"); events.GetChildNode("Undock").GetAttrib("active").Value = "False"; events.GetChildNode("UndockSameVessel").GetAttrib("active").Value = "False"; Syntax.Info(dock2, "Successfully reset docking to ready"); } catch (NullReferenceException) { Syntax.Warning(dock2, "Couldn't reset docking node, there are sub-nodes missing.\n" + "You should copy a MODULE node from a functional state 'Ready' part\n"); } } if (dock1.Parent is KmlVessel) { BuildAttachmentStructure((dock1.Parent as KmlVessel).Parts); } }
private static void RepairDockerDockee(KmlPartDock docker, KmlPartDock dockee) { if (docker.ParentPart == dockee || dockee.ParentPart == docker) { bool dockerOk = false; bool dockeeOk = false; try { KmlNode module = docker.GetOrCreateChildNode("MODULE", "ModuleDockingNode"); module.GetOrCreateAttrib("isEnabled", "True"); module.GetOrCreateAttrib("crossfeed", "True"); module.GetOrCreateAttrib("stagingEnabled").Value = "False"; module.GetOrCreateAttrib("state").Value = "Docked (docker)"; module.GetOrCreateAttrib("dockUId").Value = dockee.Uid; KmlNode events = module.GetOrCreateChildNode("EVENTS"); events.GetOrCreateChildNode("Undock").GetOrCreateAttrib("active").Value = "True"; events.GetOrCreateChildNode("UndockSameVessel").GetOrCreateAttrib("active").Value = "False"; events.GetOrCreateChildNode("Decouple").GetOrCreateAttrib("active").Value = "False"; module.GetOrCreateChildNode("ACTIONS"); KmlNode dockedVessel = module.GetOrCreateChildNode("DOCKEDVESSEL"); string defaultName; if (docker.Parent is KmlVessel) { defaultName = (docker.Parent as KmlVessel).Name + " Docker - repaired by KML"; } else { defaultName = "Unknown Docker - repaired by KML"; } if (dockedVessel.GetAttrib("vesselName") == null) { KmlAttrib attrib = dockedVessel.GetOrCreateAttrib("vesselName", defaultName); attrib.AttribValueChanged += docker.DockedVesselName_Changed; docker.DockedVesselName_Changed(attrib, new System.Windows.RoutedEventArgs()); } if (dockedVessel.GetAttrib("vesselType") == null) { KmlAttrib attrib = dockedVessel.GetOrCreateAttrib("vesselType", "6"); attrib.AttribValueChanged += docker.DockedVesselType_Changed; docker.DockedVesselType_Changed(attrib, new System.Windows.RoutedEventArgs()); } dockedVessel.GetOrCreateAttrib("rootUId", docker.Uid); dockerOk = true; } catch (NullReferenceException) { Syntax.Warning(docker, "Couldn't fix docker node, there are sub-nodes missing.\n" + "You should copy a MODULE node from a functional 'Docked (docker)' part.\n" + "Docker should be: " + docker); } try { KmlNode module = dockee.GetOrCreateChildNode("MODULE", "ModuleDockingNode"); module.GetOrCreateAttrib("isEnabled", "True"); module.GetOrCreateAttrib("crossfeed", "True"); module.GetOrCreateAttrib("stagingEnabled").Value = "False"; module.GetOrCreateAttrib("state").Value = "Docked (dockee)"; module.GetOrCreateAttrib("dockUId").Value = docker.Uid; KmlNode events = module.GetOrCreateChildNode("EVENTS"); events.GetOrCreateChildNode("Undock").GetOrCreateAttrib("active").Value = "False"; events.GetOrCreateChildNode("UndockSameVessel").GetOrCreateAttrib("active").Value = "False"; events.GetOrCreateChildNode("Decouple").GetOrCreateAttrib("active").Value = "False"; module.GetOrCreateChildNode("ACTIONS"); KmlNode dockedVessel = module.GetOrCreateChildNode("DOCKEDVESSEL"); string defaultName; string defaultUId; if (dockee.Parent is KmlVessel) { defaultName = (dockee.Parent as KmlVessel).Name; defaultUId = (dockee.Parent as KmlVessel).RootPart.Uid; } else { defaultName = "Unknown Dockee - repaired by KML"; defaultUId = dockee.Uid; } if (dockedVessel.GetAttrib("vesselName") == null) { KmlAttrib attrib = dockedVessel.GetOrCreateAttrib("vesselName", defaultName); attrib.AttribValueChanged += dockee.DockedVesselName_Changed; docker.DockedVesselName_Changed(attrib, new System.Windows.RoutedEventArgs()); } if (dockedVessel.GetAttrib("vesselType") == null) { KmlAttrib attrib = dockedVessel.GetOrCreateAttrib("vesselType", "6"); attrib.AttribValueChanged += dockee.DockedVesselType_Changed; docker.DockedVesselType_Changed(attrib, new System.Windows.RoutedEventArgs()); } dockedVessel.GetOrCreateAttrib("rootUId", defaultUId); dockeeOk = true; } catch (NullReferenceException) { Syntax.Warning(dockee, "Couldn't fix dockee node, there are sub-nodes missing.\n" + "You should copy a MODULE node from a functional 'Docked (dockee)' part.\n" + "Dockee should be: " + dockee); } if (dockerOk && dockeeOk) { Syntax.Info(docker, "Successfully repaired docker-dockee"); if (docker.Parent is KmlVessel) { BuildAttachmentStructure((docker.Parent as KmlVessel).Parts); } } } else { RepairSameVesselChoose(docker, dockee); } }
private static void RepairGrappling(KmlPartDock grapple, KmlPart part) { int grappleIndex = -1; int partIndex = -1; if (grapple.Parent == null || !(grapple.Parent is KmlVessel)) { System.Windows.MessageBox.Show("Could not search for connected parts, parent vessel is not valid"); } else { bool dockedVesselOk = true; KmlVessel vessel = (KmlVessel)grapple.Parent; grappleIndex = vessel.Parts.IndexOf(grapple); partIndex = vessel.Parts.IndexOf(part); try { KmlNode module = grapple.GetChildNode("MODULE", "ModuleGrappleNode"); module.GetAttrib("state").Value = "Grappled"; module.GetAttrib("dockUId").Value = part.Uid; KmlNode events = module.GetChildNode("EVENTS"); events.GetChildNode("Release").GetAttrib("active").Value = "True"; events.GetChildNode("ReleaseSameVessel").GetAttrib("active").Value = "False"; if (module.GetChildNode("DOCKEDVESSEL") == null) { System.Windows.MessageBox.Show("Couldn't find sub-node DOCKEDVESSEL, you should try to copy it from older save file."); dockedVesselOk = false; } if (module.GetChildNode("DOCKEDVESSEL_other") == null) { System.Windows.MessageBox.Show("Couldn't find sub-node DOCKEDVESSEL_other, you should try to copy it from older save file."); dockedVesselOk = false; } module = grapple.GetChildNode("MODULE", "ModuleAnimateGeneric"); module.GetAttrib("animSwitch").Value = "False"; module.GetAttrib("animTime").Value = "1"; events = module.GetChildNode("EVENTS"); KmlNode toggle = events.GetChildNode("Toggle"); toggle.GetAttrib("active").Value = "False"; toggle.GetAttrib("guiName").Value = "Disarm"; if (part.ParentPart == grapple) { RepairGrappleAttachment(part, grappleIndex); } else if (grapple.ParentPart == part) { RepairGrappleAttachment(grapple, partIndex); } else { // TODO KmlPartDock:RepairGrappling(): Is there a 'Grappled (same vessel)'? } if (dockedVesselOk) { // Maybe RepairGrappleAttachment() will cause a message to save and reload System.Windows.MessageBox.Show("Successfully repaired grappling. Please save and reload to see the rebuilt part structure."); // TODO KmlPartDock:RepairGrappling(): Refresh structure without save / reload } } catch (NullReferenceException) { System.Windows.MessageBox.Show("Couldn't fix grappling node, there are sub-nodes missing.\n" + "You should copy a MODULE node from a functional state 'Grappled' part.\n" + "grappled part should be: " + part); } } }
private static void RepairGrappling(KmlPartDock grapple, KmlPart part) { int grappleIndex = -1; int partIndex = -1; if (grapple.Parent is KmlVessel) { bool dockedVesselOk = true; KmlVessel vessel = (KmlVessel)grapple.Parent; grappleIndex = vessel.Parts.IndexOf(grapple); partIndex = vessel.Parts.IndexOf(part); try { KmlNode module = grapple.GetOrCreateChildNode("MODULE", "ModuleGrappleNode"); module.GetOrCreateAttrib("isEnabled", "True"); //module.GetOrCreateAttrib("stagingEnabled").Value = "False"; // True?!? module.GetOrCreateAttrib("state").Value = "Grappled"; module.GetOrCreateAttrib("dockUId").Value = part.Uid; KmlNode events = module.GetOrCreateChildNode("EVENTS"); events.GetOrCreateChildNode("Release").GetOrCreateAttrib("active").Value = "True"; events.GetOrCreateChildNode("ReleaseSameVessel").GetOrCreateAttrib("active").Value = "False"; events.GetOrCreateChildNode("Decouple").GetOrCreateAttrib("active").Value = "False"; module.GetOrCreateChildNode("ACTIONS"); KmlNode dockedVessel = module.GetOrCreateChildNode("DOCKEDVESSEL"); KmlNode dockedVesselOther = module.GetOrCreateChildNode("DOCKEDVESSEL_Other"); string vesselName; string vesselRootUId; string defaultName; if (grapple.Parent is KmlVessel) { vesselName = (grapple.Parent as KmlVessel).Name; vesselRootUId = (grapple.Parent as KmlVessel).RootPart.Uid; defaultName = vesselName + " Grappled - repaired by KML"; } else { vesselName = "Unknown Vessel - repaired by KML"; if (part.ParentPart == grapple) { vesselRootUId = grapple.Uid; } else { vesselRootUId = part.Uid; } defaultName = "Unknown Grappled - repaired by KML"; } string thisName; string otherName; string thisUid; string otherUid; if (part.ParentPart == grapple) { thisName = vesselName; thisUid = vesselRootUId; otherName = defaultName; otherUid = part.Uid; } else { thisName = defaultName; thisUid = grapple.Uid; otherName = vesselName; otherUid = vesselRootUId; } if (dockedVessel.GetAttrib("vesselName") == null) { KmlAttrib attrib = dockedVessel.GetOrCreateAttrib("vesselName", thisName); attrib.AttribValueChanged += grapple.DockedVesselName_Changed; grapple.DockedVesselName_Changed(attrib, new System.Windows.RoutedEventArgs()); } if (dockedVessel.GetAttrib("vesselType") == null) { KmlAttrib attrib = dockedVessel.GetOrCreateAttrib("vesselType", "6"); attrib.AttribValueChanged += grapple.DockedVesselType_Changed; grapple.DockedVesselType_Changed(attrib, new System.Windows.RoutedEventArgs()); } dockedVessel.GetOrCreateAttrib("rootUId", thisUid); if (dockedVesselOther.GetAttrib("vesselName") == null) { KmlAttrib attrib = dockedVesselOther.GetOrCreateAttrib("vesselName", otherName); attrib.AttribValueChanged += grapple.DockedVesselOtherName_Changed; grapple.DockedVesselOtherName_Changed(attrib, new System.Windows.RoutedEventArgs()); } if (dockedVesselOther.GetAttrib("vesselType") == null) { KmlAttrib attrib = dockedVesselOther.GetOrCreateAttrib("vesselType", "6"); attrib.AttribValueChanged += grapple.DockedVesselOtherType_Changed; grapple.DockedVesselOtherType_Changed(attrib, new System.Windows.RoutedEventArgs()); } dockedVesselOther.GetOrCreateAttrib("rootUId", otherUid); module = grapple.GetOrCreateChildNode("MODULE", "ModuleAnimateGeneric"); module.GetOrCreateAttrib("animSwitch").Value = "False"; module.GetOrCreateAttrib("animTime").Value = "1"; events = module.GetOrCreateChildNode("EVENTS"); KmlNode toggle = events.GetOrCreateChildNode("Toggle"); toggle.GetOrCreateAttrib("active").Value = "False"; toggle.GetOrCreateAttrib("guiName").Value = "Disarm"; if (part.ParentPart == grapple) { RepairGrappleAttachment(part, grappleIndex); } else if (grapple.ParentPart == part) { RepairGrappleAttachment(grapple, partIndex); } else { // TODO KmlPartDock:RepairGrappling(): Is there a 'Grappled (same vessel)'? } if (dockedVesselOk) { Syntax.Info(grapple, "Successfully repaired grappling"); BuildAttachmentStructure(vessel.Parts); } } catch (NullReferenceException) { Syntax.Warning(grapple, "Couldn't fix grappling node, there are sub-nodes missing.\n" + "You should copy a MODULE node from a functional state 'Grappled' part\n" + "grappled part should be: " + part); } } else { Syntax.Warning(grapple, "Could not search for connected parts, parent vessel is not valid"); } }
private static void RepairClearDocking(KmlPartDock dock) { RepairClearDocking(dock, null); }
private static void RepairSameVesselDockee(KmlPartDock same, KmlPartDock dockee) { if (same.ParentPart == dockee || dockee.ParentPart == same) { RepairDependingWhosParent(same, dockee); } else { bool sameOk = false; bool dockeeOk = false; try { KmlNode module = same.GetOrCreateChildNode("MODULE", "ModuleDockingNode"); module.GetOrCreateAttrib("isEnabled", "True"); module.GetOrCreateAttrib("crossfeed", "True"); module.GetOrCreateAttrib("stagingEnabled").Value = "False"; module.GetOrCreateAttrib("state").Value = "Docked (same vessel)"; module.GetOrCreateAttrib("dockUId").Value = dockee.Uid; KmlNode events = module.GetOrCreateChildNode("EVENTS"); events.GetOrCreateChildNode("Undock").GetOrCreateAttrib("active").Value = "False"; events.GetOrCreateChildNode("UndockSameVessel").GetOrCreateAttrib("active").Value = "True"; events.GetOrCreateChildNode("Decouple").GetOrCreateAttrib("active").Value = "False"; module.GetOrCreateChildNode("ACTIONS"); // TODO KmlPartDock.RepairSameVesselDockee(): Delete same DOCKEDVESSEL node? // It's not present in correct savefile with same vessel docking // KmlNode dockedVessel = module.GetChildNode("DOCKEDVESSEL"); sameOk = true; } catch (NullReferenceException) { Syntax.Warning(same, "Couldn't fix same vessel docking node, there are sub-nodes missing.\n" + "You should copy a MODULE node from a functional 'Docked (same vessel)' part.\n" + "Same vessel dock should be: " + same); } try { KmlNode module = dockee.GetOrCreateChildNode("MODULE", "ModuleDockingNode"); module.GetOrCreateAttrib("isEnabled", "True"); module.GetOrCreateAttrib("crossfeed", "True"); module.GetOrCreateAttrib("stagingEnabled").Value = "False"; module.GetOrCreateAttrib("state").Value = "Docked (dockee)"; module.GetOrCreateAttrib("dockUId").Value = same.Uid; KmlNode events = module.GetOrCreateChildNode("EVENTS"); events.GetOrCreateChildNode("Undock").GetOrCreateAttrib("active").Value = "False"; events.GetOrCreateChildNode("UndockSameVessel").GetOrCreateAttrib("active").Value = "False"; events.GetOrCreateChildNode("Decouple").GetOrCreateAttrib("active").Value = "False"; module.GetOrCreateChildNode("ACTIONS"); // TODO KmlPartDock.RepairSameVesselDockee(): Delete dockee DOCKEDVESSEL node? // It's not present in correct savefile with same vessel docking // KmlNode dockedVessel = module.GetChildNode("DOCKEDVESSEL"); dockeeOk = true; } catch (NullReferenceException) { Syntax.Warning(dockee, "Couldn't fix dockee node, there are sub-nodes missing.\n" + "You should copy a MODULE node from a functional 'Docked (dockee)' part.\n" + "Dockee should be: " + dockee); } if (sameOk && dockeeOk) { Syntax.Info(same, "Successfully repaired same vessel docking"); if (same.Parent is KmlVessel) { BuildAttachmentStructure((same.Parent as KmlVessel).Parts); } } } }
/// <summary> /// Parts of a vessel are first read one after the other, so the first part can only store indices of later parts it is connected to. /// After a complete vessel is read also all parts are read and the indices can be translated in references to now existing KmlParts. /// This is done by this method. Also reverse information (what parts are connected to this one) is then stored in a part. /// </summary> /// <param name="parts">The list of KmlParts, a KmlVessel will have one</param> /// <returns>A list of root parts (not pointing to another parent part). Could be more than one, if some connections are broken.</returns> public static List <KmlPart> BuildAttachmentStructure(List <KmlPart> parts) { List <KmlPart> roots = new List <KmlPart>(); for (int i = 0; i < parts.Count; i++) { // Check parent connection KmlPart part = parts[i]; if (part.ParentPartIndex == i) { // Parent part is itself, so ParentPart property stays null roots.Add(part); } else if (part.ParentPartIndex < 0 || part.ParentPartIndex >= parts.Count) { Syntax.Warning(part, "Part's parent part index [" + part.ParentPartIndex + "] does not point to a valid part."); roots.Add(part); } else { part.ParentPart = parts[part.ParentPartIndex]; if (!part.AttachedToNodeIndices.Contains(part.ParentPartIndex) && part.AttachedToSurfaceIndex != part.ParentPartIndex) { // Part could be docked to parent if ((part is KmlPartDock) && (part.ParentPart is KmlPartDock)) { KmlPartDock docker = (KmlPartDock)part; KmlPartDock dockee = (KmlPartDock)part.ParentPart; // In case of "Docked (same vessel)" there has to be another docker-dockee connection and that would have connection via parent part if (docker.DockState.ToLower() == "docked (docker)") { if (dockee.DockState.ToLower() != "docked (dockee)") { Syntax.Warning(dockee, "Dock part is parent of other docker part. Docking state should be 'Docked (dockee)' but is '" + dockee.DockState + "', other dock: " + docker); docker.NeedsRepair = true; dockee.NeedsRepair = true; } else { KmlPartDock.BuildDockStructure(dockee, docker); KmlPartDock.BuildDockStructure(docker, dockee); } } else if (docker.DockState.ToLower() == "docked (dockee)") { if (dockee.DockState.ToLower() != "docked (docker)") { Syntax.Warning(dockee, "Dock part is parent of other dockee part. Docking state should be 'Docked (docker)' but is '" + dockee.DockState + "', other dock: " + docker); docker.NeedsRepair = true; dockee.NeedsRepair = true; } else { KmlPartDock.BuildDockStructure(dockee, docker); KmlPartDock.BuildDockStructure(docker, dockee); } } else { if (dockee.DockState.ToLower() == "docked (dockee)") { Syntax.Warning(docker, "Dock part is docked to parent dockee part. Docking state should be 'Docked (docker)' but is '" + docker.DockState + "', parent dock: " + dockee); } else if (dockee.DockState.ToLower() == "docked (docker)") { Syntax.Warning(docker, "Dock part is docked to parent docker part. Docking state should be 'Docked (dockee)' but is '" + docker.DockState + "', parent dock: " + dockee); } else { Syntax.Warning(docker, "Dock part is docked to parent dock part. Docking state should be 'Docked (docker)' or 'Docked (dockee)' but is '" + docker.DockState + "', parent dock: " + dockee); Syntax.Warning(dockee, "Dock part is parent of other dock part. Docking state should be 'Docked (dockee)' or 'Docked (docker)' but is '" + dockee.DockState + "', other dock: " + docker); } docker.NeedsRepair = true; dockee.NeedsRepair = true; } } // Part could be grappled by parent else if ((part.ParentPart is KmlPartDock) && (part.ParentPart as KmlPartDock).DockType == KmlPartDock.DockTypes.Grapple) { KmlPartDock grapple = (KmlPartDock)part.ParentPart; if (grapple.DockUid != part.Uid) { Syntax.Warning(part, "Part not attached or grappled by parent grappling part: " + grapple); Syntax.Warning(grapple, "Grappling part is parent of other part, but is not grappled to it: " + part); grapple.NeedsRepair = true; } else if (grapple.DockState.ToLower() != "grappled") { Syntax.Warning(part, "Part grappled by parent part. Docking state should be 'Grappled' but is '" + grapple.DockState + "', parent grapple: " + grapple); Syntax.Warning(grapple, "Grappling part is parent of grappled part. Docking state should be 'Grappled' but is '" + grapple.DockState + "', grappled part: " + part); grapple.NeedsRepair = true; } else { // It's docked but grappling needs a node attachment KmlPartDock.BuildDockStructure(grapple, part); Syntax.Warning(part, "Part is docked but not attached to parent grappling part: " + grapple); Syntax.Warning(grapple, "Grappling part is parent and docked but not attached to grappled part: " + part); grapple.NeedsRepair = true; } } // TODO KmlPart.BuildAttachmentStructure(): How do KAS links work? // Usually you can only attach a new part by a node to the surface of parent // and not attach a part by surface to parents node. But if you have vessels docked // this situation may happen and this leads to this additional check else if (part.ParentPart.AttachedToSurfaceIndex != i) { Syntax.Warning(part, "Part not attached to parent part: " + part.ParentPart); } } } // Check attachments foreach (int p in part.AttachedToNodeIndices) { if (p >= 0 && p < parts.Count) { KmlPart other = parts[p]; // Sort attached part in the corresponding list, identified by position not by node name double diffX = part.Position.X - other.Position.X; double diffY = part.Position.Y - other.Position.Y; double diffZ = part.Position.Z - other.Position.Z; if (Math.Abs(diffX) > Math.Abs(diffY) && Math.Abs(diffX) > Math.Abs(diffZ)) { if (diffX > 0) { other.AttachedPartsRight.Add(part); part.AttachedToPartsLeft.Add(other); } else { other.AttachedPartsLeft.Add(part); part.AttachedToPartsRight.Add(other); } } else if (Math.Abs(diffZ) > Math.Abs(diffX) && Math.Abs(diffZ) > Math.Abs(diffY)) { if (diffZ > 0) { other.AttachedPartsFront.Add(part); part.AttachedToPartsBack.Add(other); } else { other.AttachedPartsBack.Add(part); part.AttachedToPartsFront.Add(other); } } else { if (diffY > 0) { other.AttachedPartsTop.Add(part); part.AttachedToPartsBottom.Add(other); } else { other.AttachedPartsBottom.Add(part); part.AttachedToPartsTop.Add(other); } } if (!other.AttachedToNodeIndices.Contains(parts.IndexOf(part))) { if ((other is KmlPartDock) && (other as KmlPartDock).DockType == KmlPartDock.DockTypes.Grapple) { KmlPartDock grapple = (KmlPartDock)other; if (grapple.DockUid != part.Uid) { Syntax.Warning(part, "Part node attachment not responded from other grappling part: " + grapple); grapple.NeedsRepair = true; } else if (grapple.DockState.ToLower() != "grappled") { Syntax.Warning(part, "Part grappled by other grappling part. Docking state should be 'Grappled' but is '" + grapple.DockState + ", other grapple: " + grapple); grapple.NeedsRepair = true; } else { KmlPartDock.BuildDockStructure(grapple, part); } } else if ((part is KmlPartDock) && (part as KmlPartDock).DockType == KmlPartDock.DockTypes.Grapple) { KmlPartDock grapple = (KmlPartDock)part; if (grapple.DockUid != other.Uid) { Syntax.Warning(grapple, "Grappling part node attachment not responded from other grappled part: " + other); grapple.NeedsRepair = true; } else if (grapple.DockState.ToLower() != "grappled") { Syntax.Warning(grapple, "Grappling part grappled attached part. Docking state should be 'Grappled' but is '" + grapple.DockState + ", attached part: " + other); grapple.NeedsRepair = true; } else { KmlPartDock.BuildDockStructure(grapple, other); } } else { Syntax.Warning(part, "Part node attachment not responded from other part: " + other.ToString()); } } } else { Syntax.Warning(part, "Part supposed to be node attached to part index [" + p + "], which does not point to a valid part"); } } if (part.AttachedToSurfaceIndex >= 0 && part.AttachedToSurfaceIndex < parts.Count) { parts[part.AttachedToSurfaceIndex].AttachedPartsSurface.Add(part); } else if (part.AttachedToSurfaceIndex != -1) { Syntax.Warning(part, "Part supposed to be surface attached to part index [" + part.AttachedToSurfaceIndex + "], which does not point to a valid part"); } // Check docking (with parent involved is already checked above, here needs to e checked a 'Docked (same vessel)' // Need to check one side only, other part will be touched here in another iteration of the loop if (part is KmlPartDock) { KmlPartDock dock = (KmlPartDock)part; KmlPart other = null; foreach (KmlPart p in parts) { if (p.Uid == dock.DockUid) { other = p; break; } } if (other == null) { // This happens a lot, parts show UId 0 or some other UId they have been attached to before if (dock.DockState.ToLower() == "docked (docker)" || dock.DockState.ToLower() == "docked (dockee)" || dock.DockState.ToLower() == "docked (same vessel)" || dock.DockState.ToLower() == "grappled") { Syntax.Warning(dock, "Dock part supposed to be attached to (UId " + dock.DockUid + "), which does not point to a valid part"); dock.NeedsRepair = true; } // If it still says 'Disengage' something went wron on undocking. We can repair if undocked part is now another vessel // so other will be null because not found in this vessel // Also could be 'Disarmed', 'Disabled' etc., so it's not checked to be 'Ready'. else if (dock.DockState.ToLower() == "disengage") { Syntax.Warning(dock, "Dock part state should be 'Ready' but is '" + dock.DockState + "'"); dock.NeedsRepair = true; } } // Docking with parent already checked else if (other != dock.ParentPart && other.ParentPartIndex != i) { if (dock.DockState.ToLower() == "docked (docker)" || dock.DockState.ToLower() == "docked (dockee)" || dock.DockState.ToLower() == "docked (same vessel)" || dock.DockState.ToLower() == "grappled") { KmlPartDock.BuildDockStructure(dock, other); if (other is KmlPartDock) { KmlPartDock otherDock = (KmlPartDock)other; if (otherDock.DockUid != dock.Uid) { Syntax.Warning(dock, "Dock part docked to other dock part, but docking not responded from other side. Other dock: " + otherDock); dock.NeedsRepair = true; otherDock.NeedsRepair = true; } else if (otherDock.DockState.ToLower() == "docked (dockee)") { if (dock.DockState.ToLower() != "docked (same vessel)") { Syntax.Warning(dock, "Dock part is docked to dockee part. Docking state should be 'Docked (same vessel)' but is '" + dock.DockState + "', dockee part: " + otherDock); dock.NeedsRepair = true; otherDock.NeedsRepair = true; } } else if (otherDock.DockState.ToLower() == "docked (same vessel)") { if (dock.DockState.ToLower() != "docked (dockee)") { Syntax.Warning(dock, "Dock part is docked to same vessel docking part. Docking state should be 'Docked (dockee)' but is '" + dock.DockState + "', same vessel docking part: " + otherDock); dock.NeedsRepair = true; otherDock.NeedsRepair = true; } } else { Syntax.Warning(dock, "Dock part is docked to other dock part. Docking state should be 'Docked (same vessel)' or 'Docked (dockee)' but is '" + dock.DockState + "', other dock: " + otherDock); dock.NeedsRepair = true; otherDock.NeedsRepair = true; } } else if (dock.DockType != KmlPartDock.DockTypes.Grapple) { Syntax.Warning(dock, "Dock part is no grappling device, so it should be only docked to other dock parts, but is docked to: " + other); dock.NeedsRepair = true; } } } } } return(roots); }
private void BuildContextMenu() { ContextMenu menu = new ContextMenu(); MenuItem title = new MenuItem(); title.Icon = GenerateImage(DataNode); title.Header = DataNode.ToString(); title.IsEnabled = false; title.Background = new SolidColorBrush(Colors.Black); title.BorderThickness = new Thickness(1); title.BorderBrush = new SolidColorBrush(Colors.Gray); menu.Items.Add(title); menu.Items.Add(new Separator()); if (DataNode is KmlResource) { MenuItem m = new MenuItem(); m.DataContext = DataNode; m.Icon = Icons.CreateImage(Icons.Resource); m.Header = "Refill this resource"; m.Click += ResourceRefill_Click; menu.Items.Add(m); } else if (DataNode is KmlPart) { KmlPart node = (KmlPart)DataNode; if (node.HasResources) { MenuItem m = new MenuItem(); m.DataContext = DataNode; m.Icon = Icons.CreateImage(Icons.Resource); m.Header = "Refill all resources in this part"; m.Click += PartRefill_Click; menu.Items.Add(m); foreach (string resType in node.ResourceTypes) { m = new MenuItem(); m.DataContext = DataNode; m.Icon = Icons.CreateImage(Icons.Resource); m.Header = "Refill '" + resType + "' resource in this part"; m.Tag = resType; m.Click += PartRefill_Click; menu.Items.Add(m); } } if (node is KmlPartDock) { KmlPartDock dock = (KmlPartDock)node; if (dock.NeedsRepair) { if (menu.Items.Count > 2) { menu.Items.Add(new Separator()); } MenuItem m = new MenuItem(); m.DataContext = DataNode; m.Icon = Icons.CreateImage(Icons.PartDock); m.Header = "Repair docking connection of this and connected part"; m.Click += DockRepair_Click; menu.Items.Add(m); } } } else if (DataNode is KmlVessel) { KmlVessel node = (KmlVessel)DataNode; if (node.HasResources) { MenuItem m = new MenuItem(); m.DataContext = DataNode; m.Icon = Icons.CreateImage(Icons.Resource); m.Header = "Refill all resources in all parts of this vessel"; m.Click += VesselRefill_Click; menu.Items.Add(m); foreach (string resType in node.ResourceTypes) { m = new MenuItem(); m.DataContext = DataNode; m.Icon = Icons.CreateImage(Icons.Resource); m.Header = "Refill all '" + resType + "' resources in all parts of this vessel"; m.Tag = resType; m.Click += VesselRefill_Click; menu.Items.Add(m); } } } // Need to have a seperate menu for each item, even if it is empty. // If ContextMenu is null, the parent's contextmenu will be used (WTF). // Item[0] is the menu title, Item[1] a Seperator, both always created. ContextMenu = menu; if (menu.Items.Count < 3) { ContextMenu.Visibility = System.Windows.Visibility.Hidden; } }
private Image GenerateImage(KmlNode node) { Image image = new Image(); image.Height = 16; if (node is KmlVessel) { KmlVessel vessel = (KmlVessel)node; if (vessel.Type.ToLower() == "base") { image.Source = Icons.VesselBase.Source; } else if (vessel.Type.ToLower() == "debris") { image.Source = Icons.VesselDebris.Source; } else if (vessel.Type.ToLower() == "eva") { image.Source = Icons.VesselEVA.Source; } else if (vessel.Type.ToLower() == "flag") { image.Source = Icons.VesselFlag.Source; } else if (vessel.Type.ToLower() == "lander") { image.Source = Icons.VesselLander.Source; } else if (vessel.Type.ToLower() == "probe") { image.Source = Icons.VesselProbe.Source; } else if (vessel.Type.ToLower() == "spaceobject") { image.Source = Icons.VesselSpaceObject.Source; } else if (vessel.Type.ToLower() == "station") { image.Source = Icons.VesselStation.Source; } else if (vessel.Type.ToLower() == "rover") { image.Source = Icons.VesselRover.Source; } else { image.Source = Icons.Vessel.Source; } } else if (node is KmlPartDock) { KmlPartDock dock = (KmlPartDock)node; if (dock.DockType == KmlPartDock.DockTypes.Grapple) { image.Source = Icons.PartGrapple.Source; } else { image.Source = Icons.PartDock.Source; } } else if (node is KmlPart) { image.Source = Icons.Part.Source; } else if (node is KmlResource) { image.Source = Icons.Resource.Source; } else if (node is KmlKerbal) { KmlKerbal kerbal = (KmlKerbal)node; if (kerbal.Type.ToLower() == "applicant") { image.Source = Icons.KerbalApplicant.Source; } else if (kerbal.Type.ToLower() == "tourist") { image.Source = Icons.KerbalTorist.Source; } else { image.Source = Icons.Kerbal.Source; } } else if (node is KmlGhostNode) { image.Source = Icons.Ghost.Source; } else { image.Source = Icons.Node.Source; } image.Margin = new Thickness(0, 0, 3, 0); return(image); }
private void BuildContextMenu(bool withAddMenu, bool withDeleteMenu) { ContextMenu menu = new ContextMenu(); MenuItem title = new MenuItem(); Image img = GenerateImage(DataNode); img.Margin = new Thickness(0); title.Icon = img; title.Header = DataNode.ToString(); title.IsEnabled = false; title.Background = new SolidColorBrush(Colors.Black); title.BorderThickness = new Thickness(1); title.BorderBrush = new SolidColorBrush(Colors.Gray); menu.Items.Add(title); menu.Items.Add(new Separator()); // So far it's the default Menu, wich should not be shown if no items follow int defaultMenuCount = menu.Items.Count; // Give menu item a more descriptive name string nodeName = "node"; if (DataNode is KmlResource) { nodeName = "resource"; MenuItem m = new MenuItem(); m.DataContext = DataNode; m.Icon = Icons.CreateImage(Icons.Resource); m.Header = "_Refill this resource"; m.Click += ResourceRefill_Click; menu.Items.Add(m); } else if (DataNode is KmlPart) { nodeName = "part"; KmlPart node = (KmlPart)DataNode; if (node.HasResources) { MenuItem m = new MenuItem(); m.DataContext = DataNode; m.Icon = Icons.CreateImage(Icons.Resource); m.Header = "_Refill all resources in this part"; m.Click += PartRefill_Click; menu.Items.Add(m); foreach (string resType in node.ResourceTypes) { m = new MenuItem(); m.DataContext = DataNode; m.Icon = Icons.CreateImage(Icons.Resource); m.Header = "_Refill '" + resType + "' resource in this part"; m.Tag = resType; m.Click += PartRefill_Click; menu.Items.Add(m); } } if (node is KmlPartDock) { KmlPartDock dock = (KmlPartDock)node; if (dock.NeedsRepair) { if (menu.Items.Count > defaultMenuCount) { menu.Items.Add(new Separator()); } MenuItem m = new MenuItem(); m.DataContext = DataNode; m.Icon = Icons.CreateImage(Icons.PartDock); m.Header = "Re_pair docking connection of this and connected part"; m.Click += DockRepair_Click; menu.Items.Add(m); } } } else if (DataNode is KmlVessel) { nodeName = "vessel"; KmlVessel node = (KmlVessel)DataNode; MenuItem m = new MenuItem(); m.DataContext = DataNode; img = GenerateImage(DataNode); img.Margin = new Thickness(0); m.Icon = img; m.Header = "S_witch view"; m.Click += SwitchView_Click; menu.Items.Add(m); menu.Items.Add(new Separator()); m = new MenuItem(); m.DataContext = DataNode; m.Icon = Icons.CreateImage(Icons.VesselSpaceObject); m.Header = "Send to _low kerbin orbit"; m.Click += VesselToLKO_Click; menu.Items.Add(m); if (node.HasResources) { menu.Items.Add(new Separator()); m = new MenuItem(); m.DataContext = DataNode; m.Icon = Icons.CreateImage(Icons.Resource); m.Header = "_Refill all resources in all parts of this vessel"; m.Click += VesselRefill_Click; menu.Items.Add(m); foreach (string resType in node.ResourceTypes) { m = new MenuItem(); m.DataContext = DataNode; m.Icon = Icons.CreateImage(Icons.Resource); m.Header = "_Refill all '" + resType + "' resources in all parts of this vessel"; m.Tag = resType; m.Click += VesselRefill_Click; menu.Items.Add(m); } } if (node.Flags.Count > 0) { menu.Items.Add(new Separator()); m = new MenuItem(); m.DataContext = DataNode; m.Icon = Icons.CreateImage(Icons.VesselFlag); m.Header = "Change _flag in all parts of this vessel..."; m.Click += VesselFlagExchange_Click; menu.Items.Add(m); } } else if (DataNode is KmlKerbal) { nodeName = "kerbal"; KmlKerbal node = (KmlKerbal)DataNode; MenuItem m = new MenuItem(); m.DataContext = DataNode; img = GenerateImage(DataNode); img.Margin = new Thickness(0); m.Icon = img; m.Header = "S_witch view"; m.Click += SwitchView_Click; menu.Items.Add(m); if (node.AssignedVessel != null || node.AssignedPart != null) { if (menu.Items.Count > defaultMenuCount) { menu.Items.Add(new Separator()); } if (node.AssignedVessel != null) { m = new MenuItem(); m.DataContext = DataNode; img = GenerateImage(node.AssignedVessel); img.Margin = new Thickness(0); m.Icon = img; m.Header = "Select assigned _vessel: " + node.AssignedVessel.Name; m.Click += KerbalSelectAssignedVessel_Click; menu.Items.Add(m); } if (node.AssignedPart != null) { m = new MenuItem(); m.DataContext = DataNode; img = GenerateImage(node.AssignedPart); img.Margin = new Thickness(0); m.Icon = img; m.Header = "Select assigned _part: " + node.AssignedPart.Name; m.Click += KerbalSelectAssignedPart_Click; menu.Items.Add(m); } } if (node.AssignedVessel != null || node.AssignedPart != null || node.State.ToLower() == "missing") { if (menu.Items.Count > defaultMenuCount) { menu.Items.Add(new Separator()); } m = new MenuItem(); m.DataContext = DataNode; img = Icons.CreateImage(Icons.VesselSpaceObject); m.Icon = img; m.Header = "Send _home to astronaut complex"; m.Click += KerbalSendHome_Click; menu.Items.Add(m); } } // Adding / deleting if (withAddMenu) { if (menu.Items.Count > defaultMenuCount) { menu.Items.Add(new Separator()); } MenuItem m = new MenuItem(); m.DataContext = DataNode; m.Icon = Icons.CreateImage(Icons.Add); m.Header = "Add _attribute..."; m.Click += NodeAddAttrib_Click; menu.Items.Add(m); m = new MenuItem(); m.DataContext = DataNode; m.Icon = Icons.CreateImage(Icons.Add); m.Header = "Add _child node..."; m.Click += NodeAddChild_Click; menu.Items.Add(m); m = new MenuItem(); m.DataContext = DataNode; m.Icon = Icons.CreateImage(Icons.Add); m.Header = "_Insert node..."; m.Click += NodeInsertBefore_Click; m.IsEnabled = DataNode.Parent != null; menu.Items.Add(m); } if (withDeleteMenu) { if (menu.Items.Count > defaultMenuCount) { menu.Items.Add(new Separator()); } MenuItem m = new MenuItem(); m.DataContext = DataNode; m.Icon = Icons.CreateImage(Icons.Delete); m.Header = "_Delete this " + nodeName + "..."; m.Click += NodeDelete_Click; m.IsEnabled = DataNode.CanBeDeleted; menu.Items.Add(m); } // Need to have a seperate menu for each item, even if it is empty. // If ContextMenu is null, the parent's contextmenu will be used (WTF). // Item[0] is the menu title, Item[1] a Seperator, both always created. ContextMenu = menu; if (menu.Items.Count <= defaultMenuCount) { ContextMenu.Visibility = System.Windows.Visibility.Hidden; } else { // Apply look and feel foreach (object o in menu.Items) { if (o is MenuItem) { MenuItem m = (MenuItem)o; if (!m.IsEnabled && m.Icon != null) { (m.Icon as Image).Opacity = 0.3; } } } } }
private void DrawConnectedParts(GuiVesselsPartGraphNode parent, IntPair parentKoords) { KmlPart parentPart = parent.DataPart; IntPair newKoords; // Top atteched parts foreach (KmlPart sub in parentPart.AttachedPartsTop) { if (!sub.Visited) { newKoords = CalcKoords(parentKoords, parentKoords.X, parentKoords.Y - CountBottom(sub, parentPart) - CountTop(parentPart, parentPart) + 1); for (int y = parentKoords.Y - 1; y > newKoords.Y; y--) { // Fill space with dummy nodes InsertGrid(parentKoords.X, y, new GuiVesselsPartGraphNode(parentKoords.X, y)); } DrawPartAndConnected(sub, newKoords, parentKoords, ConnectVerticalBrush); } else { DrawConnectionAndSeachPart(sub, parentKoords, ConnectVerticalBrush); } } // Bottom atteched parts foreach (KmlPart sub in parentPart.AttachedPartsBottom) { if (!sub.Visited) { newKoords = CalcKoords(parentKoords, parentKoords.X, parentKoords.Y + CountTop(sub, parentPart) + CountBottom(parentPart, parentPart) - 1); for (int y = parentKoords.Y + 1; y < newKoords.Y; y++) { // Fill space with dummy nodes InsertGrid(parentKoords.X, y, new GuiVesselsPartGraphNode(parentKoords.X, y)); } DrawPartAndConnected(sub, newKoords, parentKoords, ConnectVerticalBrush); } else { DrawConnectionAndSeachPart(sub, parentKoords, ConnectVerticalBrush); } } // Left atteched parts foreach (KmlPart sub in parentPart.AttachedPartsLeft) { if (!sub.Visited) { newKoords = CalcKoords(parentKoords, parentKoords.X - 2, parentKoords.Y); DrawPartAndConnected(sub, newKoords, parentKoords, ConnectSidesBrush); } else { DrawConnectionAndSeachPart(sub, parentKoords, ConnectSidesBrush); } } // Right atteched parts foreach (KmlPart sub in parentPart.AttachedPartsRight) { if (!sub.Visited) { newKoords = CalcKoords(parentKoords, parentKoords.X + 2, parentKoords.Y); DrawPartAndConnected(sub, newKoords, parentKoords, ConnectSidesBrush); } else { DrawConnectionAndSeachPart(sub, parentKoords, ConnectSidesBrush); } } // Back atteched parts foreach (KmlPart sub in parentPart.AttachedPartsBack) { if (!sub.Visited) { newKoords = CalcKoords(parentKoords, parentKoords.X - 2, parentKoords.Y - 1); DrawPartAndConnected(sub, newKoords, parentKoords, ConnectSidesBrush); } else { DrawConnectionAndSeachPart(sub, parentKoords, ConnectSidesBrush); } } // Front atteched parts foreach (KmlPart sub in parentPart.AttachedPartsFront) { if (!sub.Visited) { newKoords = CalcKoords(parentKoords, parentKoords.X + 2, parentKoords.Y + 1); DrawPartAndConnected(sub, newKoords, parentKoords, ConnectSidesBrush); } else { DrawConnectionAndSeachPart(sub, parentKoords, ConnectSidesBrush); } } // Surface atteched parts int i = 0; foreach (KmlPart sub in parentPart.AttachedPartsSurface) { if (!sub.Visited) { // Arrange alternating left and right do { if (i % 4 == 0) { newKoords = new IntPair(parentKoords.X - (i / 4 + 1), parentKoords.Y - 1); } else if (i % 4 == 1) { newKoords = new IntPair(parentKoords.X + (i / 4 + 1), parentKoords.Y - 1); } else if (i % 4 == 2) { newKoords = new IntPair(parentKoords.X - (i / 4 + 1), parentKoords.Y + 1); } else { newKoords = new IntPair(parentKoords.X + (i / 4 + 1), parentKoords.Y + 1); } i++; }while (!InsertGrid(newKoords.X, newKoords.Y, null)); DrawPartAndConnected(sub, newKoords, parentKoords, ConnectSurfaceBrush); } else { DrawConnectionAndSeachPart(sub, parentKoords, ConnectSurfaceBrush); i++; } } // Docked parts if (parentPart is KmlPartDock) { KmlPartDock dock = (KmlPartDock)parentPart; KmlPart sub = dock.DockedPart; if (sub != null) { if (!sub.Visited) { newKoords = CalcKoords(parentKoords, parentKoords.X + (sub.Position.X > parentPart.Position.X ? 1 : -1), parentKoords.Y + (sub.Position.Y > parentPart.Position.Y ? 1 : -1)); DrawPartAndConnected(sub, newKoords, parentKoords, ConnectDockBrush); } else { DrawConnectionAndSeachPart(sub, parentKoords, ConnectDockBrush); } } } }
/// <summary> /// Repair the docking connection of this port. /// </summary> public void Repair() { // Two docks if (DockType == DockTypes.Dock) { if (DockedPart == null) { if (Parent is KmlVessel) { KmlVessel vessel = (KmlVessel)Parent; int myIndex = vessel.Parts.IndexOf(this); for (int i = 0; i < vessel.Parts.Count; i++) { KmlPart part = vessel.Parts[i]; if (part is KmlPartDock) { KmlPartDock otherDock = (KmlPartDock)part; if (otherDock.DockedPart == this) { // This will choose the right docker / dockee or switch to same vessel if none is parent RepairDockerChoose(this, otherDock); return; } else if (otherDock.ParentPart == this || ParentPart == otherDock) { if (AttachedToSurfaceIndex == i || AttachedToNodeIndices.Contains(i) || otherDock.AttachedToSurfaceIndex == myIndex || otherDock.AttachedToNodeIndices.Contains(myIndex)) { // It's attached and not docked continue; } else { RepairDockerChoose(this, otherDock); return; } } } } // To avoid getting to here there are returns spread above // Syntax.Warning(this, "Didn't find another part in all parts of the vessel to fix this dock with"); RepairClearDocking(this); } else { Syntax.Warning(this, "Could not search for connected parts, parent vessel is not valid"); } } else if (!(DockedPart is KmlPartDock)) { Syntax.Warning(this, "Don't know how to repair this docking connection, this one is no dock: " + DockedPart); } else { KmlPartDock otherDock = (KmlPartDock)DockedPart; if (otherDock.DockedPart == this || otherDock.ParentPart == this || ParentPart == otherDock) { // They are already linked but there's something to fix unless context menu to this wouldn't be enabled // This will choose the right docker / dockee or switch to same vessel if none is parent RepairDockerChoose(this, otherDock); } else { // Semi-functional same vessel docking would be fixed above, this is no docking RepairClearDocking(this); } } } // One dock and another part else if (DockType == DockTypes.Grapple) { if (DockedPart == null) { if (Parent is KmlVessel) { KmlVessel vessel = (KmlVessel)Parent; int myIndex = vessel.Parts.IndexOf(this); for (int i = 0; i < vessel.Parts.Count; i++) { KmlPart part = vessel.Parts[i]; if (part.ParentPart == this || this.ParentPart == part) { if (AttachedToSurfaceIndex == i || AttachedToNodeIndices.Contains(i) || part.AttachedToSurfaceIndex == myIndex || part.AttachedToNodeIndices.Contains(myIndex)) { // It's attached and not grappled continue; } else { RepairGrappling(this, part); return; } } } // To avoid getting to here there are returns spread above // Syntax.Warning(this, "Didn't find another part in all parts of the vessel to fix this grappling device with"); RepairClearDocking(this); } else { Syntax.Warning(this, "Could not search for connected parts, parent vessel is not valid"); } } else { if (DockedPart.ParentPart == this || ParentPart == DockedPart) { RepairGrappling(this, DockedPart); } else { RepairClearDocking(this); } } } }