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."); } }
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; }
// 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."); } }
// 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; }
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); } } } } } } } }
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); } }
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); }