SAVX OP auto farm, auto rebirth and more! Keyless
Key Required

SAVX OP auto farm, auto rebirth and more! Keyless

[X2] +1 Cut Grass AdventureSkipz1Skipz1 114 views 29 executesUpdated Oct 3, 2026
Unrated
00
Lua Script•1161 lines (34437 chars)
-- Load Rayfield Library
local Rayfield = loadstring(game:HttpGet('https://sirius.menu/rayfield'))()

-- Runs a block safely; if it errors, shows the error on screen instead of silently killing the script
local function try(label, fn)
	local ok, err = pcall(fn)
	if not ok then
		warn("[" .. label .. "] " .. tostring(err))
		pcall(function()
			Rayfield:Notify({ Title = "Error: " .. label, Content = tostring(err), Duration = 10 })
		end)
	end
	return ok
end

local function notify(title, content)
	pcall(function()
		Rayfield:Notify({ Title = title, Content = content, Duration = 4 })
	end)
end

local Window = Rayfield:CreateWindow({
   Name = "+1 Cut Grass Adventure! | By SAVX",
   LoadingTitle = "Loading Script...",
   LoadingSubtitle = "",
   ConfigurationSaving = { Enabled = false },
   Discord = {
      Enabled = true,
      Invite = "jNxWhwcSTh", -- discord.gg/jNxWhwcSTh
      RememberJoins = true
   },
   KeySystem = false
})

-- Services
local Players = game:GetService("Players")
local Workspace = game:GetService("Workspace")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local TweenService = game:GetService("TweenService")
local UserInputService = game:GetService("UserInputService")

local LocalPlayer = Players.LocalPlayer

-- Safe remote lookup (never errors; warns + notifies if something is missing)
local function find(root, path)
	local cur = root
	for _, name in ipairs(string.split(path, "/")) do
		cur = cur and cur:FindFirstChild(name)
	end
	return cur
end

local Knit = find(ReplicatedStorage, "Packages/_Index/acecateer_knit@1.7.2/knit/Services")
local Missing = {}
local function remote(path)
	local r = Knit and find(Knit, path)
	if not r then table.insert(Missing, path) end
	return r
end

local StrengthClickRE = remote("StrengthService/RE/ClickRequested")
local NotificationRE = remote("NotificationService/RE/NotificationRequested")
local UnequipLootRF = remote("LootInventoryService/RF/UnequipLoot")
local ResetBackpackRF = remote("LootInventoryService/RF/ResetBackpackLoadAtBase")
local SellAllRF = remote("DataService/RF/SellAllBackpackLoot")
local BuyCutterRF = remote("CuttersShopService/RF/BuyCutter")
local EquipCutterRF = remote("CuttersShopService/RF/EquipCutter")
local GetShopStateRF = remote("CuttersShopService/RF/GetShopState")
local RebirthRE = remote("RebirtService/RE/RebirthButtonClicked") -- "Rebirt" spelling matches the game

-- State
local AutoFarmStrengthEnabled = false
local StrengthDelay = 0
local AutoCollectEnabled = false
local ReturnToStart = false
local AutoSellWhenFullEnabled = false
local TimedAutoSellEnabled = false
local AutoBuyCuttersEnabled = false
local AutoRebirthEnabled = false
local IsSelling = false
local PredictorBusy = false
local SellInterval = 5
local TravelSpeed = 0.3

local SelectedItems = {}      -- [normalizedName] = true
local SelectedRarities = {}   -- [lowercase rarity] = true
local RecentlyTried = {}      -- [instance] = tick()

-- Loot list
local RawLootList = {
	"01_Button", "02_Rusty_Nail", "03_Old_Coin", "04_Pocket_Watch", "05_Copper_Gear",
	"06_Silver_Spoon", "07_Medallion", "08_ Broken_Compass ", "09_ Dew_Crystal", "10_Key",
	"11_Moon_Flower", "12_Horseshoe", "13_ Violet_Shard", "14_Royal_Brooch", "15_Flaming_Ring",
	"16_Ancient_Goblet", "17_Golden_Feather", "18_Dragon_Tooth", "19_Obelisk", "20_Sun_Idol",
	"21_Black_Crystal", "22_Hourglass", "23_ Retro_Radio", "24_Ruby_Leaf", "25_ Clover_Prism",
	"26_Sealed_Scroll", "27_Tiny Portal", "28_Angel_Wing", "29_Comet_Heart", "30_Dawn_Diadem ",
	"31_Celestial_Star", "32_Moon_Fragment", "33_Living_Star", "34_Amber_Beetle", "35_Shaman_Mask",
	"36_Eternal_Flower", "37_Universe_Core", "38_Divine_Seal", "39_Light_Blade", "40_Chest",
	"41_Nebula_Rose", "42_Wishstone", "43_Genesis_Leaf", "44_Starlight_Dandelion", "45_Star_Nectar",
	"46_Aurora_Egg", "47_Rainbow_Snail", "48_Sunfire_Orb", "49_Seraph_Bell", "50_Storm_Seed",
	"51_Rune_Mushroom", "52_Celestial_Antler", "53_Spider_Charm", "54_Spirit_Feather", "55_Chrono_Moth",
	"56_Moondew_Pearl", "57_Fate_Dice", "58_Rift_Scythe", "59_Nova_Gauntlet", "60_Astral_Map",
	"61_Moonfish_Idol", "62_Zero_Compass", "63_Star_Sail", "64_Phoenix_Harp", "65_Rebirth_Mask",
	"66_Soul_Anchor", "67_Infinity_Blade", "68_Evernight_Owl", "69_Timewheel", "70_Titan_Hammer",
	"71_Origin_Chalice", "72_Leviathan_Scale", "73_Skyforge_Anvil", "74_Genesis_Gate", "75_Void_Telescope",
	"76_Meteor_Boots", "77_Orbit_Drum", "78_Nebula_Parasol", "79_Starcatcher_Net", "80_Lunar_Knight",
	"81_Verdant_Shield", "82_Rebirth_Bow", "83_Spirit_Pagoda", "84_Chrono_Codex", "85_Emerald_Warhorn",
	"86_Guardian_Scarab", "87_Abyss_Trident", "88_Dawn_Throne", "89_Colossus_Helm", "90_World_Cauldron",
	"91_Dragonbone_Totem", "92_Reality_Loom"
}

-- Rarity FALLBACK (a guess based on item number). If the game stores a real rarity
-- on the item, that is used instead. Edit the tiers below if needed.
local RarityTiers = {
	{ "Common",    1,  10 },
	{ "Uncommon", 11,  25 },
	{ "Rare",     26,  40 },
	{ "Epic",     41,  55 },
	{ "Legendary",56,  70 },
	{ "Mythic",   71,  92 },
}
local RarityOptions = {
	"Common", "Uncommon", "Rare", "Epic", "Legendary", "Mythic",
	"Secret", "Godly", "Divine", "Celestial", "Eternal", "Transcendent",
	"Cosmic", "Ascendant", "Primordial", "Exalted", "Infinite", "Genesis",
	"Anomalous", "Paradox", "Absolute", "Ashborn", "Magmaforged", "Cataclysmic",
}

-- Helpers
local function normalize(name)
	name = tostring(name):lower():gsub("^%s*%d+_", ""):gsub("[^%a]", "")
	return name
end

local function cleanLootName(rawName)
	local cleaned = rawName:gsub("^%s*%d+_", ""):gsub("_", " ")
	return cleaned:match("^%s*(.-)%s*$")
end

local ItemsByKey = {}        -- normalized -> {key, clean, num}
local CleanToKey = {}
local CleanLootOptions = {}

for _, raw in ipairs(RawLootList) do
	local clean = cleanLootName(raw)
	local key = normalize(raw)
	ItemsByKey[key] = { key = key, clean = clean, num = tonumber(raw:match("^%s*(%d+)")) or 0 }
	CleanToKey[clean] = key
	table.insert(CleanLootOptions, clean)
end

SelectedItems[normalize("Button")] = true

-- Cache: instance name -> item info (or false). Avoids re-running string ops on every part each scan.
local InfoByName = {}
local function itemInfo(name)
	local info = InfoByName[name]
	if info == nil then
		info = ItemsByKey[normalize(name)] or false
		InfoByName[name] = info
	end
	return info or nil
end

local function tierFromNumber(n)
	for _, t in ipairs(RarityTiers) do
		if n >= t[2] and n <= t[3] then return t[1] end
	end
	return "Unknown"
end

local function readRarity(inst)
	local a = inst:GetAttribute("Rarity") or inst:GetAttribute("rarity")
	if a ~= nil then return tostring(a) end
	local v = inst:FindFirstChild("Rarity")
	if v and v:IsA("ValueBase") then return tostring(v.Value) end
	return nil
end

-- Returns lowercase rarity, source ("game" or "guess")
local function getRarity(inst, info)
	local cur = inst
	for _ = 1, 4 do
		if not cur or cur == Workspace then break end
		local r = readRarity(cur)
		if r then return r:lower(), "game" end
		cur = cur.Parent
	end
	return tierFromNumber(info.num):lower(), "guess"
end

local function isPlayerStuff(inst)
	for _, p in ipairs(Players:GetPlayers()) do
		if p.Character and inst:IsDescendantOf(p.Character) then return true end
	end
	return false
end

local function getHRP()
	local c = LocalPlayer.Character
	return c and c:FindFirstChild("HumanoidRootPart")
end

-- Tween (with hard snap at the end so you always arrive)
local function sellingNow() return IsSelling end

local function tweenToCFrame(targetCFrame, duration, abortIf)
	local hrp = getHRP()
	if not hrp then return end
	duration = duration or TravelSpeed

	hrp.AssemblyLinearVelocity = Vector3.zero
	local tween = TweenService:Create(hrp, TweenInfo.new(duration, Enum.EasingStyle.Linear), { CFrame = targetCFrame })
	tween:Play()
	task.wait(duration + 0.05)
	tween:Cancel()

	-- something else (selling) took over the character; don't snap it back to this target
	if abortIf and abortIf() then return end

	if hrp.Parent then
		hrp.CFrame = targetCFrame
		hrp.AssemblyLinearVelocity = Vector3.zero
	end
end

-- Sell
local function getSellTarget()
	for _, obj in ipairs(Workspace:GetDescendants()) do
		if (obj:IsA("BasePart") or obj:IsA("Model")) and (obj.Name:lower():find("sell") or obj.Name:lower():find("base")) then
			local part = obj:IsA("BasePart") and obj or obj:FindFirstChildWhichIsA("BasePart", true)
			if part then return part end
		end
	end
	return nil
end

local function executeSell()
	if IsSelling then return end
	IsSelling = true

	local ok, err = pcall(function()
		local hrp = getHRP()
		if not hrp then return end

		local originalCFrame = hrp.CFrame
		local sellPart = getSellTarget()

		if sellPart then
			tweenToCFrame(sellPart.CFrame + Vector3.new(0, 3, 0), TravelSpeed)
			task.wait(0.1)

			local sellPrompt = sellPart.Parent:FindFirstChildWhichIsA("ProximityPrompt", true) or sellPart:FindFirstChildWhichIsA("ProximityPrompt", true)
			if sellPrompt then fireproximityprompt(sellPrompt) end

			local touch = sellPart:FindFirstChildWhichIsA("TouchTransmitter", true)
			if touch then
				firetouchinterest(hrp, sellPart, 0)
				task.wait(0.05)
				firetouchinterest(hrp, sellPart, 1)
			end
		end

		if UnequipLootRF then UnequipLootRF:InvokeServer() end
		if SellAllRF then SellAllRF:InvokeServer() end
		if ResetBackpackRF then ResetBackpackRF:InvokeServer() end

		task.wait(0.1)
		if hrp and hrp.Parent then
			tweenToCFrame(originalCFrame, TravelSpeed)
		end
	end)
	if not ok then warn("[Sell error]", err) end

	IsSelling = false
end

-- Find the nearest world item that passes the item whitelist OR the rarity whitelist
local function isWanted(inst, info)
	if SelectedItems[info.key] then return true end
	if next(SelectedRarities) then
		local rarity = getRarity(inst, info)
		if SelectedRarities[rarity] then return true end
	end
	return false
end

local function findNearestWanted(fromPos)
	local bestPart, bestRoot, bestDist = nil, nil, math.huge
	local now = tick()

	for _, obj in ipairs(Workspace:GetDescendants()) do
		if obj:IsA("Model") or obj:IsA("BasePart") then
			local info = itemInfo(obj.Name)
			if info and isWanted(obj, info) and not isPlayerStuff(obj)
				and not (RecentlyTried[obj] and now - RecentlyTried[obj] < 1.5) then

				local part = obj:IsA("BasePart") and obj or obj:FindFirstChildWhichIsA("BasePart", true)
				local prompt = part and (obj:FindFirstChildWhichIsA("ProximityPrompt", true) or part:FindFirstChildWhichIsA("ProximityPrompt", true))
				if part and prompt then
					local d = (part.Position - fromPos).Magnitude
					if d < bestDist then
						bestPart, bestRoot, bestDist = part, obj, d
					end
				end
			end
		end
	end

	return bestPart, bestRoot
end

local function collectOne()
	if IsSelling or PredictorBusy or not AutoCollectEnabled then return end

	local ok, err = pcall(function()
		local hrp = getHRP()
		if not hrp then return end

		local part, root = findNearestWanted(hrp.Position)
		if not part then return end

		RecentlyTried[root] = tick()
		local startCFrame = hrp.CFrame

		tweenToCFrame(part.CFrame, TravelSpeed, sellingNow)
		task.wait(0.05)

		if not IsSelling then
			local prompt = root:FindFirstChildWhichIsA("ProximityPrompt", true) or part:FindFirstChildWhichIsA("ProximityPrompt", true)
			if prompt then fireproximityprompt(prompt) end
			firetouchinterest(hrp, part, 0)
			firetouchinterest(hrp, part, 1)
			task.wait(0.05)
		end

		if ReturnToStart and not IsSelling then
			tweenToCFrame(startCFrame, TravelSpeed, sellingNow)
		end
	end)
	if not ok then warn("[Collect error]", err) end
end

-- Auto sell listener
if NotificationRE then
	NotificationRE.OnClientEvent:Connect(function()
		if AutoSellWhenFullEnabled then executeSell() end
	end)
end

-- Auto buy: buys the strongest affordable cutter in the shop
local FailedBuys = {}

local function buyBestAvailableCutter()
	if not (GetShopStateRF and BuyCutterRF) then return end
	local ok, err = pcall(function()
		local state = GetShopStateRF:InvokeServer()
		if type(state) ~= "table" or type(state.CuttersData) ~= "table" then return end

		local balance = tonumber(state.Balance) or 0
		local owned = state.OwnedCutters or {}
		local data = state.CuttersData

		-- strongest regular cutter already owned
		local bestOwnedMult = 0
		for name, isOwned in pairs(owned) do
			local info = data[name]
			if isOwned and info and info.Type == "Default" and (info.DamageMult or 0) > bestOwnedMult then
				bestOwnedMult = info.DamageMult
			end
		end

		-- buyable, affordable, and better than what we have
		local candidates = {}
		for name, info in pairs(data) do
			if not owned[name]
				and info.Type == "Default"
				and not info.EventOnly and not info.GamePassOnly and not info.HiddenUntilOwned
				and (info.Price or 0) > 0 and info.Price <= balance
				and (info.DamageMult or 0) > bestOwnedMult
				and not (FailedBuys[name] and tick() - FailedBuys[name] < 30) then
				table.insert(candidates, { name = name, mult = info.DamageMult })
			end
		end
		table.sort(candidates, function(a, b) return a.mult > b.mult end)

		-- don't swap away from an "OP" cutter (those give a bonus over your best cutter)
		local currentInfo = data[state.CurrentCutter]
		local keepCurrent = currentInfo and currentInfo.BestOwnedDamageBonus ~= nil

		for _, c in ipairs(candidates) do
			BuyCutterRF:InvokeServer(c.name)

			-- verify the purchase by re-reading the shop
			local newState = GetShopStateRF:InvokeServer()
			local bought = type(newState) == "table" and newState.OwnedCutters and newState.OwnedCutters[c.name]

			if bought then
				if not keepCurrent and EquipCutterRF then EquipCutterRF:InvokeServer(c.name) end
				break
			else
				FailedBuys[c.name] = tick() -- e.g. world not unlocked yet; retry later
			end
		end
	end)
	if not ok then warn("[AutoBuy error]", err) end
end

-- ---------------------------------------------------------
-- ITEM PREDICTOR (list of spawned items, most expensive first)
-- ---------------------------------------------------------
local PicturesOn = false
local ListParagraph
local PanelGui, PanelRows, PanelFrame, PanelEmpty
local PicturesToggle
local PanelExpanded = true
local PanelCount = 0
local PanelQueue = {}          -- items waiting to be collected
local CurrentTarget = nil      -- item being collected right now
local closePanel, enqueueItem
local LastScan = {}
local MAX_LIST = 10
local MAX_PICS = 5

-- Most expensive item overall (highest item number)
local TopItem
for _, info in pairs(ItemsByKey) do
	if not TopItem or info.num > TopItem.num then TopItem = info end
end

-- Uses a price stored on the item if the game has one, otherwise falls back to item number
local ValueNames = { "Price", "Value", "SellPrice", "SellValue", "Worth", "Cost", "Coins" }
local function readGameValue(inst)
	local cur = inst
	for _ = 1, 3 do
		if not cur or cur == Workspace then break end
		for _, n in ipairs(ValueNames) do
			local a = cur:GetAttribute(n)
			if type(a) == "number" then return a end
			local v = cur:FindFirstChild(n)
			if v and v:IsA("ValueBase") and type(v.Value) == "number" then return v.Value end
		end
		cur = cur.Parent
	end
	return nil
end

-- Spawned items sorted most expensive first, plus what they were ranked by
local function scanItems()
	local found, allGame = {}, true

	for _, obj in ipairs(Workspace:GetDescendants()) do
		if obj:IsA("Model") or obj:IsA("BasePart") then
			local info = itemInfo(obj.Name)
			if info and not isPlayerStuff(obj) then
				local parentInfo = obj.Parent and itemInfo(obj.Parent.Name)
				if not (parentInfo and parentInfo.key == info.key) then
					local part = obj:IsA("BasePart") and obj or obj:FindFirstChildWhichIsA("BasePart", true)
					local prompt = part and (obj:FindFirstChildWhichIsA("ProximityPrompt", true) or part:FindFirstChildWhichIsA("ProximityPrompt", true))
					if part and prompt then
						local gv = readGameValue(obj)
						if gv == nil then allGame = false end
						table.insert(found, { root = obj, part = part, info = info, gameValue = gv })
					end
				end
			end
		end
	end

	for _, f in ipairs(found) do
		f.value = (allGame and f.gameValue) or f.info.num
	end
	table.sort(found, function(a, b) return a.value > b.value end)

	return found, (allGame and #found > 0) and "game price" or "item number"
end

local function listText(found)
	if #found == 0 then return "No items spawned right now." end
	local hrp = getHRP()
	local lines = {}
	for i = 1, math.min(#found, MAX_LIST) do
		local f = found[i]
		local dist = hrp and math.floor((f.part.Position - hrp.Position).Magnitude) or 0
		table.insert(lines, i .. ". " .. f.info.clean .. " (#" .. f.info.num .. ") - " .. dist .. " studs")
	end
	if #found > MAX_LIST then
		table.insert(lines, "+" .. (#found - MAX_LIST) .. " more")
	end
	return table.concat(lines, "\n")
end

-- 3D picture of an item inside a ViewportFrame
local function setThumb(vp, root)
	vp:ClearAllChildren()
	pcall(function()
		local clone = root:Clone()
		if not clone then return end
		for _, d in ipairs(clone:GetDescendants()) do
			if d:IsA("LuaSourceContainer") or d:IsA("ProximityPrompt") then d:Destroy() end
		end
		clone.Parent = vp

		local cf, size
		if clone:IsA("Model") then
			cf, size = clone:GetBoundingBox()
		else
			cf, size = clone.CFrame, clone.Size
		end

		local cam = Instance.new("Camera")
		cam.Parent = vp
		vp.CurrentCamera = cam
		local dist = math.max(size.Magnitude, 1) * 1.1
		cam.CFrame = CFrame.lookAt(cf.Position + Vector3.new(1, 0.7, 1).Unit * dist, cf.Position)
	end)
end

-- Floating item panel: flat, black, square edges
local Theme = {
	Bg = Color3.new(0, 0, 0),
	Line = Color3.fromRGB(45, 45, 45),
	Border = Color3.fromRGB(70, 70, 70),
	Thumb = Color3.fromRGB(14, 14, 14),
	Text = Color3.new(1, 1, 1),
	Muted = Color3.fromRGB(150, 150, 150),
	Hover = Color3.fromRGB(35, 35, 35),
	Red = Color3.fromRGB(200, 45, 45),     -- idle
	Green = Color3.fromRGB(45, 175, 75),   -- collecting
	Blue = Color3.fromRGB(50, 110, 220),   -- waiting
}
local PANEL_W = 280
local HEADER_H = 30
local ROW_H = 56

-- Drag by the header (mouse and touch)
local function makeDraggable(handle, target)
	local dragging, dragStart, startPos

	handle.InputBegan:Connect(function(input)
		if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
			dragging = true
			dragStart = input.Position
			startPos = target.Position
			input.Changed:Connect(function()
				if input.UserInputState == Enum.UserInputState.End then dragging = false end
			end)
		end
	end)

	UserInputService.InputChanged:Connect(function(input)
		if dragging and (input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch) then
			local delta = input.Position - dragStart
			target.Position = UDim2.new(startPos.X.Scale, startPos.X.Offset + delta.X, startPos.Y.Scale, startPos.Y.Offset + delta.Y)
		end
	end)
end

local function panelHeight(n)
	if not PanelExpanded then return HEADER_H end
	if n == 0 then return HEADER_H + 30 end
	return HEADER_H + n * ROW_H
end

local function applyPanelSize(n)
	PanelCount = n
	if PanelFrame then
		PanelFrame.Size = UDim2.fromOffset(PANEL_W, panelHeight(n))
	end
end

local function inQueue(root)
	for _, q in ipairs(PanelQueue) do
		if q.root == root then return true end
	end
	return false
end

local function stateColor(root)
	if CurrentTarget == root then return Theme.Green end
	if inQueue(root) then return Theme.Blue end
	return Theme.Red
end

local function headerButton(parent, text, rightOffset)
	local b = Instance.new("TextButton")
	b.AnchorPoint = Vector2.new(1, 0.5)
	b.Position = UDim2.new(1, -rightOffset, 0.5, 0)
	b.Size = UDim2.fromOffset(24, 22)
	b.BackgroundColor3 = Theme.Bg
	b.BorderSizePixel = 0
	b.AutoButtonColor = false
	b.Font = Enum.Font.SourceSansBold
	b.Text = text
	b.TextSize = 18
	b.TextColor3 = Theme.Muted
	b.Parent = parent

	b.MouseEnter:Connect(function()
		b.BackgroundColor3 = Theme.Hover
		b.TextColor3 = Theme.Text
	end)
	b.MouseLeave:Connect(function()
		b.BackgroundColor3 = Theme.Bg
		b.TextColor3 = Theme.Muted
	end)
	return b
end

local function buildPanel()
	if PanelGui then return end

	local gui = Instance.new("ScreenGui")
	gui.Name = "ItemPredictorPanel"
	gui.ResetOnSpawn = false
	pcall(function()
		gui.Parent = (gethui and gethui()) or game:GetService("CoreGui")
	end)
	if not gui.Parent then gui.Parent = LocalPlayer:WaitForChild("PlayerGui") end

	local frame = Instance.new("Frame")
	frame.Name = "Panel"
	frame.Position = UDim2.new(1, -PANEL_W - 12, 0, 90)
	frame.Size = UDim2.fromOffset(PANEL_W, panelHeight(0))
	frame.BackgroundColor3 = Theme.Bg
	frame.BorderSizePixel = 1
	frame.BorderColor3 = Theme.Border
	frame.ClipsDescendants = true
	frame.Parent = gui

	-- Header
	local header = Instance.new("Frame")
	header.Name = "Header"
	header.Size = UDim2.new(1, 0, 0, HEADER_H)
	header.BackgroundColor3 = Theme.Bg
	header.BorderSizePixel = 0
	header.Active = true
	header.Parent = frame

	local title = Instance.new("TextLabel")
	title.Position = UDim2.fromOffset(8, 0)
	title.Size = UDim2.new(1, -70, 1, 0)
	title.BackgroundTransparency = 1
	title.Font = Enum.Font.SourceSansBold
	title.Text = "Item Predictor"
	title.TextColor3 = Theme.Text
	title.TextSize = 16
	title.TextXAlignment = Enum.TextXAlignment.Left
	title.Parent = header

	local minBtn = headerButton(header, "-", 34)
	local closeBtn = headerButton(header, "X", 6)

	local headerLine = Instance.new("Frame")
	headerLine.AnchorPoint = Vector2.new(0, 1)
	headerLine.Position = UDim2.new(0, 0, 1, 0)
	headerLine.Size = UDim2.new(1, 0, 0, 1)
	headerLine.BackgroundColor3 = Theme.Line
	headerLine.BorderSizePixel = 0
	headerLine.Parent = header

	makeDraggable(header, frame)

	-- Body
	local body = Instance.new("Frame")
	body.Position = UDim2.fromOffset(0, HEADER_H)
	body.Size = UDim2.new(1, 0, 1, -HEADER_H)
	body.BackgroundTransparency = 1
	body.Parent = frame

	local list = Instance.new("UIListLayout")
	list.SortOrder = Enum.SortOrder.LayoutOrder
	list.Parent = body

	local empty = Instance.new("TextLabel")
	empty.Position = UDim2.fromOffset(0, HEADER_H)
	empty.Size = UDim2.new(1, 0, 0, 30)
	empty.BackgroundTransparency = 1
	empty.Font = Enum.Font.SourceSans
	empty.Text = "No items spawned"
	empty.TextColor3 = Theme.Muted
	empty.TextSize = 15
	empty.Parent = frame

	local rows = {}
	for i = 1, MAX_PICS do
		local entry = { key = nil, item = nil }

		local row = Instance.new("Frame")
		row.LayoutOrder = i
		row.Size = UDim2.new(1, 0, 0, ROW_H)
		row.BackgroundColor3 = Theme.Bg
		row.BorderSizePixel = 0
		row.Visible = false
		row.Parent = body

		local line = Instance.new("Frame")
		line.AnchorPoint = Vector2.new(0, 1)
		line.Position = UDim2.new(0, 0, 1, 0)
		line.Size = UDim2.new(1, 0, 0, 1)
		line.BackgroundColor3 = Theme.Line
		line.BorderSizePixel = 0
		line.Parent = row

		local vp = Instance.new("ViewportFrame")
		vp.Position = UDim2.fromOffset(6, 6)
		vp.Size = UDim2.fromOffset(44, 44)
		vp.BackgroundColor3 = Theme.Thumb
		vp.BorderSizePixel = 1
		vp.BorderColor3 = Theme.Line
		vp.Parent = row

		local name = Instance.new("TextLabel")
		name.Position = UDim2.fromOffset(58, 9)
		name.Size = UDim2.new(1, -148, 0, 18)
		name.BackgroundTransparency = 1
		name.Font = Enum.Font.SourceSansBold
		name.TextColor3 = Theme.Text
		name.TextSize = 16
		name.TextXAlignment = Enum.TextXAlignment.Left
		name.TextTruncate = Enum.TextTruncate.AtEnd
		name.Parent = row

		local sub = Instance.new("TextLabel")
		sub.Position = UDim2.fromOffset(58, 29)
		sub.Size = UDim2.new(1, -148, 0, 16)
		sub.BackgroundTransparency = 1
		sub.Font = Enum.Font.SourceSans
		sub.TextColor3 = Theme.Muted
		sub.TextSize = 14
		sub.TextXAlignment = Enum.TextXAlignment.Left
		sub.Parent = row

		local btn = Instance.new("TextButton")
		btn.AnchorPoint = Vector2.new(1, 0.5)
		btn.Position = UDim2.new(1, -8, 0.5, 0)
		btn.Size = UDim2.fromOffset(74, 28)
		btn.BackgroundColor3 = Theme.Red
		btn.BorderSizePixel = 0
		btn.AutoButtonColor = false
		btn.Font = Enum.Font.SourceSansBold
		btn.Text = "COLLECT"
		btn.TextColor3 = Theme.Text
		btn.TextSize = 14
		btn.Parent = row

		btn.Activated:Connect(function()
			if entry.item and enqueueItem then enqueueItem(entry.item) end
		end)

		entry.frame, entry.vp, entry.name, entry.sub, entry.btn = row, vp, name, sub, btn
		rows[i] = entry
	end

	-- Minimize / close
	minBtn.Activated:Connect(function()
		PanelExpanded = not PanelExpanded
		minBtn.Text = PanelExpanded and "-" or "+"
		applyPanelSize(PanelCount)
	end)
	closeBtn.Activated:Connect(function()
		if closePanel then closePanel() end
	end)

	PanelGui, PanelRows, PanelFrame, PanelEmpty = gui, rows, frame, empty
end

local function updatePanel(found)
	if not (PicturesOn and PanelGui) then return end
	local hrp = getHRP()
	local count = math.min(#found, MAX_PICS)

	for i, row in ipairs(PanelRows) do
		local f = found[i]
		if f then
			local dist = hrp and math.floor((f.part.Position - hrp.Position).Magnitude) or 0
			row.item = f
			row.frame.Visible = true
			row.name.Text = f.info.clean
			row.sub.Text = "#" .. f.info.num .. "  -  " .. dist .. " studs"
			row.btn.BackgroundColor3 = stateColor(f.root)
			if row.key ~= f.info.key then
				row.key = f.info.key
				setThumb(row.vp, f.root)
			end
		else
			row.item = nil
			row.frame.Visible = false
			row.key = nil
		end
	end

	PanelEmpty.Visible = (count == 0)
	applyPanelSize(count)
end

local function setPictures(on)
	PicturesOn = on
	if on then
		local ok, err = pcall(buildPanel)
		if not ok or not PanelGui then
			PicturesOn = false
			warn("[Pictures error]", err)
			notify("Pictures failed", tostring(err))
			return
		end
		PanelGui.Enabled = true
		updatePanel(LastScan)
	elseif PanelGui then
		PanelGui.Enabled = false
	end
end

closePanel = function()
	setPictures(false)
	if PicturesToggle then
		pcall(function() PicturesToggle:Set(false) end)
	end
end

local function refreshPredictor()
	local found, source = scanItems()
	LastScan = found

	local top = found[1]
	local title = top and ("Most expensive available: " .. top.info.clean) or "Most expensive available: none spawned"
	local content = listText(found)
		.. "\n\nMost expensive in the game: " .. TopItem.clean .. " (#" .. TopItem.num .. ")"
		.. "\nRanked by " .. source

	if ListParagraph then
		pcall(function() ListParagraph:Set({ Title = title, Content = content }) end)
	end
	updatePanel(found)
end

-- Collects queued items one at a time (green = collecting, blue = waiting)
local function processQueue()
	if PredictorBusy then return end
	PredictorBusy = true

	task.spawn(function()
		local hrp0 = getHRP()
		local startCFrame = hrp0 and hrp0.CFrame

		while #PanelQueue > 0 do
			while IsSelling do task.wait(0.2) end

			local q = table.remove(PanelQueue, 1)
			CurrentTarget = q.root
			updatePanel(LastScan)

			local ok, err = pcall(function()
				local hrp = getHRP()
				if not hrp then return end
				if not (q.root.Parent and q.part.Parent) then return end -- already gone

				tweenToCFrame(q.part.CFrame, TravelSpeed, sellingNow)
				task.wait(0.05)

				local prompt = q.root:FindFirstChildWhichIsA("ProximityPrompt", true) or q.part:FindFirstChildWhichIsA("ProximityPrompt", true)
				if prompt then fireproximityprompt(prompt) end
				firetouchinterest(hrp, q.part, 0)
				firetouchinterest(hrp, q.part, 1)
				task.wait(0.1)
			end)
			if not ok then warn("[Predictor error]", err) end

			CurrentTarget = nil
			refreshPredictor()
		end

		if startCFrame and getHRP() then
			tweenToCFrame(startCFrame, TravelSpeed, sellingNow)
		end

		PredictorBusy = false
		refreshPredictor()
	end)
end

enqueueItem = function(f)
	if CurrentTarget == f.root or inQueue(f.root) then return end
	table.insert(PanelQueue, { root = f.root, part = f.part, info = f.info })
	updatePanel(LastScan)
	processQueue()
end

-- ---------------------------------------------------------
-- TAB 1: Auto Strength
-- ---------------------------------------------------------
try("Auto Strength tab", function()
	local StrengthTab = Window:CreateTab("Auto Strength", 4483362458)

	StrengthTab:CreateSection("Auto Farm Strength")

	StrengthTab:CreateToggle({
		Name = "Auto Farm Strength",
		CurrentValue = false,
		Flag = "AutoFarmStrengthToggle",
		Callback = function(Value)
			AutoFarmStrengthEnabled = Value
			if Value then
				task.spawn(function()
					while AutoFarmStrengthEnabled do
						if StrengthClickRE then StrengthClickRE:FireServer() end
						if StrengthDelay > 0 then task.wait(StrengthDelay) else task.wait() end
					end
				end)
			end
		end,
	})

	StrengthTab:CreateSlider({
		Name = "Click Delay (Seconds)",
		Range = {0, 1},
		Increment = 0.01,
		Suffix = "s",
		CurrentValue = 0,
		Flag = "StrengthDelaySlider",
		Callback = function(Value)
			StrengthDelay = Value
		end,
	})
end)

-- ---------------------------------------------------------
-- TAB 2: Auto Collect
-- ---------------------------------------------------------
try("Auto Collect tab", function()
	local CollectTab = Window:CreateTab("Auto Collect", 4483362458)

	CollectTab:CreateSection("Whitelist")

	CollectTab:CreateDropdown({
		Name = "Collect These Items",
		Options = CleanLootOptions,
		CurrentOption = {"Button"},
		MultipleOptions = true,
		Flag = "LootCleanDropdown",
		Callback = function(Options)
			SelectedItems = {}
			if type(Options) == "string" then Options = { Options } end
			for _, clean in ipairs(Options) do
				local key = CleanToKey[clean]
				if key then SelectedItems[key] = true end
			end
		end,
	})

	CollectTab:CreateDropdown({
		Name = "Collect These Rarities",
		Options = RarityOptions,
		CurrentOption = {},
		MultipleOptions = true,
		Flag = "RarityDropdown",
		Callback = function(Options)
			SelectedRarities = {}
			if type(Options) == "string" then Options = { Options } end
			for _, r in ipairs(Options) do
				SelectedRarities[r:lower()] = true
			end
		end,
	})

	CollectTab:CreateSection("Movement")

	CollectTab:CreateSlider({
		Name = "Tween Speed (Seconds)",
		Range = {0.1, 2},
		Increment = 0.1,
		Suffix = "s",
		CurrentValue = 0.3,
		Flag = "TweenSpeedSlider",
		Callback = function(Value)
			TravelSpeed = Value
		end,
	})

	CollectTab:CreateToggle({
		Name = "Return To Start After Each Pickup",
		CurrentValue = false,
		Flag = "ReturnToStartToggle",
		Callback = function(Value)
			ReturnToStart = Value
		end,
	})

	CollectTab:CreateToggle({
		Name = "Auto Collect",
		CurrentValue = false,
		Flag = "AutoCollectToggle",
		Callback = function(Value)
			AutoCollectEnabled = Value
			if Value then
				task.spawn(function()
					while AutoCollectEnabled do
						collectOne()
						task.wait(0.2)
					end
				end)
			end
		end,
	})
end)

-- ---------------------------------------------------------
-- TAB 3: Auto Sell
-- ---------------------------------------------------------
try("Auto Sell tab", function()
	local AutoSellTab = Window:CreateTab("Auto Sell", 4483362458)

	AutoSellTab:CreateToggle({
		Name = "Auto Sell When Full",
		CurrentValue = false,
		Flag = "AutoSellWhenFullToggle",
		Callback = function(Value)
			AutoSellWhenFullEnabled = Value
		end,
	})

	AutoSellTab:CreateToggle({
		Name = "Enable Timed Auto Sell",
		CurrentValue = false,
		Flag = "TimedSellToggle",
		Callback = function(Value)
			TimedAutoSellEnabled = Value
			if Value then
				task.spawn(function()
					while TimedAutoSellEnabled do
						task.wait(SellInterval)
						if TimedAutoSellEnabled then executeSell() end
					end
				end)
			end
		end,
	})

	AutoSellTab:CreateSlider({
		Name = "Sell Interval (Seconds)",
		Range = {0.1, 60},
		Increment = 0.1,
		Suffix = "s",
		CurrentValue = 5,
		Flag = "SellIntervalSlider",
		Callback = function(Value)
			SellInterval = Value
		end,
	})
end)

-- ---------------------------------------------------------
-- TAB 4: Auto Buy
-- ---------------------------------------------------------
try("Auto Buy tab", function()
	local AutoBuyTab = Window:CreateTab("Auto Buy", 4483362458)

	AutoBuyTab:CreateToggle({
		Name = "Auto Buy Best Cutter",
		CurrentValue = false,
		Flag = "AutoBuyCuttersToggle",
		Callback = function(Value)
			AutoBuyCuttersEnabled = Value
			if Value then
				task.spawn(function()
					while AutoBuyCuttersEnabled do
						buyBestAvailableCutter()
						task.wait(2)
					end
				end)
			end
		end,
	})
end)

-- ---------------------------------------------------------
-- TAB 5: Item Predictor
-- ---------------------------------------------------------
try("Item Predictor tab", function()
	local PredictorTab = Window:CreateTab("Item Predictor", 4483362458)

	PredictorTab:CreateSection("Available To Collect")

	ListParagraph = PredictorTab:CreateParagraph({
		Title = "Most expensive available",
		Content = "Scanning...",
	})

	PredictorTab:CreateButton({
		Name = "Collect Most Expensive Item",
		Callback = function()
			local top = scanItems()[1]
			if not top then
				notify("Nothing to collect", "No items spawned right now.")
				return
			end
			enqueueItem(top)
		end,
	})

	PredictorTab:CreateButton({
		Name = "Refresh",
		Callback = function()
			refreshPredictor()
		end,
	})

	PicturesToggle = PredictorTab:CreateToggle({
		Name = "Show Item Pictures",
		CurrentValue = false,
		Flag = "PredictorPicturesToggle",
		Callback = function(Value)
			setPictures(Value)
		end,
	})

	task.spawn(function()
		while true do
			pcall(refreshPredictor)
			task.wait(3)
		end
	end)
end)

-- ---------------------------------------------------------
-- TAB 6: Rebirth
-- ---------------------------------------------------------
try("Rebirth tab", function()
	local RebirthTab = Window:CreateTab("Rebirth", 4483362458)

	RebirthTab:CreateButton({
		Name = "Rebirth Now",
		Callback = function()
			if RebirthRE then RebirthRE:FireServer() end
		end,
	})

	RebirthTab:CreateToggle({
		Name = "Auto Rebirth",
		CurrentValue = false,
		Flag = "AutoRebirthToggle",
		Callback = function(Value)
			AutoRebirthEnabled = Value
			if Value then
				task.spawn(function()
					while AutoRebirthEnabled do
						if RebirthRE then RebirthRE:FireServer() end
						task.wait(2)
					end
				end)
			end
		end,
	})
end)

if #Missing > 0 then
	warn("[Missing remotes] " .. table.concat(Missing, ", "))
	Rayfield:Notify({ Title = "Missing remotes", Content = table.concat(Missing, ", "), Duration = 10 })
else
	Rayfield:Notify({ Title = "Loaded", Content = "All tabs built.", Duration = 3 })
end

Features & Information

This OP script has many features with more to come!! The script offer automated tasks like auto farm strength, auto rebirth, auto collect selected rarity’s or items. And auto sell!!
#SAVX#keyless#Keyless#Free#free

Community Comments (0)

No comments yet for this script.

More Scripts for [X2] +1 Cut Grass Adventure