Plot controller:
function PlotSystem.place(Player: Player, name: string, targetCF: CFrame, objectRotation): boolean
local object: Model = PlaceableObject:FindFirstChild(name)
local plot = Used[Player.UserId]
if not object or not plot then return false end
local objectSize = object:GetExtentsSize()
if not Validator.WithinBounds(plot, objectSize, targetCF) then return false end
if not Validator.CollisionCheck(plot, objectSize, targetCF, Player) then return false end
local successUpdating, itemTable = playerDataController.playerPlacingItem(Player, name)
if not successUpdating then return false end
local newObject: Model = object:Clone()
local newPos = targetCF.Position
newObject:PivotTo(CFrame.new(math.round(newPos.X), newPos.Y, math.round(newPos.Z)) * CFrame.Angles(0, objectRotation, 0))
newObject.Parent = plot.PlotObjects
placeChangeQuantity:FireClient(Player, itemTable, name)
return true
end
Update Async for item harshMap:
local inventoryCache = {}
function module.loadInventory(player: Player)
local playerKey = string.format("user_%d", player.UserId)
local success, data = pcall(function()
return ItemsHashMap:GetAsync(playerKey)
end)
inventoryCache[player.UserId] = (success and data) or {}
end
function module.saveInventory(player: Player)
local playerKey = string.format("user_%d", player.UserId)
local data = inventoryCache[player.UserId]
if not data then return end
pcall(function()
ItemsHashMap:SetAsync(playerKey, data, 86400)
end)
inventoryCache[player.UserId] = nil
end
function module.playerPlacingItem(player: Player, itemPlaced: string)
local inv = inventoryCache[player.UserId]
if not inv then return false, {} end
local entry = inv[itemPlaced]
if not entry or entry.Quantity <= 0 then return false, {} end
entry.Quantity -= 1
return true, entry
end