예제 #1
0
        private string GetCustomName(IBodyNameAndID sc, ISystem sys)
        {
            string rest       = IsStarNameRelatedReturnRest(sys.Name, sc.Body, sc.BodyDesignation);
            string customname = null;

            if (sc.Body.StartsWith(sys.Name, StringComparison.InvariantCultureIgnoreCase))
            {
                customname = sc.Body.Substring(sys.Name.Length).TrimStart(' ', '-');

                if (customname == "" && sc.BodyType != "Star")
                {
                    customname = sc.Body;
                }
                else if (customname == "" || customname == rest)
                {
                    customname = null;
                }
            }
            else if (rest == null || !sc.Body.EndsWith(rest))
            {
                customname = sc.Body;
            }

            return(customname);
        }
예제 #2
0
        // used by historylist during full history processing in background
        public bool AddBodyToBestSystem(IBodyNameAndID je, int startindex, List <HistoryEntry> hl)
        {
            HistoryEntry     he;
            JournalLocOrJump jl;

            return(AddBodyToBestSystem(je, startindex, hl, out he, out jl));
        }
예제 #3
0
        private List <string> ExtractElementsBodyAndID(IBodyNameAndID sc, ISystem sys, out bool isbeltcluster, out ScanNodeType starscannodetype)
        {
            starscannodetype = ScanNodeType.star;
            isbeltcluster    = false;
            List <string> elements;

            string rest = IsStarNameRelatedReturnRest(sys.Name, sc.Body, sc.BodyDesignation); // extract any relationship between the system we are in and the name, and return it if so

            if (rest != null)                                                                 // if we have a relationship..
            {
                if (rest.Length > 0)
                {
                    elements = rest.Split(' ').ToList();

                    if (elements.Count == 4 && elements[0].Length == 1 && char.IsLetter(elements[0][0]) &&           // A belt cluster N
                        elements[1].Equals("belt", StringComparison.InvariantCultureIgnoreCase) &&
                        elements[2].Equals("cluster", StringComparison.InvariantCultureIgnoreCase))
                    {
                        elements = new List <string> {
                            MainStar, elements[0] + " " + elements[1], elements[2] + " " + elements[3]
                        };                                                                                                          // reform into Main Star | A belt | Cluster N
                        isbeltcluster = true;
                    }
                    else if (elements.Count == 5 && elements[0].Length >= 1 &&                                      // AA A belt cluster N
                             elements[1].Length == 1 && char.IsLetter(elements[1][0]) &&
                             elements[2].Equals("belt", StringComparison.InvariantCultureIgnoreCase) &&
                             elements[3].Equals("cluster", StringComparison.InvariantCultureIgnoreCase))
                    {
                        elements = new List <string> {
                            elements[0], elements[1] + " " + elements[2], elements[3] + " " + elements[4]
                        };                                                                                                                  // reform into <star> | A belt | Cluster N
                        isbeltcluster = true;
                    }

                    if (char.IsDigit(elements[0][0]))       // if digits, planet number, no star designator
                    {
                        elements.Insert(0, MainStar);       // no star designator, main star, add MAIN
                    }
                    else if (elements[0].Length > 1)        // designator, is it multiple chars..
                    {
                        starscannodetype = ScanNodeType.barycentre;
                    }
                }
                else
                {
                    elements = new List <string>();      // only 1 item, the star, which is the same as the system name..
                    elements.Add(MainStar);              // Sol / SN:Sol should come thru here
                }
            }
            else
            {                                               // so not part of starname
                elements = sc.Body.Split(' ').ToList();     // not related in any way (earth) so assume all bodyparts, and
                elements.Insert(0, MainStar);               // insert the MAIN designator as the star designator
            }

            return(elements);
        }
예제 #4
0
        private string GetBodyDesignation(IBodyNameAndID je)
        {
            if (je.Body == null || je.BodyType == null || je.StarSystem == null)
            {
                return(null);
            }

            string system   = je.StarSystem;
            string bodyname = je.Body;
            bool   isstar   = je.BodyType == "Star";
            int    bodyid   = je.BodyID ?? -1;

            if (je.BodyID != null && bodyIdDesignationMap.ContainsKey(system) && bodyIdDesignationMap[system].ContainsKey(bodyid) && bodyIdDesignationMap[system][bodyid].NameEquals(bodyname))
            {
                return(bodyIdDesignationMap[system][bodyid].Designation);
            }

            Dictionary <string, Dictionary <string, string> > desigmap = isstar ? starDesignationMap : planetDesignationMap;

            // Special case for m Centauri
            if (isstar && system.ToLowerInvariant() == "m centauri")
            {
                if (bodyname == "m Centauri")
                {
                    return("m Centauri A");
                }
                else if (bodyname == "M Centauri")
                {
                    return("m Centauri B");
                }
            }
            // Special case for Castellan Belt
            else if (system.ToLowerInvariant() == "lave" && bodyname.StartsWith("Castellan Belt ", StringComparison.InvariantCultureIgnoreCase))
            {
                return("Lave A Belt " + bodyname.Substring("Castellan Belt ".Length));
            }

            if (desigmap.ContainsKey(system) && desigmap[system].ContainsKey(bodyname))
            {
                return(desigmap[system][bodyname]);
            }

            if (bodyname.Equals(system, StringComparison.InvariantCultureIgnoreCase) || bodyname.StartsWith(system + " ", StringComparison.InvariantCultureIgnoreCase))
            {
                return(bodyname);
            }

            return(bodyname);
        }
예제 #5
0
        public bool AddBodyToBestSystem(IBodyNameAndID je, int startindex, List <HistoryEntry> hl)
        {
            // reject types which are not scannable

            if (je.Body == null || je.BodyType == "Station" || je.BodyType == "StellarRing" || je.BodyType == "PlanetaryRing" || je.BodyType == "SmallBody")
            {
                return(false);
            }

            var best = FindBestSystem(startindex, hl, je.Body, je.BodyID, je.BodyType == "Star");

            if (best == null)
            {
                return(false);
            }

            je.BodyDesignation = best.Item1;

            return(ProcessBodyAndID(je, best.Item2));
        }
예제 #6
0
        private string GetBodyDesignation(IBodyNameAndID je)
        {
            if (je.Body == null || je.BodyType == null || je.StarSystem == null)
            {
                return(null);
            }

            string system   = je.StarSystem;
            string bodyname = je.Body;
            bool   isstar   = je.BodyType == "Star";

            Dictionary <string, Dictionary <string, string> > desigmap = isstar ? starDesignationMap : planetDesignationMap;

            // Special case for m Centauri
            if (isstar && system.ToLowerInvariant() == "m centauri")
            {
                if (bodyname == "m Centauri")
                {
                    return("m Centauri A");
                }
                else if (bodyname == "M Centauri")
                {
                    return("m Centauri B");
                }
            }

            if (desigmap.ContainsKey(system) && desigmap[system].ContainsKey(bodyname))
            {
                return(desigmap[system][bodyname]);
            }

            if (bodyname.Equals(system, StringComparison.InvariantCultureIgnoreCase) || bodyname.StartsWith(system + " ", StringComparison.InvariantCultureIgnoreCase))
            {
                return(bodyname);
            }

            return(bodyname);
        }
예제 #7
0
        // used by historylist directly for a single update during play, in foreground..  Also used by above.. so can be either in fore/back
        public bool AddBodyToBestSystem(IBodyNameAndID je, int startindex, List <HistoryEntry> hl, out HistoryEntry he, out JournalLocOrJump jl)
        {
            if (je.Body == null || je.BodyType == "Station" || je.BodyType == "StellarRing" || je.BodyType == "PlanetaryRing" || je.BodyType == "SmallBody")
            {
                he = null;
                jl = null;
                return(false);
            }

            for (int j = startindex; j >= 0; j--)
            {
                he = hl[j];

                if (he.IsLocOrJump && he.System.Name == je.StarSystem && (he.System.SystemAddress == null || je.SystemAddress == null || he.System.SystemAddress == je.SystemAddress))
                {
                    jl = (JournalLocOrJump)he.journalEntry;
                    string designation = GetBodyDesignation(je);

                    if (IsStarNameRelated(he.System.Name, je.Body, designation))       // if its part of the name, use it
                    {
                        je.BodyDesignation = designation;

                        return(Process(je, he.System, true));
                    }
                    else if (jl != null && IsStarNameRelated(jl.StarSystem, je.Body, designation))
                    {
                        // Ignore scans where the system name has changed
                        return(false);
                    }
                }
            }

            jl = null;
            he = null;

            je.BodyDesignation = GetBodyDesignation(je);
            return(Process(je, hl[startindex].System, true));         // no relationship, add..
        }
예제 #8
0
        private ScanNode ProcessElements(IBodyNameAndID sc, ISystem sys, SystemNode sn, string customname, List <string> elements, ScanNodeType starscannodetype, bool isbeltcluster)
        {
            SortedList <string, ScanNode> cnodes = sn.starnodes;
            ScanNode node = null;

            for (int lvl = 0; lvl < elements.Count; lvl++)
            {
                ScanNode     sublv;
                ScanNodeType sublvtype;
                string       ownname = elements[lvl];

                if (lvl == 0)
                {
                    sublvtype = starscannodetype;
                }
                else if (isbeltcluster)
                {
                    sublvtype = lvl == 1 ? ScanNodeType.belt : ScanNodeType.beltcluster;
                }
                else
                {
                    sublvtype = ScanNodeType.body;
                }

                if (cnodes == null || !cnodes.TryGetValue(elements[lvl], out sublv))
                {
                    if (node != null && node.children == null)
                    {
                        node.children = new SortedList <string, ScanNode>(new DuplicateKeyComparer <string>());
                        cnodes        = node.children;
                    }

                    sublv = new ScanNode
                    {
                        ownname        = ownname,
                        fullname       = lvl == 0 ? (sys.Name + (ownname.Contains("Main") ? "" : (" " + ownname))) : node.fullname + " " + ownname,
                        ScanData       = null,
                        children       = null,
                        type           = sublvtype,
                        level          = lvl,
                        IsTopLevelNode = lvl == 0
                    };

                    cnodes.Add(ownname, sublv);
                }

                node   = sublv;
                cnodes = node.children;

                if (lvl == elements.Count - 1)
                {
                    node.BodyLoc    = sc;
                    node.customname = customname;

                    if (sc.BodyID != null)
                    {
                        node.BodyID = sc.BodyID;
                    }

                    if (sc.BodyType == "" || sc.BodyType == "Null")
                    {
                        node.type = ScanNodeType.barycentre;
                    }
                    else if (sc.BodyType == "Belt")
                    {
                        node.type = ScanNodeType.belt;
                    }
                }
            }

            return(node);
        }
예제 #9
0
        private bool Process(IBodyNameAndID sc, ISystem sys, bool reprocessPrimary = false)  // background or foreground.. FALSE if you can't process it
        {
            SystemNode sn          = GetOrCreateSystemNode(sys);
            ScanNode   relatedScan = null;

            if ((sc.BodyDesignation == null || sc.BodyDesignation == sc.Body) && (sc.Body != sc.StarSystem || sc.BodyType != "Star"))
            {
                foreach (var body in sn.Bodies)
                {
                    if ((body.fullname == sc.Body || body.customname == sc.Body) &&
                        (body.fullname != sc.StarSystem || (sc.BodyType == "Star" && body.level == 0) || (sc.BodyType != "Star" && body.level != 0)))
                    {
                        relatedScan        = body;
                        sc.BodyDesignation = body.fullname;
                        break;
                    }
                }
            }

            if (relatedScan == null)
            {
                foreach (var body in sn.Bodies)
                {
                    if ((body.fullname == sc.Body || body.customname == sc.Body) &&
                        (body.fullname != sc.StarSystem || (sc.BodyType == "Star" && body.level == 0) || (sc.BodyType != "Star" && body.level != 0)))
                    {
                        relatedScan = body;
                        break;
                    }
                }
            }

            if (relatedScan != null && relatedScan.ScanData == null)
            {
                relatedScan.BodyLoc = sc;
                return(true); // We already have the scan
            }

            // handle Earth, starname = Sol
            // handle Eol Prou LW-L c8-306 A 4 a and Eol Prou LW-L c8-306
            // handle Colonia 4 , starname = Colonia, planet 4
            // handle Aurioum B A BELT
            // Kyloasly OY-Q d5-906 13 1

            ScanNodeType starscannodetype = ScanNodeType.star;          // presuming..
            bool         isbeltcluster    = false;

            // Extract elements from name
            List <string> elements = ExtractElements(sc, sys, out isbeltcluster, out starscannodetype);

            // Bail out if no elements extracted
            if (elements.Count == 0)
            {
                System.Diagnostics.Trace.WriteLine($"Failed to add body {sc.Body} to system {sys.Name} - not enough elements");
                return(false);
            }
            // Bail out if more than 5 elements extracted
            else if (elements.Count > 5)
            {
                System.Diagnostics.Trace.WriteLine($"Failed to add body {sc.Body} to system {sys.Name} - too deep");
                return(false);
            }

            // Get custom name if different to designation
            string customname = GetCustomName(sc, sys);

            // Process elements
            ScanNode node = ProcessElements(sc, sys, sn, customname, elements, starscannodetype, isbeltcluster);

            if (node.BodyID != null)
            {
                sn.NodesByID[(int)node.BodyID] = node;
            }

            return(true);
        }
예제 #10
0
        private bool ProcessBodyAndID(IBodyNameAndID sc, ISystem sys)  // background or foreground..
        {
            SystemNode sn          = GetOrCreateSystemNode(sys);
            ScanNode   relatedScan = null;

            // try and find the scan related to the body name

            // no designation, or same designation AND not a star
            if ((sc.BodyDesignation == null || sc.BodyDesignation == sc.Body) && (sc.Body != sc.StarSystem || sc.BodyType != "Star"))
            {
                foreach (var body in sn.Bodies)
                {
                    if ((body.FullName == sc.Body || body.CustomName == sc.Body) &&
                        (body.FullName != sc.StarSystem || (sc.BodyType == "Star" && body.Level == 0) || (sc.BodyType != "Star" && body.Level != 0)))
                    {
                        relatedScan        = body;
                        sc.BodyDesignation = body.FullName;
                        break;
                    }
                }
            }

            // else just try and find any matches
            if (relatedScan == null)
            {
                foreach (var body in sn.Bodies)
                {
                    if ((body.FullName == sc.Body || body.CustomName == sc.Body) &&
                        (body.FullName != sc.StarSystem || (sc.BodyType == "Star" && body.Level == 0) || (sc.BodyType != "Star" && body.Level != 0)))
                    {
                        relatedScan = body;
                        break;
                    }
                }
            }

            if (relatedScan != null && relatedScan.ScanData == null)
            {
                return(true); // We already have the node, with no scan, so reject
            }

            // Extract elements from name
            List <string> elements = ExtractElementsBodyAndID(sc, sys, out bool isbeltcluster, out ScanNodeType starscannodetype);

            // Bail out if no elements extracted
            if (elements.Count == 0)
            {
                System.Diagnostics.Trace.WriteLine($"Failed to add body {sc.Body} to system {sys.Name} - not enough elements");
                return(false);
            }
            // Bail out if more than 5 elements extracted
            else if (elements.Count > 5)
            {
                System.Diagnostics.Trace.WriteLine($"Failed to add body {sc.Body} to system {sys.Name} - too deep");
                return(false);
            }

            // Get custom name if different to designation
            string customname = GetCustomNameBodyAndID(sc, sys);

            // Process elements
            ScanNode node = ProcessElementsBodyAndID(sc, sys, sn, customname, elements, starscannodetype, isbeltcluster);

            if (node.BodyID != null)
            {
                sn.NodesByID[(int)node.BodyID] = node;
            }

            ProcessedSaved();  // any saved JEs due to no scan, add

            return(true);
        }
예제 #11
0
        private ScanNode ProcessElementsBodyAndID(IBodyNameAndID sc, ISystem sys, SystemNode sn, string customname, List <string> elements, ScanNodeType starscannodetype, bool isbeltcluster)
        {
            SortedList <string, ScanNode> currentnodelist = sn.StarNodes;               // current operating node list, always made
            ScanNode previousnode = null;                                               // trails subnode by 1 to point to previous node

            for (int lvl = 0; lvl < elements.Count; lvl++)
            {
                ScanNodeType sublvtype = starscannodetype;

                if (lvl > 0)
                {
                    if (isbeltcluster)
                    {
                        sublvtype = lvl == 1 ? ScanNodeType.belt : ScanNodeType.beltcluster;
                    }
                    else
                    {
                        sublvtype = ScanNodeType.body;
                    }
                }

                if (currentnodelist == null || !currentnodelist.TryGetValue(elements[lvl], out ScanNode subnode))
                {
                    if (currentnodelist == null)    // no node list, happens when we are at least 1 level down as systemnode always has a node list, make one
                    {
                        currentnodelist = previousnode.Children = new SortedList <string, ScanNode>(new DuplicateKeyComparer <string>());
                    }

                    string ownname = elements[lvl];

                    subnode = new ScanNode
                    {
                        OwnName  = ownname,
                        FullName = lvl == 0 ? (sys.Name + (ownname.Contains("Main") ? "" : (" " + ownname))) : previousnode.FullName + " " + ownname,
                        ScanData = null,
                        Children = null,
                        NodeType = sublvtype,
                        Level    = lvl,
                    };

                    currentnodelist.Add(ownname, subnode);
                }

                if (lvl == elements.Count - 1)
                {
                    subnode.CustomName = customname;

                    if (sc.BodyID != null)
                    {
                        subnode.BodyID = sc.BodyID;
                    }

                    if (sc.BodyType == "" || sc.BodyType == "Null" || sc.BodyType == "Barycentre")
                    {
                        subnode.NodeType = ScanNodeType.barycentre;
                    }
                    else if (sc.BodyType == "Belt")
                    {
                        subnode.NodeType = ScanNodeType.belt;
                    }
                }

                previousnode    = subnode;
                currentnodelist = previousnode.Children;
            }

            return(previousnode);
        }