diff --git a/src/ReplicatedStorage/Shared/PlacementManager.lua b/src/ReplicatedStorage/Shared/PlacementManager.lua index 1d79122..67498b8 100644 --- a/src/ReplicatedStorage/Shared/PlacementManager.lua +++ b/src/ReplicatedStorage/Shared/PlacementManager.lua @@ -26,6 +26,15 @@ raycastParams.FilterDescendantsInstances = {PlacementManager.ChunkFolder} raycastParams.FilterType = Enum.RaycastFilterType.Include raycastParams.IgnoreWater = true +local Mouse: Mouse = nil +local lastNormalId: Enum.NormalId? = nil +local lastRaycastFailure: string? = nil +local lastSelectedChunkKey: string? = nil +local lastSelectedBlockKey: string? = nil +local BREAK_ROLLBACK_TIMEOUT = 0.6 +local pendingBreaks = {} +local clearSelection + if _G.__BLOCKSCRAFT_PLACEMENT_MANAGER then return _G.__BLOCKSCRAFT_PLACEMENT_MANAGER end @@ -35,6 +44,17 @@ PlacementManager.SelectionBox = script.SelectionBox:Clone() PlacementManager.SelectionBox.Name = "$SelectionBox"..(game:GetService("RunService"):IsServer() and "_SERVER" or "") PlacementManager.SelectionBox.Parent = game:GetService("Workspace"):FindFirstChildOfClass("Terrain") PlacementManager.SelectionBox.Adornee = nil +PlacementManager.SelectionBox:GetPropertyChangedSignal("Adornee"):Connect(function() + local adornee = PlacementManager.SelectionBox.Adornee + if not adornee then + return + end + adornee.AncestryChanged:Connect(function(_, parent) + if not parent then + clearSelection("adornee destroyed") + end + end) +end) -- Trash method TODO: Fix this local function findChunkFolderFromDescendant(inst: Instance): Instance? @@ -71,10 +91,12 @@ local function resolveBlockInstance(chunkFolder: Instance, chunkName: string, bl return chunkInst:FindFirstChild(blockName) end -local function clearSelection(reason: string?) +clearSelection = function(reason: string?) PlacementManager.SelectionBox.Adornee = nil PlacementManager.SelectionBox.Parent = nil lastNormalId = nil + lastSelectedChunkKey = nil + lastSelectedBlockKey = nil if reason then lastRaycastFailure = reason end @@ -105,11 +127,6 @@ local function findChunkAndBlock(inst: Instance): (string?, string?) return nil, nil end -local Mouse: Mouse = nil -local lastNormalId: Enum.NormalId? = nil -local BREAK_ROLLBACK_TIMEOUT = 0.6 -local pendingBreaks = {} -local lastRaycastFailure: string? = nil local function vectorToNormalId(normal: Vector3): Enum.NormalId local ax, ay, az = math.abs(normal.X), math.abs(normal.Y), math.abs(normal.Z) if ax >= ay and ax >= az then @@ -324,6 +341,15 @@ function PlacementManager:Raycast() script.RaycastResult.Value = nil return end + local chunkKey = makeChunkKey(chunkCoords.X, chunkCoords.Y, chunkCoords.Z) + local blockKey = makeBlockKey(blockCoords.X, blockCoords.Y, blockCoords.Z) + + -- block is being optimistically broken, do not highlight it + if getPendingBreak(chunkKey, blockKey) then + clearSelection("block pending break") + script.RaycastResult.Value = nil + return + end -- hide selection if block no longer exists (air/removed) local chunk = ChunkManager:GetChunk(chunkCoords.X, chunkCoords.Y, chunkCoords.Z) @@ -341,7 +367,11 @@ function PlacementManager:Raycast() end lastRaycastFailure = nil - setSelection(blockInstance, PlacementManager.ChunkFolder) + if lastSelectedChunkKey ~= chunkKey or lastSelectedBlockKey ~= blockKey then + setSelection(blockInstance, PlacementManager.ChunkFolder) + lastSelectedChunkKey = chunkKey + lastSelectedBlockKey = blockKey + end script.RaycastResult.Value = objLookingAt lastNormalId = vectorToNormalId(result.Normal) debugPlacementLog( @@ -520,9 +550,8 @@ function PlacementManager:GetBlockAtMouse(): nil | {chunk:Vector3, block: Vector local selectedPart = PlacementManager:RaycastGetResult() --print(selectedPart and selectedPart:GetFullName() or nil) if selectedPart == nil then - PlacementManager.SelectionBox.Adornee = nil + clearSelection() script.RaycastResult.Value = nil - lastNormalId = nil debugPlacementLog("[PLACE][CLIENT][TARGET]", "no selectedPart after raycast", lastRaycastFailure) return nil end @@ -624,7 +653,7 @@ function PlacementManager:Init() PlacementManager:Raycast() end) if not a then - PlacementManager.SelectionBox.Adornee = nil + clearSelection("raycast error") script.RaycastResult.Value = nil end end)