I have a reload system for a game, it works but is extremely buggy and prone to breaking, if you switch weapons while an old one is reloading and try to reload the new one everything breaks spectacularly, the reload text does not show up. Sometimes the game things the gun has no ammo at all for some reason, I tried to remake this system like 4 times now and every time it bugs so I don’t know what to do at all anymore. I know this script is trusting the client, its a single player game so It’s fine and there are an exact replica of the client script for each gun in the game with unique attributes
Server:
local event = game.ReplicatedStorage.ImportantRemotes.ReloadGun
local activeReloads = {}
function reloadEvent(player, Gun)
if player.Character.Humanoid.Health <= 0 then return end
if Gun:GetAttribute("CanShoot") == false then return end
activeReloads[Gun] = true
player.PlayerGui.Gun.Frame.Ammo.Text = "Reloading..."
print("Reload started")
Gun:SetAttribute("CanShoot", false)
local bulletsLeft = Gun:GetAttribute("BulletsLeft")
local inMag = Gun:GetAttribute("InMag")
local maxMagSize = Gun:GetAttribute("MagSize")
local ammoToFill = maxMagSize - inMag
if bulletsLeft == 0 then
Gun:SetAttribute("CanShoot", true)
return
end
player.PlayerGui.Gun.Frame.Ammo.Text = "Reloading..."
task.wait(Gun:GetAttribute("ReloadTime"))
if bulletsLeft >= ammoToFill then
Gun:SetAttribute("InMag", maxMagSize)
Gun:SetAttribute("BulletsLeft", bulletsLeft - ammoToFill)
else
Gun:SetAttribute("InMag", bulletsLeft)
Gun:SetAttribute("BulletsLeft", 0)
end
Gun:SetAttribute("CanShoot", true)
--player.PlayerGui.Gun.Frame.Ammo.Text = Gun:GetAttribute("InMag") .. "/" .. Gun:GetAttribute("BulletsLeft")
print("Reload ended")
activeReloads[Gun] = false
end
event.OnServerEvent:Connect(function(player, Gun)
if not activeReloads[Gun] then
task.spawn(reloadEvent, player, Gun)
end
end)
client:
local tool = script.Parent
local player = game.Players.LocalPlayer
local mouse = player:GetMouse()
local UIS = game:GetService("UserInputService")
local shootEvent = script.Parent:WaitForChild("DealDamage")
local decreaseAmmo = script.Parent:WaitForChild("DecreaseAmmo")
local setAmmo = game.ReplicatedStorage.ImportantRemotes.ReloadGun
local AmmoTextLabel = player.PlayerGui.Gun.Frame.Ammo
local GynTypeTextLabel = player.PlayerGui.Gun.Frame.GunType
--tool.Activated:Connect(function()
-- local MP = mouse.Hit.Position
-- shootEvent:FireServer(player)
--end)
local tool = script.Parent
local BulletsFolder = game.Workspace:WaitForChild("Bullets")
local FastCast = require(game.ReplicatedStorage.FastCastRedux)
-- FastCast.VisualizeCasts = true
local castBehavior = FastCast.newBehavior()
local castParams = RaycastParams.new()
castParams.FilterType = Enum.RaycastFilterType.Exclude
castParams.IgnoreWater = true
local HoldingTrigger = true
local Equipped = false
local bulletTemplate = Instance.new("Part")
bulletTemplate.Anchored = true
bulletTemplate.CanCollide = false
bulletTemplate.Size = Vector3.new(0.1, 0.1, 4)
bulletTemplate.Material = Enum.Material.Neon
bulletTemplate.BrickColor = BrickColor.new("Yellow flip/flop")
castBehavior.RaycastParams = castParams
castBehavior.CosmeticBulletContainer = BulletsFolder
castBehavior.CosmeticBulletTemplate = bulletTemplate
local function updateAmmo()
AmmoTextLabel.Text = script.Parent:GetAttribute("InMag").."/"..script.Parent:GetAttribute("BulletsLeft")
end
local function Hit(cast, result, velocity, bullet)
game.Debris:AddItem(bullet, 0.1)
if Equipped == false then return end
local hit = result.Instance
local character = hit:FindFirstAncestorWhichIsA("Model")
if character and character:FindFirstChild("Humanoid") then
shootEvent:FireServer(character.Humanoid, 20)
--character.Humanoid:TakeDamage(20)
end
end
local function onLengthChanged(cast, lastPoint, direction, length, velocity, bullet)
if Equipped == false then return end
if bullet then
local bulletLength = bullet.Size.Z / 2
local offset = CFrame.new(0, 0, -(length - bulletLength))
bullet.CFrame = CFrame.lookAt(lastPoint, lastPoint + direction):ToWorldSpace(offset)
end
end
local function equipped()
Equipped = true
player.PlayerGui.Gun.Frame.Ammo.Text = script.Parent:GetAttribute("InMag").."/"..script.Parent:GetAttribute("BulletsLeft")
player.PlayerGui.Gun.Frame.GunType.Text = script.Parent.Name
castParams.FilterDescendantsInstances = {tool.Parent, BulletsFolder}
end
local caster = FastCast.new()
local function shoot()
if Equipped == false then return end
if script.Parent:GetAttribute("InMag") > 0 and script.Parent:GetAttribute("CanShoot") == true and player.Character.Humanoid.Health > 0 then
if script.Parent:GetAttribute('FireType') == "Semi" then
decreaseAmmo:FireServer()
local firePoint = script.Parent.Barrel.FirePoint
local origin = firePoint.WorldPosition
local direction = player.Character.HumanoidRootPart.CFrame.LookVector.Unit
tool.ShootSound:Play()
--updateAmmo()
caster:Fire(origin, direction * 100, 100, castBehavior)
elseif script.Parent:GetAttribute('FireType') == "Auto" then
while task.wait(script.Parent:GetAttribute('TimeBetweenShotsAuto')) do
if HoldingTrigger == false or Equipped == false or tool:GetAttribute("InMag") <= 0 or tool:GetAttribute("CanShoot") == false then break end
decreaseAmmo:FireServer()
local firePoint = script.Parent.Barrel.FirePoint
local origin = firePoint.WorldPosition
local direction = player.Character.HumanoidRootPart.CFrame.LookVector.Unit
tool.ShootSound:Play()
--updateAmmo()
caster:Fire(origin, direction * 100, 100, castBehavior)
end
end
else
tool.GunEmpty:Play()
end
end
UIS.InputBegan:Connect(function(input, gp)
if gp then return end
if input.KeyCode == Enum.KeyCode.R then
if Equipped == false then return end
setAmmo:FireServer(script.Parent)
end
end)
mouse.Button1Down:Connect(function()
if Equipped == false then return end
HoldingTrigger = true
end)
mouse.Button1Up:Connect(function()
if Equipped == false then return end
HoldingTrigger = false
end)
tool.Unequipped:Connect(function()
if Equipped == false then return end
Equipped = false
end)
script.Parent:GetAttributeChangedSignal("InMag"):Connect(function()
player.PlayerGui.Gun.Frame.Ammo.Text = script.Parent:GetAttribute("InMag").."/"..script.Parent:GetAttribute("BulletsLeft")
end)
script.Parent:GetAttributeChangedSignal("BulletsLeft"):Connect(function()
player.PlayerGui.Gun.Frame.Ammo.Text = script.Parent:GetAttribute("InMag").."/"..script.Parent:GetAttribute("BulletsLeft")
end)
tool.Equipped:Connect(equipped)
tool.Activated:Connect(shoot)
caster.LengthChanged:Connect(onLengthChanged)
caster.RayHit:Connect(Hit)