Roblox/luau_corpus huggingface dataset:
--------RIGHT DOOR --------
game.Workspace.doorright.l11.BrickColor = BrickColor.new(game.Workspace.Lighting.secondary.Value)
game.Workspace.doorright.l22.BrickColor = BrickColor.new(game.Workspace.Lighting.secondary.Value)
game.Workspace.doorright.l33.BrickColor = BrickColor.new(game.Workspace.Lighting.secondary.Value)
game.Workspace.doorright.l41.BrickColor = BrickColor.new(game.Workspace.Lighting.secondary.Value)
game.Workspace.doorright.l52.BrickColor = BrickColor.new(game.Workspace.Lighting.secondary.Value)
game.Workspace.doorright.l63.BrickColor = BrickColor.new(game.Workspace.Lighting.secondary.Value)
game.Workspace.doorright.l71.BrickColor = BrickColor.new(game.Workspace.Lighting.secondary.Value)

game.Workspace.doorright.l43.BrickColor = BrickColor.new(game.Workspace.Lighting.defaultlights.Value)
game.Workspace.doorright.l61.BrickColor = BrickColor.new(game.Workspace.Lighting.defaultlights.Value)
game.Workspace.doorright.l53.BrickColor = BrickColor.new(game.Workspace.Lighting.defaultlights.Value)
game.Workspace.doorright.l72.BrickColor = BrickColor.new(game.Workspace.Lighting.defaultlights.Value)
game.Workspace.doorright.l62.BrickColor = BrickColor.new(game.Workspace.Lighting.defaultlights.Value)
game.Workspace.doorright.l51.BrickColor = BrickColor.new(game.Workspace.Lighting.defaultlights.Value)
game.Workspace.doorright.l21.BrickColor = BrickColor.new(game.Workspace.Lighting.defaultlights.Value)
game.Workspace.doorright.l31.BrickColor = BrickColor.new(game.Workspace.Lighting.defaultlights.Value)
game.Workspace.doorright.l12.BrickColor = BrickColor.new(game.Workspace.Lighting.defaultlights.Value)
game.Workspace.doorright.l13.BrickColor = BrickColor.new(game.Workspace.Lighting.defaultlights.Value)
game.Workspace.doorright.l32.BrickColor = BrickColor.new(game.Workspace.Lighting.defaultlights.Value)
game.Workspace.doorright.l23.BrickColor = BrickColor.new(game.Workspace.Lighting.defaultlights.Value)
game.Workspace.doorright.l42.BrickColor = BrickColor.new(game.Workspace.Lighting.defaultlights.Value)
game.Workspace.doorright.l73.BrickColor = BrickColor.new(game.Workspace.Lighting.defaultlights.Value)

game.Workspace.doorright.pillar.BrickColor = BrickColor.new(game.Workspace.Lighting.defaultlights.Value)
--[[**
		ensures value is an array of a strict makeup and size

		@param check The check to compare all values with

		@returns A function that will return true iff the condition is passed
	**--]]
	function t.strictArray(...)
		local valueTypes = { ... }
		assert(t.array(t.callback)(valueTypes))

		return function(value)
			local keySuccess, keyErrMsg = arrayKeysCheck(value)
			if keySuccess == false then
				return false, string.format("[strictArray] %s", keyErrMsg or "")
			end

			-- If there's more than the set array size, disallow
			if #valueTypes < #value then
				return false, string.format("[strictArray] Array size exceeds limit of %d", #valueTypes)
			end

			for idx, typeFn in valueTypes do
				local typeSuccess, typeErrMsg = typeFn(value[idx])
				if not typeSuccess then
					return false, string.format("[strictArray] Array index #%d - %s", idx, typeErrMsg)
				end
			end

			return true
		end
	end
end

do
	local callbackArray = t.array(t.callback)
--s.Pitch = 0.7
while s.Pitch<0.6 do
s.Pitch=s.Pitch+0.010
s:Play()
if s.Pitch>0.6 then
	s.Pitch=0.6
end
wait(0.001)
end
--Tool.Equipped:connect(OnEquipped)
--Tool.Changed:connect(OnChanged)

Tool = script.Parent
mouse = game.Players.LocalPlayer:GetMouse()

colors = {45, 119, 21, 24, 23, 105, 104}

function fire(v)

	script.Parent.fire:FireServer(v)

end



Tool.Enabled = true
function onActivated()

	if not Tool.Enabled then
		return
	end

	Tool.Enabled = false

	local character = Tool.Parent;
	local humanoid = character.Humanoid
	if humanoid == nil then
		print("Humanoid not found")
		return 
	end

	local targetPos = humanoid.TargetPoint
	local lookAt = (mouse.Hit.p - character.Head.Position).unit

	fire(lookAt)

	wait(.5)

	Tool.Enabled = true
end


script.Parent.Activated:connect(onActivated)
--[[ Initialization ]]--
 -- TODO: Remove when safe! ContextActionService crashes touch clients with tupele is 2 or more
if not UserInputService.TouchEnabled then
	initialize()
	if isShiftLockMode() then
		InputCn = UserInputService.InputBegan:connect(onShiftInputBegan)
		IsActionBound = true
	end
end
--// Script
for index,Weapon in pairs(Folder:GetChildren()) do
local Clone = Template:Clone()
Clone.Name = Weapon.Name
Clone.Price.Value = Weapon.Price.Value
Clone.NAME.Text = Weapon.Name
Clone.COST.Text = Weapon.Price.Value
Clone.Parent = script.Parent
Clone.Visible = true
end
-- ROBLOX scripter hackers, see what you can do with this:
-- game:GetService("BadgeService"):UserHasBadge(userid, badgeid)


function OnTouch(part)
	if (part.Parent:FindFirstChild("Humanoid") ~= nil) then
		local p = game.Players:GetPlayerFromCharacter(part.Parent)
		if (p ~= nil) then
			print("Awarding BadgeID: " ..script.Parent.BadgeID.Value .. " to UserID: " .. p.userId)
			local b = game:GetService("BadgeService")
			b:AwardBadge(p.userId, script.Parent.BadgeID.Value)
		end
	end
end

script.Parent.Touched:connect(OnTouch)
--Sizes
local xsize = script.Parent.Size.X
local ysize = script.Parent.Size.Y
local zsize = script.Parent.Size.Z
-- Main loop for the entire game
while true do
	displayManager.updateStatus("Waiting for Players")
	
	displayManager.updateTime(0)
	
	repeat
		wait(1)
	until Players.NumPlayers >= gameSettings.minimumPlayers
	
	-- Actual Intermission
	displayManager.updateStatus("Intermission")
	gameTimer:start(gameSettings.intermissionDuration)
	displayManager.trackTimer(gameTimer)
	gameTimer.finished:Wait()
	
	roundManager.prepareGame()
	displayManager.updateStatus("Round in Progress")
	
	-- Waits until the roundEnd event has fired before continuing the script 
	local endState = roundEnd.Event:Wait()
	
	-- Displays how the game ended to the player's GUI. Ex: Winner found, time up ...
	local resultString = roundManager.endRound()
	displayRoundResult:FireAllClients(resultString)
	
	-- Starts the end intermission. Will remove player weapons if still actively in game. 
	displayManager.updateTime(0)
	wait(gameSettings.transitionEnd)
	roundManager.endGameIntermission()
	
	-- Resets the game by moving players back into the lobby and clearing used variables 
	roundManager.resetGame()
	
end
--[=[
	@prop Util Folder
	@within KnitClient
	@readonly
	References the Util folder. Should only be accessed when using Knit as
	a standalone module. If using Knit from Wally, modules should just be
	pulled in via Wally instead of relying on Knit's Util folder, as this
	folder only contains what is necessary for Knit to run in Wally mode.
]=]
KnitClient.Util = script.Parent.Parent

local Promise = require(KnitClient.Util.Promise)
local Comm = require(KnitClient.Util.Comm)
local ClientComm = Comm.ClientComm

local controllers: {[string]: Controller} = {}
local services: {[string]: Service} = {}
local servicesFolder = nil

local started = false
local startedComplete = false
local onStartedComplete = Instance.new("BindableEvent")


local function DoesControllerExist(controllerName: string): boolean
	local controller: Controller? = controllers[controllerName]
	return controller ~= nil
end


local function GetServicesFolder()
	if not servicesFolder then
		servicesFolder = script.Parent:WaitForChild("Services")
	end
	return servicesFolder
end


local function GetMiddlewareForService(serviceName: string)
	local knitMiddleware = selectedOptions.Middleware or {}
	local serviceMiddleware = selectedOptions.PerServiceMiddleware[serviceName]
	return serviceMiddleware or knitMiddleware
end


local function BuildService(serviceName: string)
	local folder = GetServicesFolder()
	local middleware = GetMiddlewareForService(serviceName)
	local clientComm = ClientComm.new(folder, selectedOptions.ServicePromises, serviceName)
	local service = clientComm:BuildObject(middleware.Inbound, middleware.Outbound)
	services[serviceName] = service
	return service
end
-- Provide functionality to the server API endpoint instance
ServerEndpoint.OnServerInvoke = function (Client, ...)
	return SyncModule.PerformAction(Client, ...);
end;
--[=[
	@param trigger KeyCode
	@param deadzoneThreshold number?
	@return number
	Gets the position of the given trigger. The triggers are usually going
	to be `Enum.KeyCode.ButtonL2` and `Enum.KeyCode.ButtonR2`. These trigger
	buttons are analog, and will output a value between the range of [0, 1].

	If `deadzoneThreshold` is not included, the `DefaultDeadzone` value is
	used instead.

	```lua
	local triggerAmount = gamepad:GetTrigger(Enum.KeyCode.ButtonR2)
	print(triggerAmount)
	```
]=]
function Gamepad:GetTrigger(trigger: Enum.KeyCode, deadzoneThreshold: number?): number
	return ApplyDeadzone(self.State[trigger].Position.Z, deadzoneThreshold or self.DefaultDeadzone)
end
----------------------------------
------------FUNCTIONS-------------
----------------------------------

function Receive(action, ...)
	local args = {...}
	if not ScriptReady then return end
	if action == "activate" then
		if not PlayingEnabled then
			Activate(args[1], args[2])
		end
	elseif action == "deactivate" then
		if PlayingEnabled then
			Deactivate()
		end
	elseif action == "play" then
		if Player ~= args[1] then
			PlayNoteServer(args[2], args[3], args[4], args[5])
		end
	end
end
function Activate(cameraCFrame, sounds)
	PlayingEnabled = true
	MakeHumanoidConnections()
	MakeKeyboardConnections()
	MakeGuiConnections()
	SetCamera(cameraCFrame)
	SetSounds(sounds)
	ShowPiano()
end
function Deactivate()
	PlayingEnabled = false
	BreakHumanoidConnections()
	BreakKeyboardConnections()
	BreakGuiConnections()
	HidePiano()
	HideSheets()
	ReturnCamera()	
	Jump()
end
function PlayNoteClient(note)
	PlayNoteSound(note)
	HighlightPianoKey(note)
	Connector:FireServer("play", note)
end
function PlayNoteServer(note, point, range)
	PlayNoteSound(note, point, range)
end
function Abort()
	Connector:FireServer("abort")
end
--returns the wielding player of this tool
function getPlayer()
	local char = Tool.Parent
	return game:GetService("Players"):GetPlayerFromCharacter(Character)
end

function Toss(direction)
	local handlePos = Vector3.new(Tool.Handle.Position.X, 0, Tool.Handle.Position.Z)
	local spawnPos = Character.Head.Position
	
	spawnPos  = spawnPos + (direction * 5)
	
	local Object = Tool.Handle:Clone()
	Object.Burn.Attachment.Debris.Enabled = true
	Object.ThinkFast:Destroy()
	Object.Parent = workspace
	Object.Swing.Pitch = Random.new():NextInteger(90, 110)/100
	Object.Swing:Play()
	Object.CanCollide = true
	Object.CFrame = Tool.Handle.CFrame
	Object.Velocity = (direction*AttackVelocity) + Vector3.new(0,AttackVelocity/7.5,0)
	Object.Trail.Enabled = true
	
	local rand = 11.25
	Object.RotVelocity = Vector3.new(Random.new():NextNumber(-rand,rand),Random.new():NextNumber(-rand,rand),Random.new():NextNumber(-rand,rand))
	Object:SetNetworkOwner(getPlayer())
	
	local ScriptClone = DamageScript:Clone()
	ScriptClone.Parent = Object
	ScriptClone.Disabled = false
	
	local tag = Instance.new("ObjectValue")
	tag.Value = getPlayer()
	tag.Name = "creator"
	tag.Parent = Object
end


PowerRemote.OnServerEvent:Connect(function(player, Power)
	local holder = getPlayer()
	if holder ~= player then return end
	
	AttackVelocity = Power
end)

TossRemote.OnServerEvent:Connect(function(player, mousePosition)
	local holder = getPlayer()
	if holder ~= player then return end
	
	if Cooldown.Value == true then return end
	Cooldown.Value = true
	
	if Humanoid and Humanoid.RigType == Enum.HumanoidRigType.R15 then
		TossRemote:FireClient(getPlayer(), "PlayAnimation", "Animation")
	end
	local targetPos = mousePosition.p
	local lookAt = (targetPos - Character.Head.Position).unit
	
	local SecretRNG = Random.new():NextInteger(1,10) --Change RNG value here
	if SecretRNG == 1 then
		local ChucklenutsSound = Tool.Handle.ThinkFast:Play()
	end
	
	Toss(lookAt)
	task.wait(CooldownTime)
	Cooldown.Value = false
end)

Tool.Equipped:Connect(function()
	Character = Tool.Parent
	Humanoid = Character:FindFirstChildOfClass("Humanoid")
end)

Tool.Unequipped:Connect(function()
	Character = nil
	Humanoid = nil
end)
-- But in this script, the animation is loaded only ONCE.

Mouse.KeyDown:connect(function(key)
     key = string.lower(key)
   if string.byte(key) == 48 then
        s:Play()
        humanoid.WalkSpeed = 67
    end
end)


Mouse.KeyUp:connect(function(key)
    key = string.lower(key)
if string.byte(key) == 48 then
        s:Stop()
        humanoid.WalkSpeed = 7
    end
end)
--]]


function getHumanoid(model)
	for _, v in pairs(model:GetChildren()) do
		if v:IsA'Humanoid' then
			return v
		end
	end
end


local ai = script.Parent
local human = getHumanoid(ai)
local hroot = ai.HumanoidRootPart
local zspeed = hroot.Velocity.magnitude


local pfs = game:GetService("PathfindingService")

function GetPlayerNames()
	local players = game:GetService('Players'):GetChildren()
	local name = nil
	for _, v in pairs(players) do
		if v:IsA'Player' then
			name = tostring(v.Name)
		end
	end
	return name
end


function GetPlayersBodyParts(t)
	local torso = t
	if torso then
		local figure = torso.Parent
		for _, v in pairs(figure:GetChildren()) do
			if v:IsA'Part' then
				return v.Name
			end
		end
	else
		return "HumanoidRootPart"
	end
end

function GetTorso(part)
	local chars = game.Workspace:GetChildren()
	local torso = nil
	for _, v in pairs(chars) do
		if v:IsA'Model' and v ~= script.Parent and v.Name == GetPlayerNames() and not v:FindFirstChild("Enemy") then
			local charRoot = v:FindFirstChild'HumanoidRootPart'
			if (charRoot.Position - part).magnitude < SearchDistance then
				torso = charRoot
			end
		end
	end
	return torso
end

for _, zambieparts in pairs(ai:GetChildren()) do
	if zambieparts:IsA'Part' then
		zambieparts.Touched:connect(function(p)
			if p.Parent.Name == GetPlayerNames() and p.Parent.Name ~= ai.Name then -- damage
				local enemy = p.Parent
				local enemyhuman = getHumanoid(enemy)
				enemyhuman:TakeDamage(aiDamage)
			end
		end)
	end
end
--while wait() do
if char then
game.StarterGui:SetCoreGuiEnabled(2,EnableBackpackGui)
for i,v in ipairs(char:GetChildren()) do
if v.className ~= ""..Weapon.."" then
wait()
if db == 1 then
player.Character.Humanoid:EquipTool(tool)
db=2
end
end
end
script.Parent.Unequipped:connect(function()
db=1
end)
end
--Update list of players in admin panel
local selectPlrFrame = panel.Pages.MainButtonsFrame.ButtonsScroller.SelectPlayerFrame
local scroller = selectPlrFrame.PlayersScroller
local selectedFrame = selectPlrFrame.SelectedPlayerFrame
selectedFrame.Visible = false

function updatePlayers()
	for i, child in pairs(scroller:GetChildren()) do
		if child:IsA("TextButton") then
			child:Destroy()
		end
	end
	
	for i, plr in pairs(game.Players:GetPlayers()) do
		
		local btn = script.PlayerButton:Clone()
		
		local name = plr.Name
		btn.PlayerName.Text = name
		
		local image = game.Players:GetUserThumbnailAsync(plr.UserId, Enum.ThumbnailType.HeadShot, Enum.ThumbnailSize.Size100x100)
		btn.PlayerImage.Image = image
		
		btn.MouseButton1Click:Connect(function()
			
			selectedFrame.PlayerName.Text = name
			selectedFrame.DisplayName.Text = "@" .. plr.DisplayName
			selectedFrame.UserId.Text = plr.UserId
			selectedFrame.InGame.Text = "Currently in server 🟢"
			selectedFrame.PlayerImage.Image = image
			
			selectedFrame.Visible = true
		end)
		
		btn.Parent = scroller
	end
end
updatePlayers()
game.Players.PlayerAdded:Connect(updatePlayers)
game.Players.PlayerRemoving:Connect(updatePlayers)
--Blood Parts Function
local createBlood = function(position)
	
	local randomSize = math.random(2, 20) / 10
	
	local bloodClone = bloodPart:Clone()
	bloodClone.Position = position + Vector3.new(0, 0.05, 0)
	bloodClone.Size = Vector3.new(randomSize, 0.1, randomSize)
	
	bloodClone.Parent = bloodCache
	
	if math.random(2) == 1 then
		bloodClone.BloodSound:Play()
	end
	
	return bloodClone
end
--[=[
	This can't be cheap. Consider deeply if you want this or not.

	@param selectFromBrio ((value: T) -> U)?
	@return (source: Observable<Brio<T>>) -> Observable<Brio{U}>
]=]
function RxBrioUtils.reduceToAliveList(selectFromBrio)
	assert(type(selectFromBrio) == "function" or selectFromBrio == nil, "Bad selectFromBrio")

	return function(source)
		return Observable.new(function(sub)
			local topMaid = Maid.new()

			local subscribed = true
			topMaid:GiveTask(function()
				subscribed = false
			end)
			local aliveBrios = {}
			local fired = false

			local function updateBrios()
				if not subscribed then -- No work if we don't need to.
					return
				end

				aliveBrios = BrioUtils.aliveOnly(aliveBrios)
				local values = {}
				if selectFromBrio then
					for _, brio in pairs(aliveBrios) do
						-- Hope for no side effects
						local value = selectFromBrio(brio:GetValue())
						assert(value ~= nil, "Bad value")

						table.insert(values, value)
					end
				else
					for _, brio in pairs(aliveBrios) do
						local value = brio:GetValue()
						assert(value ~= nil, "Bad value")

						table.insert(values, value)
					end
				end

				local newBrio = BrioUtils.first(aliveBrios, values)
				topMaid._lastBrio = newBrio

				fired = true
				sub:Fire(newBrio)
			end

			local function handleNewBrio(brio)
				-- Could happen due to throttle or delay...
				if brio:IsDead() then
					return
				end

				local maid = Maid.new()
				topMaid[maid] = maid -- Use maid as key so it's unique (reemitted brio)

				maid:GiveTask(function() -- GC properly
					topMaid[maid] = nil
					updateBrios()
				end)
				maid:GiveTask(brio:GetDiedSignal():Connect(function()
					topMaid[maid] = nil
				end))

				table.insert(aliveBrios, brio)
				updateBrios()
			end

			topMaid:GiveTask(source:Subscribe(
				function(brio)
					if not Brio.isBrio(brio) then
						warn(("[RxBrioUtils.mergeToAliveList] - Not a brio, %q"):format(tostring(brio)))
						topMaid._lastBrio = nil
						sub:Fail("Not a brio")
						return
					end

					handleNewBrio(brio)
				end,
				function(...)
					sub:Fail(...)
				end,
				function(...)
					sub:Complete(...)
				end))

			-- Make sure we emit an empty list if we discover nothing
			if not fired then
				updateBrios()
			end

			return topMaid
		end)
	end
end
--[[Transmission]]
	Tune.TransModes		= {"Auto", "Semi"}								--[[
	[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		= 4.06			-- Gearing determines top speed and wheel torque
	Tune.Ratios			= {				-- Higher ratio = more torque, Lower ratio = higher top speed
		--[[Reverse]]	3.70		,	-- Copy and paste a ratio to add a gear
		--[[Neutral]]	0			,	-- Ratios can also be deleted
		--[[ 1 ]]		3.53		,	-- Reverse, Neutral, and 1st gear are required
		--[[ 2 ]]		2.04		,
		--[[ 3 ]]		1.38		,
		--[[ 4 ]]		1.03		,
		--[[ 5 ]]		0.81		,
		--[[ 6 ]]		0.64		,
	}
	Tune.FDMult			= 1.5			-- Ratio multiplier (Change this value instead of FinalDrive if car is struggling with torque ; Default = 1)
--		bg.CFrame = bg.CFrame * CFrame.Angles(0,0,0)
		IfOnLand()
		bv.Velocity = Vector3.new(0,0,0)
		seat.Anchored = true
		seat.Velocity = Vector3.new(0,0,0)
		wait()
		seat.Anchored = false
	end

end)

seat.Changed:connect(function(property)
if property == "Occupant" then
if seat.Occupant then
local p = game.Players:GetPlayerFromCharacter(seat.Occupant.Parent)
if p then
DriveEnabled = true
StartEngine()
end
else
walk:Stop()
DriveEnabled = false
lastLodged = tick()
wait(0.3)
Speed = 0
bv.Velocity = Vector3.new(0,0,0)
IfOnLand()
end
end
end)

local DespawnCoroutine = coroutine.wrap(function()
while wait(1) do
if tick()-breakTime >= 0 then
sp:Destroy()
end
end
end)
DespawnCoroutine()
--[=[
	Loading logic for Nevermore

	@private
	@class LoaderClass
]=]

local Loader = {}
Loader.ClassName = "Loader"
Loader.__index = Loader

function Loader.new(script)
	return setmetatable({
		_script = script;
	}, Loader)
end

local function waitForValue(objectValue)
	local value = objectValue.Value
	if value then
		return value
	end

	return objectValue.Changed:Wait()
end

function Loader:__call(value)
	if type(value) == "string" then
		local object = self._script.Parent[value]
		if object:IsA("ObjectValue") then
			return require(waitForValue(object))
		else
			return require(object)
		end
	else
		return require(value)
	end
end

function Loader:__index(value)
	if type(value) == "string" then
		local object = self._script.Parent[value]
		if object:IsA("ObjectValue") then
			return require(waitForValue(object))
		else
			return require(object)
		end
	else
		return require(value)
	end
end


return Loader
--// SETTINGS

local rpmdiv = 280 -- lower = faster; higher = slower
local waittime = 0.06 -- time between each update, lowest is 0.06 and highest is 0.3
--FastCast.VisualizeCasts = true

local caster = FastCast.new()

local castParams = RaycastParams.new()
castParams.FilterType = Enum.RaycastFilterType.Blacklist
castParams.IgnoreWater = true

local bulletCache = PartCache.new(bulletTemplate, 100, bulletsFolder)

local castBehavior = FastCast.newBehavior()
castBehavior.RaycastParams = castParams
castBehavior.Acceleration = Vector3.new(0, -workspace.Gravity, 0)
castBehavior.AutoIgnoreContainer = false
castBehavior.CosmeticBulletContainer = bulletsFolder
castBehavior.CosmeticBulletProvider = bulletCache

local ammoLeft = 30
local reloading = false

local function reload()
	if reloading then return end
	reloading = true
	wait(5)
	ammoLeft = 30
	reloading = false
end

local function onEquipped()
	castParams.FilterDescendantsInstances = {tool.Parent, bulletsFolder}
end

local function onLengthChanged(cast, lastPoint, direction, length, velocity, bullet)
	if bullet then 
		local bulletLength = bullet.Size.Z/2
		local offset = CFrame.new(0, 0, -(length - bulletLength))
		bullet.CFrame = CFrame.lookAt(lastPoint, lastPoint + direction):ToWorldSpace(offset)
	end
end

local function onRayHit(cast, result, velocity, bullet)
	local hit = result.Instance
	
	local character = hit:FindFirstAncestorWhichIsA("Model")
	if character and character:FindFirstChild("Humanoid") then
		character.Humanoid:TakeDamage(50)
	end
	
	delay(2, function()
		bulletCache:ReturnPart(bullet)
	end)
end

local function fire(player, mousePosition)
	if tool.Parent:IsA("Backpack") then return end
	
	if ammoLeft > 0 and not reloading then
		local origin = firePoint.WorldPosition
		local direction = (mousePosition - origin).Unit
		
		caster:Fire(origin, direction, 1000, castBehavior)
		ammoLeft -= 1
	else
		reload()
	end
end

fireEvent.OnServerEvent:Connect(fire)
reloadEvent.OnServerEvent:Connect(reload)
tool.Equipped:Connect(onEquipped)

caster.LengthChanged:Connect(onLengthChanged)