public static void InitializeScenario(ScenarioPreset preset) { if (s_instance != null) { s_instance.InitializeScenarioInternal(preset); } }
public static ScenarioRound GenerateRound(int roundIndex, ScenarioPreset preset) { return(new ScenarioRound(roundIndex, GenerateWaves(roundIndex, preset))); }
public static ScenarioWave[] GenerateWaves(int roundIndex, ScenarioPreset preset) { float t = preset.m_waveCountCurve.Evaluate(roundIndex / (preset.m_waveCountRoundMax - 1f)); int waveCount = t < 1f ? Mathf.FloorToInt(Mathf.Lerp(preset.m_waveCountMin, preset.m_waveCountMax, t)) : preset.m_waveCountMax; ScenarioWave wave; ScenarioWave[] waves = new ScenarioWave[waveCount]; float[] wavePickRolls = new float[waveCount]; float[] waveEnemyCountRolls = new float[waveCount]; t = preset.m_waveIntervalCurve.Evaluate(roundIndex / (preset.m_waveIntervalRoundMax - 1f)); float waveInterval = Mathf.Lerp(preset.m_waveIntervalMin, preset.m_waveIntervalMax, t); Debug.Log(DebugUtilities.AddTimestampPrefix("Round " + (roundIndex + 1) + " will have " + waveCount + " waves in it, interval=" + waveInterval)); float enemyWaveCountWeightTotal, enemySpeed; int i, p, waveCountToSpawnEnemyIn, enemyCountTotal, remainingEnemyCount; List <int> pickedWaveIndices; int[] pickedWaveEnemyCounts; ScenarioPreset.Enemy enemyPreset; ScenarioWave.Enemy[] waveEnemies; // TODO: Optimize this, it's stupid now for (int e = 0; e < preset.m_enemyPresets.Length; e++) { enemyPreset = preset.m_enemyPresets[e]; if (roundIndex < enemyPreset.m_firstRoundToSpawn - 1) { continue; } // Determine how many enemies to spawn in total if (roundIndex == enemyPreset.m_firstRoundToSpawn - 1) { enemyCountTotal = enemyPreset.m_spawnCountMin; } else { t = enemyPreset.m_spawnCountCurve.Evaluate((roundIndex - (enemyPreset.m_firstRoundToSpawn - 1f)) / (enemyPreset.m_spawnCountRoundMax - enemyPreset.m_firstRoundToSpawn)); enemyCountTotal = t < 1f ? Mathf.FloorToInt(Mathf.Lerp(enemyPreset.m_spawnCountMin, enemyPreset.m_spawnCountMax, t)) : enemyPreset.m_spawnCountMax; } Debug.Log(DebugUtilities.AddTimestampPrefix("Round " + (roundIndex + 1) + " will spawn a total of " + enemyCountTotal + " instances of enemy " + enemyPreset.m_enemyPrefab.name)); // Roll for each wave after first to determine which ones to pick and the weight value for the enemy count for (i = 0; i < waveCount; i++) { // First wave is always picked wavePickRolls[i] = i == 0 ? 2f : Random.value * enemyPreset.m_waveProbabilityCurve.Evaluate((float)i / waveCount); waveEnemyCountRolls[i] = Random.value; //Debug.Log(DebugUtilities.AddTimestampPrefix("Round " + (roundIndex + 1) + " Wave[" + i + "] pick roll: " + wavePickRolls[i] + ", enemy count roll: " + waveEnemyCountRolls[i])); } waveCountToSpawnEnemyIn = Mathf.FloorToInt(enemyPreset.m_waveCountMultiplier * waveCount); pickedWaveIndices = new List <int>(waveCountToSpawnEnemyIn); pickedWaveEnemyCounts = new int[waveCountToSpawnEnemyIn]; enemyWaveCountWeightTotal = 0f; // Gather the highest rolled indices of the picked waves for (i = 0; i < waveCountToSpawnEnemyIn; i++) { pickedWaveIndices.Add(0); t = 0f; for (p = 0; p < waveCount; p++) { if (wavePickRolls[p] > t) { t = wavePickRolls[p]; pickedWaveIndices[i] = p; } } //Debug.Log(DebugUtilities.AddTimestampPrefix("Wave[" + pickedWaveIndices[i] + "] picked, roll: " + wavePickRolls[pickedWaveIndices[i]])); // Add to enemy count weight total so the amount can be distributed properly enemyWaveCountWeightTotal += waveEnemyCountRolls[pickedWaveIndices[i]]; // Strike down the best pick from the rolls so it won't be considered again wavePickRolls[pickedWaveIndices[i]] = -1f; } pickedWaveIndices.Sort(SortWaves); remainingEnemyCount = enemyCountTotal; Debug.Log(DebugUtilities.AddTimestampPrefix("Round " + (roundIndex + 1) + " will spawn these enemies in " + waveCountToSpawnEnemyIn + " waves")); // Calculate how many enemies to spawn in each chosen wave for (i = 0; i < waveCountToSpawnEnemyIn; i++) { p = pickedWaveIndices[i]; // Get the wave in question or create it if (waves[p] == null) { wave = new ScenarioWave(i, p * waveInterval); waves[p] = wave; } else { wave = waves[p]; } // Last wave should have all the remaining enemies, otherwise floor to int from roll values if (i == waveCountToSpawnEnemyIn - 1) { pickedWaveEnemyCounts[i] = remainingEnemyCount; } else { pickedWaveEnemyCounts[i] = Mathf.Max(Mathf.FloorToInt(enemyCountTotal * waveEnemyCountRolls[p] / enemyWaveCountWeightTotal), 1); remainingEnemyCount -= pickedWaveEnemyCounts[i]; } t = Mathf.Pow(enemyPreset.m_speedMultiplierGain, roundIndex); if (enemyPreset.m_speedMultiplierMax > 1f) { t = Mathf.Clamp(t, 1f, enemyPreset.m_speedMultiplierMax); } Debug.Log(DebugUtilities.AddTimestampPrefix("Wave[" + p + "] will spawn " + pickedWaveEnemyCounts[i] + " enemies of type " + enemyPreset.m_enemyPrefab.name + " with speed multiplier of " + t + " at time " + wave.WaveTime)); // Generate the enemies in this wave waveEnemies = new ScenarioWave.Enemy[pickedWaveEnemyCounts[i]]; for (p = 0; p < pickedWaveEnemyCounts[i]; p++) { // Calculate the speed for each enemy individually enemySpeed = t * Mathf.Lerp(enemyPreset.m_speedMin, enemyPreset.m_speedMax, enemyPreset.m_speedCurve.Evaluate(Random.value)); waveEnemies[p] = new ScenarioWave.Enemy(enemyPreset.m_enemyPrefab, enemyPreset.m_modelPrefab, enemySpeed); } wave.AddEnemies(waveEnemies); } } return(waves); }
public void InitializeScenarioInternal(ScenarioPreset preset) { if (preset == null) { return; } if (m_preset != null) { if (GameManager.ActivePlayerController != null) { Destroy(GameManager.ActivePlayerController.gameObject); } } m_preset = preset; m_currentRound = null; SetupGameArea(); if (m_entities == null) { m_entities = new Dictionary <int, Entity>(); } else { // TODO: Cache entities instead of outright destroying them foreach (Entity e in m_entities.Values) { Destroy(e.gameObject); } m_entities.Clear(); } m_playerScore = 0; m_playerShotsFired = 0; UserInterface.SetScore(m_playerScore); SetHighScore(LoadHighScore()); if (m_preset.m_playerPrefab != null) { Vector3 position = Environment.PlayerSpawn != null ? Environment.PlayerSpawn.position : Vector3.zero; Quaternion rotation = Environment.PlayerSpawn != null ? Environment.PlayerSpawn.rotation : Quaternion.identity; GameObject go = Instantiate <GameObject>(m_preset.m_playerPrefab, position, rotation, Environment.EntityRoot); go.name = m_preset.m_playerPrefab.name; TurretController tc; if (GameManager.State == GameState.Game) { tc = go.GetComponent <PlayerController>(); } else { tc = go.GetComponent <AIController>(); } GameManager.SetActiveTurretController(tc, false); tc.SetCanControl(false); } else { Debug.LogError(DebugUtilities.AddTimestampPrefix("ScenarioPreset doesn't define a player prefab!"), m_preset); } }