local p={}p.__index=p function p.new(X)local S=setmetatable({},p)S.CONTROL_ACTION_PRIORITY=X S.enabled=false S.vehicleSeat=nil S.throttle=0 S.steer=0 S.acceleration=0 S.decceleration=0 S.turningRight=0 S.turningLeft=0 S.vehicleMoveVector=ZERO_VECTOR3 S.autoPilot={}S.autoPilot.MaxSpeed=0 S.autoPilot.MaxSteeringAngle=0 return S end function p.BindContextActions(p)if useTriggersForThrottle then ContextActionService:BindActionAtPriority("\116\104\114\111\116\116\108\101\065\099\099\101\108",function(X,S,n)p:OnThrottleAccel(X,S,n)return Enum.ContextActionResult.Pass end,false,p.CONTROL_ACTION_PRIORITY,Enum.KeyCode.ButtonR2)ContextActionService:BindActionAtPriority("\116\104\114\111\116\116\108\101\068\101\099\099\101\108",function(X,S,n)p:OnThrottleDeccel(X,S,n)return Enum.ContextActionResult.Pass end,false,p.CONTROL_ACTION_PRIORITY,Enum.KeyCode.ButtonL2)end ContextActionService:BindActionAtPriority("\097\114\114\111\119\083\116\101\101\114\082\105\103\104\116",function(X,S,n)p:OnSteerRight(X,S,n)return Enum.ContextActionResult.Pass end,false,p.CONTROL_ACTION_PRIORITY,Enum.KeyCode.Right)ContextActionService:BindActionAtPriority("\097\114\114\111\119\083\116\101\101\114\076\101\102\116",function(X,S,n)p:OnSteerLeft(X,S,n)return Enum.ContextActionResult.Pass end,false,p.CONTROL_ACTION_PRIORITY,Enum.KeyCode.Left)end function p.Enable(S,p,X)if p==S.enabled and X==S.vehicleSeat then return end S.enabled=p S.vehicleMoveVector=ZERO_VECTOR3 if p then if X then S.vehicleSeat=X if FFlagUserClickToMoveFollowPathRefactor then S:SetupAutoPilot()end S:BindContextActions()end else if useTriggersForThrottle then ContextActionService:UnbindAction("\116\104\114\111\116\116\108\101\065\099\099\101\108")ContextActionService:UnbindAction("\116\104\114\111\116\116\108\101\068\101\099\099\101\108")end ContextActionService:UnbindAction("\097\114\114\111\119\083\116\101\101\114\082\105\103\104\116")ContextActionService:UnbindAction("\097\114\114\111\119\083\116\101\101\114\076\101\102\116")S.vehicleSeat=nil end end function p.OnThrottleAccel(n,p,X,S)if FFlagBetterHandlingVehicleInputStates then if X==Enum.UserInputState.End or X==Enum.UserInputState.Cancel then n.acceleration=0 else n.acceleration=-1 end else n.acceleration=X~=Enum.UserInputState.End and-1 or 0 end n.throttle=n.acceleration+n.decceleration end function p.OnThrottleDeccel(n,p,X,S)if FFlagBetterHandlingVehicleInputStates then if X==Enum.UserInputState.End or X==Enum.UserInputState.Cancel then n.decceleration=0 else n.decceleration=1 end else n.decceleration=X~=Enum.UserInputState.End and 1 or 0 end n.throttle=n.acceleration+n.decceleration end function p.OnSteerRight(n,p,X,S)if FFlagBetterHandlingVehicleInputStates then if X==Enum.UserInputState.End or X==Enum.UserInputState.Cancel then n.turningRight=0 else n.turningRight=1 end else n.turningRight=X~=Enum.UserInputState.End and 1 or 0 end n.steer=n.turningRight+n.turningLeft end function p.OnSteerLeft(n,p,X,S)if FFlagBetterHandlingVehicleInputStates then if X==Enum.UserInputState.End or X==Enum.UserInputState.Cancel then n.turningLeft=0 else n.turningLeft=-1 end else n.turningLeft=X~=Enum.UserInputState.End and-1 or 0 end n.steer=n.turningRight+n.turningLeft end

local VehicleController = {}
VehicleController.__index = VehicleController

function VehicleController.new(CONTROL_ACTION_PRIORITY)
	local self = setmetatable({}, VehicleController)

	self.CONTROL_ACTION_PRIORITY = CONTROL_ACTION_PRIORITY

	self.enabled = false
	self.vehicleSeat = nil
	self.throttle = 0
	self.steer = 0

	self.acceleration = 0
	self.decceleration = 0
	self.turningRight = 0
	self.turningLeft = 0

	self.vehicleMoveVector = ZERO_VECTOR3

	self.autoPilot = {}
	self.autoPilot.MaxSpeed = 0
	self.autoPilot.MaxSteeringAngle = 0

	return self
end

function VehicleController:BindContextActions()
	if useTriggersForThrottle then
		ContextActionService:BindActionAtPriority("throttleAccel", (function(actionName, inputState, inputObject)
			self:OnThrottleAccel(actionName, inputState, inputObject)
			return Enum.ContextActionResult.Pass
		end), false, self.CONTROL_ACTION_PRIORITY, Enum.KeyCode.ButtonR2)
		ContextActionService:BindActionAtPriority("throttleDeccel", (function(actionName, inputState, inputObject)
			self:OnThrottleDeccel(actionName, inputState, inputObject)
			return Enum.ContextActionResult.Pass
		end), false, self.CONTROL_ACTION_PRIORITY, Enum.KeyCode.ButtonL2)
	end
	ContextActionService:BindActionAtPriority("arrowSteerRight", (function(actionName, inputState, inputObject)
		self:OnSteerRight(actionName, inputState, inputObject)
		return Enum.ContextActionResult.Pass
	end), false, self.CONTROL_ACTION_PRIORITY, Enum.KeyCode.Right)
	ContextActionService:BindActionAtPriority("arrowSteerLeft", (function(actionName, inputState, inputObject)
		self:OnSteerLeft(actionName, inputState, inputObject)
		return Enum.ContextActionResult.Pass
	end), false, self.CONTROL_ACTION_PRIORITY, Enum.KeyCode.Left)
end

function VehicleController:Enable(enable, vehicleSeat)
	if enable == self.enabled and vehicleSeat == self.vehicleSeat then
		return
	end

	self.enabled = enable
	self.vehicleMoveVector = ZERO_VECTOR3

	if enable then
		if vehicleSeat then
			self.vehicleSeat = vehicleSeat

			if FFlagUserClickToMoveFollowPathRefactor then
				self:SetupAutoPilot()
			end

			self:BindContextActions()
		end
	else
		if useTriggersForThrottle then
			ContextActionService:UnbindAction("throttleAccel")
			ContextActionService:UnbindAction("throttleDeccel")
		end
		ContextActionService:UnbindAction("arrowSteerRight")
		ContextActionService:UnbindAction("arrowSteerLeft")
		self.vehicleSeat = nil
	end
end

function VehicleController:OnThrottleAccel(actionName, inputState, inputObject)
	if FFlagBetterHandlingVehicleInputStates then
		if inputState == Enum.UserInputState.End or inputState == Enum.UserInputState.Cancel then
			self.acceleration = 0
		else
			self.acceleration = -1
		end
	else
		self.acceleration = (inputState ~= Enum.UserInputState.End) and -1 or 0
	end
	self.throttle = self.acceleration + self.decceleration
end

function VehicleController:OnThrottleDeccel(actionName, inputState, inputObject)
	if FFlagBetterHandlingVehicleInputStates then
		if inputState == Enum.UserInputState.End or inputState == Enum.UserInputState.Cancel then
			self.decceleration = 0
		else
			self.decceleration = 1
		end
	else
		self.decceleration = (inputState ~= Enum.UserInputState.End) and 1 or 0
	end
	self.throttle = self.acceleration + self.decceleration
end

function VehicleController:OnSteerRight(actionName, inputState, inputObject)
	if FFlagBetterHandlingVehicleInputStates then
		if inputState == Enum.UserInputState.End or inputState == Enum.UserInputState.Cancel then
			self.turningRight = 0
		else
			self.turningRight = 1
		end
	else
		self.turningRight = (inputState ~= Enum.UserInputState.End) and 1 or 0
	end
	self.steer = self.turningRight + self.turningLeft
end

function VehicleController:OnSteerLeft(actionName, inputState, inputObject)
	if FFlagBetterHandlingVehicleInputStates then
		if inputState == Enum.UserInputState.End or inputState == Enum.UserInputState.Cancel then
			self.turningLeft = 0
		else
			self.turningLeft = -1
		end
	else
		self.turningLeft = (inputState ~= Enum.UserInputState.End) and -1 or 0
	end
	self.steer = self.turningRight + self.turningLeft
end
