Pinkstack/roblox-luau-corpus-text huggingface dataset:
--[=[
	@param object any -- Object to track
	@param cleanupMethod string? -- Optional cleanup name override
	@return object: any
	Adds an object to the trove. Once the trove is cleaned or
	destroyed, the object will also be cleaned up.

	The following types are accepted (e.g. `typeof(object)`):

	| Type | Cleanup |
	| ---- | ------- |
	| `Instance` | `object:Destroy()` |
	| `RBXScriptConnection` | `object:Disconnect()` |
	| `function` | `object()` |
	| `thread` | `coroutine.close(object)` |
	| `table` | `object:Destroy()` _or_ `object:Disconnect()` |
	| `table` with `cleanupMethod` | `object:<cleanupMethod>()` |

	Returns the object added.

	```lua
	-- Add a part to the trove, then destroy the trove,
	-- which will also destroy the part:
	local part = Instance.new("Part")
	trove:Add(part)
	trove:Destroy()

	-- Add a function to the trove:
	trove:Add(function()
		print("Cleanup!")
	end)
	trove:Destroy()

	-- Standard cleanup from table:
	local tbl = {}
	function tbl:Destroy()
		print("Cleanup")
	end
	trove:Add(tbl)

	-- Custom cleanup from table:
	local tbl = {}
	function tbl:DoSomething()
		print("Do something on cleanup")
	end
	trove:Add(tbl, "DoSomething")
	```
]=]


function Trove:Add(object: any, cleanupMethod: string?): any
	local cleanup = GetObjectCleanupFunction(object, cleanupMethod)
	table.insert(self._objects, {object, cleanup})
	return object
end
--[[
local dataStore = game:GetService("DataStoreService") -- gets the data store service
local data = dataStore:GetDataStore("Stats") -- makes a new data stored named "stats"


game.Players.PlayerAdded:Connect(function(plr) -- when a player joins the game

	local leaderstats = Instance.new("Folder") -- we make a leaderstats that will hold the visible stats of a player
	leaderstats.Name = "leaderstats"
	leaderstats.Parent = plr

	local Clicks = Instance.new("NumberValue") -- we make a stat named coins, you can name it whatever you want
	Clicks.Name = "Clicks"
	Clicks.Parent = leaderstats


	local Rebirths = Instance.new("NumberValue")  -- we make a second stat named xp, you can also name it whatever you want instead
	Rebirths.Name = "Rebirths"
	Rebirths.Parent = leaderstats


	local Gems = Instance.new("NumberValue")  -- we make a second stat named xp, you can also name it whatever you want instead
	Gems.Name = "Gems"
	Gems.Parent = leaderstats
	
	
	local Clicks
	local Rebirths
	local Gems



	Clicks = data:GetAsync(plr.UserId.."-Clicks") 
	-- ^^ we see if the the coin stat has been saved in the players key (their user ID) and we save coins in the "Coins" data key so we know we know we are saving coins

	Rebirths =  data:GetAsync(plr.UserId.."-Rebirths")-- same as the top except its with the xp stat
	
	Gems =  data:GetAsync(plr.UserId.."-Gems")-- same as the top except its with the xp stat
	

	if Clicks ~= nil then -- if the player has coins saved (more than 0)

		plr.leaderstats.Clicks.Value = Clicks

	end


	if Rebirths ~= nil then  -- if the player has xp saved (more than 0)

		plr.leaderstats.Rebirths.Value = Rebirths

	end


	if Gems ~= nil then  -- if the player has xp saved (more than 0)

		plr.leaderstats.Gems.Value = Gems

	end
end)

game.Players.PlayerRemoving:Connect(function(plr) -- when the players leave


	local sucess, errormsg = pcall(function() -- pcall function helps the script to contain the error if there is one instead of breaking the entire script


		data:SetAsync(plr.UserId.."-Clicks", plr.leaderstats.Clicks.Value) -- the players stats will be set to the players sync for coins

		data:SetAsync(plr.UserId.."-Rebirths", plr.leaderstats.Rebirths.Value) --  same thing but with the xp stat
		
		data:SetAsync(plr.UserId.."-Gems", plr.leaderstats.Gems.Value) --  same thing but with the xp stat
		

	end)

	if errormsg then -- if theres an error with the data store

		warn("error")
	end

end)

--]]
--- Creates a new spring
-- @param initial A number or Vector3 (anything with * number and addition/subtraction defined)
-- @param[opt=tick] clock function to use to update spring


function Spring.new(initial, clock)
	local target = initial or 0
	clock = clock or tick
	return setmetatable({
		_clock = clock;
		_time0 = clock();
		_position0 = target;
		_velocity0 = 0*target;
		_target = target;
		_damper = 1;
		_speed = 1;
	}, Spring)
end
--[[
	An implementation of Promises similar to Promise/A+.
]]



local ERROR_NON_PROMISE_IN_LIST = "Non-promise value passed into %s at index %s"
local ERROR_NON_LIST = "Please pass a list of promises to %s"
local ERROR_NON_FUNCTION = "Please pass a handler function to %s!"
local MODE_KEY_METATABLE = { __mode = "k" }

local function isCallable(value)
	if type(value) == "function" then
		return true
	end

	if type(value) == "table" then
		local metatable = getmetatable(value)
		if metatable and type(rawget(metatable, "__call")) == "function" then
			return true
		end
	end

	return false
end
--[=[
	@within Plasma
	@function portal
	@tag widgets
	@param targetInstance Instance -- Where the portal goes to
	@param children () -> () -- Children

	The portal widget creates its children inside the specified `targetInstance`. For example, you could use this
	to create lighting effects in Lighting as a widget:


	```lua
	return function(size)
		portal(Lighting, function()
			useInstance(function()
				local blur = Instance.new("BlurEffect")
				blur.Size = size
				return blur
			end)
		end)
	end
	```
]=]



local Runtime = require(script.Parent.Parent.Runtime)

return Runtime.widget(function(targetInstance, fn)
	Runtime.useInstance(function()
		return nil, targetInstance
	end)

	Runtime.scope(fn)
end)
--Starter Character Scripts


local MaxSpeed = 70
while true do
	wait()
	if script.Parent.Humanoid.MoveDirection == Vector3.new(0,0,0) then
		script.Parent.Humanoid.WalkSpeed = 1
	else
		script.Parent.Humanoid.WalkSpeed = script.Parent.Humanoid.WalkSpeed + .4
		if script.Parent.Humanoid.WalkSpeed >= MaxSpeed then
		script.Parent.Humanoid.WalkSpeed = MaxSpeed
		end
	end
end
--[=[
	@return Trove
	Creates and adds another trove to itself. This is just shorthand
	for `trove:Construct(Trove)`. This is useful for contexts where
	the trove object is present, but the class itself isn't.

	:::note
	This does _not_ clone the trove. In other words, the objects in the
	trove are not given to the new constructed trove. This is simply to
	construct a new Trove and add it as an object to track.
	:::

	```lua
	local trove = Trove.new()
	local subTrove = trove:Extend()

	trove:Clean() -- Cleans up the subTrove too
	```
]=]


function Trove:Extend()
	if self._cleaning then
		error("Cannot call trove:Extend() while cleaning", 2)
	end
	return self:Construct(Trove)
end
--[=[
	Throttles emission of observables.

	https://rxjs-dev.firebaseapp.com/api/operators/debounceTime

	:::note
	Note that on complete, the last item is not included, for now, unlike the existing version in rxjs.
	:::

	@param duration number
	@param throttleConfig { leading = true; trailing = true; }
	@return (source: Observable) -> Observable
]=]


function Rx.throttleTime(duration, throttleConfig)
	assert(type(duration) == "number", "Bad duration")
	assert(type(throttleConfig) == "table" or throttleConfig == nil, "Bad throttleConfig")

	return function(source)
		assert(Observable.isObservable(source), "Bad observable")

		return Observable.new(function(sub)
			local maid = Maid.new()

			local throttledFunction = ThrottledFunction.new(duration, function(...)
				sub:Fire(...)
			end, throttleConfig)

			maid:GiveTask(throttledFunction)
			maid:GiveTask(source:Subscribe(function(...)
				throttledFunction:Call(...)
			end, sub:GetFailComplete()))

			return maid
		end)
	end
end
--[[
		___      _______                _     
	   / _ |____/ ___/ /  ___ ____ ___ (_)__ 
	  / __ /___/ /__/ _ \/ _ `(_-<(_-</ (_-<
	 /_/ |_|   \___/_//_/\_,_/___/___/_/___/
 						SecondLogic @ Inspare
]]



local car = script.Parent.Car.Value
local vl = script.Parent.Values

local strength = 350

local max = 8 --in sps

while wait() do
	if (vl.Throttle.Value < 0.1 and vl.RPM.Value > 0 and vl.Velocity.Value.Magnitude < max and (math.abs(vl.Gear.Value) > 0)) and vl.Brake.Value == 0 then
		car.Body.Creep.BV.MaxForce = Vector3.new(strength,0,strength)
	else
		car.Body.Creep.BV.MaxForce = Vector3.new(0,0,0)
	end
	car.Body.Creep.BV.Velocity = car.Body.Creep.CFrame.lookVector*(8*(math.min(vl.Gear.Value,1)))
end
--[=[
	@function first
	@within Array

	@param array {T} -- The array to get the first item from.
	@return T -- The first item in the array.

	Gets the first item in the array.

	```lua
	local array = { 1, 2, 3 }

	local value = First(array) -- 1
	```
]=]


local function first<T>(array: { T }): T
	return At(array, 1)
end

return first
-------- OMG HAX



r = game:service("RunService")


local damage = 0 + (script.AddDam.Value/4)


local slash_damage = 0 + script.AddDam.Value


sword = script.Parent.Handle
Tool = script.Parent


local SlashSound = Instance.new("Sound")
SlashSound.SoundId = "http://www.roblox.com/asset/?id=10730819"
SlashSound.Parent = sword
SlashSound.Volume = 1


local UnsheathSound = Instance.new("Sound")
UnsheathSound.SoundId = "http://www.roblox.com/asset/?id=12722518"
UnsheathSound.Parent = sword
UnsheathSound.Volume = 1


function blow(hit)
	local humanoid = hit.Parent:findFirstChild("Humanoid")
	local vCharacter = Tool.Parent
	local vPlayer = game.Players:playerFromCharacter(vCharacter)
	local hum = vCharacter:findFirstChild("Immortal") -- non-nil if tool held by a character
	if humanoid~=nil and humanoid ~= hum and hum ~= nil then
		-- final check, make sure sword is in-hand

		local right_arm = vCharacter:FindFirstChild("Right Arm")
		if (right_arm ~= nil) then
			local joint = right_arm:FindFirstChild("RightGrip")
			if (joint ~= nil and (joint.Part0 == sword or joint.Part1 == sword)) then
				tagHumanoid(humanoid, vPlayer)
				humanoid:TakeDamage(damage)
				wait(1)
				untagHumanoid(humanoid)
			end
		end


	end
end


function tagHumanoid(humanoid, player)
	local creator_tag = Instance.new("ObjectValue")
	creator_tag.Value = player
	creator_tag.Name = "creator"
	creator_tag.Parent = humanoid
end

function untagHumanoid(humanoid)
	if humanoid ~= nil then
		local tag = humanoid:findFirstChild("creator")
		if tag ~= nil then
			tag.Parent = nil
		end
	end
end


function attack()
	damage = slash_damage
	SlashSound:play()
	local anim = Instance.new("StringValue")
	anim.Name = "toolanim"
	anim.Value = "Slash"
	anim.Parent = Tool
end


function swordUp()
	Tool.GripForward = Vector3.new(-1,0,0)
	Tool.GripRight = Vector3.new(0,1,0)
	Tool.GripUp = Vector3.new(0,0,1)
end

function swordOut()
	Tool.GripForward = Vector3.new(0,0,1)
	Tool.GripRight = Vector3.new(0,-1,0)
	Tool.GripUp = Vector3.new(-1,0,0)
end



Tool.Enabled = true

function onActivated()

	if not Tool.Enabled then
		return
	end

	Tool.Enabled = false

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

	

	attack()

	wait(1)

	Tool.Enabled = true
end


function onEquipped()
	UnsheathSound:play()
end


script.Parent.Activated:connect(onActivated)
script.Parent.Equipped:connect(onEquipped)


connection = sword.Touched:connect(blow)
--Miscellaneous Settings:


LEAVE_DISABLE	= true			--Turns off the engine when you leave the car
GEAR_SPEED		= 2.5			--Directly affects cam gear spin speed		(Arbitrary)
SHAKE_ANGLE		= 2.5			--Max angle of the engine shake in degrees
SHAKE_VALUE		= 1.0			--Intensity of the engine shake				(Arbitrary)
MH_THRESHOLD	= 6800			--RPM value in which manifold heats up
MH_COOLDOWN		= 2.5			--Manifold cool down rate
BELT_SPEED		= 5.0			--Speed of the belt							(Arbitrary)
BELT_TEXTURE	= 5503797483	--TextureID of belt in case you did not put it in the TextureID StringValue object
BELT_WIDTH		= 0.1			--Width of belt in case you did not put it in the BeltWidth StringValue object
TURBO_SPEED		= 1.0			--Directly affects turbo fan spin speed		(Arbitrary)
TURBO_BLUR		= true			--Turbo fan motion blur
-- Etc


local DESTROY_ON_DEATH = getValueFromConfig("DestroyOnDeath")
local RAGDOLL_ENABLED = getValueFromConfig("RagdollEnabled")

local DEATH_DESTROY_DELAY = 5
local PATROL_WALKSPEED = 0
local MIN_REPOSITION_TIME = 2
local MAX_REPOSITION_TIME = 10
local MAX_PARTS_PER_HEARTBEAT = 50
local SEARCH_DELAY = 1
--[[Weight and CG]]


	Tune.Weight			= 2963	-- Total weight (in pounds)
	Tune.WeightBSize	= {			-- Size of weight brick (dimmensions in studs ; larger = more stable)
	 --[[Width]]		6		,
	 --[[Height]]		4.4		,
	 --[[Length]]		15		}
	Tune.WeightDist		= 55		-- Weight distribution (0 - on rear wheels, 100 - on front wheels, can be <0 or >100)
	Tune.CGHeight		= 1.3		-- 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
-- find player's head pos



	local vCharacter = Tool.Parent
	local vPlayer = game.Players:playerFromCharacter(vCharacter)

	local head = vCharacter:findFirstChild("Head")
	if head == nil then return end

	local dir = mouse_pos - head.Position
	dir = computeDirection(dir)

	local launch = head.Position + 5 * dir

	local delta = mouse_pos - launch
	
	local dy = delta.y
	
	local new_delta = Vector3.new(delta.x, 0, delta.z)
	delta = new_delta

	local dx = delta.magnitude
	local unit_delta = delta.unit
	
	-- acceleration due to gravity in RBX units
	local g = (-9.81 * 20)

	local theta = computeLaunchAngle( dx, dy, g)

	local vy = math.sin(theta)
	local xz = math.cos(theta)
	local vx = unit_delta.x * xz
	local vz = unit_delta.z * xz
	

	local missile = Pellet:clone()
        

	Tool.Handle.Mesh:clone().Parent = missile
		

	missile.Position = launch
	missile.Velocity = Vector3.new(vx,vy,vz) * VELOCITY

	missile.PelletScript.Disabled = false

	local creator_tag = Instance.new("ObjectValue")
	creator_tag.Value = vCharacter
	creator_tag.Name = "creator"
	creator_tag.Parent = missile
	
	missile.Parent = game.Workspace

end


function computeLaunchAngle(dx,dy,grav)
	-- arcane
	-- http://en.wikipedia.org/wiki/Trajectory_of_a_projectile
	
	local g = math.abs(grav)
	local inRoot = (VELOCITY*VELOCITY*VELOCITY*VELOCITY) - (g * ((g*dx*dx) + (2*dy*VELOCITY*VELOCITY)))
	if inRoot <= 0 then
		return .25 * math.pi
	end
	local root = math.sqrt(inRoot)
	local inATan1 = ((VELOCITY*VELOCITY) + root) / (g*dx)

	local inATan2 = ((VELOCITY*VELOCITY) - root) / (g*dx)
	local answer1 = math.atan(inATan1)
	local answer2 = math.atan(inATan2)
	if answer1 < answer2 then return answer1 end
	return answer2
end

function computeDirection(vec)
	local lenSquared = vec.magnitude * vec.magnitude
	local invSqrt = 1 / math.sqrt(lenSquared)
	return Vector3.new(vec.x * invSqrt, vec.y * invSqrt, vec.z * invSqrt)
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
if loaded==true then
	loaded=false
	local targetPos = humanoid.TargetPoint

	fire(targetPos)
	wait(.2)
	Tool.Enabled = true
elseif loaded==false then
Tool.Parent.Torso["Right Shoulder"].MaxVelocity = 0.6
Tool.Parent.Torso["Right Shoulder"].DesiredAngle = -3.6
	wait(.1)
Tool.Handle.Transparency=0
wait(.1)
	loaded=true
	end
	Tool.Enabled = true
end

script.Parent.Activated:connect(onActivated)
--///////////////// Internal-Use Methods
--//////////////////////////////////////
--DO NOT REMOVE THIS. Chat must be filtered or your game will face
--moderation.


function methods:InternalApplyRobloxFilter(speakerName, message, toSpeakerName) --// USES FFLAG
	if (RunService:IsServer() and not RunService:IsStudio()) then
		local fromSpeaker = self:GetSpeaker(speakerName)
		local toSpeaker = toSpeakerName and self:GetSpeaker(toSpeakerName)

		if fromSpeaker == nil then
			return nil
		end

		local fromPlayerObj = fromSpeaker:GetPlayer()
		local toPlayerObj = toSpeaker and toSpeaker:GetPlayer()

		if fromPlayerObj == nil then
			return message
		end

		if allSpaces(message) then
			return message
		end

		local filterStartTime = tick()
		local filterRetries = 0
		while true do
			local success, message = pcall(function()
				if toPlayerObj then
					return Chat:FilterStringAsync(message, fromPlayerObj, toPlayerObj)
				else
					return Chat:FilterStringForBroadcast(message, fromPlayerObj)
				end
			end)
			if success then
				return message
			else
				warn("Error filtering message:", message)
			end
			filterRetries = filterRetries + 1
			if filterRetries > MAX_FILTER_RETRIES or (tick() - filterStartTime) > MAX_FILTER_DURATION then
				self:InternalNotifyFilterIssue()
				return nil
			end
			local backoffInterval = FILTER_BACKOFF_INTERVALS[math.min(#FILTER_BACKOFF_INTERVALS, filterRetries)]
			-- backoffWait = backoffInterval +/- (0 -> backoffInterval)
			local backoffWait = backoffInterval + ((math.random()*2 - 1) * backoffInterval)
			wait(backoffWait)
		end
	else
		--// Simulate filtering latency.
		--// There is only latency the first time the message is filtered, all following calls will be instant.
		if not StudioMessageFilteredCache[message] then
			StudioMessageFilteredCache[message] = true
			wait()
		end
		return message
	end

	return nil
end
-- LOCAL


local players = game:GetService("Players")
local runService = game:GetService("RunService")
local heartbeat = runService.Heartbeat
local localPlayer = runService:IsClient() and players.LocalPlayer
local replicatedStorage = game:GetService("ReplicatedStorage")
local httpService = game:GetService("HttpService")
local Enum_ = require(script.Enum)
local enum = Enum_.enums
local Janitor = require(script.Janitor)
local Signal = require(script.Signal)
local ZonePlusReference = require(script.ZonePlusReference)
local referenceObject = ZonePlusReference.getObject()
local zoneControllerModule = script.ZoneController
local trackerModule = zoneControllerModule.Tracker
local collectiveWorldModelModule = zoneControllerModule.CollectiveWorldModel
local ZoneController = require(zoneControllerModule)
local referenceLocation = (game:GetService("RunService"):IsClient() and "Client") or "Server"
local referencePresent = referenceObject and referenceObject:FindFirstChild(referenceLocation)
if referencePresent then
	return require(referenceObject.Value)
end

local Zone = {}
Zone.__index = Zone
if not referencePresent then
	ZonePlusReference.addToReplicatedStorage()
end
Zone.enum = enum
-- PopperCam mod



local Poppercam = require(popperCamModule)
local ZoomController = require(cameraModule:WaitForChild("ZoomController"))

function Poppercam:Update(renderDt, desiredCameraCFrame, desiredCameraFocus, cameraController)
	local rotatedFocus = desiredCameraFocus * (desiredCameraCFrame - desiredCameraCFrame.p)
	local extrapolation = self.focusExtrapolator:Step(renderDt, rotatedFocus)
	local zoom = ZoomController.Update(renderDt, rotatedFocus, extrapolation)
	return rotatedFocus*CFrame.new(0, 0, zoom), desiredCameraFocus
end
--[[
	A special key for property tables, which parents any given descendants into
	an instance.
]]



local Package = script.Parent.Parent
local PubTypes = require(Package.PubTypes)
local logWarn = require(Package.Logging.logWarn)
local Observer = require(Package.State.Observer)
local xtypeof = require(Package.Utility.xtypeof)

type Set<T> = {[T]: boolean}
--[=[
	Add a task to clean up. Tasks given to a maid will be cleaned when
	maid[index] is set to a different value.

	Task cleanup is such that if the task is an event, it is disconnected.
	If it is an object, it is destroyed.

	```
	Maid[key] = (function)         Adds a task to perform
	Maid[key] = (event connection) Manages an event connection
	Maid[key] = (thread)           Manages a thread
	Maid[key] = (Maid)             Maids can act as an event connection, allowing a Maid to have other maids to clean up.
	Maid[key] = (Object)           Maids can cleanup objects with a `Destroy` method
	Maid[key] = nil                Removes a named task.
	```

	@param index any
	@param newTask MaidTask
]=]


function Maid:__newindex(index, newTask)
	if Maid[index] ~= nil then
		error(("Cannot use '%s' as a Maid key"):format(tostring(index)), 2)
	end

	local tasks = self._tasks
	local oldTask = tasks[index]

	if oldTask == newTask then
		return
	end

	tasks[index] = newTask

	if oldTask then
		if type(oldTask) == "function" then
			oldTask()
		elseif type(oldTask) == "thread" then
			local cancelled
			if coroutine.running() ~= oldTask then
				cancelled = pcall(function()
					task.cancel(oldTask)
				end)
			end

			if not cancelled then
				task.defer(function()
					task.cancel(oldTask)
				end)
			end
		elseif typeof(oldTask) == "RBXScriptConnection" then
			oldTask:Disconnect()
		elseif oldTask.Destroy then
			oldTask:Destroy()
		end
	end
end
--[[
	
	CameraShakePresets.Bump
	CameraShakePresets.Explosion
	CameraShakePresets.Earthquake
	CameraShakePresets.BadTrip
	CameraShakePresets.HandheldCamera
	CameraShakePresets.Vibration
	CameraShakePresets.RoughDriving
	
--]]





local CameraShakeInstance = require(script.Parent.CameraShakeInstance)

local CameraShakePresets = {
	
	
	-- A high-magnitude, short, yet smooth shake.
	-- Should happen once.
	Bump = function()
		local c = CameraShakeInstance.new(2.5, 4, 0.1, 0.75)
		c.PositionInfluence = Vector3.new(0.15, 0.15, 0.15)
		c.RotationInfluence = Vector3.new(1, 1, 1)
		return c
	end;
	
	-- A high-magnitude, short, yet smooth shake.
	-- Should happen once.
	Knocked = function()
		local c = CameraShakeInstance.new(2.5, 8, 0.05, 0.75)
		c.PositionInfluence = Vector3.new(0.15, 0.15, 0.15)
		c.RotationInfluence = Vector3.new(1, 1, 1)
		return c
	end;
	
	
	-- An intense and rough shake.
	-- Should happen once.
	Explosion = function()
		local c = CameraShakeInstance.new(5, 10, 0, 1.5)
		c.PositionInfluence = Vector3.new(0.25, 0.25, 0.25)
		c.RotationInfluence = Vector3.new(4, 1, 1)
		return c
	end;
	
	
	-- A continuous, rough shake
	-- Sustained.
	Earthquake = function()
		local c = CameraShakeInstance.new(0.6, 3.5, 2, 10)
		c.PositionInfluence = Vector3.new(0.25, 0.25, 0.25)
		c.RotationInfluence = Vector3.new(1, 1, 4)
		return c
	end;
	
	
	-- A bizarre shake with a very high magnitude and low roughness.
	-- Sustained.
	BadTrip = function()
		local c = CameraShakeInstance.new(10, 0.15, 5, 10)
		c.PositionInfluence = Vector3.new(0, 0, 0.15)
		c.RotationInfluence = Vector3.new(2, 1, 4)
		return c
	end;
	
	
	-- A subtle, slow shake.
	-- Sustained.
	HandheldCamera = function()
		local c = CameraShakeInstance.new(1, 0.25, 5, 10)
		c.PositionInfluence = Vector3.new(0, 0, 0)
		c.RotationInfluence = Vector3.new(1, 0.5, 0.5)
		return c
	end;
	
	
	-- A very rough, yet low magnitude shake.
	-- Sustained.
	Vibration = function()
		local c = CameraShakeInstance.new(0.4, 20, 2, 2)
		c.PositionInfluence = Vector3.new(0, 0.15, 0)
		c.RotationInfluence = Vector3.new(1.25, 0, 4)
		return c
	end;
	
	
	-- A slightly rough, medium magnitude shake.
	-- Sustained.
	RoughDriving = function()
		local c = CameraShakeInstance.new(1, 2, 1, 1)
		c.PositionInfluence = Vector3.new(0, 0, 0)
		c.RotationInfluence = Vector3.new(1, 1, 1)
		return c
	end;
	
	
}


return setmetatable({}, {
	__index = function(t, i)
		local f = CameraShakePresets[i]
		if (type(f) == "function") then
			return f()
		end
		error("No preset found with index \"" .. i .. "\"")
	end;
})
-- Core events


ToolChanged = RbxUtility.CreateSignal();

function EquipTool(Tool)
	-- Equips and switches to the given tool

	-- Unequip current tool
	if CurrentTool and CurrentTool.Equipped then
		CurrentTool.Unequip();
		CurrentTool.Equipped = false;
	end;

	-- Set `Tool` as current
	CurrentTool = Tool;
	CurrentTool.Equipped = true;

	-- Fire relevant events
	ToolChanged:fire(Tool);

	-- Equip the tool
	Tool.Equip();

end;

function RecolorHandle(Color)
	SyncAPI:Invoke('RecolorHandle', Color);
end;