예제 #1
0
        /// <summary>
        /// Creates a GuiVesselsPartGraphNode containing the given KmlPart at the given PartGrid koordinates.
        /// Also needs a master GuiTabsManager to switch view on double click on this node.
        /// </summary>
        /// <param name="part">The KmlPart this node will represent</param>
        /// <param name="koordX">The X koord in parents PartGrid</param>
        /// <param name="koordY">The Y koord in parents PartGrid</param>
        /// <param name="master">The master GuiTabsManager</param>
        public GuiVesselsPartGraphNode(KmlPart part, int koordX, int koordY, GuiTabsManager master)
        {
            KoordX = koordX;
            KoordY = koordY;
            Master = master;
            Lines  = new List <Line>();

            if (part != null)
            {
                Orientation = System.Windows.Controls.Orientation.Horizontal;

                Icon         = new GuiTreeNode(part, true, false, true, false);
                Icon.ToolTip = part.ToString();
                Icon.Margin  = new System.Windows.Thickness(-16, 0, 0, 0);
                // GuiTreeNode gets selected and drawn highlighted after using its context menu
                // we don't want this in the part graph
                Icon.Selected += Icon_Selected;
                Children.Add(Icon);

                Text             = new Label();
                Text.DataContext = part;
                Text.Content     = "[" + (part.Parent as KmlVessel).Parts.IndexOf(part) + "]";
                Text.ToolTip     = part.ToString();
                // TODO GuiVesselsPartGraphNode.GuiVesselsPartGraphNode(): Label.ContextMenu does not really work
                Text.ContextMenu = Icon.ContextMenu;
                Text.Margin      = new System.Windows.Thickness(-6, -6, 0, 0);
                Children.Add(Text);

                MouseEnter            += Node_MouseEnter;
                MouseLeave            += Node_MouseLeave;
                Icon.MouseDoubleClick += Node_MouseDoubleClick;
                // TODO GuiVesselsPartGraphNode.GuiVesselsPartGraphNode(): Label.MouseDoubleClick does not really work
                Text.MouseDoubleClick += Node_MouseDoubleClick;
            }
        }
예제 #2
0
        /// <summary>
        /// Identify whether a KmlPart is a docking port part,
        /// so it should be replaced by an intance of KmlPartDock.
        /// </summary>
        /// <param name="part">The KmlPart to check</param>
        /// <returns>True if KmlPart should be replaced by KmlPartDock</returns>
        public static bool PartIsDock(KmlPart part)
        {
            foreach (KmlNode node in part.Children)
            {
                if (node.Tag.ToLower() != "module")
                {
                    continue;
                }

                if (node.Name.ToLower() == "moduledockingnode")
                {
                    return(true);
                }
                else if (node.Name.ToLower() == "moduledockingnodenamed")
                {
                    return(true);
                }
                else if (node.Name.ToLower() == "modulegrapplenode")
                {
                    return(true);
                }
                else if (node.Name.ToLower() == "kasmodulestrut")
                {
                    return(true);
                }
            }
            return(false);
        }
예제 #3
0
파일: KmlPartDock.cs 프로젝트: trumb/KML
        private static void RepairGrappleAttachment(KmlPart part, int attachmentIndex)
        {
            int lastIndex = -1;

            // Repair part 'attN = grapple, <attachmentIndex>'
            for (int i = 0; i < part.Attribs.Count; i++)
            {
                KmlAttrib attrib = part.Attribs[i];
                if (attrib.Name.ToLower() == "attn")
                {
                    lastIndex = i;
                    if (attrib.Value.ToLower().StartsWith("grapple,") || attrib.Value.EndsWith(", " + attachmentIndex))
                    {
                        attrib.Value = "grapple, " + attachmentIndex;
                        return;
                    }
                }
                else if (attrib.Name.ToLower() == "srfn")
                {
                    lastIndex = i;
                }
            }
            // If we got here we didn't find it
            KmlAttrib newAttrib = new KmlAttrib("attN = grapple, " + attachmentIndex);

            part.Attribs.Insert(lastIndex + 1, newAttrib);
            part.AllItems.Insert(lastIndex + 1, newAttrib);
        }
예제 #4
0
        /// <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;
                }
            }
        }
예제 #5
0
        private int CountBottom(KmlPart part, KmlPart cameFrom)
        {
            int c = 1;

            if (part.AttachedPartsSurface.Count > 2)
            {
                c = 2;
                foreach (KmlPart p in part.AttachedPartsSurface)
                {
                    if (p != cameFrom)
                    {
                        c = Math.Max(c, CountBottom(p, part) + 1);
                    }
                }
            }
            if (part.AttachedPartsFront.Count > 0)
            {
                c = Math.Max(c, 2);
                foreach (KmlPart p in part.AttachedPartsFront)
                {
                    if (p != cameFrom)
                    {
                        c = Math.Max(c, CountBottom(p, part) + 1);
                    }
                }
            }
            foreach (KmlPart p in part.AttachedPartsBack)
            {
                if (p != cameFrom)
                {
                    c = Math.Max(c, CountBottom(p, part) - 1);
                }
            }
            foreach (KmlPart p in part.AttachedPartsLeft)
            {
                if (p != cameFrom)
                {
                    c = Math.Max(c, CountBottom(p, part));
                }
            }
            foreach (KmlPart p in part.AttachedPartsRight)
            {
                if (p != cameFrom)
                {
                    c = Math.Max(c, CountBottom(p, part));
                }
            }
            if (part is KmlPartDock)
            {
                KmlPart p = ((KmlPartDock)part).DockedPart;
                if (p != null && p != cameFrom)
                {
                    c = Math.Max(c, CountBottom(p, part));
                }
            }
            return(c);
        }
예제 #6
0
        private static List <KmlItem> ParseFile(System.IO.StreamReader file, KmlNode parent)
        {
            List <KmlItem> list = new List <KmlItem>();

            string line;

            while ((line = file.ReadLine()) != null)
            {
                KmlItem newItem = ParseLine(line);
                if (newItem is KmlBegin)
                {
                    KmlItem lastItem;
                    int     l = list.Count - 1;
                    if (l < 0)
                    {
                        lastItem = new KmlItem("");
                    }
                    else
                    {
                        lastItem = list[l];
                        list.RemoveAt(l);
                    }
                    KmlNode newNode = new KmlNode(lastItem, parent);
                    if (newNode.Tag.ToLower() == "vessel")
                    {
                        newNode = new KmlVessel(newNode);
                    }
                    else if (newNode.Tag.ToLower() == "kerbal")
                    {
                        newNode = new KmlKerbal(newNode);
                    }
                    else if (newNode.Tag.ToLower() == "part")
                    {
                        newNode = new KmlPart(newNode);
                    }
                    else if (newNode.Tag.ToLower() == "resource")
                    {
                        newNode = new KmlResource(newNode);
                    }
                    list.Add(newNode);
                    newNode.AddRange(ParseFile(file, newNode));
                }
                else if (newItem is KmlEnd)
                {
                    Identify(list);
                    return(list);
                }
                else
                {
                    list.Add(newItem);
                }
            }

            Identify(list);
            return(list);
        }
예제 #7
0
 private void SetRootPart(string value)
 {
     if (int.TryParse(value, out rootPartIndex))
     {
         if (Parts.Count > rootPartIndex)
         {
             RootPart = Parts[rootPartIndex];
         }
     }
 }
예제 #8
0
        private void DrawPartAndConnected(KmlPart part, IntPair koords, IntPair parentKoords, Brush lineBrush)
        {
            GuiVesselsPartGraphNode partNode = DrawPart(part, koords);
            Line l = DrawConnection(parentKoords, koords, lineBrush);

            partNode.Lines.Add(l);
            GuiVesselsPartGraphNode parentNode = PartGrid[parentKoords.X - PartGridMinX][parentKoords.Y - PartGridMinY];

            parentNode.Lines.Add(l);
            DrawConnectedParts(partNode, koords);
        }
예제 #9
0
 /// <summary>
 /// Clear all child nodes and attributes from this node.
 /// </summary>
 public override void Clear()
 {
     Type      = "";
     Situation = "";
     Parts.Clear();
     Flags.Clear();
     ResourceTypes.Clear();
     RootPart      = null;
     rootPartIndex = 0;
     base.Clear();
 }
예제 #10
0
        private void Node_MouseDoubleClick(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            KmlPart part = null;

            if (sender is GuiTreeNode)
            {
                part = ((GuiTreeNode)sender).DataNode as KmlPart;
            }
            else if (sender is Label)
            {
                part = ((Label)sender).DataContext as KmlPart;
            }
            if (part != null)
            {
                GuiTabsManager.GetCurrent().Select(part);
            }
        }
예제 #11
0
        /// <summary>
        /// Creates a KmlVessel as a copy of a given KmlNode.
        /// </summary>
        /// <param name="node">The KmlNode to copy</param>
        public KmlVessel(KmlNode node)
            : base(node.Line)
        {
            // First parent is null, will be set later when added to parent,
            // then  IdentifyParent() will set Origin.
            Origin = VesselOrigin.Other;

            Type          = "";
            Situation     = "";
            Parts         = new List <KmlPart>();
            Flags         = new List <string>();
            AssignedCrew  = new List <KmlKerbal>();
            ResourceTypes = new SortedSet <string>();
            RootPart      = null;

            AddRange(node.AllItems);
        }
예제 #12
0
        /// <summary>
        /// Creates a KmlVessel as a copy of a given KmlNode.
        /// </summary>
        /// <param name="node">The KmlNode to copy</param>
        public KmlVessel(KmlNode node)
            : base(node.Line, node.Parent)
        {
            if (node.Parent != null && node.Parent.Tag.ToLower() == "flightstate")
            {
                Origin = VesselOrigin.Flightstate;
            }
            else
            {
                Origin = VesselOrigin.Other;
            }

            Type          = "";
            Situation     = "";
            Parts         = new List <KmlPart>();
            ResourceTypes = new SortedSet <string>();
            RootPart      = null;

            AddRange(node.AllItems);
        }
예제 #13
0
        /// <summary>
        /// After an item is completely loaded the Intentify() method is called.
        /// This is the right moment to build the connection structure of the parts.
        /// There is no class derived from KmlVessel so it doesn't need to be replaced.
        /// </summary>
        /// <returns>There is no class derived from KmlVessel so always null is returned</returns>
        protected override KmlItem Identify()
        {
            // No need to replace this by another class, but after vessel is completed
            // it's the right time to build parts structure
            List <KmlPart> roots = KmlPart.BuildAttachmentStructure(Parts);

            if (roots.Count > 1)
            {
                Syntax.Warning(this, "Vessel has more than one root part identified from part structure: " + string.Join <KmlPart>(", ", roots.ToArray()));
            }
            if (RootPart == null && roots.Count > 0)
            {
                Syntax.Warning(this, "Vessel's root part attribute does not point to a valid part. Set root to: " + string.Join <KmlPart>(", ", roots.ToArray()));
            }
            else if (RootPart != null && !roots.Contains(RootPart))
            {
                Syntax.Warning(this, "Vessel's root part attribute is not equal to root identified from part structure: " + RootPart.ToString() + " <-> " + string.Join <KmlPart>(", ", roots.ToArray()));
            }
            return(base.Identify());
        }
예제 #14
0
        private GuiVesselsPartGraphNode DrawPart(KmlPart part, int x, int y)
        {
            GuiVesselsPartGraphNode node = new GuiVesselsPartGraphNode(part, x, y, Master);

            if (!InsertGrid(x, y, node))
            {
                throw new Exception("Couldn't place GuiVesselsPartGraphNode on grid pos " + x + ", " + y + " (already occupied)");
                //IntPair p = CalcKoords(new IntPair(x, y), x + 1, y);
                //InsertGrid(p.X, p.Y, node);
            }
            Point position = CalcPosition(x, y);

            Canvas.SetLeft(node, position.X);
            Canvas.SetTop(node, position.Y);
            // Have nodes on higher ZIndex than the lines
            Canvas.SetZIndex(node, 1);
            VesselsDetails.Children.Add(node);

            part.Visited = true;
            return(node);
        }
예제 #15
0
파일: KmlItem.cs 프로젝트: fat-lobyte/KML
        private static KmlNode ParseNode(KmlItem item)
        {
            KmlNode newNode = new KmlNode(item);

            if (newNode.Tag.ToLower() == "vessel")
            {
                newNode = new KmlVessel(newNode);
            }
            else if (newNode.Tag.ToLower() == "kerbal")
            {
                newNode = new KmlKerbal(newNode);
            }
            else if (newNode.Tag.ToLower() == "part")
            {
                newNode = new KmlPart(newNode);
            }
            else if (newNode.Tag.ToLower() == "resource")
            {
                newNode = new KmlResource(newNode);
            }
            return(newNode);
        }
예제 #16
0
        private void AssignTemplate(bool withImage, bool withText)
        {
            // Fit an Image and a TextBlock into a Stackpanel,
            // have the Stackpanel as node Header

            StackPanel pan = new StackPanel();

            pan.Orientation = Orientation.Horizontal;
            if (withImage)
            {
                if (DataNode is KmlResource)
                {
                    KmlResource res = (KmlResource)DataNode;
                    pan.Children.Add(GenerateProgressBar(res.AmountRatio));
                }
                else if (DataNode is KmlPart)
                {
                    KmlPart part = (KmlPart)DataNode;
                    pan.Children.Add(GenerateImage(DataNode));
                    if (part.WorstResourceRatio >= 0.0)
                    {
                        ProgressBar prog = GenerateProgressBar(part.WorstResourceRatio);
                        prog.Height = 4;
                        prog.Margin = new Thickness(-19, 6, 3, 0);
                        pan.Children.Add(prog);
                    }
                }
                else
                {
                    pan.Children.Add(GenerateImage(DataNode));
                }
            }
            if (withText)
            {
                pan.Children.Add(new TextBlock(new Run(DataNode.ToString())));
            }
            Header = pan;
        }
예제 #17
0
        private void DrawConnectionAndSeachPart(KmlPart part, IntPair parentKoords, Brush lineBrush)
        {
            // Already drawn sub part with one way arrow.
            // Need to draw the reverse arrow only
            // But where is the node?
            Point parentPos = CalcPosition(parentKoords);
            GuiVesselsPartGraphNode parentNode = PartGrid[parentKoords.X - PartGridMinX][parentKoords.Y - PartGridMinY];

            foreach (UIElement element in VesselsDetails.Children)
            {
                if (element is GuiVesselsPartGraphNode)
                {
                    GuiVesselsPartGraphNode node = (GuiVesselsPartGraphNode)element;
                    if (node.DataPart == part)
                    {
                        Line l = DrawConnection(parentPos.X, parentPos.Y, Canvas.GetLeft(node), Canvas.GetTop(node), lineBrush);
                        node.Lines.Add(l);
                        parentNode.Lines.Add(l);
                        break;
                    }
                }
            }
        }
예제 #18
0
        private static void RepairGrappleAttachment(KmlPart part, int attachmentIndex)
        {
            KmlAttrib lastItem = null;

            // Repair part 'attN = grapple, <attachmentIndex>'
            for (int i = 0; i < part.Attribs.Count; i++)
            {
                KmlAttrib attrib = part.Attribs[i];
                if (attrib.Name.ToLower() == "attn")
                {
                    lastItem = attrib;
                    if (attrib.Value.ToLower().StartsWith("grapple,") || attrib.Value.EndsWith(", " + attachmentIndex))
                    {
                        attrib.Value = "grapple, " + attachmentIndex;
                        return;
                    }
                }
                else if (attrib.Name.ToLower() == "srfn")
                {
                    lastItem = attrib;
                }
            }
            // If we got here we didn't find it
            KmlAttrib newAttrib = new KmlAttrib("attN = grapple, " + attachmentIndex);

            // InsertAfter will add to the end if lastItem is null
            part.InsertAfter(lastItem, newAttrib);
            //if (lastItem != null)
            //{
            //    part.Attribs.Insert(part.Attribs.IndexOf(lastItem) + 1, newAttrib);
            //    part.AllItems.Insert(part.AllItems.IndexOf(lastItem) + 1, newAttrib);
            //}
            //else
            //{
            //    part.Add(newAttrib);
            //}
        }
예제 #19
0
        /// <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);
        }
예제 #20
0
        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;
                        }
                    }
                }
            }
        }
예제 #21
0
        /// <summary>
        /// Adds a child KmlItem to this nodes lists of children, depending of its
        /// derived class KmlNode, KmlPart, KmlAttrib or further derived from these.
        /// When an KmlAttrib "Name", "Type" or "Root" are found, their value
        /// will be used for the corresponding property of this node.
        /// </summary>
        /// <param name="beforeItem">The KmlItem where the new item should be inserted before</param>
        /// <param name="newItem">The KmlItem to add</param>
        protected override void Add(KmlItem beforeItem, KmlItem newItem)
        {
            if (newItem is KmlAttrib)
            {
                KmlAttrib attrib = (KmlAttrib)newItem;
                if (attrib.Name.ToLower() == "type" && Type.Length == 0)
                {
                    Type = attrib.Value;

                    // Get notified when Type changes
                    attrib.AttribValueChanged += Type_Changed;
                    attrib.CanBeDeleted        = false;
                }
                else if (attrib.Name.ToLower() == "sit" && Situation.Length == 0)
                {
                    Situation = attrib.Value;

                    // Get notified when Type changes
                    attrib.AttribValueChanged += Situation_Changed;
                    attrib.CanBeDeleted        = false;
                }
                else if (attrib.Name.ToLower() == "root" && RootPart == null)
                {
                    SetRootPart(attrib.Value);

                    // Get notified when Type changes
                    attrib.AttribValueChanged += Root_Changed;
                    attrib.CanBeDeleted        = false;
                }
            }
            else if (newItem is KmlPart)
            {
                KmlPart part = (KmlPart)newItem;
                if (beforeItem != null)
                {
                    KmlPart beforePart = null;
                    int     allIndex   = AllItems.IndexOf(beforeItem);
                    for (int i = allIndex; i < AllItems.Count; i++)
                    {
                        if (AllItems[i] is KmlPart && Parts.Contains((KmlPart)AllItems[i]))
                        {
                            beforePart = (KmlPart)AllItems[i];
                            break;
                        }
                    }
                    if (beforePart != null)
                    {
                        beforePart.InsertionPreparation();
                        Parts.Insert(Parts.IndexOf(beforePart), part);
                        beforePart.InsertionFinalization();
                    }
                    else
                    {
                        Parts.Add(part);
                    }
                }
                else
                {
                    Parts.Add(part);
                }
                if (Parts.Count == rootPartIndex + 1)
                {
                    RootPart = Parts[rootPartIndex];
                }
                if (part.Flag != "" && !Flags.Any(x => x.ToLower() == part.Flag.ToLower()))
                {
                    Flags.Add(part.Flag);
                }
                if (part.HasResources)
                {
                    foreach (string resType in part.ResourceTypes)
                    {
                        ResourceTypes.Add(resType);
                    }
                }
                KmlAttrib flag = part.GetAttrib("flag");
                if (flag != null)
                {
                    flag.AttribValueChanged += Flag_Changed;
                }
            }
            base.Add(beforeItem, newItem);
        }
예제 #22
0
 private GuiVesselsPartGraphNode DrawPart(KmlPart part, IntPair koords)
 {
     return(DrawPart(part, koords.X, koords.Y));
 }
예제 #23
0
        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;
            }
        }
예제 #24
0
        /// <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);
                    }
                }
            }
        }
예제 #25
0
        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);
                    }
                }
            }
        }
예제 #26
0
        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");
            }
        }
예제 #27
0
        /// <summary>
        /// Creates a KmlPartDock as a copy of a given KmlPart.
        /// </summary>
        /// <param name="part">The KmlPart to copy</param>
        public KmlPartDock(KmlPart part)
            : base(part)
        {
            DockType              = DockTypes.Dock;
            DockName              = "";
            DockState             = "";
            DockedVesselName      = "";
            DockedVesselType      = "";
            DockedVesselOtherName = "";
            DockedVesselOtherType = "";
            DockUid     = "";
            DockedPart  = null;
            NeedsRepair = false;

            foreach (KmlNode node in Children)
            {
                if (node.Tag.ToLower() == "module" &&
                    (node.Name.ToLower() == "moduledockingnode" ||
                     node.Name.ToLower() == "modulegrapplenode" ||
                     node.Name.ToLower() == "kasmodulestrut"))
                {
                    if (node.Name.ToLower() == "modulegrapplenode")
                    {
                        DockType = DockTypes.Grapple;
                    }
                    else if (node.Name.ToLower() == "kasmodulestrut")
                    {
                        DockType = DockTypes.KasCPort;
                    }

                    foreach (KmlAttrib attrib in node.Attribs)
                    {
                        if (attrib.Name.ToLower() == "state")
                        {
                            DockState = attrib.Value;
                            attrib.AttribValueChanged += DockState_Changed;
                            attrib.CanBeDeleted        = false;
                        }
                        else if (attrib.Name.ToLower() == "dockuid")
                        {
                            DockUid = attrib.Value;
                            attrib.AttribValueChanged += DockUid_Changed;
                            attrib.CanBeDeleted        = false;
                        }
                        else if (DockType == DockTypes.KasCPort && attrib.Name.ToLower() == "dockedpartid")
                        {
                            DockUid = attrib.Value;
                            attrib.AttribValueChanged += DockUid_Changed;
                            attrib.CanBeDeleted        = false;
                        }
                    }
                    foreach (KmlNode subnode in node.Children)
                    {
                        if (subnode.Tag.ToLower() == "dockedvessel")
                        {
                            foreach (KmlAttrib attrib in subnode.Attribs)
                            {
                                if (attrib.Name.ToLower() == "vesselname")
                                {
                                    DockedVesselName           = attrib.Value;
                                    attrib.AttribValueChanged += DockedVesselName_Changed;
                                    attrib.CanBeDeleted        = false;
                                }
                                else if (attrib.Name.ToLower() == "vesseltype")
                                {
                                    DockedVesselType           = TranslateDockedVesselType(attrib.Value);
                                    attrib.AttribValueChanged += DockedVesselType_Changed;
                                    attrib.CanBeDeleted        = false;
                                }
                            }
                        }
                        // Grapple-links with grapplingdevice on master side
                        // (the one that's name survived) need to read "dockedvessel_other" to get slave side name
                        else if (subnode.Tag.ToLower() == "dockedvessel_other")
                        {
                            foreach (KmlAttrib attrib in subnode.Attribs)
                            {
                                if (attrib.Name.ToLower() == "vesselname")
                                {
                                    DockedVesselOtherName      = attrib.Value;
                                    attrib.AttribValueChanged += DockedVesselOtherName_Changed;
                                    attrib.CanBeDeleted        = false;
                                }
                                else if (attrib.Name.ToLower() == "vesseltype")
                                {
                                    DockedVesselOtherType      = TranslateDockedVesselType(attrib.Value);
                                    attrib.AttribValueChanged += DockedVesselOtherType_Changed;
                                    attrib.CanBeDeleted        = false;
                                }
                            }
                        }
                    }
                }
                else if (node.Tag.ToLower() == "module" && node.Name.ToLower() == "moduledockingnodenamed")
                {
                    foreach (KmlAttrib attrib in node.Attribs)
                    {
                        if (attrib.Name.ToLower() == "portname")
                        {
                            DockName = attrib.Value;
                            attrib.AttribValueChanged += DockName_Changed;
                            attrib.CanBeDeleted        = false;
                        }
                    }
                }
            }
        }
예제 #28
0
        /// <summary>
        /// Adds a child KmlItem to this nodes lists of children, depending of its
        /// derived class KmlNode, KmlPart, KmlAttrib or further derived from these.
        /// When an KmlAttrib "Name", "Type" or "Root" are found, their value
        /// will be used for the corresponding property of this node.
        /// </summary>
        /// <param name="item">The KmlItem to add</param>
        public override void Add(KmlItem item)
        {
            KmlItem newItem = item;

            if (item is KmlAttrib)
            {
                KmlAttrib attrib = (KmlAttrib)item;
                if (attrib.Name.ToLower() == "type")
                {
                    Type = attrib.Value;

                    // Get notified when Type changes
                    attrib.AttribValueChanged += Type_Changed;
                    attrib.CanBeDeleted        = false;
                }
                else if (attrib.Name.ToLower() == "sit")
                {
                    Situation = attrib.Value;

                    // Get notified when Type changes
                    attrib.AttribValueChanged += Situation_Changed;
                    attrib.CanBeDeleted        = false;
                }
                else if (attrib.Name.ToLower() == "root")
                {
                    SetRootPart(attrib.Value);

                    // Get notified when Type changes
                    attrib.AttribValueChanged += Root_Changed;
                    attrib.CanBeDeleted        = false;
                }
            }
            else if (item is KmlPart)
            {
                KmlPart part = (KmlPart)item;
                Parts.Add(part);
                if (Parts.Count == rootPartIndex + 1)
                {
                    RootPart = Parts[rootPartIndex];
                }
                if (part.HasResources)
                {
                    foreach (string resType in part.ResourceTypes)
                    {
                        ResourceTypes.Add(resType);
                    }
                }
            }

            /*else if (Item is KmlNode)
             * {
             *  KmlNode node = (KmlNode)Item;
             *  if (node.Tag.ToLower() == "part")
             *  {
             *      newItem = new KmlPart(node);
             *      Parts.Add((KmlPart)newItem);
             *      if (Parts.Count == rootPartNr + 1)
             *      {
             *          RootPart = Parts[rootPartNr];
             *      }
             *  }
             * }*/
            base.Add(newItem);
        }
예제 #29
0
파일: KmlPartDock.cs 프로젝트: trumb/KML
        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);
                }
            }
        }