What do you want to achieve?
I don’t want to target the player who blocks the ball again
What is the issue?
The player who blocks the ball is targeted again to the flare who blocks the ball
BallService.TargetPlayer = nil
BallService.PreviousTargetPlayer = nil
function BallService:Reset()
if self.IsReset then return end
if self.RealBall then
self.RealBall:Destroy()
self.RealBall = nil
end
if self.FakeBall then
self.FakeBall:Destroy()
self.FakeBall = nil
end
self.CSpeed = self.DefaultSpeed
self.TargetPlayer = nil
self.BallSpawned = false
self.IsReset = true
self:RemoveAllHighlights()
end
function BallService:FindNearestPlr(plr, excludePlayer)
local Character = plr.Character
if not Character or not Character:FindFirstChild("Head") then return end
local bestMatch
local greatestDot = 0
local shortestDistance = math.huge
for _, v in ipairs(Players:GetPlayers()) do
if v ~= plr and v ~= excludePlayer and v ~= self.TargetPlayer and table.find(RoundService.ActivePlayers, v) and v.Character and v.Character:FindFirstChild("Head") then
local characterToEnemy = (v.Character.Head.Position - Character.Head.Position).Unit
local plrLook = Character.Head.CFrame.LookVector
local dotProduct = characterToEnemy:Dot(plrLook)
if dotProduct > .5 then
if dotProduct > greatestDot then
greatestDot = dotProduct
bestMatch = v
end
end
end
end
if not bestMatch then
for _, player in ipairs(Players:GetPlayers()) do
if player ~= plr and player ~= excludePlayer and player ~= self.TargetPlayer and table.find(RoundService.ActivePlayers, player) and player.Character and player.Character:FindFirstChild("HumanoidRootPart") then
local distance = (player.Character.HumanoidRootPart.Position - plr.Character.HumanoidRootPart.Position).Magnitude
if distance < shortestDistance then
shortestDistance = distance
bestMatch = player
end
end
end
end
if bestMatch == excludePlayer then
bestMatch = nil
end
return bestMatch
end
function BallService:FindRandomPlayer()
local validPlayers = {}
for _, player in ipairs(Players:GetPlayers()) do
if table.find(RoundService.ActivePlayers, player) then
table.insert(validPlayers, player)
end
end
if #validPlayers > 1 then
local RngNumber = math.random(1, #validPlayers)
local newTargetPlayer = validPlayers[RngNumber]
self.PreviousTargetPlayer = self.TargetPlayer
self.TargetPlayer = newTargetPlayer
self:HighlightPlr()
end
end
function BallService:SpawnBall()
if self.BallSpawned then return end
self:Reset()
self:FindRandomPlayer()
if not self.TargetPlayer or not RoundService._gameActive then
self:Reset()
return
end
local randomName = tostring(math.random(1, 999))
self.RealBall = BallTemplate:Clone()
self.RealBall.Name = randomName
self.RealBall.Position = RoundService.SelectedMap.BALLSPAWN.Offset.WorldCFrame.Position
self.RealBall.Parent = workspace.Balls
self.RealBall.Transparency = 1
self.FakeBall = FakeBallTemplate:Clone()
self.FakeBall.Name = randomName
self.FakeBall.Position = RoundService.SelectedMap.BALLSPAWN.Offset.WorldCFrame.Position
self.FakeBall.Parent = workspace.Balls
self.RealBall:SetNetworkOwner(nil)
self.FakeBall:SetNetworkOwner(nil)
self.BallSpawned = true
self.IsReset = false
self.RealBall.Touched:Connect(function(hit)
self:HandleBallTouched(hit)
end)
end
function BallService:HandleBallHit()
local player = self.TargetPlayer
if not player then return end
local isParried = ParryService:GetParryState(player)
if not isParried then
print("Player", player.Name, "was hit and is not parrying.")
player.Character.Humanoid.Health = 0
if not table.find(self.DeadPlayers, player) then
table.insert(self.DeadPlayers, player)
end
self:Reset()
if self.PreviousTargetPlayer then
self.Client.SendElims:Fire(self.PreviousTargetPlayer, player)
self.PreviousTargetPlayer:FindFirstChild("leaderstats"):FindFirstChild("💀 Elims").Value += 1
end
if RoundService._gameActive then
task.wait(0.5)
self:SpawnBall()
end
else
print("Ball hit was prevented due to parry state for player", player.Name)
end
end
function BallService:HandleBallBlock()
local player = self.TargetPlayer
if not player then return end
if ParryService:GetParryState(player) then
self.CSpeed = self.CSpeed + 0.1
self.ParrySuccess:Fire(player)
self:PlayParryEffects(player)
local excludePlayer = player
local nearestPlayer = self:FindNearestPlr(player, excludePlayer)
if nearestPlayer and nearestPlayer ~= excludePlayer then
if nearestPlayer == self.TargetPlayer then
print("Nearest player is the same as the current target player. Skipping redirection.")
return
end
self.PreviousTargetPlayer = self.TargetPlayer
self.TargetPlayer = nearestPlayer
self:HighlightPlr()
local lookVector = player.Character:FindFirstChild("LookVector").Value
local PointA = self.RealBall.Position
local PointC = nearestPlayer.Character.HumanoidRootPart.Position
local curveStrength = math.min(self.MaxCurveStrength, (PointC - PointA).Magnitude / 2)
local PointB = PointA + lookVector * curveStrength
self.IsCurving = true
self.CurveStartTime = tick()
self.CurveDuration = calculateCurveDuration(self.CSpeed)
self.CurveMinY = PointA.Y
self.CurvePointB = PointB
self.CurvePointC = PointC
else
print("No valid target player found for redirection after block")
end
else
print("Ball block was attempted but no parry state was found for player", player.Name)
end
end
function BallService:CheckBallCollision()
if not self.RealBall or not self.TargetPlayer or not self.TargetPlayer.Character then
return
end
local targetPosition = self.TargetPlayer.Character:FindFirstChild("HumanoidRootPart") and self.TargetPlayer.Character.HumanoidRootPart.Position
local currentPosition = self.RealBall.Position
if targetPosition then
local direction = (targetPosition - currentPosition).Unit
local raycastParams = RaycastParams.new()
raycastParams.FilterType = Enum.RaycastFilterType.Include
raycastParams.FilterDescendantsInstances = {self.TargetPlayer.Character}
local raycastResult = workspace:Raycast(currentPosition, direction * 20, raycastParams)
if raycastResult and raycastResult.Instance and raycastResult.Instance.Parent == self.TargetPlayer.Character then
local distance = (currentPosition - targetPosition).Magnitude
if distance < 7 then
local isParried = ParryService:GetParryState(self.TargetPlayer)
if isParried then
self:HandleBallBlock()
elseif distance < .05 and not isParried then
self:HandleBallHit()
end
end
end
end
end
RunService.Stepped:Connect(function(deltaTime)
if RoundService._gameActive then
if self.TargetPlayer and self.TargetPlayer.Character then
local targetPosition = self.TargetPlayer.Character:FindFirstChild("HumanoidRootPart").Position
local currentPosition = self.RealBall and self.RealBall.Position
if currentPosition and targetPosition then
local distanceToTarget = (targetPosition - currentPosition).Magnitude
local direction
if self.IsCurving then
self.CurvePointC = targetPosition
local elapsedTime = tick() - self.CurveStartTime
local t = math.clamp(elapsedTime / self.CurveDuration, 0, 1)
local bezierPosition = quadBezier(t, self.CurvePointB, currentPosition, self.CurvePointC)
local limitedPosition = limitY(bezierPosition, self.CurveMinY)
direction = (limitedPosition - currentPosition).Unit
if t >= 1 or distanceToTarget < 15 then
self.IsCurving = false
direction = (targetPosition - currentPosition).Unit
self.CurvePointB = nil
self.CurvePointC = nil
end
else
direction = (targetPosition - currentPosition).Unit
self.CSpeed = self.CSpeed + self.BallAcceleration
end
self.RealBall.Misc.LinearVelocity.VectorVelocity = direction * self.CSpeed
if distanceToTarget > 0.1 then
self:CheckBallCollision()
end
else
self:Reset()
end
else
self:Reset()
end
else
self:Reset()
end
end)
You will be targeted again even if you still exclude players who have blocked from FindNearestPlayer