public void InitializeScenario()
 {
     if (scenario != null)
     {
         return;
     }
     if (ScenarioRunner.Instance == null)
     {
         return;
     }
     if (Client.realtimeSinceStartup > (lastInitCheck + 10))
     {
         lastInitCheck = Client.realtimeSinceStartup;
         foreach (ScenarioModule sm in ScenarioRunner.GetLoadedModules())
         {
             if (scenario == null && sm is ScenarioDiscoverableObjects)
             {
                 scenario = (ScenarioDiscoverableObjects)sm;
             }
         }
         if (scenario != null)
         {
             DarkLog.Debug("Scenario module found, we can spawn asteroids!");
             scenario.spawnInterval    = float.MaxValue;
             scenario.spawnOddsAgainst = 1;
             // Disable the new Sentinel mechanic in KSP 1.3.0
             SentinelUtilities.SpawnChance = 0f;
         }
     }
 }
        /* ************************************************************************************************
        * Function Name: AdjustSpawnRate
        * Input: N/A
        * Output: N/A
        * Purpose: This function will adjust the spawn rate of the stock asteroid spawner to CactEye's
        * own calculated value, of which is based on the avialability of asteroid telescopes.
        * This function will not run if CustomAsteroids is installed at this time. Perhaps in the future,
        * this can be modified to allow CactEye and CustomAsteroids to work together, but this will require
        * some changes in CustomAsteroids first.
        * ************************************************************************************************/
        private void AdjustSpawnRate()
        {
            if (!CheckForIncompatibleMods())
            {
                try
                {
                    ScenarioDiscoverableObjects AsteroidSpawner = (ScenarioDiscoverableObjects)HighLogic.CurrentGame.scenarios.Find(scenario => scenario.moduleRef is ScenarioDiscoverableObjects).moduleRef;

                    AsteroidSpawner.spawnOddsAgainst = GlobalDiscoveryRate;

                    if (CactEyeConfig.DebugMode)
                    {
                        Debug.Log("CactEye 2: Asteroid Spawner: spawnOddsAgainst = " + AsteroidSpawner.spawnOddsAgainst.ToString());
                    }
                }
                catch (Exception e)
                {
                    Debug.Log("CactEye 2: Asteroid Spawner: Was not able to adjust spawn rate; AsteroidSpawner object is null!");
                    Debug.Log(e.ToString());
                }
            }

            else
            {
                Debug.Log("CactEye 2: An incompatible mod (most likely Custom Asteroids) was detected. CactEye will not adjust the asteroid spawn rate.");
            }
        }
Example #3
0
        public void InitializeScenario()
        {
            foreach (ProtoScenarioModule psm in HighLogic.CurrentGame.scenarios)
            {
                if (psm != null && scenario == null && psm.moduleName.Contains("Discoverable"))
                {
                    scenario = (ScenarioDiscoverableObjects)psm.moduleRef;  // this is borked as of 1.3.0; maybe they'll fix it in the future?
                }
            }
            if (scenario != null)
            {
                scenario.spawnInterval = float.MaxValue;
            }

            // Disable the new Sentinel mechanic in KSP 1.3.0
            SentinelUtilities.SpawnChance = 0f;

            initialized = true;
        }
Example #4
0
        // Startup
        private void Start()
        {
            if (!RuntimeUtility.KopernicusConfig.UseKopernicusAsteroidSystem.ToLower().Equals("stock"))
            {
                // Kill old Scenario Discoverable Objects without editing the collection while iterating through the same collection
                // @Squad: I stab you with a try { } catch { } block.

                if (HighLogic.CurrentGame.RemoveProtoScenarioModule(typeof(ScenarioDiscoverableObjects)))
                {
                    // RemoveProtoScenarioModule doesn't remove the actual Scenario; workaround!
                    foreach (Object o in
                             Resources.FindObjectsOfTypeAll(typeof(ScenarioDiscoverableObjects)))
                    {
                        ScenarioDiscoverableObjects scenario = (ScenarioDiscoverableObjects)o;
                        scenario.StopAllCoroutines();
                        Destroy(scenario);
                    }
                }
                if (RuntimeUtility.KopernicusConfig.UseKopernicusAsteroidSystem.ToLower().Equals("true"))
                {
                    Debug.Log("[Kopernicus] Using Kopernicus Asteroid Spawner.");
                    foreach (Asteroid asteroid in Asteroids)
                    {
                        StartCoroutine(AsteroidDaemon(asteroid));
                    }
                }
                else if (RuntimeUtility.KopernicusConfig.UseKopernicusAsteroidSystem.ToLower().Equals("false"))
                {
                    Debug.Log("[Kopernicus] Asteroid Spawners disabled.  Unless external spawner mod is installed no discoverable objects will be spawned.");
                }
                else
                {
                    Injector.DisplayWarning();
                    throw new InvalidCastException("Invalid value for Enum UseKopernicusAsteroidSystem.  Valid values are true, false, and stock.");
                }
            }
            else if (RuntimeUtility.KopernicusConfig.UseKopernicusAsteroidSystem.ToLower().Equals("stock"))
            {
                Debug.Log("[Kopernicus] Using stock Squad Asteroid Spawner.");
            }
        }
Example #5
0
        // Startup
        private void Start()
        {
            // Kill old Scenario Discoverable Objects without editing the collection while iterating through the same collection
            // @Squad: I stab you with a try { } catch { } block.
            if (HighLogic.CurrentGame.RemoveProtoScenarioModule(typeof(ScenarioDiscoverableObjects)))
            {
                // RemoveProtoScenarioModule doesn't remove the actual Scenario; workaround!
                foreach (Object o in
                         Resources.FindObjectsOfTypeAll(typeof(ScenarioDiscoverableObjects)))
                {
                    ScenarioDiscoverableObjects scenario = (ScenarioDiscoverableObjects)o;
                    scenario.StopAllCoroutines();
                    Destroy(scenario);
                }
                Debug.Log("[Kopernicus] ScenarioDiscoverableObjects successfully removed.");
            }

            foreach (Asteroid asteroid in Asteroids)
            {
                StartCoroutine(AsteroidDaemon(asteroid));
            }
        }
        private void FixedUpdate()
        {
            if (workerEnabled)
            {
                if (scenarioController == null)
                {
                    foreach (ProtoScenarioModule psm in HighLogic.CurrentGame.scenarios)
                    {
                        if (psm != null)
                        {
                            if (psm.moduleName == "ScenarioDiscoverableObjects")
                            {
                                if (psm.moduleRef != null)
                                {
                                    DarkLog.Debug("Found reference to asteroid spawner");
                                    scenarioController = (ScenarioDiscoverableObjects)psm.moduleRef;
                                    scenarioController.spawnInterval = float.MaxValue;
                                }
                            }
                        }
                    }
                }
            }
            if (workerEnabled && scenarioController != null)
            {
                if ((UnityEngine.Time.realtimeSinceStartup - lastAsteroidCheck) > ASTEROID_CHECK_INTERVAL)
                {
                    List<Vessel> asteroidList = GetAsteroidList();
                    lastAsteroidCheck = UnityEngine.Time.realtimeSinceStartup;
                    //Try to acquire the asteroid-spawning lock if nobody else has it.
                    if (!LockSystem.fetch.LockExists("asteroid-spawning"))
                    {
                        LockSystem.fetch.AcquireLock("asteroid-spawning", false);
                    }
                    //We have the spawn lock, lets do stuff.
                    if (LockSystem.fetch.LockIsOurs("asteroid-spawning"))
                    {
                        if (FlightGlobals.fetch.vessels != null ? FlightGlobals.fetch.vessels.Count > 0 : false)
                        {
                            lock (serverAsteroidListLock)
                            {

                                if (asteroidList.Count < maxNumberOfUntrackedAsteroids)
                                {
                                    DarkLog.Debug("Spawning asteroid, have " + asteroidList.Count + ", need " + maxNumberOfUntrackedAsteroids);
                                    scenarioController.SpawnAsteroid();
                                }
                                foreach (Vessel asteroid in asteroidList)
                                {
                                    if (!serverAsteroids.Contains(asteroid.id.ToString()))
                                    {
                                        DarkLog.Debug("Spawned in new server asteroid!");
                                        serverAsteroids.Add(asteroid.id.ToString());
                                        VesselWorker.fetch.RegisterServerVessel(asteroid.id.ToString());
                                        NetworkWorker.fetch.SendVesselProtoMessage(asteroid.protoVessel, false);
                                    }
                                }
                            }
                        }
                    }
                    //Check for changes to tracking
                    foreach (Vessel asteroid in asteroidList)
                    {
                        if (!serverAsteroidTrackStatus.ContainsKey(asteroid.id.ToString()))
                        {
                            serverAsteroidTrackStatus.Add(asteroid.id.ToString(), asteroid.DiscoveryInfo.trackingStatus.Value);
                        }
                        else
                        {
                            if (asteroid.DiscoveryInfo.trackingStatus.Value != serverAsteroidTrackStatus[asteroid.id.ToString()])
                            {
                                DarkLog.Debug("Sending changed asteroid, new state: " + asteroid.DiscoveryInfo.trackingStatus.Value + "!");
                                serverAsteroidTrackStatus[asteroid.id.ToString()] = asteroid.DiscoveryInfo.trackingStatus.Value;
                                NetworkWorker.fetch.SendVesselProtoMessage(asteroid.protoVessel, false);
                            }
                        }
                    }
                }
            }
        }
        private void Update()
        {
            if (workerEnabled)
            {
                if (scenarioController == null)
                {
                    foreach (ProtoScenarioModule psm in HighLogic.CurrentGame.scenarios)
                    {
                        if (psm != null)
                        {
                            if (psm.moduleName == "ScenarioDiscoverableObjects")
                            {
                                if (psm.moduleRef != null)
                                {
                                    scenarioController = (ScenarioDiscoverableObjects)psm.moduleRef;
                                    scenarioController.spawnInterval = float.MaxValue;
                                }
                            }
                        }
                    }
                }
            
                if (scenarioController != null)
                {
                    if ((UnityEngine.Time.realtimeSinceStartup - lastAsteroidCheck) > ASTEROID_CHECK_INTERVAL)
                    {
                        lastAsteroidCheck = UnityEngine.Time.realtimeSinceStartup;
                        //Try to acquire the asteroid-spawning lock if nobody else has it.
                        if (!LockSystem.fetch.LockExists("asteroid-spawning"))
                        {
                            LockSystem.fetch.AcquireLock("asteroid-spawning", false);
                        }

                        //We have the spawn lock, lets do stuff.
                        if (LockSystem.fetch.LockIsOurs("asteroid-spawning"))
                        {
                            if ((HighLogic.CurrentGame.flightState.protoVessels != null) && (FlightGlobals.fetch.vessels != null))
                            {
                                if ((HighLogic.CurrentGame.flightState.protoVessels.Count == 0) || (FlightGlobals.fetch.vessels.Count > 0))
                                {
                                    int beforeSpawn = GetAsteroidCount();
                                    int asteroidsToSpawn = maxNumberOfUntrackedAsteroids - beforeSpawn;
                                    for (int asteroidsSpawned = 0; asteroidsSpawned < asteroidsToSpawn; asteroidsSpawned++)
                                    {
                                        DarkLog.Debug("Spawning asteroid, have " + (beforeSpawn + asteroidsSpawned) + ", need " + maxNumberOfUntrackedAsteroids);
                                        scenarioController.SpawnAsteroid();
                                    }
                                }
                            }
                        }

                        //Check for changes to tracking
                        foreach (Vessel asteroid in GetCurrentAsteroids())
                        {
                            if (asteroid.state != Vessel.State.DEAD)
                            {
                                if (!serverAsteroidTrackStatus.ContainsKey(asteroid.id.ToString()))
                                {
                                    serverAsteroidTrackStatus.Add(asteroid.id.ToString(), asteroid.DiscoveryInfo.trackingStatus.Value);
                                }
                                else
                                {
                                    if (asteroid.DiscoveryInfo.trackingStatus.Value != serverAsteroidTrackStatus[asteroid.id.ToString()])
                                    {
                                        ProtoVessel pv = asteroid.BackupVessel();
                                        DarkLog.Debug("Sending changed asteroid, new state: " + asteroid.DiscoveryInfo.trackingStatus.Value + "!");
                                        serverAsteroidTrackStatus[asteroid.id.ToString()] = asteroid.DiscoveryInfo.trackingStatus.Value;
                                        NetworkWorker.fetch.SendVesselProtoMessage(pv, false, false);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
 private void OnGameSceneLoadRequested(GameScenes scene)
 {
     //Force the worker to find the scenario module again.
     scenarioController = null;
 }
Example #9
0
 private void FixedUpdate()
 {
     if (workerEnabled)
     {
         if (scenarioController == null)
         {
             foreach (ProtoScenarioModule psm in HighLogic.CurrentGame.scenarios)
             {
                 if (psm != null)
                 {
                     if (psm.moduleName == "ScenarioDiscoverableObjects")
                     {
                         if (psm.moduleRef != null)
                         {
                             DarkLog.Debug("Found reference to asteroid spawner");
                             scenarioController = (ScenarioDiscoverableObjects)psm.moduleRef;
                             scenarioController.spawnInterval = float.MaxValue;
                         }
                     }
                 }
             }
         }
     }
     if (workerEnabled && scenarioController != null)
     {
         if ((UnityEngine.Time.realtimeSinceStartup - lastAsteroidCheck) > ASTEROID_CHECK_INTERVAL)
         {
             List <Vessel> asteroidList = GetAsteroidList();
             lastAsteroidCheck = UnityEngine.Time.realtimeSinceStartup;
             //Try to acquire the asteroid-spawning lock if nobody else has it.
             if (!LockSystem.fetch.LockExists("asteroid-spawning"))
             {
                 LockSystem.fetch.AcquireLock("asteroid-spawning", false);
             }
             //We have the spawn lock, lets do stuff.
             if (LockSystem.fetch.LockIsOurs("asteroid-spawning"))
             {
                 if (FlightGlobals.fetch.vessels != null ? FlightGlobals.fetch.vessels.Count > 0 : false)
                 {
                     lock (serverAsteroidListLock)
                     {
                         if (asteroidList.Count < maxNumberOfUntrackedAsteroids)
                         {
                             DarkLog.Debug("Spawning asteroid, have " + asteroidList.Count + ", need " + maxNumberOfUntrackedAsteroids);
                             scenarioController.SpawnAsteroid();
                         }
                         foreach (Vessel asteroid in asteroidList)
                         {
                             if (!serverAsteroids.Contains(asteroid.id.ToString()))
                             {
                                 DarkLog.Debug("Spawned in new server asteroid!");
                                 serverAsteroids.Add(asteroid.id.ToString());
                                 VesselWorker.fetch.RegisterServerVessel(asteroid.id.ToString());
                                 NetworkWorker.fetch.SendVesselProtoMessage(asteroid.protoVessel, false);
                             }
                         }
                     }
                 }
             }
             //Check for changes to tracking
             foreach (Vessel asteroid in asteroidList)
             {
                 if (!serverAsteroidTrackStatus.ContainsKey(asteroid.id.ToString()))
                 {
                     serverAsteroidTrackStatus.Add(asteroid.id.ToString(), asteroid.DiscoveryInfo.trackingStatus.Value);
                 }
                 else
                 {
                     if (asteroid.DiscoveryInfo.trackingStatus.Value != serverAsteroidTrackStatus[asteroid.id.ToString()])
                     {
                         DarkLog.Debug("Sending changed asteroid, new state: " + asteroid.DiscoveryInfo.trackingStatus.Value + "!");
                         serverAsteroidTrackStatus[asteroid.id.ToString()] = asteroid.DiscoveryInfo.trackingStatus.Value;
                         NetworkWorker.fetch.SendVesselProtoMessage(asteroid.protoVessel, false);
                     }
                 }
             }
         }
     }
 }
        private void Update()
        {
            if (workerEnabled)
            {
                if (scenarioController == null)
                {
                    foreach (ProtoScenarioModule psm in HighLogic.CurrentGame.scenarios)
                    {
                        if (psm != null)
                        {
                            if (psm.moduleName == "ScenarioDiscoverableObjects")
                            {
                                if (psm.moduleRef != null)
                                {
                                    scenarioController = (ScenarioDiscoverableObjects)psm.moduleRef;
                                    scenarioController.spawnInterval = float.MaxValue;
                                }
                            }
                        }
                    }
                }

                if (scenarioController != null)
                {
                    if ((Client.realtimeSinceStartup - lastAsteroidCheck) > ASTEROID_CHECK_INTERVAL)
                    {
                        lastAsteroidCheck = Client.realtimeSinceStartup;
                        //Try to acquire the asteroid-spawning lock if nobody else has it.
                        if (!LockSystem.fetch.LockExists("asteroid-spawning"))
                        {
                            LockSystem.fetch.AcquireLock("asteroid-spawning", false);
                        }

                        //We have the spawn lock, lets do stuff.
                        if (LockSystem.fetch.LockIsOurs("asteroid-spawning"))
                        {
                            if ((HighLogic.CurrentGame.flightState.protoVessels != null) && (FlightGlobals.fetch.vessels != null))
                            {
                                if ((HighLogic.CurrentGame.flightState.protoVessels.Count == 0) || (FlightGlobals.fetch.vessels.Count > 0))
                                {
                                    int beforeSpawn      = GetAsteroidCount();
                                    int asteroidsToSpawn = maxNumberOfUntrackedAsteroids - beforeSpawn;
                                    for (int asteroidsSpawned = 0; asteroidsSpawned < asteroidsToSpawn; asteroidsSpawned++)
                                    {
                                        DarkLog.Debug("Spawning asteroid, have " + (beforeSpawn + asteroidsSpawned) + ", need " + maxNumberOfUntrackedAsteroids);
                                        scenarioController.SpawnAsteroid();
                                    }
                                }
                            }
                        }

                        //Check for changes to tracking
                        foreach (Vessel asteroid in GetCurrentAsteroids())
                        {
                            if (asteroid.state != Vessel.State.DEAD)
                            {
                                if (!serverAsteroidTrackStatus.ContainsKey(asteroid.id.ToString()))
                                {
                                    serverAsteroidTrackStatus.Add(asteroid.id.ToString(), asteroid.DiscoveryInfo.trackingStatus.Value);
                                }
                                else
                                {
                                    if (asteroid.DiscoveryInfo.trackingStatus.Value != serverAsteroidTrackStatus[asteroid.id.ToString()])
                                    {
                                        ProtoVessel pv = asteroid.BackupVessel();
                                        DarkLog.Debug("Sending changed asteroid, new state: " + asteroid.DiscoveryInfo.trackingStatus.Value + "!");
                                        serverAsteroidTrackStatus[asteroid.id.ToString()] = asteroid.DiscoveryInfo.trackingStatus.Value;
                                        NetworkWorker.fetch.SendVesselProtoMessage(pv, false, false);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
 private void OnGameSceneLoadRequested(GameScenes scene)
 {
     //Force the worker to find the scenario module again.
     scenarioController = null;
 }
        protected bool CheckParameters(MonolithState paramState)
        {
            if (paramState < currentState)
            {
                return(true);
            }

            // StarJeb not active vessel
            if (starJeb != null && FlightGlobals.ActiveVessel != starJeb ||
                candidate != null && FlightGlobals.ActiveVessel != candidate)
            {
                stepTime = Time.fixedTime;
                return(false);
            }

            // Create the velocity change handler
            if (velHdlr == null)
            {
                LoggingUtil.LogDebug(this, "Adding VelocityHandler");
                velHdlr       = MapView.MapCamera.gameObject.AddComponent <VelocityHandler>();
                velHdlr.param = this;
            }

            switch (currentState)
            {
            case MonolithState.STARTED:
                // Look for an eva
                if (FlightGlobals.ActiveVessel != null && FlightGlobals.ActiveVessel.vesselType == VesselType.EVA)
                {
                    candidate     = FlightGlobals.ActiveVessel;
                    candidateName = candidate.vesselName;
                    LoggingUtil.LogDebug(this, "Got an eva, starJeb = " + candidate.vesselName);
                    nextState();
                    return(true);
                }
                return(false);

            case MonolithState.EVA:
            {
                Vessel discovery         = ContractVesselTracker.Instance.GetAssociatedVessel("Discovery One");
                float  discoveryDistance = discovery == null ? 10000 : Vector3.Distance(discovery.transform.position, candidate.transform.position);

                if (distance < 10000 && discoveryDistance > distance && Time.fixedTime - stepTime > 10.0f || distance < MONOLITH_TOO_CLOSE)
                {
                    // Store Star Jeb's name
                    starJeb     = candidate;
                    starJebName = candidateName;
                    PersistentDataStore.Instance.Store <string>("starJebName", starJebName);

                    // Store Star Jeb's friend's name
                    ProtoCrewMember protoStarJeb = candidate.GetVesselCrew().First();
                    if (discovery != null)
                    {
                        string          trait      = protoStarJeb.experienceTrait.TypeName == "Scientist" ? "Pilot" : "Scientist";
                        ProtoCrewMember notStarJeb = discovery.GetVesselCrew().Where(pcm => pcm.experienceTrait.TypeName == trait).FirstOrDefault();
                        if (notStarJeb != null)
                        {
                            PersistentDataStore.Instance.Store <string>("notStarJebName", notStarJeb.name);
                        }
                    }
                    candidate = null;
                    nextState();

                    // Set the right image (male vs. female) for the end sequence
                    ConfiguredContract contract  = Root as ConfiguredContract;
                    DialogBox          dialogBox = contract.Behaviours.Select(b => b as DialogBox).Where(b => b != null).FirstOrDefault();
                    if (dialogBox != null)
                    {
                        FieldInfo detailsField = typeof(DialogBox).GetFields(BindingFlags.Instance | BindingFlags.NonPublic).
                                                 Where(fi => fi.FieldType == typeof(List <DialogBox.DialogDetail>)).First();
                        DialogBox.DialogDetail detail       = ((List <DialogBox.DialogDetail>)detailsField.GetValue(dialogBox)).First();
                        DialogBox.ImageSection starJebImage = detail.sections.First() as DialogBox.ImageSection;
                        starJebImage.imageURL = protoStarJeb.gender == ProtoCrewMember.Gender.Male ?
                                                "ContractPacks/AnomalySurveyor/Images/starjeb.dds.noload" :
                                                "ContractPacks/AnomalySurveyor/Images/starjeb_female.dds.noload";
                    }

                    return(true);
                }
            }
                return(false);

            case MonolithState.FULL_OF_STARS1:
            {
                // Backup progress tracking
                progressTreeBackup = new ConfigNode("PROGRESS_TREE_BACKUP");
                ProgressTracking.Instance.OnSave(progressTreeBackup);

                // Give the first kick away from Jool - this one using regular velocity change
                CelestialBody jool = FlightGlobals.Bodies.Where(b => b.name == "Jool").First();

                // Find closest point on the jool-monolith line, and throw us away from that (so we don't hit either)
                Vector3 line    = monolith.transform.position - jool.transform.position;
                float   t       = Vector3.Dot(line, (starJeb.transform.position - jool.transform.position)) / Vector3.Dot(line, line);
                Vector3 closest = jool.transform.position + line * t;

                velocity  = (starJeb.transform.position - (t > 1.0 ? jool.transform.position : closest)).normalized;
                velocity += new Vector3(0.0f, 0.1f, 0.0f);
                velocity *= 15000;
                LoggingUtil.LogDebug(this, "kick magnitude will be: " + velocity);
                nextState();

                // Camera to target jool
                FlightCamera.SetTarget(starJeb.transform);
                FlightCamera.fetch.SetCamCoordsFromPosition((starJeb.transform.position - jool.transform.position).normalized * 25.0f);
            }
                return(false);

            case MonolithState.FULL_OF_STARS2:
                if (Time.fixedTime - stepTime > 4.0f)
                {
                    // Give the second kick away from Jool - these using anti-kraken velocity change
                    CelestialBody jool = FlightGlobals.Bodies.Where(b => b.name == "Jool").First();
                    velocity  = (starJeb.transform.position - jool.transform.position).normalized;
                    velocity += new Vector3(0.0f, 0.1f, 0.0f);
                    velocity *= 1500000;
                    LoggingUtil.LogDebug(this, "kick magnitude will be: " + velocity);
                    nextState();
                }
                return(false);

            case MonolithState.FULL_OF_STARS3:
                if (Time.fixedTime - stepTime > 3.0f)
                {
                    // Give the third kick away from Jool
                    CelestialBody jool = FlightGlobals.Bodies.Where(b => b.name == "Jool").First();
                    velocity  = (starJeb.transform.position - jool.transform.position).normalized;
                    velocity *= 20000000;
                    LoggingUtil.LogDebug(this, "kick magnitude will be: " + velocity);
                    nextState();
                }
                return(false);

            case MonolithState.FULL_OF_STARS4:
                if (Time.fixedTime - stepTime > 2.0f)
                {
                    // Give the fourth and final kick away from Jool
                    CelestialBody jool = FlightGlobals.Bodies.Where(b => b.name == "Jool").First();
                    velocity  = (starJeb.transform.position - jool.transform.position).normalized;
                    velocity *= 200000000;
                    LoggingUtil.LogDebug(this, "kick magnitude will be: " + velocity);
                    nextState();
                }
                return(false);

            case MonolithState.FULL_OF_STARS5:
                if (Time.fixedTime - stepTime > 2.0f)
                {
                    // Move along
                    nextState();
                }
                return(false);

            case MonolithState.FULL_OF_STARS_DRES1:
            {
                // Visit Dres
                CelestialBody dres = FlightGlobals.Bodies.Where(b => b.name == "Dres").First();

                // Determine which side the sun is on - makes for a better show
                CelestialBody sun       = FlightGlobals.Bodies.Where(b => b.name == "Sun").First();
                Vector3       sunnySide = sun.transform.position - dres.transform.position;
                sunnySide.x = 0.0f;
                sunnySide.y = 1;         // Move across the top of the planet
                sunnySide.z = Math.Sign(sunnySide.z);

                // Set position for starjeb
                float distance = 4.0f * (float)dres.Radius;
                starJeb.SetPosition(dres.transform.position + new Vector3(distance, (float)dres.Radius, (float)dres.Radius * sunnySide.z));

                velocity  = (dres.transform.position - starJeb.transform.position + sunnySide * ((float)dres.Radius)).normalized;
                velocity *= distance / 3.0f;
                LoggingUtil.LogDebug(this, "kick magnitude will be: " + velocity);
                starJeb.SetWorldVelocity(dres.getRFrmVel(starJeb.transform.position));
                nextState();
            }
                return(false);

            case MonolithState.FULL_OF_STARS_DRES2:
            {
                // Camera to target Dres - do this on a seperate update to allow KSP to catch up
                CelestialBody dres = FlightGlobals.Bodies.Where(b => b.name == "Dres").First();
                FlightCamera.SetTarget(starJeb.transform);
                FlightCamera.fetch.SetCamCoordsFromPosition(starJeb.transform.position + (starJeb.transform.position - dres.transform.position).normalized * 10.0f);

                // Make sure that the camera gets fixed
                if (Time.fixedTime - stepTime > 0.1f)
                {
                    nextState();
                }
            }
                return(false);

            case MonolithState.FULL_OF_STARS_DRES3:
                if (Time.fixedTime - stepTime > 5.5f)
                {
                    // Done with Dres
                    nextState();
                }
                return(false);

            case MonolithState.FULL_OF_STARS_DUNA1:
            {
                // Start between the sun and Duna
                CelestialBody duna      = FlightGlobals.Bodies.Where(b => b.name == "Duna").First();
                CelestialBody sun       = FlightGlobals.Bodies.Where(b => b.name == "Sun").First();
                Vector3       sunnySide = sun.transform.position - duna.transform.position;
                sunnySide.Normalize();

                // Set us up a nice 4 radiuses away...
                float distance = 4.0f * (float)duna.Radius;
                starJeb.SetPosition(duna.transform.position + sunnySide * distance);

                // Go straight at Duna
                velocity  = (duna.transform.position - starJeb.transform.position).normalized;
                velocity *= distance / 3.0f;
                LoggingUtil.LogDebug(this, "kick magnitude will be: " + velocity);

                // Now offset him down so he doesn't actually hit Duna...
                starJeb.SetPosition(starJeb.transform.position + new Vector3(0.0f, -((float)duna.Radius + 55000), 0.0f));
                starJeb.SetWorldVelocity(duna.getRFrmVel(starJeb.transform.position));

                nextState();
            }
                return(false);

            case MonolithState.FULL_OF_STARS_DUNA2:
            {
                // Camera to target Duna - do this on a seperate update to allow KSP to catch up
                CelestialBody duna = FlightGlobals.Bodies.Where(b => b.name == "Duna").First();
                FlightCamera.SetTarget(starJeb.transform);
                FlightCamera.fetch.SetCamCoordsFromPosition(starJeb.transform.position + (starJeb.transform.position - duna.transform.position).normalized * 25.0f);

                // Make sure that the camera gets fixed
                if (Time.fixedTime - stepTime > 0.1f)
                {
                    nextState();
                }
            }
                return(false);

            case MonolithState.FULL_OF_STARS_DUNA3:
                if (Time.fixedTime - stepTime > 5.5f)
                {
                    // Done with Duna
                    nextState();
                }
                return(false);

            case MonolithState.FULL_OF_STARS_EELOO1:
            {
                // Start perpendicular to the sun and Eeloo
                CelestialBody eeloo = FlightGlobals.Bodies.Where(b => b.name == "Eeloo").First();
                CelestialBody sun   = FlightGlobals.Bodies.Where(b => b.name == "Sun").First();
                Vector3       perp  = eeloo.transform.position - sun.transform.position;
                float         tmp   = perp.x;
                perp.x = -perp.z;
                perp.z = tmp;
                perp.Normalize();

                // Set us up a nice 4 radiuses away...
                float distance = 4.0f * (float)eeloo.Radius;
                starJeb.SetPosition(eeloo.transform.position + perp * distance);

                // Determine which side the sun is on - makes for a better show
                Vector3 sunnySide = sun.transform.position - eeloo.transform.position;
                sunnySide.Normalize();

                // Go straight at Eeloo
                velocity  = (eeloo.transform.position - starJeb.transform.position).normalized;
                velocity *= distance / 3.0f;
                LoggingUtil.LogDebug(this, "kick magnitude will be: " + velocity);

                // Now offset him down so he doesn't actually hit Eeloo...
                starJeb.SetPosition(starJeb.transform.position + sunnySide * ((float)eeloo.Radius * 1.5f));
                starJeb.SetWorldVelocity(eeloo.getRFrmVel(starJeb.transform.position));

                nextState();
            }
                return(false);

            case MonolithState.FULL_OF_STARS_EELOO2:
            {
                // This time won't target directly towards Eeloo, as the player will have some idea
                // what is up by now.
                CelestialBody eeloo       = FlightGlobals.Bodies.Where(b => b.name == "Eeloo").First();
                CelestialBody sun         = FlightGlobals.Bodies.Where(b => b.name == "Sun").First();
                Vector3       awayFromSun = sun.transform.position - eeloo.transform.position;
                awayFromSun.Normalize();

                FlightCamera.SetTarget(starJeb.transform);
                FlightCamera.fetch.SetCamCoordsFromPosition(starJeb.transform.position + awayFromSun * 50.0f);

                // Make sure that the camera gets fixed
                if (Time.fixedTime - stepTime > 0.1f)
                {
                    nextState();
                }
            }
                return(false);

            case MonolithState.FULL_OF_STARS_EELOO3:
                if (Time.fixedTime - stepTime > 5.5f)
                {
                    velocity = null;

                    // Done with Eeloo
                    nextState();
                }
                return(false);

            case MonolithState.FULL_OF_STARS_EVE1:
            {
                CelestialBody eve            = FlightGlobals.Bodies.Where(b => b.name == "Eve").First();
                Vector3       targetPosition = Destination.Value;
                Vector3       normal         = eve.GetSurfaceNVector(eveLatitude, eveLongitude);
                startDistance = 10000000f;
                Vector3 start = targetPosition + normal * startDistance;

                starJeb.SetPosition(start);
                nextState();
            }
                return(false);

            case MonolithState.FULL_OF_STARS_EVE2:
            {
                // Camera straight towards Eve - we're going in!
                CelestialBody eve         = FlightGlobals.Bodies.Where(b => b.name == "Eve").First();
                Vector3       awayFromEve = starJeb.transform.position - eve.transform.position;
                awayFromEve.Normalize();

                FlightCamera.SetTarget(starJeb.transform);
                FlightCamera.fetch.SetCamCoordsFromPosition(starJeb.transform.position + awayFromEve * 15.0f);

                // Make sure that the camera gets fixed
                if (Time.fixedTime - stepTime > 0.1f)
                {
                    nextState();
                }
            }
                return(false);

            case MonolithState.FULL_OF_STARS_EVE3:
                // Wait until we've held the position for a split second
                if (Time.fixedTime - stepTime >= 9.3f)
                {
                    nextState();
                }
                return(false);

            case MonolithState.FULL_OF_STARS_EVE4:
                // Give the player a bit to get settled, then let the fun begins
                if (Time.fixedTime - stepTime >= 15.0f)
                {
                    // Spawn some asteroids
                    CelestialBody eve = FlightGlobals.Bodies.Where(b => b.name == "Eve").First();
                    ScenarioDiscoverableObjects asteroidSpawner = (ScenarioDiscoverableObjects)HighLogic.CurrentGame.scenarios.Find(
                        s => s.moduleRef is ScenarioDiscoverableObjects).moduleRef;
                    System.Random random = new System.Random();

                    // Spawn some more asteroids
                    for (int i = 0; i < ASTEROID_COUNT; i++)
                    {
                        asteroidSpawner.SpawnAsteroid();
                    }

                    nextState();
                }
                return(false);

            case MonolithState.FULL_OF_STARS_EVE5:
                // Wait a full second after spawning the asteroids - we're not allowed to pull
                // them off rails until they've been active a bit
                if (Time.fixedTime - stepTime > 1.0f)
                {
                    // Spawn some asteroids
                    CelestialBody eve    = FlightGlobals.Bodies.Where(b => b.name == "Eve").First();
                    System.Random random = new System.Random();

                    foreach (Vessel asteroid in FlightGlobals.Vessels.Where(v => v.vesselType == VesselType.SpaceObject).Reverse().Take(ASTEROID_COUNT))
                    {
                        // Set the position
                        double r         = random.NextDouble() * 0.02 + 0.002;
                        double theta     = random.NextDouble() * 2.0 * Math.PI;
                        double latitude  = starJeb.latitude + r * Math.Sin(theta);
                        double longitude = starJeb.longitude + r * Math.Cos(theta);
                        double altitude  = starJeb.altitude + 100 + random.NextDouble() * 200;
                        asteroid.SetPosition(eve.GetWorldSurfacePosition(latitude, longitude, altitude));
                        asteroid.ChangeWorldVelocity(asteroid.GetSrfVelocity());
                        asteroid.Load();
                        asteroid.GoOffRails();
                    }
                    nextState();
                }
                return(false);

            case MonolithState.FULL_OF_STARS_EVE6:
            {
                // Determine if there's an asteroid about to kill us
                CelestialBody eve            = FlightGlobals.Bodies.Where(b => b.name == "Eve").First();
                bool          killerAsteroid = FlightGlobals.Vessels.Where(v => v.mainBody == eve && v.vesselType == VesselType.SpaceObject &&
                                                                           Vector3.Distance(starJeb.transform.position, v.transform.position) < 5.5 * ((int)v.DiscoveryInfo.objectSize + 1)).Any();

                if (killerAsteroid || Time.fixedTime - stepTime > 20.0f)
                {
                    foreach (Vessel asteroid in FlightGlobals.Vessels.Where(v => v.vesselType == VesselType.SpaceObject).Reverse().Take(ASTEROID_COUNT))
                    {
                        asteroid.Die();
                    }
                    nextState();
                }
            }
                return(false);

            case MonolithState.FULL_OF_STARS_KERBIN1:
            {
                CheatOptions.NoCrashDamage = false;

                // Start between the sun and Kerbin
                CelestialBody kerbin    = FlightGlobals.Bodies.Where(b => b.name == "Kerbin").First();
                CelestialBody sun       = FlightGlobals.Bodies.Where(b => b.name == "Sun").First();
                Vector3       sunnySide = sun.transform.position - kerbin.transform.position;
                sunnySide.Normalize();

                // Set us up a nice 4 radiuses away...
                float distance = 4.0f * (float)kerbin.Radius;
                starJeb.SetPosition(kerbin.transform.position + sunnySide * distance);

                // Orient him properly
                KerbalEVA  keva           = starJeb.FindPartModulesImplementing <KerbalEVA>().First();
                MethodInfo rotationMethod = typeof(KerbalEVA).GetMethod("correctGroundedRotation", BindingFlags.Instance | BindingFlags.NonPublic);
                starJeb.packed = true;
                rotationMethod.Invoke(keva, new object[] { });
                starJeb.packed = false;

                // Hardcode an orbital velocity, because it's late and I'm tired
                starJeb.SetWorldVelocity(kerbin.getRFrmVel(starJeb.transform.position).normalized * 1085);

                nextState();
            }
                return(false);

            case MonolithState.FULL_OF_STARS_KERBIN2:
            {
                // Camera to target kerbin - do this on a seperate update to allow KSP to catch up
                CelestialBody kerbin = FlightGlobals.Bodies.Where(b => b.name == "Kerbin").First();
                FlightCamera.SetTarget(starJeb.transform);
                FlightCamera.fetch.SetCamCoordsFromPosition(starJeb.transform.position + (starJeb.transform.position - kerbin.transform.position).normalized * 10.0f);

                starJeb.SetRotation(FlightCamera.fetch.transform.rotation * Quaternion.AngleAxis(180.0f, FlightCamera.fetch.transform.up));

                // Make sure that the camera gets fixed
                if (Time.fixedTime - stepTime > 0.1f)
                {
                    nextState();
                }
            }
                return(false);

            case MonolithState.FULL_OF_STARS_KERBIN3:
                if (Time.fixedTime - stepTime > 2.0f)
                {
                    // Turn into star jeb
                    CelestialBody kerbin = FlightGlobals.Bodies.Where(b => b.name == "Kerbin").First();

                    starJeb.vesselName = "The Star Jeb";
                    Undress(starJeb.gameObject);
                    FlightCamera.fetch.SetCamCoordsFromPosition(starJeb.transform.position + (starJeb.transform.position - kerbin.transform.position).normalized * 1.5f);

                    nextState();
                }
                return(false);

            case MonolithState.FULL_OF_STARS_KERBIN4:
                if (Time.fixedTime - stepTime < 15.0f)
                {
                    CelestialBody kerbin       = FlightGlobals.Bodies.Where(b => b.name == "Kerbin").First();
                    Vector3       camDirection = starJeb.transform.position + (starJeb.transform.position - kerbin.transform.position).normalized;
                }
                else
                {
                    nextState();

                    monolith.Die();
                    monolith = null;

                    starJeb.Die();
                    starJeb = null;

                    Vessel discovery = ContractVesselTracker.Instance.GetAssociatedVessel("Discovery One");
                    FlightGlobals.ForceSetActiveVessel(discovery);
                }
                return(false);

            case MonolithState.FULL_OF_STARS_FINAL:
                nextState();
                return(true);

            default:
                return(false);
            }
        }
Example #13
0
        public System.Collections.IEnumerator DelayedStart()
        {
            while (HighLogic.CurrentGame.scenarios.Find(scenario => scenario.moduleRef is ScenarioDiscoverableObjects) == null)
            {
                yield return(0);
            }

            print("Checking number of asteroid-seeking vessels...");
            float          discoveryRate = 0f;
            List <Vector3> vPos          = new List <Vector3>();

            foreach (Vessel v in FlightGlobals.Vessels)
            {
                print("Checking vessel " + v.vesselName);

                float maxDiscoveryRate = 0f;

                List <ProtoPartModuleSnapshot> processors = new List <ProtoPartModuleSnapshot>();
                foreach (ProtoPartSnapshot p in v.protoVessel.protoPartSnapshots)
                {
                    ProtoPartModuleSnapshot proc = p.modules.Find(n => n.moduleName == "CactEyeProcessor");
                    if (proc != null)
                    {
                        processors.Add(proc);
                    }
                }

                print("Found " + processors.Count() + " processors");

                foreach (ProtoPartModuleSnapshot proc in processors)
                {
                    print("Disc rate: " + proc.moduleValues.GetValue("discoveryRate"));
                    float thisDiscRate = float.Parse(proc.moduleValues.GetValue("discoveryRate"));
                    if (thisDiscRate > maxDiscoveryRate)
                    {
                        maxDiscoveryRate = thisDiscRate;
                    }
                }

                if (maxDiscoveryRate > 0)
                {
                    foreach (Vector3 pos in vPos)
                    {
                        if (Vector3.Distance(pos, v.GetWorldPos3D()) < 100000)
                        {
                            print("Telescope found too close to other telescope; will not discover asteroids");
                            maxDiscoveryRate = 0f;
                        }
                    }
                }

                if (maxDiscoveryRate > 0)
                {
                    vPos.Add(v.GetWorldPos3D());
                }

                discoveryRate += maxDiscoveryRate;
            }
            print("Discovery rate is " + discoveryRate);

            ScenarioDiscoverableObjects sDO = (ScenarioDiscoverableObjects)HighLogic.CurrentGame.scenarios.Find(scenario => scenario.moduleRef is ScenarioDiscoverableObjects).moduleRef;

            if (sDO == null)
            {
                print("Could not find sDO?");
            }

            sDO.spawnOddsAgainst = (int)((100 / Mathf.Pow(discoveryRate + 1, 2)) + 1);
        }