WaveManager = {} local WaveManager = WaveManager local Array = assert(Array, "array.lua is required for wave-manager.lua") assert(Config and Config.Wave, "wave-config is required for wave-manager.lua.") local Config = Config WaveManager.waveNum = Config.initWaveNum or 1 WaveManager.waveTime = 0 WaveManager.waves = {} WaveManager.getWaveNum = function() return WaveManager.waveNum end WaveManager.getWaveTime = function() return WaveManager.waveTime end WaveManager.getWave = function(num) assert(num, "Invalid num argument.") return WaveManager.waves[num] end WaveManager.setWaveNum = function(value) assert(value, "Invalid value argument") WaveManager.waveNum = value end WaveManager.setTime = function(value) assert(value and value >= 0, "Invalid v argument.") WaveManager.time = value end WaveManager.setWave = function(num, types) num = num or WaveManager.waveNum assert(types, "Invalid types argument") WaveManager.waves[num] = types end WaveManager.incWaveNum = function(num) num = num or 1 WaveManager.waveNum = WaveManager.waveNum + num end local assignActors = function(types) local spawns = Array.map(Spawn.getSpawns(), function(spawn) return {actors = {}, spawn = spawn} end) local actors = Array.map(types, function(t) return Actor.Create(t, false, {Owner = Config.waveOwner, Location = CPos.New(0, 0)}) end) for _, actor in ipairs(actors) do local spawn = Utils.Random(spawns) table.insert(spawn.actors, actor) end return spawns, actors end local attachIdleTrigger = function(actor, target) Trigger.OnIdle(actor, function() actor.EnterTransport(target) end) end local function timedDelay(func) assert(func, "Invalid func argument") if (Interface.time > 0) then Interface.time = Interface.time - 1 Trigger.AfterDelay(1, function() timedDelay(func) end) else func() end end local setTimedWaveEnd = function(time, func) assert(time and time > 0, "Invalid time argument.") assert(func, "Invalid func argument.") Interface.time = time timedDelay(func) end WaveManager.sendWave = function(wave, time, deadFunc) if (wave) then WaveManager.waves[WaveManager.waveNum] = wave else wave = assert(WaveManager.waves[WaveManager.waveNum], "No wave provided.") end if (not next(wave)) then deadFunc() return {} end local spawns, actors = assignActors(wave) for _, spawn in ipairs(spawns) do local count = 0 local enterID = Trigger.OnEnteredFootprint({spawn.spawn.Location}, function(a) if (a.Type ~= spawn.spawn.Type) then count = count + 1 end end) Trigger.OnExitedFootprint({spawn.spawn.Location}, function(a, exitID) count = count - 1 if (count == 0) then Trigger.AfterDelay(Config.spawnDelay, function() if (#spawn.actors > 0) then local a = table.remove(spawn.actors) a.Teleport(spawn.spawn.Location) a.IsInWorld = true attachIdleTrigger(a, Utils.Random(Spawn.getSpawnTargets(spawn.spawn))) else Trigger.RemoveFootprintTrigger(enterID) Trigger.RemoveFootprintTrigger(exitID) end end) end end) if (#spawn.actors > 0) then local a = table.remove(spawn.actors, 1) a.Teleport(spawn.spawn.Location) a.IsInWorld = true attachIdleTrigger(a, Utils.Random(Spawn.getSpawnTargets(spawn.spawn))) end end if (deadFunc) then Trigger.OnAllKilled(actors, deadFunc) end if (time and time > 0) then setTimedWaveEnd(time, function() Array.map(spawns, function(spawn) spawn.actors = {} end) Array.map(actors, function(a) if (not a.IsDead) then a.Kill() end end) end) end return actors end