Making players spectate on death, then respawn next round

I’ve decided to make a gamemode for learning purposes and to practice GLUA, I’m have issues setting up spectating and team switching on death.
Basically I’m trying to make a dead player change to a different team then spectate, then when the round ends change them back to the “alive” team and let them spawn again. Also I don’t want players who join in the middle of the round so I want them to join in on the spectator team so that people can’t abuse it.

init.lua


local fol = GM.FolderName.."/gamemode/modules/"
local files, folders = file.Find(fol .. "*", "LUA")



for k,v in pairs(files) do
	include(fol .. v)
end


for _, folder in SortedPairs(folders, true) do
	if folder == "." or folder == ".." then continue end

	for _, File in SortedPairs(file.Find(fol .. folder .."/sh_*.lua", "LUA"), true) do
		AddCSLuaFile(fol..folder .. "/" ..File)
		include(fol.. folder .. "/" ..File)
	end
end
for _, folder in SortedPairs(folders, true) do
	if folder == "." or folder == ".." then continue end

	for _, File in SortedPairs(file.Find(fol .. folder .."/sv_*.lua", "LUA"), true) do
		include(fol.. folder .. "/" ..File)
	end
end

for _, folder in SortedPairs(folders, true) do
	if folder == "." or folder == ".." then continue end

	for _, File in SortedPairs(file.Find(fol .. folder .."/cl_*.lua", "LUA"), true) do
		AddCSLuaFile(fol.. folder .. "/" ..File)
	end
end

local TEAM_SPEC, TEAM_NEUTRAL = 1, 2
local alivePlayers = 0

round = {}
round.Break	= 10
round.Time	= 20
round.TimeLeft = -1
round.Breaking = false

function GM:PlayerSpawn( ply )
	
	--if !round.Breaking then
		--ply:SetTeam(TEAM_SPEC)
	--else
		--ply:SetTeam(TEAM_NEUTRAL)
	--end

	if ply:Team() == TEAM_NEUTRAL then
		ply:SetModel("models/player/pheonix.mdl")
		ply:SetGravity(1)
		ply:SetWalkSpeed(250)
		ply:SetRunSpeed(500)
		ply:SetCrouchedWalkSpeed(0.5)
		ply:SetDuckSpeed(0.5)
	end
	
	
end

function GM:DoPlayerDeath( ply, wep, killer )
	ply:Spectate( OBS_MODE_CHASE )
	ply:SpectateEntity( killer )
end

function round.Broadcast(Text)
	for k, v in pairs(player.GetAll()) do
		v:ConCommand("play buttons/button17.wav")
		v:ChatPrint(Text)
	end
end


function round.Begin(ply)
	for _, v in pairs(player.GetAll()) do
		AddSpawnpoints()
		if not v:Alive() then
			if ply:Team() != 2 then 
				ply:SetTeam(2)
			end
			--v:Spawn()
		end
	end	
	round.Broadcast("Round starting! Round ends in " .. round.Time .. " seconds!")
	round.TimeLeft = round.Time
end

function round.End()
	round.Broadcast("Round over! Next round in " .. round.Break .. " seconds!")
	ply:KillSilent()
	GAMEMODE:ClearClientState()
	GAMEMODE:CleanUpMap()
	ply:Spectate( OBS_MODE_NONE )
	round.TimeLeft = round.Break
end

function round.Handle()
	if (round.TimeLeft == -1) then
		if ( alivePlayers >= 1) then
			round.Begin()
			return
		end
	end
	round.TimeLeft = round.TimeLeft - 1
	if (round.TimeLeft == 0) then
		if (round.Breaking) then
			if ( alivePlayers >= 2) then
				round.Begin()
				round.Breaking = false
			end
		else
			round.End()
			round.Breaking = true
		end
	end
	
end
timer.Create("round.Handle", 1, 0, round.Handle)

function GM:PlayerSelectSpawn(ply)
	local spawnpoints
	local i
		spawnpoints = ents.FindByClass("spawns")
		i = math.random(#spawnpoints)
		return spawnpoints*
end

function AddSpawnpoints()
	local spawn_points = {
		Vector(-11431.851563, 11290.193359, 353.031250),
		Vector(-9055.885742, 13388.874023, 217.037521),
		Vector(-11781.977539, 11343.624023, 353.031250)
	}
	local map = {
		"rp_headattackcity_v1"
	}
	timer.Simple(3, function()
		if game.GetMap() == table.Random(map) then
			local crate = ents.Create("spawns")
			if not crate:IsValid() then return end
			crate:SetPos(table.Random(spawn_points))
			crate:Spawn()
			crate:DropToFloor()
		end
	end)
end
hook.Add("InitPostEntity", "AddSpawnpoints", AddSpawnpoints)

local function AlivePlayers()
	for k,v in pairs(player.GetAll()) do
		if v:Alive() then
			alivePlayers = alivePlayers + 1
		end
	end
	return alivePlayers
end


hook.Add("PlayerDeath", "checkAlivePlayers", function()
	if AlivePlayers() <= 1 then
		round.End()
	end
end)

I don’t understand this. I have mixed this code around at least 10 times trying to get players spectating on death and respawn when the round ends. The code is probably kind of messed up because of the many times I’ve tried new things to get it working. If anyone has any suggestions please feel free to share.

Thank you all so much for the help you provide and the time you take to aid us that have less knowledge.

I’ve tried more things lol.


PLAYER 	= FindMetaTable( "Player" );

local TEAM_SPEC, TEAM_NEUTRAL = 1, 2
local alivePlayers = 0

round = {}
round.Break	= 10
round.Time	= 20
round.TimeLeft = -1
round.Breaking = false

function PLAYER:Unassigned( )
	if ( self:Team( ) == TEAM_UNASSIGNED || self:Team( ) == TEAM_SPECTATOR ) then
		return true;
	end

	return false;
end

function PLAYER:CanRespawn( )
	if ( self:Unassigned( ) ) then
		return false;
	end
	return true;
end

function GM:PlayerSpawn( ply )
	if round.Breaking then
		ply:SetTeam( TEAM_NEUTRAL )
	else
		ply:SetTeam( TEAM_SPECTATOR )
	end

	if ply:Team() == TEAM_NEUTRAL then
		ply:SetModel("models/player/pheonix.mdl")
		ply:SetGravity(1)
		ply:SetWalkSpeed(250)
		ply:SetRunSpeed(500)
		ply:SetCrouchedWalkSpeed(0.5)
		ply:SetDuckSpeed(0.5)
	end
	
	if ( PLAYER:Unassigned( ) ) then
		Player:StripAmmo( )
		Player:StripWeapons( );
		Player:Spectate( OBS_MODE_ROAMING )

		return false;
	else
		Player:UnSpectate()
	end
	
end

function GM:PlayerDeath( victim, weapon, killer )
	if ( victim:Unassigned( ) ) then return; end
end

function GM:PlayerDeathThink( Player )
	if ( !Player:CanRespawn( ) ) then
		return false;
	else
		Player:Spawn( )
	end
end

function round.Broadcast(Text)
	for k, v in pairs(player.GetAll()) do
		v:ChatPrint(Text)
	end
end


function round.Begin(ply)
	for _, v in pairs(player.GetAll()) do
		if not v:Alive() then
			v:Spawn()
		end
	end	
	round.Broadcast("Round starting! Round ends in " .. round.Time .. " seconds!")
	round.TimeLeft = round.Time
end

function round.End()
	round.Broadcast("Round over! Next round in " .. round.Break .. " seconds!")
	round.TimeLeft = round.Break
end

function round.Handle()
	if (round.TimeLeft == -1) then
		if ( alivePlayers >= 1) then
			round.Begin()
			return
		end
	end
	round.TimeLeft = round.TimeLeft - 1
	if (round.TimeLeft == 0) then
		if (round.Breaking) then
			if ( alivePlayers >= 2) then
				round.Begin()
				round.Breaking = false
			end
		else
			round.End()
			round.Breaking = true
		end
	end
	
end
timer.Create("round.Handle", 1, 0, round.Handle)

function GM:PlayerSelectSpawn(ply)

	if ( PLAYER:Unassigned( ) ) then return; end
	
	local spawnpoints
	local i
		spawnpoints = ents.FindByClass("spawns")
		i = math.random(#spawnpoints)
		return spawnpoints*
end

function AddSpawnpoints()
	local spawn_points = {
		Vector(-11431.851563, 11290.193359, 353.031250),
		Vector(-9055.885742, 13388.874023, 217.037521),
		Vector(-11781.977539, 11343.624023, 353.031250)
	}
	local map = {
		"rp_headattackcity_v1"
	}
	timer.Simple(3, function()
		if game.GetMap() == table.Random(map) then
			local crate = ents.Create("spawns")
			if not crate:IsValid() then return end
			crate:SetPos(table.Random(spawn_points))
			crate:Spawn()
			crate:DropToFloor()
		end
	end)
end
hook.Add("InitPostEntity", "AddSpawnpoints", AddSpawnpoints)

local function AlivePlayers()
	for k,v in pairs(player.GetAll()) do
		if v:Alive() then
			alivePlayers = alivePlayers + 1
		end
	end
	return alivePlayers
end


hook.Add("PlayerDeath", "checkAlivePlayers", function()
	if AlivePlayers() <= 1 then
		round.End()
	end
end)




Very strange. None of this is working.