public bool AddBodiesTo(OrbitAchievement ss, string bodies)
 {
     ss.bodies     = GetAllbodies(bodies);
     ss.bodiesHash = ss.bodiesHash = new HashSet <string>(ss.bodies);
     Log.Info("AddBodiesTo: " + string.Join(", ", ss.bodies));
     return(ss.bodies.Count > 0);
 }
        void GetAllOrbitAchievements(ConfigNode achievements)
        {
            foreach (var node in achievements.GetNodes("ORBITACHIEVEMENT"))
            {
                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))
                {
                    OrbitAchievement ss = new OrbitAchievement(key, title, text);
                    Log.Info("GetAllOrbitAchievements, bodies: " + bodies);
                    if (AddBodiesTo(ss, bodies))
                    {
                        string b = "any";
                        node.TryGetValue("bodyRequirement", ref b);
                        if (b != "")
                        {
                            ss.requireAll = (b.ToLower() == "all");
                            ss.individual = (b.ToLower() == "individual");
                        }
                        if (node.HasValue("minAltitude"))
                        {
                            double.TryParse(node.GetValue("minAltitude"), out ss.minAltitude);
                            ss.minAltitude = Math.Max(ss.minAltitude, -1);
                        }

                        if (node.HasValue("maxAltitude"))
                        {
                            double.TryParse(node.GetValue("maxAltitude"), out ss.maxAltitude);
                            ss.maxAltitude = Math.Max(ss.maxAltitude, -1);
                        }

                        if (node.HasValue("minEccentricity"))
                        {
                            double.TryParse(node.GetValue("minEccentricity"), out ss.minEccentricity);
                            ss.minEccentricity = Math.Min(Math.Max(ss.minEccentricity, 0), MAX_ECCENTRICITY);
                        }

                        if (node.HasValue("maxEccentricity"))
                        {
                            double.TryParse(node.GetValue("maxEccentricity"), out ss.maxEccentricity);
                            ss.maxEccentricity = Math.Max(Math.Min(ss.maxEccentricity, MAX_ECCENTRICITY), 0);
                        }

                        if (node.HasValue("minInclination"))
                        {
                            double.TryParse(node.GetValue("minInclination"), out ss.minInclination);
                            ss.minInclination = Math.Min(Math.Max(ss.minInclination, 0), 90);
                        }

                        if (node.HasValue("maxInclination"))
                        {
                            double.TryParse(node.GetValue("maxInclination"), out ss.maxInclination);
                            ss.maxInclination = Math.Max(Math.Min(ss.maxInclination, 90), 0);
                        }

                        allOrbitAchievements.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);
        }