using System.Collections.Generic; using UnityEngine; [CreateAssetMenu(menuName = project_name + "/" + nameof(SpawnerTile))] public class SpawnerTile : LevelTile { [SerializeField] private GameObject _prefab; [SerializeField] private bool _spawnOnStart; private float _lifetime; [SerializeField] private float _spawnSpeed = 1.0f; [SerializeField, Range(0, 1.001f)] private float _spawnCounter = 0; private WaveObserver _observer; private bool _stopped = false; private bool _cooldownEnded = false; private bool _EnemiesCleared = true; private List _groupSpawnTimers = new List(); public void SetGroupSpawnTimers(List groupSpawnTimers) { for (int i = 0; i < groupSpawnTimers.Count; i++) { _groupSpawnTimers.Add(groupSpawnTimers[i]); } } public override void LevelStart() { _observer = WaveObserver.Instance; _observer.Attach(this); if (_spawnOnStart && _lifetime <= 0) { TriggerSpawn(_prefab); _observer.NotifyOnStart(this); } } public override void LevelUpdate() { _lifetime += Time.deltaTime; if (!_stopped) { _spawnCounter += Time.deltaTime; } if (_groupSpawnTimers.Count > 0) { if (_lifetime / 60.0f > _groupSpawnTimers[0]) { _EnemiesCleared = _observer.NotifyGroupSpawn(); if (_EnemiesCleared) //Moves on to next group { _groupSpawnTimers.RemoveAt(0); } else //Adds a delay to finish current group { _groupSpawnTimers[0] += GlobalConfig.Instance.Current.groupSpawnDelay; } } } if (_spawnCounter < _spawnSpeed) return; _spawnCounter = 0; if (!_cooldownEnded) { _observer.NotifyEndCooldown(this); _cooldownEnded = true; return; } TriggerSpawn(_prefab); _observer.NotifySpawned(this); } public override bool Equals(ILevelObject other) { return other is SpawnerTile spawner && base.Equals(spawner) && spawner._prefab == _prefab && spawner._spawnSpeed == _spawnSpeed; } public override Dictionary ToDictionary() { var dict = base.ToDictionary(); dict[nameof(_prefab)] = _prefab.name; dict[nameof(_spawnSpeed)] = _spawnSpeed; dict[nameof(_spawnCounter)] = _spawnCounter; dict[nameof(_lifetime)] = _lifetime; dict[nameof(_spawnOnStart)] = _spawnOnStart; return dict; } internal void StopSpawn() { _stopped = true; } internal void StartSpawn() { _stopped = false; } public override void LoadDictionary(Dictionary dict) { base.LoadDictionary(dict); var prefabName = dict[nameof(_prefab)].ToString(); _prefab = Database.Instance.Prefabs[prefabName]; _spawnSpeed = dict[nameof(_spawnSpeed)].ToFloat(); _spawnCounter = dict[nameof(_spawnCounter)].ToFloat(); _lifetime = dict[nameof(_lifetime)].ToFloat(); _spawnOnStart = dict[nameof(_spawnOnStart)].ToBool(); } public GameObject Prefab { set { _prefab = value; } get { return _prefab; } } /** * Called by observer * Assigns a new spawn interval */ public void ChangeSpawnSpeed(float value) { _spawnSpeed = value; } /** * Instantly spawns an enemy. * Used for GroupSpawn */ public void TriggerSpawn(GameObject enemy) { enemy.Create(Position, parent: LevelManager.Instance.LevelTransform); } #if UNITY_EDITOR [Header("DEBUG")] [SerializeField] private GameObject _debugPrefab; public void TriggerSpawnDebug() { _debugPrefab.Create(Position, parent: LevelManager.Instance.LevelTransform); } #endif }