core: broken

This commit is contained in:
2026-01-07 22:51:11 +02:00
parent a9da63e90e
commit 165913ca51
13 changed files with 582 additions and 217 deletions

View File

@@ -21,13 +21,15 @@ PlacementManager.SelectionBox.Name = "$SelectionBox"..(game:GetService("RunServi
PlacementManager.SelectionBox.Parent = game:GetService("Workspace"):FindFirstChildOfClass("Terrain")
-- Trash method TODO: Fix this
local function findParent(i: Instance): Instance
local f = i:FindFirstAncestorOfClass("Folder")
local d = i
repeat
d = d.Parent
until d.Parent == f
return d
local function findChunkFolderFromDescendant(inst: Instance): Instance?
local current = inst
while current and current.Parent do
if current.Parent == PlacementManager.ChunkFolder then
return current
end
current = current.Parent
end
return nil
end
local Mouse: Mouse = nil
@@ -141,13 +143,11 @@ local function getPlayerPosition(): Vector3?
return root and root.Position or nil
end
local MAX_REACH = 512
local function isWithinReach(cx: number, cy: number, cz: number, x: number, y: number, z: number): boolean
local playerPos = getPlayerPosition()
if not playerPos then
return false
end
local blockPos = Util.ChunkPosToCFrame(Vector3.new(cx, cy, cz), Vector3.new(x, y, z)).Position
return (blockPos - playerPos).Magnitude <= 24
-- Client-side reach loosened; rely on server authority
return true
end
-- Gets the block and normalid of the block (and surface) the player is looking at
@@ -155,9 +155,8 @@ function PlacementManager:Raycast()
if not Mouse then
Mouse = game:GetService("Players").LocalPlayer:GetMouse()
end
task.synchronize()
local objLookingAt = Mouse.Target
local dir = Mouse.TargetSurface
local dir = Mouse.TargetSurface or Enum.NormalId.Top
if not objLookingAt then
PlacementManager.SelectionBox.Adornee = nil
script.RaycastResult.Value = nil
@@ -166,17 +165,23 @@ function PlacementManager:Raycast()
end
--if not objLookingAt:IsDescendantOf(ChunkManager.ChunkFolder) then return end
local parent = findParent(objLookingAt)
if parent:GetAttribute("ns") == true then
local chunkFolder = findChunkFolderFromDescendant(objLookingAt)
if not chunkFolder then
PlacementManager.SelectionBox.Adornee = nil
script.RaycastResult.Value = nil
lastNormalId = nil
return
end
PlacementManager.SelectionBox.Adornee = parent
script.RaycastResult.Value = parent
if chunkFolder:GetAttribute("ns") == true then
PlacementManager.SelectionBox.Adornee = nil
script.RaycastResult.Value = nil
lastNormalId = nil
return
end
PlacementManager.SelectionBox.Adornee = objLookingAt
script.RaycastResult.Value = objLookingAt
lastNormalId = dir
return parent, dir
return objLookingAt, dir
end
function PlacementManager:RaycastGetResult()
@@ -190,12 +195,30 @@ local tickRemote = game:GetService("ReplicatedStorage").Tick
-- FIRES REMOTE
function PlacementManager:PlaceBlock(cx, cy, cz, x, y, z, blockId: string)
--print("placeblock")
--local chunk = ChunkManager:GetChunk(cx, cy, cz)
--chunk:CreateBlock(x, y, z, blockData)
task.synchronize()
-- ensure chunk is present/rendered client-side
local chunk = ChunkManager:GetChunk(cx, cy, cz)
if chunk and not chunk.loaded then
ChunkManager:LoadChunk(cx, cy, cz)
end
-- if the client already thinks this block is the same id, skip sending
if chunk then
local existing = chunk:GetBlockAt(x, y, z)
local existingId = existing and existing.id
if existingId and tostring(existingId) == tostring(blockId) then
return
end
end
-- optimistic local apply; server will correct on tick
if chunk then
chunk:CreateBlock(x, y, z, {
id = tonumber(blockId) or blockId,
state = {},
})
end
placeRemote:FireServer(cx, cy, cz, x, y, z, blockId)
task.desynchronize()
end
-- FIRES REMOTE
@@ -229,20 +252,24 @@ function PlacementManager:BreakBlock(cx, cy, cz, x, y, z)
chunk:RemoveBlock(x, y, z)
end
scheduleBreakRollback(cx, cy, cz, x, y, z)
task.synchronize()
breakRemote:FireServer(cx, cy, cz, x, y, z)
task.desynchronize()
end
-- CLIENTSIDED: only apply server-validated changes
local function applyPlaceBlockLocal(cx, cy, cz, x, y, z, blockData)
local chunk = ChunkManager:GetChunk(cx, cy, cz)
if chunk and not chunk.loaded then
ChunkManager:LoadChunk(cx, cy, cz)
end
chunk:CreateBlock(x, y, z, blockData)
end
-- CLIENTSIDED: only apply server-validated changes
local function applyBreakBlockLocal(cx, cy, cz, x, y, z)
local chunk = ChunkManager:GetChunk(cx, cy, cz)
if chunk and not chunk.loaded then
ChunkManager:LoadChunk(cx, cy, cz)
end
if not chunk then
return
end
@@ -270,6 +297,12 @@ function PlacementManager:GetBlockAtMouse(): nil | {chunk:Vector3, block: Vector
lastNormalId = nil
return nil
end
if not selectedPart.Parent then
PlacementManager.SelectionBox.Adornee = nil
script.RaycastResult.Value = nil
lastNormalId = nil
return nil
end
local chunkCoords = Util.BlockPosStringToCoords(selectedPart.Parent.Name)
local blockCoords = Util.BlockPosStringToCoords(selectedPart.Name)
@@ -282,14 +315,15 @@ end
function PlacementManager:GetTargetAtMouse(): nil | {chunk:Vector3, block: Vector3, normal: Enum.NormalId}
local hit = PlacementManager:GetBlockAtMouse()
if not hit or not lastNormalId then
if not hit then
return nil
end
local normal = lastNormalId or Enum.NormalId.Top
return {
chunk = hit.chunk,
block = hit.block,
normal = lastNormalId
normal = normal
}
end
@@ -312,10 +346,8 @@ function PlacementManager:Init()
PlacementManager:Raycast()
end)
if not a then
task.synchronize()
PlacementManager.SelectionBox.Adornee = nil
script.RaycastResult.Value = nil
task.desynchronize()
end
end)
tickRemote.OnClientEvent:Connect(function(m, cx, cy, cz, x, y, z, d)