Pinkstack/roblox-luau-corpus-text huggingface dataset:
--[=[
	@class RemoteProperty
	@server
	Created via `ServerComm:CreateProperty()`.

	Values set can be anything that can pass through a
	[RemoteEvent](https://developer.roblox.com/en-us/articles/Remote-Functions-and-Events#parameter-limitations).

	Here is a cheat-sheet for the below methods:
	- Setting data
		- `Set`: Set "top" value for all current and future players. Overrides any custom-set data per player.
		- `SetTop`: Set the "top" value for all players, but does _not_ override any custom-set data per player.
		- `SetFor`: Set custom data for the given player. Overrides the "top" value. (_Can be nil_)
		- `SetForList`: Same as `SetFor`, but accepts a list of players.
		- `SetFilter`: Accepts a predicate function which checks for which players to set.
	- Clearing data
		- `ClearFor`: Clears the custom data set for a given player. Player will start using the "top" level value instead.
		- `ClearForList`: Same as `ClearFor`, but accepts a list of players.
		- `ClearFilter`: Accepts a predicate function which checks for which players to clear.
	- Getting data
		- `Get`: Retrieves the "top" value
		- `GetFor`: Gets the current value for the given player. If cleared, returns the top value.

	:::caution Network
	Calling any of the data setter methods (e.g. `Set()`) will
	fire the underlying RemoteEvent to replicate data to the
	clients. Therefore, setting data should only occur when it
	is necessary to change the data that the clients receive.
	:::

	:::caution Tables
	Tables _can_ be used with RemoteProperties. However, the
	RemoteProperty object will _not_ watch for changes within
	the table. Therefore, anytime changes are made to the table,
	the data must be set again using one of the setter methods.
	:::
]=]


local RemoteProperty = {}
RemoteProperty.__index = RemoteProperty

function RemoteProperty.new(
	parent: Instance,
	name: string,
	initialValue: any,
	inboundMiddleware: Types.ServerMiddleware?,
	outboundMiddleware: Types.ServerMiddleware?
)
	local self = setmetatable({}, RemoteProperty)
	self._rs = RemoteSignal.new(parent, name, inboundMiddleware, outboundMiddleware)
	self._value = initialValue
	self._perPlayer = {}
	self._playerRemoving = Players.PlayerRemoving:Connect(function(player)
		self._perPlayer[player] = nil
	end)
	self._rs:Connect(function(player)
		local playerValue = self._perPlayer[player]
		local value = if playerValue == nil then self._value elseif playerValue == None then nil else playerValue
		self._rs:Fire(player, value)
	end)
	return self
end
-- ROBLOX MOVED: expect/jasmineUtils.lua
-- Equality function lovingly adapted from isEqual in
--   [Underscore](http://underscorejs.org)


local function eq(
	a: any,
	b: any,
	aStack: Array<any>,
	bStack: Array<any>,
	customTesters: Array<Tester>,
	_hasKey: any
): boolean
	local result = true

	local asymmetricResult = asymmetricMatch(a, b)
	if asymmetricResult ~= nil then
		return asymmetricResult
	end

	for _, value in ipairs(customTesters) do
		local customTesterResult = value(a, b)
		if customTesterResult ~= nil then
			return customTesterResult
		end
	end

	-- ROBLOX deviation: code omitted because there are no error objects in Lua

	if Object.is(a, b) then
		return true
	end

	-- ROBLOX deviation: code omitted that does strict comparison because we don't
	-- have similar concerns in Lua where there are no distinct 'null' and
	-- 'undefined' types

	-- ROBLOX deviation: as part of the upstream className check, a type difference of
	-- array/non-array would be detected so we add this in manually
	local className = getType(a)
	if className ~= getType(b) then
		return false
	elseif Array.isArray(a) ~= Array.isArray(b) then
		return false
	end

	-- ROBLOX deviation: code omitted for elseif case with regular expressions since
	-- Lua doesn't have a built in regular expression type

	if className == "boolean" or className == "string" or className == "number" or className == "userdata" then
		return Object.is(a, b)
	elseif className == "DateTime" then
		return a == b
	elseif className == "regexp" then
		return tostring(a) == tostring(b)
	end

	if typeof(a) ~= "table" or typeof(b) ~= "table" then
		return false
	end

	-- DOM code omitted for now but translated here
	--[[
		if isDomNode(a) and isDomNode(b) then
		return a.isEqualNode(b)
		end
	--]]

	-- Used to detect circular references.
	local length = #aStack
	while length > 0 do
		-- Linear search. Performance is inversely proportional to the number of
		-- unique nested structures.
		-- circular references at same depth are equal
		-- circular reference is not equal to non-circular one
		if aStack[length] == a then
			return bStack[length] == b
		elseif bStack[length] == b then
			return false
		end

		length -= 1
	end

	-- Add the first object to the stack of traversed objects.
	table.insert(aStack, a)
	table.insert(bStack, b)

	-- Recursively compare objects and arrays.
	-- Compare array lengths to determine if a deep comparison is necessary.
	if Array.isArray(a) and #a ~= #b then
		return false
	end

	-- Deep compare objects
	local aKeys = keys(a, _hasKey)
	local size = #aKeys

	-- Ensure that both objects contain the same number of properties before comparing deep equality.
	if #keys(b, _hasKey) ~= size then
		return false
	end

	while size > 0 do
		local key = aKeys[size]

		-- Deep compare each member
		result = hasKey(b, key) and eq(a[key], b[key], aStack, bStack, customTesters, _hasKey)

		if not result then
			return false
		end

		size -= 1
	end

	-- Remove the first object from the stack of traversed objects.
	table.remove(aStack)
	table.remove(bStack)

	return result
end
-------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------



function onSwimming(speed)
	if speed > 1.00 then
		local scale = 10.0
		playAnimation("swim", 0.4, Humanoid)
		setAnimationSpeed(speed / scale)
		pose = "Swimming"
	else
		playAnimation("swimidle", 0.4, Humanoid)
		pose = "Standing"
	end
end

function animateTool()
	if toolAnim == "None" then
		playToolAnimation("toolnone", toolTransitionTime, Humanoid, Enum.AnimationPriority.Idle)
		return
	end

	if toolAnim == "Slash" then
		playToolAnimation("toolslash", 0, Humanoid, Enum.AnimationPriority.Action)
		return
	end

	if toolAnim == "Lunge" then
		playToolAnimation("toollunge", 0, Humanoid, Enum.AnimationPriority.Action)
		return
	end
end

function getToolAnim(tool)
	for _, c in ipairs(tool:GetChildren()) do
		if c.Name == "toolanim" and c.ClassName == "StringValue" then
			return c
		end
	end
	return nil
end

local lastTick = 0

function stepAnimate(currentTime)
	local amplitude = 1
	local frequency = 1
  	local deltaTime = currentTime - lastTick
  	lastTick = currentTime

	local climbFudge = 0
	local setAngles = false

  	if (jumpAnimTime > 0) then
  		jumpAnimTime = jumpAnimTime - deltaTime
  	end

	if (pose == "FreeFall" and jumpAnimTime <= 0) then
		playAnimation("fall", fallTransitionTime, Humanoid)
	elseif (pose == "Seated") then
		playAnimation("sit", 0.5, Humanoid)
		return
	elseif (pose == "Running") then
		playAnimation("walk", 0.2, Humanoid)
	elseif (pose == "Dead" or pose == "GettingUp" or pose == "FallingDown" or pose == "Seated" or pose == "PlatformStanding") then
		stopAllAnimations()
		amplitude = 0.1
		frequency = 1
		setAngles = true
	end

	-- Tool Animation handling
	local tool = Character:FindFirstChildOfClass("Tool")
	local requireHandleCheck = not UserSettings():IsUserFeatureEnabled("UserToolR15Fix")
	if tool and ((requireHandleCheck and tool.RequiresHandle) or tool:FindFirstChild("Handle")) then
		local animStringValueObject = getToolAnim(tool)

		if animStringValueObject then
			toolAnim = animStringValueObject.Value
			-- message recieved, delete StringValue
			animStringValueObject.Parent = nil
			toolAnimTime = currentTime + .3
		end

		if currentTime > toolAnimTime then
			toolAnimTime = 0
			toolAnim = "None"
		end

		animateTool()		
	else
		stopToolAnimations()
		toolAnim = "None"
		toolAnimInstance = nil
		toolAnimTime = 0
	end
end
--[[
    Client side script that requests a bomb throw if the player activates their tool outside of cooldown
]]


local Players = game:GetService("Players")

local localPlayer = Players.LocalPlayer
local mouse = localPlayer:GetMouse()

local tool = script.Parent
local fireEvent = tool:WaitForChild("Fire")
local cooldown = tool:WaitForChild("Cooldown").Value

local lastThrow = 0
tool.Activated:Connect(
	function()
		local nowTick = tick()
		if nowTick - lastThrow > cooldown then
			lastThrow = nowTick
			local character = localPlayer.Character
			if character and character.PrimaryPart then
				local origin = character.PrimaryPart.Position
				local target = mouse.Hit.p
				fireEvent:FireServer(origin, target)
			end
		end
	end
)
--!nocheck
-- ^ change to strict to crash studio c:



local oldtypeof = typeof
local function typeof(objIn: any): string
	local objType = oldtypeof(objIn)
	if objType ~= "table" then return objType end

	-- Could be a custom type if it's a table.
	local meta = getmetatable(objIn)
	if oldtypeof(meta) ~= "table" then return objType end

	-- Has a metatable that's an exposed table.
	local customType: string? = meta["__type"] -- I want to mandate that this is a string.
	if customType == nil then return objType end

	-- Has a type field
	return customType
end

return typeof
--Humanoid:SetStateEnabled(Enum.HumanoidStateType.Dead, false)



Rig.Character = Character
Rig.CreateFolders()
Rig.FindParts()
Rig.CreateAltRootMotor()
Rig.ScaleAltRootMotorOffset()
Rig.CreateConstraints()
Rig.BuildConstraintRig()
if Settings.CreateAccessoryConstraints == true then Rig.CreateAccessoryConstraints() end
Rig.CreateNoClipCollisionGroup()
Rig.TakeCareOfRootPartAndHead()
Rig.CreateCustomHeadCollisionBox()
Rig.CreateNoCollisionConstraints()

local Debris = game:GetService("Debris")
local IsRagdollNow = false

local CurrentCooldown = 0

function ragdoll(Mode,Velocity)
	if Mode == true then
		if IsRagdollNow then spawn(function() if Velocity then Functions_RemoteVelocity:InvokeClient(Player,Velocity) end end) return end
		IsRagdollNow = true
		CurrentCooldown = time()+Settings.UnRagdollCooldown
		Variables_Ragdoll.Value = true
		Rig.ToggleRagdollRig(true)
		Functions_RemoteRagdoll:InvokeClient(Player,true,Velocity)
	elseif Mode == "dead" then
		if Settings.CloneCharacterOnDeath then
			Player.CharacterRemoving:Connect(function()
				Character.Archivable = true
				Humanoid.AutomaticScalingEnabled = false
				local CharClone = Character:Clone()
				CharClone.Name = Player.Name.."'s Ragdoll"
				for _,v in pairs(CharClone:GetDescendants()) do
					if v:IsA("BaseScript") or v:IsA("Sound") then
						v:Destroy()
					end
				end
				Character:Destroy()
				CharClone.Parent = workspace
				Addons.KillHumanoid(CharClone.Humanoid)
				if Settings.AutoCleanup and Settings.AutoCleanupTime then
					Debris:AddItem(CharClone, Settings.AutoCleanupTime)
				end
				pcall(function()
					for _,v in pairs(CharClone:GetDescendants()) do
						if v:IsA("BasePart") then
							v:SetNetworkOwnershipAuto()
						end
					end
				end)
			end)
		end
	else
		if not IsRagdollNow then return end
		IsRagdollNow = false
		Variables_Ragdoll.Value = false
		Rig.ToggleRagdollRig(false)
		Functions_RemoteRagdoll:InvokeClient(Player,false)
	end
end

local HealthConnection
HealthConnection = Humanoid:GetPropertyChangedSignal("Health"):Connect(function()
	if Humanoid.Health <= 0 then
		
		HealthConnection:Disconnect()												--Preparing for death sequence
		pcall(function() Character.Health:Destroy() end)
		
		-- PLACE FOR CODE MEANT TO HAPPEN BEFORE ACTUALLY KILLING					--Executing code that needs to run before death to avoid bugs
		
		--Humanoid:SetStateEnabled(Enum.HumanoidStateType.Dead, true)				--Killing
		Addons.KillHumanoid(Humanoid)
		
		ragdoll(true)																--Ragdolling
		
		if Settings.BreakJointsOnDeath then Addons.DestroyMotors(Rig.Motors) end	--Breaking joints after ragdolling to ensure consistency with ragdolling normally
		
		ragdoll("dead")																--Executing post-mortem events
		
	end
end)

Variables_Ragdoll:GetPropertyChangedSignal("Value"):Connect(function()
	if Humanoid.Health > 0 then
		ragdoll(Variables_Ragdoll.Value)
	end
end)
--[=[
	Retrieves a global remote function from the store. On the server, it constructs a new one,
	and on the client, it waits for it to exist.

	:::tip
	Consider using [PromiseGetRemoteFunction] for a non-yielding version
	:::

	```lua
	-- server.lua
	local GetRemoteFunction = require("GetRemoteFunction")

	local remoteFunction = GetRemoteFunction("testing")
	remoteFunction.OnServerInvoke = function(_player, text)
		return "HI " .. tostring(text)
	end

	-- client.lua
	local GetRemoteFunction = require("GetRemoteFunction")

	local remoteFunction = GetRemoteFunction("testing")
	print(remoteFunction:InvokeServer("Bob")) --> HI Bob
	```

	:::info
	If the game is not running, then a mock remote function will be created
	for use in testing.
	:::

	@yields
	@function GetRemoteFunction
	@within GetRemoteFunction
	@param name string
	@return RemoteFunction
]=]



local require = require(script.Parent.loader).load(script)

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RunService = game:GetService("RunService")

local ResourceConstants = require("ResourceConstants")

if not RunService:IsRunning() then
	return function(name)
		local func = Instance.new("RemoteFunction")
		func.Name = "Mock" .. name
		func.Archivable = false

		return func
	end
elseif RunService:IsServer() then
	return function(name)
		assert(type(name) == "string", "Bad name")

		local storage = ReplicatedStorage:FindFirstChild(ResourceConstants.REMOTE_FUNCTION_STORAGE_NAME)
		if not storage then
			storage = Instance.new("Folder")
			storage.Name = ResourceConstants.REMOTE_FUNCTION_STORAGE_NAME
			storage.Archivable = false
			storage.Parent = ReplicatedStorage
		end

		local func = storage:FindFirstChild(name)
		if func then
			return func
		end

		func = Instance.new("RemoteFunction")
		func.Name = name
		func.Archivable = false
		func.Parent = storage

		return func
	end
else -- RunService:IsClient()
	return function(name)
		assert(type(name) == "string", "Bad name")

		return ReplicatedStorage:WaitForChild(ResourceConstants.REMOTE_FUNCTION_STORAGE_NAME):WaitForChild(name)
	end
end
--[[
	    ___      _______                _       _______
	   / _ |____/ ___/ /  ___ ____ ___ (_)__   /__  __/
	  / __ /___/ /__/ _ \/ _ `(_-<(_-</ (_-<     / /
	 /_/ |_|   \___/_//_/\_,_/___/___/_/___/	/_/   
						SecondLogic @ Inspare
						Avxnturador @ Novena
]]




local autoscaling	= true					--Estimates top speed

local UNITS	= {								--Click on speed to change units
											--First unit is default	
	{
		units			= "KM/H"			,
		scaling			= (10/12) * 1.09728	, -- 1 stud : 10 inches | ft/s to KP/H
		maxSpeed		= 370				,
		spInc			= 40				, -- Increment between labelled notches
	},

}
--[[
	Calls await and only returns if the Promise resolves.
	Throws if the Promise rejects or gets cancelled.
]]


function Promise.prototype:awaitValue(...)
	local length, result = pack(self:awaitStatus(...))
	local status = table.remove(result, 1)

	assert(
		status == Promise.Status.Resolved,
		tostring(result[1] == nil and "" or result[1])
	)

	return unpack(result, 1, length - 1)
end
-- Connect to the current and all future cameras


workspace.Changed:connect(OnWorkspaceChanged)
OnWorkspaceChanged('CurrentCamera')

Player.CharacterAdded:connect(OnCharacterAdded)
if Player.Character then
	OnCharacterAdded(Player.Character)
end

Behaviors[MODE.CUSTOM] = function() end -- (Does nothing until SetCustomBehavior)
Behaviors[MODE.LIMBS] = LimbBehavior
Behaviors[MODE.MOVEMENT] = MoveBehavior
Behaviors[MODE.CORNERS] = CornerBehavior
Behaviors[MODE.CIRCLE1] = CircleBehavior
Behaviors[MODE.CIRCLE2] = CircleBehavior
Behaviors[MODE.LIMBMOVE] = LimbMoveBehavior

Invisicam:SetMode(STARTING_MODE)

return Invisicam
-- Updating the healthbar


game:GetService("RunService").RenderStepped:Connect(function()
	local humanoid = char:FindFirstChild("Humanoid")
	healthbar.GreenFrame.Size = UDim2.new(humanoid.Health/humanoid.MaxHealth,0,1,0)
	healthbar.HealthStatus.Text = math.floor(humanoid.Health).."/"..humanoid.MaxHealth
end)
-- Preload animations


function playAnimation(animName, transitionTime, humanoid)
	local idleFromEmote = (animName == "idle" and emoteNames[currentAnim])
	if animName ~= currentAnim and not idleFromEmote then		 
		if currentAnimTrack then
			currentAnimTrack:Stop(transitionTime)
			currentAnimTrack:Destroy()
		end
		currentAnimSpeed = 1.0
		local roll = math.random(1, animTable[animName].totalWeight) 
		local origRoll = roll
		local idx = 1
		while (roll > animTable[animName][idx].weight) do
			roll = roll - animTable[animName][idx].weight
			idx = idx + 1
		end
--This script is used for when the bomb is in the dropped weapons model in the workspace :o 


local gundrops = game.Workspace:WaitForChild("Debris")
c4where = false
if game.Players.LocalPlayer.TeamColor == BrickColor.new("Bright yellow") then

	gundrops.ChildAdded:connect(function(newobj)
		if newobj.Name == "C4" then

			c4where = true
			script.BillboardGui.Adornee = newobj
			script.BillboardGui.TextLabel.Visible = true
		end
	end)
	gundrops.ChildRemoved:connect(function(oldobj)
		if oldobj.Name == "C4" then
			c4where = false
			script.BillboardGui.Adornee = nil
			script.BillboardGui.TextLabel.Visible = false
		end
	end)
end
--Fire the WaypointReached event


local function invokeWaypointReached(self)
	local lastWaypoint = self._waypoints[self._currentWaypoint - 1]
	local nextWaypoint = self._waypoints[self._currentWaypoint]
	self._events.WaypointReached:Fire(self._agent, lastWaypoint, nextWaypoint)
end

local function moveToFinished(self, reached)
	
	--Handle case for non-humanoids
	if not self._humanoid then
		if reached and self._currentWaypoint + 1 <= #self._waypoints then
			invokeWaypointReached(self)
			self._currentWaypoint += 1
		elseif reached then
			self._visualWaypoints = destroyVisualWaypoints(self._visualWaypoints)
			self._target = nil
			self._events.Reached:Fire(self._agent, self._waypoints[self._currentWaypoint])
		else
			self._visualWaypoints = destroyVisualWaypoints(self._visualWaypoints)
			self._target = nil
			declareError(self, self.ErrorType.TargetUnreachable)
		end
		return
	end
	
	if reached and self._currentWaypoint + 1 <= #self._waypoints  then --Waypoint reached
		invokeWaypointReached(self)
		self._currentWaypoint += 1
		move(self)
	elseif reached then --Target reached, pathfinding ends
		disconnectMoveConnection(self)
		self._status = Path.StatusType.Idle
		self._visualWaypoints = destroyVisualWaypoints(self._visualWaypoints)
		self._events.Reached:Fire(self._agent, self._waypoints[self._currentWaypoint])
	else --Target unreachable
		disconnectMoveConnection(self)
		self._status = Path.StatusType.Idle
		self._visualWaypoints = destroyVisualWaypoints(self._visualWaypoints)
		declareError(self, self.ErrorType.TargetUnreachable)
	end
end
-- Check if player is walking


local check_movement = function()
    if humanoid.WalkSpeed > 0 and humanoid.MoveDirection.Magnitude > 0 and humanoid.FloorMaterial ~= Enum.Material.Air then
        return true
    elseif humanoid.WalkSpeed <= 0 or humanoid.MoveDirection.Magnitude <= 0 or humanoid.FloorMaterial == Enum.Material.Air then
        return false
    end
end
-- damps a 3D rotation in Tait-Bryan YXZ space, filtering out Z


local YawPitchSpring = {} do
	YawPitchSpring.__index = YawPitchSpring

	function YawPitchSpring.new(cf)
		assert(typeof(cf) == "CFrame")
		
		return setmetatable({
			yawG = getYaw(cf), -- yaw goal
			yawP = getYaw(cf), -- yaw position
			yawV = 0, -- yaw velocity

			pitchG = getPitch(cf), -- pitch goal
			pitchP = getPitch(cf), -- pitch position
			pitchV = 0, -- pitch velocity

			-- yaw/pitch response springs
			fSpringYaw = VariableEdgeSpring.new(
				VehicleCameraConfig.yawReponseDampingRising,
				VehicleCameraConfig.yawResponseDampingFalling,
				0
			),
			fSpringPitch = VariableEdgeSpring.new(
				VehicleCameraConfig.pitchReponseDampingRising,
				VehicleCameraConfig.pitchResponseDampingFalling,
				0
			),
		}, YawPitchSpring)
	end
	
	-- Extract Tait-Bryan angles from a CFrame rotation
	function YawPitchSpring:setGoal(goalCFrame)
		assert(typeof(goalCFrame) == "CFrame")
		
		self.yawG = getYaw(goalCFrame)
		self.pitchG = getPitch(goalCFrame)
	end

	function YawPitchSpring:getCFrame()
		return CFrame.fromEulerAnglesYXZ(self.pitchP, self.yawP, 0)
	end

	function YawPitchSpring:step(dt, pitchVel, yawVel, firstPerson)
		assert(typeof(dt) == "number")
		assert(typeof(yawVel) == "number")
		assert(typeof(pitchVel) == "number")
		assert(typeof(firstPerson) == "number")
		
		local fSpringYaw = self.fSpringYaw
		local fSpringPitch = self.fSpringPitch
		
		-- calculate the frequency spring
		fSpringYaw.g = mapClamp(
			map(firstPerson, 0, 1, yawVel, 0),
			math.rad(VehicleCameraConfig.cutoffMinAngularVelYaw),
			math.rad(VehicleCameraConfig.cutoffMaxAngularVelYaw),
			1, 0
		)

		fSpringPitch.g = mapClamp(
			map(firstPerson, 0, 1, pitchVel, 0),
			math.rad(VehicleCameraConfig.cutoffMinAngularVelPitch),
			math.rad(VehicleCameraConfig.cutoffMaxAngularVelPitch),
			1, 0
		)
		
		-- calculate final frequencies
		local fYaw = 2*math.pi*VehicleCameraConfig.yawStiffness*fSpringYaw:step(dt)
		local fPitch = 2*math.pi*VehicleCameraConfig.pitchStiffness*fSpringPitch:step(dt)
		
		-- adjust response for first person
		fPitch *= map(firstPerson, 0, 1, 1, VehicleCameraConfig.firstPersonResponseMul)
		fYaw *= map(firstPerson, 0, 1, 1, VehicleCameraConfig.firstPersonResponseMul)
		
		-- step yaw
		self.yawP, self.yawV = stepSpringAxis(
			dt,
			fYaw,
			self.yawG,
			self.yawP,
			self.yawV
		)
		
		-- step pitch
		self.pitchP, self.pitchV = stepSpringAxis(
			dt,
			fPitch,
			self.pitchG,
			self.pitchP,
			self.pitchV
		)

		return self:getCFrame()
	end
end

local VehicleCameraCore = {} do
	VehicleCameraCore.__index = VehicleCameraCore

	function VehicleCameraCore.new(transform)
		return setmetatable({
			vrs = YawPitchSpring.new(transform)
		}, VehicleCameraCore)
	end

	function VehicleCameraCore:step(dt, pitchVel, yawVel, firstPerson)
		return self.vrs:step(dt, pitchVel, yawVel, firstPerson)
	end

	function VehicleCameraCore:setTransform(transform)
		self.vrs:setGoal(transform)
	end
end

return VehicleCameraCore
-- Etc


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

local DEATH_DESTROY_DELAY = 5
local PATROL_WALKSPEED = 12
local MIN_REPOSITION_TIME = 2
local MAX_REPOSITION_TIME = 10
local MAX_PARTS_PER_HEARTBEAT = 50
local ATTACK_STAND_TIME = 1
local HITBOX_SIZE = Vector3.new(5, 3, 5)
local SEARCH_DELAY = 1
local ATTACK_RANGE = 3
local ATTACK_DELAY = 1
local ATTACK_MIN_WALKSPEED = 14
local ATTACK_MAX_WALKSPEED = 18
--[[
	DataStore2: A wrapper for data stores that caches and saves Player's data.

	DataStore2(dataStoreName, Player) - Returns a DataStore2 DataStore

	DataStore2 DataStore:
	- Get([defaultValue])
	- Set(value)
	- Update(updateFunc)
	- Increment(value, defaultValue)
	- BeforeInitialGet(modifier)
	- BeforeSave(modifier)
	- Save()
	- SaveAsync()
	- OnUpdate(callback)
	- BindToClose(callback)

	local coinStore = DataStore2("Coins", Player)

	To give a Player coins:

	coinStore:Increment(50)

	To get the current Player's coins:

	coinStore:Get()
--]]



local RunService = game:GetService("RunService")
local ServerStorage = game:GetService("ServerStorage")

local Constants = require(script.Constants)
local IsPlayer = require(script.IsPlayer)
local Promise = require(script.Promise)
local SavingMethods = require(script.SavingMethods)
local Settings = require(script.Settings)
local TableUtil = require(script.TableUtil)
local Verifier = require(script.Verifier)

local SaveInStudioObject = ServerStorage:FindFirstChild("SaveInStudio")
local SaveInStudio = SaveInStudioObject and SaveInStudioObject.Value

local function clone(value)
	if typeof(value) == "table" then
		return TableUtil.clone(value)
	else
		return value
	end
end