Exemplo n.º 1
0
        /// <summary>
        /// Generates any vessel modules needed by a particular asteroid.
        /// </summary>
        /// <param name="group">The asteroid group to which the asteroid belongs.</param>
        /// <param name="partList">The part(s) from which the asteroid is made.</param>
        /// <param name="size">The asteroid's size class.</param>
        /// <returns>A <c>VesselModules</c> node containing all vessel modules besides
        /// the defaults (currently <c>FlightIntegrator</c> and <c>AxisGroupModule</c>).</returns>
        /// <exception cref="System.NullReferenceException">Thrown if <c>group</c> or <c>partList</c> is
        /// null.</exception>
        /// <exception cref="System.InvalidOperationException">Thrown if <c>group</c> cannot generate
        /// valid data, or if <c>partList</c> does not contain exactly one part, or contains an
        /// unsupported part. The program state will be unchanged in the event of an exception.</exception>
        private ConfigNode makeVesselModules(AsteroidSet group, ConfigNode[] partList, UntrackedObjectClass size)
        {
            if (partList.Length != 1)
            {
                throw new InvalidOperationException(
                          Localizer.Format("#autoLOC_CustomAsteroids_ErrorMultiParts", partList));
            }

            ConfigNode wrapper = new ConfigNode("VESSELMODULES");

            // CometVessel seems to be removed if there's no ModuleComet, but filter just in case
            if (isComet(partList))
            {
                string         cometType  = group.getCometOrbit();
                bool           cometName  = group.getUseCometName();
                CometOrbitType stockClass = CometManager.GetCometOrbitType(cometType);
                if (stockClass is null)
                {
                    throw new InvalidOperationException(Localizer.Format("#autoLOC_CustomAsteroids_ErrorNoCometType", cometType));
                }
                // As far as I can tell the object class is used to scale the activity level
                ConfigNode moduleComet = CometManager.GenerateDefinition(stockClass, size, new System.Random().Next())
                                         .CreateVesselNode(false, 0.0f, !cometName);
                wrapper.AddNode(moduleComet);
            }
            return(wrapper);
        }
Exemplo n.º 2
0
        public void SpawnAsteroid(Asteroid asteroid, UInt32 seed)
        {
            // Create Default Orbit
            Orbit         orbit = null;
            CelestialBody body  = null;

            // Select Orbit Type
            Int32 type = Random.Range(0, 3);

            if (type == 0 && asteroid.Location.Around.Count != 0)
            {
                // Around
                Location.AroundLoader[] around = GetProbabilityList(asteroid.Location.Around,
                                                                    asteroid.Location.Around.Select(a => a.Probability.Value).ToList()).ToArray();
                Location.AroundLoader loader = around[Random.Range(0, around.Length)];
                body = UBI.GetBody(loader.Body);
                if (!body)
                {
                    return;
                }

                if (loader.Reached && !ReachedBody(body))
                {
                    return;
                }

                orbit = new Orbit
                {
                    referenceBody       = body,
                    eccentricity        = loader.Eccentricity,
                    semiMajorAxis       = loader.SemiMajorAxis,
                    inclination         = loader.Inclination,
                    LAN                 = loader.LongitudeOfAscendingNode,
                    argumentOfPeriapsis = loader.ArgumentOfPeriapsis,
                    meanAnomalyAtEpoch  = loader.MeanAnomalyAtEpoch,
                    epoch               = loader.Epoch
                };
                orbit.Init();
            }
            else if (type == 1 && asteroid.Location.Nearby.Count != 0)
            {
                // Nearby
                Location.NearbyLoader[] nearby = GetProbabilityList(asteroid.Location.Nearby,
                                                                    asteroid.Location.Nearby.Select(a => a.Probability.Value).ToList()).ToArray();
                Location.NearbyLoader loader = nearby[Random.Range(0, nearby.Length)];
                body = UBI.GetBody(loader.Body);
                if (!body)
                {
                    return;
                }

                if (loader.Reached && !ReachedBody(body))
                {
                    return;
                }

                orbit = new Orbit
                {
                    eccentricity        = body.orbit.eccentricity + loader.Eccentricity,
                    semiMajorAxis       = body.orbit.semiMajorAxis * loader.SemiMajorAxis,
                    inclination         = body.orbit.inclination + loader.Inclination,
                    LAN                 = body.orbit.LAN * loader.LongitudeOfAscendingNode,
                    argumentOfPeriapsis = body.orbit.argumentOfPeriapsis * loader.ArgumentOfPeriapsis,
                    meanAnomalyAtEpoch  = body.orbit.meanAnomalyAtEpoch * loader.MeanAnomalyAtEpoch,
                    epoch               = body.orbit.epoch,
                    referenceBody       = body.orbit.referenceBody
                };
                orbit.Init();
            }
            else if (type == 2 && asteroid.Location.Flyby.Count != 0)
            {
                // Flyby
                Location.FlybyLoader[] flyby = GetProbabilityList(asteroid.Location.Flyby,
                                                                  asteroid.Location.Flyby.Select(a => a.Probability.Value).ToList()).ToArray();
                Location.FlybyLoader loader = flyby[Random.Range(0, flyby.Length)];
                body = UBI.GetBody(loader.Body);
                if (!body)
                {
                    return;
                }

                if (loader.Reached && !ReachedBody(body))
                {
                    return;
                }

                orbit = Orbit.CreateRandomOrbitFlyBy(body, Random.Range(loader.MinDuration, loader.MaxDuration));
            }

            // Check
            if (orbit == null)
            {
                Debug.Log("[Kopernicus] No new objects this time. (Probability is " + asteroid.Probability.Value + "%)");
                return;
            }

            // Name
            String asteroidName = DiscoverableObjectsUtil.GenerateAsteroidName();

            // Lifetime
            Double lifetime    = Random.Range(asteroid.MinUntrackedLifetime, asteroid.MaxUntrackedLifetime) * 24d * 60d * 60d;
            Double maxLifetime = asteroid.MaxUntrackedLifetime * 24d * 60d * 60d;

            // Size
            UntrackedObjectClass size = (UntrackedObjectClass)(Int32)(asteroid.Size.Evaluate(Random.Range(0f, 1f)) * Enum.GetNames(typeof(UntrackedObjectClass)).Length);

            // Spawn
            ConfigNode vessel = null;

#if (KSP_VERSION_1_10_1 || KSP_VERSION_1_11_1)
            if (Random.Range(0, 100) > RuntimeUtility.KopernicusConfig.CometPercentage)
            {
#endif
            vessel = ProtoVessel.CreateVesselNode(
                asteroidName,
                VesselType.SpaceObject,
                orbit,
                0,
                new[]
            {
                ProtoVessel.CreatePartNode(
                    "PotatoRoid",
                    seed
                    )
            },
                new ConfigNode("ACTIONGROUPS"),
                ProtoVessel.CreateDiscoveryNode(
                    DiscoveryLevels.Presence,
                    size,
                    lifetime,
                    maxLifetime
                    )
                );
            OverrideNode(ref vessel, asteroid.Vessel);
            ProtoVessel protoVessel = new ProtoVessel(vessel, HighLogic.CurrentGame);
            if (asteroid.UniqueName && FlightGlobals.Vessels.Count(v => v.vesselName == protoVessel.vesselName) != 0)
            {
                return;
            }

            Kopernicus.Events.OnRuntimeUtilitySpawnAsteroid.Fire(asteroid, protoVessel);
            protoVessel.Load(HighLogic.CurrentGame.flightState);
            GameEvents.onNewVesselCreated.Fire(protoVessel.vesselRef);
            GameEvents.onAsteroidSpawned.Fire(protoVessel.vesselRef);
            Debug.Log("[Kopernicus] New object found near " + body.name + ": " + protoVessel.vesselName + "!");
#if (KSP_VERSION_1_10_1 || KSP_VERSION_1_11_1)
        }

        else
        {
            float                fragmentDynamicPressureModifier = 0f;
            bool                 optimizedCollider = false;
            CometOrbitType       cometType         = CometManager.GenerateWeightedCometType();
            Orbit                cometOrbit        = cometType.CalculateHomeOrbit();
            UntrackedObjectClass randomObjClass    = cometType.GetRandomObjClass();
            CometDefinition      cometDef          = CometManager.GenerateDefinition(cometType, randomObjClass, (int)seed);
            ConfigNode           configNode        = cometDef.CreateVesselNode(optimizedCollider, fragmentDynamicPressureModifier, hasName: false);
            ConfigNode           configNode2       = ProtoVessel.CreatePartNode("PotatoComet", seed);
            uint                 value             = 0u;
            configNode2.TryGetValue("persistentId", ref value);
            configNode.AddValue("cometPartId", value);
            ConfigNode configNode3 = new ConfigNode("VESSELMODULES");
            configNode3.AddNode(configNode);
            vessel = ProtoVessel.CreateVesselNode(DiscoverableObjectsUtil.GenerateCometName(), VesselType.SpaceObject, cometOrbit, 0, new ConfigNode[1] {
                configNode2
            }, new ConfigNode("ACTIONGROUPS"), ProtoVessel.CreateDiscoveryNode(DiscoveryLevels.Presence, randomObjClass, lifetime, maxLifetime), configNode3);
            OverrideNode(ref vessel, asteroid.Vessel);
            ProtoVessel protoVessel = new ProtoVessel(vessel, HighLogic.CurrentGame);
            Kopernicus.Events.OnRuntimeUtilitySpawnAsteroid.Fire(asteroid, protoVessel);
            protoVessel.Load(HighLogic.CurrentGame.flightState);
            GameEvents.onNewVesselCreated.Fire(protoVessel.vesselRef);
            GameEvents.onAsteroidSpawned.Fire(protoVessel.vesselRef);
            Debug.Log("[Kopernicus] New object found near " + body.name + ": " + protoVessel.vesselName + "!");
        }
#endif
        }