function Damage(N,C)local D=S.Multipliers.Head local Z=S.Multipliers.Chest local j=S.Multipliers.Limbs if Humanoid.Health~=0 then if N and N.Parent then local l=false local O=nil if N.Parent.ClassName=="\072\097\116"then if FindFirstClass(N.Parent.Parent,"\072\117\109\097\110\111\105\100")then O=FindFirstClass(N.Parent.Parent,"\072\117\109\097\110\111\105\100")l=true if O.Health>0 then if IsEnemy(O)then local N=Instance.new("\079\098\106\101\099\116\086\097\108\117\101")N.Value=Player N.Name="\099\114\101\097\116\111\114"N.Parent=O O:TakeDamage(S.Damage*RAND(D,D+.1,.01))MarkHit()end end end else if FindFirstClass(N.Parent,"\072\117\109\097\110\111\105\100")then O=FindFirstClass(N.Parent,"\072\117\109\097\110\111\105\100")l=true if O.Health>0 then if IsEnemy(O)then local C=Instance.new("\079\098\106\101\099\116\086\097\108\117\101")C.Value=Player C.Name="\099\114\101\097\116\111\114"C.Parent=O local l=0 if N.Name=="\072\101\097\100"then l=S.Damage*RAND(D,D+.1,.01)elseif N.Name=="\084\111\114\115\111"then l=S.Damage*RAND(Z,Z+.1,.01)else l=S.Damage*RAND(j,j+.1,.01)end O:TakeDamage(l)MarkHit()end end end end if not l then if S.BulletHoles then CreateBulletHole(C,N)end if S.Shockwaves then CreateShockwave(C,S.ShockwaveRadius)end end return O end end end function PenetrateWall(N,C,D,Z,j)local l=(N-Z).magnitude local O,a,t=0,nil,nil for D=.1,S.Penetration,.1 do local Z=Ray.new(N+C*D,-C)local j,l=game.Workspace:FindPartOnRayWithIgnoreList(Z,Ignore)if j then O=D a,t=j,l break end end if a then CreateBulletHole(t,a)if S.InstantHit then local N,Z=nil,nil if D then N,Z=AdvRayCast(t,C,S.BulletRange-l,{D.Parent;unpack(Ignore)})else N,Z=AdvRayCast(t,C,S.BulletRange-l)end Damage(N,Z)return Z else local N=t local C=0 spawn(function()while true do RS:wait()if C>=S.BulletRange-l then j:Destroy()break end local Z=(j.Position-N).magnitude local O=(j.Position-N).unit local a,t=nil,nil if D then a,t=AdvRayCast(N,O,Z,{D.Parent;unpack(Ignore)})else a,t=AdvRayCast(N,O,Z)end if a then Damage(a,t)j:Destroy()return t else N=j.Position C=C+Z end end end)end else if j then j:Destroy()end return N end end function IsEnemy(N)local C=game.Players:GetPlayerFromCharacter(N.Parent)if not C then return S.CanDamageNPCs end return S.AllowFriendlyFire or C.TeamColor~=Player.TeamColor or C.Neutral end
--------------------[ HIT HANDLING FUNCTIONS ]----------------------------------------

function Damage(HitObj, HitPos)
	local HeadVal = S.Multipliers.Head
	local ChestVal = S.Multipliers.Chest
	local LimbsVal = S.Multipliers.Limbs
	if Humanoid.Health ~= 0 then
		if HitObj and HitObj.Parent then
			local HumanoidFound = false
			local HitHumanoid = nil
			if HitObj.Parent.ClassName == "Hat" then
				if FindFirstClass(HitObj.Parent.Parent, "Humanoid") then
					HitHumanoid = FindFirstClass(HitObj.Parent.Parent, "Humanoid")
					HumanoidFound = true
					if HitHumanoid.Health > 0 then
						if IsEnemy(HitHumanoid) then
							local CreatorTag = Instance.new("ObjectValue")
							CreatorTag.Value = Player
							CreatorTag.Name = "creator"
							CreatorTag.Parent = HitHumanoid
							HitHumanoid:TakeDamage(S.Damage * RAND(HeadVal, HeadVal + 0.1, 0.01))
							MarkHit()
						end
					end
				end
			else
				if FindFirstClass(HitObj.Parent, "Humanoid") then
					HitHumanoid = FindFirstClass(HitObj.Parent, "Humanoid")
					HumanoidFound = true
					if HitHumanoid.Health > 0 then
						if IsEnemy(HitHumanoid) then
							local CreatorTag = Instance.new("ObjectValue")
							CreatorTag.Value = Player
							CreatorTag.Name = "creator"
							CreatorTag.Parent = HitHumanoid
							local ChosenDamage = 0
							if HitObj.Name == "Head" then
								ChosenDamage = S.Damage * RAND(HeadVal, HeadVal + 0.1, 0.01)
							elseif HitObj.Name == "Torso" then
								ChosenDamage = S.Damage * RAND(ChestVal, ChestVal + 0.1, 0.01)
							else
								ChosenDamage = S.Damage * RAND(LimbsVal, LimbsVal + 0.1, 0.01)
							end
							HitHumanoid:TakeDamage(ChosenDamage)
							MarkHit()
						end
					end
				end
			end
			if not HumanoidFound then
				if S.BulletHoles then
					CreateBulletHole(HitPos, HitObj)
				end
				if S.Shockwaves then
					CreateShockwave(HitPos, S.ShockwaveRadius)
				end
			end
			return HitHumanoid
		end
	end
end

function PenetrateWall(HitPos, Direction, HitHumanoid, OriginPos, Bullet)
	local HitDist = (HitPos - OriginPos).magnitude
	local Thickness, Wall, WallHitPos = 0, nil, nil
	for i = 0.1, S.Penetration, 0.1 do
		local WallRay = Ray.new(HitPos + (Direction * i), -Direction)
		local TempWall, TempWallHitPos = game.Workspace:FindPartOnRayWithIgnoreList(WallRay, Ignore)
		if TempWall then
			Thickness = i
			Wall, WallHitPos = TempWall, TempWallHitPos
			break
		end
	end
	if Wall then
		CreateBulletHole(WallHitPos, Wall)
		if S.InstantHit then
			local HitObj2, HitPos2 = nil, nil
			if HitHumanoid then
				HitObj2, HitPos2 =
					AdvRayCast(WallHitPos, Direction, S.BulletRange - HitDist, { HitHumanoid.Parent, unpack(Ignore) })
			else
				HitObj2, HitPos2 = AdvRayCast(WallHitPos, Direction, S.BulletRange - HitDist)
			end
			Damage(HitObj2, HitPos2)
			return HitPos2
		else
			local LastPos = WallHitPos
			local TotalDistTraveled = 0
			spawn(function()
				while true do
					RS:wait()
					if TotalDistTraveled >= S.BulletRange - HitDist then
						Bullet:Destroy()
						break
					end
					local DistTraveled = (Bullet.Position - LastPos).magnitude
					local NewDirection = (Bullet.Position - LastPos).unit
					local TempHitObj, TempHitPos = nil, nil
					if HitHumanoid then
						TempHitObj, TempHitPos =
							AdvRayCast(LastPos, NewDirection, DistTraveled, { HitHumanoid.Parent, unpack(Ignore) })
					else
						TempHitObj, TempHitPos = AdvRayCast(LastPos, NewDirection, DistTraveled)
					end
					if TempHitObj then
						Damage(TempHitObj, TempHitPos)
						Bullet:Destroy()
						return TempHitPos
					else
						LastPos = Bullet.Position
						TotalDistTraveled = TotalDistTraveled + DistTraveled
					end
				end
			end)
		end
	else
		if Bullet then
			Bullet:Destroy()
		end
		return HitPos
	end
end

function IsEnemy(Human)
	local Plyr = game.Players:GetPlayerFromCharacter(Human.Parent)
	if not Plyr then
		return S.CanDamageNPCs
	end
	return S.AllowFriendlyFire or (Plyr.TeamColor ~= Player.TeamColor or Plyr.Neutral)
end
