Need help with gamemode

So it’s me again. I have a problem with team.BestAutoJoinTeam( ). Whenever a player joins he’s always on the RED team (aka blue and red) somehow I doesn’t do it. I hooked it to PlayerInitializeSpawn. I have blue and red spawn at a spawnpoint(custom one) I created with an entity. I don’t get server or client sides errors everyone’s just RED.

I also got another question. I’m trying to create a round system, so when there are 2 or more people it will start running. then it gives rounds from about 3 minutes and like 10 round per map. Does anyone have clue how to do this. I’ve been trying to figure it out but I stopped since the AutoTeamJoin doesn’t even work anymore. It worked before.

part of Init.lua
[lua]function GM:PlayerInitialSpawn( ply )
print(“Player: " … ply:Nick() … " has spawned.”)
self.BaseClass:PlayerInitialSpawn( ply )
ply:SetGamemodeTeam( team.BestAutoJoinTeam() )
end[/lua]

idk if self.BaseClass even does anything… but.

Spawn binds ( in init.lua):
[lua] function GM:InitPostEntity()
Entity=ents.Create(“spawnred1”)
Entity:SetPos(Vector(-336, -120, 424))
Entity:Spawn()
Entity2=ents.Create(“spawnblue1”)
Entity2:SetPos(Vector(3249, -3280, 584))
Entity2:Spawn()
end

function GM:PlayerSelectSpawn( pl )
if (pl:Team() == 0) then
local spawns = ents.FindByClass( “spawnblue1” )
local random_entry = math.random( #spawns )

return spawns[ random_entry ]
elseif (pl:Team() == 1) then
local spawns = ents.FindByClass( “spawnred1” )
local random_entry = math.random( #spawns )
return spawns[ random_entry ]
end
end[/lua]

My custom file:

[lua]local ply = FindMetaTable(“Player”)

local teams = {}

teams[0] = {name = “Blue”, color = Vector( .2, .2, 1.0 ), weapons = {“weapon_crowbar”, “weapon_pistol”} }
teams[1] = {name = “Red”, color = Vector( 1.0, .2, .2 ), weapons = {“weapon_crowbar”, “weapon_pistol”} }

team.SetSpawnPoint( 1, “spawnred1” )
team.SetSpawnPoint( 0, “spawnblue1” )

function ply:SetGamemodeTeam( n )
if not teams[n] then return end

self:SetTeam( n )

    self:SetPlayerColor( teams[n].color )

    self:GiveGamemodeWeapons()
	 
return true

end [/lua]

N is defined at the end of the file(Well its locally defined so idk if it even works but it doesnt give me errors??): [lua]function ply:GiveGamemodeWeapons()
local n = self:Team()
self:StripWeapons()

    for k, wep in pairs(teams[n].weapons) do
        self:Give(wep)

end
end [/lua]
and I got this shared.lua:
[lua]team.SetUp( 0, “Blue”, Color(0, 0, 255) )
team.SetUp( 1, “Red”, Color(255, 0, 0) )

function GM:Initialize()
self.BaseClass.Initialize( self )
end[/lua]

I don’t get why its not just giving me error but only sets me to RED? Where is RED even called first. Is it because I can’t use 0 as a number?

Bump :S

I see you wrote



ply:SetGamemodeTeam( team.BestAutoJoinTeam() )


The correct use would be just ply:SetTeam

EDIT: My bad, didn’t see that he used custom function.

he is a using custom function



function ply:SetGamemodeTeam( n )
    if not teams[n] then return end
	
	self:SetTeam( n )
	
        self:SetPlayerColor( teams[n].color )
 
        self:GiveGamemodeWeapons()
		 
	return true
end  

Am I doing it wrong? Everyone uses SetGamemodeTeam

no, you dont. theres no problem there.

Why does everyone who joins get on the red team though?

After taking a look at the source of team.BestAutoJoinTeam() I found this



for id, tm in pairs( team.GetAllTeams() ) do
	if ( id != TEAM_SPECTATOR && id != TEAM_UNASSIGNED && id != TEAM_CONNECTING && tm.Joinable ) then


TEAM_SPECTATOR and TEAM_UNASSIGNED are 1001 and 1002. However TEAM_CONNECTING is 0.
Since you are using:



team.SetUp( 0, "Blue", Color(0, 0, 255) ) 


This step is skipped in the loop because your teamid is 0.

To fix this, try:



local teams = {}

teams[1] = {name = "Blue", color = Vector( .2, .2, 1.0 ), weapons = {"weapon_crowbar", "weapon_pistol"} }
teams[2] = {name = "Red", color = Vector( 1.0, .2, .2 ), weapons = {"weapon_crowbar", "weapon_pistol"} }


and



team.SetUp( 1, "Blue", Color(0, 0, 255) )
team.SetUp( 2, "Red", Color(255, 0, 0) )


Yeah! I just found out because when I joined(My TAB menu showed: Unconnected BLUE and when I connected it was RED sinceonly team that loads. Thanks so much though!!

Do u have any clue/small script for coding rounds? I found some but all not working or not what I want.

I need a small script which would when there are 2 or more people start, when u die u die until next round. Round takes 3 minutes or when one team has 0 players.

Just wrote this for you, it’s not perfect but should hopefully get you started.



-- Round system 

-- Round states 
local ROUND_STARTING = 1
local ROUND_ACTIVE = 2
local ROUND_ENDING = 3

local roundtime = 0
local activeround = 1

-- Set the round time
local function SetRoundTime(time)
	roundtime = time + CurTime()
end

-- Get the round time
local function GetRoundTime()
	return roundtime - CurTime()
end

-- Called when the round starts
local roundfunctions = {}

-- Starting
roundfunctions[ROUND_STARTING] = function()
	-- Spawn them and freeze them
	for k, v in pairs(player.GetAll()) do 
		v:SetTeam(team.BestAutoJoinTeam())
		v:Spawn()
		v:Freeze(true)
	 end 

	 -- Set duration
	SetRoundTime(5)
end

-- Active
roundfunctions[ROUND_ACTIVE] = function()
	-- Unfreeze them
	for k, v in pairs(player.GetAll()) do 
		v:Freeze(false)
	 end 

	-- 3 minutes (3 * 60 = 180)
	SetRoundTime(180)
end 

-- Ending
roundfunctions[ROUND_ENDING] = function()
	-- 5 seconds before everyone respawns
	SetRoundTime(5) 
end

-- Set the active round
local function SetRound(round)
	-- Debug
	print(round)
	-- Update this
	activeround = round 
	-- Call this
	roundfunctions[round]()
end

-- Think functions 
local roundthink = {}

-- Starting
roundthink[ROUND_STARTING] = function()
	-- Don't start if there's less than 2 players
	if (#player.GetAll() <= 1) then return end

	-- When the timer runs out (the 5 seconds) change the round state
	if (GetRoundTime() <= 0) then
		SetRound(ROUND_ACTIVE)
	end
end 

-- Active
roundthink[ROUND_ACTIVE] = function()
	-- Get players left
	local teamred, teamblue = team.NumPlayers(2), team.NumPlayers(1)

	-- Red won
	if (teamred == 0) then
		PrintMessage(HUD_PRINTCENTER, "BLUE TEAM WINS!")
		SetRound(ROUND_ENDING)
	-- Blue won
	elseif (teamblue == 0) then
		PrintMessage(HUD_PRINTCENTER, "RED TEAM WINS!")
		SetRound(ROUND_ENDING)
	-- Out of time
	elseif (GetRoundTime() < 0) then
		PrintMessage(HUD_PRINTCENTER, "OUT OF TIME!")
		SetRound(ROUND_ENDING)
	end
end 

-- Ending
roundthink[ROUND_ENDING] = function()
	-- Restart
	if (GetRoundTime() <= 0) then
		SetRound(ROUND_STARTING)
	end
end

-- Think 
function GM:Think()
        -- Call the think function of the round that is active
	roundthink[activeround]()
end

-- Called when the player dies
function GM:PlayerDeath(ply)
    -- Move them to another team
    ply:SetTeam(TEAM_SPECTATOR)
    -- Should do spectator stuff here
end 

function GM:PlayerDeathThink()
	-- Don't allow respawning
    return false 
end


Thanks dude.

[editline]31st August 2015[/editline]

I ran into some bugs though!

It seems like only the killer gets Teleported back to his spawn location. ( When I kill a blue guy as red, I respawn at my spawn point) (When a blue guy suicides, or falls, I dont respawn I just freeze and unfreeze on the same location)
and if you’re alone on the server and u die, you get to TEAM_SPECTATOR and you cannot respawn once you died.

Also how would I go making guns spawn on locations on each map ( on getpos locations )

How do I make spawnpoints only load at map. I tried this:
[lua] function GM:InitPostEntity()
if game.GetMap() == “mapname” then
Entity=ents.Create(“spawnred1”)
Entity:SetPos(Vector(-336, -120, 424))
Entity:Spawn()
Entity2=ents.Create(“spawnblue1”)
Entity2:SetPos(Vector(3249, -3280, 584))
Entity2:Spawn()
end[/lua]

but it breaks the spawnpoints. xD

Bump

You’re missing an end



function GM:InitPostEntity()
	if game.GetMap() == "mapname" then
		local Entity = ents.Create("spawnred1")
		Entity:SetPos(Vector(-336, -120, 424))
		Entity:Spawn()

		local Entity2 = ents.Create("spawnblue1")
		Entity2:SetPos(Vector(3249, -3280, 584))
		Entity2:Spawn()
	end
end


Thanks, How do I fix the TEAM_SPECTATOR bug though if you are alone on the server and u die, u can’t resapwn

Respawn the player or end the round if he’s alone?
Most roundsystems I’ve seen don’t start if the player count is below one.

I’ve slightly modified my previous code so the round ends when you die if you’re alone.



-- Round system 

-- Round states 
local ROUND_STARTING = 1
local ROUND_ACTIVE = 2
local ROUND_ENDING = 3

local roundtime = 0
local activeround = 1

-- Set the round time
local function SetRoundTime(time)
	roundtime = time + CurTime()
end

-- Get the round time
local function GetRoundTime()
	return roundtime - CurTime()
end

-- Called when the round starts
local roundfunctions = {}

-- Starting
roundfunctions[ROUND_STARTING] = function()
	-- Spawn them and freeze them
	for k, v in pairs(player.GetAll()) do 
		v:Spawn()
		v:Freeze(true)
	 end 

	 -- Set duration
	SetRoundTime(5)
end

-- Active
roundfunctions[ROUND_ACTIVE] = function()
	-- Unfreeze them
	for k, v in pairs(player.GetAll()) do 
		v:Freeze(false)
	 end 

	-- 3 minutes (3 * 60 = 180)
	SetRoundTime(180)
end 

-- Ending
roundfunctions[ROUND_ENDING] = function()
	-- 5 seconds before everyone respawns
	SetRoundTime(5) 
end

-- Set the active round
local function SetRound(round)
	-- Debug
	print(round)
	-- Update this
	activeround = round 
	-- Call this
	roundfunctions[round]()
end

-- Think functions 
local roundthink = {}

-- Starting
roundthink[ROUND_STARTING] = function()
	-- When the timer runs out (the 5 seconds) change the round state
	if (GetRoundTime() <= 0)  then
		SetRound(ROUND_ACTIVE)
	end
end 

-- Active
roundthink[ROUND_ACTIVE] = function()
	-- Only do this if we have only one player
	if (#player.GetAll() == 1) then
		-- Loop
		for k, v in pairs(player.GetAll()) do
			-- Is the player a spectator?
			if (v:Team() == TEAM_SPECTATOR) then
				-- Notify
				PrintMessage(HUD_PRINTCENTER, "GAME OVER")
				-- End the round
				SetRound(ROUND_ENDING)
				-- Stop
				return
			end 
		end

		-- Stop
		return
	end

	-- Get players left
	local teamred, teamblue = team.NumPlayers(2), team.NumPlayers(1)

	-- Red won
	if (teamred == 0) then
		PrintMessage(HUD_PRINTCENTER, "BLUE TEAM WINS!")
		SetRound(ROUND_ENDING)
	-- Blue won
	elseif (teamblue == 0) then
		PrintMessage(HUD_PRINTCENTER, "RED TEAM WINS!")
		SetRound(ROUND_ENDING)
	-- Out of time
	elseif (GetRoundTime() < 0) then
		PrintMessage(HUD_PRINTCENTER, "OUT OF TIME!")
		SetRound(ROUND_ENDING)
	end
end 

-- Ending
roundthink[ROUND_ENDING] = function()
	-- Restart
	if (GetRoundTime() <= 0) then
		SetRound(ROUND_STARTING)
	end
end

-- Think 
function GM:Think()
	roundthink[activeround]()
end

-- Called when the player spawn
function GM:PlayerSpawn(ply)
	-- Unspectate
	ply:UnSpectate()
	-- Fix hands
	ply:SetupHands()
	-- Set his team
	ply:SetGamemodeTeam(team.BestAutoJoinTeam())
end

-- Called when the player dies
function GM:PlayerDeath(ply, attacker, cinfo)
	-- Change his team
	ply:SetTeam(TEAM_SPECTATOR)
	-- Doing this without a timer doesn't work (?)
	timer.Simple(0, function() ply:Spectate(OBS_MODE_ROAMING) end)
end 

-- Can the player respawn?
function GM:PlayerDeathThink(ply)
	-- Don't allow it
	return false
end


On a sidenote, if someone spots anything that could be improved please tell me.