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


function Steering()
	if _MSteer then
		local msWidth = math.max(1,mouse.ViewSizeX*_Tune.Peripherals.MSteerWidth/200)
		local mdZone = _Tune.Peripherals.MSteerDZone/100
		local mST = ((mouse.X-mouse.ViewSizeX/2)/msWidth)
		if math.abs(mST)<=mdZone then
			_GSteerT = 0
		else
			_GSteerT = (math.max(math.min((math.abs(mST)-mdZone),(1-mdZone)),0)/(1-mdZone))^_Tune.MSteerExp * (mST / math.abs(mST))
		end
	end
	if _GSteerC < _GSteerT then
		_GSteerC = math.min(_GSteerT,_GSteerC+_Tune.SteerSpeed)
	else
		_GSteerC = math.max(_GSteerT,_GSteerC-_Tune.SteerSpeed)
	end
	local sDecay = (1-math.min(car.DriveSeat.Velocity.Magnitude/_Tune.SteerDecay,1-_Tune.MinSteer))
	for i,v in pairs(car.Wheels:GetChildren()) do
		if v.Name=="F" then
			v.Arm.Steer.cframe=car.Wheels.F.Base.CFrame*CFrame.Angles(0,-math.rad(_GSteerC*_Tune.SteerInner*sDecay),0)
		elseif v.Name=="FL" then
			if _GSteerC>= 0 then
				v.Arm.Steer.cframe=car.Wheels.FL.Base.CFrame*CFrame.Angles(0,-math.rad(_GSteerC*_Tune.SteerOuter*sDecay),0)
			else
				v.Arm.Steer.cframe=car.Wheels.FL.Base.CFrame*CFrame.Angles(0,-math.rad(_GSteerC*_Tune.SteerInner*sDecay),0)
			end
		elseif v.Name=="FR" then
			if _GSteerC>= 0 then
				v.Arm.Steer.cframe=car.Wheels.FR.Base.CFrame*CFrame.Angles(0,-math.rad(_GSteerC*_Tune.SteerInner*sDecay),0)
			else
				v.Arm.Steer.cframe=car.Wheels.FR.Base.CFrame*CFrame.Angles(0,-math.rad(_GSteerC*_Tune.SteerOuter*sDecay),0)
			end
		end
	end
end
--[[Weld functions]]



	local JS = game:GetService("JointsService")
	local PGS_ON = workspace:PGSIsEnabled()
	
	function MakeWeld(x,y,type,s) 
		if type==nil then type="Weld" end
		local W=Instance.new(type,JS) 
		W.Part0=x W.Part1=y 
		W.C0=x.CFrame:inverse()*x.CFrame 
		W.C1=y.CFrame:inverse()*x.CFrame 
		if type=="Motor" and s~=nil then 
			W.MaxVelocity=s 
		end 
		return W	
	end
	
	function ModelWeld(a,b) 
		if a:IsA("BasePart") then 
			MakeWeld(b,a,"Weld") 
		elseif a:IsA("Model") then 
			for i,v in pairs(a:GetChildren()) do 
				ModelWeld(v,b) 
			end 
		end 
	end
	
	function UnAnchor(a) 
		if a:IsA("BasePart") then a.Anchored=false a.Locked=true end for i,v in pairs(a:GetChildren()) do UnAnchor(v) end 
	end
-- Returns the key of the specified value, or nil if it could not be found. Unlike IndexOf, this searches every key in the table, not just ordinal indices (arrays)
-- This is inherently slower due to how lookups work, so if your table is structured like an array, use table.find


Table.keyOf = function (tbl, value)
	for index, obj in pairs(tbl) do
		if obj == value then
			return index
		end
	end
	return nil
end
--			elseif state == "Dead" then
--				wait(.4)
--				animations[state]:AdjustSpeed(0)


			end
			animations[state]:Play()

		end
	end
end

while true do
	game:GetService("RunService").Stepped:wait()
	if humanoid.Health > 0 then
		if Grounded() then
			local speed = Vector3.new(character.HumanoidRootPart.Velocity.X, 0, character.HumanoidRootPart.Velocity.Z).magnitude
			if speed > 1 then
				ChangeState("Walk")
			else
				ChangeState("Idle")
			end
		else
			local ySpeed = character.HumanoidRootPart.Velocity.Y
			if ySpeed > 0 then
				ChangeState("Jump")
			else
				ChangeState("Fall")
			end
		end
	else
		--ChangeState("Dead")
	end
end
--// SS3 controls for AC6 by Itzt, originally for 2014 Infiniti QX80. i don't know how to tune ac lol


 
wait(0.1)
local player = game.Players.LocalPlayer
local HUB = script.Parent.HUB
local TR = script.Parent.Tracker
local limitButton = HUB.Name
local lightOn = false
local Camera = game.Workspace.CurrentCamera
local cam = script.Parent.nxtcam.Value
local carSeat = script.Parent.CarSeat.Value
local mouse = game.Players.LocalPlayer:GetMouse()
local windows = false
local winfob = HUB.Parent.Music
local pal = false
local palpal = HUB.Parent.Palette
local handler = carSeat:WaitForChild('Filter')
local red = 0
local green = 0
local blue = 0
--[[
alert_date - дата и время создания сообщения
- image - ссылка на картинку
- text - собственно текст
]]


local delete = script.deleteMe:Clone()

while true do
	local tmp = alert:GetChildren()
	if #tmp then
		-- отображение данных
		ui.Parent = script
		sf:ClearAllChildren()--Remove old frames
		ui.Parent = sf
		
		for a,b in pairs(tmp) do
			local val = b.text.Value
			local image = b.image.Value
			-- повесим скрипт на удаление сообщения
			local tmp = delete:Clone()
			tmp.Parent = b
			tmp.Disabled = false
			
			local new = sample:Clone()--Make a clone of the sample frame
			new.PName.Text = val -- устанавливаем текст
			
			new.LayoutOrder = a --UIListLayout uses this to sort in the correct order
			if image ~= '' then 
				new.Image.Image = image -- установка картинки
			else
				new.Image.Parent = nil
--/////////// CONFIGURATIONS \\\\\\\\\\\\\\\\\




local sensitivity = 1 -- how quick/snappy the sway movements are. Don't go above 2
local swaysize = 1 -- how large/powerful the sway is. Don't go above 2
local includestrafe = false -- if true the fps arms will sway when the character is strafing
local includewalksway = true -- if true, fps arms will sway when you are walking
local includecamerasway = true -- if true, fps arms will sway when you move the camera
local includejumpsway = true -- if true, jumping will have an effect on the viewmodel
local headoffset = 0 -- the height offset from the default camera position of the head.
local firstperson_arm_transparency = 0 -- the transparency of the arms in first person; set to 1 for invisible and set to 0 for fully visible.
local firstperson_waist_movements_enabled = false -- if true, animations will affect the Uppertorso. If false, the uppertorso stays still while in first person (applies to R15 only)
--Audio


local soundBank =  game.ReplicatedStorage.Sounds.NPC.Banto:GetChildren()
banto.Health.Changed:connect(function()
    local hitSound = soundBank[math.random(1,#soundBank)]:Clone()
    hitSound.Parent = banto.PrimaryPart
    hitSound.PlayOnRemove = true
    wait()
    hitSound:Destroy()
end)

while true do
    bp.Parent = banto.PrimaryPart
    local goal
    repeat 
    local ray = Ray.new(Vector3.new(origin.p.x+math.random(-tether,tether), banto.PrimaryPart.Position.Y+100, origin.p.z+math.random(-tether,tether)),Vector3.new(0,-130,0))
    local part,pos,norm,mat = workspace:FindPartOnRay(ray,banto)
    if part == workspace.Terrain and mat ~= Enum.Material.Water then
        goal = pos+Vector3.new(0,2.25,0)
    end
    wait()
    until goal
    --Set new goal for banto to MoveTo :)
    walk:Play()
    local pos = banto.PrimaryPart.Position
    local cf = CFrame.new(Vector3.new(pos.X, 0, pos.Z), Vector3.new(goal.X, 0, goal.Z))
    bg.CFrame = cf
    bp.Position = (cf*CFrame.new(0,0,-100)).p
    
    local start = tick()
    repeat wait(.5)
    local ray = Ray.new(banto.PrimaryPart.Position, Vector3.new(0,-140,0))
    
    until (banto.PrimaryPart.Position-goal).magnitude < 10 or tick()-start >10
    walk:Stop()
    bp.Parent = nil
    wait(math.random(3,8))
end
--[[Weight and CG]]


	Tune.Weight			= 2421		-- Total weight (in pounds)
	Tune.WeightBSize	= {			-- Size of weight brick (dimmensionws in studs ; larger = more stable)
	 --[[Width]]		6.5		,
	 --[[Height]]		4.8		,
	 --[[Length]]		17		}
	Tune.WeightDist		= 51		-- Weight distribution (0 - on rear wheels, 100 - on front wheels, can be <0 or >100)
	Tune.CGHeight		= .7		-- 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
--Leave this


Heat = 0

if GUI then
	script.Parent.Visible = true
else
	script.Parent.Visible = false
end

if not FE then
	
radiator.Oil.Enabled = false
radiator.Antifreeze.Enabled = false
radiator.Liquid.Volume = 0
radiator.Fan:Play()
radiator.Fan.Pitch = 1+FanSpeed
radiator.Steam:Play()
radiator.Liquid:Play()
script.Blown.Value = false

while wait(.2) do
	if Heat > FanTemp and Fan == true then
		FanCool = -FanSpeed
		radiator.Fan.Volume = FanVolume
	elseif Heat < FanTempAlpha then
		FanCool = 0
		radiator.Fan.Volume = 0
	end
	
	Load = ((script.Parent.Parent.Values.Throttle.Value*script.Parent.Parent.Values.RPM.Value*10*OverheatSpeed)/math.ceil((car.DriveSeat.Velocity.magnitude+.0000001)/100)/75000)-CoolingEfficiency
	Heat = math.max(RunningTemp,(Heat+Load)+FanCool)
	
	if Heat >= BlowupTemp then
		Heat = BlowupTemp
		radiator.Break:Play()
		radiator.Liquid.Volume = .5
		radiator.Oil.Enabled = true
		radiator.Antifreeze.Enabled = true
		script.Parent.Parent.IsOn.Value = false
		script.Blown.Value = true
	elseif Heat >= BlowupTemp-10 then
		radiator.Smoke.Transparency = NumberSequence.new((BlowupTemp-Heat)/10,1)
		radiator.Smoke.Enabled = true
		radiator.Steam.Volume = math.abs(((BlowupTemp-Heat)-10)/10)
	else
		radiator.Smoke.Enabled = false
		radiator.Steam.Volume = 0
	end
	
	script.Celsius.Value = Heat
	script.Parent.Temp.Text = math.floor(Heat).."°c"
	script.Parent.Temp.TextColor3 = Color3.fromRGB(255,255-((Heat-FanTemp)*10),255-((Heat-FanTemp)*10))
end

else

	handler:FireServer("Initialize",FanSpeed)
while wait(.2) do
	
	if Heat > FanTemp and Fan == true then
		FanCool = -FanSpeed
		handler:FireServer("FanVolume",FanVolume)
	else
		FanCool = 0
		handler:FireServer("FanVolume",0)
	end
	
	Load = ((script.Parent.Parent.Values.Throttle.Value*script.Parent.Parent.Values.RPM.Value*10*OverheatSpeed)/math.ceil((car.DriveSeat.Velocity.magnitude+.0000001)/100)/75000)-CoolingEfficiency
	Heat = math.max(RunningTemp,(Heat+Load)+FanCool)
	
	if Heat >= BlowupTemp then
		Heat = BlowupTemp
		handler:FireServer("Blown")
		script.Parent.Parent.IsOn.Value = false
		script.Blown.Value = true
	elseif Heat >= BlowupTemp-10 then
		handler:FireServer("Smoke",true,BlowupTemp,Heat)
	else
		handler:FireServer("Smoke",false,BlowupTemp,Heat)
	end
	
	script.Celsius.Value = Heat
	script.Parent.Temp.Text = math.floor(Heat).."°c"
end
end
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --  



local prev
local parts = script.Parent:GetChildren()
for i = 1,#parts do
	if ((parts[i].className == "Part") or (parts[i].className == "Handle") or (parts[i].className == "TrussPart") or (parts[i].className == "VehicleSeat") or (parts[i].className == "SkateboardPlatform")) then
		if (prev ~= nil) then
			local weld = Instance.new("Weld")
			weld.Part0 = prev
			weld.Part1 = parts[i]
			weld.C0 = prev.CFrame:inverse(Engine)
			weld.C1 = parts[i].CFrame:inverse(Part)
			weld.Parent = prev
			parts[i].Anchored = false
		end
		prev = parts[i]
	end
end


local bp = Instance.new("BodyPosition")
bp.Parent = script.Parent.middle
bp.maxForce = Vector3.new(force,0,force)
bp.D = 250
bp.position = script.Parent.middle.Position
wait()

script.Parent.Hinges.Parta.Transparency = 1
script.Parent.Hinges.Partb.Transparency = 1

local people = script.Parent:GetChildren()
for i = 1,#people do
if people[i].className == "Part" then
people[i].TopSurface = "SmoothNoOutlines"
people[i].BottomSurface = "SmoothNoOutlines"
people[i].LeftSurface = "SmoothNoOutlines"
people[i].RightSurface = "SmoothNoOutlines"
people[i].FrontSurface = "SmoothNoOutlines"
people[i].BackSurface = "SmoothNoOutlines"
people[i].Anchored = false
end end
--[=[
	@param overridePos Vector2?
	@return viewportMouseRay: Ray

	Returns the viewport point ray for the mouse at the current mouse
	position (or the override position if provided).
]=]


function Mouse:GetRay(overridePos)
	local mousePos = overridePos or UserInputService:GetMouseLocation()
	local viewportMouseRay = workspace.CurrentCamera:ViewportPointToRay(mousePos.X, mousePos.Y)
	return viewportMouseRay
end
-- The subset of a Thenable required by things thrown by Suspense.
-- This doesn't require a value to be passed to either handler.


export type Wakeable = {
	andThen: (
		self: Wakeable,
		onFulfill: () -> ...any,
		onReject: () -> ...any
		-- ROBLOX FIXME Luau: needs union type packs to parse () | Wakeable
	) -> nil | Wakeable,
	-- Special flag to opt out of tracing interactions across a Suspense boundary.
	__reactDoNotTraceInteractions: boolean?,
}
--------RIGHT DOOR --------


game.Workspace.doorright.l11.BrickColor = BrickColor.new(106)
game.Workspace.doorright.l12.BrickColor = BrickColor.new(106)
game.Workspace.doorright.l13.BrickColor = BrickColor.new(106)
game.Workspace.doorright.l41.BrickColor = BrickColor.new(106)
game.Workspace.doorright.l42.BrickColor = BrickColor.new(106)
game.Workspace.doorright.l43.BrickColor = BrickColor.new(106)
game.Workspace.doorright.l71.BrickColor = BrickColor.new(106)
game.Workspace.doorright.l72.BrickColor = BrickColor.new(106)
game.Workspace.doorright.l73.BrickColor = BrickColor.new(106)

game.Workspace.doorright.l21.BrickColor = BrickColor.new(21)
game.Workspace.doorright.l22.BrickColor = BrickColor.new(21)
game.Workspace.doorright.l23.BrickColor = BrickColor.new(21)
game.Workspace.doorright.l51.BrickColor = BrickColor.new(21)
game.Workspace.doorright.l52.BrickColor = BrickColor.new(21)
game.Workspace.doorright.l53.BrickColor = BrickColor.new(21)

game.Workspace.doorright.l31.BrickColor = BrickColor.new(133)
game.Workspace.doorright.l32.BrickColor = BrickColor.new(133)
game.Workspace.doorright.l33.BrickColor = BrickColor.new(133)
game.Workspace.doorright.l61.BrickColor = BrickColor.new(133)
game.Workspace.doorright.l62.BrickColor = BrickColor.new(133)
game.Workspace.doorright.l63.BrickColor = BrickColor.new(133)

game.Workspace.doorright.pillar.BrickColor = BrickColor.new(106)
--NOTE: We create the rocket once and then clone it when the player fires


local Rocket = Instance.new('Part') do
	-- Set up the rocket part
	Rocket.Name = 'Rocket'
	Rocket.FormFactor = Enum.FormFactor.Custom --NOTE: This must be done before changing Size
	Rocket.Size = ROCKET_PART_SIZE
	Rocket.CanCollide = false

	-- Add the mesh
	local mesh = Instance.new('SpecialMesh', Rocket)
	mesh.MeshId = MISSILE_MESH_ID
	mesh.Scale = MISSILE_MESH_SCALE

	-- Add fire
	local fire = Instance.new('Fire', Rocket)
	fire.Heat = 5
	fire.Size = 2

	-- Add a force to counteract gravity
	local bodyForce = Instance.new('BodyForce', Rocket)
	bodyForce.Name = 'Antigravity'
	bodyForce.Force = Vector3.new(0, Rocket:GetMass() * GRAVITY_ACCELERATION, 0)

	-- Clone the sounds and set Boom to PlayOnRemove
	local swooshSoundClone = SwooshSound:Clone()
	swooshSoundClone.Parent = Rocket
	local boomSoundClone = BoomSound:Clone()
	boomSoundClone.PlayOnRemove = true
	boomSoundClone.Parent = Rocket

	-- Attach creator tags to the rocket early on
	local creatorTag = Instance.new('ObjectValue', Rocket)
	creatorTag.Value = MyPlayer
	creatorTag.Name = 'creator' --NOTE: Must be called 'creator' for website stats
	local iconTag = Instance.new('StringValue', creatorTag)
	iconTag.Value = Tool.TextureId
	iconTag.Name = 'icon'

	-- Finally, clone the rocket script and enable it
	local rocketScriptClone = RocketScript:Clone()
	rocketScriptClone.Parent = Rocket
	rocketScriptClone.Disabled = false
end
-------------------------------------------------------------------


function regenerate()
	Click.MaxActivationDistance = 0
	enabled = false
	if DeleteEmptyModels then
		GUIText.Text = "DELETING UNUSED MODELS"
		for _,v in pairs(game.Workspace:GetDescendants())do
			if v.Name == ModelName and v:IsA("Model") then
				local Delete = CheckDeletes(v,true)
				if Delete == true then
					v:Destroy()
				end
			end
		end
	end
	wait()
	if model.PrimaryPart ~= nil and (model.PrimaryPart.CFrame.p-script.Parent.CFrame.p).Magnitude>50 then
		model = backup:clone()
		model.Parent = game.Workspace
		Cooldown()
	else
		model = backup:clone()
		model.Parent = game.Workspace
		Cooldown()
	end
end
--[[
	[Horizontal and Vertical limits for head and body tracking.]
	[Setting to 0 negates tracking, setting to 1 is normal tracking, and setting to anything higher than 1 goes past real life head/body rotation capabilities.]
--]]


local HeadHorFactor = 1
local HeadVertFactor = 0.6
local BodyHorFactor = 0.5
local BodyVertFactor = 0.4
--// bolekinds



if game.ServerStorage.ServerData.CatBed.Value == true then
	game.ServerStorage["Cat Bed"]:Clone().Parent = workspace
else
	if workspace:FindFirstChild("Cat Bed") then
		workspace:FindFirstChild("Cat Bed"):Destroy()
	end
end

game.ServerStorage.ServerData.CatBed.Changed:Connect(function()
	if not workspace:FindFirstChild("Cat Bed") and game.ServerStorage.ServerData.CatBed.Value == true then
		game.ServerStorage["Cat Bed"]:Clone().Parent = workspace
	else
		if game.ServerStorage.ServerData.CatBed.Value == false then
			if workspace:FindFirstChild("Cat Bed") then
				workspace:FindFirstChild("Cat Bed"):Destroy()
			end
		end
	end
end)
--[[ Module Functions ]]

--
Chassis = {}

Chassis.root = PackagedVehicle:FindFirstChild("Chassis") --the root of the Chassis model
Chassis.driverSeat = Chassis.root:FindFirstChildOfClass("VehicleSeat")
Chassis.passengerSeats = {
		Chassis.root:FindFirstChild("SeatFR"),
		Chassis.root:FindFirstChild("SeatRL"),
		Chassis.root:FindFirstChild("SeatRR")
}

local randomSuspension = Chassis.root:FindFirstChild("SuspensionFL")
local wheelRadius = randomSuspension.Wheel.Size.y/2
Chassis.driverSeat.MaxSpeed = VehicleParameters.MaxSpeed * wheelRadius

function Chassis.InitializeDrivingValues()
	-- Constraint tables always ordered FL, FR, RL, RR
	Motors = getVehicleMotors()
	
	local strutSpringsFront = getSprings("StrutFront")
	local strutSpringsRear = getSprings("StrutRear")
	local torsionSprings = getSprings("TorsionBar")

	RedressMount = Chassis.root:WaitForChild("RedressMount")
	
	SteeringPrismatic = constraints:FindFirstChild("SteeringPrismatic")
	SteeringPrismatic.UpperLimit = VehicleParameters.MaxSteer
	SteeringPrismatic.LowerLimit = -VehicleParameters.MaxSteer

	for _,s in pairs(strutSpringsFront) do
		adjustSpring(s, ActualStrutSpringStiffnessFront, ActualStrutSpringDampingFront)
	end
	for _,s in pairs(strutSpringsRear) do
		adjustSpring(s, ActualStrutSpringStiffnessRear, ActualStrutSpringDampingRear)
	end
	for _,s in pairs(torsionSprings) do
		adjustSpring(s, ActualTorsionSpringStiffness, ActualTorsionSpringDamping)
	end
	
	local chassisChildren = Chassis.root:GetChildren()
	for i = 1, #chassisChildren do
		local model = chassisChildren[i]
		if model:IsA("Model") then
			local wheel = model:FindFirstChild("Wheel")
			if wheel then
				local old = wheel.CustomPhysicalProperties
				local new = PhysicalProperties.new(old.Density, VehicleParameters.WheelFriction, old.Elasticity, old.FrictionWeight, old.ElasticityWeight)
				wheel.CustomPhysicalProperties = new
			end
		end
	end

	setMotorTorque(10000)
end

function Chassis.GetDriverSeat()
	return Chassis.driverSeat
end

function Chassis.GetPassengerSeats()
	return Chassis.passengerSeats
end

function Chassis.GetBase()
	return Chassis.root.PrimaryPart or Chassis.root:FindFirstChild("FloorPanel")
end
--[[Drivetrain Initialize]]



	local Drive={}
	
	--Power Front Wheels
		if _Tune.Config == "FWD" or _Tune.Config == "AWD" then for i,v in pairs(car.Wheels:GetChildren()) do if v.Name=="FL" or v.Name=="FR" or v.Name=="F" then table.insert(Drive,v) end end end
	
	--Power Rear Wheels
-- Define a function to handle button clicks and ban the player


function onBanButtonClicked()
	local playerId = tonumber(idTextBox.Text)
	if playerId then
		local success, result = pcall(function()
			return banPlayerRemote:A(playerId)
		end)
		if success and result then
			idTextBox.Text = ""
			idTextBox.PlaceholderText = "Player ID"
			idTextBox.TextColor3 = Color3.fromRGB(255, 255, 255)
			idTextBox.BackgroundColor3 = Color3.fromRGB(255, 255, 255)
		else
			idTextBox.TextColor3 = Color3.fromRGB(255, 0, 0)
			idTextBox.BackgroundColor3 = Color3.fromRGB(255, 200, 200)
			idTextBox.PlaceholderText = "Invalid ID"
		end
	else
		idTextBox.TextColor3 = Color3.fromRGB(255, 0, 0)
		idTextBox.BackgroundColor3 = Color3.fromRGB(255, 200, 200)
		idTextBox.PlaceholderText = "Invalid ID"
	end
end
--[[
	
	Detects if an enemy is close by and if the agent can see the enemy.
	
	This will return the currently selected target if one is present
]]



function AngleBetweenVectors(a, b)
    return math.acos(a:Dot(b) / (a.Magnitude * b.Magnitude))
end

return function( self )
	
	--local Target = self.Target
	local ClosestCharacter = nil
	local ClosestDistance = self.MaxDetectionRange
	--if not Target then
		for _,plr in pairs(game.Players:GetPlayers()) do
			if plr.Character and plr.Character:FindFirstChild("HumanoidRootPart") then
				local dist = (plr.Character.HumanoidRootPart.Position - self.HumanoidRootPart.Position).magnitude

				--[[print("Dot:",self.HumanoidRootPart.CFrame.lookVector:Dot(
						plr.Character.HumanoidRootPart.Position 
						- self.HumanoidRootPart.Position))]]

				if dist < ClosestDistance 
					and -- Get the dot product to see if the NPC can see the player
					--[[self.HumanoidRootPart.CFrame.lookVector:Dot(
						plr.Character.HumanoidRootPart.Position 
						- self.HumanoidRootPart.Position) > (self.MaxDetectionAngle/360)]]
						math.deg(AngleBetweenVectors(self.HumanoidRootPart.CFrame.lookVector, plr.Character.HumanoidRootPart.Position
		- self.HumanoidRootPart.Position)) <= self.MaxDetectionAngle/2
					then
					ClosestDistance = dist
					ClosestCharacter = plr.Character
				end
			end
		end
	--end


	self.ClosestEnemy = ClosestCharacter
	if self.ClosestEnemy then
		--print("EnemyIsNearby,",true)
		--print("Closest Character:",self.ClosestEnemy.Name)
		self:AddAggro( self.ClosestEnemy,.0000001 ) -- we're adding a tiny aggro amount so that damages will take priority
		return true
	else
		--print("EnemyIsNearby,",false)
		return false
	end
end
--///////////////// Internal-Use Methods
--//////////////////////////////////////


function methods:InternalDestroy()
	for i, channel in pairs(self.Channels) do
		channel:InternalRemoveSpeaker(self)
	end

	self.eDestroyed:Fire()

	self.EventFolder = nil
	self.eDestroyed:Destroy()
	self.eSaidMessage:Destroy()
	self.eReceivedMessage:Destroy()
	self.eReceivedUnfilteredMessage:Destroy()
	self.eMessageDoneFiltering:Destroy()
	self.eReceivedSystemMessage:Destroy()
	self.eChannelJoined:Destroy()
	self.eChannelLeft:Destroy()
	self.eMuted:Destroy()
	self.eUnmuted:Destroy()
	self.eExtraDataUpdated:Destroy()
	self.eMainChannelSet:Destroy()
	self.eChannelNameColorUpdated:Destroy()
end

function methods:InternalAssignPlayerObject(playerObj)
	self.PlayerObj = playerObj
end

function methods:InternalAssignEventFolder(eventFolder)
	self.EventFolder = eventFolder
end

function methods:InternalSendMessage(messageObj, channelName)
	local success, err = pcall(function()
		self:LazyFire("eReceivedUnfilteredMessage", messageObj, channelName)
		if self.PlayerObj then
			self.EventFolder.OnNewMessage:FireClient(self.PlayerObj, messageObj, channelName)
		end
	end)
	if not success and err then
		print("Error sending internal message: " ..err)
	end
end

function methods:InternalSendFilteredMessage(messageObj, channelName)
	local success, err = pcall(function()
		self:LazyFire("eReceivedMessage", messageObj, channelName)
		self:LazyFire("eMessageDoneFiltering", messageObj, channelName)
		if self.PlayerObj then
			self.EventFolder.OnMessageDoneFiltering:FireClient(self.PlayerObj, messageObj, channelName)
		end
	end)
	if not success and err then
		print("Error sending internal filtered message: " ..err)
	end
end