public override bool Load(ConfigNode configNode)
        {
            // Load base class
            bool valid = base.Load(configNode);

            valid &= ConfigNodeUtil.ParseValue <Vessel.Situations>(configNode, "situation", x => situation = x, this, Vessel.Situations.ORBITING, ValidateSituations);
            valid &= ConfigNodeUtil.ParseValue <double>(configNode, "minAltitude", x => minAltitude = x, this, 0.0, x => Validation.GE(x, 0.0));
            valid &= ConfigNodeUtil.ParseValue <double>(configNode, "maxAltitude", x => maxAltitude = x, this, double.MaxValue, x => Validation.GE(x, 0.0));
            valid &= ConfigNodeUtil.ParseValue <double>(configNode, "minApA", x => minApoapsis = x, this, 0.0, x => Validation.GE(x, 0.0));
            valid &= ConfigNodeUtil.ParseValue <double>(configNode, "maxApA", x => maxApoapsis = x, this, double.MaxValue, x => Validation.GE(x, 0.0));
            valid &= ConfigNodeUtil.ParseValue <double>(configNode, "minPeA", x => minPeriapsis = x, this, 0.0, x => Validation.GE(x, 0.0));
            valid &= ConfigNodeUtil.ParseValue <double>(configNode, "maxPeA", x => maxPeriapsis = x, this, double.MaxValue, x => Validation.GE(x, 0.0));
            valid &= ConfigNodeUtil.ParseValue <double>(configNode, "minEccentricity", x => minEccentricity = x, this, 0.0, x => Validation.GE(x, 0.0));
            valid &= ConfigNodeUtil.ParseValue <double>(configNode, "maxEccentricity", x => maxEccentricity = x, this, double.MaxValue, x => Validation.GE(x, 0.0));
            valid &= ConfigNodeUtil.ParseValue <double>(configNode, "minInclination", x => minInclination = x, this, 0.0, x => Validation.Between(x, 0.0, 180.0));
            valid &= ConfigNodeUtil.ParseValue <double>(configNode, "maxInclination", x => maxInclination = x, this, 180.0, x => Validation.Between(x, 0.0, 180.0));
            valid &= ConfigNodeUtil.ParseValue <Duration>(configNode, "minPeriod", x => minPeriod = x, this, new Duration(0.0));
            valid &= ConfigNodeUtil.ParseValue <Duration>(configNode, "maxPeriod", x => maxPeriod = x, this, new Duration(double.MaxValue));

            // Validate target body
            valid &= ValidateTargetBody(configNode);

            // Validation minimum and groupings
            valid &= ConfigNodeUtil.AtLeastOne(configNode, new string[] { "minAltitude", "maxAltitude", "minApA", "maxApA", "minPeA", "maxPeA",
                                                                          "minEccentricity", "maxEccentricity", "minInclination", "maxInclination", "minPeriod", "maxPeriod" }, this);
            valid &= ConfigNodeUtil.MutuallyExclusive(configNode, new string[] { "minAltitude", "maxAltitude" },
                                                      new string[] { "minApA", "maxApA", "minPeA", "maxPeA" }, this);

            return(valid);
        }
        public override bool Load(ConfigNode configNode)
        {
            // Load base class
            bool valid = base.Load(configNode);

            valid &= ConfigNodeUtil.ParseValue <string>(configNode, "trait", x => trait = x, this, (string)null);
            valid &= ConfigNodeUtil.ParseValue <int>(configNode, "minExperience", x => minExperience = x, this, 0, x => Validation.Between(x, 0, 5));
            valid &= ConfigNodeUtil.ParseValue <int>(configNode, "maxExperience", x => maxExperience = x, this, 5, x => Validation.Between(x, 0, 5));
            valid &= ConfigNodeUtil.ParseValue <int>(configNode, "minCrew", x => minCrew = x, this, 1, x => Validation.GE(x, 0));
            valid &= ConfigNodeUtil.ParseValue <int>(configNode, "maxCrew", x => maxCrew = x, this, int.MaxValue, x => Validation.GE(x, minCrew));

            valid &= ConfigNodeUtil.ParseValue <List <Kerbal> >(configNode, "kerbal", x => kerbal = x, this, new List <Kerbal>());

            valid &= ConfigNodeUtil.AtLeastOne(configNode, new string[] { "trait", "minExperience", "maxExperience", "minCrew", "maxCrew", "kerbal" }, this);
            valid &= ConfigNodeUtil.MutuallyExclusive(configNode, new string[] { "trait", "minExperience", "maxExperience", "minCrew", "maxCrew" },
                                                      new string[] { "kerbal" }, this);

            return(valid);
        }
        public override bool Load(ConfigNode configNode)
        {
            // Load base class
            bool valid = base.Load(configNode);

            valid &= ConfigNodeUtil.ParseValue <double>(configNode, "minAltitude", ref minAltitude, this, 0.0, x => Validation.GE(x, 0.0));
            valid &= ConfigNodeUtil.ParseValue <double>(configNode, "maxAltitude", ref maxAltitude, this, double.MaxValue, x => Validation.GE(x, 0.0));
            valid &= ConfigNodeUtil.ParseValue <double>(configNode, "minApA", ref minApoapsis, this, 0.0, x => Validation.GE(x, 0.0));
            valid &= ConfigNodeUtil.ParseValue <double>(configNode, "maxApA", ref maxApoapsis, this, double.MaxValue, x => Validation.GE(x, 0.0));
            valid &= ConfigNodeUtil.ParseValue <double>(configNode, "minPeA", ref minPeriapsis, this, 0.0, x => Validation.GE(x, 0.0));
            valid &= ConfigNodeUtil.ParseValue <double>(configNode, "maxPeA", ref maxPeriapsis, this, double.MaxValue, x => Validation.GE(x, 0.0));
            valid &= ConfigNodeUtil.ParseValue <double>(configNode, "minEccentricity", ref minEccentricity, this, 0.0, x => Validation.GE(x, 0.0));
            valid &= ConfigNodeUtil.ParseValue <double>(configNode, "maxEccentricity", ref maxEccentricity, this, double.MaxValue, x => Validation.GE(x, 0.0));
            valid &= ConfigNodeUtil.ParseValue <double>(configNode, "minInclination", ref minInclination, this, 0.0, x => Validation.Between(x, 0.0, 180.0));
            valid &= ConfigNodeUtil.ParseValue <double>(configNode, "maxInclination", ref maxInclination, this, 180.0, x => Validation.Between(x, 0.0, 180.0));

            // Get minPeriod
            string minPeriodStr = null;

            valid    &= ConfigNodeUtil.ParseValue <string>(configNode, "minPeriod", ref minPeriodStr, this, (string)null);
            minPeriod = minPeriodStr != null?DurationUtil.ParseDuration(minPeriodStr) : 0.0;

            // Get maxPeriod
            string maxPeriodStr = null;

            valid &= ConfigNodeUtil.ParseValue <string>(configNode, "maxPeriod", ref maxPeriodStr, this, (string)null);
            if (maxPeriodStr != null)
            {
                maxPeriod = DurationUtil.ParseDuration(maxPeriodStr);
            }
            maxPeriod = maxPeriodStr != null?DurationUtil.ParseDuration(maxPeriodStr) : double.MaxValue;

            // Validate target body
            valid &= ValidateTargetBody(configNode);

            // Validation minimum and groupings
            valid &= ConfigNodeUtil.AtLeastOne(configNode, new string[] { "minAltitude", "maxAltitude", "minApA", "maxApA", "minPeA", "maxPeA",
                                                                          "minEccentricity", "maxEccentricity", "minInclination", "maxInclination", "minPeriod", "maxPeriod" }, this);
            valid &= ConfigNodeUtil.MutuallyExclusive(configNode, new string[] { "minAltitude", "maxAltitude" },
                                                      new string[] { "minApA", "maxApA", "minPeA", "maxPeA" }, this);

            return(valid);
        }
        public override bool LoadFromConfig(ConfigNode configNode)
        {
            // Before loading, verify the SCANsat version
            if (!SCANsatUtil.VerifySCANsatVersion())
            {
                return(false);
            }

            // Load base class
            bool valid = base.LoadFromConfig(configNode);

            // Do not check the requirement on active contracts.  Otherwise when they scan the
            // contract is invalidated, which is usually not what's meant.
            checkOnActiveContract = false;

            valid &= ConfigNodeUtil.ParseValue <string>(configNode, "scanType", x => scanType = x, this, "Anomaly", SCANsatUtil.ValidateSCANname);
            valid &= ConfigNodeUtil.ParseValue <double>(configNode, "latitude", x => latitude = x, this, 0.0);
            valid &= ConfigNodeUtil.ParseValue <double>(configNode, "longitude", x => longitude = x, this, 0.0);

            valid &= ConfigNodeUtil.MutuallyExclusive(configNode, new string[] { "latitude", "longitude" }, new string[] { "pqsCity" }, this);
            valid &= ValidateTargetBody(configNode);

            string pqsName = null;

            valid &= ConfigNodeUtil.ParseValue <string>(configNode, "pqsCity", x => pqsName = x, this, (string)null);
            if (pqsName != null)
            {
                try
                {
                    pqsCity = targetBody.GetComponentsInChildren <PQSCity>(true).Where(pqs => pqs.name == pqsName).First();
                }
                catch (Exception e)
                {
                    LoggingUtil.LogError(this, "Couldn't load PQSCity with name '" + pqsCity + "'");
                    LoggingUtil.LogException(e);
                    valid = false;
                }
            }

            return(valid);
        }
        public override bool Load(ConfigNode configNode)
        {
            // Load base class
            bool valid = base.Load(configNode);

            valid &= ConfigNodeUtil.ParseValue <Biome>(configNode, "biome", x => biome = x, this, (Biome)null);
            valid &= ConfigNodeUtil.ParseValue <ExperimentSituations?>(configNode, "situation", x => situation = x, this, (ExperimentSituations?)null);
            valid &= ConfigNodeUtil.ParseValue <BodyLocation?>(configNode, "location", x => location = x, this, (BodyLocation?)null);
            valid &= ConfigNodeUtil.ParseValue <List <ScienceExperiment> >(configNode, "experiment", x => experiment = x, this, new List <ScienceExperiment>(), x =>
                                                                           x.All(Validation.NotNull <ScienceExperiment>));
            valid &= ConfigNodeUtil.ParseValue <ScienceRecoveryMethod>(configNode, "recoveryMethod", x => recoveryMethod = x, this, ScienceRecoveryMethod.None);

            valid &= ConfigNodeUtil.ParseValue <List <ScienceSubject> >(configNode, "subject", x => subjects = x, this, new List <ScienceSubject>());

            valid &= ConfigNodeUtil.MutuallyExclusive(configNode, new string[] { "subject" }, new string[] { "biome", "situation", "location", "experiment" }, this);

            // Validate subjects
            if (subjects != null && subjects.Count > 1)
            {
                Biome b = Util.Science.GetBiome(subjects[0]);
                ExperimentSituations es = Util.Science.GetSituation(subjects[0]);

                if (subjects.Any(s => !Util.Science.GetBiome(s).Equals(b)))
                {
                    LoggingUtil.LogError(this, ErrorPrefix(configNode) + ": When using 'subject', the subjects must all have the same biome.");
                    valid = false;
                }
                if (subjects.Any(s => !Util.Science.GetSituation(s).Equals(es)))
                {
                    LoggingUtil.LogError(this, ErrorPrefix(configNode) + ": When using 'subject', the subjects must all have the same experiment situation.");
                    valid = false;
                }
            }

            return(valid);
        }