Esempio n. 1
0
        public Allegiance GetAllegianceFromCode(string code)
        {
            // TODO: Consider hashtable
            Allegiance alleg = Allegiances.Where(a => a.T5Code == code).FirstOrDefault();

            return(alleg ?? SecondSurvey.GetStockAllegianceFromCode(code));
        }
Esempio n. 2
0
        internal void Validate(ErrorLogger errors, int lineNumber, string line)
        {
            if (UWP == "???????-?")
            {
                return;
            }

            Action <string>       Error   = (string message) => { errors.Error(message, lineNumber, line); };
            Action <bool, string> ErrorIf = (bool test, string message) => { if (test)
                                                                             {
                                                                                 Error(message);
                                                                             }
            };
            Action <bool, string> ErrorUnless = (bool test, string message) => { if (!test)
                                                                                 {
                                                                                     Error(message);
                                                                                 }
            };
            Func <int, string, bool> Check = (int value, string hex) =>
            {
                for (int i = 0; i < hex.Length; ++i)
                {
                    if (value == SecondSurvey.FromHex(hex[i]))
                    {
                        return(true);
                    }
                }
                return(false);
            };

            Func <string, bool, bool> CC = (string code, bool calc) =>
            {
                if (calc)
                {
                    ErrorUnless(HasCode(code), $"Missing code: {code}");
                }
                else
                {
                    ErrorUnless(!HasCode(code), $"Extraneous code: {code}");
                }
                return(calc);
            };

#if VALIDATE_UWP
            // UWP
            ErrorIf(Atmosphere > 15, $"UWP: Atm>F: {Atmosphere}");
            ErrorIf(Hydrographics > 10, $"UWP: Hyd>A: {Hydrographics}");
            ErrorIf(PopulationExponent > 15, $"UWP: Pop>F: {PopulationExponent}");
            ErrorUnless(Util.InRange(Government, PopulationExponent - 5, Math.Max(15, PopulationExponent + 5)),
                        $"UWP: Gov={Government} out of range (Pop={PopulationExponent} + Flux)");
            ErrorUnless(Util.InRange(Law, Government - 5, Math.Max(18, Government + 5)),
                        $"UWP: Law={Law} out of range (Gov={Government} + Flux)");
            int tlmod =
                (Starport == 'A' ? 6 : 0) + (Starport == 'B' ? 4 : 0) + (Starport == 'C' ? 2 : 0) + (Starport == 'X' ? -4 : 0) +
                (Size == 0 || Size == 1 ? 2 : 0) + (Size == 2 || Size == 3 || Size == 4 ? 1 : 0) +
                (Atmosphere <= 3 ? 1 : 0) + (Atmosphere >= 10 ? 1 : 0) +
                (Hydrographics == 9 ? 1 : 0) + (Hydrographics == 10 ? 2 : 0) +
                (Util.InRange(PopulationExponent, 1, 5) ? 1 : 0) + (PopulationExponent == 9 ? 2 : 0) + (PopulationExponent >= 10 ? 4 : 0) +
                (Government == 0 || Government == 5 ? 1 : 0) + (Government == 13 ? -2 : 0);
            ErrorUnless(Util.InRange(TechLevel, tlmod + 1, tlmod + 6),
                        $"UWP: TL={TechLevel} out of range (mods={tlmod} + 1D)");
#endif

            // Planetary
            bool As = CC("As", Check(Size, "0") /*&& Check(Atmosphere, "0") && Check(Hydrographics, "0")*/);
            bool De = CC("De", Check(Atmosphere, "23456789") && Check(Hydrographics, "0"));
            bool Fl = CC("Fl", Check(Atmosphere, "ABC") && Check(Hydrographics, "123456789A"));
            bool Ga = CC("Ga", Check(Size, "678") && Check(Atmosphere, "568") && Check(Hydrographics, "567"));
            bool He = CC("He", Check(Size, "3456789A" /* + "BC" */) && Check(Atmosphere, "2479ABC") && Check(Hydrographics, "012")); // TODO: Add BC to T5SS spreadsheet calcs
            bool Ic = CC("Ic", Check(Atmosphere, "01") && Check(Hydrographics, "123456789A"));
            bool Oc = CC("Oc", Check(Size, "ABC") && Check(Atmosphere, "3456789") && Check(Hydrographics, "A"));
            bool Va = CC("Va", Check(Atmosphere, "0"));
            bool Wa = CC("Wa", Check(Size, "3456789") && Check(Atmosphere, "3456789") && Check(Hydrographics, "A"));

            // Population
            bool Di = CC("Di", PopulationExponent == 0 /*&& Government == 0 && Law == 0*/ && TechLevel > 0);
            bool Ba = CC("Ba", PopulationExponent == 0 /*&& Government == 0 && Law == 0*/ && TechLevel == 0);
            bool Lo = CC("Lo", Check(PopulationExponent, "123"));
            bool Ni = CC("Ni", Check(PopulationExponent, "456"));
            bool Ph = CC("Ph", Check(PopulationExponent, "8"));
            bool Hi = CC("Hi", Check(PopulationExponent, "9ABCDEF"));

            // Economic
            bool Pa = CC("Pa", Check(Atmosphere, "456789") && Check(Hydrographics, "45678") && Check(PopulationExponent, "48"));
            bool Ag = CC("Ag", Check(Atmosphere, "456789") && Check(Hydrographics, "45678") && Check(PopulationExponent, "567"));
            bool Na = CC("Na", Check(Atmosphere, "0123") && Check(Hydrographics, "0123") && Check(PopulationExponent, "6789ABCDEF"));
            bool Pi = CC("Pi", Check(Atmosphere, "012479") && Check(PopulationExponent, "78"));
            bool In = CC("In", Check(Atmosphere, "012479ABC") && Check(PopulationExponent, "9ABCDEF"));
            bool Po = CC("Po", Check(Atmosphere, "2345") && Check(Hydrographics, "0123"));
            bool Pr = CC("Pr", Check(Atmosphere, "68") && Check(PopulationExponent, "59"));
            bool Ri = CC("Ri", Check(Atmosphere, "68") && Check(PopulationExponent, "678"));

            // {Ix}
            int imp = 0;
            {
                string ix = Importance.Replace('{', ' ').Replace('}', ' ').Trim();

                if ("AB".Contains(Starport))
                {
                    ++imp;
                }
                if ("DEX".Contains(Starport))
                {
                    --imp;
                }
                if (TechLevel >= 10)
                {
                    ++imp;
                }
                //if (TechLevel >= 16) ++imp; // TODO: Add to T5SS spreadsheet calcs
                if (TechLevel <= 8)
                {
                    --imp;
                }
                if (PopulationExponent <= 6)
                {
                    --imp;
                }
                if (PopulationExponent >= 9)
                {
                    ++imp;
                }
                if (Ag)
                {
                    ++imp;
                }
                if (Ri)
                {
                    ++imp;
                }
                if (In)
                {
                    ++imp;
                }
                if (Bases == "NS" || Bases == "NW" || Bases == "W" || Bases == "X" || Bases == "D" || Bases == "RT" || Bases == "CK" || Bases == "KM")
                {
                    ++imp;
                }

                ErrorUnless(Int32.Parse(ix) == imp,
                            $"{{Ix}}={Importance} does not match calculated Importance={imp}");
            }

            // (Ex)
            {
                string ex             = Economic.Replace('(', ' ').Replace(')', ' ').Trim();
                int    resources      = SecondSurvey.FromHex(ex[0]);
                int    labor          = SecondSurvey.FromHex(ex[1]);
                int    infrastructure = SecondSurvey.FromHex(ex[2]);
                int    efficiency     = Int32.Parse(ex.Substring(3));

                if (TechLevel < 8)
                {
                    ErrorUnless(Util.InRange(resources, 2, 12),
                                $"(Ex) Resources={resources} out of range for TL<8={TechLevel} (2D)");
                }
                else
                {
                    ErrorUnless(Util.InRange(resources, 2 + GasGiants + Belts, 12 + GasGiants + Belts),
                                $"(Ex) Resources={resources} out of range for TL8+={TechLevel} (2D + GG={GasGiants} + Belts={Belts})");
                }

                ErrorUnless(labor == Math.Max(0, PopulationExponent - 1),
                            $"(Ex) Labor={labor} does not match Pop={PopulationExponent} - 1");

                if (Ba)
                {
                    ErrorUnless(infrastructure == 0, $"(Ex) Infrastructure={infrastructure} should be 0 if Ba");
                }
                else if (Lo)
                {
                    ErrorUnless(infrastructure == 1, $"(Ex) Infrastructure={infrastructure} should be 1 if Lo");
                }
                else if (Ni)
                {
                    ErrorUnless(Util.InRange(infrastructure, Math.Max(0, imp + 1), Math.Max(0, imp + 6)),
                                $"(Ex) Infrastructure={infrastructure} out of range for Ni (Imp={imp} + 1D)");
                }
                else
                {
                    ErrorUnless(Util.InRange(infrastructure, Math.Max(0, imp + 2), Math.Max(0, imp + 12)),
                                $"(Ex) Infrastructure={infrastructure} out of range (Imp={imp} + 2D)");
                }

                ErrorUnless(Util.InRange(efficiency, -5, 5),
                            $"(Ex) Efficiency={efficiency} out of range (Flux)");
            }

            // [Cx]
            {
                string cx          = Cultural.Replace('[', ' ').Replace(']', ' ').Trim();
                int    homogeneity = SecondSurvey.FromHex(cx[0]);
                int    acceptance  = SecondSurvey.FromHex(cx[1]);
                int    strangeness = SecondSurvey.FromHex(cx[2]);
                int    symbols     = SecondSurvey.FromHex(cx[3]);

                if (PopulationExponent == 0)
                {
                    if (homogeneity != 0)
                    {
                        Error($"[Cx] Homogeneity={homogeneity} - expected 0 for Pop 0");
                    }
                    if (acceptance != 0)
                    {
                        Error($"[Cx] Acceptance={acceptance} - expected 0 for Pop 0");
                    }
                    if (strangeness != 0)
                    {
                        Error($"[Cx] Strangeness={strangeness} - expected 0 for Pop 0");
                    }
                    if (symbols != 0)
                    {
                        Error($"[Cx] Symbols={symbols} - expected 0 for Pop 0");
                    }
                }
                else
                {
                    ErrorUnless(Util.InRange(homogeneity, Math.Max(1, PopulationExponent - 5), Math.Max(1, PopulationExponent + 5)),
                                $"[Cx] Homogeneity={homogeneity} out of range (Pop={PopulationExponent} + Flux)");
                    ErrorUnless(acceptance == Math.Max(1, PopulationExponent + imp),
                                $"[Cx] Acceptance={acceptance} not equal Pop={PopulationExponent} + Imp={imp}");
                    ErrorUnless(Util.InRange(strangeness, Math.Max(1, 5 - 5), Math.Max(1, 5 + 5)),
                                $"[Cx] Strangeness={strangeness} out of range (Flux + 5)");
                    ErrorUnless(Util.InRange(symbols, Math.Max(1, TechLevel - 5), Math.Max(1, TechLevel + 5)),
                                $"[Cx] Symbols={symbols} out of range (TL={TechLevel} + Flux)");
                }
            }

            // Ownership
            if (Government == 6 && !(HasCodePrefix("O:") || HasCodePrefix("Mr") || HasCode("Re") || HasCode("Px")))
            {
                errors.Warning("Gov 6 missing O:/Mr/Re/Px", lineNumber, line);
            }
        }
Esempio n. 3
0
        internal void Serialize(ResourceManager resourceManager, TextWriter writer, string mediaType, bool includeMetadata = true, bool includeHeader = true, bool sscoords = false, WorldFilter filter = null)
        {
            WorldCollection worlds = GetWorlds(resourceManager);

            // TODO: less hacky T5 support
            bool isT5 = (mediaType == "TabDelimited" || mediaType == "SecondSurvey");

            if (mediaType == "TabDelimited")
            {
                if (worlds != null)
                {
                    worlds.Serialize(writer, mediaType, includeHeader: includeHeader, filter: filter);
                }
                return;
            }

            if (includeMetadata)
            {
                // Header
                //
                writer.WriteLine("# Generated by http://travellermap.com");
                writer.WriteLine("# " + DateTime.Now.ToString("yyyy-MM-ddTHH:mm:sszzz", DateTimeFormatInfo.InvariantInfo));
                writer.WriteLine();

                writer.WriteLine("# {0}", Names[0]);
                writer.WriteLine("# {0},{1}", X, Y);

                writer.WriteLine();
                foreach (var name in Names)
                {
                    if (name.Lang != null)
                    {
                        writer.WriteLine("# Name: {0} ({1})", name.Text, name.Lang);
                    }
                    else
                    {
                        writer.WriteLine("# Name: {0}", name);
                    }
                }

                if (Credits != null)
                {
                    string stripped = Regex.Replace(Credits, "<.*?>", "");
                    stripped = Regex.Replace(stripped, @"\s+", " ");
                    stripped = stripped.Trim();
                    writer.WriteLine();
                    writer.WriteLine("# Credits: {0}", stripped);
                }

                if (DataFile != null)
                {
                    writer.WriteLine();
                    if (DataFile.Milieu != null)
                    {
                        writer.WriteLine("# Milieu: {0}", DataFile.Milieu);
                    }
                    writer.WriteLine();

                    if (DataFile.Author != null)
                    {
                        writer.WriteLine("# Author:    {0}", DataFile.Author);
                    }
                    if (DataFile.Publisher != null)
                    {
                        writer.WriteLine("# Publisher: {0}", DataFile.Publisher);
                    }
                    if (DataFile.Copyright != null)
                    {
                        writer.WriteLine("# Copyright: {0}", DataFile.Copyright);
                    }
                    if (DataFile.Source != null)
                    {
                        writer.WriteLine("# Source:    {0}", DataFile.Source);
                    }
                    if (DataFile.Ref != null)
                    {
                        writer.WriteLine("# Ref:       {0}", DataFile.Ref);
                    }
                }

                writer.WriteLine();
                for (int i = 0; i < 16; ++i)
                {
                    char      c  = (char)('A' + i);
                    Subsector ss = Subsector(c);
                    writer.WriteLine("# Subsector {0}: {1}", c, ss?.Name ?? "");
                }
                writer.WriteLine();
            }

            if (worlds == null)
            {
                if (includeMetadata)
                {
                    writer.WriteLine("# No world data available");
                }
                return;
            }

            // Allegiances
            if (includeMetadata)
            {
                // Use codes as present in the data, to match the worlds
                foreach (string code in worlds.AllegianceCodes().OrderBy(s => s))
                {
                    var alleg = GetAllegianceFromCode(code);
                    if (alleg != null)
                    {
                        writer.WriteLine("# Alleg: {0}: \"{1}\"", isT5 ? code : SecondSurvey.T5AllegianceCodeToLegacyCode(code), alleg.Name);
                    }
                }
                writer.WriteLine();
            }

            // Worlds
            worlds.Serialize(writer, mediaType, includeHeader: includeHeader, sscoords: sscoords, filter: filter);
        }
Esempio n. 4
0
        internal void Serialize(ResourceManager resourceManager, TextWriter writer, string mediaType, SectorSerializeOptions options)
        {
            WorldCollection worlds = GetWorlds(resourceManager);

            // TODO: less hacky T5 support
            bool isT5 = (mediaType == "TabDelimited" || mediaType == "SecondSurvey");

            if (mediaType == "TabDelimited")
            {
                worlds?.Serialize(writer, mediaType, options);
                return;
            }

            if (options.includeMetadata)
            {
                // Header
                //
                writer.WriteLine("# Generated by https://travellermap.com");
                writer.WriteLine("# " + DateTime.Now.ToString("yyyy-MM-ddTHH:mm:sszzz", DateTimeFormatInfo.InvariantInfo));
                writer.WriteLine();

                writer.WriteLine($"# {Names[0]}");
                writer.WriteLine($"# {X},{Y}");

                writer.WriteLine();
                foreach (var name in Names)
                {
                    if (name.Lang != null)
                    {
                        writer.WriteLine($"# Name: {name.Text} ({name.Lang})");
                    }
                    else
                    {
                        writer.WriteLine($"# Name: {name}");
                    }
                }

                writer.WriteLine();
                writer.WriteLine($"# Milieu: {CanonicalMilieu}");

                if (Credits != null)
                {
                    string stripped = Regex.Replace(Credits, "<.*?>", "");
                    stripped = Regex.Replace(stripped, @"\s+", " ");
                    stripped = stripped.Trim();
                    writer.WriteLine();
                    writer.WriteLine($"# Credits: {stripped}");
                }

                if (DataFile != null)
                {
                    writer.WriteLine();
                    if (DataFile.Author != null)
                    {
                        writer.WriteLine($"# Author:    {DataFile.Author}");
                    }
                    if (DataFile.Publisher != null)
                    {
                        writer.WriteLine($"# Publisher: {DataFile.Publisher}");
                    }
                    if (DataFile.Copyright != null)
                    {
                        writer.WriteLine($"# Copyright: {DataFile.Copyright}");
                    }
                    if (DataFile.Source != null)
                    {
                        writer.WriteLine($"# Source:    {DataFile.Source}");
                    }
                    if (DataFile.Ref != null)
                    {
                        writer.WriteLine($"# Ref:       {DataFile.Ref}");
                    }
                }

                writer.WriteLine();
                for (int i = 0; i < 16; ++i)
                {
                    char      c  = (char)('A' + i);
                    Subsector ss = Subsector(c);
                    writer.WriteLine($"# Subsector {c}: {ss?.Name ?? ""}");
                }
                writer.WriteLine();
            }

            if (worlds == null)
            {
                if (options.includeMetadata)
                {
                    writer.WriteLine("# No world data available");
                }
                return;
            }

            // Allegiances
            if (options.includeMetadata)
            {
                // Use codes as present in the data, to match the worlds
                foreach (string code in worlds.AllegianceCodes().OrderBy(s => s))
                {
                    var alleg = GetAllegianceFromCode(code);
                    if (alleg != null)
                    {
                        var a = isT5 ? code : SecondSurvey.T5AllegianceCodeToLegacyCode(code);
                        writer.WriteLine($"# Alleg: {a}: \"{alleg.Name}\"");
                    }
                }
                writer.WriteLine();
            }

            // Worlds
            worlds.Serialize(writer, mediaType, options);
        }