I’m unsure how I would create a chest that can be claimed every 6 hours? I know how to reward the player every six hours, I’m just don’t know how to display it locally?
I’ve tried making it display in a GUI, I’ve also tried making it appear above the chest but it doesn’t work for me?
The Claim GUI
local player = game.Players.LocalPlayer
script.Parent.MouseEnter:Connect(function()
script.Parent.Parent.ImageColor3 = Color3.fromRGB(16, 186, 53)
end)
script.Parent.MouseLeave:Connect(function()
script.Parent.Parent.ImageColor3 = Color3.fromRGB(23, 255, 77)
end)
local Rewards = require(game.ReplicatedStorage.Modules.GroupRewards)
local target = os.time() + 86400
local function toHMS(s)
return ("%02i:%02i:%02i"):format(s/3600, s/60%60, s%60)
end
script.Parent.MouseButton1Click:Connect(function()
local timeleft = tonumber(target)
if (timeleft > 0 and timeleft - os.time() > 0) then
script.Parent.Click:Play()
game.ReplicatedStorage.Claim.ClaimGReward:FireServer()
else
script.Parent.Parent.X.Text = toHMS(target - os.time())
end
end)
Server Script
local DS = game:GetService("DataStoreService")
local RS = game:GetService("ReplicatedStorage")
Rewards = require(game.ReplicatedStorage.Modules.GroupRewards)
function DailyReward(v)
local Player = game.Players:GetPlayerByUserId(v)
local MainCurrency = Player:WaitForChild("MainCurrency")
local Gems = MainCurrency:FindFirstChild("Gems")
if MainCurrency then
Gems.Value = Gems.Value + 15
end
end
game.ReplicatedStorage.Chests.GChest.OnServerEvent:Connect(function(plr, mode, table)
if (mode == "Group_R") then
print("Mode Correct")
if plr:IsInGroup(6154443) then
local Data = DS:GetDataStore("DailyRewards_V.1", plr.UserId)
local timeleft = Data:GetAsync("TimeLeft")
local hours = os.time() + 86400 --Time in seconds, default is 24 hours
if timeleft == nil then
Data:SetAsync("TimeLeft", hours)
Data:IncrementAsync("Amount", 1) --Amount of times the player got the reward
DailyReward(plr.UserId)
else
local timeleft = tonumber(timeleft)
if (timeleft > 0 and timeleft - os.time() > 0) then
DailyReward(plr.UserId)
end
end
end
end
end)
Any better ways I could do this/ or ways I could make this work properly?
The tick() function or os.time() may be your friend here as they return a number (in seconds) that has passed since (some UCT time I think).
It’s not precisely sycned across servers, some servers can (in bad cases) lag a minute or two behind but shouldn’t be an issue.
If you want to check if a hour has passed you could do this.
local lasttimeopened = os.time() --tick() is also perfectly acceptable but returns a number with decimals.
wait(60 * 60) --Les wait a hour.
if os.time() - lasttimeopened > (60 * 60) then
print("Myes, 1 hour has passed, epic.")
end
You can save this value in a data store, which is epic.
Though, since os.time() and tick() both return like a large number (something like 20183027429), it will barely take up any space, but if you want to optimize it a little/make it smaller, subtract a large amount from it when saving it to a datastore, if you want to load it from data store, add the same amount you subtracted again so it becomes the original number again.
I haven’t tried this myself exactly but what I’d do is.
local function displaytime(time)
local seconds = time % 60 --Using % divides and returns a remainder.
local minutes = (time - seconds) / 60 --Remove remainder (seconds) from total time, get a rounded up number (minutes).
return minutes, seconds
end
Could be wrong, but pretty sure this is how you do the math (anyone correct me if I made a mistake).
Basically you divide the seconds by 60, which should give you minutes, but before you divide that by 60, I first remove the remaining seconds, what can not be divided by 60 is a remainder which I remove from the total time, now I can divide it by 60 and get the total minutes left without the number being followed by decimals which is great.
Edit: This is just for minutes and seconds, if you want hours, days, weeks, etc displayed you have to divide more numbers and make more remainders to pull from the total time, etc, though, not entirely sure on how to extend that function a little more, but this should do the trick for you I hope, I think you only need minutes since it’s just 1 hour, right?
Assuming that this needs to work across play sessions, use DataStores. Assume that the “lastClaimTime” or whatever for a player is 0 if they have no data saved, otherwise use the saved value as their last claim time value. Check the current os.time() and check if the elapsed time is over an hour either as a sum or a difference. I prefer a sum.
-- Sum
local currentTime = os.time()
if currentTime < lastClaimTime + 3600 then
-- Difference
local currentTime = os.time()
if currentTime - lastClaimTime >= 3600 then
If that condition succeeds, give them rewards and update their DataStore value with the seconds given in currentTime. That’s all the debounce you really need in terms of claiming.
As for counting down, use client-side prediction. Whatever the current amount of time they need to wait for is (calculate using a difference between the current time and last claim, then by an hour and the calculated difference), have the server send that to the client which it will then count the timer down itself with a variable internally and use a time formatter to represent it in a clean way on a Gui.