protected override bool Generate()
        {
            DMAnomalyContract[] anomContracts = ContractSystem.Instance.GetCurrentContracts<DMAnomalyContract>();
            int offers = 0;
            int active = 0;
            int maxOffers = DMUtils.maxAnomalyOffered;
            int maxActive = DMUtils.maxAnomalyActive;

            for (int i = 0; i < anomContracts.Length; i++ )
            {
                DMAnomalyContract a = anomContracts[i];
                if (a.ContractState == State.Offered)
                    offers++;
                else if (a.ContractState == State.Active)
                    active++;
            }

            if (offers >= maxOffers)
                return false;
            if (active >= maxActive)
                return false;

            //Make sure that the anomaly scanner is available
            AvailablePart aPart = PartLoader.getPartInfoByName("dmAnomScanner");
            if (aPart == null)
                return false;
            if (!ResearchAndDevelopment.PartModelPurchased(aPart))
                return false;

            //Kerbin or Mun Anomalies for trivial contracts
            if (this.Prestige == ContractPrestige.Trivial)
            {
                if (rand.Next(0, 3) == 0)
                    body = FlightGlobals.Bodies[1];
                else
                    body = FlightGlobals.Bodies[2];
            }
            //Minmus and Duna are next
            else if (this.Prestige == ContractPrestige.Significant)
            {
                if (!ProgressTracking.Instance.NodeComplete(new string[] { "Kerbin", "Escape" }))
                    return false;
                if (rand.Next(0, 2) == 0)
                    body = FlightGlobals.Bodies[3];
                else
                    body = FlightGlobals.Bodies[6];
            }
            //Vall, Tylo, and Bop are last; only if we've been to Jool first
            else if (this.Prestige == ContractPrestige.Exceptional)
            {
                if (!ProgressTracking.Instance.NodeComplete(new string[] { "Jool", "Flyby" }))
                    return false;
                int i = rand.Next(0, 3);
                if (i == 0)
                    body = FlightGlobals.Bodies[10];
                else if (i == 1)
                    body = FlightGlobals.Bodies[11];
                else if (i == 2)
                    body = FlightGlobals.Bodies[12];
                else
                    return false;
            }
            else
                return false;

            PQSCity[] Cities = UnityEngine.Object.FindObjectsOfType(typeof(PQSCity)) as PQSCity[];
            foreach (PQSCity city in Cities)
            {
                if (city.transform.parent.name == body.name)
                    cities.Add(city);
            }

            r = new System.Random(this.MissionSeed);
            latRand = r.Next(-5, 5);
            lonRand = r.Next(-5, 5);

            //Select random anomaly
            targetAnomaly = new DMAnomalyObject(cities[rand.Next(0, cities.Count)]);
            hash = targetAnomaly.Name;
            lon = targetAnomaly.Lon;
            lat = targetAnomaly.Lat;
            cardNS = NSDirection(lat);
            cardEW = EWDirection(lon);

            //Assign primary anomaly contract parameter
            if ((newParam = DMAnomalyGenerator.fetchAnomalyParameter(body, targetAnomaly)) == null)
                return false;

            sciList.AddRange(DMUtils.availableScience[DMScienceType.Anomaly.ToString()].Values);

            for (i = 0; i < 3; i++)
            {
                if (sciList.Count > 0)
                {
                    DMScience = sciList[rand.Next(0, sciList.Count)];
                    anomParams[i] = (DMAnomalyGenerator.fetchAnomalyParameter(body, DMScience));
                    sciList.Remove(DMScience);
                }
                else
                    anomParams[i] = null;
            }

            this.AddParameter(newParam, "AnomalyScience");

            float primaryLocationMod = GameVariables.Instance.ScoreSituation(DMUtils.convertSit(newParam.Situation), newParam.Body) * ((float)rand.Next(85, 116) / 100f);
            newParam.SetFunds(12000f * DMUtils.reward * primaryLocationMod, body);
            newParam.SetScience(6f * DMUtils.science * DMUtils.fixSubjectVal(newParam.Situation, 1f, body), null);

            //Add the science collection parent parameter
            DMCompleteParameter DMcp = new DMCompleteParameter(3, 1);
            this.AddParameter(DMcp);

            foreach (DMAnomalyParameter aP in anomParams)
            {
                if (aP != null)
                {
                    DMcp.addToSubParams(aP, "CollectAnomalyScience");
                    float locationMod = GameVariables.Instance.ScoreSituation(DMUtils.convertSit(aP.Situation), body) * ((float)rand.Next(85, 116) / 100f);
                    aP.SetFunds(7000f * DMUtils.reward * locationMod, body);
                    aP.SetScience(aP.Container.Exp.baseValue * 0.25f * DMUtils.science * DMUtils.fixSubjectVal(aP.Situation, 1f, body), null);
                }
            }

            if (DMcp.ParameterCount < 2)
                return false;

            this.agent = AgentList.Instance.GetAgent("DMagic");
            base.SetExpiry(10 * DMUtils.deadline, 20 * DMUtils.deadline);
            base.SetDeadlineYears(1.5f * ((float)rand.Next(80, 121)) / 100f * DMUtils.deadline, body);
            base.SetReputation(8f * DMUtils.reward * primaryLocationMod, 9f * DMUtils.penalty * primaryLocationMod, null);
            base.SetFunds(20000f * DMUtils.forward * primaryLocationMod, 24000f * DMUtils.reward * primaryLocationMod, 20000f * DMUtils.penalty * primaryLocationMod, body);
            return true;
        }
        protected override bool Generate()
        {
            DMSurveyContract[] surveyContracts = ContractSystem.Instance.GetCurrentContracts<DMSurveyContract>();
            int offers = 0;
            int active = 0;
            int maxOffers = DMUtils.maxSurveyOffered;
            int maxActive = DMUtils.maxSurveyActive;

            for (int i = 0; i < surveyContracts.Length; i++)
            {
                DMSurveyContract s = surveyContracts[i];
                if (s.ContractState == State.Offered)
                    offers++;
                else if (s.ContractState == State.Active)
                    active++;
            }

            if (offers >= maxOffers)
                return false;
            if (active >= maxActive)
                return false;

            AvailablePart aPart = PartLoader.getPartInfoByName("dmmagBoom");
            if (aPart == null)
                return false;
            if (!ResearchAndDevelopment.PartModelPurchased(aPart))
                return false;

            sciList.AddRange(DMUtils.availableScience[DMScienceType.Space.ToString()].Values);

            if (sciList.Count > 0)
            {
                DMScience = sciList[rand.Next(0, sciList.Count)];
                sciList.Remove(DMScience);
            }
            else
                return false;

            //Generates the science experiment, returns null if experiment fails any check
            if ((newParams[0] = DMSurveyGenerator.fetchSurveyScience(this.Prestige, GetBodies_Reached(false, false), GetBodies_NextUnreached(4, null), DMScience)) == null)
                return false;

            body = newParams[0].Body;

            //Add an orbital parameter to difficult contracts
            if (this.Prestige == ContractPrestige.Exceptional)
                this.AddParameter(new EnterOrbit(body));

            for (int j = 1; j < 8; j++)
            {
                if (sciList.Count > 0)
                {
                    DMScience = sciList[rand.Next(0, sciList.Count)];
                    newParams[j] = DMSurveyGenerator.fetchSurveyScience(body, DMScience);
                    sciList.Remove(DMScience);
                }
                else
                    newParams[j] = null;
            }

            //Add the science collection parent parameter
            DMCompleteParameter DMcp = new DMCompleteParameter(0, 1);
            this.AddParameter(DMcp);

            int limit = 1;

            //Add in all acceptable paramaters to the contract
            foreach (DMCollectScience DMC in newParams)
            {
                if (limit > (3 + (int)this.Prestige))
                    break;
                if (DMC != null)
                {
                    DMcp.addToSubParams(DMC, "CollectScience");
                    float locationMod = GameVariables.Instance.ScoreSituation(DMUtils.convertSit(DMC.Situation), DMC.Body) * ((float)rand.Next(85, 116) / 100f);
                    DMC.SetScience(DMC.Container.Exp.baseValue * 0.2f * DMUtils.science * DMUtils.fixSubjectVal(DMC.Situation, 1f, body), null);
                    DMC.SetFunds(3500f * DMUtils.reward * locationMod, body);
                    limit++;
                }
            }

            if (DMcp.ParameterCount < 3)
                return false;

            int a = rand.Next(0, 4);
            if (a == 0)
                this.agent = AgentList.Instance.GetAgent("DMagic");
            else if (a == 1)
                this.agent = AgentList.Instance.GetAgent(newParams[0].Container.Agent);
            else
                this.agent = AgentList.Instance.GetAgentRandom();

            float primaryLocationMod = GameVariables.Instance.ScoreSituation(DMUtils.convertSit(newParams[0].Situation), newParams[0].Body) * ((float)rand.Next(85, 116) / 100f);
            base.SetExpiry(10f * DMUtils.deadline, 20f * DMUtils.deadline);
            base.SetDeadlineYears(1.7f * ((float)rand.Next(80, 121)) / 100f * DMUtils.deadline, body);
            base.SetReputation(1.9f * DMcp.ParameterCount * DMUtils.reward * primaryLocationMod, 1.5f * DMcp.ParameterCount * DMUtils.penalty * primaryLocationMod, null);
            base.SetFunds(8500 * DMcp.ParameterCount * DMUtils.forward * primaryLocationMod, 10500 * DMcp.ParameterCount * DMUtils.reward * primaryLocationMod, 7500 * DMcp.ParameterCount * DMUtils.penalty * primaryLocationMod, body);
            return true;
        }
        protected override bool Generate()
        {
            DMMagneticSurveyContract[] magContracts = ContractSystem.Instance.GetCurrentContracts<DMMagneticSurveyContract>();
            int offers = 0;
            int active = 0;
            int maxOffers = DMUtils.maxMagneticOffered;
            int maxActive = DMUtils.maxMagneticActive;

            for (int i = 0; i < magContracts.Length; i++)
            {
                DMMagneticSurveyContract m = magContracts[i];
                if (m.ContractState == State.Offered)
                    offers++;
                else if (m.ContractState == State.Active)
                    active++;
            }

            if (offers >= maxOffers)
                return false;
            if (active >= maxActive)
                return false;

            //Make sure that the RPWS is available
            AvailablePart aPart = PartLoader.getPartInfoByName("rpwsAnt");
            if (aPart == null)
                return false;
            if (!ResearchAndDevelopment.PartModelPurchased(aPart))
                return false;

            body = DMUtils.nextTargetBody(this.Prestige, GetBodies_Reached(false, false), GetBodies_NextUnreached(4, null));
            if (body == null)
                return false;

            DMScienceContainer magContainer = DMUtils.availableScience["All"].FirstOrDefault(m => m.Key == "Magnetometer Scan").Value;
            DMScienceContainer rpwsContainer = DMUtils.availableScience["All"].FirstOrDefault(r => r.Key == "Radio Plasma Wave Scan").Value;

            magParams[0] = DMCollectContractGenerator.fetchScienceContract(body, ExperimentSituations.InSpaceLow, magContainer);
            magParams[1] = DMCollectContractGenerator.fetchScienceContract(body, ExperimentSituations.InSpaceHigh, magContainer);
            magParams[2] = DMCollectContractGenerator.fetchScienceContract(body, ExperimentSituations.InSpaceLow, rpwsContainer);
            magParams[3] = DMCollectContractGenerator.fetchScienceContract(body, ExperimentSituations.InSpaceHigh, rpwsContainer);

            double time = 2160000d *(double)(this.Prestige + 1) * ((double)rand.Next(6, 17) / 10d);
            double eccen = 0.15d * (double)(this.Prestige + 1) * ((double)rand.Next(10, 21) / 10d);
            if (eccen > 0.7) eccen = 0.7;
            double inclination = 20d * (double)(this.Prestige + 1) * ((double)rand.Next(8, 15) / 10d);
            if (inclination > 75) inclination = 75;

            DMLongOrbitParameter longParam = new DMLongOrbitParameter(time);
            DMOrbitalParameters eccentricParam = new DMOrbitalParameters(eccen, 0);
            DMOrbitalParameters inclinedParam = new DMOrbitalParameters(inclination, 1);

            this.AddParameter(longParam);
            longParam.AddParameter(eccentricParam);
            longParam.AddParameter(inclinedParam);

            if (eccentricParam == null || inclinedParam == null)
                return false;

            //Add the science collection parent parameter
            DMCompleteParameter DMcp = new DMCompleteParameter(1, 0);
            this.AddParameter(DMcp);

            foreach (DMCollectScience DMCS in magParams)
            {
                if (DMCS == null)
                    return false;
                else
                {
                    DMcp.addToSubParams(DMCS, "MagFieldScience");
                    DMCS.SetFunds(5000f * DMUtils.reward  * ((float)rand.Next(85, 116) / 100f), body);
                    DMCS.SetScience(2f * DMUtils.science * DMUtils.fixSubjectVal(DMCS.Situation, 1f, body), null);
                }
            }

            if (this.ParameterCount == 0)
                return false;

            float primaryModifier = ((float)rand.Next(80, 121) / 100f);
            float diffModifier = 1 + ((float)this.Prestige * 0.5f);

            this.agent = AgentList.Instance.GetAgent("DMagic");
            base.SetExpiry(10 * DMUtils.deadline, 20f * DMUtils.deadline);
            base.SetDeadlineDays((float)(time  / KSPUtil.KerbinDay) * 3.7f * (this.GetDestinationWeight(body) / 1.8f) * DMUtils.deadline * primaryModifier, null);
            base.SetReputation(8f * diffModifier * DMUtils.reward * primaryModifier, 7f * diffModifier * DMUtils.penalty * primaryModifier, null);
            base.SetFunds(35000 * diffModifier * DMUtils.forward * primaryModifier, 40000 * diffModifier * DMUtils.reward * primaryModifier, 28000 * diffModifier * DMUtils.penalty * primaryModifier, body);
            base.SetScience(10f * diffModifier * DMUtils.science * primaryModifier, body);
            return true;
        }
        protected override bool Generate()
        {
            DMAsteroidSurveyContract[] astContracts = ContractSystem.Instance.GetCurrentContracts<DMAsteroidSurveyContract>();
            int offers = 0;
            int active = 0;
            int maxOffers = DMUtils.maxAsteroidOffered;
            int maxActive = DMUtils.maxAsteroidActive;

            for (int i = 0; i < astContracts.Length; i++)
            {
                DMAsteroidSurveyContract a = astContracts[i];
                if (a.ContractState == State.Offered)
                    offers++;
                else if (a.ContractState == State.Active)
                    active++;
            }

            if (offers >= maxOffers)
                return false;
            if (active >= maxActive)
                return false;

            if (this.Prestige == ContractPrestige.Trivial)
                return false;
            else if (this.Prestige == ContractPrestige.Significant)
                size = rand.Next(0, 3);
            else if (this.Prestige == ContractPrestige.Exceptional)
                size = rand.Next(2, 4);
            else
                return false;
            hash = DMUtils.sizeHash(size);

            //Make sure that the grappling device is available
            AvailablePart aPart = PartLoader.getPartInfoByName("GrapplingDevice");
            if (aPart == null)
                return false;
            if (!ResearchAndDevelopment.PartModelPurchased(aPart))
                return false;

            sciList.AddRange(DMUtils.availableScience[DMScienceType.Asteroid.ToString()].Values);

            //Generates new asteroid science experiments
            for (i = 0; i < 6; i++)
            {
                if (sciList.Count > 0)
                {
                    DMScience = sciList[rand.Next(0, sciList.Count)];
                    newParams[i] = DMAsteroidGenerator.fetchAsteroidParameter(DMScience);
                    sciList.Remove(DMScience);
                }
                else
                    newParams[i] = null;
            }

            //Add the science collection parent parameter
            DMCompleteParameter DMcp = new DMCompleteParameter(2, 1);
            this.AddParameter(DMcp);

            int limit = 0;

            //Add in all acceptable paramaters to the contract
            foreach (DMAsteroidParameter DMAP in newParams)
            {
                if (limit > 3 + (int)this.prestige)
                    break;
                if (DMAP != null)
                {
                    DMcp.addToSubParams(DMAP, "CollectAsteroidScience");
                    float modifier = ((float)rand.Next(85, 116) / 100f);
                    DMAP.SetScience(DMAP.Container.Exp.baseValue * 0.3f * DMUtils.science * DMUtils.asteroidSubjectVal(1f, size), null);
                    DMAP.SetFunds(5000f * DMUtils.reward * DMUtils.asteroidSubjectVal(1f, size) * modifier, null);
                    limit++;
                }
            }

            if (DMcp.ParameterCount < 3)
                return false;

            float primaryModifier = ((float)rand.Next(85, 116) / 100f);

            this.agent = AgentList.Instance.GetAgent("DMagic");
            base.SetExpiry(10 * DMUtils.deadline, 20 * DMUtils.deadline);
            base.SetDeadlineYears(3.8f * DMUtils.deadline * primaryModifier, null);
            base.SetReputation(1.5f * DMcp.ParameterCount * DMUtils.reward * (size + 1) * primaryModifier, 1.2f * DMcp.ParameterCount * DMUtils.penalty * primaryModifier, null);
            base.SetFunds(8000 * DMcp.ParameterCount * DMUtils.forward * (size + 1) * primaryModifier, 9500 * DMcp.ParameterCount * DMUtils.reward * (size + 1) * primaryModifier, 7000 * DMcp.ParameterCount * DMUtils.penalty * (size + 1) * primaryModifier, null);
            return true;
        }