I've been trying to figure out a way to be able to make the pistol this for FPS Roblox pistol model not to do damage to players, but the script is too long and complicated for me to understand. Please help.
Thank you!
(pistol this for FPS script)
--------------------- TEMPLATE ASSAULT RIFLE WEAPON --------------------------- -- Waits for the child of the specified parent local function WaitForChild(parent, childName) while not parent:FindFirstChild(childName) do parent.ChildAdded:wait() end return parent[childName] end ----- MAGIC NUMBERS ABOUT THE TOOL ----- -- How much damage a bullet does local Damage = 50 -- How many times per second the gun can fire local FireRate = 20 / 30 -- The maximum distance the can can shoot, this value should never go above 1000 local Range = 400 -- In radians the minimum accuracy penalty local MinSpread = 0.01 -- In radian the maximum accuracy penalty local MaxSpread = 0.1 -- Number of bullets in a clip local ClipSize = 12 -- DefaultValue for spare ammo local SpareAmmo = 100 -- The amount the aim will increase or decrease by -- decreases this number reduces the speed that recoil takes effect local AimInaccuracyStepAmount = 0.01 -- Time it takes to reload weapon local ReloadTime = 2 ---------------------------------------- -- Colors 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 -- Player specific convenience variables local MyPlayer = nil local MyCharacter = nil local MyHumanoid = nil local MyTorso = nil local MyMouse = nil local RecoilAnim local RecoilTrack = nil local IconURL = Tool.TextureId -- URL to the weapon icon asset local DebrisService = game:GetService('Debris') local PlayersService = game:GetService('Players') local FireSound local OnFireConnection = nil local OnReloadConnection = nil local DecreasedAimLastShot = false local LastSpreadUpdate = time() -- this is a dummy object that holds the flash made when the gun is fired 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 -- @preconditions: vec should be a unit vector, and 0 < rayLength <= 1000 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 -- there is a chance here for potential infinite recursion return RayCast(hitPos, vec, distance) end end return hitObject, hitPos end function TagHumanoid(humanoid, player) -- Add more tags here to customize what tags are available. 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 CreateFlash() if FlashHolder then local flash = Instance.new('Fire', FlashHolder) flash.Color = Color3.new(1, 140 / 255, 0) flash.SecondaryColor = Color3.new(1, 0, 0) flash.Size = 0.3 DebrisService:AddItem(flash, FireRate / 1.5) else FlashHolder = Instance.new("Part", Tool) FlashHolder.Transparency = 1 FlashHolder.CanCollide= false FlashHolder.Size = Vector3.new(1, 1, 1) FlashHolder.Position = Tool.Handle.Position local Weld = Instance.new("ManualWeld") Weld.C0 = CFrame.new(0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1) Weld.C1 = CFrame.new(0, 2.2, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0) Weld.Part0 = FlashHolder Weld.Part1 = Tool.Handle Weld.Parent = FlashHolder end end local function CreateBullet(bulletPos) local bullet = Instance.new('Part', Workspace) bullet.FormFactor = Enum.FormFactor.Custom bullet.Size = Vector3.new(0.1, 0.1, 0.1) bullet.BrickColor = MyPlayer.TeamColor bullet.Shape = Enum.PartType.Ball bullet.CanCollide = false bullet.CFrame = CFrame.new(bulletPos) bullet.Anchored = true bullet.TopSurface = Enum.SurfaceType.Smooth bullet.BottomSurface = Enum.SurfaceType.Smooth bullet.Name = 'Bullet' DebrisService:AddItem(bullet, 2.5) local fire = Instance.new("Fire", bullet) fire.Color = Color3.new(MyPlayer.TeamColor.r, MyPlayer.TeamColor.g, MyPlayer.TeamColor.b) fire.SecondaryColor = Color3.new(MyPlayer.TeamColor.r, MyPlayer.TeamColor.g, MyPlayer.TeamColor.b) fire.Size = 5 fire.Heat = 0 DebrisService:AddItem(fire, 0.2) return bullet end local function Reload() if not Reloading then Reloading = true -- Don't reload if you are already full or have no extra ammo if AmmoInClip ~= ClipSize and SpareAmmo > 0 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 wait(ReloadTime) -- Only use as much ammo as you have local ammoToUse = math.min(ClipSize - AmmoInClip, SpareAmmo) AmmoInClip = AmmoInClip + ammoToUse SpareAmmo = SpareAmmo - ammoToUse UpdateAmmo(AmmoInClip) 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 Handle.FireSound:Play() end CreateFlash() if MyMouse then local targetPoint = MyMouse.Hit.p local shootDirection = (targetPoint - Handle.Position).unit -- Adjust the shoot direction randomly off by a little bit to account for recoil 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 -- Create a bullet here 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) if MyPlayer.Neutral or (hitPlayer and hitPlayer.TeamColor ~= MyPlayer.TeamColor) then TagHumanoid(hitHumanoid, MyPlayer) hitHumanoid:TakeDamage(Damage) if bullet then bullet:Destroy() bullet = nil --bullet.Transparency = 1 end Spawn(UpdateTargetHit) end end end AmmoInClip = AmmoInClip - 1 UpdateAmmo(AmmoInClip) end wait(FireRate) end IsShooting = false if AmmoInClip == 0 then 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 -- Continued
don't think you can't understand something because it's too long. remember that each section of the code only takes care of one particular task, so you can break it down in chunks. that said, I will try to help you identify the area of your code that you want to change. if you don't care and this is only for fun, skip to the end.
since you have the entire gun here, your code involves the recoil, the crosshair, the reload, etc. however, you don't care about any of that, and what you want is the damage mechanism.
thankfully, the creator of this gun named all of their functions correctly. you will find functions like Reload()
, which are obviously useless to you, so you can skip it. in this way you can break down this large piece of code into something smaller. look for functions you think are important. for example, I read through the function CreateBullet()
, but there was nothing about damage, so I skipped it. eventually you will find the function OnFire()
.
the way players are damaged in games is by changing the health of their Humanoid
, this is an object that has health, speed, and other things you find in a player. most of the time, npcs will also have humanoids, if not some other type of health system.
for this reason, I'll look for the word "Humanoid", and there it is, on line 227. here is your relevant code:
local hitHumanoid = hitObject.Parent:FindFirstChild("Humanoid") if hitHumanoid then local hitPlayer = game.Players:GetPlayerFromCharacter(hitHumanoid.Parent) if MyPlayer.Neutral or (hitPlayer and hitPlayer.TeamColor ~= MyPlayer.TeamColor) then TagHumanoid(hitHumanoid, MyPlayer) hitHumanoid:TakeDamage(Damage) if bullet then bullet:Destroy() bullet = nil --bullet.Transparency = 1 end Spawn(UpdateTargetHit) end end
it looks like this gun was only designed for killing players on the opposite team, not npcs. therefore, you can just delete that part. instead, just check if it was not a player, since npcs are the only humanoids that are not players. you can do this with the function GetPlayerFromCharacter()
. if you get nothing, that means that the character did not have a player, so it wasn't one.
change lines 227-240 to this
local hitHumanoid = hitObject.Parent:FindFirstChild("Humanoid") if hitHumanoid and not game.Players:GetPlayerFromCharacter(hitHumanoid.Parent) then hitHumanoid:TakeDamage(Damage) if bullet then bullet:Destroy() bullet = nil --bullet.Transparency = 1 end Spawn(UpdateTargetHit) end
-- Continued function UpdateAmmo(value) if WeaponGui and WeaponGui:FindFirstChild('AmmoHud') and WeaponGui.AmmoHud:FindFirstChild('ClipAmmo') then WeaponGui.AmmoHud.ClipAmmo.Text = AmmoInClip if value > 0 and WeaponGui:FindFirstChild('Crosshair') and WeaponGui.Crosshair:FindFirstChild('ReloadingLabel') then WeaponGui.Crosshair.ReloadingLabel.Visible = false end end if WeaponGui and WeaponGui:FindFirstChild('AmmoHud') and WeaponGui.AmmoHud:FindFirstChild('TotalAmmo') then WeaponGui.AmmoHud.TotalAmmo.Text = SpareAmmo end end function OnMouseDown() LeftButtonDown = true OnFire() end function OnMouseUp() LeftButtonDown = false end function OnKeyDown(key) if string.lower(key) == 'r' then Reload() end end function OnEquipped(mouse) RecoilAnim = WaitForChild(Tool, 'Recoil') 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 UpdateAmmo(AmmoInClip) end if RecoilAnim then RecoilTrack = MyHumanoid:LoadAnimation(RecoilAnim) end if MyMouse then -- Disable mouse icon MyMouse.Icon = "rbxasset://textures\\GunCursor.png" MyMouse.Button1Down:connect(OnMouseDown) MyMouse.Button1Up:connect(OnMouseUp) MyMouse.KeyDown:connect(OnKeyDown) end end -- Unequip logic here function OnUnequipped() LeftButtonDown = 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 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.033) if WeaponGui and WeaponGui:FindFirstChild('Crosshair') and MyMouse then WeaponGui.Crosshair.Position = UDim2.new(0, MyMouse.X, 0, MyMouse.Y) SetReticleColor(NeutralReticleColor) 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