public int randomWaveNumber = 0; // assigned and only used for random sorting. // ReSharper restore InconsistentNaming /// <summary> /// Call this method to clone the wave (used by clone icon in Inspector) /// </summary> /// <returns>A deep copy of the wave.</returns> public LevelWave Clone() { var clone = new LevelWave { waveType = waveType, skipWaveType = skipWaveType, skipWavePassCriteria = skipWavePassCriteria, waveName = waveName, musicSettings = musicSettings, WaveDuration = WaveDuration, endEarlyIfAllDestroyed = endEarlyIfAllDestroyed, waveBeatBonusesEnabled = waveBeatBonusesEnabled, useCompletionEvents = useCompletionEvents, completionCustomEvents = completionCustomEvents, waveDefeatVariableModifiers = waveDefeatVariableModifiers, isExpanded = isExpanded }; return clone; }
public int randomWaveNumber = 0; // assigned and only used for random sorting. // ReSharper restore InconsistentNaming /// <summary> /// Call this method to clone the wave (used by clone icon in Inspector) /// </summary> /// <returns>A deep copy of the wave.</returns> public LevelWave Clone() { var clone = new LevelWave { waveType = waveType, skipWaveType = skipWaveType, skipWavePassCriteria = skipWavePassCriteria, waveName = waveName, musicSettings = musicSettings, WaveDuration = WaveDuration, endEarlyIfAllDestroyed = endEarlyIfAllDestroyed, waveBeatBonusesEnabled = waveBeatBonusesEnabled, useCompletionEvents = useCompletionEvents, completionCustomEvents = completionCustomEvents, waveDefeatVariableModifiers = waveDefeatVariableModifiers, isExpanded = isExpanded }; return(clone); }
// Return true to skip wave, false means we started spawning the wave. private bool SpawnOrSkipNewWave(LevelWave waveInfo) { var skipThisWave = true; if (enableWaveWarp) { // check for Custom Start Wave and skip all before it if (CurrentLevel < startLevelNumber.Value - 1) { return true; // skip } if (CurrentLevel == startLevelNumber.Value - 1 && CurrentLevelWave < startWaveNumber.Value - 1) { return true; // skip } enableWaveWarp = false; // should only happen once after you pass the warped wave. } if (waveInfo.skipWavePassCriteria.statMods.Count == 0 || waveInfo.skipWaveType == SkipWaveMode.None) { skipThisWave = false; } if (skipThisWave) { switch (waveInfo.skipWaveType) { case SkipWaveMode.Always: break; case SkipWaveMode.IfWorldVariableValueAbove: if (!SkipWaveOrNot(waveInfo, true)) { skipThisWave = false; } break; case SkipWaveMode.IfWorldVariableValueBelow: if (!SkipWaveOrNot(waveInfo, false)) { skipThisWave = false; } break; } } if (skipThisWave) { if (listener != null) { listener.WaveSkipped(waveInfo); } return true; } SpawnNewWave(waveInfo, false); return false; }
private void SpawnNewWave(LevelWave waveInfo, bool isRestartWave) { EliminationSpawnersUnkilled.Clear(); SpawnedItemsRemaining.Clear(); WaveRemainingItemsChanged(); foreach (var syncro in _syncroSpawners) { if (!syncro.WaveChange(isRestartWave)) { // returns true if wave found. continue; } switch (waveInfo.waveType) { case WaveType.Elimination: EliminationSpawnersUnkilled.Add(syncro.GetInstanceID(), syncro); break; case WaveType.Timed: EliminationSpawnersUnkilled.Add(syncro.GetInstanceID(), syncro); TimeRemainingInCurrentWave = CurrentWaveInfo.WaveDuration; break; } } if (listener != null) { listener.WaveStarted(CurrentWaveInfo); } }
private IEnumerator CoUpdate() { while (true) { yield return _loopDelay; // respawn timers if (PrefabsToRespawn.Count > 0) { var respawnedIndexes = new List<int>(); for (var i = 0; i < PrefabsToRespawn.Count; i++) { var p = PrefabsToRespawn[i]; if (Time.realtimeSinceStartup < p.TimeToRespawn) { continue; } var spawned = PoolBoss.SpawnInPool(p.PrefabToRespawn, p.Position, p.PrefabToRespawn.rotation); if (spawned == null) { continue; } respawnedIndexes.Add(i); } // ReSharper disable once ForCanBeConvertedToForeach for (var i = 0; i < respawnedIndexes.Count; i++) { PrefabsToRespawn.RemoveAt(respawnedIndexes[i]); } } if (_gameIsOver || _wavesArePaused || !useWaves) { continue; } //check if level or wave is done. if (_hasFirstWaveBeenStarted && !_skipCurrentWave) { var timeToCompare = ActiveWaveInfo.WaveDuration; var waveType = ActiveWaveInfo.waveType; switch (waveType) { case WaveType.Timed: var tempTime = (int)(timeToCompare - (Time.time - _lastWaveChangeTime)); // ReSharper disable once RedundantCheckBeforeAssignment if (tempTime != TimeRemainingInCurrentWave) { TimeRemainingInCurrentWave = tempTime; } var allDead = ActiveWaveInfo.endEarlyIfAllDestroyed && EliminationSpawnersUnkilled.Count == 0; if (!allDead && Time.time - _lastWaveChangeTime < timeToCompare) { continue; } EndCurrentWaveNormally(); break; case WaveType.Elimination: if (EliminationSpawnersUnkilled.Count > 0) { continue; } EndCurrentWaveNormally(); break; } } if (_skipCurrentWave && listener != null) { listener.WaveEndedEarly(CurrentWaveInfo); } bool waveSkipped; do { var waveInfo = CurrentWaveInfo; if (!disableSyncroSpawners) { // notify all synchro spawners waveSkipped = SpawnOrSkipNewWave(waveInfo); if (waveSkipped) { if (isLoggingOn) { Debug.Log("Wave skipped - wave# is: " + (_currentLevelWave + 1) + " on Level: " + (_currentLevel + 1)); } } else { waveSkipped = false; } } else { waveSkipped = false; } LevelWaveMusicSettings musicSpec = null; // change music maybe if (_currentLevel > 0 && _currentLevelWave == 0) { if (isLoggingOn) { Debug.Log("Level up - new level# is: " + (_currentLevel + 1) + " . Wave 1 starting, occurred at time: " + Time.time); } musicSpec = waveInfo.musicSettings; } else if (_currentLevel > 0 || _currentLevelWave > 0) { if (isLoggingOn) { Debug.Log("Wave up - new wave# is: " + (_currentLevelWave + 1) + " on Level: " + (_currentLevel + 1) + ". Occured at time: " + Time.time); } musicSpec = waveInfo.musicSettings; } else if (_currentLevel == 0 && _currentLevelWave == 0) { musicSpec = waveInfo.musicSettings; } _previousWave = CurrentWaveInfo; _currentLevelWave++; if (_currentLevelWave >= WaveLengths.Count) { _currentLevelWave = 0; var completedLevel = _currentLevel; _currentLevel++; if (!_gameIsOver && _currentLevel >= _waveSettingsByLevel.Count) { switch (repeatLevelMode) { case LevelLoopMode.RepeatAllLevelsFromBeginning: if (IsLoggingOn) { Debug.Log("Levels restarting from beginning!"); } musicSpec = null; if (LevelTimes[completedLevel].waveOrder == WaveOrder.RandomOrder) { var allWaves = _waveSettingsByLevel[completedLevel]; // ReSharper disable once ForCanBeConvertedToForeach for (var i = 0; i < allWaves.Count; i++) { var aWave = allWaves[i]; aWave.randomWaveNumber = Random.Range(0, allWaves.Count); } allWaves.Sort(delegate(LevelWave x, LevelWave y) { return x.randomWaveNumber.CompareTo(y.randomWaveNumber); }); } GotoWave(1, 1); break; case LevelLoopMode.Win: musicSpec = gameOverMusicSettings; Win(); IsGameOver = true; break; } } } PlayMusicIfSet(musicSpec); } while (waveSkipped); _lastWaveChangeTime = Time.time; _hasFirstWaveBeenStarted = true; _skipCurrentWave = false; } // ReSharper disable once FunctionNeverReturns }
// ReSharper disable once UnusedMember.Local private void Awake() { useGUILayout = false; _trans = transform; // Global waves should only be launched from the server. if (!PoolBoss.IsServer) { return; } _hasFirstWaveBeenStarted = false; _isValid = true; _wavesArePaused = false; var iLevel = 0; _currentLevel = 0; _currentLevelWave = 0; _previousWave = null; _skipCurrentWave = false; if (persistBetweenScenes) { DontDestroyOnLoad(gameObject); } if (useWaves) { if (LevelTimes.Count == 0) { LogIfNew("NO LEVEL / WAVE TIMES DEFINED. ABORTING."); _isValid = false; return; } if (LevelTimes[0].WaveSettings.Count == 0) { LogIfNew("NO LEVEL 1 / WAVE 1 TIME DEFINED! ABORTING."); _isValid = false; return; } } var levelSettingScripts = FindObjectsOfType(typeof(LevelSettings)); if (levelSettingScripts.Length > 1) { LogIfNew( "You have more than one LevelWaveSettings prefab in your scene. Please delete all but one. Aborting."); _isValid = false; return; } _waveSettingsByLevel = new Dictionary<int, List<LevelWave>>(); // ReSharper disable once TooWideLocalVariableScope List<LevelWave> waveLs; for (var i = 0; i < LevelTimes.Count; i++) { var level = LevelTimes[i]; if (level.WaveSettings.Count == 0) { LogIfNew("NO WAVES DEFINED FOR LEVEL: " + (iLevel + 1)); _isValid = false; continue; } waveLs = new List<LevelWave>(); LevelWave newLevelWave; var w = 0; foreach (var waveSetting in level.WaveSettings) { if (waveSetting.WaveDuration <= 0) { LogIfNew("WAVE DURATION CANNOT BE ZERO OR LESS - OCCURRED IN LEVEL " + (i + 1) + "."); _isValid = false; return; } newLevelWave = new LevelWave() { waveType = waveSetting.waveType, WaveDuration = waveSetting.WaveDuration, musicSettings = new LevelWaveMusicSettings() { WaveMusicMode = waveSetting.musicSettings.WaveMusicMode, WaveMusicVolume = waveSetting.musicSettings.WaveMusicVolume, WaveMusic = waveSetting.musicSettings.WaveMusic, FadeTime = waveSetting.musicSettings.FadeTime }, waveName = waveSetting.waveName, waveDefeatVariableModifiers = waveSetting.waveDefeatVariableModifiers, useCompletionEvents = waveSetting.useCompletionEvents, completionCustomEvents = waveSetting.completionCustomEvents, waveBeatBonusesEnabled = waveSetting.waveBeatBonusesEnabled, skipWaveType = waveSetting.skipWaveType, skipWavePassCriteria = waveSetting.skipWavePassCriteria, sequencedWaveNumber = w, endEarlyIfAllDestroyed = waveSetting.endEarlyIfAllDestroyed, pauseGlobalWavesWhenCompleted = waveSetting.pauseGlobalWavesWhenCompleted }; if (waveSetting.waveType == WaveType.Elimination) { newLevelWave.WaveDuration = 500; // super long to recognize this problem if it occurs. } waveLs.Add(newLevelWave); w++; } var sequencedWaves = new List<LevelWave>(); switch (level.waveOrder) { case WaveOrder.SpecifiedOrder: sequencedWaves.AddRange(waveLs); break; case WaveOrder.RandomOrder: while (waveLs.Count > 0) { var randIndex = Random.Range(0, waveLs.Count); sequencedWaves.Add(waveLs[randIndex]); waveLs.RemoveAt(randIndex); } break; } if (i == LevelTimes.Count - 1) { // extra bogus wave so that the real last wave will get run newLevelWave = new LevelWave() { musicSettings = new LevelWaveMusicSettings() { WaveMusicMode = WaveMusicMode.KeepPreviousMusic, WaveMusic = null }, WaveDuration = 1, sequencedWaveNumber = w }; sequencedWaves.Add(newLevelWave); } _waveSettingsByLevel.Add(iLevel, sequencedWaves); iLevel++; } // ReSharper disable once TooWideLocalVariableScope WaveSyncroPrefabSpawner spawner; foreach (var gObj in GetAllSpawners) { spawner = gObj.GetComponent<WaveSyncroPrefabSpawner>(); _syncroSpawners.Add(spawner); } _waveTimeRemaining = 0; SpawnedItemsRemaining.Clear(); _gameIsOver = false; _hasPlayerWon = false; // ReSharper disable once InvertIf if (initializationSettingsExpanded) { // ReSharper disable once ForCanBeConvertedToForeach for (var i = 0; i < initializationCustomEvents.Count; i++) { var anEvent = initializationCustomEvents[i].CustomEventName; FireCustomEventIfValid(anEvent, _trans.position); } } }
private static bool SkipWaveOrNot(LevelWave waveInfo, bool valueAbove) { var skipThisWave = true; // ReSharper disable once ForCanBeConvertedToForeach for (var i = 0; i < waveInfo.skipWavePassCriteria.statMods.Count; i++) { var stat = waveInfo.skipWavePassCriteria.statMods[i]; var variable = WorldVariableTracker.GetWorldVariable(stat._statName); if (variable == null) { skipThisWave = false; break; } var varVal = stat._varTypeToUse == WorldVariableTracker.VariableType._integer ? variable.CurrentIntValue : variable.CurrentFloatValue; var compareVal = stat._varTypeToUse == WorldVariableTracker.VariableType._integer ? stat._modValueIntAmt.Value : stat._modValueFloatAmt.Value; if (valueAbove) { if (!(varVal < compareVal)) { continue; } skipThisWave = false; break; } else { if (!(varVal > compareVal)) { continue; } skipThisWave = false; break; } } return skipThisWave; }
/// <summary> /// This method gets called when a Global Wave ends, just before the next one starts. /// </summary> public virtual void WaveEnded(LevelWave levelWaveInfo) { // your code here. }
/// <summary> /// This method gets called when a Global Wave restarts. /// </summary> public virtual void WaveRestarted(LevelWave levelWaveInf) { // your code here. }
private void AddBonusStatModifier(string modifierName, LevelWave waveSpec) { if (waveSpec.waveDefeatVariableModifiers.HasKey(modifierName)) { DTInspectorUtility.ShowAlert("This Wave already has a modifier for World Variable: " + modifierName + ". Please modify that instead."); return; } UndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _settings, "add Wave Completion Bonus modifier"); var vType = WorldVariableTracker.GetWorldVariableScript(modifierName); waveSpec.waveDefeatVariableModifiers.statMods.Add(new WorldVariableModifier(modifierName, vType.varType)); }
private void AddWaveSkipLimit(string modifierName, LevelWave spec) { if (spec.skipWavePassCriteria.HasKey(modifierName)) { DTInspectorUtility.ShowAlert("This wave already has a Skip Wave Limit for World Variable: " + modifierName + ". Please modify the existing one instead."); return; } var myVar = WorldVariableTracker.GetWorldVariableScript(modifierName); UndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _settings, "add Skip Wave Limit"); spec.skipWavePassCriteria.statMods.Add(new WorldVariableModifier(modifierName, myVar.varType)); }
private void CreateNewLevelAfter(int? index = null) { var spawners = LevelSettings.GetAllSpawners; var newLevel = new LevelSpecifics(); var newWave = new LevelWave(); newLevel.WaveSettings.Add(newWave); int newLevelIndex; if (index == null) { newLevelIndex = _settings.LevelTimes.Count; } else { newLevelIndex = index.Value + 1; } UndoHelper.RecordObjectPropertyForUndo(ref _isDirty, _settings, "Add Level"); _settings.LevelTimes.Insert(newLevelIndex, newLevel); foreach (var spawner in spawners) { var spawnerScript = spawner.GetComponent<WaveSyncroPrefabSpawner>(); spawnerScript.InsertLevel(newLevelIndex); } }
private static void InsertWaveAfter(LevelSpecifics spec, int waveToInsertAt, int level) { var spawners = LevelSettings.GetAllSpawners; var newWave = new LevelWave(); waveToInsertAt++; spec.WaveSettings.Insert(waveToInsertAt, newWave); foreach (var spawner in spawners) { var spawnerScript = spawner.GetComponent<WaveSyncroPrefabSpawner>(); spawnerScript.InsertWave(waveToInsertAt, level); } }
/// <summary> /// This method gets called when a Global Wave ends early. /// </summary> public virtual void WaveEndedEarly(LevelWave levelWaveInfo) { // your code here. }
/// <summary> /// This method gets called when a Global Wave restarts. /// </summary> public virtual void WaveRestarted(LevelWave levelWaveInf) { // your code here. }
/// <summary> /// This method gets called when a Global Wave is skipped through Skip Wave criteria or other means. /// </summary> public virtual void WaveSkipped(LevelWave levelWaveInfo) { // your code here. }