--Made by Luckymaxer

Model = script.Parent

Players = game:GetService("Players")
Debris = game:GetService("Debris")
RunService = game:GetService("RunService")

Humanoid = Model:WaitForChild("Humanoid")
Humanoid.Health = Humanoid.MaxHealth
Seat = Model:WaitForChild("Seat")
Torso = Model:WaitForChild("Torso")

InteractiveControl = script:WaitForChild("InteractiveControl")

Animations = {
	Walk = {Animation = Model:WaitForChild("Walk"), FadeTime = nil, Weight = nil, Speed = 1},
	Ride = {Animation = Model:WaitForChild("Ride"), FadeTime = 0.25, Weight = nil, Speed = nil},
}

Walking = false
Rider = nil

Gravity = 196.20

Gyro = (Torso:FindFirstChild("BodyGyro") or Instance.new("BodyGyro"))
Gyro.Name = "BodyGyro"
Gyro.cframe = Torso.CFrame
Gyro.maxTorque = Vector3.new(math.huge, math.huge, math.huge)
Gyro.Parent = Torso

Velocity = (Torso:FindFirstChild("BodyVelocity") or Instance.new("BodyVelocity"))
Velocity.Name = "BodyVelocity"
Velocity.maxForce = Vector3.new(math.huge, 0, math.huge)
Velocity.Parent = Torso

WalkTrack = Humanoid:LoadAnimation(Animations.Walk.Animation)

Remotes = script:WaitForChild("Remotes")
Remotes:ClearAllChildren()

LastJump = 0
Disabled = false

ServerControl = (Remotes:FindFirstChild("ServerControl") or Instance.new("RemoteFunction"))
ServerControl.Name = "ServerControl"
ServerControl.Parent = Remotes

ClientControl = (Remotes:FindFirstChild("ClientControl") or Instance.new("RemoteFunction"))
ClientControl.Name = "ClientControl"
ClientControl.Parent = Remotes

function OnServerInvoke(player, Mode, Value)
	if player ~= Rider or not Mode then
		return
	end
	if Mode == "Jump" then
		local Now = tick()
		if (Now - LastJump) >= 2 then
			LastJump = Now
			Humanoid.Jump = true
		end
	elseif Mode == "Dismount" then
		Dismount()
	end
end

ServerControl.OnServerInvoke = OnServerInvoke

Humanoid.Changed:connect(function(Property)
	if Property == "Sit" and Humanoid.Sit then
		Humanoid.Sit = false
	end
end)

Humanoid.Died:connect(function()
	Disabled = true
	Debris:AddItem(Model, 3)
	Model:BreakJoints()
end)

function InvokeClient(Mode, Value)
	local ClientReturn = nil
	pcall(function()
		ClientReturn = ClientControl:InvokeClient(Rider, Mode, Value)
	end)
	return ClientReturn
end

function Animate(Time)
	if Humanoid.Health == 0 or Disabled then
		return
	end
	--Walking
	if not Walking and Torso.Velocity.magnitude > 1 then
		local Animation = Animations.Walk
		WalkTrack:Play(Animation.FadeTime, Animation.Weight, Animation.Speed)
		Walking = true
	end
	if Walking and Torso.Velocity.magnitude < 1 then
		WalkTrack:Stop()
		Walking = false
	end
	--Motion
	Velocity.velocity = (Torso.CFrame.lookVector * Seat.Throttle * Humanoid.WalkSpeed)
	Gyro.cframe = (Gyro.cframe * CFrame.Angles(0, (math.pi / 1.5 * Time * -Seat.Steer), 0))
end

function Dismount()
	if Rider and Rider.Parent then
		local Character = Rider.Character
		if Character then
			local Humanoid = nil
			for i, v in pairs(Character:GetChildren()) do
				if v:IsA("Humanoid") then
					Humanoid = v
					break
				end
			end
			Humanoid:ChangeState(Enum.HumanoidStateType.Jumping)
			Humanoid.Jump = true
		end
	end
end

function PlayerSeated(Child)
	local function BreakWeld()
		Debris:AddItem(Child, 0.5)
		if Child and Child.Parent then
			Child:Destroy()
		end
	end
	if not Child:IsA("Weld") or not Child.Name == "SeatWeld" then
		return
	end
	if Child.Part0 ~= Seat or not Child.Part1 or not Child.Part1.Parent then
		return
	end
	Child.C1 = (Child.C1 * CFrame.new(0, 0.5, 0.375))
	local character = Child.Part1.Parent
	local humanoid = character:FindFirstChild("Humanoid")
	if humanoid then
		local Animation = Animations.Ride
		RideTrack = humanoid:LoadAnimation(Animation.Animation)
		RideTrack:Play(Animation.FadeTime, Animation.Weight, Animation.Speed)
	end
	local Player = Players:GetPlayerFromCharacter(character)
	if not Player then
		BreakWeld()
		return
	end
	local PlayerGui = Player:FindFirstChild("PlayerGui")
	if not PlayerGui then
		BreakWeld()
		return
	end
	InteractiveControlCopy = InteractiveControl:Clone()
	local ServerCommunication = Instance.new("ObjectValue")
	ServerCommunication.Name = "ServerControl"
	ServerCommunication.Value = ServerControl
	ServerCommunication.Parent = InteractiveControlCopy
	InteractiveControlCopy.Disabled = false
	InteractiveControlCopy.Parent = PlayerGui
	Rider = Player
end

function PlayerDismounted(Child)
	if not Child:IsA("Weld") or not Child.Name == "SeatWeld" then
		return
	end
	if not Child.Part1 or not Child.Part1.Parent then
		return
	end
	local Player = Players:GetPlayerFromCharacter(Child.Part1.Parent)
	if not Player or Player ~= Rider then
		return
	end
	if InteractiveControlCopy and InteractiveControlCopy.Parent then
		InteractiveControlCopy:Destroy()
	end
	if RideTrack then
		RideTrack:Stop()
	end
	Rider = nil
end

RunService.Heartbeat:connect(Animate)
Seat.ChildAdded:connect(PlayerSeated)
Seat.ChildRemoved:connect(PlayerDismounted)