Wave Script | Restarting Help

Hello! I’m working on a wave game as in waves of zombies.

This is my script for the spawning etc:

local lobbySpawn = workspace:WaitForChild("LobbySpawn")  -- Lobby spawn point where the player initially spawns
local spawnLocation = workspace:WaitForChild("SpawnLocation")  -- Actual spawn location where the player fights zombies
local updateUI = game.ReplicatedStorage:WaitForChild("UpdateUI")  -- RemoteEvent for UI updates

local zombiesPerWave = 5  -- Base number of zombies per wave
local maxWaves = 20  -- Set to 20 waves
local ToolsToGive = {  -- List of tool names to give to the players when wave starts
	"Sword",          -- Replace with your actual tool names in the game
	"Hammer",
	"Gun",
	"Fists"           -- Added "Fists" to the list of tools to be given
}

local PlayersTools = {}  -- To store players' removed tools

-- Function to check if all zombies have been cleared
local function allZombiesCleared()
	local remainingZombies = 0
	for _, obj in pairs(workspace:GetChildren()) do
		if obj:IsA("Model") and (obj.Name == "Zombie" or obj.Name == "TankZombie") then
			remainingZombies = remainingZombies + 1
		end
	end
	return remainingZombies == 0
end

-- Function to spawn zombies in a wave
local function spawnWave(waveNumber)
	local waveZombies = zombiesPerWave + waveNumber  -- Increase zombies per wave based on wave number
	local spawnRadius = 5  -- Random spawn radius around spawn location for variety

	-- Only spawn TankZombies from wave 5 and onwards
	for i = 1, waveZombies do  -- Spawn one zombie at a time
		local newZombie
		if waveNumber >= 5 and i % 5 == 0 then  -- Every 5th zombie is a TankZombie from wave 5 onwards
			newZombie = tankZombieModel:Clone()
		else
			newZombie = zombieModel:Clone()  -- Regular zombie
		end

		newZombie.Parent = workspace  -- Parent it to the workspace

		-- Randomly select a spawn location from the list of spawn locations
		local randomSpawnLocation = spawnLocations[math.random(1, #spawnLocations)]  -- Spawn at a random location

		-- Randomize the spawn position within a small radius around the selected spawn location
		local randomOffset = Vector3.new(math.random(-spawnRadius, spawnRadius), 0, math.random(-spawnRadius, spawnRadius))
		newZombie:SetPrimaryPartCFrame(randomSpawnLocation.CFrame * CFrame.new(randomOffset))  -- Position it at a random spot near the selected spawn location

		-- Ensure zombies are cleaned up when they die
		local humanoid = newZombie:WaitForChild("Humanoid")
		humanoid.Died:Connect(function()
			newZombie:Destroy()  -- Destroy zombie when it dies
		end)

		-- Wait 3 seconds before spawning the next zombie
		wait(3)  -- Small delay to spawn zombies every 3 seconds
	end
end

-- Function to start the waves
local function startWaves()
	for waveNumber = 1, maxWaves do
		print("Wave " .. waveNumber .. " starting!")  -- Debugging output in the console

		-- Countdown before each wave
		for remainingTime = 10, 1, -1 do
			print("Sending countdown: " .. remainingTime)  -- Debugging output for the countdown timer

			-- Send countdown info to the client (UI update)
			updateUI:FireAllClients(waveNumber, remainingTime)

			-- Wait 1 second between each countdown step
			wait(1)
		end

		-- Send the final "0" second mark
		updateUI:FireAllClients(waveNumber, 0)

		-- When countdown reaches 0, spawn the zombies
		spawnWave(waveNumber)  -- Spawn the zombies for this wave

		-- Wait until all zombies are cleared before starting the next wave
		repeat
			wait(1)  -- Wait 1 second before checking again
		until allZombiesCleared()  -- Check if all zombies are cleared

		print("Wave " .. waveNumber .. " has finished spawning!")
	end
end

-- Function to handle player joining
local function handlePlayerJoin(player)
	-- Set the player's spawn point to LobbySpawn initially
	player.RespawnLocation = lobbySpawn

	-- Initialize player tools storage
	PlayersTools[player.UserId] = {}

	-- Remove any tools the player may have
	for _, tool in pairs(player.Backpack:GetChildren()) do
		if tool:IsA("Tool") then
			table.insert(PlayersTools[player.UserId], tool)  -- Store the tool
			tool:Destroy()  -- Remove the tool from the player
		end
	end

	-- Make sure "Fists" is not automatically equipped to the player
	local character = player.Character or player.CharacterAdded:Wait()
	local fistsTool = character:FindFirstChild("Fists")
	if fistsTool then
		fistsTool:Destroy()  -- Remove the "Fists" tool if it was added to the character
	end

	-- Intermission when player joins (30 seconds)
	local intermissionTime = 30
	for remainingTime = intermissionTime, 1, -1 do
		-- Send the intermission countdown to the client (UI update)
		updateUI:FireClient(player, "Intermission", remainingTime)
		wait(1)
	end

	-- Send final message before the first wave
	updateUI:FireClient(player, "Wave", 1)

	-- Now teleport the player to the SpawnLocation for the fight
	if player.Character then
		player.Character:SetPrimaryPartCFrame(spawnLocation.CFrame)
		local Players = game:GetService("Players")
		local Teams = game:GetService("Teams")

		-- Ensure the "Players" team exists
		local playersTeam = Teams:FindFirstChild("Players")
		if not playersTeam then
			playersTeam = Instance.new("Team")
			playersTeam.Name = "Players"
			playersTeam.Parent = Teams
		end

		-- Function to add player to the "Players" team
		local function addPlayerToTeam(player)
			player.Team = playersTeam
		end

		-- Connect the function to PlayerAdded event
		Players.PlayerAdded:Connect(addPlayerToTeam)

		-- Also add existing players to the team
		for _, player in Players:GetPlayers() do
			addPlayerToTeam(player)
		end
	end

	-- Start the wave system after the intermission
	startWaves()

	-- After the wave starts, give back the tools to the player
	-- Give tools to the player at the beginning of each wave
	for _, toolName in ipairs(ToolsToGive) do
		local tool = game.ServerStorage:FindFirstChild(toolName)  -- Make sure tool exists in ServerStorage
		if tool then
			local clonedTool = tool:Clone()
			clonedTool.Parent = player.Backpack
		end
	end
end

-- Event listener for when a player joins
game.Players.PlayerAdded:Connect(handlePlayerJoin)

And I’m looking to get it to restart the intermission when all the players are in the spectators team. If you can help that would be greatly appreciated ! ! !

-sodasquid :slightly_smiling_face:

1 Like

Excuse me if I’m wrong but, can’t you just do this (?):

local Players = game:GetService("Players")
local Spectators = 0

for _, Player in Players:GetPlayers() do
	if Player.Team.Name == "Spectator" then --Or your team's name
		Spectators += 1
	end
end

if Spectators == #Players:GetPlayers() then
	-- Do what you want to do
end
2 Likes

Ah Thank you. That must’ve slipped my mind!

2 Likes

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.