REMOTES.Reload.OnServerEvent:connect(function(Q,T)local S=Q.Character if S then local w=S.Equipped local t=S.Ammo if w.Value==T then local S=CONFIG:GetConfig(T)local j=t[S.Size]local A=T.Ammo if j.Value>0 then if cancels[T]then cancels[T]=nil end local t=S.Magazine for S,w in pairs(Players:GetPlayers())do if w~=Q then REMOTES.Effect:FireClient(w,"\082\101\108\111\097\100",T)end end local V=t-A.Value local D=tick()local q=0 repeat q=tick()-D RunService.Stepped:wait()until q>=S.ReloadTime or w.Value~=T or cancels[T]if w.Value==T then if q>=S.ReloadTime then if j.Value>=V then A.Value=A.Value+V j.Value=j.Value-V else A.Value=A.Value+j.Value j.Value=0 end end end if cancels[T]then cancels[T]=nil end end end end end)REMOTES.Hit.OnServerEvent:connect(function(Q,T,S)spawn(function()local w=shots[Q]if w then local t=Q.Character local j=t.Equipped if j.Value==w.Item then local t=T.Parent:FindFirstChildOfClass("\072\117\109\097\110\111\105\100")if t then if DAMAGE:PlayerCanDamage(Q,t)then local j=w.Position local A=w.Directions[S]local V=w.Config if A then local D=Ray.new(j,A)local q=(T.Position-j).Magnitude local y={}for Q,T in pairs(Players:GetPlayers())do if T.Character then table.insert(y,T.Character)end end if q<=V.Range then local q=D:Distance(T.Position)if q<15 then if t.Health>0 then w.Directions[S]=nil local D=0 for Q,T in pairs(w.Directions)do if T then D=D+1 end end if D==0 then shots[Q]=nil end local q=t:FindFirstChild("\068\111\119\110")local y=false if q then y=q.Value end local Y=DAMAGE:Calculate(w.Item,T,j)DAMAGE:Damage(t,Y,Q)local k=Players:GetPlayerFromCharacter(t.Parent)if k then REMOTES.HitIndicator:FireClient(k,A,Y)end if t.Health<=0 then for Q,T in pairs(t.Parent:GetChildren())do if T:IsA("\066\097\115\101\080\097\114\116")then T.Velocity=A*V.Damage end end local T=math.floor((j-t.Parent.HumanoidRootPart.Position).Magnitude+.5)STAT_SCRIPT.FurthestKill:Fire(Q,T)REMOTES.Killfeed:FireAllClients(Q.Name,t.Parent.Name,w.Item.Name,T)end end end end end end end end end end)end)REMOTES.Shoot.OnServerEvent:connect(function(Q,T,S,w)if shots[Q]then shots[Q]=nil end local t=Q.Character local j=t.HumanoidRootPart local A=t.Humanoid local V=A.Down local D=t.Equipped local q=t.Items if T.Parent==q and not V.Value then if(j.Position-S).Magnitude<15 then if D.Value==T then local t=T.Ammo local j=CONFIG:GetConfig(T)if#w==j.ShotSize then if t.Value>0 then t.Value=t.Value-1 for Q,T in pairs(w)do w[Q]=T.Unit end local A={Item=T,Config=j,Position=S;Directions=w}shots[Q]=A cancels[T]=true for t,j in pairs(Players:GetPlayers())do if j~=Q then REMOTES.Effect:FireClient(j,"\083\104\111\111\116",T,S,w)end end end end end end end end)Players.PlayerRemoving:connect(function(Q)if shots[Q]then shots[Q]=nil end end)
-- events

REMOTES.Reload.OnServerEvent:connect(function(player, item)
	local character = player.Character

	if character then
		local equipped = character.Equipped
		local ammo = character.Ammo
		if equipped.Value == item then
			local config = CONFIG:GetConfig(item)
			local storedAmmo = ammo[config.Size]
			local itemAmmo = item.Ammo

			if storedAmmo.Value > 0 then
				if cancels[item] then
					cancels[item] = nil
				end
				local magazine = config.Magazine

				for _, p in pairs(Players:GetPlayers()) do
					if p ~= player then
						REMOTES.Effect:FireClient(p, "Reload", item)
					end
				end

				local needed = magazine - itemAmmo.Value
				local start = tick()
				local elapsed = 0

				repeat
					elapsed = tick() - start
					RunService.Stepped:wait()
				until elapsed >= config.ReloadTime or equipped.Value ~= item or cancels[item]

				if equipped.Value == item then
					if elapsed >= config.ReloadTime then
						if storedAmmo.Value >= needed then
							itemAmmo.Value = itemAmmo.Value + needed
							storedAmmo.Value = storedAmmo.Value - needed
						else
							itemAmmo.Value = itemAmmo.Value + storedAmmo.Value
							storedAmmo.Value = 0
						end
					end
				end

				if cancels[item] then
					cancels[item] = nil
				end
			end
		end
	end
end)

REMOTES.Hit.OnServerEvent:connect(function(player, hit, index)
	spawn(function() -- spawn to avoid race conditions
		local shot = shots[player]

		if shot then
			local character = player.Character
			local equipped = character.Equipped

			if equipped.Value == shot.Item then
				local humanoid = hit.Parent:FindFirstChildOfClass("Humanoid")
				if humanoid then
					if DAMAGE:PlayerCanDamage(player, humanoid) then
						local position = shot.Position
						local direction = shot.Directions[index]
						local config = shot.Config

						if direction then
							local ray = Ray.new(position, direction)
							local distance = (hit.Position - position).Magnitude
							local ignore = {}

							for _, p in pairs(Players:GetPlayers()) do
								if p.Character then
									table.insert(ignore, p.Character)
								end
							end

							--local h	= Raycast(position, direction.Unit * distance, ignore)

							if distance <= config.Range then --and (not h) then
								local offset = ray:Distance(hit.Position)
								if offset < 15 then
									if humanoid.Health > 0 then
										shot.Directions[index] = nil
										local numDir = 0
										for _, v in pairs(shot.Directions) do
											if v then
												numDir = numDir + 1
											end
										end
										if numDir == 0 then
											shots[player] = nil
										end

										local down = humanoid:FindFirstChild("Down")
										local alreadyDowned = false

										if down then
											alreadyDowned = down.Value
										end

										local damage = DAMAGE:Calculate(shot.Item, hit, position)
										DAMAGE:Damage(humanoid, damage, player)

										local otherPlayer = Players:GetPlayerFromCharacter(humanoid.Parent)
										if otherPlayer then
											REMOTES.HitIndicator:FireClient(otherPlayer, direction, damage)
										end

										if humanoid.Health <= 0 then
											for _, part in pairs(humanoid.Parent:GetChildren()) do
												if part:IsA("BasePart") then
													part.Velocity = direction * config.Damage
												end
											end
											local killDist = math.floor(
												(position - humanoid.Parent.HumanoidRootPart.Position).Magnitude + 0.5
											)
											STAT_SCRIPT.FurthestKill:Fire(player, killDist)
											REMOTES.Killfeed:FireAllClients(
												player.Name,
												humanoid.Parent.Name,
												shot.Item.Name,
												killDist
											)
										end
									end
								end
							end
						end
					end
				end
			end
		end
	end)
end)

REMOTES.Shoot.OnServerEvent:connect(function(player, item, position, directions)
	if shots[player] then
		shots[player] = nil
	end

	local character = player.Character
	local rootPart = character.HumanoidRootPart
	local humanoid = character.Humanoid
	local down = humanoid.Down
	local equipped = character.Equipped
	local items = character.Items

	if item.Parent == items and not down.Value then
		if (rootPart.Position - position).Magnitude < 15 then
			if equipped.Value == item then
				local ammo = item.Ammo
				local config = CONFIG:GetConfig(item)

				if #directions == config.ShotSize then
					if ammo.Value > 0 then
						ammo.Value = ammo.Value - 1
						for i, dir in pairs(directions) do
							directions[i] = dir.Unit
						end

						local shot = {
							Item = item,
							Config = config,
							Position = position,
							Directions = directions,
						}

						shots[player] = shot
						cancels[item] = true

						for _, other in pairs(Players:GetPlayers()) do
							if other ~= player then
								REMOTES.Effect:FireClient(other, "Shoot", item, position, directions)
							end
						end
					end
				end
			end
		end
	end
end)

Players.PlayerRemoving:connect(function(player)
	if shots[player] then
		shots[player] = nil
	end
end)
