/// <summary> /// Returns the time until the next asteroid should be detected. Does not throw exceptions. /// </summary> /// <returns>The number of seconds before an asteroid detection, or infinity if asteroids /// should not spawn.</returns> private static double asteroidWaitTime() { double rate = AsteroidManager.spawnRate(); // asteroids per day if (rate > 0.0) { // Waiting time in a Poisson process follows an exponential distribution rate /= SECONDS_PER_EARTH_DAY; // asteroids per second return(RandomDist.drawExponential(1.0 / rate)); } else { return(double.PositiveInfinity); } }
/// <summary> /// Uses criteria similar to ScenarioDiscoverableObjects to decide whether to create an /// asteroid. /// </summary> protected override void checkSpawn() { if (areAsteroidsTrackable() && AsteroidManager.spawnRate() > 0.0 && countUntrackedAsteroids() < rng.Next(SPAWN_GROUP_MIN_LIMIT, SPAWN_GROUP_MAX_LIMIT)) { if (rng.NextDouble() < 1.0 / (1.0 + SPAWN_ODDS_AGAINST)) { spawnAsteroid(); } else { Debug.Log("[StockalikeSpawner]: " + Localizer.Format("#autoLOC_CustomAsteroids_LogSpawnStock", SPAWN_ODDS_AGAINST)); } } }
/// <summary> /// Returns the probability of detecting an asteroid in one tick. Does not throw exceptions. /// </summary> /// <param name="tickLength">The number of seconds in the current tick.</param> /// <returns>The asteroid discovery probability, scaled for the current time warp.</returns> private static float asteroidChance(double tickLength) { if (tickLength <= 0.0) { return(0.0f); } double rate = AsteroidManager.spawnRate() / SECONDS_PER_EARTH_DAY; // asteroids per second if (rate > 0.0) { float expected = (float)(rate * tickLength); return(Mathf.Max(0.0f, Mathf.Min(1.0f - Mathf.Exp(-expected), 1.0f))); } else { return(0.0f); // Avoid small nonzero probability if rate == 0.0 } }