I'm not having errors and it works, but it's really finicky. I have a LocalScript to do all the math and everything and then I send it through an event to place it with a ServerScript. I was hoping someone could improve my code to make it better. Here is the LocalScript inside StarterGui
local uis = game:GetService('UserInputService')
local plr = game.Players.LocalPlayer
local mouse = plr:GetMouse()
if uis.MouseEnabled then
local OriginalMousePos = mouse.Hit.Position
mouse.Button1Down:Connect(function()
if plr.Mode.Value == 'Building' and plr.Block.Value ~= '' then --Mode is the mode they are in (None, Building, or Removing) and Block is the block they are using (string of the block's name)
local pos = mouse.Hit.Position
local x = math.floor(pos.X)
local y = math.floor(pos.Y)
local z = math.floor(pos.Z)
local bs = plr.BlockSize.Value --Size of the block
local base = workspace.Plots[plr.Plot.Value].Bases.Base --base they are building on
local downX = base.Position.X - (base.Size.X / 2)
local upX = base.Position.X + (base.Size.X / 2)
local downZ = base.Position.Z - (base.Size.Z / 2)
local upZ = base.Position.Z + (base.Size.Z / 2)
local coords = Vector3.new(x + bs/2, y + bs/2, z + bs/2)
if coords.X > downX and coords.X < upX and coords.Z > downZ and coords.Z < upZ then --Make sure they are in they're plot
game.ReplicatedStorage["Remove Passive"]:FireServer() --remove any pasiive blocks on the base
game.ReplicatedStorage["Place Block"]:FireServer(plr.Block.Value, coords, bs, false) --place a block
end
end
end)
while true do
wait()
if OriginalMousePos ~= mouse.Hit.Position and plr.Mode.Value == 'Building' and plr.Block.Value ~= '' then --If they still have the same position, there is no point in placing another passive block
local pos = mouse.Hit.Position
OriginalMousePos = pos --update OriginalMousePos
local x = math.floor(pos.X)
local y = math.floor(pos.Y)
local z = math.floor(pos.Z)
local bs = plr.BlockSize.Value --Size of the block
local base = workspace.Plots[plr.Plot.Value].Bases.Base
local downX = base.Position.X - (base.Size.X / 2)
local upX = base.Position.X + (base.Size.X / 2)
local downZ = base.Position.Z - (base.Size.Z / 2)
local upZ = base.Position.Z + (base.Size.Z / 2)
local coords = Vector3.new(x + bs/2, y + bs/2, z + bs/2)
if coords.X > downX and coords.X < upX and coords.Z > downZ and coords.Z < upZ then --Make sure they are inside the base
game.ReplicatedStorage["Remove Passive"]:FireServer() --remove any passive blocks
game.ReplicatedStorage["Place Block"]:FireServer(plr.Block.Value, Vector3.new(x + bs/2, y + bs/2, z + bs/2), bs, true) --place passive block.
end
end
end
end
If you are wondering why I added half the size of the block when firing the event to place the block, it's to center the block on the plot.
If you need it, here are the scripts for placing a block and removing a passive. Placing a Block in ServerScriptService
local PS = game:GetService('PhysicsService')
game.ReplicatedStorage["Place Block"].OnServerEvent:Connect(function(plr, block, coords, bs, passive)
local block = game.ReplicatedStorage.Blocks[block]:Clone()
block.Position = coords
block.Size = Vector3.new(bs, bs, bs)
if passive then
block.CanCollide = false
block.Transparency = 0.5
block.Name = 'Passive'
PS:SetPartCollisionGroup(block, 'Building')
else
PS:SetPartCollisionGroup(block, 'Built')
plr.Blocks[block.Name].Value = plr.Blocks[block.Name].Value - 1
plr.Refresh.Value = true
end
block.Parent = workspace.Plots[plr.Plot.Value].Blocks
end)
Removing a Passive in ServerScriptService
game.ReplicatedStorage["Remove Passive"].OnServerEvent:Connect(function(plr)
pcall(function()
workspace.Plots[plr.Plot.Value].Blocks.Passive:Destroy()
end)
end)
Thx in advance

2 comments
You should do your calculations on the server to prevent hackers
Alright, thx