My gun doesn't deal damage

So I made my own modified version from a Free Gun Model that I saw. It is an AK47, It works fine, everything is correct but only by the Local Part.

All the Scripts of the gun are into a Local Script and probably, for that reason the gun “doesn’t deal damage to other players”, only in the local part. I mean, you can damage them, but in their camera, they won’t die or loose health.

I tried to make a RemoteEvent that could run the Damage function in a Script instead of a LocalScript, but anything worked, do you have any ideas of what can I do? I also checked many Free Models, to see if any model could deal damage to other players and… Nope, they weren’t able to do it.

Now I’m wondering, how the “working guns” are able to deal damage.

8 Likes

Can you include your code (from both scripts)? This’ll help us diagnose specific errors.

2 Likes

Please provide the code you have used.

2 Likes
local function WaitForChild(parent, childName)
	while not parent:FindFirstChild(childName) do parent.ChildAdded:wait() end
	return parent[childName]
end

local UserInput = game:GetService("UserInputService")


local Damage = 18

local FireRate = 1 / 10

local Range = 350

local MinSpread = 0.005

local MaxSpread = 0.07

local ClipSize = 30

local SpareAmmo = 30

local AimInaccuracyStepAmount = .5

local ReloadTime = 2.1


local FriendlyReticleColor = Color3.new(0, 1, 0)
local EnemyReticleColor	= Color3.new(1, 0, 0)
local NeutralReticleColor	= Color3.new(1, 1, 1)

local Spread = MinSpread
local AmmoInClip = ClipSize

local Tool = script.Parent
local Handle = WaitForChild(Tool, 'Handle')
local WeaponGui = nil

local LeftButtonDown
local Reloading = false
local IsShooting = false
local Pitch = script.Parent.Handle.FireSound

local MyPlayer = nil
local MyCharacter = nil
local MyHumanoid = nil
local MyTorso = nil
local MyMouse = nil


local RecoilAnim
local RecoilTrack = nil

local ReloadAnim
local ReloadTrack = nil

local IconURL = Tool.TextureId  
local DebrisService = game:GetService("Debris")
local PlayersService = game:GetService("Players")


local FireSound

local OnFireConnection = nil
local OnReloadConnection = nil

local DecreasedAimLastShot = false
local LastSpreadUpdate = time()

local flare = script.Parent:WaitForChild("Flare")

local FlashHolder = nil


local WorldToCellFunction = workspace.Terrain.WorldToCellPreferSolid
local GetCellFunction = workspace.Terrain.GetCell

function RayIgnoreCheck(hit, pos)
	if hit then
		if hit.Transparency >= 1 or string.lower(hit.Name) == "water" or
				hit.Name == "Effect" or hit.Name == "Rocket" or hit.Name == "Bullet" or
				hit.Name == "Handle" or hit:IsDescendantOf(MyCharacter) then
			return true
		elseif hit:IsA('Terrain') and pos then
			local cellPos = WorldToCellFunction(workspace.Terrain, pos)
			if cellPos then
				local cellMat = GetCellFunction(workspace.Terrain, cellPos.x, cellPos.y, cellPos.z)
				if cellMat and cellMat == Enum.CellMaterial.Water then
					return true
				end
			end
		end
	end
	return false
end

function RayCast(startPos, vec, rayLength)
	local hitObject, hitPos = game.Workspace:FindPartOnRay(Ray.new(startPos + (vec * .01), vec * rayLength), Handle)
	if hitObject and hitPos then
		local distance = rayLength - (hitPos - startPos).magnitude
		if RayIgnoreCheck(hitObject, hitPos) and distance > 0 then
			return RayCast(hitPos, vec, distance)
		end
	end
	return hitObject, hitPos
end



function TagHumanoid(humanoid, player)
	while humanoid:FindFirstChild('creator') do
		humanoid:FindFirstChild('creator'):Destroy()
	end 
	local creatorTag = Instance.new("ObjectValue")
	creatorTag.Value = player
	creatorTag.Name = "creator"
	creatorTag.Parent = humanoid
	DebrisService:AddItem(creatorTag, 1.5)

	local weaponIconTag = Instance.new("StringValue")
	weaponIconTag.Value = IconURL
	weaponIconTag.Name = "icon"
	weaponIconTag.Parent = creatorTag
end


local function CreateBullet(bulletPos)
	local shell = Instance.new("Part")
	shell.CFrame = Tool.Handle.CFrame * CFrame.fromEulerAnglesXYZ(1.5,0,0)
	shell.Size = Vector3.new(1,1,1)
	shell.BrickColor = BrickColor.new("Brick yellow")
	shell.Parent = game.Workspace
	shell.CFrame = script.Parent.Handle.CFrame
	shell.CanCollide = false
	shell.Transparency = 0
	shell.BottomSurface = 0
	shell.TopSurface = 0
	shell.Name = "Shell"
	shell.Velocity = Tool.Handle.CFrame.lookVector * 35 + Vector3.new(math.random(-10,10),20,math.random(-10,20))
	shell.RotVelocity = Vector3.new(0,200,0)
	DebrisService:AddItem(shell, 1)

	local shellmesh = Instance.new("SpecialMesh")
	shellmesh.Scale = Vector3.new(.15,.4,.15)
	shellmesh.Parent = shell
	
	return shell
end

local function Mag(magPos)
	local mag = Instance.new("Part")
	mag.CFrame = Tool.Handle.CFrame * CFrame.fromEulerAnglesXYZ(1.5, 0, 0)
	mag.Size = Vector3.new(1, 0.1, 1.25)
	mag.BrickColor = BrickColor.new("Black")
	mag.Parent = game.Workspace
	mag.CFrame = script.Parent.Handle.CFrame
	mag.CanCollide = true
	mag.Transparency = 0
	mag.Velocity = Tool.Handle.CFrame.lookVector * 35 + Vector3.new(math.random(-6, 2), 6,math.random(-2, 4))
	DebrisService:AddItem(mag, 1)
	mag.CastShadow = false

	local magmesh = Instance.new("SpecialMesh", mag)
	magmesh.MeshId = "rbxassetid://2047126151"
	magmesh.TextureId = "rbxgameasset://Images/magmesh"
	magmesh.Scale = Vector3.new(.05,.05,.05)

	local theScript = Tool.Destroyer:Clone()
	theScript.Parent = mag
	mag.Destroyer.Disabled = false
	
	return mag
end

local function Reload()
	if not Reloading then
		Reloading = true
		
		if AmmoInClip ~= ClipSize then
			if RecoilTrack then
				RecoilTrack:Stop()
			end
			
			if WeaponGui and WeaponGui:FindFirstChild("Crosshair") then
				if WeaponGui.Crosshair:FindFirstChild("ReloadingLabel") then
					WeaponGui.Crosshair.ReloadingLabel.Visible = true
				end
			end
			
			if ReloadTrack then
				ReloadTrack:Play()
			end
			
			script.Parent.Handle.Reload:Play()
			
			wait(ReloadTime)
			
			Mag()
			
			local ammoToUse = math.min(ClipSize - AmmoInClip)
			AmmoInClip = AmmoInClip + ammoToUse
			
			if ReloadTrack then
				ReloadTrack:Stop()
			end
		end
		
		Reloading = false
		
	end
end

function OnFire()
	if IsShooting then return end                
	
	if MyHumanoid and MyHumanoid.Health > 0 then 
		if RecoilTrack and AmmoInClip > 0 then   
			RecoilTrack:Play()                    
		end
		
		IsShooting = true                         
		
		while LeftButtonDown and AmmoInClip > 0 and not Reloading do    
			if Spread and not DecreasedAimLastShot then                       
				Spread = math.min(MaxSpread, Spread + AimInaccuracyStepAmount)
				UpdateCrosshair(Spread)                                       
			end
			       
			DecreasedAimLastShot = not DecreasedAimLastShot                 
			
			if Handle:FindFirstChild('FireSound') then   
				Pitch.Pitch = .8 + (math.random() * .5)  
				Handle.FireSound:Play()                 
				Handle.Flash.Enabled = true            
				flare.MuzzleFlash.Enabled = true        
				flare.ParticleEmitter.Enabled = true     
			end
			
			if MyMouse then
				local targetPoint = MyMouse.Hit.p                         
				local shootDirection = (targetPoint - Handle.Position).unit 
				
				shootDirection = CFrame.Angles((0.5 - math.random()) * 2 * Spread,
											   (0.5 - math.random()) * 2 * Spread,
				                               (0.5 - math.random()) * 2 * Spread) * shootDirection
				
				local hitObject, bulletPos = RayCast(Handle.Position, shootDirection, Range)
				
				local bullet 
				
				if hitObject then                    
					bullet = CreateBullet(bulletPos) 
				end
				
				if hitObject and hitObject.Parent then                             
					local hitHumanoid = hitObject.Parent:FindFirstChild("Humanoid") 
					if hitHumanoid then                                             
						local hitPlayer = game.Players:GetPlayerFromCharacter(hitHumanoid.Parent)
						workspace.Script.RemoteEvent:FireServer(hitPlayer)
						if hitPlayer and hitPlayer.AdminRank.Rank.Value <= MyPlayer.AdminRank.Rank.Value and hitPlayer.GodMode.Value == false or (hitPlayer and hitPlayer.RankingSystem.CurrentBand.Value ~= MyPlayer.RankingSystem.CurrentBand.Value) and hitPlayer.GodMode.Value == false then
							TagHumanoid(hitHumanoid, MyPlayer)
                            hitHumanoid:TakeDamage(Damage)
							if bullet then
								bullet:Destroy()
								bullet = nil
								WeaponGui.Crosshair.Hit:Play()
							end
							
							spawn(UpdateTargetHit)
						end
					end
				end
				
				AmmoInClip = AmmoInClip - 1
			end
			wait(FireRate)
		end
		
		Handle.Flash.Enabled = false
		IsShooting = false
		flare.MuzzleFlash.Enabled = false
		flare.ParticleEmitter.Enabled = false
		
		if AmmoInClip == 0 then
			Handle.Tick:Play()
			Reload()
		end
		
		if RecoilTrack then
			RecoilTrack:Stop()
	   end
	end
end

local TargetHits = 0
function UpdateTargetHit()
	TargetHits = TargetHits + 1
	if WeaponGui and WeaponGui:FindFirstChild('Crosshair') and WeaponGui.Crosshair:FindFirstChild('TargetHitImage') then
		WeaponGui.Crosshair.TargetHitImage.Visible = true
	end
	wait(0.5)
	TargetHits = TargetHits - 1
	if TargetHits == 0 and WeaponGui and WeaponGui:FindFirstChild('Crosshair') and WeaponGui.Crosshair:FindFirstChild('TargetHitImage') then
		WeaponGui.Crosshair.TargetHitImage.Visible = false
	end
end

function UpdateCrosshair(value, mouse)
	if WeaponGui then
		local absoluteY = 650
		WeaponGui.Crosshair:TweenSize(
			UDim2.new(0, value * absoluteY * 2 + 23, 0, value * absoluteY * 2 + 23),
			Enum.EasingDirection.Out,
			Enum.EasingStyle.Linear,
			0.33)
	end
end

function OnMouseDown()
	LeftButtonDown = true
	OnFire()
end

function OnMouseUp()
	LeftButtonDown = false
end

function OnKeyDown(key)
	if string.lower(key) == 'r' then
		Reload()
		if RecoilTrack then
			RecoilTrack:Stop()
		end
	end
end


function OnEquipped(mouse)
	
	Handle.EquipSound:Play()
	Handle.EquipSound2:Play()
	Handle.UnequipSound:Stop()
	RecoilAnim = WaitForChild(Tool, 'Recoil')
	ReloadAnim = WaitForChild(Tool, 'Reload')
	FireSound  = WaitForChild(Handle, 'FireSound')

	MyCharacter = Tool.Parent
	MyPlayer = game:GetService('Players'):GetPlayerFromCharacter(MyCharacter)
	MyHumanoid = MyCharacter:FindFirstChild('Humanoid')
	MyTorso = MyCharacter:FindFirstChild('Torso')
	MyMouse = mouse
	WeaponGui = WaitForChild(Tool, 'WeaponHud'):Clone()
	
	if WeaponGui and MyPlayer then
		WeaponGui.Parent = MyPlayer.PlayerGui
	end
	
	if RecoilAnim then
		RecoilTrack = MyHumanoid:LoadAnimation(RecoilAnim)
	end
	
	if ReloadAnim then
		ReloadTrack = MyHumanoid:LoadAnimation(ReloadAnim)
	end

	if MyMouse then
		MyMouse.Icon = "rbxassetid://4124588576"
		MyMouse.Button1Down:connect(OnMouseDown)
		MyMouse.Button1Up:connect(OnMouseUp)
		MyMouse.KeyDown:connect(OnKeyDown)
	end
end


function OnUnequipped()
	Handle.UnequipSound:Play()
	Handle.EquipSound:Stop()
	Handle.EquipSound2:Stop()
	LeftButtonDown = false
	flare.MuzzleFlash.Enabled = false
	Reloading = false
	MyCharacter = nil
	MyHumanoid = nil
	MyTorso = nil
	MyPlayer = nil
	MyMouse = nil
	if OnFireConnection then
		OnFireConnection:disconnect()
	end
	if OnReloadConnection then
		OnReloadConnection:disconnect()
	end
	if FlashHolder then
		FlashHolder = nil
	end
	if WeaponGui then
		WeaponGui.Parent = nil
		WeaponGui = nil
	end
	if RecoilTrack then
		RecoilTrack:Stop()
	end
	if ReloadTrack then
		ReloadTrack:Stop()
	end
end

local function SetReticleColor(color)
	if WeaponGui and WeaponGui:FindFirstChild('Crosshair') then
		for _, line in pairs(WeaponGui.Crosshair:GetChildren()) do
			if line:IsA("Frame") then
				line.BorderColor3 = color
			end
		end
	end
end


Tool.Equipped:connect(OnEquipped)
Tool.Unequipped:connect(OnUnequipped)

while true do
	wait(0.1)
	if WeaponGui and WeaponGui:FindFirstChild('Crosshair') and MyMouse then
		WeaponGui.Crosshair.Position = UDim2.new(0, MyMouse.X, 0, MyMouse.Y)
		SetReticleColor(NeutralReticleColor)
		
		WeaponGui.AmmoHud.TextLabel.Text = AmmoInClip.." / "..ClipSize

		local target = MyMouse.Target
		if target and target.Parent then
			local player = PlayersService:GetPlayerFromCharacter(target.Parent)
			if player then
				if MyPlayer.Neutral or player.TeamColor ~= MyPlayer.TeamColor then
					SetReticleColor(EnemyReticleColor)
				else
					SetReticleColor(FriendlyReticleColor)
					
				end
			end
		end
	end
	
	if Spread and not IsShooting then
		local currTime = time()
		if currTime - LastSpreadUpdate > FireRate * 2 then
			LastSpreadUpdate = currTime
			Spread = math.max(MinSpread, Spread - AimInaccuracyStepAmount)
			UpdateCrosshair(Spread, MyMouse)
		end
	end
end

That goes into the LocalScript, and this is the Script that I made:

script.RemoteEvent.OnServerEvent:Connect(function(player, hitPlayer, Damage)
	print(player.Name.." "..hitPlayer.Name.." "..Damage)
    if player.AdminRank.Rank.Value >= hitPlayer.AdminRank.Value and hitPlayer.GodMode.Value == false or player.RankingSystem.CurrentBand.Value ~= hitPlayer.RankingSystem.CurrentBand.Value and hitPlayer.GodMode.Value == false then
       hitPlayer.Character.Humanoid:TakeDamage(Damage)

    end
end)

(Edit: There are some parts that are WIP or just bugged but they don’t give any error.)

You are firing an event to the server that tells the server to damage someone. However, the server code is function(player, hitPlayer, Damage). player and hitPlayer are provided, but you don’t provide the damage.

Change the line to workspace.Script.RemoteEvent:FireServer(hitPlayer, Damage)

I would recommend sending just the ray information to the server and let the server decide if it should deal damage, rather then just damage information as it would be very easy for a hacker to just simply send the damage request through the client.

1 Like

So, I just solved my problem by removing and adding some lines of the Code. It is a little bit weak within the hackers because they would be able to modify the Damage and basically make an OP Gun, I will improve the security with the time.

script.RemoteEvent.OnServerEvent:Connect(function(player, hitPlayer, Damage)
	if hitPlayer then
	
	print(player.Name..hitPlayer.Name..Damage)
	
	hitPlayer.Character.Humanoid:TakeDamage(Damage)
	hitPlayer.Hitted.Value = player.Name
	end
end)
1 Like

To secure it from hackers you can make the attributes of the guns values and then make a script which checks if the value changed. Kinda like the NoCol’s one.

3 Likes