Skip to content
WorkingCombat

Pistol Arena | Auto Shoot, Wallbang, ESP

DEDementor89387 viewsPistol ArenaJul 19, 2026
Share
Pistol Arena | Auto Shoot, Wallbang, ESP

Script Code

Lua
if getgenv().Library and typeof(getgenv().Library.Unload) == "function" and not getgenv().Library.Unloaded then
	pcall(function()
		getgenv().Library:Unload()
	end)
	task.wait(0.15)
end

local repo = "https://raw.githubusercontent.com/mstudio45/LinoriaLib/main/"
local Library = loadstring(game:HttpGet(repo .. "Library.lua"))()
local ThemeManager = loadstring(game:HttpGet(repo .. "addons/ThemeManager.lua"))()
local SaveManager = loadstring(game:HttpGet(repo .. "addons/SaveManager.lua"))()
local Options = Library.Options
local Toggles = Library.Toggles

local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local UserInputService = game:GetService("UserInputService")
local Lighting = game:GetService("Lighting")
local ReplicatedStorage = game:GetService("ReplicatedStorage")

local LocalPlayer = Players.LocalPlayer
local Camera = workspace.CurrentCamera

local RemoteEvents = ReplicatedStorage:WaitForChild("Events"):WaitForChild("RemoteEvents")
local RequestActionSync = ReplicatedStorage
	:WaitForChild("SystemResources")
	:WaitForChild("BufferCache")
	:WaitForChild("RequestActionSync")
local CharacterMuzzleFlash = RemoteEvents:WaitForChild("CharacterMuzzleFlash")
local ReplicateFakeBullet = RemoteEvents:WaitForChild("ReplicateFakeBullet")
local WeaponConfig = require(ReplicatedStorage.Modules.WeaponConfig)

local State = {
	AutoShoot = false,
	Sticky = true,
	Wallbang = true,
	VisibleCheck = false,
	FOV = 180,
	HitPart = "Head",
	Smoothness = 0.35,

	ESP = false,
	Boxes = true,
	Names = true,
	Distance = true,
	Health = true,
	Tracers = false,
	HeadDot = true,
	Skeleton = false,
	Offscreen = false,
	MaxDistance = 2000,

	Chams = false,
	ChamsFill = 0.45,
	ChamsOutline = 0,
	ChamsThroughWalls = true,
	LocalChams = false,
	GunChams = false,

	Fullbright = false,
	NoFog = false,
	Ambient = false,

	ShowFOV = true,
	Crosshair = false,
	CrosshairSize = 8,
	CrosshairGap = 4,

	Color = Color3.fromRGB(255, 255, 255),
	TracerColor = Color3.fromRGB(255, 255, 255),
	ChamsFillColor = Color3.fromRGB(255, 255, 255),
	ChamsOutlineColor = Color3.fromRGB(255, 255, 255),
	FOVColor = Color3.fromRGB(255, 255, 255),
	CrosshairColor = Color3.fromRGB(255, 255, 255),
}

local CurrentTarget = nil
local LastShot = 0
local ESPFolder = {}
local ChamFolder = {}
local LightingBackup = nil

local FOVCircle = Drawing.new("Circle")
FOVCircle.Thickness = 1
FOVCircle.NumSides = 64
FOVCircle.Filled = false
FOVCircle.ZIndex = 2
FOVCircle.Visible = false

local Cross = {
	T = Drawing.new("Line"),
	B = Drawing.new("Line"),
	L = Drawing.new("Line"),
	R = Drawing.new("Line"),
}
for _, line in pairs(Cross) do
	line.Thickness = 1
	line.Visible = false
	line.ZIndex = 3
end

local Connections = {}
local function bind(c)
	Connections[#Connections + 1] = c
	return c
end

local function wipeDrawings(bag)
	for _, obj in pairs(bag) do
		if typeof(obj) == "table" then
			wipeDrawings(obj)
		else
			pcall(function()
				obj:Remove()
			end)
		end
	end
end

local function cleanup()
	for _, c in ipairs(Connections) do
		pcall(function()
			c:Disconnect()
		end)
	end
	table.clear(Connections)
	for _, d in pairs(ESPFolder) do
		wipeDrawings(d)
	end
	table.clear(ESPFolder)
	for _, h in pairs(ChamFolder) do
		pcall(function()
			h:Destroy()
		end)
	end
	table.clear(ChamFolder)
	pcall(function()
		FOVCircle:Remove()
	end)
	wipeDrawings(Cross)
	if LightingBackup then
		for k, v in pairs(LightingBackup) do
			pcall(function()
				Lighting[k] = v
			end)
		end
	end
end

Library:OnUnload(cleanup)

local function getHumanoid(player)
	local char = player.Character
	return char and char:FindFirstChildOfClass("Humanoid")
end

local function getHRP(player)
	local char = player.Character
	return char and char:FindFirstChild("HumanoidRootPart")
end

local function alive(player)
	local hum = getHumanoid(player)
	return hum and hum.Health > 0
end

local function worldToScreen(pos)
	local v, on = Camera:WorldToViewportPoint(pos)
	return Vector2.new(v.X, v.Y), on, v.Z
end

local function los(from, to, ignore)
	local params = RaycastParams.new()
	params.FilterType = Enum.RaycastFilterType.Exclude
	params.FilterDescendantsInstances = ignore or { LocalPlayer.Character, Camera }
	params.IgnoreWater = true
	local result = workspace:Raycast(from, to - from, params)
	if not result then
		return true
	end
	local hit = result.Instance
	for _, plr in ipairs(Players:GetPlayers()) do
		if plr ~= LocalPlayer and plr.Character and hit:IsDescendantOf(plr.Character) then
			return true
		end
	end
	return false
end

local function hitPart(character, prefer)
	if not character then
		return
	end
	local part = character:FindFirstChild(prefer)
	if part and part:IsA("BasePart") then
		return part
	end
	if prefer == "Head" then
		part = character:FindFirstChild("HeadHitbox")
		if part and part:IsA("BasePart") then
			return part
		end
	end
	return character:FindFirstChild("HumanoidRootPart") or character:FindFirstChildWhichIsA("BasePart")
end

local function weaponReady()
	if LocalPlayer:GetAttribute("Deployed") ~= true then
		return false
	end
	local char = LocalPlayer.Character
	if not char then
		return false
	end
	local hum = char:FindFirstChildOfClass("Humanoid")
	if not (hum and hum.Health > 0) then
		return false
	end
	if not char:FindFirstChildOfClass("Tool") then
		return false
	end
	Camera = workspace.CurrentCamera
	return Camera and Camera:FindFirstChild("Viewmodel") ~= nil
end

local function getTarget()
	Camera = workspace.CurrentCamera
	if not Camera then
		return
	end

	local mouse = UserInputService:GetMouseLocation()
	local origin = Camera.CFrame.Position
	local look = Camera.CFrame.LookVector
	local maxDeg = math.clamp((State.FOV / math.max(Camera.ViewportSize.Y, 1)) * Camera.FieldOfView, 5, 180)
	local best, bestScore = nil, State.FOV
	local range = WeaponConfig.WeaponStats.Range or 1000

	for _, plr in ipairs(Players:GetPlayers()) do
		if plr == LocalPlayer or not alive(plr) then
			continue
		end
		local char = plr.Character
		if not char or char:FindFirstChild("SpawnProtection") then
			continue
		end
		local part = hitPart(char, State.HitPart)
		if not part then
			continue
		end

		local offset = part.Position - origin
		local dist = offset.Magnitude
		if dist < 1 or dist > range then
			continue
		end

		local dir = offset.Unit
		local ang = math.deg(math.acos(math.clamp(look:Dot(dir), -1, 1)))
		local screen, onScreen = worldToScreen(part.Position)
		local screenDist = onScreen and (screen - mouse).Magnitude or math.huge
		local inFov = screenDist <= State.FOV or (State.Wallbang and ang <= maxDeg)
		if not inFov then
			continue
		end

		if State.VisibleCheck then
			if not los(origin, part.Position, { LocalPlayer.Character, Camera, char }) then
				continue
			end
		end

		local score = onScreen and screenDist or (ang / maxDeg) * State.FOV
		if score <= bestScore then
			bestScore = score
			best = {
				Player = plr,
				Part = part,
				Humanoid = getHumanoid(plr),
				IsHeadshot = part.Name == "Head" or part.Name == "HeadHitbox",
			}
		end
	end

	if State.Sticky and CurrentTarget and CurrentTarget.Player and alive(CurrentTarget.Player) then
		local char = CurrentTarget.Player.Character
		if char and not char:FindFirstChild("SpawnProtection") then
			local part = hitPart(char, State.HitPart)
			if part then
				if State.VisibleCheck and not los(origin, part.Position, { LocalPlayer.Character, Camera, char }) then
					-- drop sticky if we can't see them anymore
				else
					local offset = part.Position - origin
					if offset.Magnitude >= 1 then
						local ang = math.deg(math.acos(math.clamp(look:Dot(offset.Unit), -1, 1)))
						local screen, onScreen = worldToScreen(part.Position)
						local screenDist = onScreen and (screen - mouse).Magnitude or math.huge
						if screenDist <= State.FOV * 1.35 or (State.Wallbang and ang <= maxDeg * 1.25) then
							CurrentTarget.Part = part
							CurrentTarget.Humanoid = getHumanoid(CurrentTarget.Player)
							CurrentTarget.IsHeadshot = part.Name == "Head" or part.Name == "HeadHitbox"
							return CurrentTarget
						end
					end
				end
			end
		end
	end

	CurrentTarget = best
	return best
end

local function smoothLook(goal, dt)
	Camera = workspace.CurrentCamera
	if not Camera then
		return
	end
	local smooth = math.clamp(State.Smoothness, 0, 1)
	if smooth <= 0.02 then
		Camera.CFrame = goal
		return
	end
	local speed = (1.05 - smooth) * 16
	Camera.CFrame = Camera.CFrame:Lerp(goal, math.clamp(dt * speed, 0, 1))
end

local function buildLegitShot()
	Camera = workspace.CurrentCamera
	local char = LocalPlayer.Character
	if not (Camera and char) then
		return
	end

	local stats = WeaponConfig.WeaponStats
	local range = stats.Range or 1000
	local radius = stats.BulletRadius or 0.75
	local origin = Camera.CFrame.Position
	local look = Camera.CFrame.LookVector
	local effects = workspace:FindFirstChild("Effects")
	local ragdolls = workspace:FindFirstChild("Ragdolls")

	local worldParams = RaycastParams.new()
	worldParams.FilterType = Enum.RaycastFilterType.Exclude
	local exclude = { char, Camera }
	if effects then
		exclude[#exclude + 1] = effects
	end
	if ragdolls then
		exclude[#exclude + 1] = ragdolls
	end
	for _, plr in ipairs(Players:GetPlayers()) do
		if plr.Character then
			exclude[#exclude + 1] = plr.Character
		end
	end
	worldParams.FilterDescendantsInstances = exclude

	local playerParams = RaycastParams.new()
	playerParams.FilterType = Enum.RaycastFilterType.Include
	local include = {}
	for _, plr in ipairs(Players:GetPlayers()) do
		if plr ~= LocalPlayer and plr.Character then
			include[#include + 1] = plr.Character
		end
	end
	playerParams.FilterDescendantsInstances = include

	local worldHit = workspace:Raycast(origin, look * range, worldParams)
	local playerHit = workspace:Spherecast(origin, radius, look * range, playerParams)

	local hitPosition, hitInstance, hitHumanoid = nil, nil, nil
	local worldDist = worldHit and (worldHit.Position - origin).Magnitude or (range + 1)
	local playerDist = playerHit and (playerHit.Position - origin).Magnitude or (range + 1)

	if playerHit and playerDist < worldDist then
		hitPosition = playerHit.Position
		local model = playerHit.Instance:FindFirstAncestorOfClass("Model")
		if model then
			hitHumanoid = model:FindFirstChildOfClass("Humanoid")
			local head = model:FindFirstChild("Head") or model:FindFirstChild("HeadHitbox")
			if head then
				local unit = look.Unit
				local along = (head.Position - origin):Dot(unit)
				if along > 0 and (head.Position - (origin + unit * along)).Magnitude <= radius * 1.1 then
					hitInstance = head
				else
					hitInstance = playerHit.Instance
				end
			else
				hitInstance = playerHit.Instance
			end
		else
			hitInstance = playerHit.Instance
		end
	elseif worldHit then
		hitPosition = worldHit.Position
		hitInstance = worldHit.Instance
	end

	local isHeadshot = hitInstance and (hitInstance.Name == "Head" or hitInstance.Name == "HeadHitbox") or false
	return {
		origin = origin,
		direction = look,
		hitPosition = hitPosition,
		hitInstance = hitInstance,
		hitHumanoid = hitHumanoid,
		IsHeadshot = isHeadshot,
	}
end

local function aimedAt(target, maxAngle)
	if not (target and target.Part and Camera) then
		return false
	end
	local origin = Camera.CFrame.Position
	local dir = (target.Part.Position - origin)
	if dir.Magnitude < 0.05 then
		return false
	end
	local ang = math.deg(math.acos(math.clamp(Camera.CFrame.LookVector:Dot(dir.Unit), -1, 1)))
	return ang <= (maxAngle or 2.5)
end

local function shoot(target)
	if not target or not target.Part or not target.Humanoid then
		return
	end
	if not weaponReady() or target.Humanoid.Health <= 0 then
		return
	end
	local char = target.Player and target.Player.Character
	if char and char:FindFirstChild("SpawnProtection") then
		return
	end

	-- wait until camera is actually on them (not silent)
	if not aimedAt(target, 3) then
		return
	end

	local reload = tonumber(WeaponConfig.WeaponStats.ReloadDuration) or 1.1
	local now = os.clock()
	if now - LastShot < reload then
		return
	end

	local payload = buildLegitShot()
	if not payload then
		return
	end

	-- only fire if the real ray hit this target (or any living enemy in FOV lock)
	if payload.hitHumanoid ~= target.Humanoid then
		return
	end

	LastShot = now
	RequestActionSync:FireServer(payload)
	pcall(function()
		CharacterMuzzleFlash:FireServer()
	end)
	pcall(function()
		ReplicateFakeBullet:FireServer(
			CFrame.new(payload.origin, payload.origin + payload.direction),
			payload.direction
		)
	end)
end

local function ensureESP(player)
	if ESPFolder[player] then
		return ESPFolder[player]
	end
	local d = {
		Box = Drawing.new("Square"),
		Name = Drawing.new("Text"),
		Dist = Drawing.new("Text"),
		Health = Drawing.new("Line"),
		Tracer = Drawing.new("Line"),
		Head = Drawing.new("Circle"),
		Arrow = Drawing.new("Triangle"),
		Bones = {},
	}
	d.Box.Filled = false
	d.Box.Thickness = 1
	d.Name.Size = 13
	d.Name.Center = true
	d.Name.Outline = true
	d.Dist.Size = 12
	d.Dist.Center = true
	d.Dist.Outline = true
	d.Health.Thickness = 2
	d.Tracer.Thickness = 1
	d.Head.Filled = true
	d.Head.NumSides = 16
	d.Head.Thickness = 1
	d.Arrow.Filled = true
	d.Arrow.Thickness = 1
	for i = 1, 12 do
		local bone = Drawing.new("Line")
		bone.Thickness = 1
		bone.Visible = false
		d.Bones[i] = bone
	end
	for _, obj in pairs(d) do
		if typeof(obj) ~= "table" then
			obj.Visible = false
		end
	end
	ESPFolder[player] = d
	return d
end

local function hideESP(d)
	d.Box.Visible = false
	d.Name.Visible = false
	d.Dist.Visible = false
	d.Health.Visible = false
	d.Tracer.Visible = false
	d.Head.Visible = false
	d.Arrow.Visible = false
	for _, bone in ipairs(d.Bones) do
		bone.Visible = false
	end
end

local BONE_PAIRS = {
	{ "Head", "UpperTorso" },
	{ "UpperTorso", "LowerTorso" },
	{ "UpperTorso", "LeftUpperArm" },
	{ "LeftUpperArm", "LeftLowerArm" },
	{ "LeftLowerArm", "LeftHand" },
	{ "UpperTorso", "RightUpperArm" },
	{ "RightUpperArm", "RightLowerArm" },
	{ "RightLowerArm", "RightHand" },
	{ "LowerTorso", "LeftUpperLeg" },
	{ "LeftUpperLeg", "LeftLowerLeg" },
	{ "LowerTorso", "RightUpperLeg" },
	{ "RightUpperLeg", "RightLowerLeg" },
}

local function drawSkeleton(d, character, color)
	for i, pair in ipairs(BONE_PAIRS) do
		local a = character:FindFirstChild(pair[1])
		local b = character:FindFirstChild(pair[2])
		local bone = d.Bones[i]
		if a and b and a:IsA("BasePart") and b:IsA("BasePart") then
			local p1, o1 = worldToScreen(a.Position)
			local p2, o2 = worldToScreen(b.Position)
			if o1 and o2 then
				bone.From = p1
				bone.To = p2
				bone.Color = color
				bone.Visible = true
			else
				bone.Visible = false
			end
		else
			bone.Visible = false
		end
	end
end

local function applyChams(player, enabled)
	local existing = ChamFolder[player]
	if not enabled then
		if existing then
			existing:Destroy()
			ChamFolder[player] = nil
		end
		return
	end
	local char = player.Character
	if not char then
		return
	end
	if existing and existing.Parent == char then
		existing.FillColor = State.ChamsFillColor
		existing.OutlineColor = State.ChamsOutlineColor
		existing.FillTransparency = State.ChamsFill
		existing.OutlineTransparency = State.ChamsOutline
		existing.DepthMode = State.ChamsThroughWalls and Enum.HighlightDepthMode.AlwaysOnTop
			or Enum.HighlightDepthMode.Occluded
		existing.Enabled = true
		return
	end
	if existing then
		existing:Destroy()
	end
	local hl = Instance.new("Highlight")
	hl.Name = "PA_Chams"
	hl.Adornee = char
	hl.FillColor = State.ChamsFillColor
	hl.OutlineColor = State.ChamsOutlineColor
	hl.FillTransparency = State.ChamsFill
	hl.OutlineTransparency = State.ChamsOutline
	hl.DepthMode = State.ChamsThroughWalls and Enum.HighlightDepthMode.AlwaysOnTop
		or Enum.HighlightDepthMode.Occluded
	hl.Parent = char
	ChamFolder[player] = hl
end

local function applyGunChams(enabled)
	local viewmodel = Camera and Camera:FindFirstChild("Viewmodel")
	local old = ChamFolder.__gun
	if not enabled or not viewmodel then
		if old then
			old:Destroy()
			ChamFolder.__gun = nil
		end
		return
	end
	if old and old.Parent == viewmodel then
		old.FillColor = State.ChamsFillColor
		old.OutlineColor = State.ChamsOutlineColor
		old.FillTransparency = State.ChamsFill
		old.OutlineTransparency = State.ChamsOutline
		return
	end
	if old then
		old:Destroy()
	end
	local hl = Instance.new("Highlight")
	hl.Name = "PA_GunChams"
	hl.Adornee = viewmodel
	hl.FillColor = State.ChamsFillColor
	hl.OutlineColor = State.ChamsOutlineColor
	hl.FillTransparency = State.ChamsFill
	hl.OutlineTransparency = State.ChamsOutline
	hl.DepthMode = Enum.HighlightDepthMode.AlwaysOnTop
	hl.Parent = viewmodel
	ChamFolder.__gun = hl
end

local function updateLighting()
	if not LightingBackup then
		LightingBackup = {
			Brightness = Lighting.Brightness,
			ClockTime = Lighting.ClockTime,
			FogEnd = Lighting.FogEnd,
			FogStart = Lighting.FogStart,
			Ambient = Lighting.Ambient,
			OutdoorAmbient = Lighting.OutdoorAmbient,
			GlobalShadows = Lighting.GlobalShadows,
		}
	end
	if State.Fullbright then
		Lighting.Brightness = 2
		Lighting.ClockTime = 14
		Lighting.GlobalShadows = false
		Lighting.Ambient = Color3.new(1, 1, 1)
		Lighting.OutdoorAmbient = Color3.new(1, 1, 1)
	elseif not State.Ambient then
		Lighting.Brightness = LightingBackup.Brightness
		Lighting.ClockTime = LightingBackup.ClockTime
		Lighting.GlobalShadows = LightingBackup.GlobalShadows
		Lighting.Ambient = LightingBackup.Ambient
		Lighting.OutdoorAmbient = LightingBackup.OutdoorAmbient
	end
	if State.NoFog then
		Lighting.FogEnd = 1e6
		Lighting.FogStart = 1e6
	else
		Lighting.FogEnd = LightingBackup.FogEnd
		Lighting.FogStart = LightingBackup.FogStart
	end
	if State.Ambient and not State.Fullbright then
		Lighting.Ambient = Color3.fromRGB(120, 120, 120)
		Lighting.OutdoorAmbient = Color3.fromRGB(120, 120, 120)
	end
end

bind(Players.PlayerRemoving:Connect(function(plr)
	if ESPFolder[plr] then
		wipeDrawings(ESPFolder[plr])
		ESPFolder[plr] = nil
	end
	if ChamFolder[plr] then
		ChamFolder[plr]:Destroy()
		ChamFolder[plr] = nil
	end
	if CurrentTarget and CurrentTarget.Player == plr then
		CurrentTarget = nil
	end
end))

bind(RunService.RenderStepped:Connect(function(dt)
	Camera = workspace.CurrentCamera
	local mouse = UserInputService:GetMouseLocation()
	local color = State.Color

	FOVCircle.Position = mouse
	FOVCircle.Radius = State.FOV
	FOVCircle.Color = State.FOVColor
	FOVCircle.Visible = State.ShowFOV and State.AutoShoot

	if State.Crosshair then
		local s, g = State.CrosshairSize, State.CrosshairGap
		local c = State.CrosshairColor
		Cross.T.From = Vector2.new(mouse.X, mouse.Y - g - s)
		Cross.T.To = Vector2.new(mouse.X, mouse.Y - g)
		Cross.B.From = Vector2.new(mouse.X, mouse.Y + g)
		Cross.B.To = Vector2.new(mouse.X, mouse.Y + g + s)
		Cross.L.From = Vector2.new(mouse.X - g - s, mouse.Y)
		Cross.L.To = Vector2.new(mouse.X - g, mouse.Y)
		Cross.R.From = Vector2.new(mouse.X + g, mouse.Y)
		Cross.R.To = Vector2.new(mouse.X + g + s, mouse.Y)
		for _, line in pairs(Cross) do
			line.Color = c
			line.Visible = true
		end
	else
		for _, line in pairs(Cross) do
			line.Visible = false
		end
	end

	if State.AutoShoot then
		local target = getTarget()
		if target and target.Part and weaponReady() then
			smoothLook(CFrame.lookAt(Camera.CFrame.Position, target.Part.Position), dt)
			shoot(target)
		end
	end

	applyGunChams(State.GunChams)
	applyChams(LocalPlayer, State.LocalChams)

	for _, plr in ipairs(Players:GetPlayers()) do
		if plr == LocalPlayer then
			continue
		end

		applyChams(plr, State.Chams)

		local d = ensureESP(plr)
		if not State.ESP or not alive(plr) then
			hideESP(d)
			continue
		end

		local char = plr.Character
		local hrp = getHRP(plr)
		local hum = getHumanoid(plr)
		local head = char and char:FindFirstChild("Head")
		if not (hrp and hum and head) then
			hideESP(d)
			continue
		end

		local dist3d = (hrp.Position - Camera.CFrame.Position).Magnitude
		if dist3d > State.MaxDistance then
			hideESP(d)
			continue
		end

		local top, on1 = worldToScreen(head.Position + Vector3.new(0, 0.55, 0))
		local bottom, on2 = worldToScreen(hrp.Position - Vector3.new(0, 3, 0))

		if not (on1 and on2) then
			hideESP(d)
			if State.Offscreen then
				local dir = (hrp.Position - Camera.CFrame.Position).Unit
				local flat = Vector3.new(dir.X, 0, dir.Z)
				if flat.Magnitude > 0 then
					local rel = Camera.CFrame:VectorToObjectSpace(flat.Unit)
					local ang = math.atan2(rel.X, -rel.Z)
					local radius = math.min(Camera.ViewportSize.X, Camera.ViewportSize.Y) * 0.35
					local cx = Camera.ViewportSize.X / 2
					local cy = Camera.ViewportSize.Y / 2
					local tip = Vector2.new(cx + math.sin(ang) * radius, cy - math.cos(ang) * radius)
					local left = tip + Vector2.new(math.sin(ang + 2.4) * 10, -math.cos(ang + 2.4) * 10)
					local right = tip + Vector2.new(math.sin(ang - 2.4) * 10, -math.cos(ang - 2.4) * 10)
					d.Arrow.PointA = tip
					d.Arrow.PointB = left
					d.Arrow.PointC = right
					d.Arrow.Color = color
					d.Arrow.Visible = true
				end
			end
			continue
		end

		local height = math.abs(bottom.Y - top.Y)
		local width = height / 1.85
		local boxPos = Vector2.new(top.X - width / 2, top.Y)

		if State.Boxes then
			d.Box.Size = Vector2.new(width, height)
			d.Box.Position = boxPos
			d.Box.Color = color
			d.Box.Visible = true
		else
			d.Box.Visible = false
		end

		if State.Names then
			d.Name.Text = plr.DisplayName
			d.Name.Position = Vector2.new(top.X, top.Y - 15)
			d.Name.Color = color
			d.Name.Visible = true
		else
			d.Name.Visible = false
		end

		if State.Distance then
			d.Dist.Text = math.floor(dist3d) .. "m"
			d.Dist.Position = Vector2.new(bottom.X, bottom.Y + 2)
			d.Dist.Color = color
			d.Dist.Visible = true
		else
			d.Dist.Visible = false
		end

		if State.Health then
			local pct = math.clamp(hum.Health / math.max(hum.MaxHealth, 1), 0, 1)
			local x = boxPos.X - 4
			d.Health.From = Vector2.new(x, bottom.Y)
			d.Health.To = Vector2.new(x, bottom.Y - height * pct)
			d.Health.Color = Color3.fromRGB(255 * (1 - pct), 255 * pct, 80)
			d.Health.Visible = true
		else
			d.Health.Visible = false
		end

		if State.Tracers then
			d.Tracer.From = Vector2.new(Camera.ViewportSize.X / 2, Camera.ViewportSize.Y)
			d.Tracer.To = Vector2.new(bottom.X, bottom.Y)
			d.Tracer.Color = State.TracerColor
			d.Tracer.Visible = true
		else
			d.Tracer.Visible = false
		end

		if State.HeadDot then
			local hp, hon = worldToScreen(head.Position)
			if hon then
				d.Head.Position = hp
				d.Head.Radius = math.clamp(width * 0.12, 2, 8)
				d.Head.Color = color
				d.Head.Visible = true
			else
				d.Head.Visible = false
			end
		else
			d.Head.Visible = false
		end

		if State.Skeleton then
			drawSkeleton(d, char, color)
		else
			for _, bone in ipairs(d.Bones) do
				bone.Visible = false
			end
		end

		d.Arrow.Visible = false
	end
end))

-- UI
local Window = Library:CreateWindow({
	Title = "pistol arena",
	Center = true,
	AutoShow = true,
	TabPadding = 8,
	MenuFadeTime = 0.15,
})

local Tabs = {
	Combat = Window:AddTab("Combat"),
	Visuals = Window:AddTab("Visuals"),
	Settings = Window:AddTab("Settings"),
}

local Aim = Tabs.Combat:AddLeftGroupbox("Aim")
Aim:AddToggle("AutoShoot", {
	Text = "Auto Shoot",
	Default = false,
	Callback = function(v)
		State.AutoShoot = v
	end,
}):AddKeyPicker("AutoShootKey", {
	Default = "None",
	SyncToggleState = true,
	Mode = "Toggle",
	Text = "Auto Shoot",
})
Aim:AddToggle("Sticky", {
	Text = "Sticky Target",
	Default = true,
	Callback = function(v)
		State.Sticky = v
	end,
})
Aim:AddToggle("Wallbang", {
	Text = "Wallbang",
	Default = true,
	Callback = function(v)
		State.Wallbang = v
	end,
})
Aim:AddToggle("VisibleCheck", {
	Text = "Visible Check",
	Default = false,
	Callback = function(v)
		State.VisibleCheck = v
	end,
})
Aim:AddSlider("FOV", {
	Text = "FOV",
	Default = 180,
	Min = 20,
	Max = 800,
	Rounding = 0,
	Callback = function(v)
		State.FOV = v
	end,
})
Aim:AddDropdown("HitPart", {
	Values = { "Head", "HumanoidRootPart", "UpperTorso", "Torso" },
	Default = 1,
	Multi = false,
	Text = "Hit Part",
	Callback = function(v)
		State.HitPart = v
	end,
})
Aim:AddSlider("Smoothness", {
	Text = "Smoothness",
	Default = 0.35,
	Min = 0,
	Max = 1,
	Rounding = 2,
	Callback = function(v)
		State.Smoothness = v
	end,
})

local EspBox = Tabs.Visuals:AddLeftGroupbox("ESP")
EspBox:AddToggle("ESP", {
	Text = "Enabled",
	Default = false,
	Callback = function(v)
		State.ESP = v
	end,
}):AddKeyPicker("ESPKey", {
	Default = "None",
	SyncToggleState = true,
	Mode = "Toggle",
	Text = "ESP",
})
EspBox:AddToggle("Boxes", {
	Text = "Boxes",
	Default = true,
	Callback = function(v)
		State.Boxes = v
	end,
})
EspBox:AddToggle("Names", {
	Text = "Names",
	Default = true,
	Callback = function(v)
		State.Names = v
	end,
})
EspBox:AddToggle("Distance", {
	Text = "Distance",
	Default = true,
	Callback = function(v)
		State.Distance = v
	end,
})
EspBox:AddToggle("Health", {
	Text = "Health Bar",
	Default = true,
	Callback = function(v)
		State.Health = v
	end,
})
EspBox:AddToggle("Tracers", {
	Text = "Tracers",
	Default = false,
	Callback = function(v)
		State.Tracers = v
	end,
})
EspBox:AddToggle("HeadDot", {
	Text = "Head Dot",
	Default = true,
	Callback = function(v)
		State.HeadDot = v
	end,
})
EspBox:AddToggle("Skeleton", {
	Text = "Skeleton",
	Default = false,
	Callback = function(v)
		State.Skeleton = v
	end,
})
EspBox:AddToggle("Offscreen", {
	Text = "Offscreen Arrows",
	Default = false,
	Callback = function(v)
		State.Offscreen = v
	end,
})
EspBox:AddSlider("MaxDistance", {
	Text = "Max Distance",
	Default = 2000,
	Min = 100,
	Max = 5000,
	Rounding = 0,
	Callback = function(v)
		State.MaxDistance = v
	end,
})
EspBox:AddLabel("Color"):AddColorPicker("ESPColor", {
	Default = State.Color,
	Title = "ESP",
	Callback = function(c)
		State.Color = c
	end,
})
EspBox:AddLabel("Tracers"):AddColorPicker("TracerColor", {
	Default = State.TracerColor,
	Title = "Tracers",
	Callback = function(c)
		State.TracerColor = c
	end,
})

local ChamsBox = Tabs.Visuals:AddRightGroupbox("Chams")
ChamsBox:AddToggle("Chams", {
	Text = "Enemy Chams",
	Default = false,
	Callback = function(v)
		State.Chams = v
	end,
})
ChamsBox:AddToggle("ChamsWalls", {
	Text = "Through Walls",
	Default = true,
	Callback = function(v)
		State.ChamsThroughWalls = v
	end,
})
ChamsBox:AddToggle("LocalChams", {
	Text = "Local Chams",
	Default = false,
	Callback = function(v)
		State.LocalChams = v
	end,
})
ChamsBox:AddToggle("GunChams", {
	Text = "Gun Chams",
	Default = false,
	Callback = function(v)
		State.GunChams = v
	end,
})
ChamsBox:AddSlider("ChamsFill", {
	Text = "Fill Transparency",
	Default = 0.45,
	Min = 0,
	Max = 1,
	Rounding = 2,
	Callback = function(v)
		State.ChamsFill = v
	end,
})
ChamsBox:AddSlider("ChamsOutline", {
	Text = "Outline Transparency",
	Default = 0,
	Min = 0,
	Max = 1,
	Rounding = 2,
	Callback = function(v)
		State.ChamsOutline = v
	end,
})
ChamsBox:AddLabel("Fill"):AddColorPicker("ChamsFillColor", {
	Default = State.ChamsFillColor,
	Title = "Fill",
	Callback = function(c)
		State.ChamsFillColor = c
	end,
})
ChamsBox:AddLabel("Outline"):AddColorPicker("ChamsOutlineColor", {
	Default = State.ChamsOutlineColor,
	Title = "Outline",
	Callback = function(c)
		State.ChamsOutlineColor = c
	end,
})

local WorldBox = Tabs.Visuals:AddRightGroupbox("World")
WorldBox:AddToggle("ShowFOV", {
	Text = "FOV Circle",
	Default = true,
	Callback = function(v)
		State.ShowFOV = v
	end,
})
WorldBox:AddLabel("FOV"):AddColorPicker("FOVColor", {
	Default = State.FOVColor,
	Title = "FOV",
	Callback = function(c)
		State.FOVColor = c
	end,
})
WorldBox:AddToggle("Crosshair", {
	Text = "Crosshair",
	Default = false,
	Callback = function(v)
		State.Crosshair = v
	end,
})
WorldBox:AddSlider("CrosshairSize", {
	Text = "Crosshair Size",
	Default = 8,
	Min = 2,
	Max = 30,
	Rounding = 0,
	Callback = function(v)
		State.CrosshairSize = v
	end,
})
WorldBox:AddSlider("CrosshairGap", {
	Text = "Crosshair Gap",
	Default = 4,
	Min = 0,
	Max = 20,
	Rounding = 0,
	Callback = function(v)
		State.CrosshairGap = v
	end,
})
WorldBox:AddLabel("Crosshair"):AddColorPicker("CrosshairColor", {
	Default = State.CrosshairColor,
	Title = "Crosshair",
	Callback = function(c)
		State.CrosshairColor = c
	end,
})
WorldBox:AddDivider()
WorldBox:AddToggle("Fullbright", {
	Text = "Fullbright",
	Default = false,
	Callback = function(v)
		State.Fullbright = v
		updateLighting()
	end,
})
WorldBox:AddToggle("NoFog", {
	Text = "No Fog",
	Default = false,
	Callback = function(v)
		State.NoFog = v
		updateLighting()
	end,
})
WorldBox:AddToggle("Ambient", {
	Text = "Soft Ambient",
	Default = false,
	Callback = function(v)
		State.Ambient = v
		updateLighting()
	end,
})

local Menu = Tabs.Settings:AddLeftGroupbox("Menu")
Menu:AddLabel("Menu bind"):AddKeyPicker("MenuKeybind", {
	Default = "RightShift",
	NoUI = true,
	Text = "Menu keybind",
})
Library.ToggleKeybind = Options.MenuKeybind
Menu:AddButton({
	Text = "Unload",
	Func = function()
		Library:Unload()
	end,
})

ThemeManager:SetLibrary(Library)
SaveManager:SetLibrary(Library)
SaveManager:IgnoreThemeSettings()
SaveManager:SetIgnoreIndexes({ "MenuKeybind" })
ThemeManager:SetFolder("PistolArena")
SaveManager:SetFolder("PistolArena/configs")
SaveManager:BuildConfigSection(Tabs.Settings)
ThemeManager:ApplyToTab(Tabs.Settings)
SaveManager:LoadAutoloadConfig()

Description

Pistol Arena a Linoria-based script built for Pistol Arena with aim assist, ESP, and visual utilities in one clean menu. Aim Auto shoot with sticky target lock Wallbang + optional visibility check Adjustable FOV, hit part, and smoothness FOV circle overlay Visuals Full ESP: boxes, names, distance, health, tracers, head dots, skeleton, offscreen indicators Player / local / gun chams with through-walls support Custom colors across ESP, tracers, and chams World Custom crosshair Fullbright, no fog, ambient lighting tweaks

Comments (0)

Log in to join the conversation

  • Be the first to comment.

Frequently asked questions

How do I use the Pistol Arena | Auto Shoot, Wallbang, ESP script?
Copy the script code above, join Pistol Arena on Roblox, then paste and execute the code in your executor. The features activate as soon as the script runs.
Is Pistol Arena | Auto Shoot, Wallbang, ESP still working?
Yes — Pistol Arena | Auto Shoot, Wallbang, ESP is currently marked as working (last updated Sep 18, 2026). If it breaks after a Roblox update, check back soon for a refreshed version.
Which executor works with Pistol Arena | Auto Shoot, Wallbang, ESP?
This script works with most popular Roblox executors. Check our executors page to find a trusted free or paid executor for your device.