Custom Gamemode, Trying to Create Point System

Recently I’ve developed a very simple gamemode in which players are split into two teams, one player is a runner and the rest are hunters.
The runner objective is to hold the runner title for 120 seconds, and the hunters’ objective is to kill the runner so as to become the runner.

So far things have gone fairly well, but I’ve run into a snag in which the custom scoreboard doesn’t display anyone’s score but the local player’s, which sucks.

The points system is run with Network Integers which I know nothing about, and I believe that this is where the problem lies.

This is everything in my shared.lua file



team.SetUp(0, "Hunter", Color( 50, 50, 255 ) )
team.SetUp(1, "Runner", Color( 255, 50, 50 ) )

include("cl_scoreboard.lua")

local meta = FindMetaTable("Player")

function GM:Initialize()
	
	self.BaseClass:Initialize(self)
	
end

function meta:GetPoints()

	return self:GetNWInt( "ply_points" ) 

end

function meta:SetPoints( amt )

	self:SetNWInt( "ply_points", amt )
	
end

function meta:AddPoints( amt )

	self:SetNWInt( "ply_points", self:GetPoints() + amt )
	
end


I only have a vague idea of what this means.

When LocalPlayer() is defined as ply and ply:GetPoints() is called in the cl_init file, all is fine.
But when in init.lua, and used in a function like this:




for k, ply in pairs( player.GetAll() ) do
		print( ply:Nick().. "  " ..ply:GetPoints().. "  ".. ply:Frags )
	end



The ply:GetPoints() outputs 0 without exception, whereas the player’s name and kills display correctly.

How can I redo this so that the player’s points can be called more-or-less anywhere?

Any help would be appreciated. ~KyleTheScientist

You should use Pdata instead of NWVar otherwise points will be lost on a server restart.

Something similar to below which I wrote up in my browser, so expect it to be broken.

[lua]
team.SetUp(0, “Hunter”, Color( 50, 50, 255 ) )
team.SetUp(1, “Runner”, Color( 255, 50, 50 ) )

include(“cl_scoreboard.lua”)

if SERVER then

util.AddNetworkString("sendpoints")

local meta = FindMetaTable("Player")

function GM:Initialize()
	
	self.BaseClass:Initialize(self)
	
end

function meta:GetPoints()

	return self:GetPData("ply_points", 0)

end

function meta:SetPoints( amt )

	self:SetPData("ply_points", amt)
	self:UpdatePoints()
	
end

function meta:AddPoints( amt )

	local curpoints = self:GetPoints()
	self:SetPData("ply_points", curpoints + amt)
	self:UpdatePoints()
	
end

function meta:UpdatePoints()

	local points = self:GetPoints()

	--Broadcast a netmessage to all clients to let them know how many points this user has.
	net.Start("sendpoints")
		net.WriteEntity(self)
		net.WriteInt(points,32)
	net.Broadcast()

end

end

if CLIENT then

-- Receive the netmessage and adjust players to their correct points (This lets all clients know who has what points.)
net.Receive( "sendpoints", function( len, pl )

	local ply = net.ReadEntity()
	local points = net.ReadInt(32)

	ply.Points = points

end)

-- Print all players points client side with a console command "getpoints"
concommand.Add( "getpoints", function( ply )
	for k,ply in pairs(player.GetAll()) do
		ply:ChatPrint(ply.Points)
	end
end )

end
[/lua]

If you want to display it on HUD or somewhere do tostring( ply:GetPoints() )

I would suggest you use Player:AddFrags() instead of NWInts. They are basically the point system and are already networked too. Use PData if you need to keep it between server restarts or if the same player logs back in a day later and needs to get his points back - but that is usually not a good idea in a gamemode.

Looks fine and dandy, but where should I now add the function that adds points to anyone on the runner team?

Previously I had a function in the client file like this:




local nextadd = 0 

hook.Add("Think", "runneraddpoints", function()
	
	local ply = LocalPlayer()
	
	if ply:Team() ~= 1 then return end
	if ply:GetPoints() >= 120 then 
	
		RunConsoleCommand("reset")
		
		net.Start("SendWinner")
				net.WriteEntity( LocalPlayer() )
		net.SendToServer()
			
		ply:SetPoints(0)
	
	return end

	if CurTime() < nextadd then return end

	if CurTime() >= nextadd then
		ply:AddPoints(1)
		nextadd = CurTime() + 1
	end

end)


Which basically just adds a point to anyone who’s on team 1 (runners) every second and then lets the server know when someone’s reached 120 points.

How can implement this with the new functions and variables you’ve applied?
Thanks for the help ~KTS

Don’t do that clientside as someone could easily fake the net message and say they won.

This is in the server side code

[lua]
meta:GetPoints()
[/lua]

Which returns the players points, so you could create a timer as such:

[lua]
timer.Create( “CheckWinner”, 1, 0, function()

for k,ply in pairs(player.GetAll()) do
	if ply:Team() ~= 1 then return end
	if ply:GetPoints() &gt;= 120 then
		RunConsoleCommand("reset") -- not sure if this needs to be called server or client side.
		ply:SetPoints(0)
	end
end

ply:AddPoints(1)

end )
[/lua]

This adds a timer that runs indefinitely and runs the code inside every 1 second, it will check if the players points are equal or above 120 and if not, add points to the player.

This needs to be inside
[lua]
if SERVER then
[/lua]

That looks like a smart way to do it.
I’ll give it a shot in a moment! Thanks for everything

[editline]23rd July 2015[/editline]

It doesn’t look like any points are getting added to anyone but me.

Also, how do I access the individual players’ scores from the client so that I can display each players’ own score to them?

Seriously thanks for the patience you’ve been a big help.