--// Made by @DirectMemoryAccess local Players = game:GetService("Players") local ReplicatedStorage = game:GetService("ReplicatedStorage") local Workspace = game:GetService("Workspace") local TweenService = game:GetService("TweenService") local RunService = game:GetService("RunService") local Settings = { Farming = { Enabled = true, AutoStart = true, RefreshRate = 0.3, TweenSpeed = 14, MaxDistance = 1.2, MaxDuration = 3.5, MinDuration = 0.6, FollowOffset = 4, PhotoRange = 10, MaxAttempts = 60, } } local S = Settings.Farming --// tasks local AREA_TASKS = { { canonical = "Rooftop", aliases = { "rooftop", "roof" } }, { canonical = "Courtyard", aliases = { "courtyard", "court yard" } }, { canonical = "Cafeteria", aliases = { "cafeteria", "cafe", "lunch room", "lunchroom" } }, { canonical = "Basketball Court", aliases = { "basketball court", "basketball", "bball court" } }, { canonical = "Dojo Room", aliases = { "dojo room", "dojo" } }, { canonical = "Music Room", aliases = { "music room", "music" } }, { canonical = "Parking Lot", aliases = { "parking lot", "parking", "car park" } }, { canonical = "Nishikata High Entrance", aliases = { "nishikata high entrance", "school entrance", "entrance", "nishikata entrance", "high entrance", "school front", "front entrance" } }, { canonical = "Infirmary", aliases = { "infirmary", "nurse office", "nurse's office", "medical room" } }, { canonical = "Study Room", aliases = { "study room", "study", "library" } }, { canonical = "Lounge", aliases = { "lounge" } }, { canonical = "GAKUMART", aliases = { "gakumart", "mart", "store", "shop" } }, { canonical = "Nishikata District", aliases = { "nishikata district", "district", "nishikata" } }, } local LocalPlayer = Players.LocalPlayer local Character, HRP, Humanoid local phoneScreenPush = nil local photoJobSubmit = nil local State = { farming = false, processing = false, following = false, tweening = false, lastTask = "", taskCount = 0, } local followConnection = nil local currentTween = nil --// handler local function bindCharacter(char) Character = char HRP = char:WaitForChild("HumanoidRootPart") Humanoid = char:WaitForChild("Humanoid") if followConnection then followConnection:Disconnect() followConnection = nil State.following = false end if currentTween then currentTween:Cancel() currentTween = nil State.tweening = false end for _, p in ipairs(char:GetDescendants()) do if p:IsA("BasePart") then p.CanCollide = true end end end local Util = {} function Util.findRemotes() local remotes = ReplicatedStorage:FindFirstChild("Remotes") if not remotes then return false end phoneScreenPush = remotes:FindFirstChild("PhoneScreenPush") photoJobSubmit = remotes:FindFirstChild("PhotoJobSubmit") return phoneScreenPush ~= nil and photoJobSubmit ~= nil end function Util.startPhotoJob() if not photoJobSubmit then return end pcall(photoJobSubmit.InvokeServer, photoJobSubmit, "Start") task.wait(0.5) end function Util.setCollision(enabled) if not Character then return end for _, p in ipairs(Character:GetDescendants()) do if p:IsA("BasePart") then p.CanCollide = enabled end end end function Util.cancelActiveTween() if currentTween then currentTween:Cancel() currentTween = nil end State.tweening = false end --// tween functions function Util.smoothTween(targetPos) if not HRP then return end Util.cancelActiveTween() local origin = HRP.Position local dist = (targetPos - origin).Magnitude if dist < S.MaxDistance then HRP.CFrame = CFrame.new(targetPos) Util.setCollision(true) return end Util.setCollision(false) State.tweening = true local duration = math.clamp(dist / S.TweenSpeed, S.MinDuration, S.MaxDuration) local midPos = origin:Lerp(targetPos, 0.55) local phase1 = TweenService:Create( HRP, TweenInfo.new(duration * 0.55, Enum.EasingStyle.Quad, Enum.EasingDirection.In), { CFrame = CFrame.new(midPos) } ) local phase2 = TweenService:Create( HRP, TweenInfo.new(duration * 0.45, Enum.EasingStyle.Cubic, Enum.EasingDirection.Out), { CFrame = CFrame.new(targetPos) } ) currentTween = phase1 phase1:Play() phase1.Completed:Wait() if not State.farming then Util.cancelActiveTween() Util.setCollision(true) return end currentTween = phase2 phase2:Play() phase2.Completed:Wait() currentTween = nil Util.setCollision(true) State.tweening = false task.wait(0.08) end function Util.fastFollowTween(targetPos) if not HRP or State.tweening then return end State.tweening = true Util.setCollision(false) local dist = (targetPos - HRP.Position).Magnitude local dur = math.clamp(dist / (S.TweenSpeed * 1.6), 0.25, 1.4) if currentTween then currentTween:Cancel() end currentTween = TweenService:Create( HRP, TweenInfo.new(dur, Enum.EasingStyle.Exponential, Enum.EasingDirection.Out), { CFrame = CFrame.new(targetPos) } ) currentTween:Play() currentTween.Completed:Wait() currentTween = nil State.tweening = false end --// photo functions function Util.takePhoto(targetPos) if not phoneScreenPush or not photoJobSubmit or not HRP then return end local buf = buffer.create(7) buffer.writeu8(buf, 0, 1) buffer.writeu8(buf, 1, 4) buffer.writeu8(buf, 2, 0) buffer.writeu8(buf, 3, 1) buffer.writeu8(buf, 4, 1) buffer.writeu8(buf, 5, 42) buffer.writeu8(buf, 6, 24) pcall(phoneScreenPush.FireServer, phoneScreenPush, buf) task.wait(0.15) local lookAt = targetPos or (HRP.Position + HRP.CFrame.LookVector * 10) pcall(photoJobSubmit.InvokeServer, photoJobSubmit, "Submit", CFrame.new(HRP.Position, lookAt)) task.wait(0.15) end --// find functions function Util.findPlayer(name) local low = name:lower() for _, p in ipairs(Players:GetPlayers()) do if p ~= LocalPlayer then if p.Name:lower():find(low, 1, true) or p.DisplayName:lower():find(low, 1, true) then if p.Character and p.Character:FindFirstChild("HumanoidRootPart") then return p end end end end return nil end local function fuzzyScore(haystack, needle) local score = 0 for word in needle:gmatch("%S+") do if #word > 2 and haystack:find(word, 1, true) then score = score + 1 end end return score end function Util.normalizeTaskText(raw) return raw :gsub("^get a photo of ", "") :gsub("^a photo of ", "") :gsub("^photo of ", "") :gsub("^the ", "") :lower() :match("^%s*(.-)%s*$") end function Util.resolveCanonical(normalized) for _, entry in ipairs(AREA_TASKS) do for _, alias in ipairs(entry.aliases) do if normalized == alias then return entry.canonical end end end for _, entry in ipairs(AREA_TASKS) do for _, alias in ipairs(entry.aliases) do if normalized:find(alias, 1, true) or alias:find(normalized, 1, true) then return entry.canonical end end end local bestScore = 0 local bestCanonical = nil for _, entry in ipairs(AREA_TASKS) do for _, alias in ipairs(entry.aliases) do local s = fuzzyScore(alias, normalized) + fuzzyScore(normalized, alias) if s > bestScore then bestScore = s bestCanonical = entry.canonical end end end if bestScore > 0 then return bestCanonical end return nil end function Util.findLocation(raw) local normalized = Util.normalizeTaskText(raw) local canonical = Util.resolveCanonical(normalized) local searchTerms = {} if canonical then table.insert(searchTerms, canonical:lower()) end table.insert(searchTerms, normalized) for word in normalized:gmatch("%S+") do if #word > 3 then table.insert(searchTerms, word) end end local bestPart = nil local bestScore = 0 for _, obj in ipairs(Workspace:GetDescendants()) do if obj:IsA("BasePart") then local objName = obj.Name:lower() for _, term in ipairs(searchTerms) do if objName:find(term, 1, true) then local s = fuzzyScore(objName, term) + 1 if s > bestScore then bestScore = s bestPart = obj end end end local lm = obj:FindFirstChild("PhotoJobLandmark") if lm and lm.Value then local lmVal = lm.Value:lower() for _, term in ipairs(searchTerms) do if lmVal:find(term, 1, true) then local s = fuzzyScore(lmVal, term) + 2 if s > bestScore then bestScore = s bestPart = obj end end end end end end return bestPart and bestPart.Position or nil end --// gui functions function Util.getTaskText() local gui = LocalPlayer:FindFirstChild("PlayerGui") if not gui then return nil end local jobGui = gui:FindFirstChild("PhotoJobGui") if not jobGui then return nil end local card = jobGui:FindFirstChild("Card") if not card then return nil end local label = card:FindFirstChild("Task") if not label or not label:IsA("TextLabel") then return nil end return label.Text end local function isKnownArea(text) local low = text:lower() for _, entry in ipairs(AREA_TASKS) do for _, alias in ipairs(entry.aliases) do if low:find(alias, 1, true) then return true end end end return false end --// task handlers local function handlePlayerTask(playerName) local targetPlayer = Util.findPlayer(playerName) if not targetPlayer then return end State.following = true followConnection = RunService.Heartbeat:Connect(function() if not State.following or not targetPlayer or not targetPlayer.Character then State.following = false return end local tRoot = targetPlayer.Character:FindFirstChild("HumanoidRootPart") if not tRoot or not HRP then return end local goal = tRoot.Position + Vector3.new(S.FollowOffset, 0, S.FollowOffset) if (goal - HRP.Position).Magnitude > 3 then Util.fastFollowTween(goal) end if HRP then HRP.CFrame = CFrame.new(HRP.Position, tRoot.Position) end end) local attempts = 0 local photoTaken = false while attempts < S.MaxAttempts and State.farming and State.following do if not targetPlayer or not targetPlayer.Character then targetPlayer = Util.findPlayer(playerName) if not targetPlayer then break end end local tRoot = targetPlayer.Character:FindFirstChild("HumanoidRootPart") if tRoot and HRP then if (tRoot.Position - HRP.Position).Magnitude < S.PhotoRange then Util.cancelActiveTween() Util.setCollision(true) Util.takePhoto(tRoot.Position) photoTaken = true break end end task.wait(0.3) attempts += 1 end State.following = false if followConnection then followConnection:Disconnect() followConnection = nil end Util.setCollision(true) State.tweening = false if not photoTaken and targetPlayer and targetPlayer.Character then local tRoot = targetPlayer.Character:FindFirstChild("HumanoidRootPart") if tRoot then Util.smoothTween(tRoot.Position + Vector3.new(S.FollowOffset, 0, S.FollowOffset)) task.wait(0.2) Util.takePhoto(tRoot.Position) end end end local function handleLocationTask(taskText) local pos = Util.findLocation(taskText) if not pos then return end Util.smoothTween(pos) task.wait(0.2) Util.takePhoto(pos) end --// process task local function processTask() if State.processing or not State.farming then return end local taskText = Util.getTaskText() if not taskText or taskText == "" or taskText == "Waiting for assignment..." then return end if taskText == State.lastTask then return end State.lastTask = taskText State.processing = true State.taskCount += 1 local low = taskText:lower() local hasPhotoOf = low:find("get a photo of ") ~= nil local hasThe = low:find(" the ") ~= nil or low:find("^the ") ~= nil local knownArea = isKnownArea(taskText) local hasPlayer = low:find("player") ~= nil local isPlayerTask = hasPlayer or (hasPhotoOf and not hasThe and not knownArea) if isPlayerTask then local playerName = taskText :gsub("^get a photo of ", "") :gsub("^a photo of ", "") :gsub("^photo of ", "") handlePlayerTask(playerName) else handleLocationTask(taskText) end Util.setCollision(true) State.tweening = false task.wait(0.5) State.processing = false State.lastTask = "" end --// farm loop local function farmLoop() while State.farming do if not State.processing then processTask() end task.wait(S.RefreshRate) end end --// setup local initChar = LocalPlayer.Character or LocalPlayer.CharacterAdded:Wait() bindCharacter(initChar) LocalPlayer.CharacterAdded:Connect(bindCharacter) --// main task.spawn(function() local tries = 0 while not Util.findRemotes() and tries < 10 do task.wait(1) tries += 1 end Util.startPhotoJob() if S.AutoStart then State.farming = true task.spawn(farmLoop) end end) --// global functions _G.StopFarming = function() State.farming = false State.following = false State.tweening = false State.processing = false if followConnection then followConnection:Disconnect(); followConnection = nil end if currentTween then currentTween:Cancel(); currentTween = nil end Util.setCollision(true) end _G.StartFarming = function() if State.farming then return end State.farming = true State.processing = false State.following = false State.tweening = false State.lastTask = "" State.taskCount = 0 Util.setCollision(true) task.spawn(farmLoop) end _G.GetStatus = function() return State end