Created Serializable class GroupList in WaveConfig.cs to contain multiple enemy types per group
176 lines
5.3 KiB
C#
176 lines
5.3 KiB
C#
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
|
|
public class WaveObserver : Singleton<WaveObserver>
|
|
{
|
|
private List<SpawnerTile> _subjects = new List<SpawnerTile>();
|
|
private List<float> _aliveEnemyCount = new List<float>();
|
|
private List<int> _copyConstantSpawn;
|
|
private List<GroupList> _copyGroupSpawn;
|
|
private List<float> _groupSpawnTimers;
|
|
private WaveConfig _levelConfig;
|
|
private const int MAXTOUGHNESS = 10;
|
|
private int _spawnerTiming = 0;
|
|
private List<int> _intervalTiming = new List<int>();
|
|
private bool _once = true;
|
|
private int _currentGroupIndex = 0;
|
|
public WaveConfig LevelConfig
|
|
{
|
|
set
|
|
{
|
|
_levelConfig = value;
|
|
_copyConstantSpawn = new List<int>();
|
|
_copyGroupSpawn = new List<GroupList>();
|
|
_groupSpawnTimers = new List<float>();
|
|
foreach (EnemyType enemy in _levelConfig.ConstantSpawn)
|
|
{
|
|
_copyConstantSpawn.Add(enemy.Count);
|
|
}
|
|
for (int index = 0; index < _levelConfig.NestedGroupSpawn.Count; index++)
|
|
{
|
|
_copyGroupSpawn.Add(_levelConfig.NestedGroupSpawn[index]);
|
|
_groupSpawnTimers.Add(_levelConfig.NestedGroupSpawn[index].triggerTime);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Called by spawner at the start of the game
|
|
* Assigns enemy to spawn and registers them
|
|
*/
|
|
public void Attach(SpawnerTile spawnerSubject)
|
|
{
|
|
|
|
spawnerSubject.Prefab = _levelConfig.GetRandomSpawn().GetEnemyObject();
|
|
_subjects.Add(spawnerSubject);
|
|
_aliveEnemyCount.Add(0);
|
|
_intervalTiming.Add(++_spawnerTiming);
|
|
// Ensures that only one spawner keeps track of the grouped spawn timer.
|
|
if (_once)
|
|
{
|
|
_once = false;
|
|
spawnerSubject.GroupSpawnTimers = _groupSpawnTimers;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Called by spawner when making enemies
|
|
* Assigns a new interval
|
|
*/
|
|
public void NotifySpawned(SpawnerTile spawnerSubject)
|
|
{
|
|
GameObject paramPrefab = spawnerSubject.Prefab;
|
|
spawnerSubject.ChangeSpawnSpeed(_levelConfig.GetInterval() * _spawnerTiming);
|
|
if (paramPrefab.Equals(_levelConfig.ConstantSpawn[0].GetEnemyObject()))
|
|
{
|
|
int currentCount = 0;
|
|
for (int i = 0; i < _copyConstantSpawn.Count; i++)
|
|
{
|
|
if (_levelConfig.ConstantSpawn[i].GetEnemyObject() == paramPrefab)
|
|
{
|
|
currentCount = --_copyConstantSpawn[i];
|
|
break;
|
|
}
|
|
}
|
|
if (currentCount <= 0)
|
|
{
|
|
foreach (SpawnerTile spawner in _subjects)
|
|
{
|
|
if (spawner.Prefab.Equals(paramPrefab))
|
|
{
|
|
spawner.StopSpawn();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Called by enemy when they spawn
|
|
* Keeps track of their row
|
|
*/
|
|
public int NotifyEnemy(float yPosition, float toughness)
|
|
{
|
|
int index = FindEnemyIndex(yPosition);
|
|
_aliveEnemyCount[index] += toughness;
|
|
if (_aliveEnemyCount[index] >= MAXTOUGHNESS)
|
|
{
|
|
_subjects[index].StopSpawn();
|
|
}
|
|
return index;
|
|
}
|
|
|
|
/**
|
|
* Called when an enemy dies
|
|
* Reactivates spawning on that row if disabled before
|
|
*/
|
|
public void NotifyDies(int position, float toughness)
|
|
{
|
|
_aliveEnemyCount[position] -= toughness;
|
|
if (_aliveEnemyCount[position] < MAXTOUGHNESS)
|
|
{
|
|
_subjects[position].StartSpawn();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Called when an enemy is spawned automatically at the start of the game
|
|
* Adjusts the intervall between spawns
|
|
*/
|
|
public void NotifyOnStart(SpawnerTile spawnerSubject)
|
|
{
|
|
float interval = _levelConfig.GetUpdatedInterval();
|
|
foreach (var subject in _subjects)
|
|
{
|
|
subject.ChangeSpawnSpeed(interval);
|
|
}
|
|
NotifySpawned(spawnerSubject);
|
|
}
|
|
|
|
// To find which spawner an ennemy came from.
|
|
private int FindEnemyIndex(float yPosition)
|
|
{
|
|
for (int i = 0; i < _subjects.Count; i++)
|
|
{
|
|
if (_subjects[i].Position.y == yPosition)
|
|
{
|
|
return i;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
/**
|
|
* Spawners wait 1 second to have time to register them all
|
|
* Then gets assigned a random spawn interval
|
|
*/
|
|
public void NotifyEndCooldown(SpawnerTile spawnerTile)
|
|
{
|
|
System.Random rand = new System.Random();
|
|
int index;
|
|
do
|
|
{
|
|
index = rand.Next(_subjects.Count);
|
|
} while (_intervalTiming.Count <= index);
|
|
spawnerTile.ChangeSpawnSpeed(_levelConfig.GetInterval() * _intervalTiming[index]);
|
|
_intervalTiming.Remove(index);
|
|
}
|
|
|
|
/**
|
|
* Called when it is time to spawn a group
|
|
* Assigns a random element of the group to a random spawner
|
|
*/
|
|
public void NotifyGroupSpawn()
|
|
{
|
|
System.Random rand = new System.Random();
|
|
foreach (EnemyType groupEnemy in _copyGroupSpawn[_currentGroupIndex].groupSpawn)
|
|
{
|
|
for (int i = 0; i < groupEnemy.Count; i++)
|
|
{
|
|
_subjects[rand.Next(_subjects.Count)].TriggerSpawn(groupEnemy.GetEnemyObject());
|
|
}
|
|
}
|
|
_currentGroupIndex++;
|
|
}
|
|
}
|