• Money System Help
    5 replies, posted
I've been looking at some tutorials and I decided to try and make my own money system where it would save how much the player has to a text file. But the problem is I can't get salary's to work. [lua] local ply_meta = FindMetaTable( "Player" ); local money = "PlayerMoney"; function ply_meta:SteamIDFormat( ) format1 = string.gsub( self:SteamID(), "STEAM", "" ) -- replaces STEAM with nothing format2 = string.gsub( format1, ":", "" ) -- replaces _ with nothing format3 = string.gsub( format2, "_", "" ) return format3; end function ply_meta:SetMoney( amount ) self:SetPData( money, amount ) -- set the players money to amount self:SetNWInt( money, amount ) end function ply_meta:AddMoney( amount ) self:SetPData( money, self:GetPData( money ) + amount ) -- Get the players money then add the amount self:SetNWInt( money, self:GetPData( money ) ) end function ply_meta:SubtractMoney( amount ) self:SetPData( money, self:GetPData( money ) - amount ) self:SetNWInt( money, self:GetPData( money ) ) end function ply_meta:GetMoney( amount ) self:GetPData( money ) -- get the players money end function ply_meta:HasMoney( amount ) if self:GetPData( money ) >= amount then self:SubtractMoney( amount ) else print( "You don't have enough money" ) end end function ply_meta:SaveMoney( ) file.Write("Money_system_test/".. SteamIDFormat .. ".txt", self:GetMoney() ) end local function InitialPlayerSpawn( ply ) if file.Exists("money_system_test/" .. SteamIDFormat .. ".txt") then ply:SetPData( money, file.Read("money_system_test/" .. self:SteamIDFormat .. ".txt") ) else file.Write("Money_system_test/" .. SteamIDFormat .. ".txt", 500) end end hook.Add("PlayerInitialSpawn", "MoneyFiles", InitialPlayerSpawn ) function ply_meta:SetSalary( time, amount) timer.Create( "PayDayBitches", time, 0, function() self:AddMoney( amount ) self:ChatPrint( "You have received a Paycheck! You now have " .. self:GetMoney( ) ); end) end timer.Create( "MoneySave", 60, 0, function( ) for k, v in pairs( player.GetAll( ) ) do v:SaveMoney( ); end; end ); [/lua] I get this error when i start the gamemode: gamemodes\testgamemode\gamemode\init.lua:41] attempt to call method 'SetSalary' (a nil value)(Hook: PlayerLoadout) Heres my Init.lua [lua] function GM:PlayerLoadout( ply ) if ply:Team() == 1 then ply:Give( "weapon_physcannon" ) ply:Give( "weapon_physgun" ) ply:Give( "gmod_tool" ) ply:SetSalary( 10, 50) -- Line 41 elseif ply:Team() == 2 then ply:Give("weapon_physcannon") ply:Give("weapon_physgun") ply:Give("gmod_tool") elseif ply:Team() == 3 then ply:Give("weapon_physcannon") ply:Give("weapon_physgun") ply:Give("gmod_tool") end end [/lua] Any help would be appreciated, I've been trying to get this to work for a while now and I don't know what to do. Also, Merry Christmass!
You have to define SetSalary before you call it. Post your whole init.lua, or at least up until the PlayerLoadout hook.
First off your first function, [lua] function ply_meta:SteamIDFormat( ) format1 = string.gsub( self:SteamID(), "STEAM", "" ) -- replaces STEAM with nothing format2 = string.gsub( format1, ":", "" ) -- replaces _ with nothing format3 = string.gsub( format2, "_", "" ) return format3; end [/lua] Is redundant, and instead can be called like this [lua] function ply_meta:SteamIDFormat() return string.gsub( self:SteamID(), ":", "_") -- Replaces psteamid colons (:) with underlines (_) end [/lua] Now you can save to files (Not that I'd recommend doing that, but whatever), and it's easier on the eyes to read. Also, your saving and reading will not work, you should be doing self:SteamIDFormat() instead of SteamIDFormat since it's a function and not a variable. A quick fix instead of redoing all that will be putting [lua] local SteamIDFormat = self:SteamIDFormat() [/lua] at the top of the file underneath the money variable. That should fix the erroring but in case you haven't noticed your GetMoney function will only work serverside. Get rid of the function arguments in ply_meta:GetMoney() Also replace GetPData() with GetNWInt() because GetPData() is [b]only[/b] allowed to be called through the server. NW isn't. However the SetNW's and GetNW's can be expensive. They should only be called when you need to give it to all players. Don't get overexcited about NW's, spamming them everywhere for a shortcut. Your FPS will pay for that. Now, the function should now look something like this now: [lua] function ply_meta:GetMoney() -- Return money using GetNWInt instead so you may use it in HUD's or menus. return self:GetNWInt( money ) end [/lua] There shouldn't be an error in ply_meta:HasMoney(), but usually coders will not put an error like "You do not have enough money" in a meta function, and save it for a function that actually calls it and stuff, because you do not know 100% what you will use HasMoney() for. Not only that, but since you are making a money system serverside you would be printing "You do not have enough money" to the server console, and not the player himself. If you decide to keep the ply_meta:HasMoney( amount ) then at least do something like this: [lua] function ply_meta:HasMoney( amount ) if self:GetPData( money ) >= amount then -- *sigh* self:SubtractMoney( amount ) else -- *sigh* self:PrintMessage(HUD_PRINTCONSOLE, "You don't have enough money\n" ) end end [/lua] Changed your mind? Great: [lua] function ply_meta:HasMoney( amount ) if self:GetPData( money ) >= amount then -- Don't take their money! -- You do NOT know what you're going to use this for 100% -- Return true to say that the player has the money needed. return true else -- Return false: Player doesn't have the money needed :( return false end end [/lua] Couple more things: Your InitialPlayerSpawn( ply ) function, good, it's local and it should be unless you plan on calling it somewhere else? (You won't) If you plan on making a HUD or menu, switch that ply:SetPData( money, file.Read("money_system_test/" .. SteamIDFormat .. ".txt") ) with ply:SetNWInt( money, file.Read("money_system_test/" .. SteamIDFormat .. ".txt") ) A big thing too: When you are creating a timer, the timer is being set for everyone, so if a new player comes the player that was about to get a payday gets the timer reset, or something like that will happen. Change it to [lua] timer.Create( "PayDayBitches_"..ply:UserID(), time, 0, function() [/lua] Now the saving timer, how often do you plan on setting players payday timer? If it's plan is 60 seconds I would still make it save like every 30 seconds. ( You never now if someone will trade money or spend something or etc) ALSO 2 more things 1.) I recommend that you add a playerdisconnect save money hook. Something like this: [lua] local function PlayerDisconnect_SaveMoney( pl ) -- Save the players money when they leave pl:SaveMoney() end -- Hook so that the above function works. Yes. hook.Add("PlayerDisconnected", "SaveMoney_PlayerDisconnected", PlayerDisconnect_SaveMoney) [/lua] One last thing, SetPData and GetPData are [b]retrieving from a local SQLite database[/b], and you are using them [b]to save to text files[/b]... Whatever, do what you want. [QUOTE=shadowndacorner;33886554]You have to define SetSalary before you call it. Post your whole init.lua, or at least up until the PlayerLoadout hook.[/QUOTE] Not necessarily. Edit: And merry Christmas to you as well!
Thank you very much, I really appreciate this, it was very informative! I thought I did some things wrong but I wasn't sure. Thanks again man and Merry Christmas!
If you want some help with lua add me on steam: modegg Im in a good mood.
[QUOTE=I Fail At Lua;33891907]Thank you very much, I really appreciate this, it was very informative! I thought I did some things wrong but I wasn't sure. Thanks again man and Merry Christmas![/QUOTE] In case it wasn't clear, you can still use the SetPData and GetPData, but it's kind of redundant to do so.
Sorry, you need to Log In to post a reply to this thread.