After a painful 5 hours of searching, I decided to just replace the code with this:
It may not be the best, but at least it works.
local function calculateGridCFrame(model:Model, position:Vector3, normal:Vector3)
local plot = workspace.Plots:FindFirstChild(client:GetAttribute('plot'))
local cf, size = getBoundingBox({plot:FindFirstChild('Base')})
local bounds, m_size = getBoundingBox({model.PrimaryPart})
local lpos = cf:PointToObjectSpace(position) + normal * m_size / 2
local size2 = (size - m_size) / 2
local x = math.clamp(lpos.X, -size2.X, size2.X)
local y = math.clamp(lpos.Y, 0, cf.Y + 100) - 1
local z = math.clamp(lpos.Z, -size2.Z, size2.Z)
local abs_x, abs_y, abs_z = math.abs(x), math.abs(y), math.abs(z)
local sign_x, sign_y, sign_z = math.sign(x), math.sign(y), math.sign(z)
x = sign_x * (math.round(abs_x) + (size2.X % 1))
y = sign_y * (math.round(abs_y) + (size2.Y % 1))
z = sign_z * (math.round(abs_z) + (size2.Z % 1))
return cf * CFrame.new(x, y, z) * orientation
end
...
while is_placing do
local dt = task.wait()
local mouse = UserInputService:GetMouseLocation()
local ray = camera:ViewportPointToRay(mouse.X, mouse.Y)
local params = RaycastParams.new()
params.FilterType = Enum.RaycastFilterType.Include
params.FilterDescendantsInstances = {plot}
local result = workspace:Raycast(ray.Origin, ray.Direction.Unit * 1024, params)
if result then
bounds:PivotTo(orientation)
place_cf = calculateGridCFrame(bounds, result.Position, result.Normal)
local cf = pivot:Lerp(place_cf, dt * 15)
preview:PivotTo(cf)
if (place_cf.Position - cf.Position).Magnitude > 50 then
cf = place_cf
preview:PivotTo(place_cf)
end
pivot = cf
end
end