Sha4kHub
Key Required

Sha4kHub

[🔥UPD] Tag MeAI_ScriptMakerAI_ScriptMaker 1.3K views 1.8K executesUpdated Sep 19, 2026
Unrated
00
Lua Script•7458 lines (81598 chars)
--============================================================
--                         Sha4kHub
--                    FULL COMBINED SCRIPT
--============================================================
--
-- TABS
--   Auto
--   ESP
--   Tag
--   Movement
--   Settings
--
-- INCLUDED
--   • Auto Vault
--   • Hard 1-second Auto Vault cooldown
--   • Vault re-arm system
--   • Auto Pallet Stun
--   • Ready/dropped pallet detection
--   • Dropped-pallet-only Auto Vault
--   • Auto Break
--   • Player ESP
--   • Chaser / Runner / Eliminated ESP colors
--   • Object ESP
--   • Pallet / SmallPallet
--   • Window / SmallWindow
--   • Vault1 / Vault2
--   • Custom RGB colors
--   • Custom ESP distance
--   • Player names / roles / health
--   • Auto Tag
--   • Tag Nearest Runner
--   • Runner target cycling
--   • Saved return position
--   • WalkSpeed
--   • Changeable GUI toggle key
--   • Hover sound
--   • Click sound
--   • Draggable GUI
--   • Floating GUI button
--   • UI scale
--   • Notifications
--
-- ROLE SYSTEM
--   StringValue named "Team"
--
--   Chaser     = Tagger
--   Runner     = Runner
--   Anything else = Eliminated
--
-- PALLET SYSTEM
--
--   A BasePart named exactly "Pallet" is checked.
--
--   READY:
--      Orientation ~= (-87.00299835205078, 0, 180)
--      actually uses a tiny tolerance around the values.
--
--   DROPPED:
--      Any orientation outside the ready orientation.
--
--   Auto Pallet Stun:
--      Runner + Chaser within 4 studs of pallet
--      + pallet still ready
--      = attempt pallet drop.
--
--   Auto Vault:
--      Vault1 / Vault2 can be vaulted normally.
--      Pallet can ONLY be vaulted if it is dropped.
--
--============================================================


--============================================================
-- SERVICES
--============================================================

local Players = game:GetService("Players")
local TweenService = game:GetService("TweenService")
local UserInputService = game:GetService("UserInputService")
local RunService = game:GetService("RunService")
local SoundService = game:GetService("SoundService")

local LocalPlayer = Players.LocalPlayer
local PlayerGui = LocalPlayer:WaitForChild("PlayerGui")


--============================================================
-- VIRTUAL INPUT
--============================================================

local VirtualInputManager

pcall(function()
	VirtualInputManager = game:GetService(
		"VirtualInputManager"
	)
end)


--============================================================
-- REMOVE OLD HUB
--============================================================

pcall(function()

	local old = PlayerGui:FindFirstChild(
		"Sha4kHub"
	)

	if old then
		old:Destroy()
	end

end)


--============================================================
-- CONFIG
--============================================================

local Config = {

	--========================================================
	-- GUI
	--========================================================

	ToggleKey = Enum.KeyCode.RightShift,

	UIAnimations = true,

	UIScale = 1,

	--========================================================
	-- SOUNDS
	--========================================================

	SoundsEnabled = true,

	HoverSounds = true,

	ClickSounds = true,

	SoundVolume = 0.4,

	HoverSoundId =
		"rbxassetid://5852470908",

	ClickSoundId =
		"rbxassetid://140207837688369",

	--========================================================
	-- AUTO
	--========================================================

	AutoVault = false,

	VaultDistance = 6,

	-- Hard minimum is 1 second.
	AutoVaultCooldown = 1,

	AutoBreak = false,

	BreakDistance = 6,

	AutoBreakCooldown = 0.25,

	--========================================================
	-- AUTO PALLET STUN
	--========================================================

	AutoPalletStun = false,

	PalletStunDistance = 4,

	PalletDropCooldown = 0.75,

	--========================================================
	-- MOVEMENT
	--========================================================

	WalkSpeedEnabled = false,

	WalkSpeed = 16,

	--========================================================
	-- PLAYER ESP
	--========================================================

	PlayerESP = true,

	PlayerESPDistance = 500,

	ShowPlayerNames = true,

	ShowPlayerRoles = true,

	ShowPlayerHealth = true,

	ChaserColor =
		Color3.fromRGB(
			255,
			80,
			80
		),

	RunnerColor =
		Color3.fromRGB(
			80,
			170,
			255
		),

	EliminatedColor =
		Color3.fromRGB(
			135,
			135,
			135
		),

	--========================================================
	-- OBJECT ESP
	--========================================================

	ObjectESP = true,

	ShowObjectNames = true,

	ObjectFillTransparency = 0.65,

	ObjectOutlineTransparency = 0,

	--========================================================
	-- TAGGING
	--========================================================

	AutoTag = false,

	TagDistance = 100,

	TagInterval = 0.25,

	ReturnAfterTag = true,

	--========================================================
	-- QOL
	--========================================================

	NotifyRoleChanges = true,

	NotifyAutomation = true,
}


--============================================================
-- OBJECT SETTINGS
--============================================================

local ObjectSettings = {

	Pallet = {

		Enabled = true,

		Color =
			Color3.fromRGB(
				255,
				180,
				60
			),

		Distance = 150,
	},

	SmallPallet = {

		Enabled = true,

		Color =
			Color3.fromRGB(
				255,
				120,
				40
			),

		Distance = 150,
	},

	Window = {

		Enabled = true,

		Color =
			Color3.fromRGB(
				80,
				200,
				255
			),

		Distance = 150,
	},

	SmallWindow = {

		Enabled = true,

		Color =
			Color3.fromRGB(
				80,
				255,
				180
			),

		Distance = 150,
	},

	Vault1 = {

		Enabled = true,

		Color =
			Color3.fromRGB(
				161,
				157,
				184
			),

		Distance = 100,
	},

	Vault2 = {

		Enabled = true,

		Color =
			Color3.fromRGB(
				210,
				160,
				255
			),

		Distance = 100,
	},
}


--============================================================
-- CUSTOM ESP
--============================================================

local CustomObjects = {}


--============================================================
-- CHARACTER
--============================================================

local Character
local Humanoid
local RootPart


local function RefreshCharacter()

	Character =
		LocalPlayer.Character
		or LocalPlayer.CharacterAdded:Wait()

	Humanoid =
		Character:WaitForChild(
			"Humanoid"
		)

	RootPart =
		Character:WaitForChild(
			"HumanoidRootPart"
		)
end


RefreshCharacter()


LocalPlayer.CharacterAdded:Connect(
	function()

		task.wait(0.4)

		RefreshCharacter()
	end
)


--============================================================
-- ROLE SYSTEM
--============================================================

local function GetRole(player)

	player =
		player or LocalPlayer


	local teamValue =
		player:FindFirstChild(
			"Team"
		)


	if teamValue
		and teamValue:IsA(
			"StringValue"
		) then

		if teamValue.Value ==
			"Chaser" then

			return "Chaser"
		end


		if teamValue.Value ==
			"Runner" then

			return "Runner"
		end


		return "Eliminated"
	end


	return "Eliminated"
end


local function IsChaser()

	return GetRole() == "Chaser"
end


local function IsRunner()

	return GetRole() == "Runner"
end


--============================================================
-- SOUNDS
--============================================================

local HoverSound =
	Instance.new(
		"Sound"
	)

HoverSound.Name =
	"Sha4kHubHover"

HoverSound.SoundId =
	Config.HoverSoundId

HoverSound.Volume =
	Config.SoundVolume

HoverSound.Parent =
	SoundService


local ClickSound =
	Instance.new(
		"Sound"
	)

ClickSound.Name =
	"Sha4kHubClick"

ClickSound.SoundId =
	Config.ClickSoundId

ClickSound.Volume =
	Config.SoundVolume

ClickSound.Parent =
	SoundService


local function PlayHover()

	if not Config.SoundsEnabled then
		return
	end

	if not Config.HoverSounds then
		return
	end


	HoverSound.Volume =
		Config.SoundVolume

	HoverSound:Stop()

	HoverSound:Play()
end


local function PlayClick()

	if not Config.SoundsEnabled then
		return
	end

	if not Config.ClickSounds then
		return
	end


	ClickSound.Volume =
		Config.SoundVolume

	ClickSound:Stop()

	ClickSound:Play()
end


--============================================================
-- SPACE INPUT
--============================================================

local function PressSpace()

	if VirtualInputManager then

		local success =
			pcall(function()

				VirtualInputManager:SendKeyEvent(
					true,
					Enum.KeyCode.Space,
					false,
					game
				)

				task.wait(0.025)

				VirtualInputManager:SendKeyEvent(
					false,
					Enum.KeyCode.Space,
					false,
					game
				)

			end)


		if success then
			return
		end
	end


	if Humanoid then
		Humanoid.Jump = true
	end
end


--============================================================
-- GENERAL POSITION HELPERS
--============================================================

local function GetPosition(object)

	if not object then
		return nil
	end


	if object:IsA(
		"BasePart"
	) then

		return object.Position
	end


	if object:IsA(
		"Model"
	) then

		if object.PrimaryPart then
			return object.PrimaryPart.Position
		end


		local part =
			object:FindFirstChildWhichIsA(
				"BasePart",
				true
			)


		if part then
			return part.Position
		end
	end


	return nil
end


local function GetDistance(object)

	if not RootPart then
		return math.huge
	end


	local position =
		GetPosition(
			object
		)


	if not position then
		return math.huge
	end


	return (
		RootPart.Position -
		position
	).Magnitude
end


--============================================================
-- PALLET ORIENTATION SYSTEM
--============================================================

local READY_PALLET_X =
	-87.00299835205078

local READY_PALLET_Y =
	0

local READY_PALLET_Z =
	180


-- Tiny allowance for floating point / physics changes.
local PALLET_ANGLE_TOLERANCE =
	0.15


local function IsPalletReady(
	pallet
)

	if not pallet then
		return false
	end


	if not pallet:IsA(
		"BasePart"
	) then

		return false
	end


	local orientation =
		pallet.Orientation


	local xReady =
		math.abs(
			orientation.X -
			READY_PALLET_X
		)
		<= PALLET_ANGLE_TOLERANCE


	local yReady =
		math.abs(
			orientation.Y -
			READY_PALLET_Y
		)
		<= PALLET_ANGLE_TOLERANCE


	local zReady =
		math.abs(
			orientation.Z -
			READY_PALLET_Z
		)
		<= PALLET_ANGLE_TOLERANCE


	return
		xReady
		and yReady
		and zReady
end


local function IsPalletDropped(
	pallet
)

	if not pallet then
		return false
	end


	if not pallet:IsA(
		"BasePart"
	) then

		return false
	end


	return not IsPalletReady(
		pallet
	)
end


--============================================================
-- FIND CHASER NEAR POSITION
--============================================================

local function FindNearbyChaser(
	position,
	maxDistance
)

	local nearest
	local nearestDistance =
		maxDistance


	for _, player in ipairs(
		Players:GetPlayers()
	) do

		if player ~= LocalPlayer
			and GetRole(player) ==
			"Chaser" then

			local character =
				player.Character


			if character then

				local root =
					character:FindFirstChild(
						"HumanoidRootPart"
					)


				if root then

					local distance =
						(
							root.Position -
							position
						).Magnitude


					if distance <=
						nearestDistance then

						nearest =
							player

						nearestDistance =
							distance
					end
				end
			end
		end
	end


	return nearest,
		nearestDistance
end


--============================================================
-- FIND READY PALLET WITH CHASER CLOSE
--============================================================

local function FindNearbyReadyPallet()

	local nearestPallet
	local nearestChaser
	local nearestDistance =
		Config.PalletStunDistance


	for _, object in ipairs(
		workspace:GetDescendants()
	) do

		-- Part / MeshPart / UnionOperation etc.
		-- all inherit BasePart.
		if object:IsA(
			"BasePart"
		)
		and object.Name ==
			"Pallet" then

			if IsPalletReady(
				object
			) then

				local chaser,
					chaserDistance =
					FindNearbyChaser(
						object.Position,
						Config.PalletStunDistance
					)


				if chaser
					and chaserDistance <=
					nearestDistance then

					nearestPallet =
						object

					nearestChaser =
						chaser

					nearestDistance =
						chaserDistance
				end
			end
		end
	end


	return nearestPallet,
		nearestChaser,
		nearestDistance
end


--============================================================
-- PALLET DROP
--============================================================

local LastPalletDropTimes = {}


local function AttemptDropPallet(
	pallet
)

	if not pallet then
		return false
	end


	if not pallet.Parent then
		return false
	end


	-- Never attempt to drop an already
	-- dropped pallet.
	if not IsPalletReady(
		pallet
	) then

		return false
	end


	local now =
		os.clock()


	local lastTime =
		LastPalletDropTimes[pallet]
		or 0


	if now - lastTime <
		Config.PalletDropCooldown then

		return false
	end


	LastPalletDropTimes[pallet] =
		now


	--========================================================
	-- PROXIMITY PROMPT
	--========================================================

	local prompt =
		pallet:FindFirstChildWhichIsA(
			"ProximityPrompt",
			true
		)


	if prompt then

		local used =
			false


		-- Some supported environments expose
		-- fireproximityprompt to LocalScripts.
		pcall(function()

			if fireproximityprompt then

				fireproximityprompt(
					prompt
				)

				used =
					true
			end

		end)


		if used then
			return true
		end
	end


	--========================================================
	-- CLICK DETECTOR
	--========================================================

	local clickDetector =
		pallet:FindFirstChildWhichIsA(
			"ClickDetector",
			true
		)


	if clickDetector then

		local used =
			false


		pcall(function()

			if fireclickdetector then

				fireclickdetector(
					clickDetector
				)

				used =
					true
			end

		end)


		if used then
			return true
		end
	end


	return false
end


--============================================================
-- AUTO PALLET STUN
--============================================================

local function TryAutoPalletStun()

	if not Config.AutoPalletStun then
		return
	end


	-- The local player should be the Runner
	-- who is dropping the pallet.
	if not IsRunner() then
		return
	end


	local pallet,
		chaser =
		FindNearbyReadyPallet()


	if not pallet
		or not chaser then

		return
	end


	-- One final check before interacting.
	if not IsPalletReady(
		pallet
	) then

		return
	end


	local dropped =
		AttemptDropPallet(
			pallet
		)


	if dropped then

		-- Allow physics/game logic a moment
		-- to change the orientation.
		task.delay(
			0.1,

			function()

				if pallet
					and pallet.Parent
					and IsPalletDropped(
						pallet
					) then

					if Config.NotifyAutomation then

						Notify(
							"Pallet dropped!"
						)
					end
				end
			end
		)
	end
end


--============================================================
-- ESP STORAGE
--============================================================

local ESPWorldFolder =
	Instance.new(
		"Folder"
	)

ESPWorldFolder.Name =
	"Sha4kHubESP"

ESPWorldFolder.Parent =
	workspace


local ESPBillboardFolder =
	Instance.new(
		"Folder"
	)

ESPBillboardFolder.Name =
	"Sha4kHubESP"

ESPBillboardFolder.Parent =
	PlayerGui


local ObjectESPObjects = {}

local PlayerESPObjects = {}


--============================================================
-- REMOVE OBJECT ESP
--============================================================

local function RemoveObjectESP(
	object
)

	local data =
		ObjectESPObjects[
			object
		]


	if not data then
		return
	end


	if data.Highlight then
		data.Highlight:Destroy()
	end


	if data.Billboard then
		data.Billboard:Destroy()
	end


	ObjectESPObjects[
		object
	] = nil
end


--============================================================
-- CREATE OBJECT ESP
--============================================================

local function CreateObjectESP(
	object,
	settings
)

	if not object
		or not object:IsDescendantOf(
			workspace
		) then

		return
	end


	if ObjectESPObjects[
		object
	] then

		return
	end


	local highlight =
		Instance.new(
			"Highlight"
		)


	highlight.Name =
		"Sha4kObjectESP"


	highlight.Adornee =
		object


	highlight.FillColor =
		settings.Color


	highlight.OutlineColor =
		settings.Color


	highlight.FillTransparency =
		Config.ObjectFillTransparency


	highlight.OutlineTransparency =
		Config.ObjectOutlineTransparency


	highlight.DepthMode =
		Enum.HighlightDepthMode.AlwaysOnTop


	highlight.Parent =
		ESPWorldFolder


	local billboard


	if Config.ShowObjectNames then

		local part


		if object:IsA(
			"BasePart"
		) then

			part =
				object

		elseif object:IsA(
			"Model"
		) then

			part =
				object.PrimaryPart
				or object:FindFirstChildWhichIsA(
					"BasePart",
					true
				)
		end


		if part then

			billboard =
				Instance.new(
					"BillboardGui"
				)


			billboard.Name =
				"Sha4kObjectName"


			billboard.Adornee =
				part


			billboard.Size =
				UDim2.fromOffset(
					170,
					26
				)


			billboard.StudsOffset =
				Vector3.new(
					0,
					2.5,
					0
				)


			billboard.AlwaysOnTop =
				true


			billboard.Parent =
				ESPBillboardFolder


			local label =
				Instance.new(
					"TextLabel"
				)


			label.Size =
				UDim2.fromScale(
					1,
					1
				)


			label.BackgroundTransparency =
				1


			label.Font =
				Enum.Font.GothamBold


			label.TextSize =
				12


			label.TextColor3 =
				settings.Color


			label.TextStrokeTransparency =
				0.35


			label.Text =
				object.Name


			label.Parent =
				billboard
		end
	end


	ObjectESPObjects[
		object
	] = {

		Highlight =
			highlight,

		Billboard =
			billboard,
	}
end


--============================================================
-- UPDATE OBJECT ESP
--============================================================

local function UpdateObjectESP(
	object
)

	if not object
		or not object:IsDescendantOf(
			workspace
		) then

		RemoveObjectESP(
			object
		)

		return
	end


	local settings =
		ObjectSettings[
			object.Name
		]
		or
		CustomObjects[
			object.Name
		]


	if not Config.ObjectESP
		or not settings
		or not settings.Enabled then

		RemoveObjectESP(
			object
		)

		return
	end


	local distance =
		GetDistance(
			object
		)


	if distance >
		settings.Distance then

		local data =
			ObjectESPObjects[
				object
			]


		if data then

			data.Highlight.Enabled =
				false


			if data.Billboard then

				data.Billboard.Enabled =
					false
			end
		end


		return
	end


	if not ObjectESPObjects[
		object
	] then

		CreateObjectESP(
			object,
			settings
		)
	end


	local data =
		ObjectESPObjects[
			object
		]


	if not data then
		return
	end


	data.Highlight.Enabled =
		true


	data.Highlight.FillColor =
		settings.Color


	data.Highlight.OutlineColor =
		settings.Color


	data.Highlight.FillTransparency =
		Config.ObjectFillTransparency


	data.Highlight.OutlineTransparency =
		Config.ObjectOutlineTransparency


	if data.Billboard then

		data.Billboard.Enabled =
			Config.ShowObjectNames


		local label =
			data.Billboard:FindFirstChildOfClass(
				"TextLabel"
			)


		if label then
			label.TextColor3 =
				settings.Color
		end
	end
end


--============================================================
-- PLAYER ESP COLOR
--============================================================

local function GetPlayerColor(
	player
)

	local role =
		GetRole(
			player
		)


	if role ==
		"Chaser" then

		return Config.ChaserColor


	elseif role ==
		"Runner" then

		return Config.RunnerColor


	else

		return Config.EliminatedColor
	end
end


--============================================================
-- REMOVE PLAYER ESP
--============================================================

local function RemovePlayerESP(
	player
)

	local data =
		PlayerESPObjects[
			player
		]


	if not data then
		return
	end


	if data.Highlight then
		data.Highlight:Destroy()
	end


	if data.Billboard then
		data.Billboard:Destroy()
	end


	PlayerESPObjects[
		player
	] = nil
end


--============================================================
-- CREATE PLAYER ESP
--============================================================

local function CreatePlayerESP(
	player
)

	if player ==
		LocalPlayer then

		return
	end


	local character =
		player.Character


	if not character then
		return
	end


	local root =
		character:FindFirstChild(
			"HumanoidRootPart"
		)


	if not root then
		return
	end


	RemovePlayerESP(
		player
	)


	local color =
		GetPlayerColor(
			player
		)


	local highlight =
		Instance.new(
			"Highlight"
		)


	highlight.Name =
		"Sha4kPlayerESP"


	highlight.Adornee =
		character


	highlight.FillColor =
		color


	highlight.OutlineColor =
		color


	highlight.FillTransparency =
		Config.ObjectFillTransparency


	highlight.OutlineTransparency =
		Config.ObjectOutlineTransparency


	highlight.DepthMode =
		Enum.HighlightDepthMode.AlwaysOnTop


	highlight.Parent =
		ESPWorldFolder


	local billboard =
		Instance.new(
			"BillboardGui"
		)


	billboard.Name =
		"Sha4kPlayerInfo"


	billboard.Adornee =
		root


	billboard.Size =
		UDim2.fromOffset(
			190,
			65
		)


	billboard.StudsOffset =
		Vector3.new(
			0,
			3.5,
			0
		)


	billboard.AlwaysOnTop =
		true


	billboard.Parent =
		ESPBillboardFolder


	local label =
		Instance.new(
			"TextLabel"
		)


	label.Size =
		UDim2.fromScale(
			1,
			1
		)


	label.BackgroundTransparency =
		1


	label.Font =
		Enum.Font.GothamBold


	label.TextSize =
		12


	label.TextColor3 =
		color


	label.TextStrokeTransparency =
		0.35


	label.TextWrapped =
		true


	label.Parent =
		billboard


	PlayerESPObjects[
		player
	] = {

		Highlight =
			highlight,

		Billboard =
			billboard,

		Label =
			label,
	}
end


--============================================================
-- UPDATE PLAYER ESP
--============================================================

local function UpdatePlayerESP(
	player
)

	if player ==
		LocalPlayer then

		return
	end


	if not Config.PlayerESP then

		RemovePlayerESP(
			player
		)

		return
	end


	local character =
		player.Character


	if not character then

		RemovePlayerESP(
			player
		)

		return
	end


	local root =
		character:FindFirstChild(
			"HumanoidRootPart"
		)


	if not root then

		RemovePlayerESP(
			player
		)

		return
	end


	local distance =
		GetDistance(
			character
		)


	if distance >
		Config.PlayerESPDistance then

		local data =
			PlayerESPObjects[
				player
			]


		if data then

			data.Highlight.Enabled =
				false

			data.Billboard.Enabled =
				false
		end


		return
	end


	if not PlayerESPObjects[
		player
	] then

		CreatePlayerESP(
			player
		)
	end


	local data =
		PlayerESPObjects[
			player
		]


	if not data then
		return
	end


	local role =
		GetRole(
			player
		)


	local color =
		GetPlayerColor(
			player
		)


	data.Highlight.Enabled =
		true


	data.Billboard.Enabled =
		true


	data.Highlight.FillColor =
		color


	data.Highlight.OutlineColor =
		color


	data.Highlight.FillTransparency =
		Config.ObjectFillTransparency


	data.Highlight.OutlineTransparency =
		Config.ObjectOutlineTransparency


	local lines = {}


	if Config.ShowPlayerNames then

		table.insert(
			lines,
			player.DisplayName
		)
	end


	if Config.ShowPlayerRoles then

		table.insert(
			lines,
			"[" ..
			role ..
			"]"
		)
	end


	if Config.ShowPlayerHealth then

		local humanoid =
			character:FindFirstChildOfClass(
				"Humanoid"
			)


		if humanoid then

			table.insert(
				lines,

				string.format(
					"HP: %d/%d",

					math.floor(
						humanoid.Health
					),

					math.floor(
						humanoid.MaxHealth
					)
				)
			)
		end
	end


	data.Label.Text =
		table.concat(
			lines,
			"\n"
		)


	data.Label.TextColor3 =
		color
end


--============================================================
-- CUSTOM ESP
--============================================================

local function AddCustomESP(
	name,
	color,
	distance
)

	if typeof(name) ~=
		"string"
		or name == "" then

		return false
	end


	CustomObjects[
		name
	] = {

		Enabled =
			true,

		Color =
			color
			or Color3.new(
				1,
				1,
				1
			),

		Distance =
			distance
			or 150,
	}


	return true
end


--============================================================
-- FIND NEAREST OBJECT
--============================================================

local function FindNearestObject(
	names,
	maxDistance
)

	local nearest
	local nearestDistance =
		maxDistance


	for _, object in ipairs(
		workspace:GetDescendants()
	) do

		if names[
			object.Name
		] then

			local distance =
				GetDistance(
					object
				)


			if distance <=
				nearestDistance then

				nearest =
					object

				nearestDistance =
					distance
			end
		end
	end


	return nearest,
		nearestDistance
end


--============================================================
-- AUTOMATION: VAULT
--============================================================

local VaultNames = {

	Vault1 = true,

	Vault2 = true,
}


local LastVaultTime = 0

local VaultLockedObject = nil

local VaultRearmDistance = 2


local function FindNearestVaultableObject(
	maxDistance
)

	local nearest
	local nearestDistance =
		maxDistance


	--========================================================
	-- VAULT1 / VAULT2
	--========================================================

	for _, object in ipairs(
		workspace:GetDescendants()
	) do

		if VaultNames[
			object.Name
		] then

			local distance =
				GetDistance(
					object
				)


			if distance <=
				nearestDistance then

				nearest =
					object

				nearestDistance =
					distance
			end
		end
	end


	--========================================================
	-- DROPPED PALLETS ONLY
	--========================================================

	for _, object in ipairs(
		workspace:GetDescendants()
	) do

		if object:IsA(
			"BasePart"
		)
		and object.Name ==
			"Pallet" then

			-- This is the important rule:
			-- upright/ready pallets are NEVER
			-- considered vaultable.
			if IsPalletDropped(
				object
			) then

				local distance =
					GetDistance(
						object
					)


				if distance <=
					nearestDistance then

					nearest =
						object

					nearestDistance =
						distance
				end
			end
		end
	end


	return nearest
end


local function TryAutoVault()

	if not Config.AutoVault then
		return
	end


	if not Character
		or not RootPart
		or not Humanoid then

		return
	end


	local now =
		os.clock()


	--========================================================
	-- HARD 1-SECOND COOLDOWN
	--========================================================

	if now -
		LastVaultTime <
		Config.AutoVaultCooldown then

		return
	end


	--========================================================
	-- SAME-OBJECT REARM
	--========================================================
	--
	-- Once a vault is activated, the script will
	-- not activate that exact object again until
	-- the player has moved away from it.
	--
	-- This prevents:
	-- SPACE -> vault -> SPACE -> vault -> ...
	--
	--========================================================

	if VaultLockedObject then

		if not VaultLockedObject:IsDescendantOf(
			workspace
		) then

			VaultLockedObject =
				nil

		else

			local distance =
				GetDistance(
					VaultLockedObject
				)


			if distance >
				Config.VaultDistance
				+ VaultRearmDistance then

				VaultLockedObject =
					nil

			else

				return
			end
		end
	end


	--========================================================
	-- FIND VAULTABLE OBJECT
	--========================================================

	local vault =
		FindNearestVaultableObject(
			Config.VaultDistance
		)


	if not vault then
		return
	end


	-- Extra safety:
	-- a pallet must still be dropped
	-- immediately before vaulting.
	if vault.Name ==
		"Pallet"
		and not IsPalletDropped(
			vault
		) then

		return
	end


	LastVaultTime =
		now


	VaultLockedObject =
		vault


	PressSpace()
end


--============================================================
-- AUTOMATION: AUTO BREAK
--============================================================

local LastBreakTime = 0


local function TryAutoBreak()

	if not Config.AutoBreak then
		return
	end


	if not IsChaser() then
		return
	end


	local now =
		os.clock()


	if now -
		LastBreakTime <
		Config.AutoBreakCooldown then

		return
	end


	local pallet =
		FindNearestObject(
			{
				Pallet = true,
				SmallPallet = true
			},

			Config.BreakDistance
		)


	if not pallet then
		return
	end


	LastBreakTime =
		now


	PressSpace()
end


--============================================================
-- TAGGING
--============================================================

local TagActive = false

local TagTarget = nil

local OriginalTagPosition = nil


local function SaveTagPosition()

	if RootPart then

		OriginalTagPosition =
			RootPart.CFrame
	end
end


local function ReturnToTagPosition()

	if Config.ReturnAfterTag
		and OriginalTagPosition
		and RootPart then

		RootPart.CFrame =
			OriginalTagPosition
	end


	OriginalTagPosition =
		nil
end


local function StopTagging(
	returnPosition
)

	TagActive =
		false


	TagTarget =
		nil


	if returnPosition then

		ReturnToTagPosition()

	else

		OriginalTagPosition =
			nil
	end
end


local function FindNearestRunner(
	maxDistance
)

	if not RootPart then
		return nil
	end


	local nearest
	local nearestDistance =
		maxDistance
		or math.huge


	for _, player in ipairs(
		Players:GetPlayers()
	) do

		if player ~= LocalPlayer
			and GetRole(player) ==
			"Runner" then

			local character =
				player.Character


			if character then

				local root =
					character:FindFirstChild(
						"HumanoidRootPart"
					)


				if root then

					local distance =
						(
							RootPart.Position -
							root.Position
						).Magnitude


					if distance <
						nearestDistance then

						nearest =
							player

						nearestDistance =
							distance
					end
				end
			end
		end
	end


	return nearest
end


local function GetRunnerList()

	local runners = {}


	for _, player in ipairs(
		Players:GetPlayers()
	) do

		if player ~= LocalPlayer
			and GetRole(player) ==
			"Runner" then

			table.insert(
				runners,
				player
			)
		end
	end


	table.sort(
		runners,

		function(a, b)

			return a.Name <
				b.Name
		end
	)


	return runners
end


local function TeleportToTarget(
	target
)

	if not target
		or not target.Parent
		or not RootPart then

		return false
	end


	local character =
		target.Character


	if not character then
		return false
	end


	local targetRoot =
		character:FindFirstChild(
			"HumanoidRootPart"
		)


	if not targetRoot then
		return false
	end


	RootPart.CFrame =
		targetRoot.CFrame *
		CFrame.new(
			0,
			0,
			-3
		)


	return true
end


--============================================================
-- GUI
--============================================================

local ScreenGui =
	Instance.new(
		"ScreenGui"
	)

ScreenGui.Name =
	"Sha4kHub"

ScreenGui.ResetOnSpawn =
	false

ScreenGui.IgnoreGuiInset =
	true

ScreenGui.ZIndexBehavior =
	Enum.ZIndexBehavior.Sibling

ScreenGui.Parent =
	PlayerGui


local UIScale =
	Instance.new(
		"UIScale"
	)

UIScale.Scale =
	Config.UIScale

UIScale.Parent =
	ScreenGui


--============================================================
-- NOTIFICATION HOLDER
--============================================================

local NotificationHolder =
	Instance.new(
		"Frame"
	)

NotificationHolder.AnchorPoint =
	Vector2.new(
		1,
		1
	)

NotificationHolder.Position =
	UDim2.new(
		1,
		-18,
		1,
		-18
	)

NotificationHolder.Size =
	UDim2.fromOffset(
		310,
		260
	)

NotificationHolder.BackgroundTransparency =
	1

NotificationHolder.Parent =
	ScreenGui


local NotificationLayout =
	Instance.new(
		"UIListLayout"
	)

NotificationLayout.VerticalAlignment =
	Enum.VerticalAlignment.Bottom

NotificationLayout.HorizontalAlignment =
	Enum.HorizontalAlignment.Right

NotificationLayout.Padding =
	UDim.new(
		0,
		7
	)

NotificationLayout.Parent =
	NotificationHolder


--============================================================
-- NOTIFY
--============================================================

local function Notify(
	text
)

	local notification =
		Instance.new(
			"Frame"
		)


	notification.Size =
		UDim2.fromOffset(
			290,
			50
		)


	notification.BackgroundColor3 =
		Color3.fromRGB(
			23,
			23,
			30
		)


	notification.BorderSizePixel =
		0


	notification.Parent =
		NotificationHolder


	local corner =
		Instance.new(
			"UICorner"
		)


	corner.CornerRadius =
		UDim.new(
			0,
			9
		)


	corner.Parent =
		notification


	local stroke =
		Instance.new(
			"UIStroke"
		)


	stroke.Color =
		Color3.fromRGB(
			161,
			157,
			184
		)


	stroke.Transparency =
		0.45


	stroke.Parent =
		notification


	local label =
		Instance.new(
			"TextLabel"
		)


	label.Position =
		UDim2.fromOffset(
			13,
			0
		)


	label.Size =
		UDim2.new(
			1,
			-26,
			1,
			0
		)


	label.BackgroundTransparency =
		1


	label.Font =
		Enum.Font.GothamMedium


	label.TextSize =
		13


	label.TextColor3 =
		Color3.fromRGB(
			240,
			240,
			245
		)


	label.TextXAlignment =
		Enum.TextXAlignment.Left


	label.Text =
		text


	label.Parent =
		notification


	notification.Position =
		UDim2.new(
			1,
			20,
			0,
			0
		)


	TweenService:Create(

		notification,

		TweenInfo.new(
			0.25,
			Enum.EasingStyle.Quint,
			Enum.EasingDirection.Out
		),

		{
			Position =
				UDim2.new(
					0,
					0,
					0,
					0
				)
		}

	):Play()


	task.delay(
		2.5,

		function()

			if not notification.Parent then
				return
			end


			local tween =
				TweenService:Create(

					notification,

					TweenInfo.new(
						0.22,
						Enum.EasingStyle.Quint,
						Enum.EasingDirection.In
					),

					{
						Position =
							UDim2.new(
								1,
								20,
								0,
								0
							)
					}
				)


			tween:Play()


			tween.Completed:Once(
				function()

					if notification then
						notification:Destroy()
					end
				end
			)
		end
	)
end


--============================================================
-- INTRO
--============================================================

local Intro =
	Instance.new(
		"Frame"
	)

Intro.Size =
	UDim2.fromScale(
		1,
		1
	)

Intro.BackgroundTransparency =
	1

Intro.Parent =
	ScreenGui


local IntroText =
	Instance.new(
		"TextLabel"
	)

IntroText.AnchorPoint =
	Vector2.new(
		0.5,
		0.5
	)

IntroText.Position =
	UDim2.fromScale(
		0.5,
		0.5
	)

IntroText.Size =
	UDim2.fromOffset(
		500,
		100
	)

IntroText.BackgroundTransparency =
	1

IntroText.RichText =
	true

IntroText.Font =
	Enum.Font.GothamBold

IntroText.TextSize =
	48

IntroText.TextTransparency =
	1

IntroText.Text =
	'<font color="rgb(161,157,184)">Sha4k</font>' ..
	'<font color="rgb(255,255,255)">Hub</font>'

IntroText.Parent =
	Intro


TweenService:Create(

	IntroText,

	TweenInfo.new(
		0.45,
		Enum.EasingStyle.Quint,
		Enum.EasingDirection.Out
	),

	{
		TextTransparency = 0
	}

):Play()


task.wait(1.1)


TweenService:Create(

	IntroText,

	TweenInfo.new(
		0.3,
		Enum.EasingStyle.Quint,
		Enum.EasingDirection.In
	),

	{
		TextTransparency = 1
	}

):Play()


task.wait(0.35)

Intro:Destroy()


--============================================================
-- COLORS
--============================================================

local Accent =
	Color3.fromRGB(
		161,
		157,
		184
	)

local ButtonColor =
	Color3.fromRGB(
		28,
		28,
		36
	)

local SelectedColor =
	Color3.fromRGB(
		161,
		157,
		184
	)

local TextColor =
	Color3.fromRGB(
		238,
		238,
		242
	)

local MutedColor =
	Color3.fromRGB(
		150,
		149,
		163
	)


--============================================================
-- MAIN FRAME
--============================================================

local Main =
	Instance.new(
		"Frame"
	)

Main.AnchorPoint =
	Vector2.new(
		0.5,
		0.5
	)

Main.Position =
	UDim2.fromScale(
		0.5,
		0.5
	)

Main.Size =
	UDim2.fromOffset(
		600,
		500
	)

Main.BackgroundColor3 =
	Color3.fromRGB(
		18,
		18,
		24
	)

Main.BorderSizePixel =
	0

Main.ClipsDescendants =
	true

Main.Parent =
	ScreenGui


local MainCorner =
	Instance.new(
		"UICorner"
	)

MainCorner.CornerRadius =
	UDim.new(
		0,
		14
	)

MainCorner.Parent =
	Main


local MainStroke =
	Instance.new(
		"UIStroke"
	)

MainStroke.Color =
	Color3.fromRGB(
		65,
		63,
		78
	)

MainStroke.Transparency =
	0.25

MainStroke.Parent =
	Main


--============================================================
-- TOPBAR
--============================================================

local Topbar =
	Instance.new(
		"Frame"
	)

Topbar.Size =
	UDim2.new(
		1,
		0,
		0,
		58
	)

Topbar.BackgroundColor3 =
	Color3.fromRGB(
		23,
		23,
		30
	)

Topbar.BorderSizePixel =
	0

Topbar.Parent =
	Main


local Title =
	Instance.new(
		"TextLabel"
	)

Title.Position =
	UDim2.fromOffset(
		18,
		0
	)

Title.Size =
	UDim2.fromOffset(
		250,
		58
	)

Title.BackgroundTransparency =
	1

Title.RichText =
	true

Title.Font =
	Enum.Font.GothamBold

Title.TextSize =
	21

Title.TextXAlignment =
	Enum.TextXAlignment.Left

Title.Text =
	'<font color="rgb(161,157,184)">Sha4k</font>' ..
	'<font color="rgb(255,255,255)">Hub</font>'

Title.Parent =
	Topbar


local RoleLabel =
	Instance.new(
		"TextLabel"
	)

RoleLabel.AnchorPoint =
	Vector2.new(
		1,
		0.5
	)

RoleLabel.Position =
	UDim2.new(
		1,
		-17,
		0.5,
		0
	)

RoleLabel.Size =
	UDim2.fromOffset(
		200,
		25
	)

RoleLabel.BackgroundTransparency =
	1

RoleLabel.Font =
	Enum.Font.GothamMedium

RoleLabel.TextSize =
	12

RoleLabel.TextColor3 =
	Color3.fromRGB(
		170,
		168,
		184
	)

RoleLabel.TextXAlignment =
	Enum.TextXAlignment.Right

RoleLabel.Text =
	"Role: " ..
	GetRole()

RoleLabel.Parent =
	Topbar


--============================================================
-- DRAGGING
--============================================================

local Dragging = false

local DragStart

local StartPosition


Topbar.InputBegan:Connect(
	function(input)

		if input.UserInputType ==
			Enum.UserInputType.MouseButton1
			or
			input.UserInputType ==
			Enum.UserInputType.Touch then

			Dragging =
				true

			DragStart =
				input.Position

			StartPosition =
				Main.Position
		end
	end
)


UserInputService.InputChanged:Connect(
	function(input)

		if not Dragging then
			return
		end


		if input.UserInputType ~=
			Enum.UserInputType.MouseMovement
			and
			input.UserInputType ~=
			Enum.UserInputType.Touch then

			return
		end


		local delta =
			input.Position -
			DragStart


		Main.Position =
			UDim2.new(

				StartPosition.X.Scale,

				StartPosition.X.Offset +
					delta.X,

				StartPosition.Y.Scale,

				StartPosition.Y.Offset +
					delta.Y
			)
	end
)


UserInputService.InputEnded:Connect(
	function(input)

		if input.UserInputType ==
			Enum.UserInputType.MouseButton1
			or
			input.UserInputType ==
			Enum.UserInputType.Touch then

			Dragging =
				false
		end
	end
)


--============================================================
-- NAVIGATION
--============================================================

local Navigation =
	Instance.new(
		"Frame"
	)

Navigation.Position =
	UDim2.fromOffset(
		10,
		68
	)

Navigation.Size =
	UDim2.new(
		0,
		105,
		1,
		-78
	)

Navigation.BackgroundTransparency =
	1

Navigation.Parent =
	Main


local NavigationLayout =
	Instance.new(
		"UIListLayout"
	)

NavigationLayout.Padding =
	UDim.new(
		0,
		7
	)

NavigationLayout.SortOrder =
	Enum.SortOrder.LayoutOrder

NavigationLayout.Parent =
	Navigation


local Content =
	Instance.new(
		"Frame"
	)

Content.Position =
	UDim2.fromOffset(
		125,
		68
	)

Content.Size =
	UDim2.new(
		1,
		-135,
		1,
		-78
	)

Content.BackgroundTransparency =
	1

Content.Parent =
	Main


--============================================================
-- TAB SYSTEM
--============================================================

local Tabs = {}

local CurrentTab


local function SwitchTab(
	name
)

	for tabName, tab in pairs(
		Tabs
	) do

		local selected =
			tabName == name


		tab.Page.Visible =
			selected


		if selected then

			TweenService:Create(

				tab.Button,

				TweenInfo.new(
					0.15,
					Enum.EasingStyle.Quint,
					Enum.EasingDirection.Out
				),

				{
					BackgroundColor3 =
						SelectedColor
				}

			):Play()


			tab.Label.TextColor3 =
				Color3.fromRGB(
					22,
					22,
					28
				)


			tab.Icon.ImageColor3 =
				Color3.fromRGB(
					22,
					22,
					28
				)

		else

			TweenService:Create(

				tab.Button,

				TweenInfo.new(
					0.15,
					Enum.EasingStyle.Quint,
					Enum.EasingDirection.Out
				),

				{
					BackgroundColor3 =
						ButtonColor
				}

			):Play()


			tab.Label.TextColor3 =
				TextColor


			tab.Icon.ImageColor3 =
				TextColor
		end
	end


	CurrentTab =
		name
end


local function CreateTab(
	name,
	iconId
)

	local page =
		Instance.new(
			"ScrollingFrame"
		)

	page.Name =
		name

	page.Size =
		UDim2.fromScale(
			1,
			1
		)

	page.BackgroundTransparency =
		1

	page.BorderSizePixel =
		0

	page.ScrollBarThickness =
		3

	page.ScrollBarImageColor3 =
		Accent

	page.AutomaticCanvasSize =
		Enum.AutomaticSize.Y

	page.CanvasSize =
		UDim2.new()

	page.Visible =
		false

	page.Parent =
		Content


	local layout =
		Instance.new(
			"UIListLayout"
		)

	layout.Padding =
		UDim.new(
			0,
			7
		)

	layout.SortOrder =
		Enum.SortOrder.LayoutOrder

	layout.Parent =
		page


	local button =
		Instance.new(
			"TextButton"
		)

	button.Size =
		UDim2.new(
			1,
			0,
			0,
			44
		)

	button.BackgroundColor3 =
		ButtonColor

	button.BorderSizePixel =
		0

	button.AutoButtonColor =
		false

	button.Text =
		""

	button.Parent =
		Navigation


	local corner =
		Instance.new(
			"UICorner"
		)

	corner.CornerRadius =
		UDim.new(
			0,
			9
		)

	corner.Parent =
		button


	local icon =
		Instance.new(
			"ImageLabel"
		)

	icon.Position =
		UDim2.fromOffset(
			10,
			10
		)

	icon.Size =
		UDim2.fromOffset(
			23,
			23
		)

	icon.BackgroundTransparency =
		1

	icon.Image =
		"rbxassetid://" ..
		tostring(
			iconId
		)

	icon.ImageColor3 =
		TextColor

	icon.Parent =
		button


	local label =
		Instance.new(
			"TextLabel"
		)

	label.Position =
		UDim2.fromOffset(
			40,
			0
		)

	label.Size =
		UDim2.new(
			1,
			-45,
			1,
			0
		)

	label.BackgroundTransparency =
		1

	label.Font =
		Enum.Font.GothamSemibold

	label.TextSize =
		11

	label.TextColor3 =
		TextColor

	label.TextXAlignment =
		Enum.TextXAlignment.Left

	label.Text =
		name

	label.Parent =
		button


	local tab = {

		Page =
			page,

		Button =
			button,

		Icon =
			icon,

		Label =
			label,
	}


	Tabs[
		name
	] =
		tab


	button.MouseEnter:Connect(
		function()

			PlayHover()
		end
	)


	button.MouseButton1Click:Connect(
		function()

			PlayClick()

			SwitchTab(
				name
			)
		end
	)


	return page
end


--============================================================
-- TAB ICONS
--============================================================

local HAMMER_ICON =
	120310022500584

local EYE_ICON =
	111235212335141

local GEAR_ICON =
	104626039242165


--============================================================
-- CREATE TABS
--============================================================

local AutoPage =
	CreateTab(
		"Auto",
		HAMMER_ICON
	)


local ESPPage =
	CreateTab(
		"ESP",
		EYE_ICON
	)


local TagPage =
	CreateTab(
		"Tag",
		HAMMER_ICON
	)


local MovementPage =
	CreateTab(
		"Movement",
		GEAR_ICON
	)


local SettingsPage =
	CreateTab(
		"Settings",
		GEAR_ICON
	)


--============================================================
-- UI BUILDERS
--============================================================

local function AddSection(
	parent,
	text
)

	local label =
		Instance.new(
			"TextLabel"
		)

	label.Size =
		UDim2.new(
			1,
			-5,
			0,
			28
		)

	label.BackgroundTransparency =
		1

	label.Font =
		Enum.Font.GothamBold

	label.TextSize =
		12

	label.TextColor3 =
		Accent

	label.TextXAlignment =
		Enum.TextXAlignment.Left

	label.Text =
		string.upper(
			text
		)

	label.Parent =
		parent


	return label
end


local function AddButton(
	parent,
	text,
	callback,
	height
)

	local button =
		Instance.new(
			"TextButton"
		)

	button.Size =
		UDim2.new(
			1,
			-5,
			0,
			height or 42
		)

	button.BackgroundColor3 =
		ButtonColor

	button.BorderSizePixel =
		0

	button.AutoButtonColor =
		false

	button.Font =
		Enum.Font.GothamMedium

	button.TextSize =
		13

	button.TextColor3 =
		TextColor

	button.Text =
		text

	button.Parent =
		parent


	local corner =
		Instance.new(
			"UICorner"
		)

	corner.CornerRadius =
		UDim.new(
			0,
			9
		)

	corner.Parent =
		button


	button.MouseEnter:Connect(
		function()

			PlayHover()


			TweenService:Create(

				button,

				TweenInfo.new(
					0.12
				),

				{
					BackgroundColor3 =
						Color3.fromRGB(
							36,
							36,
							46
						)
				}

			):Play()
		end
	)


	button.MouseLeave:Connect(
		function()

			TweenService:Create(

				button,

				TweenInfo.new(
					0.12
				),

				{
					BackgroundColor3 =
						ButtonColor
				}

			):Play()
		end
	)


	button.MouseButton1Click:Connect(
		function()

			PlayClick()


			if callback then
				callback()
			end
		end
	)


	return button
end


local function AddToggle(
	parent,
	text,
	description,
	initial,
	callback
)

	local enabled =
		initial


	local holder =
		Instance.new(
			"TextButton"
		)


	holder.Size =
		UDim2.new(
			1,
			-5,
			0,
			60
		)


	holder.BackgroundColor3 =
		ButtonColor


	holder.BorderSizePixel =
		0


	holder.AutoButtonColor =
		false


	holder.Text =
		""


	holder.Parent =
		parent


	local corner =
		Instance.new(
			"UICorner"
		)


	corner.CornerRadius =
		UDim.new(
			0,
			9
		)


	corner.Parent =
		holder


	local title =
		Instance.new(
			"TextLabel"
		)


	title.Position =
		UDim2.fromOffset(
			13,
			7
		)


	title.Size =
		UDim2.new(
			1,
			-85,
			0,
			22
		)


	title.BackgroundTransparency =
		1


	title.Font =
		Enum.Font.GothamSemibold


	title.TextSize =
		13


	title.TextColor3 =
		TextColor


	title.TextXAlignment =
		Enum.TextXAlignment.Left


	title.Text =
		text


	title.Parent =
		holder


	local desc =
		Instance.new(
			"TextLabel"
		)


	desc.Position =
		UDim2.fromOffset(
			13,
			30
		)


	desc.Size =
		UDim2.new(
			1,
			-90,
			0,
			18
		)


	desc.BackgroundTransparency =
		1


	desc.Font =
		Enum.Font.Gotham


	desc.TextSize =
		10


	desc.TextColor3 =
		MutedColor


	desc.TextXAlignment =
		Enum.TextXAlignment.Left


	desc.Text =
		description


	desc.Parent =
		holder


	local switch =
		Instance.new(
			"Frame"
		)


	switch.AnchorPoint =
		Vector2.new(
			1,
			0.5
		)


	switch.Position =
		UDim2.new(
			1,
			-13,
			0.5,
			0
		)


	switch.Size =
		UDim2.fromOffset(
			42,
			22
		)


	switch.BorderSizePixel =
		0


	switch.Parent =
		holder


	local switchCorner =
		Instance.new(
			"UICorner"
		)


	switchCorner.CornerRadius =
		UDim.new(
			1,
			0
		)


	switchCorner.Parent =
		switch


	local dot =
		Instance.new(
			"Frame"
		)


	dot.AnchorPoint =
		Vector2.new(
			0.5,
			0.5
		)


	dot.Size =
		UDim2.fromOffset(
			16,
			16
		)


	dot.BackgroundColor3 =
		Color3.fromRGB(
			245,
			245,
			245
		)


	dot.BorderSizePixel =
		0


	dot.Parent =
		switch


	local dotCorner =
		Instance.new(
			"UICorner"
		)


	dotCorner.CornerRadius =
		UDim.new(
			1,
			0
		)


	dotCorner.Parent =
		dot


	local function Update(
		animated
	)

		local targetColor

		local targetPosition


		if enabled then

			targetColor =
				Accent

			targetPosition =
				UDim2.new(
					1,
					-11,
					0.5,
					0
				)

		else

			targetColor =
				Color3.fromRGB(
					48,
					48,
					58
				)

			targetPosition =
				UDim2.new(
					0,
					11,
					0.5,
					0
				)
		end


		if animated then

			TweenService:Create(

				switch,

				TweenInfo.new(
					0.18
				),

				{
					BackgroundColor3 =
						targetColor
				}

			):Play()


			TweenService:Create(

				dot,

				TweenInfo.new(
					0.2,
					Enum.EasingStyle.Quint,
					Enum.EasingDirection.Out
				),

				{
					Position =
						targetPosition
				}

			):Play()

		else

			switch.BackgroundColor3 =
				targetColor

			dot.Position =
				targetPosition
		end
	end


	Update(false)


	holder.MouseEnter:Connect(
		function()

			PlayHover()
		end
	)


	holder.MouseButton1Click:Connect(
		function()

			PlayClick()


			enabled =
				not enabled


			Update(true)


			if callback then
				callback(
					enabled
				)
			end
		end
	)


	return holder
end


local function AddNumberBox(
	parent,
	text,
	value,
	minimum,
	maximum,
	callback
)

	local holder =
		Instance.new(
			"Frame"
		)


	holder.Size =
		UDim2.new(
			1,
			-5,
			0,
			47
		)


	holder.BackgroundColor3 =
		ButtonColor


	holder.BorderSizePixel =
		0


	holder.Parent =
		parent


	local corner =
		Instance.new(
			"UICorner"
		)


	corner.CornerRadius =
		UDim.new(
			0,
			9
		)


	corner.Parent =
		holder


	local label =
		Instance.new(
			"TextLabel"
		)


	label.Position =
		UDim2.fromOffset(
			13,
			0
		)


	label.Size =
		UDim2.new(
			1,
			-115,
			1,
			0
		)


	label.BackgroundTransparency =
		1


	label.Font =
		Enum.Font.GothamSemibold


	label.TextSize =
		12


	label.TextColor3 =
		TextColor


	label.TextXAlignment =
		Enum.TextXAlignment.Left


	label.Text =
		text


	label.Parent =
		holder


	local box =
		Instance.new(
			"TextBox"
		)


	box.AnchorPoint =
		Vector2.new(
			1,
			0.5
		)


	box.Position =
		UDim2.new(
			1,
			-11,
			0.5,
			0
		)


	box.Size =
		UDim2.fromOffset(
			75,
			30
		)


	box.BackgroundColor3 =
		Color3.fromRGB(
			19,
			19,
			25
		)


	box.BorderSizePixel =
		0


	box.Font =
		Enum.Font.GothamMedium


	box.TextSize =
		12


	box.TextColor3 =
		Color3.new(
			1,
			1,
			1
		)


	box.Text =
		tostring(
			value
		)


	box.ClearTextOnFocus =
		false


	box.Parent =
		holder


	local boxCorner =
		Instance.new(
			"UICorner"
		)


	boxCorner.CornerRadius =
		UDim.new(
			0,
			7
		)


	boxCorner.Parent =
		box


	box.FocusLost:Connect(
		function()

			local number =
				tonumber(
					box.Text
				)


			if not number then

				box.Text =
					tostring(
						value
					)

				return
			end


			number =
				math.clamp(
					number,
					minimum,
					maximum
				)


			value =
				number


			box.Text =
				tostring(
					number
				)


			if callback then
				callback(
					number
				)
			end
		end
	)


	return holder
end


local function AddRGB(
	parent,
	text,
	color,
	callback
)

	local holder =
		Instance.new(
			"Frame"
		)


	holder.Size =
		UDim2.new(
			1,
			-5,
			0,
			47
		)


	holder.BackgroundColor3 =
		ButtonColor


	holder.BorderSizePixel =
		0


	holder.Parent =
		parent


	local corner =
		Instance.new(
			"UICorner"
		)


	corner.CornerRadius =
		UDim.new(
			0,
			9
		)


	corner.Parent =
		holder


	local title =
		Instance.new(
			"TextLabel"
		)


	title.Position =
		UDim2.fromOffset(
			12,
			0
		)


	title.Size =
		UDim2.fromOffset(
			110,
			47
		)


	title.BackgroundTransparency =
		1


	title.Font =
		Enum.Font.GothamSemibold


	title.TextSize =
		11


	title.TextColor3 =
		TextColor


	title.TextXAlignment =
		Enum.TextXAlignment.Left


	title.Text =
		text


	title.Parent =
		holder


	local values = {

		math.floor(
			color.R * 255
		),

		math.floor(
			color.G * 255
		),

		math.floor(
			color.B * 255
		),
	}


	local boxes = {}


	for i = 1, 3 do

		local box =
			Instance.new(
				"TextBox"
			)


		box.Position =
			UDim2.fromOffset(
				108 +
					((i - 1) * 48),
				8
			)


		box.Size =
			UDim2.fromOffset(
				43,
				30
			)


		box.BackgroundColor3 =
			Color3.fromRGB(
				19,
				19,
				25
			)


		box.BorderSizePixel =
			0


		box.Font =
			Enum.Font.GothamMedium


		box.TextSize =
			11


		box.TextColor3 =
			Color3.fromRGB(
				230,
				230,
				235
			)


		box.Text =
			tostring(
				values[i]
			)


		box.ClearTextOnFocus =
			false


		box.Parent =
			holder


		local c =
			Instance.new(
				"UICorner"
			)


		c.CornerRadius =
			UDim.new(
				0,
				6
			)


		c.Parent =
			box


		boxes[i] =
			box
	end


	local apply =
		Instance.new(
			"TextButton"
		)


	apply.AnchorPoint =
		Vector2.new(
			1,
			0.5
		)


	apply.Position =
		UDim2.new(
			1,
			-8,
			0.5,
			0
		)


	apply.Size =
		UDim2.fromOffset(
			52,
			30
		)


	apply.BackgroundColor3 =
		Accent


	apply.BorderSizePixel =
		0


	apply.Font =
		Enum.Font.GothamBold


	apply.TextSize =
		10


	apply.TextColor3 =
		Color3.fromRGB(
			20,
			20,
			25
		)


	apply.Text =
		"SET"


	apply.Parent =
		holder


	local applyCorner =
		Instance.new(
			"UICorner"
		)


	applyCorner.CornerRadius =
		UDim.new(
			0,
			6
		)


	applyCorner.Parent =
		apply


	apply.MouseEnter:Connect(
		function()

			PlayHover()
		end
	)


	apply.MouseButton1Click:Connect(
		function()

			PlayClick()


			local r =
				math.clamp(
					tonumber(
						boxes[1].Text
					)
					or 255,
					0,
					255
				)


			local g =
				math.clamp(
					tonumber(
						boxes[2].Text
					)
					or 255,
					0,
					255
				)


			local b =
				math.clamp(
					tonumber(
						boxes[3].Text
					)
					or 255,
					0,
					255
				)


			local newColor =
				Color3.fromRGB(
					r,
					g,
					b
				)


			if callback then
				callback(
					newColor
				)
			end
		end
	)


	return holder
end


--============================================================
-- AUTO PAGE
--============================================================

AddSection(
	AutoPage,
	"Automation"
)


AddToggle(
	AutoPage,

	"Auto Vault",

	"Vault near Vault1 / Vault2 and dropped pallets.",

	Config.AutoVault,

	function(value)

		Config.AutoVault =
			value


		if not value then

			VaultLockedObject =
				nil
		end
	end
)


AddNumberBox(
	AutoPage,

	"Vault Distance",

	Config.VaultDistance,

	1,
	50,

	function(value)

		Config.VaultDistance =
			value
	end
)


AddNumberBox(
	AutoPage,

	"Vault Cooldown",

	Config.AutoVaultCooldown,

	1,
	10,

	function(value)

		-- Hard minimum:
		-- Auto Vault can NEVER be lower than 1 second.
		Config.AutoVaultCooldown =
			math.max(
				1,
				value
			)
	end
)


AddToggle(
	AutoPage,

	"Auto Break",

	"Press SPACE near pallets as Chaser.",

	Config.AutoBreak,

	function(value)

		Config.AutoBreak =
			value
	end
)


AddNumberBox(
	AutoPage,

	"Break Distance",

	Config.BreakDistance,

	1,
	50,

	function(value)

		Config.BreakDistance =
			value
	end
)


AddNumberBox(
	AutoPage,

	"Break Cooldown",

	Config.AutoBreakCooldown,

	0.1,
	5,

	function(value)

		Config.AutoBreakCooldown =
			value
	end
)


--============================================================
-- AUTO PALLET STUN UI
--============================================================

AddSection(
	AutoPage,
	"Auto Pallet Stun"
)


AddToggle(
	AutoPage,

	"Auto Pallet Stun",

	"Drop ready Pallet when a Chaser gets close.",

	Config.AutoPalletStun,

	function(value)

		Config.AutoPalletStun =
			value
	end
)


AddNumberBox(
	AutoPage,

	"Chaser Distance",

	Config.PalletStunDistance,

	1,
	20,

	function(value)

		Config.PalletStunDistance =
			value
	end
)


AddNumberBox(
	AutoPage,

	"Drop Cooldown",

	Config.PalletDropCooldown,

	0.1,
	5,

	function(value)

		Config.PalletDropCooldown =
			value
	end
)


AddButton(
	AutoPage,

	"Reset Vault Lock",

	function()

		VaultLockedObject =
			nil

		LastVaultTime =
			0

		Notify(
			"Vault system re-armed."
		)
	end
)


--============================================================
-- ESP PAGE
--============================================================

AddSection(
	ESPPage,
	"Players"
)


AddToggle(
	ESPPage,

	"Player ESP",

	"Role-colored player highlights.",

	Config.PlayerESP,

	function(value)

		Config.PlayerESP =
			value
	end
)


AddNumberBox(
	ESPPage,

	"Player Distance",

	Config.PlayerESPDistance,

	10,
	5000,

	function(value)

		Config.PlayerESPDistance =
			value
	end
)


AddToggle(
	ESPPage,

	"Player Names",

	"Show player display names.",

	Config.ShowPlayerNames,

	function(value)

		Config.ShowPlayerNames =
			value
	end
)


AddToggle(
	ESPPage,

	"Player Roles",

	"Show Chaser / Runner / Eliminated.",

	Config.ShowPlayerRoles,

	function(value)

		Config.ShowPlayerRoles =
			value
	end
)


AddToggle(
	ESPPage,

	"Player Health",

	"Show current / maximum HP.",

	Config.ShowPlayerHealth,

	function(value)

		Config.ShowPlayerHealth =
			value
	end
)


AddRGB(
	ESPPage,

	"Chaser RGB",

	Config.ChaserColor,

	function(color)

		Config.ChaserColor =
			color
	end
)


AddRGB(
	ESPPage,

	"Runner RGB",

	Config.RunnerColor,

	function(color)

		Config.RunnerColor =
			color
	end
)


AddRGB(
	ESPPage,

	"Eliminated RGB",

	Config.EliminatedColor,

	function(color)

		Config.EliminatedColor =
			color
	end
)


AddSection(
	ESPPage,
	"Object ESP"
)


AddToggle(
	ESPPage,

	"Object ESP",

	"Enable object highlights.",

	Config.ObjectESP,

	function(value)

		Config.ObjectESP =
			value
	end
)


AddToggle(
	ESPPage,

	"Object Names",

	"Show object names.",

	Config.ShowObjectNames,

	function(value)

		Config.ShowObjectNames =
			value
	end
)


AddNumberBox(
	ESPPage,

	"Fill Transparency %",

	math.floor(
		Config.ObjectFillTransparency *
		100
	),

	0,
	100,

	function(value)

		Config.ObjectFillTransparency =
			value / 100
	end
)


AddNumberBox(
	ESPPage,

	"Outline Transparency %",

	math.floor(
		Config.ObjectOutlineTransparency *
		100
	),

	0,
	100,

	function(value)

		Config.ObjectOutlineTransparency =
			value / 100
	end
)


--============================================================
-- PALLET ESP
--============================================================

AddSection(
	ESPPage,
	"Pallets"
)


AddToggle(
	ESPPage,

	"Pallet",

	"Highlight Pallet.",

	ObjectSettings.Pallet.Enabled,

	function(value)

		ObjectSettings.Pallet.Enabled =
			value
	end
)


AddNumberBox(
	ESPPage,

	"Pallet Distance",

	ObjectSettings.Pallet.Distance,

	1,
	5000,

	function(value)

		ObjectSettings.Pallet.Distance =
			value
	end
)


AddRGB(
	ESPPage,

	"Pallet RGB",

	ObjectSettings.Pallet.Color,

	function(color)

		ObjectSettings.Pallet.Color =
			color
	end
)


AddToggle(
	ESPPage,

	"SmallPallet",

	"Highlight SmallPallet.",

	ObjectSettings.SmallPallet.Enabled,

	function(value)

		ObjectSettings.SmallPallet.Enabled =
			value
	end
)


AddNumberBox(
	ESPPage,

	"SmallPallet Distance",

	ObjectSettings.SmallPallet.Distance,

	1,
	5000,

	function(value)

		ObjectSettings.SmallPallet.Distance =
			value
	end
)


AddRGB(
	ESPPage,

	"SmallPallet RGB",

	ObjectSettings.SmallPallet.Color,

	function(color)

		ObjectSettings.SmallPallet.Color =
			color
	end
)


--============================================================
-- WINDOW ESP
--============================================================

AddSection(
	ESPPage,
	"Windows"
)


AddToggle(
	ESPPage,

	"Window",

	"Highlight Window.",

	ObjectSettings.Window.Enabled,

	function(value)

		ObjectSettings.Window.Enabled =
			value
	end
)


AddNumberBox(
	ESPPage,

	"Window Distance",

	ObjectSettings.Window.Distance,

	1,
	5000,

	function(value)

		ObjectSettings.Window.Distance =
			value
	end
)


AddRGB(
	ESPPage,

	"Window RGB",

	ObjectSettings.Window.Color,

	function(color)

		ObjectSettings.Window.Color =
			color
	end
)


AddToggle(
	ESPPage,

	"SmallWindow",

	"Highlight SmallWindow.",

	ObjectSettings.SmallWindow.Enabled,

	function(value)

		ObjectSettings.SmallWindow.Enabled =
			value
	end
)


AddNumberBox(
	ESPPage,

	"SmallWindow Distance",

	ObjectSettings.SmallWindow.Distance,

	1,
	5000,

	function(value)

		ObjectSettings.SmallWindow.Distance =
			value
	end
)


AddRGB(
	ESPPage,

	"SmallWindow RGB",

	ObjectSettings.SmallWindow.Color,

	function(color)

		ObjectSettings.SmallWindow.Color =
			color
	end
)


--============================================================
-- VAULT ESP
--============================================================

AddSection(
	ESPPage,
	"Vaults"
)


AddToggle(
	ESPPage,

	"Vault1",

	"Highlight Vault1.",

	ObjectSettings.Vault1.Enabled,

	function(value)

		ObjectSettings.Vault1.Enabled =
			value
	end
)


AddNumberBox(
	ESPPage,

	"Vault1 Distance",

	ObjectSettings.Vault1.Distance,

	1,
	5000,

	function(value)

		ObjectSettings.Vault1.Distance =
			value
	end
)


AddRGB(
	ESPPage,

	"Vault1 RGB",

	ObjectSettings.Vault1.Color,

	function(color)

		ObjectSettings.Vault1.Color =
			color
	end
)


AddToggle(
	ESPPage,

	"Vault2",

	"Highlight Vault2.",

	ObjectSettings.Vault2.Enabled,

	function(value)

		ObjectSettings.Vault2.Enabled =
			value
	end
)


AddNumberBox(
	ESPPage,

	"Vault2 Distance",

	ObjectSettings.Vault2.Distance,

	1,
	5000,

	function(value)

		ObjectSettings.Vault2.Distance =
			value
	end
)


AddRGB(
	ESPPage,

	"Vault2 RGB",

	ObjectSettings.Vault2.Color,

	function(color)

		ObjectSettings.Vault2.Color =
			color
	end
)


--============================================================
-- CUSTOM ESP
--============================================================

AddSection(
	ESPPage,
	"Custom ESP"
)


local CustomESPColor =
	Color3.fromRGB(
		255,
		255,
		255
	)


local CustomESPDistance =
	150


local CustomNameHolder =
	Instance.new(
		"Frame"
	)


CustomNameHolder.Size =
	UDim2.new(
		1,
		-5,
		0,
		47
	)


CustomNameHolder.BackgroundColor3 =
	ButtonColor


CustomNameHolder.BorderSizePixel =
	0


CustomNameHolder.Parent =
	ESPPage


local customNameCorner =
	Instance.new(
		"UICorner"
	)


customNameCorner.CornerRadius =
	UDim.new(
		0,
		9
	)


customNameCorner.Parent =
	CustomNameHolder


local CustomNameBox =
	Instance.new(
		"TextBox"
	)


CustomNameBox.Position =
	UDim2.fromOffset(
		10,
		8
	)


CustomNameBox.Size =
	UDim2.new(
		1,
		-125,
		0,
		30
	)


CustomNameBox.BackgroundColor3 =
	Color3.fromRGB(
		19,
		19,
		25
	)


CustomNameBox.BorderSizePixel =
	0


CustomNameBox.Font =
	Enum.Font.GothamMedium


CustomNameBox.TextSize =
	11


CustomNameBox.TextColor3 =
	Color3.new(
		1,
		1,
		1
	)


CustomNameBox.PlaceholderText =
	"Object name..."


CustomNameBox.ClearTextOnFocus =
	false


CustomNameBox.Parent =
	CustomNameHolder


local customBoxCorner =
	Instance.new(
		"UICorner"
	)


customBoxCorner.CornerRadius =
	UDim.new(
		0,
		6
	)


customBoxCorner.Parent =
	CustomNameBox


local CustomAddButton =
	Instance.new(
		"TextButton"
	)


CustomAddButton.AnchorPoint =
	Vector2.new(
		1,
		0.5
	)


CustomAddButton.Position =
	UDim2.new(
		1,
		-8,
		0.5,
		0
	)


CustomAddButton.Size =
	UDim2.fromOffset(
		100,
		30
	)


CustomAddButton.BackgroundColor3 =
	Accent


CustomAddButton.BorderSizePixel =
	0


CustomAddButton.Font =
	Enum.Font.GothamBold


CustomAddButton.TextSize =
	10


CustomAddButton.TextColor3 =
	Color3.fromRGB(
		20,
		20,
		25
	)


CustomAddButton.Text =
	"ADD ESP"


CustomAddButton.Parent =
	CustomNameHolder


local customAddCorner =
	Instance.new(
		"UICorner"
	)


customAddCorner.CornerRadius =
	UDim.new(
		0,
		6
	)


customAddCorner.Parent =
	CustomAddButton


CustomAddButton.MouseEnter:Connect(
	function()

		PlayHover()
	end
)


AddNumberBox(
	ESPPage,

	"Custom Distance",

	CustomESPDistance,

	1,
	5000,

	function(value)

		CustomESPDistance =
			value
	end
)


AddRGB(
	ESPPage,

	"Custom RGB",

	CustomESPColor,

	function(color)

		CustomESPColor =
			color
	end
)


CustomAddButton.MouseButton1Click:Connect(
	function()

		PlayClick()


		local name =
			CustomNameBox.Text


		if name == "" then

			Notify(
				"Enter an object name."
			)

			return
		end


		AddCustomESP(
			name,
			CustomESPColor,
			CustomESPDistance
		)


		Notify(
			"Added ESP: " ..
			name
		)


		CustomNameBox.Text =
			""
	end
)


--============================================================
-- TAG PAGE
--============================================================

AddSection(
	TagPage,
	"Tagging"
)


AddToggle(
	TagPage,

	"Auto Tag",

	"Automatically follow the selected Runner.",

	Config.AutoTag,

	function(value)

		if value
			and not IsChaser() then

			Notify(
				"You aren't tagged!"
			)

			return
		end


		Config.AutoTag =
			value


		if value then

			if not TagTarget
				or GetRole(
					TagTarget
				) ~= "Runner" then

				TagTarget =
					FindNearestRunner(
						Config.TagDistance
					)
			end


			if TagTarget then

				SaveTagPosition()

				TagActive =
					true


				Notify(
					"Auto Tag: " ..
					TagTarget.DisplayName
				)

			else

				Config.AutoTag =
					false


				Notify(
					"No Runner found."
				)
			end

		else

			StopTagging(
				true
			)
		end
	end
)


AddNumberBox(
	TagPage,

	"Tag Distance",

	Config.TagDistance,

	5,
	5000,

	function(value)

		Config.TagDistance =
			value
	end
)


AddNumberBox(
	TagPage,

	"Tag Interval",

	Config.TagInterval,

	0.05,
	5,

	function(value)

		Config.TagInterval =
			value
	end
)


AddToggle(
	TagPage,

	"Return After Tag",

	"Return to saved position after stopping.",

	Config.ReturnAfterTag,

	function(value)

		Config.ReturnAfterTag =
			value
	end
)


AddButton(
	TagPage,

	"Tag Nearest Runner",

	function()

		if not IsChaser() then

			Notify(
				"You aren't tagged!"
			)

			return
		end


		local target =
			FindNearestRunner(
				Config.TagDistance
			)


		if not target then

			Notify(
				"No Runner within distance."
			)

			return
		end


		TagTarget =
			target


		SaveTagPosition()


		TagActive =
			true


		Notify(
			"Target: " ..
			target.DisplayName
		)
	end
)


AddButton(
	TagPage,

	"Cycle Runner Target",

	function()

		if not IsChaser() then

			Notify(
				"You aren't tagged!"
			)

			return
		end


		local runners =
			GetRunnerList()


		if #runners == 0 then

			Notify(
				"No Runners."
			)

			return
		end


		local currentIndex =
			0


		for i, player in ipairs(
			runners
		) do

			if player ==
				TagTarget then

				currentIndex =
					i

				break
			end
		end


		local nextIndex =
			currentIndex +
			1


		if nextIndex >
			#runners then

			nextIndex =
				1
		end


		TagTarget =
			runners[
				nextIndex
			]


		Notify(
			"Selected: " ..
			TagTarget.DisplayName
		)
	end
)


AddButton(
	TagPage,

	"Stop Tagging",

	function()

		Config.AutoTag =
			false


		StopTagging(
			true
		)


		Notify(
			"Tagging stopped."
		)
	end
)


AddButton(
	TagPage,

	"Save Current Position",

	function()

		if RootPart then

			OriginalTagPosition =
				RootPart.CFrame


			Notify(
				"Position saved."
			)
		end
	end
)


AddButton(
	TagPage,

	"Return To Saved Position",

	function()

		if OriginalTagPosition
			and RootPart then

			RootPart.CFrame =
				OriginalTagPosition


			OriginalTagPosition =
				nil


			Notify(
				"Returned to saved position."
			)

		else

			Notify(
				"No position saved."
			)
		end
	end
)


--============================================================
-- MOVEMENT PAGE
--============================================================

AddSection(
	MovementPage,
	"Movement"
)


AddToggle(
	MovementPage,

	"WalkSpeed Override",

	"Continuously maintain the selected speed.",

	Config.WalkSpeedEnabled,

	function(value)

		Config.WalkSpeedEnabled =
			value


		if not value
			and Humanoid then

			Humanoid.WalkSpeed =
				16
		end
	end
)


AddNumberBox(
	MovementPage,

	"WalkSpeed",

	Config.WalkSpeed,

	1,
	250,

	function(value)

		Config.WalkSpeed =
			value


		if Config.WalkSpeedEnabled
			and Humanoid then

			Humanoid.WalkSpeed =
				value
		end
	end
)


AddButton(
	MovementPage,

	"Reset WalkSpeed",

	function()

		Config.WalkSpeed =
			16


		if Humanoid then

			Humanoid.WalkSpeed =
				16
		end


		Notify(
			"WalkSpeed reset."
		)
	end
)


--============================================================
-- SETTINGS PAGE
--============================================================

AddSection(
	SettingsPage,
	"Interface"
)


AddToggle(
	SettingsPage,

	"UI Animations",

	"Enable GUI tweens.",

	Config.UIAnimations,

	function(value)

		Config.UIAnimations =
			value
	end
)


AddNumberBox(
	SettingsPage,

	"UI Scale %",

	math.floor(
		Config.UIScale *
		100
	),

	70,
	140,

	function(value)

		Config.UIScale =
			value /
			100


		UIScale.Scale =
			Config.UIScale
	end
)


--============================================================
-- SETTINGS: SOUNDS
--============================================================

AddSection(
	SettingsPage,
	"Sounds"
)


AddToggle(
	SettingsPage,

	"Sounds",

	"Enable Sha4kHub sounds.",

	Config.SoundsEnabled,

	function(value)

		Config.SoundsEnabled =
			value
	end
)


AddToggle(
	SettingsPage,

	"Hover Sound",

	"Hover sound 5852470908.",

	Config.HoverSounds,

	function(value)

		Config.HoverSounds =
			value
	end
)


AddToggle(
	SettingsPage,

	"Click Sound",

	"Click sound 140207837688369.",

	Config.ClickSounds,

	function(value)

		Config.ClickSounds =
			value
	end
)


AddNumberBox(
	SettingsPage,

	"Sound Volume %",

	math.floor(
		Config.SoundVolume *
		100
	),

	0,
	100,

	function(value)

		Config.SoundVolume =
			value /
			100
	end
)


--============================================================
-- SETTINGS: KEYBIND
--============================================================

AddSection(
	SettingsPage,
	"Keybind"
)


local KeybindButton


KeybindButton =
	AddButton(
		SettingsPage,

		"Toggle Key: " ..
			Config.ToggleKey.Name,

		function()

			Notify(
				"Press a keyboard key..."
			)


			local connection


			connection =
				UserInputService.InputBegan:Connect(

					function(
						input,
						processed
					)

						if processed then
							return
						end


						if input.UserInputType ==
							Enum.UserInputType.Keyboard then

							Config.ToggleKey =
								input.KeyCode


							KeybindButton.Text =
								"Toggle Key: " ..
								Config.ToggleKey.Name


							connection:Disconnect()


							Notify(
								"Key changed to " ..
								Config.ToggleKey.Name
							)
						end
					end
				)


			task.delay(
				10,

				function()

					if connection then
						connection:Disconnect()
					end
				end
			)
		end
	)


--============================================================
-- SETTINGS: QUALITY OF LIFE
--============================================================

AddSection(
	SettingsPage,
	"Quality of Life"
)


AddToggle(
	SettingsPage,

	"Role Notifications",

	"Notify when your role changes.",

	Config.NotifyRoleChanges,

	function(value)

		Config.NotifyRoleChanges =
			value
	end
)


AddToggle(
	SettingsPage,

	"Automation Notifications",

	"Notify about automation events.",

	Config.NotifyAutomation,

	function(value)

		Config.NotifyAutomation =
			value
	end
)


AddButton(
	SettingsPage,

	"Reset Vault Lock",

	function()

		VaultLockedObject =
			nil


		LastVaultTime =
			0


		Notify(
			"Vault system re-armed."
		)
	end
)


AddButton(
	SettingsPage,

	"Destroy Sha4kHub",

	function()

		for object in pairs(
			ObjectESPObjects
		) do

			RemoveObjectESP(
				object
			)
		end


		for player in pairs(
			PlayerESPObjects
		) do

			RemovePlayerESP(
				player
			)
		end


		ScreenGui:Destroy()
	end
)


--============================================================
-- FLOATING BUTTON
--============================================================

local Floating =
	Instance.new(
		"TextButton"
	)


Floating.AnchorPoint =
	Vector2.new(
		0,
		0.5
	)


Floating.Position =
	UDim2.new(
		0,
		15,
		0.5,
		0
	)


Floating.Size =
	UDim2.fromOffset(
		50,
		50
	)


Floating.BackgroundColor3 =
	Color3.fromRGB(
		24,
		24,
		31
	)


Floating.BorderSizePixel =
	0


Floating.AutoButtonColor =
	false


Floating.Font =
	Enum.Font.GothamBold


Floating.TextSize =
	17


Floating.TextColor3 =
	Accent


Floating.Text =
	"S4"


Floating.Parent =
	ScreenGui


local FloatingCorner =
	Instance.new(
		"UICorner"
	)


FloatingCorner.CornerRadius =
	UDim.new(
		0,
		12
	)


FloatingCorner.Parent =
	Floating


local FloatingStroke =
	Instance.new(
		"UIStroke"
	)


FloatingStroke.Color =
	Accent


FloatingStroke.Transparency =
	0.35


FloatingStroke.Parent =
	Floating


--============================================================
-- SHOW / HIDE GUI
--============================================================

local GUIVisible =
	true


local OriginalMainSize =
	UDim2.fromOffset(
		600,
		500
	)


local function ToggleGUI()

	GUIVisible =
		not GUIVisible


	if GUIVisible then

		Main.Visible =
			true


		Main.Size =
			UDim2.fromOffset(
				550,
				0
			)


		if Config.UIAnimations then

			TweenService:Create(

				Main,

				TweenInfo.new(
					0.3,
					Enum.EasingStyle.Back,
					Enum.EasingDirection.Out
				),

				{
					Size =
						OriginalMainSize
				}

			):Play()

		else

			Main.Size =
				OriginalMainSize
		end

	else

		if Config.UIAnimations then

			local tween =
				TweenService:Create(

					Main,

					TweenInfo.new(
						0.2,
						Enum.EasingStyle.Quint,
						Enum.EasingDirection.In
					),

					{
						Size =
							UDim2.fromOffset(
								550,
								0
							)
					}
				)


			tween:Play()


			tween.Completed:Once(
				function()

					if not GUIVisible then

						Main.Visible =
							false
					end
				end
			)

		else

			Main.Visible =
				false
		end
	end
end


Floating.MouseEnter:Connect(
	function()

		PlayHover()


		TweenService:Create(

			Floating,

			TweenInfo.new(
				0.15,
				Enum.EasingStyle.Quint,
				Enum.EasingDirection.Out
			),

			{
				Size =
					UDim2.fromOffset(
						55,
						55
					)
			}

		):Play()
	end
)


Floating.MouseLeave:Connect(
	function()

		TweenService:Create(

			Floating,

			TweenInfo.new(
				0.15
			),

			{
				Size =
					UDim2.fromOffset(
						50,
						50
					)
			}

		):Play()
	end
)


Floating.MouseButton1Click:Connect(
	function()

		PlayClick()

		ToggleGUI()
	end
)


--============================================================
-- TOGGLE KEY
--============================================================

UserInputService.InputBegan:Connect(
	function(
		input,
		processed
	)

		if processed then
			return
		end


		if input.KeyCode ==
			Config.ToggleKey then

			ToggleGUI()
		end
	end
)


--============================================================
-- AUTOMATION LOOP
--============================================================

task.spawn(
	function()

		while ScreenGui.Parent do

			if Character
				and RootPart
				and Humanoid then

				--================================================
				-- WALKSPEED
				--================================================

				if Config.WalkSpeedEnabled then

					if Humanoid.WalkSpeed ~=
						Config.WalkSpeed then

						Humanoid.WalkSpeed =
							Config.WalkSpeed
					end
				end


				--================================================
				-- AUTO PALLET STUN
				--================================================

				TryAutoPalletStun()


				--================================================
				-- AUTO VAULT
				--================================================

				TryAutoVault()


				--================================================
				-- AUTO BREAK
				--================================================

				TryAutoBreak()
			end


			task.wait(
				0.05
			)
		end
	end
)


--============================================================
-- TAG LOOP
--============================================================

task.spawn(
	function()

		while ScreenGui.Parent do

			if Config.AutoTag then

				-- Must remain Chaser.
				if not IsChaser() then

					Config.AutoTag =
						false


					StopTagging(
						true
					)


					Notify(
						"You aren't tagged!"
					)

				else

					TagActive =
						true


					if not TagTarget
						or not TagTarget.Parent
						or GetRole(
							TagTarget
						) ~= "Runner" then

						TagTarget =
							FindNearestRunner(
								Config.TagDistance
							)


						if not TagTarget then

							Config.AutoTag =
								false


							StopTagging(
								true
							)


							Notify(
								"No Runner found."
							)
						end
					end


					if TagTarget then

						if not OriginalTagPosition then
							SaveTagPosition()
						end


						TeleportToTarget(
							TagTarget
						)
					end
				end
			end


			-- Manual / selected tagging.
			if TagActive
				and TagTarget
				and not Config.AutoTag then

				if not IsChaser() then

					StopTagging(
						true
					)

				elseif GetRole(
					TagTarget
				) ~= "Runner" then

					StopTagging(
						true
					)

				else

					TeleportToTarget(
						TagTarget
					)
				end
			end


			task.wait(
				math.max(
					0.05,
					Config.TagInterval
				)
			)
		end
	end
)


--============================================================
-- ESP LOOP
--============================================================

task.spawn(
	function()

		while ScreenGui.Parent do

			--================================================
			-- PLAYER ESP
			--================================================

			for _, player in ipairs(
				Players:GetPlayers()
			) do

				if player ~= LocalPlayer then

					UpdatePlayerESP(
						player
					)
				end
			end


			--================================================
			-- OBJECT ESP
			--================================================

			for _, object in ipairs(
				workspace:GetDescendants()
			) do

				if ObjectSettings[
					object.Name
				]
				or
				CustomObjects[
					object.Name
				] then

					UpdateObjectESP(
						object
					)
				end
			end


			task.wait(
				0.2
			)
		end
	end
)


--============================================================
-- WORKSPACE ESP EVENTS
--============================================================

workspace.DescendantAdded:Connect(
	function(object)

		if ObjectSettings[
			object.Name
		]
		or
		CustomObjects[
			object.Name
		] then

			task.defer(
				function()

					local settings =
						ObjectSettings[
							object.Name
						]
						or
						CustomObjects[
							object.Name
						]


					if settings then

						CreateObjectESP(
							object,
							settings
						)
					end
				end
			)
		end
	end
)


workspace.DescendantRemoving:Connect(
	function(object)

		RemoveObjectESP(
			object
		)


		if VaultLockedObject ==
			object then

			VaultLockedObject =
				nil
		end


		LastPalletDropTimes[
			object
		] = nil
	end
)


--============================================================
-- PLAYER EVENTS
--============================================================

Players.PlayerAdded:Connect(
	function(player)

		player.CharacterAdded:Connect(
			function()

				task.wait(
					0.4
				)


				if Config.PlayerESP then

					CreatePlayerESP(
						player
					)
				end
			end
		)
	end
)


Players.PlayerRemoving:Connect(
	function(player)

		RemovePlayerESP(
			player
		)


		if TagTarget ==
			player then

			TagTarget =
				nil


			if Config.AutoTag then

				TagTarget =
					FindNearestRunner(
						Config.TagDistance
					)
			end
		end
	end
)


--============================================================
-- INITIAL PLAYER ESP
--============================================================

for _, player in ipairs(
	Players:GetPlayers()
) do

	if player ~= LocalPlayer then

		if player.Character then

			task.defer(
				function()

					CreatePlayerESP(
						player
					)
				end
			)
		end


		player.CharacterAdded:Connect(
			function()

				task.wait(
					0.4
				)


				if Config.PlayerESP then

					CreatePlayerESP(
						player
					)
				end
			end
		)
	end
end


--============================================================
-- ROLE WATCHER
--============================================================

local LastRole =
	GetRole()


task.spawn(
	function()

		while ScreenGui.Parent do

			local role =
				GetRole()


			RoleLabel.Text =
				"Role: " ..
				role


			if role ~=
				LastRole then

				if Config.NotifyRoleChanges then

					Notify(
						"Role changed: " ..
						role
					)
				end


				--================================================
				-- BECAME RUNNER
				--================================================

				if role ==
					"Runner" then

					Config.AutoTag =
						false


					TagActive =
						false


					ReturnToTagPosition()


					TagTarget =
						nil
				end


				--================================================
				-- NO LONGER CHASER
				--================================================

				if role ~=
					"Chaser" then

					Config.AutoTag =
						false
				end


				LastRole =
					role
			end


			task.wait(
				0.15
			)
		end
	end
)


--============================================================
-- DEFAULT TAB
--============================================================

SwitchTab(
	"Auto"
)


--============================================================
-- STARTUP
--============================================================

Notify(
	"Sha4kHub loaded."
)


print(
	"[Sha4kHub] Loaded."
)


print(
	"[Sha4kHub] Role:",
	GetRole()
)


print(
	"[Sha4kHub] Auto Vault cooldown:",
	Config.AutoVaultCooldown,
	"second(s)"
)


print(
	"[Sha4kHub] Auto Pallet Stun:",
	Config.PalletStunDistance,
	"stud trigger"
)

Features & Information

With this you can: Highlight Pallets, Windows, Auto Break pallets, auto vault, Auto tag, Change Walkspeed and MORE! And is open source so you can mess with the code! just don't steal, or do idrc,
#Auto#Hub#AI#Ai Generated

Community Comments (0)

No comments yet for this script.

More Scripts for [🔥UPD] Tag Me