Last active
January 17, 2022 23:06
-
-
Save angeld23/7f7a3acd515951710b3cf7cb2a2faaa3 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- Name: Leaderstats Module | |
-- Author: angeld23 | |
-- Date: 2022-17-01 | |
-- Description: Wrapper that automatically handles the creation and modification of leaderstats inside Roblox Player instances. | |
--[[ Usage Example | |
```lua | |
local Leaderstats = require(Path.To.Leaderstats.Module.Here) | |
local Player1 = game.Players.Player1 | |
local tableForPlayer1 = Leaderstats[Player1] | |
tableForPlayer1.TestValue = 999 --// A new entry labeled "TestValue" will appear on the leaderboard next to Player1 with the value "999" | |
print(tableForPlayer1.TestValue) --> 999 | |
--// You can also overwrite the whole table like this: | |
Leaderstats[Player1] = { | |
Value1 = 999; | |
Value2 = 9001; | |
Value3 = 1337; | |
} | |
--// To remove a value from the leaderboard, just set it to nil: | |
tableForPlayer1.Value3 = nil | |
--// You can set the value to a different type and the Value object will be updated automatically: | |
tableForPlayer1.Value3 = 1337 -- NumberValue is created | |
tableForPlayer1.Value3 = "Hello World" -- NumberValue is deleted, and StringValue is created with the same name | |
--// To iterate over either the whole leaderboard or a specific player's stats, use the following: | |
for plr, statsTable in Leaderstats.__pairs() do | |
-- (this code runs for every player) | |
end | |
for statKey, statValue in Leaderstats[Player1].__pairs() do | |
-- (this code runs for every stat in Player1's leaderboard) | |
end | |
-- (if only roblox supported the __pairs metamethod) | |
-- :( | |
--// Not all types are supported because Roblox Value objects have limits. | |
--// Supported types: | |
-- string, number, boolean, Vector3, Color3, Instance, CFrame, Ray | |
--// The module will throw an error otherwise. | |
--// But there's honestly no reason to be using anything except strings and numbers. | |
--// It's just a leaderboard, dude. | |
``` | |
]] | |
local types = { | |
string = "StringValue"; | |
number = "NumberValue"; | |
boolean = "BoolValue"; | |
Vector3 = "Vector3Value"; | |
Color3 = "Color3Value"; | |
Instance = "ObjectValue"; | |
CFrame = "CFrameValue"; | |
Ray = "RayValue"; | |
["nil"] = ""; -- so the type validation somewhere below this doesn't freak out | |
} | |
function getLeaderstatFolder (plr) | |
local leaderstats = plr:FindFirstChild("leaderstats") or Instance.new("Folder", plr) | |
leaderstats.Name = "leaderstats" | |
return leaderstats | |
end | |
function setLeaderstat (plr, key, value) | |
local folder = getLeaderstatFolder(plr) | |
if value == nil then | |
local stat = folder:FindFirstChild(key) | |
if stat then | |
stat:Destroy() | |
end | |
else | |
local stat = folder:FindFirstChild(key) | |
if not stat then | |
stat = Instance.new(types[typeof(value)], folder) | |
stat.Name = key | |
elseif stat.ClassName ~= types[typeof(value)] then | |
stat:Destroy() | |
stat = Instance.new(types[typeof(value)], folder) | |
stat.Name = key | |
end | |
stat.Value = value | |
end | |
end | |
function getLeaderstat (plr, key, value) | |
local folder = getLeaderstatFolder(plr) | |
local stat = folder:FindFirstChild(key) | |
if stat then | |
return stat.Value | |
end | |
end | |
local toReturn = {} | |
toReturn.__pairs = (function () | |
local tablefied = {} | |
for _, plr in pairs(game:GetService("Players"):GetPlayers()) do | |
tablefied[plr] = toReturn[plr] | |
end | |
return pairs(tablefied) | |
end) | |
setmetatable(toReturn, { | |
__index = (function (t, plr) | |
if typeof(plr) == "Instance" and plr:IsA("Player") then | |
local p = {} | |
p.__pairs = function () | |
local tablefied = {} | |
for _, valueObj in pairs(getLeaderstatFolder(plr):GetChildren()) do | |
tablefied[valueObj.Name] = valueObj.Value | |
end | |
return pairs(tablefied) | |
end | |
return setmetatable(p, { | |
__index = (function(t, key) | |
return getLeaderstat(plr, key) | |
end); | |
__newindex = (function(t, key, value) | |
if not types[typeof(value)] then | |
error("Invalid leaderstat type: " .. typeof(value), 2) | |
end | |
setLeaderstat(plr, key, value) | |
end); | |
}) | |
end | |
end); | |
__newindex = function (t, plr, value) | |
if typeof(value) == "table" and typeof(plr) == "Instance" and plr:IsA("Player") then | |
getLeaderstatFolder(plr):ClearAllChildren() | |
for key, val in pairs(value) do | |
if not types[typeof(val)] then | |
continue | |
end | |
setLeaderstat(plr, key, val) | |
end | |
end | |
end; | |
__metatable = "Locked"; | |
}) | |
return toReturn |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment