if not getgenv().has99daysScript then getgenv().has99daysScript = true else return end getgenv().ENABLE_FPS_BOOST = true -- đổi false/true để bật-tắt FPS boost -- MODE: "longtime" (farm vô hạn, KHÔNG craft giường, KHÔNG cứu kid) -- "shorttime" (craft giường + cứu kid + auto-reset ở 100 days + 3 strongholds) getgenv().MODE = "shorttime" -- Override setfpscap: khi boost off, luôn cap = 60 (không bao giờ giảm xuống 3) local _origSetFpsCap = setfpscap setfpscap = function(n) if getgenv().ENABLE_FPS_BOOST then _origSetFpsCap(n) else _origSetFpsCap(60) end end -- setfpscap(10) getgenv().stopall = false getgenv().config = { Url = "http://103.56.162.62", Url2 = "http://157.66.27.10", WebhookUrl = "https://discord.com/api/webhooks/1435238253837029396/64VO0AaMG-OVW94JZIk7hjfiTcIe85T3rH-qFvS24pVQHGivhFhqozvuYiulgEpDAK0o", ChangeFrom = "FOLDER_NAME_A", ChangeTo = "FOLDER_NAME_B", ChangeDiamonds = 1000, Fuel = { 'Coal', 'Log', 'Fuel Canister', 'Oil Barrel', 'Chair', 'Biofuel', }, Food = { 'Carrot', 'Berry', 'Apple', 'Cake', 'Chili', 'Stew', 'Meat? Sandwich', 'Sweet Potato', 'Cooked Morsel', 'Cooked Steak', -- Crockpot outputs 'Hearty Stew', 'Steak Dinner', 'Carrot Cake', 'BBQ Ribs', 'Berry Juice', 'Seafood Chowder', 'Stuffed Peppers', 'Casserole', 'Corn on the Cob', 'Sweet Potato Pie', 'Roast Turkey', }, Wood = {"Log", "Chair"}, Scrap = {"Bolt", "Sheet Metal", "UFO Junk" , "UFO Component", "Broken Fan", "Broken Radio", "Broken Microwave", "Tyre", "Metal Chair", "Old Car Engine", "Washing Machine", "Cultist Experiment", "Cultist Prototype"}, Healing = {"Bandage", "Medkit"}, Animals = {"Bunny", "Wolf", "Alpha Wolf", "Frog", "Scorpion"}, } repeat task.wait(0.5) until game:IsLoaded() local Services = setmetatable({}, { __index = function(_, Name) return cloneref(game:GetService(Name)) end, }) -- local p = game.Players.LocalPlayer -- p.CharacterAdded:Connect(function() -- setfflag('NextGenReplicatorEnabledWrite4', 'False') -- setfflag('NextGenReplicatorEnabledWrite4', 'True') -- end) -- setfflag('NextGenReplicatorEnabledWrite4', 'False') -- setfflag('NextGenReplicatorEnabledWrite4', 'True') -- task.wait(5) -- p.Character.Humanoid.Health = 0 local coreGui = Services.CoreGui local workspace = Services.Workspace local playerService = Services.Players local replicatedStorage = Services.ReplicatedStorage local runService = Services.RunService local virtualUser = Services.VirtualUser local VirtualInputManager = Services.VirtualInputManager local HttpService = game:GetService("HttpService") local plr = playerService.LocalPlayer local EventClient = plr.PlayerScripts:FindFirstChild('Client') local remotes = replicatedStorage:FindFirstChild('RemoteEvents') or replicatedStorage:WaitForChild('RemoteEvents', 15) -- ★★ SỬA GỐC (đo live 2026-08-13): trước đây tất cả remote dưới đây chụp bằng FindFirstChild — -- KHÔNG CHỜ. Script chạy trước khi RemoteEvents replicate xong ⇒ cái nào chưa kịp thì biến -- local đó NIL VĨNH VIỄN, kể cả khi remote xuất hiện 1 giây sau. Mọi `X:InvokeServer(...)` -- sau đó ném "attempt to index nil with 'InvokeServer'", và vì phần lớn nằm trong pcall nên -- LỖI BỊ NUỐT — script chạy mà không làm gì, không một dòng báo lỗi. -- Bằng chứng: log in DestroyObject=NIL và lỗi L1360 (RequestBagStoreItem nil), trong khi đo -- trực tiếp thì RemoteEvents có 250 con và RequestBagStoreItem TỒN TẠI. -- ⇒ CHỜ MỘT LẦN cho folder nạp xong, rồi tra tức thì. -- -- ⚠ Bản đầu tôi cho mỗi remote tự WaitForChild(5s). Log thật cho thấy đó là sai lầm: -- khi folder chưa nạp thì CẢ 10 cái cùng timeout ⇒ ~50 GIÂY chết cứng lúc khởi động -- (19:40:38 → 19:41:21 trong log). Giờ chỉ chờ đúng MỘT mốc: 'ToolDamageObject' — -- remote chắc chắn có trong build này. Nó xuất hiện là cả folder đã nạp ⇒ 10 lần -- FindFirstChild sau đó đều tức thì, và remote thiếu thật thì báo ngay, không chờ thêm. -- ⚠⚠ LOBBY VÀ IN-GAME CÓ HAI BỘ REMOTE KHÁC HẲN NHAU (đo live): -- lobby (79546208627805): ~42 con, CÓ TeleportEvent, KHÔNG có ToolDamageObject/farming -- in-game (126509999114328): ~243-250 con, CÓ ToolDamageObject, KHÔNG có TeleportEvent -- Và folder bị DỰNG LẠI mỗi lần teleport (đo được 42 con → 30s sau 243 con). -- -- ⇒ Ở LOBBY thì KHÔNG resolve/không cảnh báo đám remote in-game — lobby chỉ cần TeleportEvent -- để nhảy vào game. Chờ ToolDamageObject ở lobby là treo 20s vô ích, và mọi "remote KHONG co" -- ở lobby là ĐƯƠNG NHIÊN, không phải lỗi. Đúng ý: IS_LOBBY thì bỏ qua hết. local IS_LOBBY = (game.PlaceId == 79546208627805) -- đọc remote từ folder SỐNG (không tin biến 'remotes' chụp lúc load — teleport có thể đã dựng lại nó) local function liveRemotes() return replicatedStorage:FindFirstChild('RemoteEvents') end local function R(name) local re = liveRemotes() return re and re:FindFirstChild(name) end local TeleportEvent, ToolDamageObject, RequestConsumeItem, RequestBagStoreItem, RequestPlaceStructure, RequestTakeDiamonds, AcceptPlayAgain, EquipItemHandle, DestroyObject, CraftItem, RequestHotbarItem if IS_LOBBY then -- LOBBY: chỉ cần cái này. Đám còn lại để nil, KHÔNG chờ, KHÔNG cảnh báo. TeleportEvent = R('TeleportEvent') else -- IN-GAME: chờ MỘT LẦN cho folder nạp (mốc ToolDamageObject), rồi tra tức thì. local t0 = os.clock() while not R('ToolDamageObject') and (os.clock() - t0) < 20 do task.wait(0.2) end if not R('ToolDamageObject') then local re = liveRemotes() warn(("[99n] RemoteEvents chua nap sau 20s (%d con) — farming se loi"):format(re and #re:GetChildren() or -1)) end ToolDamageObject = R('ToolDamageObject') RequestConsumeItem = R('RequestConsumeItem') RequestBagStoreItem = R('RequestBagStoreItem') RequestPlaceStructure = R('RequestPlaceStructure') RequestTakeDiamonds = R('RequestTakeDiamonds') AcceptPlayAgain = R('AcceptPlayAgain') EquipItemHandle = R('EquipItemHandle') DestroyObject = R('DestroyObject') -- thật sự không có trong build này → nil, im lặng CraftItem = R('CraftItem') RequestHotbarItem = R('RequestHotbarItem') -- chỉ báo remote in-game NÀO thiếu (bỏ TeleportEvent/DestroyObject vì đằng nào cũng ko có in-game) for _, pair in ipairs({ {ToolDamageObject,'ToolDamageObject'}, {RequestConsumeItem,'RequestConsumeItem'}, {RequestBagStoreItem,'RequestBagStoreItem'}, {RequestPlaceStructure,'RequestPlaceStructure'}, {RequestTakeDiamonds,'RequestTakeDiamonds'}, {AcceptPlayAgain,'AcceptPlayAgain'}, {EquipItemHandle,'EquipItemHandle'}, {CraftItem,'CraftItem'}, {RequestHotbarItem,'RequestHotbarItem'}, }) do if not pair[1] then warn(("[99n] remote in-game '%s' thieu"):format(pair[2])) end end end local TouchZone = CFrame.new(19.9145088, 3.30494165, -3.24200487, 1, 0, 0, 0, 1, 0, 0, 0, 1) getgenv().sogemnhanduoc = 0 -- Enable debug logs để trace script hoạt động -- print = function() end -- disabled original override task.spawn(function() if game.PlaceId ~= 79546208627805 then if getgenv().MODE == "shorttime" then task.wait(60 * 90) plr:Kick('You have been kicked for being idle for too long. Please rejoin the game.') end else task.wait(60 * 5) plr:Kick('You have been kicked for being idle for too long. Please rejoin the game.') end end) local oldSack = nil local oldAxe = nil local function sendWebhook(username, timeElapsed, days, diamonds, timestronghold, whatdie) if not getgenv().config.WebhookUrl or getgenv().config.WebhookUrl == "" then return end pcall(function() local data = { ["embeds"] = {{ ["title"] = "🎮 Game Ended Version-QuanhDzVclLuxury2NewKeke", ["color"] = 3066993, ["fields"] = { { ["name"] = "👤 Username", ["value"] = tostring(username), ["inline"] = true }, { ["name"] = "⏱️ Time", ["value"] = tostring(timeElapsed) .. " seconds", ["inline"] = true }, { ["name"] = "📅 Days", ["value"] = tostring(days), ["inline"] = true }, { ["name"] = "💎 Diamonds", ["value"] = tostring(diamonds), ["inline"] = true }, { ["name"] = "TimeStrongHold", ["value"] = tostring(timestronghold), ["inline"] = true }, { ["name"] = "Why I Die?", ["value"] = tostring(whatdie), ["inline"] = true }, }, ["timestamp"] = os.date("!%Y-%m-%dT%H:%M:%S") }} } local headers = { ["Content-Type"] = "application/json" } request({ Url = getgenv().config.WebhookUrl, Method = "POST", Headers = headers, Body = HttpService:JSONEncode(data) }) end) end if getgenv().ENABLE_FPS_BOOST then Services.Lighting.ExposureCompensation = - math.huge end plr.Idled:Connect(function() virtualUser:Button2Down(Vector2.new(0, 0), workspace.CurrentCamera.CFrame) task.wait(0.25) virtualUser:Button2Up(Vector2.new(0, 0), workspace.CurrentCamera.CFrame) end) -- DISABLED: 5-min auto-kick (logic ngược, kick tất cả player ở 99 Nights) -- task.spawn(function() -- if game.PlaceId ~= 79546208627805 then -- else -- task.wait(60 * 5) -- plr:Kick('You have been kicked for being idle for too long. Please rejoin the game.') -- end -- end) function checkNearPlayer(pos) for _, v in pairs(playerService:GetPlayers()) do if v ~= plr and v.Character and v.Character:FindFirstChild('HumanoidRootPart') then if (v.Character.HumanoidRootPart.Position - pos).magnitude < 8 then return true end end end return false end function joinGame() pcall(function() for _, v in pairs(workspace:GetChildren()) do if string.find(v.Name, 'Teleporter') and v:FindFirstChild('BillboardHolder') then if not checkNearPlayer(v.BillboardHolder.Position) then plr.Character.HumanoidRootPart.CFrame = v.EnterPart.CFrame firesignal(TeleportEvent.OnClientEvent, 'Choose', 1) task.wait(0.5) TeleportEvent:FireServer('Chosen', nil, 1) task.wait(0.5) end end end end) end function decode(data) if not data then return {} end return HttpService:JSONDecode(data) end function encode(data) if not data then return {} end return HttpService:JSONEncode(data) end local function get(url) return request({ Url = url, Method = "GET", }) end local function post(url, data) return request({ Url = url, Headers = { ["content-type"] = "application/json" }, Method = "POST", Body = HttpService:JSONEncode(data), }) end getgenv().farmLogs = getgenv().farmLogs or {} local function logF(tag, msg) -- local entry = os.date("%H:%M:%S") .. " [" .. tag .. "] " .. tostring(msg) -- table.insert(getgenv().farmLogs, entry) -- if #getgenv().farmLogs > 200 then table.remove(getgenv().farmLogs, 1) end -- print(entry) -- -- Best-effort write to file -- pcall(function() -- if writefile then -- local existing = "" -- pcall(function() existing = readfile("99days_farm.log") end) -- writefile("99days_farm.log", (existing or "") .. entry .. "\n") -- end -- end) end function joinGame2() local a = loadstring(game:HttpGet("https://quanhdev.com/servervip.txt"))() local dbuoi, dcac = a.GenerateAccessCode(126509999114328) game.RobloxReplicatedStorage.ContactListIrisInviteTeleport:FireServer(126509999114328, "", dbuoi) writefile("AccessId_".. plr.UserId ..".txt", dbuoi) end function getItem(name) for _, v in pairs(plr.Inventory:GetChildren()) do if string.find(v.Name, name) then return v end end return nil end function equipSack() if plr.Character:FindFirstChild("ToolHandle") then if string.find(tostring(plr.Character.ToolHandle.OriginalItem.Value), "Sack") then return end end if oldSack then getconnections(oldSack.MouseButton1Click)[1]:Fire() end end function equipAxe() if plr.Character:FindFirstChild("ToolHandle") then if string.find(tostring(plr.Character.ToolHandle.OriginalItem.Value), "Axe") then return end end local axe = getItem("Axe") if not axe then return end -- Use InventoryHandler.RequestEquipItem (sets v9 state — required for ActivateTool) local ok = pcall(function() local cm = require(plr.PlayerScripts.Client) if cm and cm.InventoryHandler and cm.InventoryHandler.RequestEquipItem then cm.InventoryHandler.RequestEquipItem(axe) else EquipItemHandle:FireServer("FireAllClients", axe) end end) if not ok then pcall(function() EquipItemHandle:FireServer("FireAllClients", axe) end) end end local _chopLogAt = 0 -- chặn log chặt cây, 1 dòng/giây function cutTree(tree) if not tree or not tree:FindFirstChild("Trunk") then return end equipAxe() local OldAxe = getItem("Axe") if not OldAxe then return end local GetDamageAxe = OldAxe:GetAttribute('WeaponResourceDamage') or 0 local GetHealthTree = tree:GetAttribute('Health') or 0 task.wait(0.3) -- ★★ GỐC RỄ (đo live 2026-08-13): mọi remote ở L81-91 được chụp bằng FindFirstChild — -- KHÔNG CHỜ. Cái nào chưa replicate xong lúc script load thì biến local đó NIL VĨNH VIỄN. -- Bằng chứng: log in "DestroyObject=NIL" trong khi đo trực tiếp thì remote ĐÓ CÓ TỒN TẠI. -- Nếu ToolDamageObject (L82) cũng chụp hụt ⇒ `ToolDamageObject:InvokeServer(...)` ném lỗi -- MỖI LẦN, pcall ở vòng ngoài nuốt sạch, HP cây không bao giờ giảm — đúng log HP=50 đứng im. -- ⇒ Lấy lại remote NGAY LÚC GỌI, đừng tin biến chụp lúc load. local TDO = ToolDamageObject or (remotes and remotes:FindFirstChild('ToolDamageObject')) local DOB = DestroyObject or (remotes and remotes:FindFirstChild('DestroyObject')) if not TDO then if tick() - _chopLogAt >= 1 then _chopLogAt = tick() warn("[chop] KHONG lay duoc remote ToolDamageObject -> khong the chat") end return end -- ★ willDestroy: GIỮ `false`. -- Tôi từng đổi thành `GetDamageAxe >= GetHealthTree` và ĐÓ LÀ MỘT BƯỚC LÙI — log thật cho thấy -- với rìu mạnh (dmg=50) gặp cây HP=50 thì cờ thành true và HP KẸT Ở 50 suốt 6 lượt liền. -- Ngược lại lúc cờ = false (dmg=4) thì HP tụt 50 → 46 bình thường. -- ⚠ Tôi CHƯA hiểu đúng hợp đồng của tham số này: thử tay nhiều lượt cho kết quả mâu thuẫn -- (lúc true ăn, lúc false ăn, lúc không cái nào ăn). Nên bám vào cấu hình ĐÃ QUAN SÁT -- THẤY CHẠY trong log thật thay vì suy đoán. local willDestroy = false if tick() - _chopLogAt >= 1 then _chopLogAt = tick() print(("[chop] %s | HP=%s | dmg=%s | willDestroy=%s | TDO=%s DOB=%s"):format( tostring(tree.Name), tostring(GetHealthTree), tostring(GetDamageAxe), tostring(willDestroy), TDO and "co" or "NIL", DOB and "co" or "NIL")) end TDO:InvokeServer( tree, OldAxe, '1_8912555794', CFrame.new(-41, 1, -116, 1, 0, 0, 0, 1, 0, 0, 0, 1), willDestroy ) if willDestroy and DOB and tree:FindFirstChild("Trunk") then pcall(function() firesignal(DOB.OnClientEvent, tree, tree.Trunk.CFrame) end) end end function getNearestTree() local char = plr.Character if not char or not char:FindFirstChild('HumanoidRootPart') then return end local nearest = nil local minDist = math.huge local mainFirePos = workspace.Map.Campground.MainFire.Center.Position noclip() for _, v in pairs(workspace.Map.Foliage:GetChildren()) do if v.Name == 'Small Tree' and v:FindFirstChild('Trunk') then local dist = (v.Trunk.Position - mainFirePos).Magnitude if dist < minDist then minDist = dist nearest = v end end end if nearest and nearest:FindFirstChild('Trunk') then plr.Character.HumanoidRootPart.CFrame = nearest.Trunk.CFrame + Vector3.new(0, -20, 2) end return nearest end function allTree() local tree = getNearestTree() if tree then cutTree(tree) end end function getMaxSafeDistance() local mainFirePos = workspace.Map.Campground.MainFire.Center.Position local fogPos = workspace.Map.Boundaries.Fog.Part.Position local firePos2D = Vector2.new(mainFirePos.X, mainFirePos.Z) local fogPos2D = Vector2.new(fogPos.X, fogPos.Z) return (firePos2D - fogPos2D).Magnitude - 20 end function CollectLog(isCraft, listItem) local centerCF = workspace.Map.Campground.MainFire.Center.CFrame local TouchZone = workspace.Map.Campground.CraftingBench.TouchZone local mainFirePos = centerCF.Position local maxSafeDistance = getMaxSafeDistance() local validItems = {} for _, v in pairs(workspace.Items:GetChildren()) do local isValidItem = (not isCraft and table.find(getgenv().config.Fuel, v.Name)) or (isCraft and table.find(listItem, v.Name)) if isValidItem and v.PrimaryPart then local distance = (mainFirePos - v.PrimaryPart.Position).Magnitude if distance <= (maxSafeDistance * 0.8) then table.insert(validItems, { item = v, distance = distance }) end end end table.sort(validItems, function(a, b) return a.distance < b.distance end) local SackItem = getItem("Sack") if not SackItem then return end local capacity = SackItem:GetAttribute("Capacity") or 10 local collected = 0 for _, itemData in pairs(validItems) do if collected >= capacity then break end local v = itemData.item if v and v.PrimaryPart then plr.Character.HumanoidRootPart.CFrame = CFrame.new(v.PrimaryPart.Position + Vector3.new(0, -20, 0)) task.wait(0.5) local success = pcall(function() RequestBagStoreItem:InvokeServer(SackItem, v) end) if success then collected = collected + 1 end task.wait(0.5) end end -- Drop items for _, v in pairs(plr.ItemBag:GetChildren()) do equipSack() plr.Character.HumanoidRootPart.CFrame = (isCraft and TouchZone.CFrame or centerCF) * CFrame.new(0, 10, 0) task.wait(0.5) VirtualInputManager:SendKeyEvent(true, "F", false, game) task.wait(0.1) VirtualInputManager:SendKeyEvent(false, "F", false, game) end end function tpdeobisao(targetCFrame, shouldWait) if shouldWait == nil then shouldWait = false end local plr = game.Players.LocalPlayer local hrp = plr.Character.HumanoidRootPart if not targetCFrame then targetCFrame = CFrame.new(0, 0, 0) end if plr.Character.Humanoid.Health <= 0 then return {Stop = function() end} end local TweenService = game:GetService("TweenService") local tweenSpeed = 400 local startPos = hrp.Position local targetPos = targetCFrame.Position local flyHeight = 235 local skyStart = Vector3.new(startPos.X, flyHeight, startPos.Z) local skyTarget = Vector3.new(targetPos.X, flyHeight, targetPos.Z) local phase1Distance = (skyStart - startPos).Magnitude local phase2Distance = (skyTarget - skyStart).Magnitude local tweenInfo1 = TweenInfo.new( phase1Distance / tweenSpeed, Enum.EasingStyle.Sine, Enum.EasingDirection.Out ) local tweenInfo2 = TweenInfo.new( phase2Distance / tweenSpeed, Enum.EasingStyle.Linear ) local currentTween = nil local stopped = false local completed = false local function executeTween() if stopped then return end currentTween = TweenService:Create(hrp, tweenInfo1, {CFrame = CFrame.new(skyStart)}) currentTween:Play() currentTween.Completed:Wait() if stopped then return end currentTween = TweenService:Create(hrp, tweenInfo2, {CFrame = CFrame.new(skyTarget)}) currentTween:Play() currentTween.Completed:Wait() completed = true end if shouldWait then executeTween() else task.spawn(executeTween) end return { Stop = function() stopped = true if currentTween then currentTween:Cancel() end end, IsCompleted = function() return completed end } end function CollectLogv2(isCraft, listItem) local centerCF = workspace.Map.Campground.MainFire.Center.CFrame local mainFirePos = centerCF.Position local maxSafeDistance = getMaxSafeDistance() local numPoints = 8 local radius = maxSafeDistance * 0.9 local circlePoints = {} for i = 1, numPoints do local angle = (i - 1) * (2 * math.pi / numPoints) local x = mainFirePos.X + radius * math.cos(angle) local z = mainFirePos.Z + radius * math.sin(angle) table.insert(circlePoints, Vector3.new(x, mainFirePos.Y, z)) end for _, point in pairs(circlePoints) do tpdeobisao(CFrame.new(point), true) end plr.Character.HumanoidRootPart.CFrame = centerCF * CFrame.new(0, -50, 0) task.wait(0.5) end function collectItem() local centerCF = workspace.Map.Campground.MainFire.Center.CFrame for i,v in pairs(workspace.Items:GetChildren()) do if v:FindFirstChild("IceBlock") then continue end local args = {[1] = v} replicatedStorage.RemoteEvents.RequestStartDraggingItem:FireServer(unpack(args)) local process = getProgress() if process > 6 then return end if process > 2 then if v.Name == "Log" then task.wait(.1) v.PrimaryPart.CFrame = TouchZone * CFrame.new(0, 20, 0) end if table.find(getgenv().config.Fuel, "Log") then table.remove(getgenv().config.Fuel, table.find(getgenv().config.Fuel, "Log")) return end end if table.find(getgenv().config.Fuel, v.Name) and v.PrimaryPart then task.wait(.2) v.PrimaryPart.CFrame = centerCF * CFrame.new(0, 20, 0) elseif table.find(getgenv().config.Scrap, v.Name) and v.PrimaryPart then v.PrimaryPart.CFrame = TouchZone * CFrame.new(0, 20, 0) elseif (v.Name == "Steak" or v.Name == "Morsel") and v.PrimaryPart then v.PrimaryPart.CFrame = centerCF * CFrame.new(0, 20, 0) task.wait(.1) end end end function Noclip() for i, v in ipairs(plr.Character:GetDescendants()) do if v:IsA("BasePart") and v.CanCollide == true then v.CanCollide = false end end end -- Noclip: CanCollide enforce event-driven + maintain loop 0.5s (thay vì 60fps) local function applyNoclipToCharacter(char) if not char then return end for _, v in ipairs(char:GetDescendants()) do if v:IsA("BasePart") and v.CanCollide then v.CanCollide = false end end end -- ========================================================== -- NOCLIP v2 — per-frame (RunService.Stepped) + cached parts list -- Không BodyVelocity/BodyGyro (không freeze player, vẫn TP được) -- Không PlatformStand (tránh anticheat detect) -- ========================================================== local RunService = game:GetService("RunService") local _noclipParts = {} -- cached BasePart refs of current character local function rebuildNoclipCache(char) table.clear(_noclipParts) if not char then return end for _, v in ipairs(char:GetDescendants()) do if v:IsA("BasePart") then _noclipParts[v] = true end end end -- Handle new character spawn / parts added local function hookCharacter(char) if not char then return end rebuildNoclipCache(char) char.DescendantAdded:Connect(function(v) if v:IsA("BasePart") then _noclipParts[v] = true if getgenv().noclip and v.CanCollide then v.CanCollide = false end end end) char.DescendantRemoving:Connect(function(v) _noclipParts[v] = nil end) end plr.CharacterAdded:Connect(hookCharacter) if plr.Character then hookCharacter(plr.Character) end -- PER-FRAME noclip + float (CanCollide=false + BV/BG/PlatformStand maintained 60Hz) RunService.Stepped:Connect(function() if not getgenv().noclip then return end -- CanCollide=false mỗi frame for part, _ in pairs(_noclipParts) do if part.Parent and part.CanCollide then part.CanCollide = false end end -- Float: BV/BG/PlatformStand ensure mỗi frame (để đứng trên không) local char = plr.Character local hrp = char and char:FindFirstChild("HumanoidRootPart") local hum = char and char:FindFirstChildOfClass("Humanoid") if not hrp or not hum then return end if not hrp:FindFirstChild("NoclipBV") then local BV = Instance.new('BodyVelocity') BV.Velocity = Vector3.zero BV.MaxForce = Vector3.new(9e9, 9e9, 9e9) BV.Name = "NoclipBV" BV.Parent = hrp end if not hrp:FindFirstChild("NoclipBG") then local BG = Instance.new('BodyGyro') BG.P = 9e4 BG.maxTorque = Vector3.new(9e9, 9e9, 9e9) BG.cframe = workspace.CurrentCamera.CFrame BG.Name = "NoclipBG" BG.Parent = hrp end if not hum.PlatformStand then hum.PlatformStand = true end end) function noclip() getgenv().noclip = true applyNoclipToCharacter(plr.Character) end function deleteNoclip() getgenv().noclip = false pcall(function() local hrp = plr.Character and plr.Character:FindFirstChild("HumanoidRootPart") if hrp then local bv = hrp:FindFirstChild("NoclipBV") local bg = hrp:FindFirstChild("NoclipBG") if bv then bv:Destroy() end if bg then bg:Destroy() end end local hum = plr.Character and plr.Character:FindFirstChildOfClass("Humanoid") if hum then hum.PlatformStand = false end end) end -- ========================================================== -- FOOD SYSTEM v2 — hunt animal → cook meat → eat -- ========================================================== local HUNGER_EAT_THRESHOLD = 150 -- dưới ngưỡng này thì ăn local HUNGER_HUNT_THRESHOLD = 120 -- dưới ngưỡng này + không có food → đi săn local _foodHitCounter = 0 -- Damage 1 animal đến khi chết (hoặc timeout) local function killAnimal(animal, timeoutSec) timeoutSec = timeoutSec or 10 local hum = animal:FindFirstChildOfClass("Humanoid") local ah = animal:FindFirstChild("HumanoidRootPart") or animal.PrimaryPart if not hum or not ah or hum.Health <= 0 then return false end equipAxe() local axe = getItem("Axe") if not axe then print("[Hunt] no axe found"); return false end local char = plr.Character local hrp = char and char:FindFirstChild("HumanoidRootPart") if not hrp then return false end -- TP phía trên animal 40Y (noclip + spam damage) getgenv()._foodBusy = true noclip() local deadline = tick() + timeoutSec while animal.Parent and hum.Health > 0 and tick() < deadline do if not char.Parent then char = plr.Character; hrp = char and char:FindFirstChild("HumanoidRootPart") end if not hrp then break end hrp.CFrame = ah.CFrame * CFrame.new(0, 40, 0) _foodHitCounter = _foodHitCounter + 1 pcall(function() replicatedStorage.RemoteEvents.ToolDamageObject:InvokeServer( animal, axe, _foodHitCounter .. "_" .. plr.UserId, ah.CFrame, false ) end) task.wait() end getgenv()._foodBusy = false local died = (hum.Health <= 0) or (not animal.Parent) print(("[Hunt] %s %s (hp=%d, %.1fs)"):format(animal.Name, died and "DEAD" or "timeout", math.floor(hum.Health), tick() - (deadline - timeoutSec))) return died end -- Drag meat/raw food xuống MainFire để cook thành Cooked Steak/Morsel local function cookPendingMeat() pcall(function() local centerCF = workspace.Map.Campground.MainFire.Center.CFrame for _, v in ipairs(workspace.Items:GetChildren()) do if (v.Name == "Steak" or v.Name == "Morsel") and v.PrimaryPart then pcall(function() replicatedStorage.RemoteEvents.RequestStartDraggingItem:FireServer(v) end) task.wait(0.1) v.PrimaryPart.CFrame = centerCF * CFrame.new(0, 20, 0) task.wait(0.2) end end end) end -- Tìm animal gần nhất còn sống local function findNearestAnimal(maxDist) maxDist = maxDist or 500 local char = plr.Character local hrp = char and char:FindFirstChild("HumanoidRootPart") if not hrp then return nil end local best, bestDist = nil, maxDist for _, v in ipairs(workspace.Characters:GetChildren()) do if table.find(getgenv().config.Animals, v.Name) then local hum = v:FindFirstChildOfClass("Humanoid") local h = v:FindFirstChild("HumanoidRootPart") or v.PrimaryPart if hum and h and hum.Health > 0 then local d = (h.Position - hrp.Position).Magnitude if d < bestDist then best, bestDist = v, d end end end end return best, bestDist end -- Search radius dynamic theo mức đói (càng đói càng tìm xa) local function getHuntRadius() local h = plr:GetAttribute('Hunger') or 200 if h >= 100 then return 800 end if h >= 50 then return 2500 end return math.huge end -- EMERGENCY: ăn raw Steak/Morsel khi cực đói (tốn HP nhưng sống) local function eatRawEmergency() local h = plr:GetAttribute('Hunger') or 200 if h >= 40 then return end print("[EatRaw] EMERGENCY hunger=" .. math.floor(h)) getgenv()._foodBusy = true -- Inventory raw first (không cần TP) for _, v in ipairs(plr.Inventory:GetChildren()) do if v.Name == "Steak" or v.Name == "Morsel" then pcall(function() RequestConsumeItem:InvokeServer(v) end) task.wait(0.3) if (plr:GetAttribute('Hunger') or 0) >= 100 then getgenv()._foodBusy = false return end end end -- Ground raw (cần TP nên set _foodBusy) local hrp = plr.Character and plr.Character:FindFirstChild("HumanoidRootPart") if not hrp then getgenv()._foodBusy = false; return end for _, v in ipairs(workspace.Items:GetChildren()) do if v.Name == "Steak" or v.Name == "Morsel" then local pivPos = v:GetPivot().Position -- ⚠️ SKIP Y > 10 (cooked Steak trên MainFire) — tránh TP lên cao bị giết if pivPos.Y <= 10 then pcall(function() hrp.CFrame = CFrame.new(pivPos + Vector3.new(0, -30, 0)) end) task.wait(0.3) pcall(function() RequestConsumeItem:InvokeServer(v) end) task.wait(0.2) if (plr:GetAttribute('Hunger') or 0) >= 100 then break end end end end getgenv()._foodBusy = false end -- Đếm food có thể ăn ngay (ground + inventory) local function countEdibleFood() local n = 0 for _, v in ipairs(workspace.Items:GetChildren()) do if not v:GetAttribute("Slept") and ((v:GetAttribute("RestoreHunger") or 0) > 0 or table.find(getgenv().config.Food, v.Name)) then n = n + 1 end end for _, v in ipairs(plr.Inventory:GetChildren()) do if not v:GetAttribute("Slept") and ((v:GetAttribute("RestoreHunger") or 0) > 0 or table.find(getgenv().config.Food, v.Name)) then n = n + 1 end end return n end -- Chi tiết food theo loại: inv + ground + raw + cooked local function summarizeFood() local inv, ground, raw = {}, {}, {} local function bump(t, name) t[name] = (t[name] or 0) + 1 end for _, v in ipairs(plr.Inventory:GetChildren()) do if table.find(getgenv().config.Food, v.Name) then bump(inv, v.Name) elseif v.Name == "Steak" or v.Name == "Morsel" then bump(raw, v.Name) end end for _, v in ipairs(workspace.Items:GetChildren()) do if table.find(getgenv().config.Food, v.Name) then bump(ground, v.Name) elseif v.Name == "Steak" or v.Name == "Morsel" then bump(raw, v.Name) end end local function fmt(t) local parts, total = {}, 0 for k, v in pairs(t) do table.insert(parts, k .. "x" .. v); total = total + v end table.sort(parts) return total, (#parts > 0 and table.concat(parts, ",") or "-") end local ni, si = fmt(inv) local ng, sg = fmt(ground) local nr, sr = fmt(raw) return ni + ng, ni, ng, nr, si, sg, sr end -- Item có ăn được không? (check RestoreHunger attribute + skip Slept/expired) local function isEdibleFood(item) if item:GetAttribute("Slept") then return false end -- expired food local restore = item:GetAttribute("RestoreHunger") if restore and restore > 0 then return true end -- Fallback: check config list (for items without attribute) return table.find(getgenv().config.Food, item.Name) ~= nil end function AutoEat(ohNo) local hunger = plr:GetAttribute('Hunger') or 0 if hunger >= HUNGER_EAT_THRESHOLD then return end local char = plr.Character local hrp = char and char:FindFirstChild('HumanoidRootPart') if not hrp then return end getgenv()._foodBusy = true -- 1. Cook meat đang drop trước cookPendingMeat() -- 2. Ăn food trong Inventory (không cần TP, skip Slept) for _, v in ipairs(plr.Inventory:GetChildren()) do if isEdibleFood(v) then if (plr:GetAttribute('Hunger') or 0) >= HUNGER_EAT_THRESHOLD then break end local rh = v:GetAttribute("RestoreHunger") or "?" print("[AutoEat] inv: " .. v.Name .. " (+" .. tostring(rh) .. ")") pcall(function() RequestConsumeItem:InvokeServer(v) end) task.wait(0.3) end end -- 3. Ăn food trên ground (skip Slept, prioritize highest RestoreHunger) -- ⚠️ SKIP food Y > 10 (food trên MainFire/cooked) — tránh TP lên cao bị giết local foods = {} for _, v in ipairs(workspace.Items:GetChildren()) do if isEdibleFood(v) then local pivPos = v:GetPivot().Position if pivPos.Y <= 10 then table.insert(foods, { item = v, dist = (pivPos - hrp.Position).Magnitude, restore = v:GetAttribute("RestoreHunger") or 10, }) end end end -- Sort: highest RestoreHunger first, then closest table.sort(foods, function(a, b) if a.restore ~= b.restore then return a.restore > b.restore end return a.dist < b.dist end) print(("[AutoEat] hunger=%d ground=%d"):format(math.floor(hunger), #foods)) if #foods > 0 then noclip() for _, v in ipairs(foods) do if (plr:GetAttribute('Hunger') or 0) >= HUNGER_EAT_THRESHOLD then break end hrp.CFrame = CFrame.new(v.item:GetPivot().Position + Vector3.new(0, -30, 0)) task.wait(0.3) pcall(function() RequestConsumeItem:InvokeServer(v.item) end) task.wait(0.2) end end getgenv()._foodBusy = false -- 4. Vẫn đói + không có food → HUNT animal if not ohNo and (plr:GetAttribute('Hunger') or 0) < HUNGER_HUNT_THRESHOLD and countEdibleFood() == 0 then local deadline = tick() + 60 while tick() < deadline do local radius = getHuntRadius() local animal = findNearestAnimal(radius) if not animal then -- Không tìm thấy → emergency raw + đợi eatRawEmergency() task.wait(2) else print(("[AutoEat] hunt %s (r=%s)"):format(animal.Name, tostring(radius == math.huge and "INF" or radius))) killAnimal(animal, 10) task.wait(0.3) pcall(collectItem) task.wait(0.3) cookPendingMeat() task.wait(1.5) AutoEat(true) eatRawEmergency() if (plr:GetAttribute('Hunger') or 0) >= HUNGER_EAT_THRESHOLD then break end end end end end function AutoHeal() local char = plr.Character if not char or not char:FindFirstChild('Humanoid') then return end local humanoid = char.Humanoid local healthPercent = (humanoid.Health / humanoid.MaxHealth) * 100 if healthPercent >= 70 then return end for _, healingItem in pairs(getgenv().config.Healing) do local item = plr.Inventory:FindFirstChild(healingItem) if item then pcall(function() RequestConsumeItem:InvokeServer(item) task.wait(0.5) end) return end end end function getProgress() return workspace:GetAttribute('Progress') or 0 end function ClaimDiamond() if not plr:FindFirstChild('UnclaimedBadges') or not EventClient then return end local unclaimedBadges = plr.UnclaimedBadges:GetAttributes() for i, badge in pairs(unclaimedBadges) do require(EventClient).Events.RequestClaimBadgeDiamonds:FireServer(tonumber(i)) end end function createDiamondUI() local screenGui = Instance.new("ScreenGui") screenGui.Name = "DiamondDisplay" screenGui.Parent = coreGui screenGui.ZIndexBehavior = Enum.ZIndexBehavior.Sibling local mainFrame = Instance.new("Frame") mainFrame.Name = "MainFrame" mainFrame.Parent = screenGui mainFrame.BackgroundColor3 = Color3.fromRGB(0, 0, 0) mainFrame.BackgroundTransparency = 0 mainFrame.BorderSizePixel = 0 mainFrame.Position = UDim2.new(0, 0, 0, 0) mainFrame.Size = UDim2.new(1, 0, 1, 0) mainFrame.Transparency = 0.5 local diamondLabel = Instance.new("TextLabel") diamondLabel.Name = "DiamondLabel" diamondLabel.Parent = mainFrame diamondLabel.BackgroundTransparency = 1 diamondLabel.Position = UDim2.new(0, 0, 0, 0) diamondLabel.Size = UDim2.new(1, 0, 0.25, 0) diamondLabel.Font = Enum.Font.SourceSansBold diamondLabel.Text = "GEMS: 0" diamondLabel.TextColor3 = Color3.fromRGB(0, 255, 127) diamondLabel.TextSize = 96 diamondLabel.TextStrokeTransparency = 0 diamondLabel.TextStrokeColor3 = Color3.fromRGB(0, 0, 0) local gemsEarnedLabel = Instance.new("TextLabel") gemsEarnedLabel.Name = "GemsEarnedLabel" gemsEarnedLabel.Parent = mainFrame gemsEarnedLabel.BackgroundTransparency = 1 gemsEarnedLabel.Position = UDim2.new(0, 0, 0.25, 0) gemsEarnedLabel.Size = UDim2.new(1, 0, 0.25, 0) gemsEarnedLabel.Font = Enum.Font.SourceSansBold gemsEarnedLabel.Text = "EARNED: 0" gemsEarnedLabel.TextColor3 = Color3.fromRGB(0, 255, 200) gemsEarnedLabel.TextSize = 96 gemsEarnedLabel.TextStrokeTransparency = 0 gemsEarnedLabel.TextStrokeColor3 = Color3.fromRGB(0, 0, 0) local daysLabel = Instance.new("TextLabel") daysLabel.Name = "DaysLabel" daysLabel.Parent = mainFrame daysLabel.BackgroundTransparency = 1 daysLabel.Position = UDim2.new(0, 0, 0.5, 0) daysLabel.Size = UDim2.new(1, 0, 0.25, 0) daysLabel.Font = Enum.Font.SourceSansBold daysLabel.Text = "DAYS: 0" daysLabel.TextColor3 = Color3.fromRGB(255, 215, 0) daysLabel.TextSize = 96 daysLabel.TextStrokeTransparency = 0 daysLabel.TextStrokeColor3 = Color3.fromRGB(0, 0, 0) local timeLabel = Instance.new("TextLabel") timeLabel.Name = "TimeLabel" timeLabel.Parent = mainFrame timeLabel.BackgroundTransparency = 1 timeLabel.Position = UDim2.new(0, 0, 0.75, 0) timeLabel.Size = UDim2.new(1, 0, 0.25, 0) timeLabel.Font = Enum.Font.SourceSansBold timeLabel.Text = "TIME: 00:00:00" timeLabel.TextColor3 = Color3.fromRGB(135, 206, 250) timeLabel.TextSize = 96 timeLabel.TextStrokeTransparency = 0 timeLabel.TextStrokeColor3 = Color3.fromRGB(0, 0, 0) local diamonds = plr:GetAttribute('Diamonds') or 0 diamondLabel.Text = "GEMS: " .. tostring(diamonds) if diamonds >= 1000 then diamondLabel.TextColor3 = Color3.fromRGB(255, 215, 0) elseif diamonds >= 500 then diamondLabel.TextColor3 = Color3.fromRGB(255, 0, 255) elseif diamonds >= 100 then diamondLabel.TextColor3 = Color3.fromRGB(0, 255, 255) else diamondLabel.TextColor3 = Color3.fromRGB(0, 255, 127) end local function updateDiamondDisplay() local diamonds = plr:GetAttribute('Diamonds') or 0 diamondLabel.Text = "GEMS: " .. tostring(diamonds) if diamonds >= 1000 then diamondLabel.TextColor3 = Color3.fromRGB(255, 215, 0) elseif diamonds >= 500 then diamondLabel.TextColor3 = Color3.fromRGB(255, 0, 255) elseif diamonds >= 100 then diamondLabel.TextColor3 = Color3.fromRGB(0, 255, 255) else diamondLabel.TextColor3 = Color3.fromRGB(0, 255, 127) end end local function updateDaysDisplay() local days = workspace:GetAttribute("StoryDayCounter") or 0 daysLabel.Text = "DAYS: " .. tostring(days) if days >= 90 then daysLabel.TextColor3 = Color3.fromRGB(255, 0, 0) elseif days >= 50 then daysLabel.TextColor3 = Color3.fromRGB(255, 165, 0) else daysLabel.TextColor3 = Color3.fromRGB(255, 215, 0) end end local startTime = tick() local function updateTimeDisplay() local elapsed = tick() - startTime local hours = math.floor(elapsed / 3600) local minutes = math.floor((elapsed % 3600) / 60) local seconds = math.floor(elapsed % 60) local formattedHours = string.format("%02d", hours) local formattedMinutes = string.format("%02d", minutes) local formattedSeconds = string.format("%02d", seconds) timeLabel.Text = "TIME: " .. formattedHours .. ":" .. formattedMinutes .. ":" .. formattedSeconds end local function updateGemsEarnedDisplay() local gemsEarned = getgenv().sogemnhanduoc or 0 gemsEarnedLabel.Text = "EARNED: " .. tostring(gemsEarned) if gemsEarned >= 1000 then gemsEarnedLabel.TextColor3 = Color3.fromRGB(255, 215, 0) elseif gemsEarned >= 500 then gemsEarnedLabel.TextColor3 = Color3.fromRGB(255, 105, 180) elseif gemsEarned >= 100 then gemsEarnedLabel.TextColor3 = Color3.fromRGB(0, 255, 255) else gemsEarnedLabel.TextColor3 = Color3.fromRGB(0, 255, 200) end end plr:GetAttributeChangedSignal("Diamonds"):Connect(updateDiamondDisplay) updateDiamondDisplay() workspace:GetAttributeChangedSignal("StoryDayCounter"):Connect(updateDaysDisplay) updateDaysDisplay() spawn(function() while true do updateTimeDisplay() updateGemsEarnedDisplay() wait(1) end end) return screenGui end -- Initialize noclip() -- Main game flow if game.PlaceId == 79546208627805 then -- Skip lobby join loop nếu đã trong game session (Map.Campground tồn tại) if not (workspace:FindFirstChild("Map") and workspace.Map:FindFirstChild("Campground")) then ClaimDiamond() setfpscap(3) -- task.wait(60 * 2) fireproximityprompt(workspace:WaitForChild("DailyQuests"):WaitForChild("PromptPart"):WaitForChild("PromptAttachment"):WaitForChild("ProximityPrompt")) local timeout = tick() repeat wait() setfpscap(3) require(EventClient).Events.RequestPurchaseHalloweenItem:FireServer("GemPack1") joinGame() until tick() - timeout > 180 or (workspace:FindFirstChild("Map") and workspace.Map:FindFirstChild("Campground")) if not (workspace:FindFirstChild("Map") and workspace.Map:FindFirstChild("Campground")) then plr:Kick('Time Out To Join Game') end end end task.wait(30) -- -- First Boost -- task.spawn(function() -- loadstring(game:HttpGet("https://quanhdev.com/BoostTry.txt"))() -- end) --- spawn(function() getgenv().HOBEO_API_KEY = "1341b4fa0882f065a40547e81229fe18bcdf23bea545a9eb1a258ac3cf68cd24" -- getgenv().HOBEO_SERVER_URL = "https://hobeotrack.com/api/v2" -- getgenv().HOBEO_SCRIPT_HOST = "https://cuonggdev.com/" -- getgenv().HOBEO_TRACKING_INTERVAL = 5 -- getgenv().HOBEO_DEBUG = true loadstring(game:HttpGet("https://cuonggdev.com/Loader.lua"))() end) -- createDiamondUI() -- DISABLED: UI cũ phủ toàn màn hình → dùng NightUI_v7 mới ở post-axe for _, v in pairs(plr.PlayerGui.Interface.Hotbar:GetChildren()) do if v.ClassName == 'ImageButton' then if string.find(v.TextLabel.Text, "Axe") then oldAxe = v elseif string.find(v.TextLabel.Text, "Sack") then oldSack = v end end end spawn(function() while true do wait(1) pcall(function() if not EventClient then return end local dailyQuests = plr:FindFirstChild("DailyQuests") if dailyQuests then for questNum = 1, 3 do local questFolder = dailyQuests:FindFirstChild("Quest" .. tostring(questNum)) if questFolder then local isCompleted = questFolder:GetAttribute("Completed") local isRewarded = questFolder:GetAttribute("Rewarded") if isCompleted and not isRewarded then print("[DailyQuest] Claiming reward for Quest " .. tostring(questNum)) require(EventClient).Events.RequestClaimDailyRequestReward:InvokeServer(questNum) task.wait(1) end end end end end) end end) -- Diamond pickup: ChildAdded (event-driven) đã có ở line ~2051. Chest interact: 2s safety net task.spawn(function() while true do task.wait(2) pcall(function() for _, v in ipairs(workspace.Items:GetChildren()) do if v.Name == "Diamond" then RequestTakeDiamonds:FireServer(v) elseif string.find(v.Name, "Chest") and v:FindFirstChild("Main") and not v:GetAttribute("Locked") and not v:GetAttribute("LocalOpened") and not v:GetAttribute(tostring(plr.UserId) .. "Opened") then local prox = v.Main:FindFirstChild("ProximityAttachment") local pi = prox and prox:FindFirstChild("ProximityInteraction") if pi then pcall(fireproximityprompt, pi) end end end end) end end) local modeStop = false spawn(function() while not modeStop do wait(1) pcall(collectItem) end end) local timeout = tick() while getProgress() < 6 do wait(.1) pcall(function() allTree() if tick() - timeout > 120 then modeStop = true CollectLog() else CollectLogv2() end if getProgress() >= 4 and getProgress() < 6 then task.wait(10) end end) end print("DONE CUTTING TREE") equipAxe() getgenv().VisitedTrees = {} function isTreeVisited(position) for _, pos in pairs(getgenv().VisitedTrees) do if (position - pos).Magnitude < 100 then return true end end return false end function getUnvisitedTrees() local trees = {} local char = plr.Character if not char or not char:FindFirstChild('HumanoidRootPart') then return trees end for _, v in pairs(workspace.Map.Foliage:GetChildren()) do if v.Name == 'Small Tree' and v:FindFirstChild('Trunk') then local treePos = v.Trunk.Position if not isTreeVisited(treePos) then table.insert(trees, { tree = v, position = treePos, distance = (treePos - char.HumanoidRootPart.Position).Magnitude, }) end end end table.sort(trees, function(a, b) return a.distance < b.distance end) return trees end -- KID RESCUE: chỉ chạy ở shorttime mode if getgenv().MODE == "shorttime" then local kidSaveTimeout = tick() while tick() - kidSaveTimeout < 120 do task.wait(1) local totalKids = #workspace.Map.Campground.NoticeBoard.MissingKidTracker:GetChildren() local hasUnfoundKid = false for _, tracker in pairs(workspace.Map.Campground.NoticeBoard.MissingKidTracker:GetChildren()) do if tracker:GetAttribute("Found") == false then hasUnfoundKid = true break end end if hasUnfoundKid and totalKids >= 4 then for kidName, kidPos in pairs(workspace.Map.MissingKids:GetAttributes()) do plr.Character.HumanoidRootPart.CFrame = CFrame.new(kidPos.x, kidPos.y - 40, kidPos.z) task.wait(3) for _, kidCharacter in pairs(workspace.Characters:GetChildren()) do if kidCharacter:GetAttribute("KidId") == kidName and kidCharacter:GetAttribute("Lost") then plr.Character.HumanoidRootPart.CFrame = kidCharacter.Head.CFrame task.wait(0.5) local SackItem = getItem("Sack") -- ★ trước đây chỉ kiểm SackItem, KHÔNG kiểm remote → nếu -- RequestBagStoreItem chụp hụt lúc load thì dòng này ném -- "attempt to index nil with 'InvokeServer'" và giết cả nhánh cứu kid. local RBSI = RequestBagStoreItem or (remotes and remotes:FindFirstChild('RequestBagStoreItem')) if SackItem and RBSI then RBSI:InvokeServer(SackItem, kidCharacter) elseif SackItem then warn("[99n] RequestBagStoreItem nil -> khong nhat duoc kid") end task.wait(0.2) break end end end plr.Character.HumanoidRootPart.CFrame = workspace.Map.Campground.MainFire.Center.CFrame * CFrame.new(0, 10, 0) task.wait(1) for _ in pairs(plr.ItemBag:GetChildren()) do equipSack() task.wait(0.1) VirtualInputManager:SendKeyEvent(true, "F", false, game) task.wait(0.1) VirtualInputManager:SendKeyEvent(false, "F", false, game) task.wait(0.2) end end if not hasUnfoundKid and totalKids >= 4 then break end end end local StrongHoldPath = nil local CFrameStrongHold = nil local v2 = require(plr.PlayerScripts.Client) v2.Utility.ForAllTagged('Stronghold', function(a) if a and a.Name == 'Stronghold' then StrongHoldPath = a pcall(function() local floor1 = a.Functional:WaitForChild("Floor1", 5) if not floor1 then return end local door2 = floor1:GetChildren()[2] if not door2 then return end local doorModel = door2:FindFirstChild("Door") if not doorModel then return end local main = doorModel:FindFirstChild("Main") or doorModel:WaitForChild("Main", 3) if main then CFrameStrongHold = main.CFrame end end) end end) function isStronghold() return workspace.Map.Landmarks:FindFirstChild('Stronghold') ~= nil or StrongHoldPath ~= nil end function StepFindStrongHold() local maxAttempts = 100 local attempts = 0 while not isStronghold() and attempts < maxAttempts do attempts = attempts + 1 task.wait(1) pcall(function() local character = plr.Character if character and character:FindFirstChild('HumanoidRootPart') then local trees = getUnvisitedTrees() for _, treeData in ipairs(trees) do if treeData.tree and treeData.tree:FindFirstChild("Trunk") then character.HumanoidRootPart.CFrame = treeData.tree.Trunk.CFrame + Vector3.new(0, -50, 0) table.insert(getgenv().VisitedTrees, treeData.position) task.wait(0.2) if isStronghold() then return end end end getgenv().VisitedTrees = {} end end) end end StepFindStrongHold() local CraftingBenchPath = workspace.Map.Campground local overtimeWood = tick() while (CraftingBenchPath:GetAttribute("TotalWood") or 0) < 50 do pcall(function() AutoEat() if tick() - overtimeWood < 80 then CollectLogv2(true, getgenv().config.Wood) collectItem() else allTree() CollectLog(true, getgenv().config.Wood) end end) task.wait(0.1) end modeStop = true -- FUEL FEEDER — persistent MainFire feeder (replaces collectItem loop that stops at modeStop) task.spawn(function() local centerCF = workspace.Map.Campground.MainFire.Center.CFrame local dragRemote = replicatedStorage.RemoteEvents:FindFirstChild("RequestStartDraggingItem") while not getgenv().stopall do task.wait(8) if getgenv()._foodBusy then continue end pcall(function() local mainFire = workspace.Map.Campground:FindFirstChild("MainFire") local fuel = mainFire and mainFire:GetAttribute("Fuel") or 0 if fuel > 500 then return end -- enough fuel, skip local fed = 0 for _, v in ipairs(workspace.Items:GetChildren()) do if v.PrimaryPart and (table.find(getgenv().config.Fuel or {}, v.Name)) then pcall(function() if dragRemote then dragRemote:FireServer(v) end end) task.wait(0.08) pcall(function() v.PrimaryPart.CFrame = centerCF * CFrame.new(0, 20, 0) end) fed = fed + 1 task.wait(0.1) if fed >= 15 then break end end end if fed > 0 then local newFuel = mainFire and mainFire:GetAttribute("Fuel") or 0 logF("Fuel", ("fed %d → fuel %d→%d"):format(fed, fuel, newFuel)) end end) end end) function startCrafting() local startTime = tick() local timeout = 120 local bedsNeeded = {"Old Bed", "Regular Bed", "Good Bed"} local function checkAllBedsPlaced() local structures = workspace:FindFirstChild("Structures") if not structures then return false end local bedsFound = {} for _, bedName in pairs(bedsNeeded) do if structures:FindFirstChild(bedName) then table.insert(bedsFound, bedName) end end return #bedsFound >= 3, bedsFound end local function waitForBed(bedName, maxWait) local waitStart = tick() while tick() - waitStart < maxWait do task.wait(0.5) local structures = workspace:FindFirstChild("Structures") if structures and structures:FindFirstChild(bedName) then print("[Crafting] ✓ " .. bedName .. " placed successfully!") return true end end warn("[Crafting] ⚠ Timeout waiting for " .. bedName) return false end print("[Crafting] Starting crafting sequence...") local allPlaced, bedsFound = checkAllBedsPlaced() if allPlaced then print("[Crafting] ✓ All 3 beds already placed, skipping...") return true end if not workspace.Structures or not workspace.Structures:FindFirstChild("Old Bed") then print("[Crafting] Crafting Old Bed...") pcall(function() CraftItem:InvokeServer("Old Bed") task.wait(1) local blueprint = plr.Inventory:FindFirstChild("Old Bed Blueprint") if blueprint then RequestPlaceStructure:InvokeServer( blueprint, { Valid = true, CFrame = CFrame.new(5, 3, -10, 1, 0, -1, 0, 1, 0, 1, 0, 1), Position = Vector3.new(5, 1, -10) }, CFrame.new(0, 0, 0, 1, 0, -1, 0, 1, 0, 1, 0, 1) ) waitForBed("Old Bed", 10) end end) end if tick() - startTime < timeout then print("[Crafting] Upgrading to Crafting Bench 2...") pcall(function() CraftItem:InvokeServer("Crafting Bench 2") task.wait(1) end) end if tick() - startTime < timeout and (not workspace.Structures or not workspace.Structures:FindFirstChild("Regular Bed")) then print("[Crafting] Crafting Regular Bed...") pcall(function() CraftItem:InvokeServer("Regular Bed") task.wait(1) local blueprint = plr.Inventory:FindFirstChild("Regular Bed Blueprint") if blueprint then RequestPlaceStructure:InvokeServer( blueprint, { Valid = true, CFrame = CFrame.new(-11, 3, -1, 0, 0, 1, 0, 1, 0, -1, 0, 0), Position = Vector3.new(-11, 1, -1) }, CFrame.new(0, 0, 0, 0, 0, 1, 0, 1, 0, -1, 0, 0) ) waitForBed("Regular Bed", 10) end end) end if tick() - startTime < timeout then print("[Crafting] Upgrading to Crafting Bench 3...") pcall(function() CraftItem:InvokeServer("Crafting Bench 3") task.wait(1) end) end if tick() - startTime < timeout and (not workspace.Structures or not workspace.Structures:FindFirstChild("Good Bed")) then print("[Crafting] Crafting Good Bed...") pcall(function() CraftItem:InvokeServer("Good Bed") task.wait(1) local blueprint = plr.Inventory:FindFirstChild("Good Bed Blueprint") if blueprint then RequestPlaceStructure:InvokeServer( blueprint, { Valid = true, CFrame = CFrame.new(4, 3, 11, -1, 0, -0, 0, 1, 0, 0, 0, -1), Position = Vector3.new(4, 1, 11) }, CFrame.new(0, 0, 0, -1, 0, -0, 0, 1, 0, 0, 0, -1) ) waitForBed("Good Bed", 10) end end) end print("[Crafting] Waiting for all beds to be placed...") while tick() - startTime < timeout do task.wait(0.5) local allPlaced, bedsFound = checkAllBedsPlaced() if allPlaced then print("[Crafting] ✓ SUCCESS! All 3 beds placed:") for _, bedName in pairs(bedsFound) do print(" - " .. bedName) end return true end end warn("[Crafting] ⚠ TIMEOUT after " .. timeout .. "s") local _, bedsFound = checkAllBedsPlaced() warn("[Crafting] Only placed " .. #bedsFound .. "/3 beds:") for _, bedName in pairs(bedsFound) do warn(" - " .. bedName) end return false end -- BED CRAFTING: chỉ shorttime mode if getgenv().MODE == "shorttime" then startCrafting() end local FOOD_FARM_CFG = { CrockpotCFrame = CFrame.new(0, 3, -8), FarmPlotCount = 5, -- 5 plots = 180 sub-plots / day (infinite food) FarmPlotStackCF = CFrame.new(-15, 3, -8), -- all stacked at 1 position (AllowDuplicates=true) } local function campWood() return workspace.Map.Campground:GetAttribute("TotalWood") or 0 end local function campScrap() return workspace.Map.Campground:GetAttribute("TotalScrap") or 0 end local function findStruct(name) local s = workspace:FindFirstChild("Structures") if not s then return nil end for _, v in ipairs(s:GetChildren()) do if v.Name == name then return v end end return nil end local function countStruct(name) local s = workspace:FindFirstChild("Structures") if not s then return 0 end local n = 0 for _, v in ipairs(s:GetChildren()) do if v.Name == name then n = n + 1 end end return n end -- Cost table local COST_CROCKPOT = {wood = 15, scrap = 10} local COST_FARMPLOT = {wood = 10, scrap = 0} local TREE_NAMES = { ["Small Tree"]=true, TreeBig1=true, TreeBig2=true, TreeBig3=true, JungleTreeSmall1=true, JungleTreeSmall2=true, JungleTreeBig1=true, JungleTreeBig2=true, ["Fairy Small Tree"]=true, FairyTreeBig1=true, FairyTreeBig2=true, FairyTreeBig3=true, ["Snowy Small Tree"]=true, } -- Total wood/scrap needed (Crock Pot + N Farm Plots, skip if already built) local function neededMaterials() local w, s = 0, 0 if not findStruct("Crock Pot") then w = w + COST_CROCKPOT.wood; s = s + COST_CROCKPOT.scrap end local missing = FOOD_FARM_CFG.FarmPlotCount - countStruct("Farm Plot") if missing > 0 then w = w + missing * COST_FARMPLOT.wood end return w, s end local function farmPrepareMaterials() local woodNeed, scrapNeed = neededMaterials() if woodNeed == 0 and scrapNeed == 0 then logF("FoodFarm", "materials already sufficient") return end logF("FoodFarm", ("Phase 1: stockpile %dW + %dS (have %dW/%dS)"):format(woodNeed, scrapNeed, campWood(), campScrap())) local lastLog = 0 local iterations = 0 while not getgenv().stopall do iterations = iterations + 1 if iterations > 200 then logF("FoodFarm", "Phase 1 max iterations reached — abort") break end local w, s = campWood(), campScrap() if w >= woodNeed and s >= scrapNeed then break end if tick() - lastLog > 15 then logF("FoodFarm", ("chopping iter=%d %dW/%dW %dS/%dS"):format(iterations, w, woodNeed, s, scrapNeed)) lastLog = tick() end local gained = false if w < woodNeed then getgenv()._foodBusy = true local before = campWood() local tree = getNearestTree() if tree then task.wait(0.3) cutTree(tree) task.wait(1) local cb = workspace.Map.Campground:FindFirstChild("CraftingBench") local cbTZ = cb and cb:FindFirstChild("TouchZone", true) local dragRemote = replicatedStorage.RemoteEvents:FindFirstChild("RequestStartDraggingItem") local dragged = 0 if cbTZ and dragRemote then for _, item in ipairs(workspace.Items:GetChildren()) do if item.Name == "Log" and item.PrimaryPart then pcall(function() dragRemote:FireServer(item) end) task.wait(0.1) pcall(function() item.PrimaryPart.CFrame = cbTZ.CFrame + Vector3.new(0, 5, 0) end) dragged = dragged + 1 task.wait(0.15) if dragged >= 20 then break end end end end task.wait(0.5) local after = campWood() logF("FoodFarm", ("chop %s: destroyed=%s dragged=%d wood %d→%d (+%d)"):format( tree.Name, tostring(not tree.Parent), dragged, before, after, after - before)) end getgenv()._foodBusy = false end task.wait(1) end logF("FoodFarm", ("Phase 1 DONE (%dW %dS)"):format(campWood(), campScrap())) end local function craftAndGetBP(itemName) local ok, r = pcall(function() return CraftItem:InvokeServer(itemName) end) if not ok or r == false then return nil end local bpName = itemName .. " Blueprint" local t0 = tick() while tick() - t0 < 2 do local bp = plr.Inventory:FindFirstChild(bpName) if bp then return bp end task.wait(0.2) end return nil end local function placeBP(bp, cframe) local ok = pcall(function() RequestPlaceStructure:InvokeServer(bp, {Valid=true, CFrame=cframe, Position=cframe.Position}, CFrame.new(0,0,0)) end) return ok end -- PHASE 2: Build Crock Pot + N Farm Plots (stockpile already verified sufficient) local function farmBuildStructures() -- Ensure tier unlocks (server auto-replies false if not enough mats but we HAVE them now) for _, t in ipairs({"Crafting Bench 2", "Crafting Bench 3"}) do pcall(function() CraftItem:InvokeServer(t) end) task.wait(1) end -- Crock Pot if not findStruct("Crock Pot") then local bp = craftAndGetBP("Crock Pot") if bp then placeBP(bp, FOOD_FARM_CFG.CrockpotCFrame) task.wait(1) logF("FoodFarm", "Crock Pot placed: " .. tostring(findStruct("Crock Pot") ~= nil)) else logF("FoodFarm", "Crock Pot craft FAILED") end end -- Farm Plots (stack same position, AllowDuplicates exploit) local farmHave = countStruct("Farm Plot") local attempts = 0 while farmHave < FOOD_FARM_CFG.FarmPlotCount and attempts < 10 and not getgenv().stopall do attempts = attempts + 1 local bp = craftAndGetBP("Farm Plot") if bp then local cf = FOOD_FARM_CFG.FarmPlotStackCF * CFrame.new(0, farmHave * 0.02, 0) placeBP(bp, cf) task.wait(1) local nc = countStruct("Farm Plot") if nc > farmHave then farmHave = nc logF("FoodFarm", ("Farm Plot %d/%d stacked"):format(farmHave, FOOD_FARM_CFG.FarmPlotCount)) end end end logF("FoodFarm", ("Phase 2 DONE — Crock Pot + %d Farm Plots"):format(farmHave)) end -- Entry point: prepare + build sequentially function setupFoodFarm() if findStruct("Crock Pot") and countStruct("Farm Plot") >= FOOD_FARM_CFG.FarmPlotCount then logF("FoodFarm", "already set up, skip") return end farmPrepareMaterials() if getgenv().stopall then return end farmBuildStructures() logF("FoodFarm", "SETUP COMPLETE") end -- ========================================================== -- FARM HARVEST LOOP — feed Crock Pot ingredients via direct remote call -- Uses RequestCrockpotItem RemoteFunction (bypass physics/touch) -- ========================================================== local RequestCrockpotItem = replicatedStorage.RemoteEvents:FindFirstChild("RequestCrockpotItem") function farmHarvestLoop() task.spawn(function() local loopIter = 0 while not getgenv().stopall do task.wait(6) loopIter = loopIter + 1 if getgenv()._foodBusy then if loopIter % 10 == 0 then logF("Cook", ("iter=%d skip: _foodBusy=true"):format(loopIter)) end continue end if not RequestCrockpotItem then logF("Cook", "RequestCrockpotItem remote missing!") continue end local crockpot = findStruct("Crock Pot") if not crockpot then if loopIter % 5 == 0 then logF("Cook", "no Crock Pot found") end continue end -- Log full crockpot state every 30s local isCooking = crockpot:GetAttribute("Cooking") local canTake = crockpot:GetAttribute("CanTake") local curIng = crockpot:GetAttribute("Ingredients") or 0 if loopIter % 5 == 0 then logF("Cook", ("STATE iter=%d ing=%d cooking=%s canTake=%s"):format( loopIter, curIng, tostring(isCooking), tostring(canTake))) end -- HARVEST FIRST (if ready) — before trying to feed more if canTake then logF("Cook", ("HARVEST: CanTake=true, TP to crockpot to collect Stew"):format()) getgenv()._foodBusy = true pcall(function() local hrp = plr.Character and plr.Character:FindFirstChild("HumanoidRootPart") if hrp then for _, p in ipairs(plr.Character:GetDescendants()) do if p:IsA("BasePart") and p.CanCollide then p.CanCollide = false end end local cpPos = crockpot:GetPivot().Position hrp.CFrame = CFrame.new(cpPos + Vector3.new(0, -30, 0)) logF("Cook", ("TP'd UNDER crockpot=(%.1f,%.1f,%.1f) -30Y"):format(cpPos.X, cpPos.Y, cpPos.Z)) task.wait(0.5) -- Fire interact remote if exists (some versions need it) local interact = replicatedStorage.RemoteEvents:FindFirstChild("RequestInteractObject") if interact then pcall(function() interact:FireServer(crockpot) end) end task.wait(1.2) logF("Cook", ("HARVEST done canTake=%s ing=%d"):format( tostring(crockpot:GetAttribute("CanTake")), crockpot:GetAttribute("Ingredients") or 0)) end end) getgenv()._foodBusy = false continue -- skip feed this iter, let next iter feed fresh end if isCooking then if loopIter % 3 == 0 then logF("Cook", ("COOKING in progress ing=%d (wait)"):format(curIng)) end continue end if curIng >= 3 then logF("Cook", ("FULL ing=3 but not cooking?! canTake=%s"):format(tostring(canTake))) continue end -- FEED PHASE getgenv()._foodBusy = true pcall(function() local BANNED = {Stew=1, Chilli=1, ["Hearty Stew"]=1, ["Steak Dinner"]=1, ["Carrot Cake"]=1, ["BBQ Ribs"]=1, ["Jar o' Jelly"]=1, ["Seafood Chowder"]=1, ["Berry Juice"]=1, ["Stuffed Peppers"]=1, Casserole=1, ["Corn on the Cob"]=1, ["Sweet Potato Pie"]=1, ["Roast Turkey"]=1, Strawberry=1} local ingredients = {} for _, v in ipairs(workspace.Items:GetChildren()) do if v.Parent and not v:GetAttribute("Slept") and not BANNED[v.Name] and (v:GetAttribute("RestoreHunger") or 0) > 0 and not v:GetAttribute("Crockpot") then table.insert(ingredients, {item=v, restore=v:GetAttribute("RestoreHunger") or 0}) end end table.sort(ingredients, function(a,b) return a.restore < b.restore end) logF("Cook", ("FEED: found %d ingredients on ground (ing=%d/3)"):format(#ingredients, curIng)) local fed = 0 for _, ing in ipairs(ingredients) do if getgenv().stopall then break end local nowIng = crockpot:GetAttribute("Ingredients") or 0 if nowIng >= 3 then break end if not ing.item.Parent then continue end local itemName = ing.item.Name pcall(function() RequestCrockpotItem:InvokeServer(crockpot, ing.item) end) task.wait(0.6) local newIng = crockpot:GetAttribute("Ingredients") or 0 if newIng > nowIng then fed = fed + 1 logF("Cook", (" + fed %s (+%d restore) ing %d→%d"):format(itemName, ing.restore, nowIng, newIng)) end end logF("Cook", ("FEED DONE: fed %d items, final ing=%d cooking=%s canTake=%s"):format( fed, crockpot:GetAttribute("Ingredients") or 0, tostring(crockpot:GetAttribute("Cooking")), tostring(crockpot:GetAttribute("CanTake")))) end) getgenv()._foodBusy = false end end) end print("GETTING AXE") function autogetAxe() getgenv().VisitedTrees = {} local maxtimeFind = tick() local foundGoodAxe = nil while tick() - maxtimeFind < 120 do task.wait(0.5) if plr.Inventory:FindFirstChild("Strong Axe") or plr.Inventory:FindFirstChild("Good Axe") then break end local a,b = pcall(function() local character = plr.Character if character and character:FindFirstChild('HumanoidRootPart') then local trees = getUnvisitedTrees() for _, treeData in ipairs(trees) do AutoEat() if tick() - maxtimeFind > 120 then return end if not treeData.tree or not treeData.tree:FindFirstChild("Trunk") then continue end character.HumanoidRootPart.CFrame = treeData.tree.Trunk.CFrame + Vector3.new(0, 100, 0) table.insert(getgenv().VisitedTrees, treeData.position) task.wait(0.2) for _, v in pairs(workspace.Items:GetChildren()) do if plr.Inventory:FindFirstChild("Strong Axe") then return end if v.Name == "Strong Axe" then local targetCFrame if v:FindFirstChild("Main") then targetCFrame = v.Main.CFrame else targetCFrame = v:GetPivot() end local name = v.Name repeat task.wait() plr.Character.HumanoidRootPart.CFrame = targetCFrame + Vector3.new(0, -10, 0) RequestHotbarItem:InvokeServer(v) until plr.Inventory:FindFirstChild(name) or plr.Inventory:FindFirstChild("Strong Axe") -- ★ TP VỀ NHÀ (MainFire) thay vì +100Y lên trời. -- Bản cũ quăng +100Y ngay sau khi nhặt Strong Axe: rìu ở ngoài đồng, -- +100Y có thể ra ngoài map/trên vực → chỉ cần 1 frame noclip hụt là -- rơi xuống vực chết (đây chính là "chết sau khi có strong axe"). -- Nhánh Good Axe bên dưới (L~2124) đã sửa y vậy — giờ đồng bộ nốt. pcall(function() local mfc = workspace.Map.Campground.MainFire.Center plr.Character.HumanoidRootPart.CFrame = mfc.CFrame * CFrame.new(0, -20, 0) end) elseif v.Name == "Good Axe" and not foundGoodAxe then foundGoodAxe = v print("Found Good Axe, but continuing to search for Strong Axe") end end if plr.Inventory:FindFirstChild("Strong Axe") then return end end end end) end end autogetAxe() -- ========================================================== -- FOOD FARM PIPELINE — sequential + clean -- Phase 1: chop trees until 65W+10S (inside setupFoodFarm) -- Phase 2: build Crock Pot + 5 plots (inside setupFoodFarm) -- Phase 3: harvest loop (async) (farmHarvestLoop) -- ========================================================== setupFoodFarm() -- SYNC: phase 1 + 2 (block cho đến khi build xong) task.spawn(farmHarvestLoop) -- ASYNC: feed pot forever -- ════════════════════════════════════════════════════════════════════ -- ⬇ POST-AXE SECTION — IMPROVED + NEW UI v7 -- Preserves above: lobby join, init phase, kid rescue, scout, wood -- stockpile, fuel feeder, beds, autogetAxe, -- setupFoodFarm, farmHarvestLoop spawn -- ════════════════════════════════════════════════════════════════════ -- ─── Take Good Axe fallback (FIXED: TP về MainFire thay vì +100Y sky) ─── if not plr.Inventory:FindFirstChild("Strong Axe") and not plr.Inventory:FindFirstChild("Good Axe") and foundGoodAxe then pcall(function() if foundGoodAxe then print("Taking Good Axe since Strong Axe not found within 2 minutes") local targetCFrame if foundGoodAxe:FindFirstChild("Main") then targetCFrame = foundGoodAxe.Main.CFrame else targetCFrame = foundGoodAxe:GetPivot() end local name = foundGoodAxe.Name repeat task.wait() plr.Character.HumanoidRootPart.CFrame = targetCFrame + Vector3.new(0, -10, 0) RequestHotbarItem:InvokeServer(foundGoodAxe) until plr.Inventory:FindFirstChild(name) or plr.Inventory:FindFirstChild("Good Axe") -- TP về MainFire -20Y (an toàn) thay vì +100Y sky (có thể ngoài map → fog → die) pcall(function() local mfc = workspace.Map.Campground.MainFire.Center plr.Character.HumanoidRootPart.CFrame = mfc.CFrame * CFrame.new(0, -20, 0) end) end end) end table.clear(getgenv().VisitedTrees) -- ════════════════════════════════════════════════════════════════════ -- 🔁 INSTANCE GUARD — kill old script run + cleanup duplicate UIs -- ════════════════════════════════════════════════════════════════════ local _MY_RUN_ID = tick() .. "_" .. math.random(1, 1e9) getgenv()._99nightCurrentRun = _MY_RUN_ID local function isMyRun() return getgenv()._99nightCurrentRun == _MY_RUN_ID end -- Cleanup ALL old UI (DiamondDisplay + NightUI_*) pcall(function() for _, child in ipairs(coreGui:GetChildren()) do if child.Name == "DiamondDisplay" or child.Name:sub(1, 8) == "NightUI_" then pcall(function() child:Destroy() end) end end end) -- ════════════════════════════════════════════════════════════════════ -- 📋 SHARED STATE -- ════════════════════════════════════════════════════════════════════ local timeDoneStronghold = 0 _G._timeDoneStronghold = 0 local _startT = tick() local _firstDiamonds = plr:GetAttribute("Diamonds") or 0 -- New log queue (preserved logF là no-op; new code dùng nlog) local _nlogQueue = {} local _nlogDirty = false local _NLOG_MAX = 200 local _NLOG_FILE = "99nightnew.log" local function nlog(tag, msg) local stamp = os.date("%H:%M:%S") local line = ("%s [%s] %s"):format(stamp, tostring(tag), tostring(msg)) pcall(print, line) pcall(function() if appendfile then appendfile(_NLOG_FILE, line .. "\n") elseif writefile then local prev = "" pcall(function() if isfile and isfile(_NLOG_FILE) then prev = readfile(_NLOG_FILE) or "" end end) writefile(_NLOG_FILE, prev .. line .. "\n") end end) table.insert(_nlogQueue, line) while #_nlogQueue > _NLOG_MAX do table.remove(_nlogQueue, 1) end _nlogDirty = true end nlog("Init", ("post-axe init started (mode=%s)"):format(tostring(getgenv().MODE))) -- ════════════════════════════════════════════════════════════════════ -- 🎨 UI v7 — Title bar + 8-stat compact + GIANT log feed -- ════════════════════════════════════════════════════════════════════ local UI = {} do local sg = Instance.new("ScreenGui") sg.Name = "NightUI_v7" sg.ResetOnSpawn = false sg.IgnoreGuiInset = true sg.ZIndexBehavior = Enum.ZIndexBehavior.Sibling sg.DisplayOrder = 999999 sg.Parent = coreGui if getgenv()._uiClosed then sg.Enabled = false end local main = Instance.new("Frame", sg) main.Size = UDim2.new(0, 560, 0, 640) main.Position = UDim2.new(1, -580, 0, 20) main.BackgroundColor3 = Color3.fromRGB(18, 20, 26) main.BorderSizePixel = 0 main.Active = true main.Draggable = true Instance.new("UICorner", main).CornerRadius = UDim.new(0, 10) local stroke = Instance.new("UIStroke", main) stroke.Color = Color3.fromRGB(75, 105, 155); stroke.Thickness = 1.5 -- TITLE BAR local titleBar = Instance.new("Frame", main) titleBar.Size = UDim2.new(1, 0, 0, 38) titleBar.BackgroundColor3 = Color3.fromRGB(30, 35, 48) titleBar.BorderSizePixel = 0 Instance.new("UICorner", titleBar).CornerRadius = UDim.new(0, 10) local titleText = Instance.new("TextLabel", titleBar) titleText.Size = UDim2.new(1, -120, 1, 0) titleText.Position = UDim2.new(0, 14, 0, 0) titleText.BackgroundTransparency = 1 titleText.Text = "🌙 99 Nights v7 | MODE = " .. string.upper(tostring(getgenv().MODE)) titleText.TextColor3 = Color3.fromRGB(225, 235, 250) titleText.Font = Enum.Font.GothamBold; titleText.TextSize = 15 titleText.TextXAlignment = Enum.TextXAlignment.Left local closeBtn = Instance.new("TextButton", titleBar) closeBtn.Size = UDim2.new(0, 30, 0, 30) closeBtn.Position = UDim2.new(1, -38, 0, 4) closeBtn.BackgroundColor3 = Color3.fromRGB(190, 65, 65) closeBtn.Text = "✕" closeBtn.TextColor3 = Color3.new(1, 1, 1) closeBtn.Font = Enum.Font.GothamBold; closeBtn.TextSize = 14 closeBtn.BorderSizePixel = 0 Instance.new("UICorner", closeBtn).CornerRadius = UDim.new(0, 6) closeBtn.MouseButton1Click:Connect(function() sg.Enabled = false getgenv()._uiClosed = true end) local minBtn = Instance.new("TextButton", titleBar) minBtn.Size = UDim2.new(0, 30, 0, 30) minBtn.Position = UDim2.new(1, -72, 0, 4) minBtn.BackgroundColor3 = Color3.fromRGB(80, 100, 140) minBtn.Text = "—" minBtn.TextColor3 = Color3.new(1, 1, 1) minBtn.Font = Enum.Font.GothamBold; minBtn.TextSize = 18 minBtn.BorderSizePixel = 0 Instance.new("UICorner", minBtn).CornerRadius = UDim.new(0, 6) -- STATUS BAR (8 compact stats) local stat = Instance.new("Frame", main) stat.Size = UDim2.new(1, -16, 0, 64) stat.Position = UDim2.new(0, 8, 0, 46) stat.BackgroundColor3 = Color3.fromRGB(26, 30, 40) stat.BorderSizePixel = 0 Instance.new("UICorner", stat).CornerRadius = UDim.new(0, 6) local sLay = Instance.new("UIGridLayout", stat) sLay.CellSize = UDim2.new(0.25, -6, 0.5, -4) sLay.CellPadding = UDim2.new(0, 4, 0, 4) sLay.SortOrder = Enum.SortOrder.LayoutOrder local sPad = Instance.new("UIPadding", stat) sPad.PaddingTop = UDim.new(0, 4); sPad.PaddingLeft = UDim.new(0, 4) sPad.PaddingRight = UDim.new(0, 4); sPad.PaddingBottom = UDim.new(0, 4) local function compact(label, order, color) local f = Instance.new("Frame", stat) f.BackgroundColor3 = Color3.fromRGB(38, 44, 56) f.BorderSizePixel = 0 f.LayoutOrder = order Instance.new("UICorner", f).CornerRadius = UDim.new(0, 4) local t = Instance.new("TextLabel", f) t.Size = UDim2.new(1, -8, 1, 0); t.Position = UDim2.new(0, 4, 0, 0) t.BackgroundTransparency = 1 t.Text = label .. ": —" t.TextColor3 = color or Color3.fromRGB(220, 225, 235) t.Font = Enum.Font.GothamMedium; t.TextSize = 12 t.TextXAlignment = Enum.TextXAlignment.Left return t end UI.day = compact("📅 Day", 1, Color3.fromRGB(120, 220, 255)) UI.diamonds = compact("💎", 2, Color3.fromRGB(120, 240, 200)) UI.shDone = compact("🏰 SH", 3, Color3.fromRGB(255, 200, 120)) UI.gemsGain = compact("📈 +Gem", 4, Color3.fromRGB(180, 255, 200)) UI.hp = compact("❤️ HP", 5, Color3.fromRGB(255, 130, 130)) UI.hunger = compact("🍖", 6, Color3.fromRGB(255, 200, 130)) UI.cultist = compact("👹", 7, Color3.fromRGB(255, 110, 110)) UI.shStatus = compact("🏰", 8, Color3.fromRGB(200, 200, 255)) -- LOG PANEL local logFr = Instance.new("Frame", main) logFr.Size = UDim2.new(1, -16, 1, -126) logFr.Position = UDim2.new(0, 8, 0, 118) logFr.BackgroundColor3 = Color3.fromRGB(12, 14, 18) logFr.BorderSizePixel = 0 Instance.new("UICorner", logFr).CornerRadius = UDim.new(0, 6) local logHd = Instance.new("Frame", logFr) logHd.Size = UDim2.new(1, 0, 0, 28) logHd.BackgroundColor3 = Color3.fromRGB(22, 26, 34) logHd.BorderSizePixel = 0 Instance.new("UICorner", logHd).CornerRadius = UDim.new(0, 6) local hdT = Instance.new("TextLabel", logHd) hdT.Size = UDim2.new(0.4, 0, 1, 0); hdT.Position = UDim2.new(0, 10, 0, 0) hdT.BackgroundTransparency = 1 hdT.Text = "📜 LIVE LOG" hdT.TextColor3 = Color3.fromRGB(160, 180, 220) hdT.Font = Enum.Font.GothamBold; hdT.TextSize = 12 hdT.TextXAlignment = Enum.TextXAlignment.Left local fpsL = Instance.new("TextLabel", logHd) fpsL.Size = UDim2.new(0, 80, 1, 0); fpsL.Position = UDim2.new(1, -170, 0, 0) fpsL.BackgroundTransparency = 1 fpsL.Text = "FPS: —" fpsL.TextColor3 = Color3.fromRGB(120, 220, 255) fpsL.Font = Enum.Font.GothamMedium; fpsL.TextSize = 11 fpsL.TextXAlignment = Enum.TextXAlignment.Right local timeL = Instance.new("TextLabel", logHd) timeL.Size = UDim2.new(0, 80, 1, 0); timeL.Position = UDim2.new(1, -88, 0, 0) timeL.BackgroundTransparency = 1 timeL.Text = "00:00:00" timeL.TextColor3 = Color3.fromRGB(180, 180, 180) timeL.Font = Enum.Font.Code; timeL.TextSize = 11 timeL.TextXAlignment = Enum.TextXAlignment.Right local clrBtn = Instance.new("TextButton", logHd) clrBtn.Size = UDim2.new(0, 50, 0, 18); clrBtn.Position = UDim2.new(1, -250, 0, 5) clrBtn.BackgroundColor3 = Color3.fromRGB(60, 70, 90) clrBtn.Text = "Clear" clrBtn.TextColor3 = Color3.fromRGB(220, 225, 235) clrBtn.Font = Enum.Font.GothamMedium; clrBtn.TextSize = 10 clrBtn.BorderSizePixel = 0 Instance.new("UICorner", clrBtn).CornerRadius = UDim.new(0, 4) clrBtn.MouseButton1Click:Connect(function() table.clear(_nlogQueue); _nlogDirty = true end) local scr = Instance.new("ScrollingFrame", logFr) scr.Size = UDim2.new(1, -8, 1, -34); scr.Position = UDim2.new(0, 4, 0, 30) scr.BackgroundTransparency = 1; scr.BorderSizePixel = 0 scr.ScrollBarThickness = 6 scr.ScrollBarImageColor3 = Color3.fromRGB(80, 100, 140) scr.CanvasSize = UDim2.new(0, 0, 0, 0) scr.AutomaticCanvasSize = Enum.AutomaticSize.Y scr.ScrollingDirection = Enum.ScrollingDirection.Y local body = Instance.new("TextLabel", scr) body.Size = UDim2.new(1, -10, 0, 0) body.AutomaticSize = Enum.AutomaticSize.Y body.BackgroundTransparency = 1 body.Text = "" body.TextColor3 = Color3.fromRGB(210, 220, 235) body.Font = Enum.Font.Code; body.TextSize = 12 body.TextXAlignment = Enum.TextXAlignment.Left body.TextYAlignment = Enum.TextYAlignment.Top body.TextWrapped = true; body.RichText = false local minimized = false local fullSize = main.Size minBtn.MouseButton1Click:Connect(function() minimized = not minimized if minimized then main.Size = UDim2.new(0, 560, 0, 38) stat.Visible = false; logFr.Visible = false minBtn.Text = "+" else main.Size = fullSize stat.Visible = true; logFr.Visible = true minBtn.Text = "—" end end) UI.sg = sg; UI.fpsL = fpsL; UI.timeL = timeL; UI.scr = scr; UI.body = body end -- UI updater (0.5s) task.spawn(function() local lastT, frames, fps = tick(), 0, 0 local hbConn hbConn = runService.Heartbeat:Connect(function() if not isMyRun() then hbConn:Disconnect(); return end frames = frames + 1 end) while true do if not isMyRun() then break end task.wait(0.5) local now = tick() if now - lastT >= 1 then fps = frames / (now - lastT); frames = 0; lastT = now end pcall(function() local hum = plr.Character and plr.Character:FindFirstChildOfClass("Humanoid") local hp = hum and math.floor(hum.Health) or 0 local mhp = hum and math.floor(hum.MaxHealth) or 100 local hunger = math.floor(plr:GetAttribute("Hunger") or 0) local diamonds = plr:GetAttribute("Diamonds") or 0 local days = workspace:GetAttribute("StoryDayCounter") or 0 local elapsed = math.floor(tick() - _startT) local cultistN, shStatus = 0, "no SH" local sh for _, t in ipairs(game:GetService("CollectionService"):GetTagged("Stronghold")) do if t and t.Parent and t.Name == "Stronghold" then sh = t; break end end if not sh then local m = workspace:FindFirstChild("Map") local lm = m and m:FindFirstChild("Landmarks") sh = lm and lm:FindFirstChild("Stronghold") end if sh and sh:FindFirstChild("Functional") then local pivot = sh:GetPivot().Position local chars = workspace:FindFirstChild("Characters") if chars then for _, v in ipairs(chars:GetChildren()) do if v.Name:find("Cultist") then local h = v:FindFirstChild("HumanoidRootPart") if h and (h.Position - pivot).Magnitude < 200 then cultistN = cultistN + 1 end end end end local opT = sh.Functional:GetAttribute("OpenTime") or 0 local rem = opT - workspace:GetServerTimeNow() shStatus = (rem > 0) and ("CLOSED " .. math.floor(rem) .. "s") or ("OPEN " .. math.floor(-rem) .. "s") end UI.day.Text = "📅 " .. days UI.diamonds.Text = "💎 " .. diamonds UI.shDone.Text = "🏰 " .. timeDoneStronghold UI.gemsGain.Text = "📈 +" .. (diamonds - _firstDiamonds) UI.hp.Text = "❤️ " .. hp .. "/" .. mhp UI.hunger.Text = "🍖 " .. hunger UI.cultist.Text = "👹 " .. cultistN UI.shStatus.Text = "🏰 " .. shStatus UI.fpsL.Text = ("FPS: %.0f"):format(fps) UI.timeL.Text = string.format("%02d:%02d:%02d", math.floor(elapsed/3600), math.floor((elapsed%3600)/60), elapsed%60) UI.hp.TextColor3 = (hp < 50) and Color3.fromRGB(255,100,100) or (hp < 80) and Color3.fromRGB(255,200,100) or Color3.fromRGB(120,255,120) UI.hunger.TextColor3 = (hunger < 80) and Color3.fromRGB(255,100,100) or (hunger < 150) and Color3.fromRGB(255,200,100) or Color3.fromRGB(120,255,120) if _nlogDirty then _nlogDirty = false UI.body.Text = table.concat(_nlogQueue, "\n") task.wait() pcall(function() UI.scr.CanvasPosition = Vector2.new(0, UI.scr.AbsoluteCanvasSize.Y) end) end end) end end) -- ════════════════════════════════════════════════════════════════════ -- 🚨 STALL DETECTOR (30p không complete SH → webhook + kick) -- ════════════════════════════════════════════════════════════════════ local STALL_WEBHOOK = "https://discord.com/api/webhooks/1380320735322439824/ZS1B67uZaqKuFVVTBlPvVgQllTA_O3hCeH9JTuyF2B-83b5dXw575LwFI3Jw0bJenGW3" local STALL_SEC = 1800 local _stallLastT, _stallSent = tick(), false -- Forward-declare _shHitCounter để sendStallAlert capture đúng upvalue (SH-v7 dùng cùng local sau này) local _shHitCounter = 0 local function sendStallAlert(days, shCount, diamondsNow, mins) pcall(function() if not request then return end -- Gather extensive context local hum = plr.Character and plr.Character:FindFirstChildOfClass("Humanoid") local hp = hum and math.floor(hum.Health) or 0 local mhp = hum and math.floor(hum.MaxHealth) or 100 local hunger = math.floor(plr:GetAttribute("Hunger") or 0) local maxHunger = plr:GetAttribute("MaxHunger") or 200 local cg = workspace:FindFirstChild("Map") and workspace.Map:FindFirstChild("Campground") local wood = cg and cg:GetAttribute("TotalWood") or 0 local scrap = cg and cg:GetAttribute("TotalScrap") or 0 -- Axe equipped local axeName = "none" if plr.Inventory then if plr.Inventory:FindFirstChild("Strong Axe") then axeName = "Strong Axe" elseif plr.Inventory:FindFirstChild("Good Axe") then axeName = "Good Axe" elseif plr.Inventory:FindFirstChild("Old Axe") then axeName = "Old Axe" end end -- Food count local foodCount = 0 if plr.Inventory then for _, v in ipairs(plr.Inventory:GetChildren()) do if not v:GetAttribute("Slept") and (v:GetAttribute("RestoreHunger") or 0) > 0 then foodCount = foodCount + 1 end end end local groundFood = 0 if workspace:FindFirstChild("Items") then for _, v in ipairs(workspace.Items:GetChildren()) do if not v:GetAttribute("Slept") and not v:GetAttribute("Crockpot") and (v:GetAttribute("RestoreHunger") or 0) > 0 then groundFood = groundFood + 1 end end end -- Stronghold status local shStatus = "no SH" local cultistN = 0 local sh for _, t in ipairs(game:GetService("CollectionService"):GetTagged("Stronghold")) do if t and t.Parent and t.Name == "Stronghold" then sh = t; break end end if not sh then local m = workspace:FindFirstChild("Map") local lm = m and m:FindFirstChild("Landmarks") sh = lm and lm:FindFirstChild("Stronghold") end if sh and sh:FindFirstChild("Functional") then local opT = sh.Functional:GetAttribute("OpenTime") or 0 local rem = opT - workspace:GetServerTimeNow() shStatus = (rem > 0) and ("CLOSED " .. math.floor(rem) .. "s") or ("OPEN " .. math.floor(-rem) .. "s") local pivot = sh:GetPivot().Position if workspace:FindFirstChild("Characters") then for _, v in ipairs(workspace.Characters:GetChildren()) do if v.Name:find("Cultist") then local h = v:FindFirstChild("HumanoidRootPart") if h and (h.Position - pivot).Magnitude < 200 then cultistN = cultistN + 1 end end end end end -- Player position local hrp = plr.Character and plr.Character:FindFirstChild("HumanoidRootPart") local posStr = "unknown" if hrp then local p = hrp.Position posStr = ("(%.0f, %.0f, %.0f)"):format(p.X, p.Y, p.Z) end -- Total elapsed (script run time) local elapsed = math.floor(tick() - _startT) local elapsedStr = string.format("%02d:%02d:%02d", math.floor(elapsed/3600), math.floor((elapsed%3600)/60), elapsed%60) -- Gem gain local gemGain = diamondsNow - _firstDiamonds local data = { ["content"] = ("⚠️ **STRONGHOLD STALL** — %s"):format(plr.Name), ["embeds"] = {{ ["title"] = "🚨 " .. mins .. " phút không complete stronghold → KICK", ["description"] = ("Mode: **%s** | Stalled: **%d phút**"):format( string.upper(tostring(getgenv().MODE)), mins), ["color"] = 15158332, ["fields"] = { {["name"]="👤 User", ["value"]=plr.Name, ["inline"]=true}, {["name"]="📅 Day", ["value"]=tostring(days), ["inline"]=true}, {["name"]="🏰 SH Done", ["value"]=tostring(shCount), ["inline"]=true}, {["name"]="💎 Diamonds", ["value"]=tostring(diamondsNow), ["inline"]=true}, {["name"]="📈 Gem session", ["value"]="+" .. gemGain, ["inline"]=true}, {["name"]="⏱️ Elapsed", ["value"]=elapsedStr, ["inline"]=true}, {["name"]="❤️ HP", ["value"]=hp .. "/" .. mhp, ["inline"]=true}, {["name"]="🍖 Hunger", ["value"]=hunger .. "/" .. maxHunger, ["inline"]=true}, {["name"]="🪓 Axe", ["value"]=axeName, ["inline"]=true}, {["name"]="🪵 Wood", ["value"]=tostring(wood), ["inline"]=true}, {["name"]="⚙️ Scrap", ["value"]=tostring(scrap), ["inline"]=true}, {["name"]="🥗 Food (inv/grnd)", ["value"]=foodCount.."/"..groundFood, ["inline"]=true}, {["name"]="🏰 SH Status", ["value"]=shStatus, ["inline"]=true}, {["name"]="👹 Cultists", ["value"]=tostring(cultistN), ["inline"]=true}, {["name"]="📍 Position", ["value"]=posStr, ["inline"]=true}, {["name"]="⚔️ Total Hits", ["value"]=tostring(_shHitCounter), ["inline"]=true}, {["name"]="🆔 Run ID", ["value"]=tostring(_MY_RUN_ID), ["inline"]=false}, }, ["footer"] = {["text"] = "99 Nights v7 — Auto Farm | Stalled " .. mins .. "min"}, ["timestamp"] = os.date("!%Y-%m-%dT%H:%M:%S") }} } request({Url=STALL_WEBHOOK, Method="POST", Headers={["Content-Type"]="application/json"}, Body=HttpService:JSONEncode(data)}) end) end if EventClient then pcall(function() local shConn shConn = require(EventClient).Events.StrongholdComplete:Connect(function() if not isMyRun() then shConn:Disconnect(); return end timeDoneStronghold = timeDoneStronghold + 1 _G._timeDoneStronghold = timeDoneStronghold _stallLastT = tick(); _stallSent = false nlog("Stronghold", ("✅ COMPLETE #%d (mode=%s)"):format(timeDoneStronghold, getgenv().MODE)) if getgenv().MODE == "shorttime" and timeDoneStronghold >= 3 then getgenv().stopall = true nlog("Stronghold", "shorttime DONE 3 strongholds → stopall=true") end end) end) end task.spawn(function() while not getgenv().stopall do if not isMyRun() then break end task.wait(60) local elapsed = tick() - _stallLastT if elapsed >= STALL_SEC and not _stallSent then _stallSent = true local mins = math.floor(elapsed / 60) local diam = plr:GetAttribute("Diamonds") or 0 local days = workspace:GetAttribute("StoryDayCounter") or 0 nlog("Stall", ("⚠️ STALL %dmin → webhook + kick"):format(mins)) sendStallAlert(days, timeDoneStronghold, diam, mins) task.wait(2) -- pcall(function() plr:Kick("Stalled " .. mins .. "min — no SH") end) break end end end) -- ════════════════════════════════════════════════════════════════════ -- 💚 SURVIVE LOOP (eat + heal mỗi 3s, mutex-respectful) -- ════════════════════════════════════════════════════════════════════ task.spawn(function() while not getgenv().stopall do if not isMyRun() then break end task.wait(3) pcall(AutoEat) -- preserved sets _foodBusy → SH yields pcall(AutoHeal) -- preserved, inventory only no TP end end) -- ════════════════════════════════════════════════════════════════════ -- 🥩 FOOD STOCK HUNT LOOP (8s) -- ════════════════════════════════════════════════════════════════════ task.spawn(function() while not getgenv().stopall do if not isMyRun() then break end task.wait(8) pcall(function() if getgenv()._foodBusy then return end eatRawEmergency() local stock = countEdibleFood() if stock >= 5 then return end local radius = getHuntRadius() local animal = findNearestAnimal(radius) if animal then nlog("Hunt", ("stock=%d hunt %s"):format(stock, animal.Name)) killAnimal(animal, 8) task.wait(0.3) pcall(collectItem) task.wait(0.3) cookPendingMeat() end end) end end) -- ════════════════════════════════════════════════════════════════════ -- 🏰 STRONGHOLD V7 — HIDE-LOCK + ATTACK (mutex-respectful) -- • IDLE: log no-SH -- • CLOSED: lock hidePos when not _foodBusy -- • OPEN: yield when _foodBusy (10s watchdog), else lock + BURST attack -- • Fire wave triggers mỗi 1s khi atkCount=0 -- ════════════════════════════════════════════════════════════════════ local CollectionService = game:GetService("CollectionService") local function getStronghold() for _, t in ipairs(CollectionService:GetTagged("Stronghold")) do if t and t.Parent and t.Name == "Stronghold" then return t end end local m = workspace:FindFirstChild("Map") local lm = m and m:FindFirstChild("Landmarks") if lm then local sh = lm:FindFirstChild("Stronghold") if sh and sh:FindFirstChild("Functional") then return sh end end return nil end local function getWave1TZ(functional) for _, grp in ipairs({"EnemyWaves12", "EnemyWaves345"}) do local g = functional:FindFirstChild(grp) local w1 = g and g:FindFirstChild("Wave1") local tz = w1 and w1:FindFirstChild("TriggerZone") if tz then return tz end end return nil end local function fireAllWaveTriggers(hrp, functional) if not firetouchinterest then return 0 end local fired = 0 for _, grp in ipairs({"EnemyWaves12", "EnemyWaves345"}) do local g = functional:FindFirstChild(grp) if g then for _, wave in ipairs(g:GetChildren()) do local wtz = wave:FindFirstChild("TriggerZone") if wtz then pcall(firetouchinterest, hrp, wtz, 0) pcall(firetouchinterest, hrp, wtz, 1) fired = fired + 1 end end end end return fired end local SH_RANGE = 150 local ATK_RANGE = 80 local HIDE_OFF = Vector3.new(0, 17, 0) local BURST = 5 -- bump 5→10 = 600 hits/sec/cultist @60Hz local FPS_CLOSED = 5 -- CLOSED hoặc idle: 5 FPS tiết kiệm CPU local FPS_OPEN = 10 -- OPEN attack: 10 FPS vừa đủ local REACH_NO_INRANGE_SEC = 3 -- sau 3s không có cultist in-range → REACH lite -- _shHitCounter đã forward-declared trước sendStallAlert (line ~2380) local StrongHoldPath = nil pcall(function() local v2 = require(plr.PlayerScripts.Client) if v2 and v2.Utility and v2.Utility.ForAllTagged then v2.Utility.ForAllTagged("Stronghold", function(a) if a and a.Name == "Stronghold" then StrongHoldPath = a end end) end end) task.spawn(function() local iter, lastMode = 0, nil local cAxe, cAxeT = nil, 0 local lastFireT = 0 while not getgenv().stopall do if not isMyRun() then break end task.wait() iter = iter + 1 local ok, err = pcall(function() local hrp = plr.Character and plr.Character:FindFirstChild("HumanoidRootPart") if not hrp then return end local sh = getStronghold() if not sh or not sh:FindFirstChild("Functional") then if lastMode ~= "IDLE" then nlog("SH-v7", "IDLE: no stronghold tag → FPS=" .. FPS_CLOSED) setfpscap(FPS_CLOSED) -- idle = same as CLOSED, 5 FPS end lastMode = "IDLE" return end StrongHoldPath = sh local functional = sh.Functional local shPivot = sh:GetPivot() local tz = getWave1TZ(functional) local hidePos = tz and CFrame.new(tz.Position - HIDE_OFF) or (shPivot * CFrame.new(0, -20, 0)) local openTime = functional:GetAttribute("OpenTime") or 0 local timeRem = openTime - workspace:GetServerTimeNow() -- CLOSED: respect _foodBusy if timeRem > 0 then if lastMode ~= "CLOSED" then nlog("SH-v7", ("⬇️ CLOSED %ds"):format(math.floor(timeRem))) noclip(); setfpscap(FPS_CLOSED); lastMode = "CLOSED" end if not getgenv()._foodBusy then hrp.CFrame = hidePos end return end -- OPEN: combat if lastMode ~= "OPEN" then nlog("SH-v7", ("⬆️ OPEN day=%d"):format(workspace:GetAttribute("StoryDayCounter") or 0)) noclip(); setfpscap(FPS_OPEN); lastMode = "OPEN" lastFireT = 0 end -- Watchdog _foodBusy stuck >10s → force reset (chống leak) if getgenv()._foodBusy then local stuckT = getgenv()._foodBusyStartT or 0 if stuckT == 0 then getgenv()._foodBusyStartT = tick() elseif tick() - stuckT > 10 then nlog("SH-v7", "⚠️ _foodBusy stuck >10s → force reset") getgenv()._foodBusy = false getgenv()._foodBusyStartT = 0 end else getgenv()._foodBusyStartT = 0 end -- 🔒 Lock hidePos (CHỈ khi không busy, để AutoEat/Hunt TP nếu cần) local hidePosV = hidePos.Position if not getgenv()._foodBusy then local curPos = hrp.Position if (curPos - hidePosV).Magnitude > 5 and iter % 60 == 0 then nlog("SH-v7", ("🔒 back to hide %.0f studs"):format((curPos - hidePosV).Magnitude)) end hrp.CFrame = hidePos end -- Cache axe (mỗi 2s) if tick() - cAxeT > 2 then cAxe = (plr.Inventory and ( plr.Inventory:FindFirstChild("Strong Axe") or plr.Inventory:FindFirstChild("Good Axe") or plr.Inventory:FindFirstChild("Old Axe") )) cAxeT = tick() if cAxe then equipAxe() end end if not cAxe then return end -- ⚔️ ATTACK: BURST hits — KHÔNG yield khi _foodBusy (đánh liên tục) -- Hit mọi cultist 0 and (vh.Position - shPivot.Position).Magnitude < SH_RANGE then local d = (vh.Position - hidePosV).Magnitude if d < ATK_RANGE then atkCount = atkCount + 1 for _ = 1, BURST do _shHitCounter = _shHitCounter + 1 pcall(function() replicatedStorage.RemoteEvents.ToolDamageObject:InvokeServer( v, cAxe, _shHitCounter .. "_" .. plr.UserId, hrp.CFrame, false) end) end else oorList[#oorList+1] = v end end end end end -- Track time since last in-range cultist if atkCount > 0 then _G._shLastInRangeT = tick() end -- 🚀 REACH LITE: nếu KHÔNG có cultist in-range > 3s VÀ có OOR cultists -- → TP nhanh tới nearest OOR, BURST hits, TP về hidePos if atkCount == 0 and #oorList > 0 and not getgenv()._foodBusy then local lastInT = _G._shLastInRangeT or 0 if tick() - lastInT > REACH_NO_INRANGE_SEC then -- Pick nearest OOR cultist local nearest, nearestD = nil, math.huge for _, v in ipairs(oorList) do local vh = v:FindFirstChild("HumanoidRootPart") if vh then local d = (vh.Position - hidePosV).Magnitude if d < nearestD then nearest, nearestD = v, d end end end if nearest then getgenv()._foodBusy = true pcall(function() local vh = nearest:FindFirstChild("HumanoidRootPart") if vh then hrp.CFrame = CFrame.new(vh.Position - Vector3.new(0, 20, 0)) for _ = 1, BURST do _shHitCounter = _shHitCounter + 1 pcall(function() replicatedStorage.RemoteEvents.ToolDamageObject:InvokeServer( nearest, cAxe, _shHitCounter .. "_" .. plr.UserId, hrp.CFrame, false) end) end task.wait(0.05) hrp.CFrame = hidePos -- TP về hide ngay end end) getgenv()._foodBusy = false nlog("SH-v7", ("🚀 REACH OOR cultist (d=%.0f)"):format(nearestD)) end end end if iter % 120 == 0 then nlog("SH-v7", ("ATK in80=%d OOR=%d hits=%d"):format(atkCount, #oorList, _shHitCounter)) end -- Fire wave triggers mỗi 1s khi không có cultist if atkCount == 0 and #oorList == 0 and tick() - lastFireT >= 1 then lastFireT = tick() local fired = fireAllWaveTriggers(hrp, functional) if fired > 0 and iter % 180 == 0 then nlog("SH-v7", ("FIRE waves=%d"):format(fired)) end end end) if not ok then nlog("SH-v7", "ERR: " .. tostring(err)) end end nlog("SH-v7", "loop stopped") end) -- ════════════════════════════════════════════════════════════════════ -- ⚔️ GLOBAL ATTACK LOOP (0.1s, hostile only ≤80 studs) -- ════════════════════════════════════════════════════════════════════ local HOSTILE = {Cultist=1, Wolf=1, Bear=1, Spider=1, Witch=1, ["Alpha Wolf"]=1} task.spawn(function() local cAxe, cAxeT = nil, 0 local hitId = 0 while not getgenv().stopall do if not isMyRun() then break end task.wait(0.1) pcall(function() if getgenv()._foodBusy then return end local hrp = plr.Character and plr.Character:FindFirstChild("HumanoidRootPart") if not hrp then return end if tick() - cAxeT > 2 then cAxe = (plr.Inventory and ( plr.Inventory:FindFirstChild("Strong Axe") or plr.Inventory:FindFirstChild("Good Axe") or plr.Inventory:FindFirstChild("Old Axe") )) cAxeT = tick() end if not cAxe then return end local pos = hrp.Position local chars = workspace:FindFirstChild("Characters"); if not chars then return end for _, v in ipairs(chars:GetChildren()) do local hostile = false for kw, _ in pairs(HOSTILE) do if v.Name:find(kw) then hostile = true; break end end if hostile then local hum = v:FindFirstChildOfClass("Humanoid") if hum and hum.Health > 0 then local ok, cf = pcall(v.GetPivot, v) if ok and cf and (cf.Position - pos).Magnitude < 80 then hitId = hitId + 1 pcall(function() replicatedStorage.RemoteEvents.ToolDamageObject:InvokeServer( v, cAxe, hitId .. "_" .. plr.UserId, hrp.CFrame, false) end) end end end end end) end end) -- ════════════════════════════════════════════════════════════════════ -- 💊 LOOT HEALING ITEMS (one-time after 5s) -- ════════════════════════════════════════════════════════════════════ task.spawn(function() task.wait(5) pcall(function() local items = workspace:FindFirstChild("Items"); if not items then return end for _, v in ipairs(items:GetChildren()) do if table.find(getgenv().config.Healing or {}, v.Name) then pcall(function() if v:GetPivot().Position.Y < 30 then local hrp = plr.Character and plr.Character:FindFirstChild("HumanoidRootPart") if hrp then hrp.CFrame = v:GetPivot() + Vector3.new(0, -30, 0) task.wait(0.1) local rem = replicatedStorage.RemoteEvents:FindFirstChild("RequestHotbarItem") if rem then rem:InvokeServer(v) end end end end) end end end) nlog("Loot", "✅ healing items collected") end) -- ════════════════════════════════════════════════════════════════════ -- ⚡ FPS BOOST + NPC UNRENDER -- ════════════════════════════════════════════════════════════════════ if getgenv().ENABLE_FPS_BOOST then pcall(function() for _, v in ipairs(workspace:GetDescendants()) do pcall(function() if v:IsA("BasePart") and not v:IsA("MeshPart") then v.Material = Enum.Material.Plastic; v.Reflectance = 0 elseif v:IsA("Decal") or v:IsA("Texture") then v.Transparency = 1 elseif v:IsA("ParticleEmitter") or v:IsA("Trail") then v.Lifetime = NumberRange.new(0) elseif v:IsA("Fire") or v:IsA("SpotLight") or v:IsA("Smoke") or v:IsA("Sparkles") then v.Enabled = false end end) end if sethiddenproperty then pcall(function() sethiddenproperty(Services.Lighting, "Technology", 2) end) pcall(function() sethiddenproperty(workspace.Terrain, "Decoration", false) end) end Services.Lighting.GlobalShadows = false Services.Lighting.FogEnd = 9e9 for _, c in ipairs(Services.Lighting:GetChildren()) do if c:IsA("Atmosphere") or c:IsA("Sky") or c:IsA("Clouds") or c:IsA("BlurEffect") or c:IsA("SunRaysEffect") or c:IsA("BloomEffect") or c:IsA("DepthOfFieldEffect") or c:IsA("ColorCorrectionEffect") then pcall(function() c:Destroy() end) end end pcall(function() workspace.StreamingEnabled = false end) local SS = game:GetService("SoundService") SS.AmbientReverb = Enum.ReverbType.NoReverb; SS.RolloffScale = 0 pcall(function() settings().Rendering.QualityLevel = Enum.QualityLevel.Level01 end) end) local fpsConn fpsConn = workspace.DescendantAdded:Connect(function(v) if not isMyRun() then fpsConn:Disconnect(); return end pcall(function() if v:IsA("ParticleEmitter") or v:IsA("Trail") or v:IsA("Smoke") or v:IsA("Sparkles") then v.Enabled = false elseif v:IsA("Fire") then v.Heat = 0; v.Size = 0 elseif v:IsA("PointLight") or v:IsA("SpotLight") or v:IsA("SurfaceLight") then v.Enabled = false end end) end) nlog("FPSBoost", "✅ applied") end -- NPC unrender (event-driven, cached state) do local UNRENDER_DIST = 250 local npcState = {} local function regNPC(npc) if npcState[npc] or npc == plr.Character then return end local parts = {} for _, p in ipairs(npc:GetDescendants()) do if p:IsA("BasePart") then parts[#parts+1] = p end end npcState[npc] = {parts=parts, hidden=false} end local function setHide(npc, hide) local st = npcState[npc]; if not st or st.hidden == hide then return end for _, p in ipairs(st.parts) do pcall(function() p.LocalTransparencyModifier = hide and 1 or 0 end) end st.hidden = hide end if workspace:FindFirstChild("Characters") then for _, c in ipairs(workspace.Characters:GetChildren()) do regNPC(c) end local addConn, remConn addConn = workspace.Characters.ChildAdded:Connect(function(c) if not isMyRun() then addConn:Disconnect(); return end regNPC(c) end) remConn = workspace.Characters.ChildRemoved:Connect(function(c) if not isMyRun() then remConn:Disconnect(); return end npcState[c] = nil end) end task.spawn(function() while not getgenv().stopall do if not isMyRun() then break end task.wait(2) local hrp = plr.Character and plr.Character:FindFirstChild("HumanoidRootPart") if hrp then local pos = hrp.Position for npc, _ in pairs(npcState) do if npc.Parent then local ok, pivPos = pcall(function() return npc:GetPivot().Position end) if ok and pivPos then setHide(npc, (pivPos - pos).Magnitude > UNRENDER_DIST) end else npcState[npc] = nil end end end end end) end -- ════════════════════════════════════════════════════════════════════ -- 🏁 ENDGAME TRIGGER (WIN) + 💀 GAME LOST DETECTOR (LOSE) -- ════════════════════════════════════════════════════════════════════ local SH_TARGET_DAYS = (getgenv().MODE == "shorttime") and 100 or 1000 local SH_TARGET_DONE = (getgenv().MODE == "shorttime") and 3 or 30 local _endgameDone = false -- chống fire 2 lần (WIN và LOSE dùng chung) -- ★ "KILL ME" — copy nguyên từ sab_scanner: messagebox "Kill Me" → Kick → game:Shutdown(). -- THAY cho toàn bộ kick/hop/die + webhook ở endgame. Đóng hẳn client; launcher ngoài (nếu có) -- sẽ relaunch acc. Mỗi lệnh pcall riêng: messagebox chặn tới khi bấm OK, kick rời trước, -- shutdown là chốt cuối nếu kick không ăn. local function _killLeave() pcall(function() messagebox(plr.Name, "Kill Me", 0x00000010) task.wait(1) end) pcall(function() plr:Kick("\n[99n] leave") end) pcall(function() task.wait(1) game:Shutdown() end) end -- 🏆 WIN: đạt day target + SH target → _killLeave (CÓ webhook) task.spawn(function() while true do if not isMyRun() then break end task.wait(2) if not getgenv().stopall then continue end local days = workspace:GetAttribute("StoryDayCounter") or 0 if days >= SH_TARGET_DAYS and timeDoneStronghold >= SH_TARGET_DONE then if _endgameDone then break end _endgameDone = true nlog("Endgame", ("🏆 WIN! day=%d done=%d → kill me"):format(days, timeDoneStronghold)) local timeElapsed = math.floor(tick() - _startT) local diamonds = plr:GetAttribute("Diamonds") or 0 sendWebhook(plr.Name, timeElapsed, days, diamonds, timeDoneStronghold, "🏆 WIN") deleteNoclip() _killLeave() break end end end) -- 💀 LOSE: monitor PlayerGui.Interface.GameLostFrame.Visible → _killLeave (CÓ webhook) task.spawn(function() while true do if not isMyRun() then break end task.wait(3) pcall(function() local pg = plr:FindFirstChild("PlayerGui") local interface = pg and pg:FindFirstChild("Interface") local lostFrame = interface and interface:FindFirstChild("GameLostFrame") if lostFrame and lostFrame.Visible == true and not _endgameDone then _endgameDone = true local days = workspace:GetAttribute("StoryDayCounter") or 0 nlog("Endgame", ("💀 LOSE! day=%d done=%d → kill me"):format(days, timeDoneStronghold)) local timeElapsed = math.floor(tick() - _startT) local diamonds = plr:GetAttribute("Diamonds") or 0 sendWebhook(plr.Name, timeElapsed, days, diamonds, timeDoneStronghold, "💀 LOSE (Game Lost Frame)") _killLeave() end end) end end) -- 🔄 AUTO CHANGE FOLDER (Based on Diamond threshold) local doneChange = false local _warnedNoClient = false task.spawn(function() while true do if not isMyRun() then break end task.wait(5) if doneChange then continue end local diamonds = plr:GetAttribute("Diamonds") or 0 local targetDiamonds = getgenv().config.ChangeDiamonds or 1000 if diamonds >= targetDiamonds then if not getgenv().client or not getgenv().client.ChangeToFolder then if not _warnedNoClient then _warnedNoClient = true nlog("Change", "WARN: getgenv().client.ChangeToFolder not found — executor hub missing, change disabled") end continue end local from = getgenv().config.ChangeFrom local to = getgenv().config.ChangeTo if not from or not to or from == "" or to == "" then if not _warnedNoClient then _warnedNoClient = true nlog("Change", "WARN: ChangeFrom/ChangeTo not configured properly") end continue end nlog("Change", "Diamonds reached " .. diamonds .. "/" .. targetDiamonds .. " -> Changing folder " .. from .. " to " .. to) local ok, result = pcall(function() return getgenv().client:ChangeToFolder(from, to, false, nil) end) if ok and result then nlog("Change", "Change SUCCESS!") doneChange = true else nlog("Change", "Change FAILED: " .. tostring(result)) end end end end) nlog("Init", "✅ all post-axe systems running")