So I was working on revamping my old gun system, and I wanted to add ammo, but I came across an issue pretty soon. If you have 1 magazine left, but you have 0 bullets in your current magazine, it wouldn’t reload. Here is the script:
Server script inside of tool
local db = false
local configs = script.Parent.Configs
script.Parent.Fire.OnServerEvent:Connect(function(player, mousePos)
local storedammo = configs.StoredAmmo
local ammo = configs.Ammo
local mags = configs.Mags
local tool = script.Parent
--local fireAniM = tool.FireAnim
local char = tool.Parent
local hmoid = char.Humanoid
--local animT = hmoid:LoadAnimation(fireAniM)
if mags.Value ~= 0 and ammo.Value ~= 0 then
if ammo.Value ~= 0 then
ammo.Value -= 1
--animT:Play()
script.Parent.Handle.Shot:Play()
local raycastParams = RaycastParams.new()
raycastParams.FilterDescendantsInstances = {player.Character}
raycastParams.FilterType = Enum.RaycastFilterType.Blacklist
local raycastResult = workspace:Raycast(script.Parent.Handle.Position, (mousePos - script.Parent.Handle.Position)*configs.BulletRange.Value,raycastParams)
if raycastResult then
local hitPart = raycastResult.Instance
local model = hitPart:FindFirstAncestorOfClass("Model")
if model then
if model:FindFirstChild("Humanoid") then
model.Humanoid:TakeDamage(script.Parent.Configs.Damage.Value)
game:GetService("ReplicatedStorage"):WaitForChild("HitMark"):FireClient(player)
end
end
end
elseif ammo.Value == 0 then
if not db then
db = true
script.Parent.Handle.Reload:Play()
wait(script.Parent.Handle.Reload.TimeLength)
mags.Value -= 1
ammo.Value = storedammo.Value
db = false
end
end
end
end)
In your first “if”, you look whether the gun has a mag and ammo left. You then do a check for when the ammo is not zero or when it’s zero. Because of this, the first if needs to be removed. Additionally, the mag check (whether you have a mag left) needs to be placed inside the elseif, because that’s where you reload the gun.
...
elsif ammo.Value == 0 and mags.Value ~= 0 then
...
For some reason, it’s not working. No errors, just nothing is happening, updated script:
local db = false
local configs = script.Parent.Configs
script.Parent.Fire.OnServerEvent:Connect(function(player, mousePos)
local storedammo = configs.StoredAmmo
local ammo = configs.Ammo
local mags = configs.Mags
local tool = script.Parent
--local fireAniM = tool.FireAnim
local char = tool.Parent
local hmoid = char.Humanoid
--local animT = hmoid:LoadAnimation(fireAniM)
if ammo.Value ~= 0 then
ammo.Value -= 1
--animT:Play()
script.Parent.Handle.Shot:Play()
local raycastParams = RaycastParams.new()
raycastParams.FilterDescendantsInstances = {player.Character}
raycastParams.FilterType = Enum.RaycastFilterType.Blacklist
local raycastResult = workspace:Raycast(script.Parent.Handle.Position, (mousePos - script.Parent.Handle.Position)*configs.BulletRange.Value,raycastParams)
if raycastResult then
local hitPart = raycastResult.Instance
local model = hitPart:FindFirstAncestorOfClass("Model")
if model then
if model:FindFirstChild("Humanoid") then
model.Humanoid:TakeDamage(script.Parent.Configs.Damage.Value)
game:GetService("ReplicatedStorage"):WaitForChild("HitMark"):FireClient(player)
end
end
end
elseif ammo.Value == 0 and ammo.Value ~= 0 then
if not db then
db = true
script.Parent.Handle.Reload:Play()
wait(script.Parent.Handle.Reload.TimeLength)
mags.Value -= 1
ammo.Value = storedammo.Value
db = false
end
end
end)
Also, should I keep the reloads, and ammo on the server or the client?
Depends on the design, but if you don’t want your players to be able to exploit, then you should store the important information on the server. Even hitting a player could be checked by the server, so that an exploiter can’t shoot a player across the map.
Everything but the detection of the player clicking and the ammo gui is on the client. I have another question, I made the walk speed of a player change when you equip the gun on the client, should it be on the server?
Sadly speedhacking is very easy due to the fact that the client can change everything on its own machine. Even when only setting the speed change (from the gun) server-side, the player can still speedhack. What you could do is timed checks on the server, setting the speed of the player accordingly, so when the player changes its speed on his client, it gets reset. But this can be heavy on performance so might not be the perfect solution.
EDIT: In general, it’s very difficult to make a game 100% exploit proof. So I would keep exploit defence in mind, but would compare it with the potential performance decrease. In the end, exploiters are not present in very big numbers, so the experience of normal players has a big factor.
I was mostly thinking about if the change in the walk speed on the client was displayed on the server so other players could see it. I am pretty sure you can get the player in the equipped function like this:
tool.Equipped:Connect(function(plr)
end)
Is something like this possible? Also thank you for the information on exploiters.
EDIT: I did a test about printing the plr on the server, and it just prints “Instance”.
Yes, you can see server side whether a player has a weapon equipped, but it’s more difficult then just doing it client side tbh. Client side, it’s like you showed with the function (without the player), but server side, you would need to check whether the tool is in the backpack of the player (How do I check if a tool is equipped? - #2 by BasedKnowledge).
So personally, I would do it client side. If you need information from the server when you equip the weapon, you can get that by making a remote function.
In a local script, can other players see the change of speed? If you answered this question in your reply, sorry I either didn’t see it, or understood it.
Yes, but the server itself will not know how fast the player is walking.
Let’s say that there are two players, A and B. They both have speed 10. Player A changes its speed locally with your code, so its speed becomes 16. When player A walks around, the server and player B can see that player A is moving faster, but the speed value for the server will still be 10. This is not really a problem when the server doesn’t need that information though.
EDIT: If you’re not sure on some things regarding server replication, you can always create two game instances with the “start server” button on the test tab in Roblox Studio, after selecting two players. You basically start a game with that button where each window that opens is another player.