Money system, more explanation needed.

This is what i got so far in an attempted modular rp gamemode (yes rp, i’m sick of editing darkrp for my friends, don’t turn this into a rant please, just a learning curve for me). And no this ain’t all of my gamemode, just the money part that will be shared between init and cl_init.


local player = FindMetaTable( "Player" )

if ( SERVER ) then
	util.AddNetworkString( "ply_SetMoney" )
	
	function player:SetMoney( amount )
		net.Start( "ply_SetMoney" )
			net.WriteInt( amount, 16 )
		net.Send( self )

		self.i_Money = amount
	end

	-- Use negative values to take money, + (-amount) is always negative
	function player:AddMoney( amount )
		self:SetMoney( self:GetMoney() + amount )
	end

	function player:HasMoney( amount )
		if self:GetMoney() >= amount then
			return true
		else
			return false
		end
	end

	function player:SaveMoney()

		-- Find the directory called "money" from data
		local _, folder = file.Find( "money", "DATA" )

		-- Create directory if one doesn't exist
		if (!folder[1]) then
			file.CreateDir( "money" )
		end
		
		local uniqueID = self:UniqueID()
		local amount = self:GetMoney()

		-- If you also need the players steam name for some reason added to the file, use self:GetName() and append to amount
		file.Write( "money/"..uniqueID..".txt", amount )
	end

	function player:RestoreMoney()
		local uniqueID = self:UniqueID()
		local content = file.Read( "money/"..uniqueID..".txt", "DATA" )

		if ( content ) then
			local amount = tonumber( content )

			if ( amount ) then
				self:SetMoney( amount )
			end
		else
			self:SetMoney ( defaultamount )
		end	
	end
else
	net.Receive( "ply_SetMoney", function( length )
		local amount = net.ReadInt( 16 );

		LocalPlayer().i_Money = amount;
	end
end

function player:GetMoney()
	return self.i_Money or 0
end

I believe chessnut posted this somewhere so i took the liberty of using it as a base. Anyway, few questions.

  • For saving what should i use? I’ve heard of pdata but i have never used it, kind of clueless with the entire saving/textfile/database side of things.
  • Where should i hook the SaveMoney() function to? I was thinking of player disconnect but i’ve read it ain’t the most reliable hook. I know i should probably be putting restoremoney in GM:Initialize(). Again if there are any other saving methods, please teach me.
  • Could someone show me how do i make a concommand for this and if i should be making a concommand for addmoney? I would defineatly want to use both derma and chat commands for these functions.

When saving, you are going to use ‘PData’ as a kind of Basic SQLite.
Hook your SaveMoney() function to ‘PlayerDisconnected’, so when a player leaves it saves.

PData is SQLLite

[lua]
if ( !sql.TableExists( “playerpdata” ) ) then

sql.Query( "CREATE TABLE IF NOT EXISTS playerpdata ( infoid TEXT NOT NULL PRIMARY KEY, value TEXT );" )

end
[/lua]

[lua]
function meta:GetPData( name, default )

name = Format( "%s[%s]", self:UniqueID(), name )
local val = sql.QueryValue( "SELECT value FROM playerpdata WHERE infoid = " .. SQLStr(name) .. " LIMIT 1" )
if ( val == nil ) then return default end

return val

end
[/lua]

[lua]
function meta:SetPData( name, value )

name = Format( "%s[%s]", self:UniqueID(), name )
sql.Query( "REPLACE INTO playerpdata ( infoid, value ) VALUES ( "..SQLStr(name)..", "..SQLStr(value).." )" )

end
[/lua]

Thanks for clarifying the pdata thing, i can figure everything else out on my own :slight_smile:

One more question, for restoring money, what i have so far is:


function GM:Initialize()
for k,v in pairs(***whatdoiouthere***) do
    player.GetByID( v ):GetPData( "money", 0 )
    player.GetByID( v ):SetMoney( amount )
end
end

What i need to know is how do i get maximum amount of ID’s or should i just hook my RestoreMoney() into Initialize? I like overriding existing functions more that’s why i tried this.

You don’t do it like this.



function GM:InitialSpawn(ply)
    ply:GetPData( "money", 0 )
   ply:SetMoney( amount )
end


Thanks! So this is what i have for saving and restoring if anyone is trying the same thing:



function GM:PlayerInitialSpawn( ply )
    local amount = ply:GetPData( "money", 0 )
    ply:SetMoney( amount )
end
function GM:PlayerDisconnected( ply )
    -- Save everything player related here
    ply:SetPData( "money", ply:GetMoney() )
    PrintMessage( HUD_PRINTTALK, ply:Name().. " has left the server." )
end