How to verify snap server sided?

image

How would I verify that the placement is within the grid and on the grid square line as on the picture on the server?

function BuildingModule:wallSnap(grid)		
	local GridSize = {X = math.floor(grid.Size.X / snapSize), Z = math.floor(grid.Size.Z / snapSize)}
	local Pivot = {X = grid.Position.X - (grid.Size.X / 2), Z = grid.Position.Z - (grid.Size.Z / 2)}

	local X = math.min(GridSize.X, math.max(0, math.floor((mouse.Hit.X - Pivot.X) / snapSize))) * snapSize
	local Z = math.min(GridSize.Z, math.max(0, math.floor((mouse.Hit.Z - Pivot.Z) / snapSize))) * snapSize

	local normalizedRotation = self.rotation % 360
	local isRotated = normalizedRotation == 90 or normalizedRotation == 270

	local adjustX = isRotated and (self.object.PrimaryPart.Size.Z / 2) or (self.object.PrimaryPart.Size.X / 2)
	local adjustZ = isRotated and (self.object.PrimaryPart.Size.X / 2) or (self.object.PrimaryPart.Size.Z / 2)

	local Position = Vector3.new(Pivot.X + X - adjustX, grid.Position.Y + (grid.Size.Y / 2), Pivot.Z + Z - adjustZ)

	local cf = CFrame.new(Position) * CFrame.Angles(0, math.rad(normalizedRotation), 0)

	local tween = TweenService:Create(self.object.PrimaryPart, TweenInfo.new(0.4, Enum.EasingStyle.Quad),
		{CFrame = cf}
	)
		
	tween:Play()
	tween.Completed:Wait()
end
6 Likes

Either shoot a ray downwards from the part and check if it hits a line, or check if the position of the part is within the area of the grid. You can find the documentation for Raycasts here.

2 Likes

The line is a texture, checking if its within the grid is easy however that will allow exploiters to place it anywhere within the grid which is not what I want

3 Likes
local function checkWallPlacement(data)
	local position = data.pos
	local gridData = GridsModule.getData(data.plr)[1]
	local gridSize = gridData.gridPart.Size
	local snapSize = gridData.tileSize
	
	local grid = gridData.gridPart

	local GridSize = {X = math.floor(grid.Size.X / snapSize), Z = math.floor(grid.Size.Z / snapSize)}
	local Pivot = {X = GridSize.X - (GridSize.X / 2), Z = grid.Position.Z - (GridSize.Z / 2)}

	local X = math.min(gridSize.X, math.max(0, math.floor((data.hitX - Pivot.X) / snapSize))) * snapSize
	local Z = math.min(gridSize.Z, math.max(0, math.floor((data.hitZ- Pivot.Z) / snapSize))) * snapSize
	print(X,Z)
	
	if X % snapSize then
		print("here")
	end
	
	if Z % snapSize then
		print("here")
	end
end

should I try something like this? not sure if my logic is right

2 Likes

You could just do this. Here’s an example where I checked if the X position is legit, you can use the same concept for the Z value.

local function checkWallPlacement(data)
	local gridData = GridsModule.getData(data.plr)[1]
	local gridSize = gridData.gridPart.Size
	local snapSize = gridData.tileSize

    -- Check if X is inside the grid, and if it's divisible by the snapSize then X is on the line texture
    if data.hitX <= gridSize.X and data.hitX % snapSize == 0 then
        print("X is legit")
    end
end
3 Likes

I don’t know what your data.hitX value is, but in this example I assumed it to be the Part’s position on the X axis relative to the corner of the grid. So if your Part is in the center of the grid and the gridSize is 100 then data.hitX should be 50. Here’s how you can calculate this if you’re not already doing this:

local corner = grid.Position - grid.size / 2
data.hitX = Part.Position.X - corner.X
data.hitZ = Part.Position.Z - corner.Z

Now you should be able to implement it. If it works please mark the reply above as solution :smiley:

1 Like

Woudn’t hitX and hitZ be based off of the mouse positions?

1 Like

Yea but you’re moving the Part to the mouse position no?

1 Like
local function checkWallPlacement(data)
	local gridData = GridsModule.getData(data.plr)[1]
	local snapSize = gridData.tileSize
	
	local gridPart = gridData.gridPart
	local gridSize = gridData.gridPart.Size
			
	local corner = gridPart.Position - gridSize	 / 2
	data.hitX = data.pos.X - corner.X
	data.hitZ = data.pos.Z - corner.Z

	-- Check if X is inside the grid, and if it's divisible by the snapSize then X is on the line texture
	if data.hitX <= gridSize.X and data.hitX % snapSize == 0 then
		print("X is legit")
	end
end

data.pos is the Position at the object/part, I tried this code and even when its on the grid it doesn’t print "X is legit’

1 Like

Oh, I understand now. You can create a new variable for X and Z instead of changing hitX/hitZ.

I just didn’t know what hitX was and I assumed it was something else like I said earlier.

1 Like

So what would the detection for X and Z be? Mouse positions aren’t needed if the position of the object is checked based on

  1. if its in the grid
  2. if its on a line aka snappable (but idk how to calculate that)
1 Like

You can use hitX and hitZ instead of the parts X and Z positions because they should be the same anyways.

1 Like

I just tested it in Studio and it works perfectly fine for me. Can you send a video of you testing?

1 Like

I’m gonna create a simple test place please give me a few minutes

1 Like

The only problem I found is when the Part goes in a negative direction it still thinks that X is legit so supplement the if statement with X >= 0 like so:

if X >= 0 and X <= gridSize.X and X % snapSize == 0 then
	print("X is legit")
end
1 Like

Please check, its all handled in the ModuleScript in ReplicatedStorage

1 Like

Finally found a solution, instead of checking if its snappable on server I just sent raw data and snapped it on the server, thank you for your help though!

A lot easier than I imagined

1 Like

The problem is not with the check, it’s with the positioning of the part. If you print data.X you will get a number with decimals like 59.9988

1 Like

Yea I was gonna say you have to snap it on the server

3 Likes

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.