When you're close to each other, if you make a curve (bezier), the curve breaks

  1. What do you want to achieve?
    I don’t want the curve to break anymore

  2. What is the issue?

  3. What solutions have you tried so far?
    I dueled with ChatGPT for about 5 hours to fix this :sob:

It breaks when the curve starts when you’re close, but it works well when you’re doing it from a distance

There might be a translation error using a translator

local function lerp(a, b, c)
	return a + (b - a) * c
end

local function quadBezier(t, p0, p1, p2)
	local l1 = lerp(p0, p1, t)
	local l2 = lerp(p1, p2, t)
	local quad = lerp(l1, l2, t)
	return quad
end

local function limitY(position, minY)
	return Vector3.new(position.X, math.max(position.Y, minY), position.Z)
end

local function calculateCurveDuration(speed)
	local baseDuration = 1
	local speedFactor = 0.1
	return baseDuration / (speedFactor + (speed / 90))
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 nearestPlayer = self:FindNearestPlr(player, player)
		if nearestPlayer then
			if nearestPlayer == player 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

			print("Ball Blocked!")
			print("Current Target Player:", self.TargetPlayer.Name)
			print("Nearest Player:", nearestPlayer.Name)
			print("Curve Strength:", curveStrength)
			print("Curve Points: PointA", PointA, "PointB", PointB, "PointC", PointC)

			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

	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)