I decided to get back into LUA and so I wanted to start working on a few projects to jog my mind.
It’s a very basic click-destroy that uses remote events/functions and a tool to function.
How it works?
The player has a tool in there inventory. When equipped, it will send the server the target of the mouse. The server then checks if the target is nil (pointing at something that isnt a part / the sky) and if it is on a blacklist (parts you cant destroy.)
If so, it returns true and sends these results back to the client. Once the client gets the all good, it then begins listening for the event that destroys the part.
Note: You can’t fire the destroy part event without going through the checking event, and if you do you get kicked by the server. The activation event wont start until after you’ve passed the check.
Next, the server then finally checks if you already passed the check and the part is safe to destroy. If so, the server destroys the part. Simple!
Server Script
--// Variables \\--
local rs, players = game:GetService("ReplicatedStorage"), game:GetService("Players")
local requestDestroy = rs.RequestEvent
local checkPart = rs.CheckPart
local allowedToFire = false
local selectedTarget
local remoteFired = false
local blacklist = {
"Baseplate"
};
--// Remotes \\--
checkPart.OnServerInvoke = function(player, target)
remoteFired = true
allowedToFire = false
selectedTarget = nil
if target == nil then
print("Selected target is nil.")
allowedToFire = false
return
else
for i, v in pairs(blacklist) do
if target.Name ~= v then
print("Target not in blacklist.")
game.Workspace[player.Name].Sword.Handle.Color = Color3.new(0.0666667, 1, 0.141176)
print("Set handle to green.")
allowedToFire = true
selectedTarget = target
return true
else
allowedToFire = false
return false
end
end
end
game.Workspace[player.Name].Sword.Handle.Color = Color3.new(1, 0, 0.0156863)
remoteFired = false
end
requestDestroy.OnServerEvent:Connect(function(player, target)
if not remoteFired then
player:Kick("Attempting to illegally fire remotes.")
else
if selectedTarget == nil then
return
else
selectedTarget:Destroy()
end
end
end)
Local Script
--// Variables \\--
local rs, players, runService = game:GetService("ReplicatedStorage"), game:GetService("Players"), game:GetService("RunService")
local requestDestroy = rs.RequestEvent
local checkPart = rs.CheckPart
local player = players.LocalPlayer
local tool = script.Parent
local mouse = player:GetMouse()
local debounce = false
--// Events \\--
runService.RenderStepped:Connect(function()
if not debounce then
debounce = true
tool.Equipped:Connect(function()
print("Tool is equipped.")
local requestAllowed = checkPart:InvokeServer(mouse.Target)
if requestAllowed then
print("Beginning to listen for mouse input.")
tool.Activated:Connect(function()
requestDestroy:FireServer(mouse.Target)
end)
end
end)
end
end)
I made sure to always keep in mind not to trust the client and therefore I minimized how much control the client has when it comes to allowing the parts to be destroyed. If you can bypass this or point out any flaws, that would be nice.
I was also trying to figure out how to actively get the player’s mouse target while its equipped, but gave up. If you know how please let me know.