• How could I make a timer that pauses and saves if a player leaves?
    22 replies, posted
So, I need a timer that pauses and saves when a player leaves, and starts right back up from where it left off when the player joins, I have no clue where to even start with creating something like this. I am acutely aware that I am asking to (basically) be spoonfed, but my poor little 2 IQ brain has no idea how timers, or time in general works XD
You can use the on-board Source database. You could also save the value of the timer to a flat file in your server's data directory. I will be back with some links that will give you a general idea of how to store this information.
Alright, thanks man
you cant after posting the post
Are mods able to switch it for me?
Source's SQL database method: Player/SetPData Lets you set a simple value with a key identifier on a player's account on your server. Player/GetPData Lets you retrieve set data. Using a flat file: file.Write file.Read you can store the value as a simple "1337" if there are 1337 seconds left on the timer at the time of player disconnect, in a file under "data/nameOfYourTimer/playerID.txt You can detect when to store the timer with GM/PlayerDisconnected and when to set the timer with GM/PlayerInitialSpawn For someone like you I would probably use the SetPData method.
there is.
Don't use string names. Try passing the player object itself as an argument to the timer. Remember this is Lua. You can also describe the timer with "HourTimer"..Player:GetSteamID, then override that timer every time the player reconnects in a given server session.
So what exactly is the problem with string names? I don't think they would make a difference, they're just used to identify that timer, Is using "TimerNameHere"..LocalPlayer():GetSteamID() any better? and if so how? since this timer is being ran clientside, i'm assuming the timer would already attach to the player.
If you're wanting to do saving data by a timer you don't even need to. Just make it save on key functions you can even do one for PlayerDisconnected so when they do leave it'll save their data BUT I would also suggest saving in certain functions like if you have a shop / money save after they purchase etc..
That's not the point. I want to create a timer that starts when a player joins, and saves its position when the player disconnects, and when the player re-joins the timer will pick up from where it last left off.
Wait why is it being run clientside? Shouldn't it be run serverside?
Well, I use the server side to tell the client that either a player spawned or disconnected, Its ease of use tbh. The timer gives the client 1 coin every hour, and i hate networking variables XD
Well this is just poor application design. I could easily give myself unlimited coins by just running a clientside script. Networking variables is very easy. Just run the timers on the server, and every tick, update the networked variable on the player by setting a networked value on them. Then if the user needs to see it display it then on their HUD or in a DPanel, whatever you're already doing. It's really very easy to network this.
"and every tick, update the networked variable on the player by setting a networked value on them." I'd rather not... I don't feel like taking up my server's CPU to do that.
Quick question: I'm getting this error when trying to use ply:GetNWInt("StaffPoints") on the client, any reasons why? [ERROR] addons/responsible_promoter/lua/autorun/cl_points.lua:9: attempt to call method 'GetNWInt' (a nil value) 1. unknown - addons/responsible_promoter/lua/autorun/cl_points.lua:9
What is line 9
Could you post the whole file?
AddCSLuaFile("points.lua") AddCSLuaFile("config.lua") include("points.lua") include("config.lua") local ply = FindMetaTable("Player") local staffCoinAmount = ply:GetNWInt("StaffPoints") or ply:GetPData("StaffPoints") net.Receive("pointsgoingtoclientoriginal", function()     -- Ready levelingFrame = vgui.Create("DFrame") levelingFrame.Main = vgui.Create("DScrollPanel", levelingFrame) levelingFrame.List = vgui.Create("DListLayout", levelingFrame.Main) levelingFrame.Points = vgui.Create("DPanel",levelingFrame) levelingFrame.Points.Text = vgui.Create("DLabel",levelingFrame.Points) if userPoints == true then  levelingFrame.Points.UText = vgui.Create("DLabel",levelingFrame.Points) end levelingFrame.Notify = vgui.Create("DNotify")     --Set levelingFrame:SetTitle("THIS IS A TEST, AND ONLY A TEST OF THE INVALIDS THANG") levelingFrame:SetSize(512,512) levelingFrame:SetPos(ScrW() / 2 - 256, ScrH() / 2 -256) levelingFrame:MakePopup() levelingFrame:SetDraggable(true) levelingFrame:SetDeleteOnClose(true) levelingFrame.Main:SetBackgroundColor(Color(0,0,0,255)) levelingFrame.Main:SetSize(512, 512-25) levelingFrame.Main:SetPos(0,25) levelingFrame.List:SetPaintBackground(false) levelingFrame.List:SetBackgroundColor(Color(0,100,100)) levelingFrame.List:SetSize( 100, 100 ) levelingFrame.List:SetPos(20,50) levelingFrame.Points:SetSize(120,50) levelingFrame.Points:SetPos(392,25) levelingFrame.Points.Text:SetText(staffPointName..": "..tostring(staffCoinAmount or 0)) levelingFrame.Points.Text:SetContentAlignment( 5 ) levelingFrame.Points.Text:SizeToContents() levelingFrame.Points.Text:CenterHorizontal(0.5) levelingFrame.Points.Text:CenterVertical(0.3) if userPoints == true then levelingFrame.Points.UText:SetText(userPointName..": "..tostring(userCoinAmount or 0)) levelingFrame.Points.UText:SetContentAlignment( 5 ) levelingFrame.Points.UText:SizeToContents() levelingFrame.Points.UText:CenterHorizontal(0.5) levelingFrame.Points.UText:CenterVertical(0.7) end local blur = Material("pp/blurscreen") local function DrawBlur(panel, amount) local x, y = panel:LocalToScreen(0, 0) local scrW, scrH = ScrW(), ScrH() surface.SetDrawColor(255, 255, 255) surface.SetMaterial(blur) for i = 1, 3 do blur:SetFloat("$blur", (i / 3) * (amount or 6)) blur:Recompute() render.UpdateScreenEffectTexture() surface.DrawTexturedRect(x * -1, y * -1, scrW, scrH) end end levelingFrame.Paint = function(self,w,h) DrawBlur(self, 9) draw.RoundedBox(0,0,0,w,h,Color(100,100,100,60)) draw.RoundedBox(0,0,0,512,25,Color(255,255,255,255)) end levelingFrame.Points.Paint = function(self,w,h) DrawBlur(self, 3) draw.RoundedBox(0,0,0,w,h,Color(50,50,50,200)) end     --Do the do     local function getleaves(root)     local leaves = {}     for k,v in pairs(root) do         local tbllen = 0         for k,v in pairs(v) do             tbllen = tbllen + 1         end         if tbllen == 0 then             leaves[#leaves + 1] = k         else             local newleaves = getleaves(v)             for i,j in pairs(newleaves) do                 leaves[#leaves + 1] = j             end         end     end     return leaves end local ranks = getleaves(ULib.ucl.getInheritanceTree()) for k,v in pairs(ranks) do     levelingFrame.List:Add( Label(v) )     print(v) end end)
You should be doing this inside of some hook that provides a player entity - you can't just run methods on the player metatable.
What do you mean by that? do you want me to do something like this?: local ply = LocalPlayer() ?
Sure, just make sure to do it inside of the net.Receive
okay, yep its working, The timer has no way to check if it is properly, but i'll do what I can to do some tests on it, but I do believe that everything is working. I'll keep you updated
Sorry, you need to Log In to post a reply to this thread.