예제 #1
0
 private bool ValidateOrbitType(OrbitData obData, OrbitGeneratorFactory factory)
 {
     if (obData.orbitType == OrbitType.KOLNIYA && !CelestialUtilities.CanBodyBeKolniya(obData.targetBody))
     {
         string error = string.Format("Cannot use a Kolniya orbit with {0}.", obData.targetBody.theName);
         if (factory != null)
         {
             LoggingUtil.LogError(factory, factory.ErrorPrefix() + ": " + error);
             return(false);
         }
         else
         {
             throw new ArgumentException(error);
         }
     }
     else if (obData.orbitType == OrbitType.TUNDRA && !CelestialUtilities.CanBodyBeTundra(obData.targetBody))
     {
         string error = string.Format("Cannot use a tundra orbit with {0}.", obData.targetBody.theName);
         if (factory != null)
         {
             LoggingUtil.LogError(factory, factory.ErrorPrefix() + ": " + error);
             return(false);
         }
         else
         {
             throw new ArgumentException(error);
         }
     }
     return(true);
 }
예제 #2
0
        /*
         * Copy constructor.
         */
        public OrbitGenerator(OrbitGenerator orig, Contract contract)
            : base()
        {
            foreach (OrbitData old in orig.orbits)
            {
                // Copy orbit data
                orbits.Add(new OrbitData(old, contract));
            }

            System.Random random = new System.Random(contract.MissionSeed);

            // Find/add the AlwaysTrue parameter
            AlwaysTrue alwaysTrue = AlwaysTrue.FetchOrAdd(contract);

            int i = 0;

            foreach (OrbitData obData in orbits)
            {
                // Do type specific handling
                if (obData.type == "RANDOM_ORBIT")
                {
                    obData.orbit = CelestialUtilities.GenerateOrbit(obData.orbitType, contract.MissionSeed + i++, obData.orbit.referenceBody, obData.difficulty);
                }

                // Create the wrapper to the SpecificOrbit parameter that will do the rendering work
                SpecificOrbitWrapper s = new SpecificOrbitWrapper(obData.orbitType, obData.orbit.inclination,
                                                                  obData.orbit.eccentricity, obData.orbit.semiMajorAxis, obData.orbit.LAN, obData.orbit.argumentOfPeriapsis,
                                                                  obData.orbit.meanAnomalyAtEpoch, obData.orbit.epoch, obData.orbit.referenceBody,
                                                                  obData.difficulty, 3.0);
                s.DisableOnStateChange = false;
                alwaysTrue.AddParameter(s);
                obData.index = alwaysTrue.ParameterCount - 1;
            }
        }
예제 #3
0
        public void Draw()
        {
            // No contract
            if (contract == null)
            {
                return;
            }

            // Check contract state when displaying
            if (contract.ContractState == Contract.State.Active ||
                contract.ContractState == Contract.State.Offered && HighLogic.LoadedScene == GameScenes.TRACKSTATION)
            {
                // Update the map icons
                foreach (OrbitData obData in orbits)
                {
                    SpecificOrbitParameter s = AlwaysTrue.FetchOrAdd(contract).GetParameter(obData.index) as SpecificOrbitParameter;
                    s.updateMapIcons(CelestialUtilities.MapFocusBody() == obData.orbit.referenceBody);
                }
            }
        }
예제 #4
0
        private static void GenerateStrandedKerbal(int bodyId, string kerbalName)
        {
            //Add kerbal to crew roster.
            LunaLog.Log($"[LMP]: Spawning missing kerbal, Name: {kerbalName}");

            var pcm = HighLogic.CurrentGame.CrewRoster.GetNewKerbal(ProtoCrewMember.KerbalType.Unowned);

            pcm.ChangeName(kerbalName);
            pcm.rosterStatus = ProtoCrewMember.RosterStatus.Assigned;

            //Create protovessel
            var newPartId    = ShipConstruction.GetUniqueFlightID(HighLogic.CurrentGame.flightState);
            var contractBody = FlightGlobals.Bodies[bodyId];

            //Atmo: 10km above atmo, to half the planets radius out.
            //Non-atmo: 30km above ground, to half the planets radius out.
            var minAltitude = CelestialUtilities.GetMinimumOrbitalDistance(contractBody, 1.1f);
            var maxAltitude = minAltitude + contractBody.Radius * 0.5;

            var strandedOrbit = Orbit.CreateRandomOrbitAround(FlightGlobals.Bodies[bodyId], minAltitude, maxAltitude);

            var kerbalPartNode = new[] { ProtoVessel.CreatePartNode("kerbalEVA", newPartId, pcm) };

            var protoVesselNode = ProtoVessel.CreateVesselNode(kerbalName, VesselType.EVA, strandedOrbit, 0,
                                                               kerbalPartNode);

            //It's not supposed to be infinite, but you're crazy if you think I'm going to decipher the values field of the rescue node.
            var discoveryNode = ProtoVessel.CreateDiscoveryNode(DiscoveryLevels.Unowned, UntrackedObjectClass.A,
                                                                double.PositiveInfinity,
                                                                double.PositiveInfinity);

            var protoVessel = new ProtoVessel(protoVesselNode, HighLogic.CurrentGame)
            {
                discoveryInfo = discoveryNode
            };

            HighLogic.CurrentGame.flightState.protoVessels.Add(protoVessel);
        }
예제 #5
0
 public static double MinPeR(this Orbit obt)
 {
     return(obt.referenceBody.atmosphere ?
            obt.referenceBody.Radius + obt.referenceBody.atmosphereDepth :
            obt.referenceBody.Radius + CelestialUtilities.GetHighestPeak(obt.referenceBody) + 1000);
 }
예제 #6
0
 public DMAnomalyStorage(CelestialBody b, bool s = true)
 {
     body    = b;
     scanned = s;
     level   = CelestialUtilities.PlanetScienceRanking(b);
 }
예제 #7
0
        public static void RegisterMethods()
        {
            RegisterMethod(new Method <CelestialBody, bool>("HasAtmosphere", cb => cb != null && cb.atmosphere));
            RegisterMethod(new Method <CelestialBody, bool>("HasOcean", cb => cb != null && cb.ocean));
            RegisterMethod(new Method <CelestialBody, bool>("HasSurface", cb => cb != null && cb.pqsController != null));
            RegisterMethod(new Method <CelestialBody, bool>("IsHomeWorld", cb => cb != null && cb.isHomeWorld));
            RegisterMethod(new Method <CelestialBody, bool>("IsSun", cb => BodyType(cb) == CelestialBodyType.SUN));
            RegisterMethod(new Method <CelestialBody, bool>("IsPlanet", cb => BodyType(cb) == CelestialBodyType.PLANET));
            RegisterMethod(new Method <CelestialBody, bool>("IsMoon", cb => BodyType(cb) == CelestialBodyType.MOON));
            RegisterMethod(new Method <CelestialBody, bool>("IsOrbitalSurveyComplete", cb => cb != null && ResourceScenario.Instance != null &&
                                                            ResourceScenario.Instance.gameSettings.GetPlanetScanInfo().Where(psd => psd.PlanetId == cb.flightGlobalsIndex).Any(), false));

            RegisterMethod(new Method <CelestialBody, bool>("HaveReached", cb => IsReached(cb, ProgressItem.REACHED), false));
            RegisterMethod(new Method <CelestialBody, bool>("HaveOrbited", cb => IsReached(cb, ProgressItem.ORBITED), false));
            RegisterMethod(new Method <CelestialBody, bool>("HaveLandedOn", cb => IsReached(cb, ProgressItem.LANDED), false));
            RegisterMethod(new Method <CelestialBody, bool>("HaveEscaped", cb => IsReached(cb, ProgressItem.ESCAPED), false));
            RegisterMethod(new Method <CelestialBody, bool>("HaveReturnedFrom", cb => IsReached(cb, ProgressItem.RETURNED_FROM), false));

            RegisterMethod(new Method <CelestialBody, bool>("CanHaveKolniyaOrbit", cb => cb != null && CelestialUtilities.CanBodyBeKolniya(cb)));
            RegisterMethod(new Method <CelestialBody, double, bool>("CanHaveSynchronousOrbit", (cb, ecc) => cb != null && CelestialUtilities.CanBodyBeSynchronous(cb, ecc)));
            RegisterMethod(new Method <CelestialBody, bool>("CanHaveTundraOrbit", cb => cb != null && CelestialUtilities.CanBodyBeTundra(cb)));

            RegisterMethod(new Method <CelestialBody, double>("Radius", cb => cb != null ? cb.Radius : 0.0));
            RegisterMethod(new Method <CelestialBody, double>("Mass", cb => cb != null ? cb.Mass : 0.0));
            RegisterMethod(new Method <CelestialBody, double>("RotationalPeriod", cb => cb != null ? cb.rotationPeriod : 0.0));
            RegisterMethod(new Method <CelestialBody, double>("AtmosphereAltitude", cb => cb != null ? cb.atmosphereDepth : 0.0));
            RegisterMethod(new Method <CelestialBody, float>("FlyingAltitudeThreshold", cb => cb != null ? cb.scienceValues.flyingAltitudeThreshold : 0.0f));
            RegisterMethod(new Method <CelestialBody, float>("SpaceAltitudeThreshold", cb => cb != null ? cb.scienceValues.spaceAltitudeThreshold : 0.0f));
            RegisterMethod(new Method <CelestialBody, double>("SphereOfInfluence", cb => cb != null ? cb.sphereOfInfluence : 0.0));
            RegisterMethod(new Method <CelestialBody, double>("SemiMajorAxis", cb => cb != null && cb.orbit != null ? cb.orbit.semiMajorAxis : 0.0));

            RegisterMethod(new Method <CelestialBody, CelestialBody>("Parent", cb => cb != null ? cb.referenceBody : null));
            RegisterMethod(new Method <CelestialBody, List <CelestialBody> >("Children", cb => cb != null ? cb.orbitingBodies.ToList() : new List <CelestialBody>()));
            RegisterMethod(new Method <CelestialBody, List <PQSCity> >("PQSCities", cb => cb != null ? cb.GetComponentsInChildren <PQSCity>(true).ToList() : new List <PQSCity>()));
            RegisterMethod(new Method <CelestialBody, int>("Index", cb => FlightGlobals.Bodies.IndexOf(cb)));

            RegisterMethod(new Method <CelestialBody, List <Biome> >("Biomes", cb => cb != null && cb.BiomeMap != null ?
                                                                     cb.BiomeMap.Attributes.Select(att => new Biome(cb, att.name)).ToList() : new List <Biome>()));

            RegisterMethod(new Method <CelestialBody, string>("Name", cb => cb != null ? cb.name : ""));

            RegisterMethod(new Method <CelestialBody, double>("Multiplier", cb => cb != null ? GameVariables.Instance.GetContractDestinationWeight(cb) : 1.0));

            RegisterMethod(new Method <CelestialBody, double>("RemoteTechCoverage", cb => cb != null ? RemoteTechCoverage(cb) : 0.0d, false));
            RegisterMethod(new Method <CelestialBody, string, double>("SCANsatCoverage", SCANsatCoverage, false));

            RegisterGlobalFunction(new Function <CelestialBody>("HomeWorld", () => FlightGlobals.Bodies.Where(cb => cb.isHomeWorld).First()));
            RegisterGlobalFunction(new Function <CelestialBody>("Sun", () => FlightGlobals.Bodies[0]));
            RegisterGlobalFunction(new Function <List <CelestialBody> >("AllBodies", () => FlightGlobals.Bodies.Where(cb => cb != null && cb.Radius >= BARYCENTER_THRESHOLD).ToList()));
            RegisterGlobalFunction(new Function <List <CelestialBody> >("OrbitedBodies", () => BodiesForItem(ProgressItem.ORBITED).ToList(), false));
            RegisterGlobalFunction(new Function <List <CelestialBody> >("LandedBodies", () => BodiesForItem(ProgressItem.LANDED).ToList(), false));
            RegisterGlobalFunction(new Function <List <CelestialBody> >("EscapedBodies", () => BodiesForItem(ProgressItem.ESCAPED).ToList(), false));
            RegisterGlobalFunction(new Function <List <CelestialBody> >("ReachedBodies", () => BodiesForItem(ProgressItem.REACHED).ToList(), false));
            RegisterGlobalFunction(new Function <List <CelestialBody> >("ReturnedFromBodies", () => BodiesForItem(ProgressItem.RETURNED_FROM).ToList(), false));
            RegisterGlobalFunction(new Function <CelestialBody, CelestialBody>("CelestialBody", cb => cb));
            RegisterGlobalFunction(new Function <CelestialBody>("NextUnreachedBody", () => FinePrint.Utilities.ProgressUtilities.GetNextUnreached(1).FirstOrDefault(), false));
            RegisterGlobalFunction(new Function <int, List <CelestialBody> >("NextUnreachedBodies", (count) => FinePrint.Utilities.ProgressUtilities.GetNextUnreached(count), false));
        }
예제 #8
0
        protected override bool Generate()
        {
            DMReconContract[] reconContracts = ContractSystem.Instance.GetCurrentContracts <DMReconContract>();
            int offers    = 0;
            int active    = 0;
            int maxOffers = DMContractDefs.DMRecon.maxOffers;
            int maxActive = DMContractDefs.DMRecon.maxActive;

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

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

            List <CelestialBody> customReachedBodies = new List <CelestialBody>();

            switch (prestige)
            {
            case ContractPrestige.Trivial:
                Func <CelestialBody, bool> cb = delegate(CelestialBody b)
                {
                    if (b == Planetarium.fetch.Sun)
                    {
                        return(false);
                    }

                    if (b.pqsController == null)
                    {
                        return(false);
                    }

                    return(true);
                };
                customReachedBodies.AddRange(ProgressUtilities.GetBodiesProgress(ProgressType.ORBIT, true, cb));
                customReachedBodies.AddRange(ProgressUtilities.GetNextUnreached(2, cb));
                var activeBodies = ContractSystem.Instance.GetCurrentActiveContracts <DMReconContract>().Select(r => r.body).ToList();
                customReachedBodies.RemoveAll(a => activeBodies.Contains(a));
                var completedBodies = ContractSystem.Instance.GetCompletedContracts <DMReconContract>().Select(r => r.body).ToList();
                customReachedBodies.RemoveAll(a => completedBodies.Contains(a));
                break;

            case ContractPrestige.Significant:
                customReachedBodies = ContractSystem.Instance.GetCompletedContracts <DMReconContract>().Where(r => r.prestige == ContractPrestige.Trivial).Select(r => r.body).ToList();
                var activeSigBodies = ContractSystem.Instance.GetCurrentActiveContracts <DMReconContract>().Where(r => r.prestige == ContractPrestige.Significant).Select(r => r.body).ToList();
                customReachedBodies.RemoveAll(a => activeSigBodies.Contains(a));
                var completedSigBodies = ContractSystem.Instance.GetCompletedContracts <DMReconContract>().Where(r => r.prestige == ContractPrestige.Significant).Select(r => r.body).ToList();
                customReachedBodies.RemoveAll(a => completedSigBodies.Contains(a));
                break;

            case ContractPrestige.Exceptional:
                customReachedBodies = ContractSystem.Instance.GetCompletedContracts <DMReconContract>().Where(r => r.prestige == ContractPrestige.Significant).Select(r => r.body).ToList();
                var activeExcBodies = ContractSystem.Instance.GetCurrentActiveContracts <DMReconContract>().Where(r => r.prestige == ContractPrestige.Exceptional).Select(r => r.body).ToList();
                customReachedBodies.RemoveAll(a => activeExcBodies.Contains(a));
                var completedExcBodies = ContractSystem.Instance.GetCompletedContracts <DMReconContract>().Where(r => r.prestige == ContractPrestige.Exceptional).Select(r => r.body).ToList();
                customReachedBodies.RemoveAll(a => completedExcBodies.Contains(a));
                break;
            }

            if (customReachedBodies.Count <= 0)
            {
                return(false);
            }

            body = customReachedBodies[rand.Next(0, customReachedBodies.Count)];

            if (body == null)
            {
                return(false);
            }

            double time = 0;

            OrbitType orbitType = OrbitType.POLAR;

            Dictionary <int, List <string> > parts = new Dictionary <int, List <string> >();
            Orbit o = new Orbit();

            double incMod  = (rand.NextDouble() * 10) - 5;
            double timeMod = 1080000;

            if (!DMUtils.availableScience.ContainsKey("All"))
            {
                return(false);
            }

            DMScienceContainer container = null;

            switch (prestige)
            {
            case ContractPrestige.Trivial:
                if (!DMUtils.partAvailable(DMContractDefs.DMRecon.reconTrivialParts))
                {
                    return(false);
                }

                parts.Add(0, DMContractDefs.DMRecon.reconTrivialParts);

                if (!DMUtils.availableScience["All"].ContainsKey(DMContractDefs.DMRecon.trivialExperimentTitle))
                {
                    return(false);
                }

                container = DMUtils.availableScience["All"][DMContractDefs.DMRecon.trivialExperimentTitle];

                o = CelestialUtilities.GenerateOrbit(orbitType, this.MissionSeed, body, 0.15, ContractDefs.Satellite.TrivialInclinationDifficulty);

                double st = o.semiMajorAxis - o.referenceBody.Radius;

                double mt = o.referenceBody.scienceValues.spaceAltitudeThreshold * 5 * .95;

                if (st > mt)
                {
                    o.semiMajorAxis = (mt * Math.Max(0.4, rand.NextDouble())) + o.referenceBody.Radius;
                }

                timeMod = DMContractDefs.DMRecon.trivialTimeModifier * 6 * 3600;
                break;

            case ContractPrestige.Significant:
                if (!DMUtils.partAvailable(DMContractDefs.DMRecon.reconSignificantParts))
                {
                    return(false);
                }

                parts.Add(0, DMContractDefs.DMRecon.reconSignificantParts);

                if (!DMUtils.availableScience["All"].ContainsKey(DMContractDefs.DMRecon.significantExperimentTitle))
                {
                    return(false);
                }

                container = DMUtils.availableScience["All"][DMContractDefs.DMRecon.significantExperimentTitle];

                if (SystemUtilities.CoinFlip(rand))
                {
                    if (CelestialUtilities.CanBodyBeKolniya(body))
                    {
                        orbitType = OrbitType.KOLNIYA;
                    }
                    else if (CelestialUtilities.CanBodyBeTundra(body))
                    {
                        orbitType = OrbitType.TUNDRA;
                    }
                    else
                    {
                        orbitType = OrbitType.POLAR;
                    }
                }
                else
                {
                    if (CelestialUtilities.CanBodyBeTundra(body))
                    {
                        orbitType = OrbitType.TUNDRA;
                    }
                    else if (CelestialUtilities.CanBodyBeKolniya(body))
                    {
                        orbitType = OrbitType.KOLNIYA;
                    }
                    else
                    {
                        orbitType = OrbitType.POLAR;
                    }
                }
                o       = CelestialUtilities.GenerateOrbit(orbitType, this.MissionSeed, body, 0.5, ContractDefs.Satellite.TrivialInclinationDifficulty);
                timeMod = DMContractDefs.DMRecon.significantTimeModifier * 6 * 3600;
                incMod  = 0;
                break;

            case ContractPrestige.Exceptional:
                if (!DMUtils.partAvailable(DMContractDefs.DMRecon.reconExceptionalParts))
                {
                    return(false);
                }

                parts.Add(0, DMContractDefs.DMRecon.reconExceptionalParts);

                if (!DMUtils.availableScience["All"].ContainsKey(DMContractDefs.DMRecon.exceptionalExperimentTitle))
                {
                    return(false);
                }

                container = DMUtils.availableScience["All"][DMContractDefs.DMRecon.exceptionalExperimentTitle];

                o = CelestialUtilities.GenerateOrbit(orbitType, this.MissionSeed, body, 0.15, ContractDefs.Satellite.TrivialInclinationDifficulty);

                double se = o.semiMajorAxis - o.referenceBody.Radius;

                double me = o.referenceBody.scienceValues.spaceAltitudeThreshold * 5 * .95;

                if (se > me)
                {
                    o.semiMajorAxis = (me * Math.Max(0.4, rand.NextDouble())) + o.referenceBody.Radius;
                }

                timeMod = DMContractDefs.DMRecon.exceptionalTimeModifier * 6 * 3600;
                break;
            }

            if (container == null)
            {
                return(false);
            }

            time           = timeMod * ((double)rand.Next(6, 17) / 10d);
            o.inclination += incMod;

            DMLongOrbitParameter     longOrbit   = new DMLongOrbitParameter(time);
            DMPartRequestParameter   partRequest = new DMPartRequestParameter(parts, DMContractDefs.DMRecon.useVesselWaypoints, body);
            DMSpecificOrbitParameter reconParam  = new DMSpecificOrbitParameter(orbitType, o.inclination, o.eccentricity, o.semiMajorAxis, o.LAN, o.argumentOfPeriapsis, o.meanAnomalyAtEpoch, o.epoch, body, ContractDefs.Satellite.SignificantDeviation, longOrbit);

            this.AddParameter(longOrbit);
            longOrbit.AddParameter(reconParam);
            longOrbit.AddParameter(partRequest);
            longOrbit.setPartRequest(partRequest);

            sciParams[0] = DMCollectContractGenerator.fetchScienceContract(body, ExperimentSituations.InSpaceLow, "SouthernHemisphere", container);
            sciParams[1] = DMCollectContractGenerator.fetchScienceContract(body, ExperimentSituations.InSpaceLow, "NorthernHemisphere", container);

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

            this.AddParameter(DMcp);

            foreach (DMCollectScience DMCS in sciParams)
            {
                if (DMCS == null)
                {
                    return(false);
                }
                else
                {
                    if (DMCS.Container == null)
                    {
                        continue;
                    }

                    float modifier = ((float)rand.Next(85, 116) / 100f);
                    DMcp.addToSubParams(DMCS);
                    DMCS.SetFunds(DMContractDefs.DMRecon.Funds.ParamReward * modifier, DMContractDefs.DMRecon.Funds.ParamFailure * modifier, body);
                    DMCS.SetScience(DMContractDefs.DMRecon.Science.ParamReward * DMUtils.fixSubjectVal(DMCS.Situation, 1f, body), null);
                    DMCS.SetReputation(DMContractDefs.DMRecon.Reputation.ParamReward * modifier, DMContractDefs.DMRecon.Reputation.ParamFailure * modifier, null);
                }
            }

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

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

            float Mod = primaryModifier * diffModifier;

            int t = rand.Next(0, 4);

            if (t == 0)
            {
                this.agent = AgentList.Instance.GetAgent("DMagic");
            }
            else
            {
                this.agent = AgentList.Instance.GetAgentRandom();
            }

            if (this.agent == null)
            {
                this.agent = AgentList.Instance.GetAgentRandom();
            }

            base.SetExpiry(DMContractDefs.DMRecon.Expire.MinimumExpireDays, DMContractDefs.DMRecon.Expire.MaximumExpireDays);
            base.SetDeadlineDays((float)(time / ((KSPUtil.DefaultDateTimeFormatter)KSPUtil.dateTimeFormatter).KerbinDay) * DMContractDefs.DMRecon.Expire.DeadlineModifier * (this.GetDestinationWeight(body) / 1.4f) * primaryModifier, null);
            base.SetReputation(DMContractDefs.DMRecon.Reputation.BaseReward * Mod, DMContractDefs.DMRecon.Reputation.BaseFailure * Mod, null);
            base.SetFunds(DMContractDefs.DMRecon.Funds.BaseAdvance * Mod, DMContractDefs.DMRecon.Funds.BaseReward * Mod, DMContractDefs.DMRecon.Funds.BaseFailure * Mod, body);
            base.SetScience(DMContractDefs.DMRecon.Science.BaseReward * Mod, body);
            return(true);
        }