core: fix hotbar

This commit is contained in:
2026-01-08 23:52:32 +02:00
parent 2c41f40151
commit 2a0dd51659
8 changed files with 429 additions and 53 deletions

View File

@@ -18,8 +18,7 @@ local PM = require(ReplicatedStorage.Shared.PlacementManager)
local BlockManager = require(ReplicatedStorage.Shared.ChunkManager.BlockManager)
local PlacementState = require(ReplicatedStorage.Shared.PlacementState)
local Util = require(ReplicatedStorage.Shared.Util)
local blocksFolder = ReplicatedStorage:WaitForChild("Blocks")
local ClientState = require(ReplicatedStorage.Shared.ClientState)
local HOTBAR_SIZE = 10
@@ -53,33 +52,34 @@ local function isTextInputFocused(): boolean
return config ~= nil and config.IsFocused
end
local function buildHotbarIds(): {string}
local ids = {}
local names = {}
for _, block in ipairs(blocksFolder:GetChildren()) do
local id = block:GetAttribute("n")
if id ~= nil then
local n = tonumber(id)
if n and n > 0 then
local idStr = tostring(n)
table.insert(ids, idStr)
names[idStr] = block:GetAttribute("displayName") or block:GetAttribute("dn") or block.Name
end
end
local function resolveSelectedSlot(slots, desired)
if desired and desired >= 1 and desired <= HOTBAR_SIZE and slots[desired] ~= "" then
return desired
end
table.sort(ids, function(a, b)
local na = tonumber(a)
local nb = tonumber(b)
if na and nb then
return na < nb
end
return a < b
end)
local slots = table.create(HOTBAR_SIZE)
for i = 1, HOTBAR_SIZE do
slots[i] = ids[i] or ""
if slots[i] and slots[i] ~= "" then
return i
end
end
return slots, names
return desired or 1
end
local function buildHotbarFromState()
local slots = table.create(HOTBAR_SIZE)
local names = {}
for i = 1, HOTBAR_SIZE do
local info = ClientState:GetSlotInfo(i)
if info then
slots[i] = tostring(info.id)
names[slots[i]] = info.name or slots[i]
else
slots[i] = ""
end
end
local selected = resolveSelectedSlot(slots, ClientState:GetSelectedSlot())
return slots, names, selected
end
local function ensurePreviewRig(part: Instance)
@@ -131,40 +131,43 @@ end
local Hotbar = Roact.Component:extend("Hotbar")
function Hotbar:init()
local slots, names, selected = buildHotbarFromState()
self.state = {
slots = nil,
names = nil,
selected = 1,
slots = slots,
names = names,
selected = selected,
}
local slots, names = buildHotbarIds()
self.state.slots = slots
self.state.names = names
local initialId = slots and slots[1] or ""
if initialId and initialId ~= "" then
local initialName = names and (names[initialId] or initialId) or initialId
PlacementState:SetSelected(initialId, initialName)
end
self._updateSlots = function()
local nextSlots, nextNames = buildHotbarIds()
self._syncFromClientState = function()
local nextSlots, nextNames, nextSelected = buildHotbarFromState()
nextSelected = resolveSelectedSlot(nextSlots, nextSelected or self.state.selected)
self:setState({
slots = nextSlots,
names = nextNames,
selected = nextSelected,
})
local id = nextSlots[nextSelected] or ""
local name = ""
if id ~= "" then
name = nextNames[id] or id
end
PlacementState:SetSelected(id, name)
end
self._setSelected = function(slot: number)
if slot < 1 or slot > HOTBAR_SIZE then
return
end
local info = ClientState:GetSlotInfo(slot)
if not info then
return
end
ClientState:SetSelectedSlot(slot)
self:setState({
selected = slot,
})
local id = self.state.slots and self.state.slots[slot] or ""
local name = ""
if id ~= "" and self.state.names then
name = self.state.names[id] or id
end
local id = tostring(info.id)
local name = info.name or id
Util.StudioLog("[PLACE][CLIENT][SELECT]", "slot", slot, "id", id, "name", name)
PlacementState:SetSelected(id, name)
end
@@ -258,11 +261,11 @@ end
function Hotbar:didMount()
self._connections = {
blocksFolder.ChildAdded:Connect(self._updateSlots),
blocksFolder.ChildRemoved:Connect(self._updateSlots),
ClientState.Changed:Connect(self._syncFromClientState),
UIS.InputBegan:Connect(self._handleInput),
UIS.InputChanged:Connect(self._handleScroll),
}
self._syncFromClientState()
self:_refreshViewports()
-- initialize selection broadcast
local id = self.state.slots and self.state.slots[self.state.selected] or ""