Files
block-game/ReplicatedStorage/Shared/ClientState.lua
2026-01-08 23:52:32 +02:00

129 lines
2.5 KiB
Lua

--!native
--!optimize 2
local RunService = game:GetService("RunService")
if RunService:IsServer() then
error("ClientState can only be required on the client")
end
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Replica = require(ReplicatedStorage.Packages.replica)
local ClientState = {}
local HOTBAR_SIZE = 10
local localPlayer = Players.LocalPlayer
local replicaForPlayer = nil
local changed = Instance.new("BindableEvent")
local function fireChanged()
changed:Fire()
end
local function onReplicaNew(replica)
local tags = replica.Tags or {}
if tags.UserId ~= localPlayer.UserId and tags.Player ~= localPlayer then
return
end
replicaForPlayer = replica
replica:OnChange(fireChanged)
fireChanged()
end
Replica.OnNew("ClientState", onReplicaNew)
Replica.RequestData()
function ClientState:IsReady(): boolean
return replicaForPlayer ~= nil
end
function ClientState:GetReplica()
return replicaForPlayer
end
function ClientState:GetSelectedSlot(): number?
if not replicaForPlayer then
return nil
end
return replicaForPlayer.Data.selectedSlot
end
local function getInventory()
return replicaForPlayer and replicaForPlayer.Data.inventory or nil
end
function ClientState:GetItemInfo(blockId: any)
if not replicaForPlayer or not blockId then
return nil
end
local inv = getInventory()
local entry = inv and inv[tostring(blockId)]
if not entry then
return nil
end
return {
id = tostring(blockId),
name = entry.name or tostring(blockId),
count = entry.count,
}
end
function ClientState:GetHotbarSlots(): {string}
if not replicaForPlayer then
local slots = table.create(HOTBAR_SIZE)
for i = 1, HOTBAR_SIZE do
slots[i] = ""
end
return slots
end
return replicaForPlayer.Data.hotbar or {}
end
function ClientState:GetSlotInfo(slot: number)
if not replicaForPlayer then
return nil
end
local hotbar = replicaForPlayer.Data.hotbar
if not hotbar then
return nil
end
local id = hotbar[slot]
if not id then
return nil
end
return ClientState:GetItemInfo(id)
end
function ClientState:GetSelectedBlock()
if not replicaForPlayer then
return nil
end
local slot = ClientState:GetSelectedSlot()
if not slot then
return nil
end
return ClientState:GetSlotInfo(slot)
end
function ClientState:SetSelectedSlot(slot: number)
if not replicaForPlayer then
return
end
local hotbar = replicaForPlayer.Data.hotbar
if not hotbar or not hotbar[slot] then
return
end
replicaForPlayer:FireServer("SelectHotbarSlot", slot)
end
ClientState.Changed = changed.Event
return ClientState