public bool AddBodiesTo(Landing ss, string bodies)
        {
            ss.bodies     = GetAllbodies(bodies);
            ss.bodiesHash = new HashSet <string>(ss.bodies);

            return(ss.bodies.Count > 0);
        }
        void GetAllLandings(ConfigNode achievements)
        {
            foreach (var node in achievements.GetNodes("LANDING"))
            {
                string key = "", title = "", text = "", bodies = "";

                if (node.TryGetValue("key", ref key) &&
                    node.TryGetValue("title", ref title) &&
                    node.TryGetValue("text", ref text) &&
                    node.TryGetValue("bodies", ref bodies))
                {
                    Landing ss = new Landing(key, title, text);
                    if (AddBodiesTo(ss, bodies))
                    {
                        string b = "any";
                        node.TryGetValue("bodyRequirement", ref b);
                        if (b != "")
                        {
                            ss.requireAll = (b.ToLower() == "all");
                            ss.individual = (b.ToLower() == "individual");
                        }
                        b = "false";
                        node.TryGetValue("splash", ref b);
                        if (b != "")
                        {
                            bool.TryParse(b, out ss.splash);
                        }

                        b = "false";
                        node.TryGetValue("stableOrbit", ref b);
                        if (b != "")
                        {
                            bool.TryParse(b, out ss.stableOrbit);
                        }
                        b = "-1";
                        node.TryGetValue("minAltitude", ref b);
                        if (b != "")
                        {
                            double.TryParse(b, out ss.minAltitude);
                        }

                        b = "-1";
                        node.TryGetValue("maxDegreesLatitudeFromEquator", ref b);
                        if (b != "")
                        {
                            double.TryParse(b, out ss.maxDegreesLatitudeFromEquator);
                        }

                        string locations = "";
                        if (node.TryGetValue("locations", ref locations))
                        {
                            List <string> list = locations.Split(charSeparators, StringSplitOptions.RemoveEmptyEntries).ToList();
                            foreach (var l in list)
                            {
                                if (allLocations.ContainsKey(l))
                                {
                                    ss.locations.Add(allLocations[l]);
                                }
                                else
                                {
                                    Log.Error("Missing location: " + l);
                                }
                            }
                        }
                        allLandings.Add(key, ss);
                    }
                }
            }
        }
        internal void LoadCfgAchievements()
        {
            AddPredefined();
            var achievements = GameDatabase.Instance.GetConfigNodes("ACHIEVEMENTS");

            //List<Achievement> loadedAchievements = new List<Achievement>();
            List <Achievement> loadedSurfaceSampleAchievements = new List <Achievement>();
            List <Achievement> loadedOrbitAchievements         = new List <Achievement>();
            List <Achievement> loadedLandingAchievements       = new List <Achievement>();

            foreach (var achievementGroup in achievements)
            {
                GetAllBodies(achievementGroup);
                GetAllSurfaceSamples(achievementGroup);
                GetAllOrbitAchievements(achievementGroup);
                GetAllLocations(achievementGroup);
                GetAllLandings(achievementGroup);
                //GetAllEVAs(achievementGroup);


#if false
                Log.Info("Allbodies dump=================================================");
                foreach (var b in AllBodies)
                {
                    Log.Info(b.ToString());
                }

                Log.Info("allSurfaceSamples dump=================================================");
#endif

                foreach (var a in allSurfaceSamples)
                {
                    var ass = a.Value;
                    Log.Info(a.ToString());
                    if (ass.individual)
                    {
                        foreach (var f in ass.bodies)
                        {
                            if (Body.allBodiesDict.ContainsKey(f))
                            {
                                var         body = Body.allBodiesDict[f];
                                List <Body> l    = new List <Body>();
                                l.Add(body);
                                loadedSurfaceSampleAchievements.Add(
                                    new AllBodiesSurfaceSample(l,
                                                               BodyReplacement(ass.title, body.name),
                                                               BodyReplacement(ass.text, body.name),
                                                               ass.key + "." + body.name).addon());
                            }
                        }
                    }
                    if (ass.requireAll)
                    {
                    }
                    if (!ass.individual && !ass.requireAll)
                    {
                        var f = flatten(ass.bodies);
                        loadedSurfaceSampleAchievements.Add(
                            new AllBodiesSurfaceSample(f,
                                                       ass.title,
                                                       ass.text,
                                                       ass.key + ".all").addon());
                    }
                }


#if false
                Log.Info("allOrbitAchievements dump=================================================");
#endif
                foreach (var a in allOrbitAchievements)
                {
                    //Log.Info(a.ToString());

                    OrbitAchievement aoa = a.Value;
                    if (aoa.individual)
                    {
                        Log.Info("OrbitAchievement, key: " + a.Key);
                        foreach (string f in aoa.bodies)
                        {
                            Log.Info("OrbitAchievement, key: " + a.Key + ", body: " + f);
                            if (Body.allBodiesDict.ContainsKey(f))
                            {
                                var         body       = Body.allBodiesDict[f];
                                List <Body> bodiesList = new List <Body>();

                                bodiesList.Add(body);
                                Log.Info("Adding existing body to allOrbitAchievements: " + body.name);
                                loadedOrbitAchievements.Add(
                                    new SpecifiedOrbitAchievement(
                                        bodiesList,
                                        BodyReplacement(aoa.title, body.name),
                                        BodyReplacement(aoa.text, body.name),
                                        aoa.minAltitude,
                                        aoa.maxAltitude,
                                        aoa.minEccentricity,
                                        aoa.maxEccentricity,
                                        aoa.minInclination,
                                        aoa.maxInclination));
                            }
                        }
                    }
                    if (aoa.requireAll)
                    {
                    }
                    if (!aoa.individual && !aoa.requireAll)
                    {
                        IEnumerable <Body> bodiesIenumerable = flatten(aoa.bodies);
                        loadedOrbitAchievements.Add(
                            new
                            SpecifiedOrbitAchievement(
                                bodiesIenumerable,
                                aoa.title,
                                aoa.text,
                                aoa.minAltitude,
                                aoa.maxAltitude,
                                aoa.minEccentricity,
                                aoa.maxEccentricity,
                                aoa.minInclination,
                                aoa.maxInclination));
                    }
                }
#if false
                Log.Info("allLocations dump=================================================");
                foreach (var l in allLocations)
                {
                    Log.Info(l.ToString());
                }
                Log.Info("allLandings dump=================================================");
#endif
                foreach (var l in allLandings)
                {
                    Log.Info(l.Value.ToString());
                    Landing landing = l.Value;
#if false
                    foreach (CfgLocation ll in al.locations)
                    {
                        Log.Info("BodyLanding.location: " + ll.ToString());
                    }
#endif
                    if (landing.locations.Count > 0)
                    {
                        loadedLandingAchievements.Add(new BodyLanding(Body.allBodiesDict[landing.bodies.First()], landing.splash, landing.stableOrbit, landing.minAltitude, landing.maxDegreesLatitudeFromEquator,
                                                                      CfgLocationsToLocations(landing.locations), landing.title, landing.text, landing.key));
                    }
                    else
                    {
                        foreach (var b in landing.bodies)
                        {
                            //loadedLandingAchievements.Add(new BodyLanding(Body.allBodiesDict[b], al.splash, al.title));

                            loadedLandingAchievements.Add(new BodyLanding(Body.allBodiesDict[b], landing.splash,
                                                                          landing.stableOrbit, landing.minAltitude, landing.maxDegreesLatitudeFromEquator,
                                                                          new Location[0],
                                                                          BodyReplacement(landing.title, b),
                                                                          BodyReplacement(landing.text, b),
                                                                          landing.key + "." + b));
                        }
                    }
                }
#if false
                Log.Info("End dump=================================================");
#endif
            }
            Log.Info("Total new body achievements loaded from cfg: " + loadedSurfaceSampleAchievements.Count());
            Log.Info("Total new orbit achievements loaded from cfg: " + loadedOrbitAchievements.Count());
            Log.Info("Total new landing achievements loaded from cfg: " + loadedLandingAchievements.Count());

            var achievementList = (List <Achievement>)EarnedAchievements.instance.achievements[Category.RESEARCH_AND_DEVELOPMENT];
            achievementList.AddRange(loadedSurfaceSampleAchievements);

            achievementList = (List <Achievement>)EarnedAchievements.instance.achievements[Category.SPACEFLIGHT];
            achievementList.AddRange(loadedOrbitAchievements);

            achievementList = (List <Achievement>)EarnedAchievements.instance.achievements[Category.LANDING];
            achievementList.AddRange(loadedLandingAchievements);

            EarnedAchievements.instance.achievementsList.AddRange(loadedSurfaceSampleAchievements);
            EarnedAchievements.instance.achievementsList.AddRange(loadedOrbitAchievements);
            EarnedAchievements.instance.achievementsList.AddRange(loadedLandingAchievements);
        }