Hello blazepowerroblox!
The reason you should not allow the client to decide what damage is to be dealt is because exploiters will tamper with this and increase their damages to irregular amounts.
The solution?
Whenever the client fires what part they hit (unless you are raycasting on the server, not recommended for FPS games where hit registration is required to be precise), you can verify that X part is a part of a character, X part could have been hit by Y client, Y client had enough ammo to shoot X part, and keep a table of damages per weapon on the server.
local damages = setmetatable({
["M4A1"] = setmetatable({
["Head"] = {100,110},
["Torso"] = {50,60},
["Left Arm"] = {30,40},
["Right Arm"] = {30,40},
["Left Leg"] = {30,40},
["Right Leg"] = {30,40}
},{
__index = function(data,indexed)
return {30,40}
end,
})
},{
__index = function(data,indexed) --we use metatables so that we can prevent errors from occurring if X gun does not have damage values set
return setmetatable({
["Head"] = {100,110},
["Torso"] = {50,60},
["Left Arm"] = {30,40},
["Right Arm"] = {30,40},
["Left Leg"] = {30,40},
["Right Leg"] = {30,40}
},{
__index = function(data,indexed)
return {30,40}
end,
})
end,
})
--
local function processhitregister(player,hitpart) --will return the player and the amount they should be damaged for
if player.Character then
local tool = player.Character:FindFirstChildOfClass("Tool")
if tool then
if tool:FindFirstChild("CurrentAmmo") then --this is an example of an ammo check
if tool.CurrentAmmo.Value > 0 then --this is an example of an ammo check
local player2 = game.Players:GetPlayerFromCharacter(hitpart.Parent)
if player2 then
local random = Random.new(os.time())
local damagetable = damages[tool.Name][hitpart.Name]
return player2,random:NextInteger(damagetable[1],damagetable[2])
end
end
end
end
end
end