Pinkstack/roblox-luau-corpus-text huggingface dataset:
--[[Vehicle Weight]]

	
	--Determine Current Mass
	local mass=0
	
	function getMass(p)
		for i,v in pairs(p:GetChildren())do
			if v:IsA("BasePart") and not v.Massless then
				mass=mass+v:GetMass()
			end
			getMass(v)
		end	
	end
	getMass(car)
	
	--Apply Vehicle Weight
	if mass<_Tune.Weight*weightScaling then
		--Calculate Weight Distribution
		local centerF = Vector3.new()
		local centerR = Vector3.new()
		local countF = 0
		local countR = 0
		
		for i,v in pairs(Drive) do
			if v.Name=="FL" or v.Name=="FR" or v.Name=="F" then
				centerF = centerF+v.CFrame.p
				countF = countF+1
			else
				centerR = centerR+v.CFrame.p
				countR = countR+1
			end
		end
		centerF = centerF/countF
		centerR = centerR/countR
		local center = centerR:Lerp(centerF, _Tune.WeightDist/100)  
		
		--Create Weight Brick
		local weightB = Instance.new("Part",car.Body)
		weightB.Name = "#Weight"
		weightB.Anchored = true
		weightB.CanCollide = false
		weightB.BrickColor = BrickColor.new("Really black")
		weightB.TopSurface = Enum.SurfaceType.Smooth
		weightB.BottomSurface = Enum.SurfaceType.Smooth
		if _Tune.WBVisible then
			weightB.Transparency = .75			
		else
			weightB.Transparency = 1			
		end
		weightB.Size = Vector3.new(_Tune.WeightBSize[1],_Tune.WeightBSize[2],_Tune.WeightBSize[3])
		weightB.CustomPhysicalProperties = PhysicalProperties.new(((_Tune.Weight*weightScaling)-mass)/(weightB.Size.x*weightB.Size.y*weightB.Size.z),0,0,0,0)
		weightB.CFrame=(car.DriveSeat.CFrame-car.DriveSeat.Position+center)*CFrame.new(0,_Tune.CGHeight,0)
	else
		--Existing Weight Is Too Massive
		warn( "\n\t [AC6C V".._BuildVersion.."]: Mass too high for specified weight."
			.."\n\t    Target Mass:\t"..(math.ceil(_Tune.Weight*weightScaling*100)/100)
			.."\n\t    Current Mass:\t"..(math.ceil(mass*100)/100)
			.."\n\t Reduce part size or axle density to achieve desired weight.")
	end
	
	local flipG = Instance.new("BodyGyro",car.DriveSeat)
	flipG.Name = "Flip"
	flipG.D = 0
	flipG.MaxTorque = Vector3.new(0,0,0)
	flipG.P = 0
---[[ Window Settings ]]


module.MinimumWindowSize = UDim2.new(0.35, 0, 0.3, 0)
module.MaximumWindowSize = UDim2.new(1, 0, 1, 0) -- if you change this to be greater than full screen size, weird things start to happen with size/position bounds checking.
module.DefaultWindowPosition = UDim2.new(0, 0, 0, 0)
local extraOffset = (7 * 2) + (5 * 2) -- Extra chatbar vertical offset
module.DefaultWindowSizePhone = UDim2.new(0.5, 0, 0.5, extraOffset)
module.DefaultWindowSizeTablet = UDim2.new(0.4, 0, 0.3, extraOffset)
module.DefaultWindowSizeDesktop = UDim2.new(0.3, 0, 0.25, extraOffset)
-- events



REMOTES.Chat.OnServerEvent:connect(function(player, message, scope)
	local players
	
	if scope == "Global" then
		players	= Players:GetPlayers()
	elseif scope == "Squad" then
		local squad	= GetSquad(player)
		if squad then
			players	= {}
			
			for _, p in pairs(squad.Players:GetChildren()) do
				table.insert(players, Players[p.Name])
			end
		end
	end
	
	if not cooldowns[player] then
		cooldowns[player]	= 0
	end
	
	cooldowns[player]	= cooldowns[player] + 1
	
	if cooldowns[player] <= MAX_PER_SECOND then
		if players then
			if string.gsub(message, "%s", "") ~= "" then
				local result	= TextService:FilterStringAsync(message, player.UserId)
				for _, p in pairs(players) do
					spawn(function()
						pcall(function()
							if player.Parent == Players and p.Parent == Players and Chat:CanUsersChatAsync(player.UserId, p.UserId) then
								local filtered	= result:GetChatForUserAsync(p.UserId)
								REMOTES.Chat:FireClient(p, player.Name, filtered, scope)
							end
						end)
					end)
				end
			end
		end
	else
		REMOTES.Chat:FireClient(player, "SERVER", "Woah there, you're sending messages too fast!", "Server")
	end
end)

Players.PlayerRemoving:connect(function(player)
	if cooldowns[player] then
		cooldowns[player]	= nil
	end
end)
--[[
    Turns brake lights on or off depending on the status
]]


function VehicleSoundComponent:updateSounds()
	local speed = self.controller:getSpeed()

	if speed and speed < 3 then
		TweenService:Create(self.idle, tweenInfo, {Volume = 0.3}):Play()
		TweenService:Create(self.engine, tweenInfo, {Volume = speed / 5}):Play()
	else
		TweenService:Create(self.idle, tweenInfo, {Volume = 0}):Play()
		TweenService:Create(
			self.engine,
			tweenInfo,
			{Volume = 0.8, PlaybackSpeed = 0.5 + (((speed or 0) + math.random(0, 20)) / 100)}
		):Play()
	end
end
--Click to Open/Close Drawer--


local clickDetector = script.Parent.Parent.ClickBox.ClickDetector
local clicker = script.Parent.Parent.ClickBox


game:GetService("SoundService")

local Phone = game.SoundService["P0 Sounds"].PhoneSound


clickDetector.MouseClick:Connect(function()
	print("Phone Clicked")

	print("SoundPlayed")
	
		local copysound = Phone:Clone()
		copysound.Parent = clicker
		copysound.Ended:Connect(function() copysound:Destroy() end)
		copysound:Play()
		print("SoundKilled")
	
end)
--use this to determine if you want this human to be harmed or not, returns boolean



function boom()
	task.wait(2)
	Used = true
	Object.Anchored = true
	Object.CanCollide = false
	Object.Sparks.Enabled = false
	Object.Orientation = Vector3.new(0,0,0)
	Object.Transparency = 1
	Object.Fuse:Stop()
	Object.Explode:Play()
	Object.Explosion:Emit(100)
	Object.Smoke1:Emit(150)
	Object.Smoke2:Emit(50)
	Object.Smoke3:Emit(50)
	Object.Debris:Emit(200)
	Object.Debris2:Emit(900)
	Object.Debris3:Emit(900)
	Explode()
end

boom()
--[[
  Returns a dictionary with the model and difficulty data for each tile type and slope type
]]


local ServerStorage = game:GetService("ServerStorage")

local TileTypes = require(ServerStorage.Source.Constants.TileTypes)
local SlopeTypes = require(ServerStorage.Source.Constants.SlopeTypes)

return function()
	local tileIndex = {}

	local tiles = ServerStorage:FindFirstChild("Tiles")
	for _, tileType in pairs(TileTypes) do
		tileIndex[tileType] = {}

		local tileFolder = tiles:FindFirstChild(tileType)

		for _, slopeType in pairs(SlopeTypes) do
			tileIndex[tileType][slopeType] = {}

			local slopeFolder = tileFolder:FindFirstChild(slopeType)
			if slopeFolder then
				for _, model in pairs(slopeFolder:GetChildren()) do
					local difficultyObject = model:FindFirstChild("Difficulty")

					-- Clamp the difficulty value between 0 and 100 (as it is a percent)
					local difficulty = math.clamp(difficultyObject.Value, 0, 100)

					table.insert(
						tileIndex[tileType][slopeType],
						{
							model = model,
							difficulty = difficulty,
							type = tileType
						}
					)
				end
			end
		end
	end

	return tileIndex
end
-- initialization/finalization stuff



function makeGyro(humanoid)
	Gyro = Instance.new("BodyGyro")
	Gyro.Name = "SkateboardGyro"
	Gyro.maxTorque = Vector3.new(0,0,0) -- start off
	Gyro.P = 50
	Gyro.D = 50
	Gyro.Parent = humanoid.Parent.Torso
end

function onButtonChanged(button)
	if button == Enum.Button.Dismount then
		Board.ControllingHumanoid.Jump = Controller:getButton(Enum.Button.Dismount)
	end
	if button == Enum.Button.Jump then
		if Controller:getButton(Enum.Button.Jump) and jumpok then
			jumpok = false
			KickAnim:Stop()
			LeftAnim:Stop(.5)

			RightAnim:Stop(.5)
			OllieAnim:Play(0,1,4)
			Board.StickyWheels = false
			Board:ApplySpecificImpulse(Vector3.new(0,45,0))
			OllieHack.force = Vector3.new(0,1200,0)
			didAction("jump")
			delay(.1, function() if (OllieHack ~= nil) then OllieHack.force = Vector3.new(0,0,0) end end)
		else
			Board.StickyWheels = true
		end
	end
end

function onEquip(humanoid, controller)
	print("Board equipped")
	print(controller)
	if not Controller then -- debounce
		Controller = controller
		
		makeGyro(humanoid)
		controller.AxisChanged:connect(onAxisChanged)
		Board.MoveStateChanged:connect(onMoveStateChanged)
		CoastingAnim = humanoid:loadAnimation(Board.coastingpose)	
		LeftAnim = humanoid:loadAnimation(Board.leftturn)
		RightAnim = humanoid:loadAnimation(Board.rightturn)
		OllieAnim = humanoid:loadAnimation(Board.ollie)
		--OllieAnim:AdjustSpeed(2)
		KickAnim = humanoid:loadAnimation(Board.boardkick)
		CoastingAnim:Play()

		Controller:bindButton(Enum.Button.Jump, "Ollie")
		Controller:bindButton(Enum.Button.Dismount, "Dismount")
		Controller.ButtonChanged:connect(onButtonChanged)
	end
end

function onUnequip(board)
	print("Board unequipped")
	Controller = nil
	Gyro.Parent = nil
	Gyro= nil
	CoastingAnim:Stop()
	KickAnim:Stop()
	CoastingAnim = nil
	KickAnim = nil
	LeftAnim:Stop()
	LeftAnim = nil
	RightAnim:Stop()
	RightAnim = nil
	OllieAnim:Stop()
	OllieAnim = nil

	if (OllieThrust ~= nil) then
		OllieThrust:Remove()
		OllieThrust = nil
	end
end
--Made by Stickmasterluke




sp=script.Parent

speedboost=2		--200% speed bonus
speedforsmoke=10	--smoke apears when character running >= 10 studs/second.

function waitfor(a, b, c)
	local c = c or 5 * 60
	local d=tick()+c
	while a:FindFirstChild(b)==nil and tick()<=d do
		wait()
	end
	return a:FindFirstChild(b)
end

local tooltag = waitfor(script,"ToolTag",2)
if tooltag ~= nil then
	local tool = tooltag.Value
	local h = sp:FindFirstChild("Humanoid")
	if h ~= nil then
		h.WalkSpeed = 16+16*speedboost
		local t = sp:FindFirstChild("Torso")
		if t ~= nil then
			smokepart = Instance.new("Part")
			smokepart.FormFactor = "Custom"
			smokepart.Size =Vector3.new(0, 0, 0)
			smokepart.TopSurface = "Smooth"
			smokepart.BottomSurface = "Smooth"
			smokepart.CanCollide = false
			smokepart.Transparency = 1
			local weld = Instance.new("Weld")
			weld.Name = "SmokePartWeld"
			weld.Part0 = t
			weld.Part1 = smokepart
			weld.C0 = CFrame.new(0, -3.5, 0) * CFrame.Angles(math.pi / 4, 0, 0)
			weld.Parent = smokepart
			smokepart.Parent = sp
			smoke = Instance.new("Smoke")
			smoke.Enabled = t.Velocity.magnitude > speedforsmoke
			smoke.RiseVelocity = 2
			smoke.Opacity = 0.25
			smoke.Size = 0.5
			smoke.Parent = smokepart
			h.Running:connect(function(speed)
				if smoke and smoke ~= nil then
					smoke.Enabled = speed > speedforsmoke
				end
			end)
		end
	end
	while tool ~= nil and tool.Parent == sp and h ~= nil do
		sp.ChildRemoved:wait()
	end
	local h = sp:FindFirstChild("Humanoid")
	if h ~= nil then
		h.WalkSpeed = 16
	end
end

if smokepart ~= nil then
	smokepart:remove()
end
script:remove()
--[[Weight and CG]]


	Tune.Weight			= 1873		-- Total weight (in pounds)
	Tune.WeightBSize	= {			-- Size of weight brick (dimmensions in studs ; larger = more stable)
	 --[[Width]]		6		,
	 --[[Height]]		3.5		,
	 --[[Length]]		14		}
	Tune.WeightDist		= 50		-- Weight distribution (0 - on rear wheels, 100 - on front wheels, can be <0 or >100)
	Tune.CGHeight		= .8		-- Center of gravity height (studs relative to median of all wheels)
	Tune.WBVisible		= false		-- Makes the weight brick visible
	
	--Unsprung Weight
	Tune.FWheelDensity	= .1		-- Front Wheel Density
	Tune.RWheelDensity	= .1		-- Rear Wheel Density
	Tune.FWLgcyDensity	= 1			-- Front Wheel Density [PGS OFF]
	Tune.RWLgcyDensity	= 1			-- Rear Wheel Density [PGS OFF]
	
	Tune.AxleSize		= 2			-- Size of structural members (larger = more stable/carry more weight)
	Tune.AxleDensity	= .1		-- Density of structural members
--//Main script


script.Parent:WaitForChild("ClickDetector").MouseClick:connect(function(Player)
	if not InUse and game:GetService("Players"):FindFirstChild(Player.Name) and Player.Character.Humanoid.RigType == Enum.HumanoidRigType.R15 and Player.Character.Humanoid.Health > 0 and not Player.Character:FindFirstChild("GotCostume") then
		InUse = true
		Player:ClearCharacterAppearance()
		local CostumeLabel = Instance.new("BoolValue", Player.Character)
		CostumeLabel.Name = "GotCostume"
		LockPlayer(Player, true)
		local OldCFrame = Player.Character:FindFirstChild("HumanoidRootPart").CFrame
		Player.Character:SetPrimaryPartCFrame(script.Parent.Parent:FindFirstChild("Position").CFrame)
		for _,BodyPart in pairs(Player.Character:GetChildren()) do
			if BodyPart:IsA("BasePart") and CheckName(BodyPart) then
				if BodyPart.Name == "Head" then
					BodyPart.Transparency = 0.99
				else
					BodyPart.Transparency = 1
				end
				local Face = BodyPart:FindFirstChildOfClass("Decal")
				if Face then
					Face:Destroy()
				end
				local CostumeObject = script.Parent.Parent.Parent.Costume:FindFirstChild(BodyPart.Name)
				if CostumeObject then
					local ClonedCostumeObject = CostumeObject:Clone()
					ClonedCostumeObject.Parent = Player.Character
					for _,CostumeObjectPart in pairs(ClonedCostumeObject:GetChildren()) do
						if CostumeObjectPart:IsA("BasePart") then
							CostumeObjectPart.CustomPhysicalProperties = PhysicalProperties.new(0, 0, 0, 0, 0)
							AddWeld(BodyPart, CostumeObjectPart)
							CostumeObjectPart.Anchored = false
							CostumeObjectPart.CanCollide = false
							CostumeObjectPart.Locked = true
						end
					end
				else
					warn("A piece of costume is missing:", BodyPart.Name)
				end
			end
			wait()
		end
		Player.Character:SetPrimaryPartCFrame(OldCFrame)
		LockPlayer(Player, false)
		InUse = false
	end
end)
------Modules------


local modules = script.Parent.Parent.Modules
local core = require(modules.CoreModule)
local actions = require(modules.ActionsModule)
local combat = require(modules.CombatModule)
local targeting = require(modules.TargetModule)
local movement = require(modules.MovementModule)
local status = require(modules.Status)
local troubleshoot = require(modules.Troubleshoot)

local wait = task.wait
local spawn = task.spawn
local delay = task.delay
--[[
	Calls a function and throws an error if it attempts to yield.
	Pass any number of arguments to the function after the callback.
	This function supports multiple return; all results returned from the
	given function will be returned.
--]]



local function resultHandler(co, ok, ...)
	if not ok then
		local message = (...)
		error(debug.traceback(co, message), 2)
	end

	if coroutine.status(co) ~= "dead" then
		error(debug.traceback(co, "Attempted to yield inside changed event!"), 2)
	end

	return ...
end

type Callback = (...any) -> ...any

local function noYield(callback: Callback, ...): ...any
	local co = coroutine.create(callback)

	return resultHandler(co, coroutine.resume(co, ...))
end

return noYield
--여기까지



local ser = game:GetService("Debris") --오브젝트 삭제 관련 서비스
local skill = game.ReplicatedStorage.Skill:FindFirstChild(skillName) --스킬 찾기
local Cooldown = true
local DamageCool = false

script.Parent.SkillEvent.OnServerEvent:Connect(function(plr, X,Y ,Z, Target) --플레이어가 스킬을 클릭하면
	if Cooldown == true and Target ~= nil and not Target:FindFirstChild("Humanoid") then --조건이 맞으면
		Cooldown = false

		local clone = skill:Clone() --스킬 복사
		clone.Parent = game.Workspace.SkillPart --스킬 적용
		clone.Position = Vector3.new(X, (Y + 100), Z) --스킬 위치를 플레이어가 터치한 자리에
		
		clone.Touched:Connect(function(hit) --다른 플레이어가 스킬에 닿이면
			local human = hit.Parent:FindFirstChild("Humanoid") --휴머노이드 찾기
			local human2 = hit.Parent.Parent:FindFirstChild("Humanoid") --휴머노이드 찾기
			
			if human ~= nil and hit.Parent then --조건이 맞다면
				if hit.Parent.Name == script.Parent.Parent.Name and DamageCool == false then return	end --자신은 데미지 안먹힘 

				if human and DamageCool == false then --해당 조건이 맞으면

					DamageCool = true
					human:TakeDamage(Damage) --데미지 입히기
					wait(DamageCoolTime) --스킬 데미지 쿨타임 기다리기
					DamageCool = false

				elseif human2 and DamageCool == false then

					DamageCool = true
					human2:TakeDamage(Damage) --데미지 입히기
					wait(DamageCoolTime) --스킬 데미지 쿨타임 기다리기
					DamageCool = false
				end
			end 
		end) --끝
		
		script.Parent.Handle:FindFirstChild(Sound):Play() --오디오 틀기
		
		wait(1) --1초 기다림
		
		local bomb = game.ReplicatedStorage.Skill.Explosion:Clone() --폭팔 이펙트 복사
		bomb.Parent = game.Workspace.SkillPart --이펙트 적용
		bomb.Position = Vector3.new(clone.Position.X, clone.Position.Y, clone.Position.Z) --이펙트 위치 지정
		
		script.Parent.Handle:FindFirstChild(Sound2):Play() --오디오 틀기
		script.Parent.SkillEvent:FireClient(plr) --메세지 보내기(화면 흔들림 효과)

		ser:AddItem(bomb, 1) --1초뒤에 이펙트 삭제

		wait(CoolTime) --스킬 쿨타임 기다리기
		Cooldown = true
	end
end) --끝
--[[function Float()
	local Wobble = {
		Size = 3,
		Speed = 0.3,
		Factor = 0,
	}
	local UpVector = Vector3.new(0, 0, 0)
	local SpeedVector = Part.Velocity
	local PerpVector = SpeedVector.Unit:Cross(UpVector)
	local RandomAngle = (math.random() * math.pi * 2) --Get random angle in the perpendicular plane we just solved for
	local WobbleVector = (PerpVector * math.cos(RandomAngle) + UpVector * math.sin(RandomAngle)) --Get a random "wobble vector" in the perpendicular plane
	Spawn(function()
		while true do
			if not Part or not Part.Parent then
				break
			end
			--Part.RotVelocity = (Part.RotVelocity + Vector3.new(0, ((math.random() - 0.5) * 2), 0)) --See if is z instead of x value
			Part.Velocity = (SpeedVector + WobbleVector * math.sin(Wobble.Factor) * Wobble.Size)
			Wobble.Factor = (Wobble.Factor + Wobble.Speed)
			wait(0.25)
		end
	end)
end]]



function GetCreator()
	return ((Creator and Creator.Value and Creator.Value:IsA("Player") and Creator.Value) or nil)
end

function Blow(Object)
	local TouchedConnection
	TouchedConnection = Object.Touched:connect(function(Hit)
		if not Hit or not Hit.Parent then
			return
		end
		local character = Hit.Parent
		local humanoid = character:FindFirstChild("Humanoid")
		if not humanoid or humanoid.Health == 0 then
			return
		end
		local CreatorPlayer = GetCreator()
		local player = Players:GetPlayerFromCharacter(character)
		if player and CreatorPlayer and (player == CreatorPlayer or IsTeamMate(CreatorPlayer, player)) then
			return
		end
		UntagHumanoid(humanoid)
		TagHumanoid(humanoid, CreatorPlayer)
		humanoid:TakeDamage(Damage.Value)
		Part.Anchored = true
		Part.Transparency = 1
	end)
	return TouchedConnection		
end

Blow(Part)
--[[
	Returns the price of the given itemId
--]]



local ReplicatedStorage = game:GetService("ReplicatedStorage")

local getCategoryForItemId = require(ReplicatedStorage.Source.Utility.Farm.getCategoryForItemId)
local getItemByIdInCategory = require(ReplicatedStorage.Source.Utility.Farm.getItemByIdInCategory)
local getAttribute = require(ReplicatedStorage.Source.Utility.getAttribute)
local Attribute = require(ReplicatedStorage.Source.SharedConstants.Attribute)
local ItemCategory = require(ReplicatedStorage.Source.SharedConstants.ItemCategory)

local function getPurchaseCost(itemId: string)
	local categoryId: ItemCategory.EnumType = getCategoryForItemId(itemId)
	local itemModel = getItemByIdInCategory(itemId, categoryId)

	return getAttribute(itemModel, Attribute.PurchaseCost)
end

return getPurchaseCost
--script.Parent.Values.Gear.Changed:connect(function()
--	mult=1
--	if script.Parent.Values.RPM.Value>5500 then
--		shift=.2
--	end
--end)



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

handler:FireServer("newSound","Rev",car.DriveSeat,script.Rev.SoundId,0,script.Rev.Volume,true)
handler:FireServer("playSound","Rev")
car.DriveSeat:WaitForChild("Rev")

while wait() do
	mult=math.max(0,mult-.1)
	local _RPM = script.Parent.Values.RPM.Value
	
	if script.Parent.Values.Throttle.Value <= _Tune.IdleThrottle/100 then
		throt = math.max(.3,throt-.2)
		trmmult = math.max(0,trmmult-.05)
		trmon = 1		
	else
		throt = math.min(1,throt+.1)
		trmmult = 1
		trmon = 0		
	end	
	shift = math.min(1,shift+.2)	
	if script.Parent.Values.RPM.Value > _Tune.Redline-_Tune.RevBounce/4 and script.Parent.Values.Throttle.Value > _Tune.IdleThrottle/100 then
		redline=.5
	else
		redline=1
	end
	if not script.Parent.IsOn.Value then on=math.max(on-.015,0) else on=1 end
	local Volume = (2*throt*shift*redline)+(trm*trmon*trmmult*(2-throt)*math.sin(tick()*50))
	local Pitch = math.max((((script.Rev.SetPitch.Value + script.Rev.SetRev.Value*_RPM/_Tune.Redline))*on^2)+(det*mult*math.sin(80*tick())),script.Rev.SetPitch.Value)
	if FE then
		handler:FireServer("updateSound","Rev",script.Rev.SoundId,Pitch,Volume)
	else
		car.DriveSeat.Rev.Volume = Volume
		car.DriveSeat.Rev.Pitch = Pitch
	end
end
--[[
	Draws a ray between CFrame towards part. If the ray is close to the part (as defined by the discrepencies below), returns true - else returns false.
]]


local MAX_PERIPHERAL_SIGHT = 10
local MAX_SIGHT_RANGE = 1

return function(originCFrame, targetPart, ignoreInstance)
	local targetPartCFrame = targetPart.CFrame

	local pointedCFrame = CFrame.new(originCFrame.Position, targetPartCFrame.Position)

	local ray = Ray.new(pointedCFrame.Position, pointedCFrame.LookVector * 500)

	local hitPart, hitPosition = workspace:FindPartOnRay(ray, ignoreInstance)

	local discrepency = (hitPosition - targetPartCFrame.Position).magnitude
	local range = (originCFrame.LookVector - pointedCFrame.LookVector).magnitude

	if hitPart and (hitPart == targetPart or discrepency < MAX_PERIPHERAL_SIGHT) and range < MAX_SIGHT_RANGE then
		return true
	else
		return false
	end
end
-- ROBLOX FIXME: Can we define ClientChatModules statically in the project config


pcall(function() ChatLocalization = require((game:GetService("Chat") :: any).ClientChatModules.ChatLocalization :: any) end)

function CreateSystemMessageLabel(messageData, channelName)
	local message = messageData.Message
	if ChatLocalization and ChatLocalization.LocalizeFormattedMessage then
		message = ChatLocalization:LocalizeFormattedMessage(message)
	end
	local extraData = messageData.ExtraData or {}
	local useFont = extraData.Font or ChatSettings.DefaultFont
	local useTextSize = extraData.TextSize or ChatSettings.ChatWindowTextSize
	local useChatColor = extraData.ChatColor or ChatSettings.DefaultMessageColor
	local useChannelColor = extraData.ChannelColor or useChatColor

	local BaseFrame, BaseMessage = util:CreateBaseMessage(message, useFont, useTextSize, useChatColor)
	BaseMessage.AutoLocalize = true
	local ChannelButton = nil

	if channelName ~= messageData.OriginalChannel then
		local formatChannelName
		if ChatLocalization and messageData.OriginalChannel == "System" then
			local localizedChannelName = ChatLocalization:Get("InGame.Chat.Label.SystemMessagePrefix", "System")
			formatChannelName = string.format("{%s}", localizedChannelName)
		elseif ChatLocalization and messageData.OriginalChannel == "Team" then
			local localizedChannelName = ChatLocalization:Get("InGame.Chat.Label.TeamMessagePrefix", "System")
			formatChannelName = string.format("{%s}", localizedChannelName)
		else
			formatChannelName = string.format("{%s}", messageData.OriginalChannel)
		end
		ChannelButton = util:AddChannelButtonToBaseMessage(BaseMessage, useChannelColor, formatChannelName, messageData.OriginalChannel)
		local numNeededSpaces = util:GetNumberOfSpaces(formatChannelName, useFont, useTextSize) + 1
		BaseMessage.Text = string.rep(" ", numNeededSpaces) .. message
	end

	local function GetHeightFunction(xSize)
		return util:GetMessageHeight(BaseMessage, BaseFrame, xSize)
	end

	local FadeParmaters = {}
	FadeParmaters[BaseMessage] = {
		TextTransparency = {FadedIn = 0, FadedOut = 1},
		TextStrokeTransparency = {FadedIn = 0.75, FadedOut = 1}
	}

	if ChannelButton then
		FadeParmaters[ChannelButton] = {
			TextTransparency = {FadedIn = 0, FadedOut = 1},
			TextStrokeTransparency = {FadedIn = 0.75, FadedOut = 1}
		}
	end

	local FadeInFunction, FadeOutFunction, UpdateAnimFunction = util:CreateFadeFunctions(FadeParmaters)

	return {
		[util.KEY_BASE_FRAME] = BaseFrame,
		[util.KEY_BASE_MESSAGE] = BaseMessage,
		[util.KEY_UPDATE_TEXT_FUNC] = nil,
		[util.KEY_GET_HEIGHT] = GetHeightFunction,
		[util.KEY_FADE_IN] = FadeInFunction,
		[util.KEY_FADE_OUT] = FadeOutFunction,
		[util.KEY_UPDATE_ANIMATION] = UpdateAnimFunction
	}
end

return {
	[util.KEY_MESSAGE_TYPE] = ChatConstants.MessageTypeSystem,
	[util.KEY_CREATOR_FUNCTION] = CreateSystemMessageLabel
}