Pinkstack/roblox-luau-corpus-text huggingface dataset:
--PlayAnim


while true do
	wait(0.3)
	
	local function TweenTransparency ()
		local TweenTransInfo = TweenInfo.new(0.4,Enum.EasingStyle.Quad,Enum.EasingDirection.In,0,false)
		local Tween = TweenService:Create(Money, TweenTransInfo, {ImageTransparency = 1})
		Tween:Play()
	end
	
	local function MoneyDown ()
		TweenTransparency()
		Money:TweenPosition(
			UDim2.new(MoneyPX, 0, MoneyPY - 0.112 , 0),
			Enum.EasingDirection.In,
			Enum.EasingStyle.Quad,
			0.35,
			false
		)
	end
	
	local function MoneyUp ()
		Money.ImageTransparency = 0
		Money:TweenPosition(
			UDim2.new(MoneyPX, 0,MoneyPY - 0.400 , 0),
			Enum.EasingDirection.Out,
			Enum.EasingStyle.Quad,
			0.40,
			false,
			MoneyDown
		)
	end
	
	local function MoveDown ()
		--call money tween
		MoneyUp()
		--Move to origin
		MoneyBag:TweenPosition(
			UDim2.new(MoneyPX, 0,MoneyPY, 0),
			Enum.EasingDirection.Out,
			Enum.EasingStyle.Back,
			0.8,
			false
		)
		wait(0.8)
	end
	
	--moveUp
	MoneyBag:TweenPosition(
		UDim2.new(MoneyPX, 0,MoneyPY - 0.122 , 0),
		Enum.EasingDirection.In,
		Enum.EasingStyle.Back,
		0.8,
		false,
		MoveDown
	)

end
-- ANimation


local Sound = script:WaitForChild("Haoshoku Sound")

UIS.InputBegan:Connect(function(Input)
	if Input.KeyCode == Enum.KeyCode.C and Debounce == 1 and Tool.Equip.Value == true and Tool.Active.Value == "None" and script.Parent.DargonOn.Value == true then
		Debounce = 2
		Track1 = plr.Character.Dragon.Dragonoid:LoadAnimation(script.AnimationCharge)
		Track1:Play()
		for i = 1,math.huge do
			if Debounce == 2 then
				
				plr.Character.HumanoidRootPart.CFrame = CFrame.new(plr.Character.HumanoidRootPart.Position, Mouse.Hit.p)
				plr.Character.HumanoidRootPart.Anchored = true
			else
				
				break
				end
	     wait()
	  end
	end
end)

UIS.InputEnded:Connect(function(Input)
	if Input.KeyCode == Enum.KeyCode.C and Debounce == 2 and Tool.Equip.Value == true and Tool.Active.Value == "None" and script.Parent.DargonOn.Value == true then
		Debounce = 3
		local Track2 = plr.Character.Dragon.Dragonoid:LoadAnimation(script.AnimationRelease)
		Track2:Play()
		Track1:Stop()
		Sound:Play()
		local mousepos = Mouse.Hit
		script.RemoteEvent:FireServer(mousepos,Mouse.Hit.p)
		wait(1)
		Track2:Stop()
		plr.Character.HumanoidRootPart.Anchored = false
		wait(.5)
		Tool.Active.Value = "None"
		wait(3)
		Debounce = 1
	end
end)
--------RIGHT DOOR --------



game.Workspace.doorright.l12.BrickColor = BrickColor.new(106)
game.Workspace.doorright.l22.BrickColor = BrickColor.new(106)
game.Workspace.doorright.l32.BrickColor = BrickColor.new(106)
game.Workspace.doorright.l42.BrickColor = BrickColor.new(106)
game.Workspace.doorright.l52.BrickColor = BrickColor.new(106)
game.Workspace.doorright.l62.BrickColor = BrickColor.new(106)
game.Workspace.doorright.l72.BrickColor = BrickColor.new(1003)
--[[Tires]]

--
	-- Tire Curve Profiler: https://www.desmos.com/calculator/og4x1gyzng
	Tune.TireCylinders	= 4			-- How many cylinders are used for the tires. More means a smoother curve but way more parts meaning lag. (Default = 4)
	Tune.TiresVisible	= false		-- Makes the tires visible (Debug)
-- @Description Add and return a HandleAdornment class object with basic parameters to the terrain.
-- @Arg1 ObjectClass


function Debug.AddObject(ObjectType)
	local Obj = Instance.new(ObjectType)
	Obj.AlwaysOnTop = true
	Obj.Color3 = Color3.new(1,1,1)
	Obj.Transparency = .5
	Obj.AdornCullingMode = Enum.AdornCullingMode.Never
	Obj.ZIndex = 1
	
	Obj.Adornee = game.Workspace.Terrain
	Obj.Parent = game.Workspace.Terrain
	return Obj
end
--[=[
	@interface KnitOptions
	.ServicePromises boolean?
	.Middleware Middleware?
	.PerServiceMiddleware PerServiceMiddleware?
	@within KnitClient

	- `ServicePromises` defaults to `true` and indicates if service methods use promises.
	- Each service will go through the defined middleware, unless the service
	has middleware defined in `PerServiceMiddleware`.
]=]


type KnitOptions = {
	ServicePromises: boolean,
	Middleware: Middleware?,
	PerServiceMiddleware: PerServiceMiddleware?
}

local defaultOptions: KnitOptions = {
	ServicePromises = true;
	Middleware = nil;
	PerServiceMiddleware = {};
}

local selectedOptions = nil
--SeregaTopYTReal2
--Put the "died" sound to npc's head



local NPC = script.Parent
local Head = NPC.Head
local Humanoid
for i,v in pairs(NPC:GetChildren()) do 
	if v:IsA('Humanoid') then 
		Humanoid = v 
	end 
end

if Humanoid then
	Humanoid.Died:Connect(function()
		wait(0.0001)
		Head:FindFirstChild("died"):Play()
	end)
else
	warn('Cannot find Humanoid in DeathSound Script!')
end
--// Handling Settings		


	Firerate = 60 / 650; -- 60 = 1 Minute, 700 = Rounds per that 60 seconds. DO NOT TOUCH THE 60!
	
	FireMode = 2; -- 1 = Semi, 2 = Auto, 3 = Burst, 4 = Bolt Action, 5 = Shot, 6 = Explosive
--[[ NON-STATIC METHODS ]]

--
function Path:Destroy()
	for _, event in ipairs(self._events) do
		event:Destroy()
	end
	self._events = nil
	self._visualWaypoints = destroyVisualWaypoints(self._visualWaypoints)
	self._agent = nil
	self._humanoid = nil
	self._path:Destroy()
	self._path =nil
	self._status = nil
	self._t = nil
	self._position = nil
	self._target = nil
end

function Path:Stop()
	if not self._humanoid then
		output(error, "Attempt to call Path:Stop() on a non-humanoid.")
		return
	end
	disconnectMoveConnection(self)
	self._status = Path.StatusType.Idle
	self._visualWaypoints = destroyVisualWaypoints(self._visualWaypoints)
	self._events.Stopped:Fire(self._model)
end

function Path:Run(target)
	
	--Non-humanoid handle case
	if not target and not self._humanoid and self._target then
		moveToFinished(self, true)
		return
	end
	
	--Parameter check
	if not (target and (typeof(target) == "Vector3" or target:IsA("BasePart"))) then
		output(error, "Pathfinding target must be a valid Vector3 or BasePart.")
	end
	
	--Refer to Settings.TIME_VARIANCE
	if os.clock() - self._t <= Settings.TIME_VARIANCE and self._humanoid then
		task.wait(os.clock() - self._t)
		declareError(self, self.ErrorType.LimitReached)
		return false
	elseif self._humanoid then
		self._t = os.clock()
	end
	
	--Compute path
	local pathComputed, msg = pcall(function()
		self._path:ComputeAsync(self._agent.PrimaryPart.Position, (typeof(target) == "Vector3" and target) or target.Position)
	end)
	
	--Make sure path computation is successful
	if not pathComputed 
		or self._path.Status == Enum.PathStatus.NoPath 
		or #self._path:GetWaypoints() < 2 
		or (self._humanoid and self._humanoid:GetState() == Enum.HumanoidStateType.Freefall) then
		self._visualWaypoints = destroyVisualWaypoints(self._visualWaypoints)
		task.wait()
		declareError(self, self.ErrorType.ComputationError)
		return false
	end
	
	--Set status to active; pathfinding starts
	self._status = (self._humanoid and Path.StatusType.Active) or Path.StatusType.Idle
	self._target = target
	
	--Set network owner to server to prevent "hops"
	pcall(function() self._agent.PrimaryPart:SetNetworkOwner(nil) end)
	
	--Initialize waypoints
	self._waypoints = self._path:GetWaypoints()
	self._currentWaypoint = 2
	
	--Refer to Settings.COMPARISON_CHECKS
	if self._humanoid then comparePosition(self) end
	
	--Visualize waypoints
	destroyVisualWaypoints(self._visualWaypoints)
	self._visualWaypoints = (self.Visualize and createVisualWaypoints(self._waypoints))
	
	--Create a new move connection if it doesn't exist already
	self._moveConnection = self._humanoid and (self._moveConnection or self._humanoid.MoveToFinished:Connect(function(...) moveToFinished(self, ...) end))
	
	--Begin pathfinding
	if self._humanoid then
		self._humanoid:MoveTo(self._waypoints[self._currentWaypoint].Position)
	elseif #self._waypoints == 2 then
		self._target = nil
		self._visualWaypoints = destroyVisualWaypoints(self._visualWaypoints)
		self._events.Reached:Fire(self._agent, self._waypoints[2])
	else
		self._currentWaypoint = getNonHumanoidWaypoint(self)
		moveToFinished(self, true)
	end
	return true
end

return Path
--[[Transmission]]


	Tune.TransModes		= {"Semi","Auto"}												--[[
	[Modes]
		"Auto"		: Automatic shifting
		"Semi"		: Clutchless manual shifting, dual clutch transmission
		"Manual"	: Manual shifting with clutch
		
		>Include within brackets
			eg: {"Semi"} or {"Auto", "Manual"}								
		>First mode is default mode													]]
	
	--Automatic Settings
	Tune.AutoShiftMode	= "Speed"												--[[
	[Modes]
		"Speed"		: Shifts based on wheel speed
		"RPM"		: Shifts based on RPM											]]	
	Tune.AutoUpThresh	= -200		--Automatic upshift point 	(relative to peak RPM, positive = Over-rev)
	Tune.AutoDownThresh = 1400		--Automatic downshift point (relative to peak RPM, positive = Under-rev)
	
	--Gear Ratios
	
	Tune.FinalDrive		= 6.5
	Tune.Ratios			= {
		--[[Reverse]]	5			,
		--[[Neutral]]	0			,
		--[[ 1 ]]		3.9			,
		--[[ 2 ]]		2.52		,
		--[[ 3 ]]		1.85		,
		--[[ 4 ]]		1.38		,
		--[[ 5 ]]		1.05		,
		--[[ 6 ]]		.87			,
		--[[ 7 ]]		.69			,
	}
	Tune.FDMult			= 1			-- Ratio multiplier (keep this at 1 if car is not struggling with torque)
--[[
		___      _______                _     
	   / _ |____/ ___/ /  ___ ____ ___ (_)__ 
	  / __ /___/ /__/ _ \/ _ `(_-<(_-</ (_-<
	 /_/ |_|   \___/_//_/\_,_/___/___/_/___/
 						SecondLogic @ Inspare
]]


local FE = workspace.FilteringEnabled
local car = script.Parent.Car.Value
local _Tune = require(car["A-Chassis Tune"])
local on = 0

script:WaitForChild("Idle")



if not FE then
	for i,v in pairs(car.DriveSeat:GetChildren()) do
		for _,a in pairs(script:GetChildren()) do
			if v.Name==a.Name then v:Stop() wait() v:Destroy() end
		end
	end
	for i,v in pairs(script:GetChildren()) do
		v.Parent=car.DriveSeat
	end
	
	
	while wait() do
		local _RPM = script.Parent.Values.RPM.Value
		
		if not script.Parent.IsOn.Value then on=math.max(on-.015,0) else on=1 end
    car.DriveSeat.Idle.Pitch = (car.DriveSeat.Idle.SetPitch.Value - car.DriveSeat.Idle.SetRev.Value*_RPM/_Tune.Redline)*on^2
end
else
	local handler = car.AC6_FE_Sounds
	handler:FireServer("newSound","Idle",car.DriveSeat,script.Idle.SoundId,0,true)
	handler:FireServer("playSound","Idle")

	local pitch=0

	while wait() do
		local _RPM = script.Parent.Values.RPM.Value
		
		if not script.Parent.IsOn.Value then on=math.max(on-.015,0) else on=1 end
		pitch = (script.Idle.SetPitch.Value - script.Idle.SetRev.Value*_RPM/_Tune.Redline)*on^2
		handler:FireServer("updateSound","Idle",script.Idle.SoundId,pitch,script.Idle.Volume)
	end
end
--- Add a line to the command bar


function Window:AddLine(text, color)
	if #text == 0 then
		Window:UpdateWindowHeight()
		return
	end

	local line = Line:Clone()
	line.Text = self.Cmdr.Util.EmulateTabstops(text or "nil", 8)
	line.TextColor3 = color or line.TextColor3
	line.Parent = Gui
end
--edit the function below to return true when you want this response/prompt to be valid
--player is the player speaking to the dialogue, and dialogueFolder is the object containing the dialogue data


return function(player, dialogueFolder)
	local ClassInformationTable = require(game.ReplicatedStorage.Source.Modules.CharacterScripts.Classes.ClassInformation)
	
	local NumOfSupers = #require(game.ReplicatedStorage.Source.Modules.CharacterScripts.Classes.ClassInformation):GetObtainedSupers(player)
	
	return NumOfSupers < 2 and ClassInformationTable:GetClassFolder(player,"Warlock").Obtained.Value ~= true
end
-- Libraries


local Libraries = Tool:WaitForChild 'Libraries'
local Support = require(Libraries:WaitForChild 'SupportLibrary')
local Signal = require(Libraries:WaitForChild 'Signal')
local Maid = require(Libraries:WaitForChild 'Maid')
local Make = require(Libraries:WaitForChild 'Make')
local InstancePool = require(Libraries:WaitForChild 'InstancePool')
--		carSeat.Parent.Body.Dash.Screen.G.Radio.Song.Text = "PRESET 4"
--		carSeat.Parent.Body.Dash.Screen.G.Radio.Title.Text = ""


	elseif carSeat.Stations.mood.Value == 4 then
		carSeat.Parent.Body.MP.Sound:Stop()
		carSeat.Stations.mood.Value = 1
-- Ritter's loose bounding sphere algorithm


function CameraUtils.getLooseBoundingSphere(parts: {BasePart})
	local points = table.create(#parts)
	for idx, part in pairs(parts) do
		points[idx] = part.Position
	end

	-- pick an arbitrary starting point
	local x = points[1]

	-- get y, the point furthest from x
	local y = x
	local yDist = 0

	for _, p in ipairs(points) do
		local pDist = (p - x).Magnitude

		if pDist > yDist then
			y = p
			yDist = pDist
		end
	end

	-- get z, the point furthest from y
	local z = y
	local zDist = 0

	for _, p in ipairs(points) do
		local pDist = (p - y).Magnitude

		if pDist > zDist then
			z = p
			zDist = pDist
		end
	end

	-- use (y, z) as the initial bounding sphere
	local sc = (y + z)*0.5
	local sr = (y - z).Magnitude*0.5

	-- expand sphere to fit any outlying points
	for _, p in ipairs(points) do
		local pDist = (p - sc).Magnitude

		if pDist > sr then
			-- shift to midpoint
			sc = sc + (pDist - sr)*0.5*(p - sc).Unit

			-- expand
			sr = (pDist + sr)*0.5
		end
	end

	return sc, sr
end
--[[ Script Variables ]]

--
while not Players.LocalPlayer do
	task.wait()
end
local LocalPlayer = Players.LocalPlayer
local ThumbpadFrame = nil
local TouchObject = nil
local OnInputEnded = nil	-- is defined in Create()
local OnTouchChangedCn = nil
local OnTouchEndedCn = nil
local currentMoveVector = Vector3.new(0,0,0)
--Functions


game.Players.PlayerAdded:Connect(function(player)
	player.CharacterAdded:Connect(function(char)
		--Varibles
		local head = char.Head
		local newtext = nametag:Clone() --Cloning the text.
		local uppertext = newtext.UpperText
		local lowertext = newtext.LowerText
		local humanoid = char.Humanoid

		humanoid.DisplayDistanceType = "None"

		--Main Text
		newtext.Parent = head
		newtext.Adornee = head
		uppertext.Text = player.Name

		--"If" Statements

	end)
end)
-- << COMMANDS >>


local module = {
	
	-----------------------------------
	{
	Name = "";
	Aliases	= {};
	Prefixes = {settings.Prefix};
	Rank = 1;
	RankLock = false;
	Loopable = false;
	Tags = {};
	Description = "";
	Contributors = {};
	--
	Args = {};
	Function = function(speaker, args)
		
	end;
	UnFunction = function(speaker, args)
		
	end;
	--
	};
	
	
	
	
	-----------------------------------
	{
	Name = "";
	Aliases	= {};
	Prefixes = {settings.Prefix};
	Rank = 1;
	RankLock = false;
	Loopable = false;
	Tags = {};
	Description = "";
	Contributors = {};
	--
	Args = {};
	ClientCommand = true;
	--[[
	FireAllClients = true;
	BlockWhenPunished = true;
	PreFunction = function(speaker, args)
		
	end;
	Function = function(speaker, args)
		wait(10)
	end;
	--]]
	--
	};
	
	
	
	
	-----------------------------------
	
};



return module
--Create Tweens


F.ExtendTweenInfo = function(Time,Style,Direction,Repeat,Reverse,DelayTime,WA1,WA2)
	local Tweeninfo = TweenInfo.new(Time, Style, Direction, Repeat, Reverse, DelayTime)
	TS = TweenService:Create(Weld1, Tweeninfo, {C0 = Orig1 * CFrame.Angles(0,0,WA1)})
	TS1 = TweenService:Create(Weld2, Tweeninfo, {C0 = Orig2 * CFrame.Angles(0,0,WA2)})
end

F.RetractTweenInfo = function(Time,Style,Direction,Repeat,Reverse,DelayTime)
	local Tweeninfo1 = TweenInfo.new(Time, Style, Direction, Repeat, Reverse, DelayTime)
	TS2 = TweenService:Create(Weld1, Tweeninfo1, {C0 = Orig1})
	TS3 = TweenService:Create(Weld2, Tweeninfo1, {C0 = Orig2})
end
--[=[
	Retrieves the service, ensuring initialization if we are in
	the initialization phase.

	@param serviceType ServiceType
	@return any
]=]


function ServiceBag:GetService(serviceType)
	if typeof(serviceType) == "Instance" then
		serviceType = require(serviceType)
	end

	assert(type(serviceType) == "table", "Bad serviceType definition")

	local service = self._services[serviceType]
	if service then
		self:_ensureInitialization(serviceType)
		return self._services[serviceType]
	else
		if self._parentProvider then
			return self._parentProvider:GetService(serviceType)
		end

		-- Try to add the service if we're still initializing services
		self:_addServiceType(serviceType)
		self:_ensureInitialization(serviceType)
		return self._services[serviceType]
	end
end
---[[ Message Settings ]]


module.MaximumMessageLength = 350
module.DisallowedWhiteSpace = {"\n", "\r", "\t", "\v", "\f"}
module.ClickOnPlayerNameToWhisper = true
module.ClickOnChannelNameToSetMainChannel = true
module.BubbleChatMessageTypes = {ChatConstants.MessageTypeDefault, ChatConstants.MessageTypeWhisper}
--Precalculated paths


local t,f,n=true,false,{}
local r={
[58]={{60,41,30,56,58},t},
[49]={{60,41,39,35,34,32,31,29,28,44,45,49},t},
[16]={n,f},
[19]={{60,41,30,56,58,20,19},t},
[59]={{60,41,59},t},
[63]={{60,41,30,56,58,23,62,63},t},
[34]={{60,41,39,35,34},t},
[21]={{60,41,30,56,58,20,21},t},
[48]={{60,41,39,35,34,32,31,29,28,44,45,49,48},t},
[27]={{60,41,39,35,34,32,31,29,28,27},t},
[14]={n,f},
[31]={{60,41,39,35,34,32,31},t},
[56]={{60,41,30,56},t},
[29]={{60,41,39,35,34,32,31,29},t},
[13]={n,f},
[47]={{60,41,39,35,34,32,31,29,28,44,45,49,48,47},t},
[12]={n,f},
[45]={{60,41,39,35,34,32,31,29,28,44,45},t},
[57]={{60,41,30,56,57},t},
[36]={{60,41,39,35,37,36},t},
[25]={{60,41,39,35,34,32,31,29,28,27,26,25},t},
[71]={{60,61,71},t},
[20]={{60,41,30,56,58,20},t},
[60]={{60},t},
[8]={n,f},
[4]={n,f},
[75]={{60,61,71,72,76,73,75},t},
[22]={{60,41,30,56,58,20,21,22},t},
[74]={{60,61,71,72,76,73,74},t},
[62]={{60,41,30,56,58,23,62},t},
[1]={n,f},
[6]={n,f},
[11]={n,f},
[15]={n,f},
[37]={{60,41,39,35,37},t},
[2]={n,f},
[35]={{60,41,39,35},t},
[53]={{60,41,39,35,34,32,31,29,28,44,45,49,48,47,52,53},t},
[73]={{60,61,71,72,76,73},t},
[72]={{60,61,71,72},t},
[33]={{60,41,39,35,37,36,33},t},
[69]={{60,69},t},
[65]={{60,41,30,56,58,20,19,66,64,65},t},
[26]={{60,41,39,35,34,32,31,29,28,27,26},t},
[68]={{60,41,30,56,58,20,19,66,64,67,68},t},
[76]={{60,61,71,72,76},t},
[50]={{60,41,39,35,34,32,31,29,28,44,45,49,48,47,50},t},
[66]={{60,41,30,56,58,20,19,66},t},
[10]={n,f},
[24]={{60,41,39,35,34,32,31,29,28,27,26,25,24},t},
[23]={{60,41,30,56,58,23},t},
[44]={{60,41,39,35,34,32,31,29,28,44},t},
[39]={{60,41,39},t},
[32]={{60,41,39,35,34,32},t},
[3]={n,f},
[30]={{60,41,30},t},
[51]={{60,41,39,35,34,32,31,29,28,44,45,49,48,47,50,51},t},
[18]={n,f},
[67]={{60,41,30,56,58,20,19,66,64,67},t},
[61]={{60,61},t},
[55]={{60,41,39,35,34,32,31,29,28,44,45,49,48,47,52,53,54,55},t},
[46]={{60,41,39,35,34,32,31,29,28,44,45,49,48,47,46},t},
[42]={{60,41,39,40,38,42},t},
[40]={{60,41,39,40},t},
[52]={{60,41,39,35,34,32,31,29,28,44,45,49,48,47,52},t},
[54]={{60,41,39,35,34,32,31,29,28,44,45,49,48,47,52,53,54},t},
[43]={n,f},
[7]={n,f},
[9]={n,f},
[41]={{60,41},t},
[17]={n,f},
[38]={{60,41,39,40,38},t},
[28]={{60,41,39,35,34,32,31,29,28},t},
[5]={n,f},
[64]={{60,41,30,56,58,20,19,66,64},t},
}
return r
------------------------------------------------------------------------



local TOGGLE_INPUT_PRIORITY = Enum.ContextActionPriority.High.Value + 100
local INPUT_PRIORITY = Enum.ContextActionPriority.High.Value + 101
local FREECAM_MACRO_KB = {Enum.KeyCode.LeftShift, Enum.KeyCode.Z}

local NAV_GAIN = Vector3.new(1, 1, 1)*64
local PAN_GAIN = Vector2.new(0.75, 1)*8
local FOV_GAIN = 300

local PITCH_LIMIT = rad(90)

local VEL_STIFFNESS = 1.5
local PAN_STIFFNESS = 1.0
local FOV_STIFFNESS = 4.0
--[[
	Creates a throttle function that drops any repeat calls within a cooldown period and instead returns the result of the last call
]]


function FunctionUtils.throttle(fn, secondsCooldown)
	assert(FunctionUtils.isCallable(fn))
	assert(type(secondsCooldown) == "number")
	assert(secondsCooldown > 0)

	local cached = false
	local lastResult = nil

	return function(...)
		if not cached then
			cached = true
			lastResult = fn(...)
			delay(
				secondsCooldown,
				function()
					cached = false
				end
			)
		end
		return lastResult
	end
end

function FunctionUtils.isCallable(thing)
	return type(thing) == "function" or
		(type(thing) == "table" and getmetatable(thing) and getmetatable(thing).__call ~= nil)
end

return FunctionUtils
-- 1 - Look Right or Go left


	if Logic == 1 then

		if Distance >= 1 then
			if ClimbingLadder == false then -- or target.Position.y < torsoPos.y + 4 then 
				TurnRight()
			end -- else go straight or go up
		else
			TurnLeft()
		end

		if FireRayAhead() then  -- Check straight first. (And Diagonaly left)
			TurnLeft()
         if FireRay() then  -- Check left (And Diagonaly left & back)
				TurnLeft()
				if FireRay() then
					TurnLeft()
					if FireRay() then
						targpos = torsoPos + Vector3.new(Xdir,0,Zdir)
						hum.Jump = true
					end -- right
				end -- Back
			end -- Left
		else -- If succesful Ahead then... (We only check RightTurns for a get-out-of-jail-Free card)

			if Xdir == OldX and OldZ == Zdir then -- Gracefully exiting Logic 1
				Logic = 0
			end -- check Goal dir?
		end -- Ahead
	end -- Logic 1
-- ================================================================================
-- PUBLIC FUNCTIONS
-- ================================================================================


function RaceModule:SetRacers(racerList)
	for i = 1, #racerList do
		addRacer(racerList[i])
	end
end -- RaceModule:SetRacers()

function RaceModule:RegisterCheckpoint(checkpoint)
	if not checkpoints[checkpoint] then
		local newCheckpoint = Checkpoint.new(checkpoint, RaceModule)
		numCheckpoints = numCheckpoints + 1
		checkpoints[checkpoint] = newCheckpoint
	end
end -- RaceModule:RegisterCheckpoint()

function RaceModule:PlayerCrossedCheckpoint(player, checkpoint)
	local racer = racers[player]	
	
	if not racer or racer.FinishedRace then return end
	local currentLap = racer.CurrentLap

	CheckpointEvent:FireClient(player, {{"checkpointHit", checkpoint.CollisionBody}})
	
	if not racer:HasStartedLap(currentLap) then
		racer:StartLap(currentLap)
		onLapStartedEvent:Fire(player, currentLap)
	end
	
	if racer:HasStartedLap(currentLap) then
		local alreadyPassed = checkpoint:SetPlayerPassed(player, currentLap)
		if not alreadyPassed then		
			onCheckpointPassedEvent:Fire(checkpoint.CollisionBody)
		end
	end
	
	if hasPlayerFinishedLap(player, currentLap) then
		local lapTime = racer:FinishLap(currentLap)
		onLapFinishedEvent:Fire(player, currentLap, lapTime)
		if currentLap == numLaps then
			if not winner then
				winner = player
			end
			racer.FinishedRace = true
			onRaceFinishedEvent:Fire(winner)
		else
			wait() -- Let the last checkpoint temporarily change to hit color
			
			CheckpointEvent:FireClient(player, {{"newLap"}})
			
			racer.CurrentLap = racer.CurrentLap + 1
		end
	end
end -- RaceModule:PlayerCrossedCheckpoint()

function RaceModule:Start(activePlayers)
	if debugEnabled then print("RACEMODULE: Starting race") end	
	
	winner = nil
	
	assert(numCheckpoints > 0, "No checkpoints registered")
	assert(startCheckpoint, "Start Checkpoint not set")
	assert(finishCheckpoint, "Finish Checkpoint not set")
	
	if debugEnabled then print("RACEMODULE: Checking if players set") end
	if #racers == 0 then
		RaceModule:SetRacers(activePlayers)
	end	
	
	for _, checkpoint in pairs(checkpoints) do
		checkpoint:Reset()
	end

	onRaceStartedEvent:Fire()
	
	local raceOver = false
	local finishedConnection
	finishedConnection = RaceModule.RaceFinished:connect(function()
		raceOver = true
		racers = {}
		finishedConnection:disconnect()
	end)
	spawn(function()
		wait(raceDuration)
		if not raceOver then
			onRaceFinishedEvent:Fire(winner)
		end
	end)
end -- RaceModule:Start()
--[=[
	@within TableUtil
	@function Sample
	@param tbl table
	@param sampleSize number
	@param rngOverride Random?
	@return table

	Returns a random sample of the table.

	```lua
	local t = {1, 2, 3, 4, 5, 6, 7, 8, 9}
	local sample = TableUtil.Sample(t, 3)
	print(sample) --> e.g. {6, 2, 5}
	```

	:::note Arrays only
	This function works on arrays, but not dictionaries.
]=]


local function Sample<T>(tbl: { T }, size: number, rngOverride: Random?): { T }
	assert(type(tbl) == "table", "First argument must be a table")
	assert(type(size) == "number", "Second argument must be a number")
	local shuffled = table.clone(tbl)
	local sample = table.create(size)
	local random = if typeof(rngOverride) == "Random" then rngOverride else rng
	local len = #tbl
	size = math.clamp(size, 1, len)
	for i = 1, size do
		local j = random:NextInteger(i, len)
		shuffled[i], shuffled[j] = shuffled[j], shuffled[i]
	end
	table.move(shuffled, 1, size, 1, sample)
	return sample
end