-- a long flight -- ui is FeatherLite: https://github.com/S2kh/FeatherLite if game.GameId ~= 10768785226 then return end local FeatherLite = loadstring(game:HttpGet("https://raw.githubusercontent.com/S2kh/FeatherLite/main/FeatherLite.lua"))() local Players = game:GetService("Players") local RS = game:GetService("ReplicatedStorage") local RunService = game:GetService("RunService") local UIS = game:GetService("UserInputService") local Lighting = game:GetService("Lighting") local CS = game:GetService("CollectionService") local LP = Players.LocalPlayer local G = getgenv() if G.FeatherLongFlight and G.FeatherLongFlight.stop then pcall(G.FeatherLongFlight.stop) end local alive = true local conns = {} G.FeatherLongFlight = {} local function req(m) if not m then return nil end local ok, r = pcall(require, m) return ok and r or nil end local function discordButton(group, notifyFn) group:Button({ Name = "Copy Discord invite", Description = "https://discord.gg/CVqV9YnzUd", Callback = function() if setclipboard then pcall(setclipboard, "https://discord.gg/CVqV9YnzUd") notifyFn("Discord invite copied.") end end }) end -- the lobby is its own place with none of the flight stuff, so just tell them to start a run if RS:FindFirstChild("LobbyRemotes") or RS:FindFirstChild("MenuRemotes") then local W = FeatherLite:Window({ Title = "A Long Flight", Folder = "FeatherLite/ALongFlight", Key = Enum.KeyCode.RightShift }) local function say(text) W:Notify({ Title = "A Long Flight", Text = text, Duration = 6 }) end local tab = W:Tab({ Name = "Home", Icon = "World" }) local start = tab:Group("Start a run") start:Paragraph({ Title = "You're in the lobby", Text = "Start or join a run, then execute the script again once you've loaded in. All the features unlock there." }) discordButton(tab:Group("Community"), say) say("You're in the lobby. Start a run, then execute the script again.") G.FeatherLongFlight.stop = function() pcall(W.Unload, W) end return end local IS = RS:WaitForChild("InteractionSystem", 20) if not IS then return end local Remotes = IS:WaitForChild("Remotes") local WorldFolder = RS:WaitForChild("World") local Weapons = RS:WaitForChild("Weapons") local Begin = Remotes:WaitForChild("Begin") local EndRemote = Remotes:WaitForChild("End") local UpdateRemote = Remotes:WaitForChild("Update") local UseItem = Remotes:WaitForChild("UseItem") local SprintState = Remotes:WaitForChild("SprintState") local GunFire = Weapons.Remotes:WaitForChild("GunFire") local GunReload = Weapons.Remotes:WaitForChild("GunReload") local RPGFire = Weapons.Remotes:WaitForChild("RPGFire") local Punch = Weapons.Remotes:WaitForChild("Punch") local WeaponAction = RS:WaitForChild("WeaponKit"):WaitForChild("Remotes"):WaitForChild("WeaponAction") local ItemConfig = req(WorldFolder:WaitForChild("ItemConfig")) local GunConfig = req(Weapons:WaitForChild("GunConfig")) local PunchConfig = req(Weapons:WaitForChild("PunchConfig")) or { Cooldown = 0.55, Range = 8 } local AircraftUtil = req(IS:WaitForChild("AircraftUtil")) local STUDS_PER_M = 3.57 local Window local F = setmetatable({}, { __index = function(_, k) local el = Window and Window.Flags[k] if el then return el:Get() end end }) local function on(sig, fn) local c = sig:Connect(fn) conns[#conns + 1] = c return c end local function notify(text) if Window then Window:Notify({ Title = "A Long Flight", Text = text, Duration = 4 }) end end local function hum() local c = LP.Character return c and c:FindFirstChildOfClass("Humanoid") end local function root() local c = LP.Character return c and c:FindFirstChild("HumanoidRootPart") end local function flat(v) return Vector3.new(v.X, 0, v.Z) end local function meters(studs) return math.floor(studs / STUDS_PER_M) end local function posOf(x) if x:IsA("BasePart") then return x.Position end if x:IsA("Model") then return x:GetPivot().Position end end local function picked(list, v) if type(list) ~= "table" then return false end for _, x in ipairs(list) do if x == v then return true end end return false end -- all the esp stuff goes in one folder so unload can just delete it local espRoot = Instance.new("Folder") espRoot.Name = "FeatherLongFlight" if not pcall(function() espRoot.Parent = (gethui and gethui()) or game:GetService("CoreGui") end) then espRoot.Parent = LP:WaitForChild("PlayerGui") end local function makeTag(adornee, color) local bb = Instance.new("BillboardGui") bb.AlwaysOnTop = true bb.Size = UDim2.fromOffset(180, 36) bb.StudsOffset = Vector3.new(0, 3, 0) bb.LightInfluence = 0 bb.Adornee = adornee local tl = Instance.new("TextLabel") tl.BackgroundTransparency = 1 tl.Size = UDim2.fromScale(1, 1) tl.Font = Enum.Font.GothamBold tl.TextSize = 13 tl.TextColor3 = color tl.TextStrokeTransparency = 0.4 tl.TextWrapped = true tl.Parent = bb bb.Parent = espRoot return { bb = bb, tl = tl } end local function dropTag(t) if t then pcall(t.bb.Destroy, t.bb) if t.hl then pcall(t.hl.Destroy, t.hl) end end end -- makes the tags match whatever list we hand it: new ones get made, missing ones get dropped local function syncTags(store, list, highlight) local seen = {} for _, e in ipairs(list) do seen[e.key] = true local t = store[e.key] if not t then t = makeTag(e.part, e.color) if e.offset then t.bb.StudsOffset = e.offset end store[e.key] = t end t.bb.Adornee = e.part t.tl.Text = e.text t.tl.TextColor3 = e.color if highlight and e.model then if not t.hl then t.hl = Instance.new("Highlight") t.hl.FillColor = e.color t.hl.FillTransparency = 0.6 t.hl.OutlineColor = Color3.fromRGB(255, 255, 255) t.hl.DepthMode = Enum.HighlightDepthMode.AlwaysOnTop t.hl.Parent = espRoot end t.hl.Adornee = e.model elseif t.hl then t.hl:Destroy() t.hl = nil end end for k, t in pairs(store) do if not seen[k] then dropTag(t) store[k] = nil end end end -- // planes -- my plane is the one you're sitting in, or the last one you sat in, or the starter plane local lastPlane local function myPlane() local h = hum() local seat = h and h.SeatPart if seat and AircraftUtil then local p = AircraftUtil.FromInstance(seat) if p then lastPlane = p return p, seat end end if lastPlane and lastPlane.Parent then return lastPlane, nil end for _, m in ipairs(workspace:GetChildren()) do if m:IsA("Model") and m.Name:sub(1, 5) == "Scene" and m:GetAttribute("PilotUserId") == LP.UserId then return m, nil end end return workspace:FindFirstChild("Scene"), nil end local function planeRoot(p) return p and (p:FindFirstChild("RootPart") or p.PrimaryPart) end -- other planes sitting around the map (airfields etc). they're all "Scene..." models with a RootPart local function otherPlanes() local mine = myPlane() local out = {} for _, m in ipairs(workspace:GetChildren()) do if m:IsA("Model") and m ~= mine and m.Name:sub(1, 5) == "Scene" and m:FindFirstChild("RootPart") then out[#out + 1] = m end end return out end local function planeName(m) local n = m.Name:gsub("^Scene", ""):gsub("_%u_%d+$", ""):gsub("_", " ") return n ~= "" and n or "Plane" end -- // enemies local function zombieList() local out = {} for _, z in ipairs(CS:GetTagged("Zombie")) do local h = z:FindFirstChildOfClass("Humanoid") if h and h.Health > 0 and z:IsDescendantOf(workspace) then out[#out + 1] = z end end return out end local function banditList() local out, seen = {}, {} local function add(m) if m:IsA("Model") and not seen[m] and m:IsDescendantOf(workspace) and planeRoot(m) then seen[m] = true out[#out + 1] = m end end for _, m in ipairs(CS:GetTagged("BanditAircraft")) do add(m) end local folder = workspace:FindFirstChild("Bandits") if folder then for _, m in ipairs(folder:GetChildren()) do add(m) end end return out end local function zombiePart(z, head) return (head and z:FindFirstChild("Head")) or z:FindFirstChild("UpperTorso") or z:FindFirstChild("HumanoidRootPart") end -- stuff we can shoot: zombies and bandit planes local function targets(includeBandits) local out = {} for _, z in ipairs(zombieList()) do local p = zombiePart(z, F.AimHead ~= false) if p then out[#out + 1] = { model = z, part = p, kind = "zombie" } end end if includeBandits then for _, b in ipairs(banditList()) do out[#out + 1] = { model = b, part = planeRoot(b), kind = "bandit" } end end return out end local rayParams = RaycastParams.new() rayParams.FilterType = Enum.RaycastFilterType.Exclude local function clearShot(from, to, targetModel) local skip = { LP.Character, targetModel } local items = workspace:FindFirstChild("Items") if items then skip[#skip + 1] = items end local plane = myPlane() if plane then skip[#skip + 1] = plane end rayParams.FilterDescendantsInstances = skip return workspace:Raycast(from, to - from, rayParams) == nil end -- the target closest to the crosshair, inside the fov circle local function aimTarget(origin, range) local cam = workspace.CurrentCamera local center = cam.ViewportSize / 2 local best, bestD for _, t in ipairs(targets(F.AimBandits)) do local pos = t.part.Position if (pos - origin).Magnitude <= range then local sp, onScreen = cam:WorldToViewportPoint(pos) if onScreen then local d = (Vector2.new(sp.X, sp.Y) - center).Magnitude if d <= (F.AimFov or 150) and (not bestD or d < bestD) and (not F.WallCheck or clearShot(origin, pos, t.model)) then best, bestD = t, d end end end end return best end local function nearestBandit(from, range) local best, bd for _, b in ipairs(banditList()) do local r = planeRoot(b) local d = (r.Position - from).Magnitude if d <= range and (not bd or d < bd) then best, bd = b, d end end return best end -- where to aim so the bullet actually meets a moving plane local function leadPoint(from, part, speed) local pos, vel = part.Position, part.AssemblyLinearVelocity local t = (pos - from).Magnitude / speed for _ = 1, 2 do t = ((pos + vel * t) - from).Magnitude / speed end return pos + vel * t end -- fov circle (display order 1 so it stays under the menu) local fovGui = Instance.new("ScreenGui") fovGui.Name = "FeatherLongFlightFov" fovGui.IgnoreGuiInset = true fovGui.DisplayOrder = 1 fovGui.ResetOnSpawn = false fovGui.Parent = espRoot.Parent local fov = Instance.new("Frame") fov.AnchorPoint = Vector2.new(0.5, 0.5) fov.Position = UDim2.fromScale(0.5, 0.5) fov.BackgroundTransparency = 1 fov.Visible = false fov.Parent = fovGui Instance.new("UICorner", fov).CornerRadius = UDim.new(1, 0) local fovStroke = Instance.new("UIStroke", fov) fovStroke.Color = Color3.fromRGB(255, 255, 255) fovStroke.Transparency = 0.5 fovStroke.Thickness = 1.5 on(RunService.RenderStepped, function() local show = F.SilentAim and F.ShowFov fov.Visible = show == true if show then local r = F.AimFov or 150 fov.Size = UDim2.fromOffset(r * 2, r * 2) end end) -- // remote hooks -- one namecall hook for all of it. handlers return new args (table.pack) or nil to let the call through local hooks = {} local function equippedGun() local c = LP.Character local t = c and c:FindFirstChildOfClass("Tool") if t and t:GetAttribute("GunId") then return t end end local function gunCfg(tool) return tool and GunConfig and GunConfig.Guns[tool:GetAttribute("GunId") or ""] end hooks[GunFire] = function(tool, origin, dir) if not F.SilentAim or typeof(origin) ~= "Vector3" then return end local cfg = gunCfg(tool) local t = aimTarget(origin, cfg and cfg.Range or 500) if not t then return end local aim = t.kind == "bandit" and leadPoint(origin, t.part, (cfg and cfg.TracerSpeed) or 1100) or t.part.Position return table.pack(tool, origin, (aim - origin).Unit) end -- mounted plane guns send an aim point, we swap it for the closest bandit (with lead) hooks[WeaponAction] = function(action, point, ...) if action ~= "AimPoint" or not F.MountAim then return end local plane = myPlane() local r = planeRoot(plane) if not r then return end local b = nearestBandit(r.Position, F.MountRange or 900) if not b then return end return table.pack(action, leadPoint(r.Position, planeRoot(b), 1250), ...) end -- rpg: if you fire without a lock, hand it the closest bandit so the rocket homes in hooks[RPGFire] = function(lockTarget, look, point) if not F.RPGLock or lockTarget ~= nil then return end local c = LP.Character local from = c and c:GetPivot().Position or workspace.CurrentCamera.CFrame.Position local b = nearestBandit(from, 1500) if not b then return end return table.pack(b, typeof(look) == "Vector3" and look or (planeRoot(b).Position - from).Unit) end -- the server only drains energy while it thinks you're sprinting hooks[SprintState] = function(state) if F.InfStamina and state == true then return table.pack(false) end end local oldNamecall if hookmetamethod and getnamecallmethod and checkcaller then oldNamecall = hookmetamethod(game, "__namecall", newcclosure(function(self, ...) local h = hooks[self] if h and alive and not checkcaller() and getnamecallmethod() == "FireServer" then local ok, a = pcall(h, ...) if ok and a then return oldNamecall(self, table.unpack(a, 1, a.n)) end end return oldNamecall(self, ...) end)) end -- // guns -- gun stats live in one shared config table, the gun script reads them every shot local gunOrig = {} local function applyGunMods() if not GunConfig or not GunConfig.Guns then return end for id, g in pairs(GunConfig.Guns) do local o = gunOrig[id] if not o then o = { SpreadHip = g.SpreadHip, SpreadAim = g.SpreadAim, SpreadMove = g.SpreadMove, FireInterval = g.FireInterval, Automatic = g.Automatic, InfiniteAmmo = g.InfiniteAmmo, ReloadTime = g.ReloadTime, ReloadEmptyTime = g.ReloadEmptyTime, Recoil = type(g.Recoil) == "table" and table.clone(g.Recoil) or nil, } gunOrig[id] = o end local nospread = F.NoSpread == true g.SpreadHip = nospread and 0 or o.SpreadHip g.SpreadAim = nospread and 0 or o.SpreadAim g.SpreadMove = nospread and 0 or o.SpreadMove if o.Recoil and type(g.Recoil) == "table" then for k, v in pairs(o.Recoil) do if type(v) == "number" then g.Recoil[k] = F.NoRecoil and 0 or v end end end if o.FireInterval then g.FireInterval = F.RapidFire and o.FireInterval / (F.FireRateMult or 2) or o.FireInterval end g.Automatic = (F.FullAuto and true) or o.Automatic g.InfiniteAmmo = (F.InfAmmo and true) or o.InfiniteAmmo if o.ReloadTime then g.ReloadTime = F.FastReload and o.ReloadTime * 0.25 or o.ReloadTime end if o.ReloadEmptyTime then g.ReloadEmptyTime = F.FastReload and o.ReloadEmptyTime * 0.25 or o.ReloadEmptyTime end end end local function restoreGuns() if not GunConfig or not GunConfig.Guns then return end for id, o in pairs(gunOrig) do local g = GunConfig.Guns[id] if g then for k, v in pairs(o) do if k == "Recoil" then for rk, rv in pairs(v) do g.Recoil[rk] = rv end else g[k] = v end end end end end -- kill aura: shoots the closest zombie in range with the gun in your hands local auraLast, reloadUntil = 0, 0 local function auraTick() if not F.KillAura then return end local tool = equippedGun() local cfg = gunCfg(tool) local c = LP.Character local head = c and c:FindFirstChild("Head") if not tool or not cfg or not head then return end local now = os.clock() if now < reloadUntil or now - auraLast < math.max(cfg.FireInterval or 0.2, 0.05) then return end local ammo = tool:GetAttribute("Ammo") or 0 if ammo <= 0 then if (tool:GetAttribute("Reserve") or 0) > 0 then GunReload:FireServer(tool) reloadUntil = now + (cfg.ReloadEmptyTime or 2) + 0.1 end return end local origin = workspace.CurrentCamera.CFrame.Position if (origin - head.Position).Magnitude > 4 then origin = head.Position end local best, bd for _, t in ipairs(targets(F.AimBandits)) do local d = (t.part.Position - origin).Magnitude if d <= math.min(F.AuraRange or 80, cfg.Range or 500) and (not bd or d < bd) and clearShot(origin, t.part.Position, t.model) then best, bd = t, d end end if not best then return end auraLast = now local aim = best.kind == "bandit" and leadPoint(origin, best.part, cfg.TracerSpeed or 1100) or best.part.Position GunFire:FireServer(tool, origin, (aim - origin).Unit) end -- punch aura: no gun out, zombie in arm's reach, punch it local punchLast = 0 local function punchTick() if not F.PunchAura then return end local c = LP.Character local h, r = hum(), root() if not c or not h or not r or h.SeatPart or c:FindFirstChildOfClass("Tool") then return end if os.clock() - punchLast < (PunchConfig.Cooldown or 0.55) + 0.05 then return end local reach = (PunchConfig.Range or 8) - 1.5 for _, z in ipairs(zombieList()) do local p = zombiePart(z, false) if p and (p.Position - r.Position).Magnitude <= reach then punchLast = os.clock() Punch:FireServer((p.Position - workspace.CurrentCamera.CFrame.Position).Unit) return end end end on(RunService.Heartbeat, function() pcall(auraTick) pcall(punchTick) end) -- // items local CATS = { "Fuel", "Food & water", "Medical", "Weapons & ammo", "Tools", "Other" } local CAT_COLOR = { ["Fuel"] = Color3.fromRGB(255, 196, 70), ["Food & water"] = Color3.fromRGB(120, 220, 110), ["Medical"] = Color3.fromRGB(255, 120, 160), ["Weapons & ammo"] = Color3.fromRGB(255, 110, 90), ["Tools"] = Color3.fromRGB(110, 180, 255), ["Other"] = Color3.fromRGB(220, 220, 220), } local items = {} local function addItem(m) if m:IsA("Model") or m:IsA("BasePart") then items[m] = true end end for _, tag in ipairs({ "WorldItem", "Canister" }) do for _, m in ipairs(CS:GetTagged(tag)) do addItem(m) end on(CS:GetInstanceAddedSignal(tag), addItem) end local function itemInfo(m) local id = m:GetAttribute("ItemId") return id and ItemConfig and ItemConfig.Items[id] or {} end local function itemUse(m) return itemInfo(m).Use or m:GetAttribute("UseType") end local function itemCat(m) if m:HasTag("Canister") then return "Fuel" end local use = itemUse(m) if m:GetAttribute("WeaponTool") or m:GetAttribute("InteractionType") == "WeaponPickup" or use == "Ammo" then return "Weapons & ammo" end if use == "Eat" or use == "Drink" or use == "DrinkContainer" then return "Food & water" end if use == "Heal" then return "Medical" end if use == "Light" or use == "Tool" or m:HasTag("SiphonPump") or m:HasTag("Tool") then return "Tools" end return "Other" end local function itemName(m) return itemInfo(m).Name or m:GetAttribute("InteractionName") or m.Name end local function itemPart(m) if m:IsA("BasePart") then return m end return m.PrimaryPart or m:FindFirstChildWhichIsA("BasePart", true) end local function looseItem(m) return m.Parent ~= nil and m:IsDescendantOf(workspace) and m:GetAttribute("HeldBy") == nil and not m:GetAttribute("Docked") end local function liquidLabel(m) local parts = {} for k, v in pairs(m:GetAttributes()) do if k:sub(1, 7) == "Liquid_" and type(v) == "number" and v > 0.05 then parts[#parts + 1] = string.format("%.1fL %s", v, k:sub(8)) end end return #parts > 0 and table.concat(parts, ", ") or "empty" end local itemTags = {} local function updateItemEsp() local list = {} local r = root() local cats = F.ItemCats if F.ItemESP and r and type(cats) == "table" and #cats > 0 then local range = F.EspRange or 800 local found = {} for m in pairs(items) do if not m.Parent then items[m] = nil elseif looseItem(m) then local cat = itemCat(m) if picked(cats, cat) then local p = posOf(m) local d = p and (p - r.Position).Magnitude if d and d <= range then found[#found + 1] = { m = m, cat = cat, d = d } end end end end table.sort(found, function(a, b) return a.d < b.d end) for i = 1, math.min(#found, 80) do local it = found[i] local part = itemPart(it.m) if part then local name = itemName(it.m) if it.cat == "Fuel" then name = name .. " (" .. liquidLabel(it.m) .. ")" end list[#list + 1] = { key = it.m, part = part, color = CAT_COLOR[it.cat], offset = Vector3.new(0, 1.5, 0), text = string.format("%s\n%dm", name, meters(it.d)), } end end end syncTags(itemTags, list, false) end -- grab an item the same way pressing F does. returns true if the server let us local function grab(m) local p = itemPart(m) if not p then return false end local ok, granted = pcall(Begin.InvokeServer, Begin, m, p.Position) return ok and not not granted end local function release(m) pcall(EndRemote.FireServer, EndRemote, m) end local function moveItem(m, cf) local p = itemPart(m) if not p then return end if m:IsA("Model") then m:PivotTo(cf * p.CFrame:ToObjectSpace(m:GetPivot())) else p.CFrame = cf end p.AssemblyLinearVelocity = Vector3.zero p.AssemblyAngularVelocity = Vector3.zero end -- bring: tp to the item, pick it up, tp back and put it down. on foot only local bringing = false local taken = setmetatable({}, { __mode = "k" }) -- already brought it or got refused, don't go back for it local function cargoSpot(i) local plane = myPlane() local floor = plane and plane:FindFirstChild("ALF_CargoFloor", true) if not floor or not floor:IsA("BasePart") then return nil end local col, row = (i - 1) % 3, math.floor((i - 1) / 3) % 3 return floor.CFrame * CFrame.new((col - 1) * 1.2, floor.Size.Y / 2 + 1, (row - 1) * 1.2), floor end local function bringItems() if bringing then return end local r, h = root(), hum() if not r or not h then return end if h.SeatPart then notify("Get out of the plane first.") return end local cats = F.BringCats if type(cats) ~= "table" or #cats == 0 then notify("Pick what to bring first.") return end local toCargo = F.BringTo == "Plane cargo" if toCargo and not cargoSpot(1) then notify("Couldn't find your plane's cargo floor.") return end bringing = true local start = r.CFrame local list = {} for m in pairs(items) do if m.Parent and not taken[m] and looseItem(m) and picked(cats, itemCat(m)) then local p = itemPart(m) local d = p and (p.Position - start.Position).Magnitude local plane = myPlane() local inPlane = plane and m:IsDescendantOf(plane) if d and d > 6 and d <= (F.BringRange or 200) and not inPlane then list[#list + 1] = { m = m, d = d } end end end table.sort(list, function(a, b) return a.d < b.d end) local got = 0 for i = 1, math.min(#list, F.BringMax or 6) do local m = list[i].m if not alive or not r.Parent then break end local p = itemPart(m) if p and looseItem(m) then taken[m] = true r.CFrame = CFrame.new(p.Position + Vector3.new(0, 3, 0)) task.wait(0.2) if grab(m) then task.wait(0.1) local dest, stand if toCargo then local spot, floor = cargoSpot(got + 1) dest = spot stand = CFrame.new(floor.Position + floor.CFrame.ZVector * 4 + Vector3.new(0, 3, 0)) else stand = start dest = start * CFrame.new((got % 3 - 1) * 1.5, -1, -4) end for _ = 1, 6 do r.CFrame = stand moveItem(m, dest) RunService.Heartbeat:Wait() end release(m) got += 1 end task.wait(0.1) end end if r.Parent then r.CFrame = start end bringing = false notify(got > 0 and ("Brought " .. got .. " item(s).") or "Nothing came back. Try a smaller range.") end -- auto eat / drink / heal: picks up the closest one and uses it, same as pressing R while holding it local using = false local function usable(m, kind) local use = itemInfo(m).Use if kind == "drink" and use == "DrinkContainer" then -- canisters count as drink containers too, don't drink the kerosene return not m:HasTag("Canister") and (m:GetAttribute("Liquid_Water") or 0) > 0.05 end return use == ({ eat = "Eat", drink = "Drink", heal = "Heal" })[kind] end local function useNearest(kind) local r, h = root(), hum() if not r or not h then return false end local reach = h.SeatPart and 12 or (F.UseRange or 60) local best, bd for m in pairs(items) do if m.Parent and looseItem(m) and not taken[m] and usable(m, kind) then local p = itemPart(m) local d = p and (p.Position - r.Position).Magnitude if d and d <= reach and (not bd or d < bd) then best, bd = m, d end end end if not best then return false end local start = r.CFrame local hop = bd > 10 and not h.SeatPart if hop then r.CFrame = CFrame.new(itemPart(best).Position + Vector3.new(0, 3, 0)) task.wait(0.2) end local ok = grab(best) if ok then task.wait(0.1) pcall(UseItem.InvokeServer, UseItem, best, {}) task.wait(0.1) if best.Parent and best:GetAttribute("HeldBy") == LP.UserId then if hop and r.Parent then for _ = 1, 4 do r.CFrame = start moveItem(best, start * CFrame.new(0, -1, -3)) RunService.Heartbeat:Wait() end end release(best) end else taken[best] = true end if hop and r.Parent then r.CFrame = start end return ok end local lastUse = 0 local function survivalTick() if using or os.clock() - lastUse < 3 then return end local h = hum() if not h or h.Health <= 0 then return end local todo if F.AutoHeal and h.Health / math.max(h.MaxHealth, 1) * 100 < (F.HealAt or 50) then todo = "heal" elseif F.AutoEat and (LP:GetAttribute("Hunger") or 100) < (F.EatAt or 40) then todo = "eat" elseif F.AutoDrink and (LP:GetAttribute("Thirst") or 100) < (F.DrinkAt or 40) then todo = "drink" end if not todo then return end using, lastUse = true, os.clock() pcall(useNearest, todo) using = false end task.spawn(function() while alive do pcall(survivalTick) task.wait(1) end end) -- // esp local zombieTags, banditTags, placeTags, planeTags, playerTags = {}, {}, {}, {}, {} local function updateEsp() local r = root() local cam = workspace.CurrentCamera local from = r and r.Position or cam.CFrame.Position local range = F.EspRange or 800 local zl = {} if F.ZombieESP then for _, z in ipairs(zombieList()) do local p = zombiePart(z, true) local h = z:FindFirstChildOfClass("Humanoid") local d = p and (p.Position - from).Magnitude if d and d <= range then zl[#zl + 1] = { key = z, part = p, model = z, color = Color3.fromRGB(255, 95, 95), text = string.format("Zombie %d/%d\n%dm", math.floor(h.Health), math.floor(h.MaxHealth), meters(d)) } end end table.sort(zl, function(a, b) return (a.part.Position - from).Magnitude < (b.part.Position - from).Magnitude end) for i = #zl, 41, -1 do zl[i] = nil end end syncTags(zombieTags, zl, F.ZombieHighlight) local bl = {} if F.BanditESP then for _, b in ipairs(banditList()) do local p = planeRoot(b) bl[#bl + 1] = { key = b, part = p, model = b, color = Color3.fromRGB(200, 110, 255), offset = Vector3.new(0, 8, 0), text = string.format("Bandit plane\n%dm", meters((p.Position - from).Magnitude)) } end end syncTags(banditTags, bl, F.BanditESP) local pl = {} if F.PlaneESP then for _, m in ipairs(otherPlanes()) do local p = planeRoot(m) local fuel = m:GetAttribute("FuelLiters") pl[#pl + 1] = { key = m, part = p, color = Color3.fromRGB(120, 220, 255), offset = Vector3.new(0, 7, 0), text = string.format("%s%s\n%dm", planeName(m), fuel and string.format(" (%dL fuel)", math.floor(fuel)) or "", meters((p.Position - from).Magnitude)) } end end syncTags(planeTags, pl, false) local ll = {} local locs = workspace:FindFirstChild("World") and workspace.World:FindFirstChild("Locations") if F.PlaceESP and locs then for _, l in ipairs(locs:GetChildren()) do local part = l:IsA("Model") and (l.PrimaryPart or l:FindFirstChildWhichIsA("BasePart", true)) or (l:IsA("BasePart") and l) if part then ll[#ll + 1] = { key = l, part = part, color = Color3.fromRGB(255, 230, 140), offset = Vector3.new(0, 20, 0), text = string.format("%s\n%dm", l:GetAttribute("POIName") or l.Name, meters((l:GetPivot().Position - from).Magnitude)) } end end end syncTags(placeTags, ll, false) local pp = {} if F.PlayerESP then for _, p in ipairs(Players:GetPlayers()) do local hrp = p ~= LP and p.Character and p.Character:FindFirstChild("HumanoidRootPart") if hrp then pp[#pp + 1] = { key = p, part = hrp, color = Color3.fromRGB(110, 190, 255), text = string.format("%s\n%dm", p.DisplayName, meters((hrp.Position - from).Magnitude)) } end end end syncTags(playerTags, pp, false) end task.spawn(function() while alive do pcall(updateEsp) pcall(updateItemEsp) task.wait(0.3) end end) -- // player and world -- the game resets WalkSpeed every frame, so speed boost just nudges you along your move direction local flying = false on(RunService.Heartbeat, function(dt) local r, h = root(), hum() if F.SpeedBoost and r and h and not h.SeatPart and not flying and h.MoveDirection.Magnitude > 0 then r.CFrame += h.MoveDirection * (F.SpeedAmount or 10) * dt end if F.InfStamina then if LP:GetAttribute("Energy") ~= 100 then LP:SetAttribute("Energy", 100) end LP:SetAttribute("Exhausted", nil) end end) on(UIS.JumpRequest, function() local h = hum() if F.InfJump and h and not h.SeatPart then h:ChangeState(Enum.HumanoidStateType.Jumping) end end) -- fly. wasd + space/ctrl on pc, thumbstick on mobile (look up/down to climb) local flyVel, flyGyro local function stopFly() flying = false if flyVel then flyVel:Destroy() flyVel = nil end if flyGyro then flyGyro:Destroy() flyGyro = nil end end on(RunService.RenderStepped, function() local r, h = root(), hum() if not F.Fly or not r or not h or h.SeatPart then if flying then stopFly() end return end flying = true if not flyVel or flyVel.Parent ~= r then if flyVel then flyVel:Destroy() end if flyGyro then flyGyro:Destroy() end flyVel = Instance.new("BodyVelocity") flyVel.MaxForce = Vector3.new(1e6, 1e6, 1e6) flyVel.Parent = r flyGyro = Instance.new("BodyGyro") flyGyro.MaxTorque = Vector3.new(1e6, 1e6, 1e6) flyGyro.P = 9000 flyGyro.Parent = r end local look = workspace.CurrentCamera.CFrame.LookVector local move = h.MoveDirection local dir = move if move.Magnitude > 0 then local fwd = flat(look) local along = fwd.Magnitude > 0 and move:Dot(fwd.Unit) or 0 dir = move + Vector3.new(0, look.Y * along, 0) end if UIS:IsKeyDown(Enum.KeyCode.Space) then dir += Vector3.yAxis end if UIS:IsKeyDown(Enum.KeyCode.LeftControl) then dir -= Vector3.yAxis end flyVel.Velocity = dir.Magnitude > 0 and dir.Unit * (F.FlySpeed or 50) or Vector3.zero flyGyro.CFrame = CFrame.lookAt(r.Position, r.Position + flat(look) + Vector3.new(0, 0.001, 0)) end) local noclipped = {} on(RunService.Stepped, function() local c = LP.Character if F.Noclip and c then for _, p in ipairs(c:GetDescendants()) do if p:IsA("BasePart") and p.CanCollide then noclipped[p] = true p.CanCollide = false end end elseif next(noclipped) then for p in pairs(noclipped) do if p.Parent then p.CanCollide = true end end noclipped = {} end end) -- this runs after the game's environment script every frame so our lighting sticks local savedLight, savedFog local function lightTick() local atm = Lighting:FindFirstChildOfClass("Atmosphere") if F.Fullbright then savedLight = savedLight or { Ambient = Lighting.Ambient, OutdoorAmbient = Lighting.OutdoorAmbient, Brightness = Lighting.Brightness, GlobalShadows = Lighting.GlobalShadows, ClockTime = Lighting.ClockTime } Lighting.Ambient = Color3.fromRGB(170, 170, 170) Lighting.OutdoorAmbient = Color3.fromRGB(170, 170, 170) Lighting.Brightness = 2 Lighting.GlobalShadows = false elseif savedLight then for k, v in pairs(savedLight) do if k ~= "ClockTime" then pcall(function() Lighting[k] = v end) end end savedLight = nil end if F.NoFog then savedFog = savedFog or { FogEnd = Lighting.FogEnd, FogStart = Lighting.FogStart, Density = atm and atm.Density, Haze = atm and atm.Haze } Lighting.FogEnd = 1e6 Lighting.FogStart = 1e6 if atm then atm.Density = 0 atm.Haze = 0 end elseif savedFog then Lighting.FogEnd = savedFog.FogEnd Lighting.FogStart = savedFog.FogStart if atm and savedFog.Density then atm.Density = savedFog.Density atm.Haze = savedFog.Haze end savedFog = nil end end local LIGHT_BIND = "FeatherLongFlightLight" RunService:BindToRenderStep(LIGHT_BIND, Enum.RenderPriority.Last.Value + 5, function() if F.Fullbright or F.NoFog or savedLight or savedFog then pcall(lightTick) end end) -- weather: turns off rain, dust and tornado effects. visuals only, storms still hit the plane local hiddenFx = {} local function weatherTick() if F.NoWeather then local gui = LP.PlayerGui:FindFirstChild("WeatherFxScreen") if gui and gui.Enabled then hiddenFx[gui] = true gui.Enabled = false end for _, name in ipairs({ "WeatherFx", "ClientTornadoes" }) do local f = workspace:FindFirstChild(name) if f then for _, d in ipairs(f:GetDescendants()) do if (d:IsA("ParticleEmitter") or d:IsA("Beam") or d:IsA("Trail")) and d.Enabled then hiddenFx[d] = true d.Enabled = false end end end end elseif next(hiddenFx) then for d in pairs(hiddenFx) do pcall(function() d.Enabled = true end) end hiddenFx = {} end end task.spawn(function() while alive do pcall(weatherTick) task.wait(0.5) end end) on(LP.Idled, function() if F.AntiAfk then local VU = game:GetService("VirtualUser") VU:CaptureController() VU:ClickButton2(Vector2.new()) end end) -- // teleports local function placeList() local out = {} local locs = workspace:FindFirstChild("World") and workspace.World:FindFirstChild("Locations") local r = root() if locs then for _, l in ipairs(locs:GetChildren()) do local name = l:GetAttribute("POIName") or l.Name local d = r and (l:GetPivot().Position - r.Position).Magnitude or 0 out[#out + 1] = { name = string.format("%s (%dm)", name, meters(d)), inst = l, d = d } end end table.sort(out, function(a, b) return a.d < b.d end) return out end local function placeNames() local t = {} for _, p in ipairs(placeList()) do t[#t + 1] = p.name end if #t == 0 then t[1] = "Nothing nearby" end return t end local function onFoot() local r, h = root(), hum() if h and h.SeatPart then notify("Get out of the plane first.") return end return h and r end local function teleportToPlace(name) local r = onFoot() if not r then return end for _, p in ipairs(placeList()) do if p.name == name then r.CFrame = CFrame.new(p.inst:GetPivot().Position + Vector3.new(0, 8, 0)) return end end notify("That place isn't loaded anymore, refresh the list.") end local function teleportToPlane(m) local r = onFoot() local pr = planeRoot(m) if not r then return end if not pr then notify("Couldn't find the plane.") return end r.CFrame = CFrame.new(pr.Position + pr.CFrame.ZVector * 7 + Vector3.new(0, 3, 0)) end -- the plane has a "Grab & push" interaction. the server drags the grab point to wherever -- you hold it and can spin the plane too, which is all unflip needs local function grabPlane(plane, grip) local target = plane if plane:GetAttribute("InteractionType") ~= "Grab" then for _, d in ipairs(plane:GetDescendants()) do if d:GetAttribute("InteractionType") == "Grab" then target = d break end end end local ok, granted, info = pcall(Begin.InvokeServer, Begin, target, grip) if not ok or not granted then return end local rel = type(info) == "table" and typeof(info.gripRel) == "Vector3" and info.gripRel return target, rel or planeRoot(plane).CFrame:PointToObjectSpace(grip) end -- unflip: grab the plane and spin it back onto its wheels local function unflip() local r = onFoot() local plane = myPlane() local pr = planeRoot(plane) if not r or not pr then return end if pr.CFrame.YVector.Y > 0.55 then notify("Your plane isn't flipped.") return end local grip = pr.Position + Vector3.new(0, 1, 0) r.CFrame = CFrame.new(grip + flat(-pr.CFrame.ZVector).Unit * 5 + Vector3.new(0, 2, 0)) task.wait(0.2) local target, rel = grabPlane(plane, grip) if not target then notify("Couldn't grab the plane. Stand closer and try again.") return end local t0 = os.clock() while alive and os.clock() - t0 < 8 and pr.CFrame.YVector.Y < 0.9 do local up = pr.CFrame.YVector local axis = up:Cross(Vector3.yAxis) if axis.Magnitude < 0.05 then axis = -pr.CFrame.XVector end -- upside down, roll it over UpdateRemote:FireServer(target, { Hold = pr.CFrame:PointToWorldSpace(rel) + Vector3.new(0, 2, 0), Spin = axis.Unit * 1.2 }) task.wait(0.05) end release(target) end -- // menu Window = FeatherLite:Window({ Title = "A Long Flight", Folder = "FeatherLite/ALongFlight", Key = Enum.KeyCode.RightShift }) local gates = {} local function gate(test, els) gates[#gates + 1] = { test = test, els = els } end do local tab = Window:Tab({ Name = "Plane", Icon = "World" }) local plane = tab:Group("Plane") plane:Button({ Name = "Teleport to my plane", Callback = function() teleportToPlane((myPlane())) end }) plane:Button({ Name = "Unflip plane", Description = "Stand near your plane. Grabs it and spins it back onto its wheels.", Callback = function() task.spawn(unflip) end }) end do local tab = Window:Tab({ Name = "Combat", Icon = "Combat" }) local aim = tab:Group("Aim") aim:Toggle({ Name = "Silent aim", Flag = "SilentAim", Default = false, Description = "Your shots go to the zombie closest to your crosshair." }) gate("SilentAim", { aim:Toggle({ Name = "Aim at head", Flag = "AimHead", Default = true }), aim:Toggle({ Name = "Wall check", Flag = "WallCheck", Default = true }), aim:Toggle({ Name = "Show FOV circle", Flag = "ShowFov", Default = true }), aim:Slider({ Name = "FOV", Flag = "AimFov", Min = 40, Max = 500, Step = 10, Default = 150, Suffix = " px" }), }) aim:Toggle({ Name = "Target bandit planes", Flag = "AimBandits", Default = true, Description = "Silent aim and kill aura also go for bandit planes." }) local aura = tab:Group({ Name = "Kill aura", Description = "Hold a gun." }) aura:Toggle({ Name = "Kill aura", Flag = "KillAura", Default = false, Description = "Shoots the closest zombie in range and reloads for you." }) gate("KillAura", { aura:Slider({ Name = "Aura range", Flag = "AuraRange", Min = 10, Max = 300, Step = 5, Default = 80, Suffix = " studs" }), }) aura:Toggle({ Name = "Punch aura", Flag = "PunchAura", Default = false, Description = "Punches zombies that get close while your hands are empty." }) local guns = tab:Group("Guns") guns:Toggle({ Name = "No spread", Flag = "NoSpread", Default = false }) guns:Toggle({ Name = "No recoil", Flag = "NoRecoil", Default = false }) guns:Toggle({ Name = "Full auto", Flag = "FullAuto", Default = false, Description = "Hold to keep firing with any gun." }) guns:Toggle({ Name = "Infinite ammo", Flag = "InfAmmo", Default = false }) guns:Toggle({ Name = "Fast reload", Flag = "FastReload", Default = false }) guns:Toggle({ Name = "Rapid fire", Flag = "RapidFire", Default = false }) gate("RapidFire", { guns:Slider({ Name = "Fire rate", Flag = "FireRateMult", Min = 1.5, Max = 4, Step = 0.5, Default = 2, Suffix = "x" }), }) local planeGuns = tab:Group("Plane weapons") planeGuns:Toggle({ Name = "Plane gun aim", Flag = "MountAim", Default = false, Description = "Mounted guns and rockets aim at the closest bandit plane, leading the shot." }) gate("MountAim", { planeGuns:Slider({ Name = "Range", Flag = "MountRange", Min = 200, Max = 1000, Step = 50, Default = 900, Suffix = " studs" }), }) planeGuns:Toggle({ Name = "Instant RPG lock", Flag = "RPGLock", Default = false, Description = "Firing the RPG without a lock still homes in on the closest bandit plane." }) end do local tab = Window:Tab({ Name = "Visuals", Icon = "Visuals" }) local enemies = tab:Group("Enemies") enemies:Toggle({ Name = "Zombie ESP", Flag = "ZombieESP", Default = false }) gate("ZombieESP", { enemies:Toggle({ Name = "Highlight", Flag = "ZombieHighlight", Default = true }), }) enemies:Toggle({ Name = "Bandit ESP", Flag = "BanditESP", Default = false }) enemies:Toggle({ Name = "Player ESP", Flag = "PlayerESP", Default = false }) local world = tab:Group("World") world:Toggle({ Name = "Place ESP", Flag = "PlaceESP", Default = false, Description = "Airfields, gas stations, towns and camps." }) world:Toggle({ Name = "Plane ESP", Flag = "PlaneESP", Default = false, Description = "Other planes parked around the map, with their fuel." }) world:Slider({ Name = "ESP range", Flag = "EspRange", Min = 100, Max = 3000, Step = 50, Default = 800, Suffix = " studs" }) local look = tab:Group("Look") look:Toggle({ Name = "Fullbright", Flag = "Fullbright", Default = false, Description = "See clearly at night." }) look:Toggle({ Name = "No fog", Flag = "NoFog", Default = false }) look:Toggle({ Name = "No weather effects", Flag = "NoWeather", Default = false, Description = "Hides rain, dust and tornado effects." }) end do local tab = Window:Tab({ Name = "Items", Icon = "Search" }) local esp = tab:Group("Item ESP") esp:Toggle({ Name = "Item ESP", Flag = "ItemESP", Default = false }) gate("ItemESP", { esp:Dropdown({ Name = "Show", Flag = "ItemCats", Options = CATS, Multi = true, Default = { "Fuel", "Food & water", "Medical", "Weapons & ammo" } }), }) local bring = tab:Group({ Name = "Bring items", Description = "Works on foot, not in the plane." }) bring:Dropdown({ Name = "Bring", Flag = "BringCats", Options = CATS, Multi = true, Default = { "Fuel", "Food & water" } }) bring:Dropdown({ Name = "Drop at", Flag = "BringTo", Options = { "Next to me", "Plane cargo" }, Default = "Next to me" }) bring:Slider({ Name = "Range", Flag = "BringRange", Min = 20, Max = 500, Step = 10, Default = 200, Suffix = " studs" }) bring:Slider({ Name = "Items per press", Flag = "BringMax", Min = 1, Max = 15, Step = 1, Default = 6 }) bring:Button({ Name = "Bring items", Callback = function() task.spawn(bringItems) end }) local survive = tab:Group({ Name = "Survival", Description = "In the plane it only uses what's within reach." }) survive:Toggle({ Name = "Auto eat", Flag = "AutoEat", Default = false }) gate("AutoEat", { survive:Slider({ Name = "Eat below", Flag = "EatAt", Min = 10, Max = 90, Step = 5, Default = 40, Suffix = "%" }) }) survive:Toggle({ Name = "Auto drink", Flag = "AutoDrink", Default = false, Description = "Water and soda only, never fuel." }) gate("AutoDrink", { survive:Slider({ Name = "Drink below", Flag = "DrinkAt", Min = 10, Max = 90, Step = 5, Default = 40, Suffix = "%" }) }) survive:Toggle({ Name = "Auto heal", Flag = "AutoHeal", Default = false }) gate("AutoHeal", { survive:Slider({ Name = "Heal below", Flag = "HealAt", Min = 10, Max = 90, Step = 5, Default = 50, Suffix = "%" }) }) survive:Slider({ Name = "Search range on foot", Flag = "UseRange", Min = 10, Max = 150, Step = 5, Default = 60, Suffix = " studs" }) end do local tab = Window:Tab({ Name = "Player", Icon = "Player" }) local move = tab:Group("Movement") move:Toggle({ Name = "Infinite stamina", Flag = "InfStamina", Default = false }) move:Toggle({ Name = "Speed boost", Flag = "SpeedBoost", Default = false }) gate("SpeedBoost", { move:Slider({ Name = "Extra speed", Flag = "SpeedAmount", Min = 2, Max = 40, Step = 1, Default = 10 }), }) move:Toggle({ Name = "Infinite jump", Flag = "InfJump", Default = false }) move:Toggle({ Name = "Fly", Flag = "Fly", Default = false, Description = "WASD, space and ctrl on PC. On mobile use the thumbstick and look up or down to climb." }) gate("Fly", { move:Slider({ Name = "Fly speed", Flag = "FlySpeed", Min = 10, Max = 200, Step = 5, Default = 50 }), }) move:Toggle({ Name = "Noclip", Flag = "Noclip", Default = false }) end do local tab = Window:Tab({ Name = "Teleport", Icon = "Teleport" }) local places = tab:Group({ Name = "Places", Description = "Places loaded near you. On foot only." }) local list = places:Dropdown({ Name = "Place", Flag = "Place", Options = placeNames(), Default = placeNames()[1] }) places:Button({ Name = "Refresh list", Callback = function() local names = placeNames() list:SetOptions(names) list:Set(names[1]) end }) places:Button({ Name = "Teleport", Callback = function() teleportToPlace(F.Place) end }) local planes = tab:Group({ Name = "Planes", Description = "Other planes parked nearby." }) local function planeNames() local t = {} for _, m in ipairs(otherPlanes()) do t[#t + 1] = m.Name end if #t == 0 then t[1] = "None nearby" end return t end local pList = planes:Dropdown({ Name = "Plane", Flag = "OtherPlane", Options = planeNames(), Default = planeNames()[1] }) planes:Button({ Name = "Refresh list", Callback = function() local names = planeNames() pList:SetOptions(names) pList:Set(names[1]) end }) planes:Button({ Name = "Teleport", Callback = function() teleportToPlane(workspace:FindFirstChild(F.OtherPlane or "")) end }) end do local tab = Window:Tab({ Name = "Misc", Icon = "Misc" }) local misc = tab:Group("Misc") misc:Toggle({ Name = "Anti AFK", Flag = "AntiAfk", Default = true, Description = "Stops the 20 minute idle kick on long flights." }) local community = tab:Group("Community") community:Paragraph({ Title = "Feather Discord", Text = "Found a bug or want a new feature? Join the Discord." }) discordButton(community, notify) end task.spawn(function() while alive do for _, g in ipairs(gates) do local onNow = F[g.test] == true for _, el in ipairs(g.els) do if el and el.SetLocked and (el.Locked == true) == onNow then pcall(el.SetLocked, el, not onNow) end end end pcall(applyGunMods) task.wait(0.5) end end) if not oldNamecall then notify("Your executor can't hook remotes, so silent aim, plane gun aim and infinite stamina won't work.") end -- unload: turn everything off and undo the patches local function stop() if not alive then return end alive = false for _, c in ipairs(conns) do pcall(c.Disconnect, c) end pcall(RunService.UnbindFromRenderStep, RunService, LIGHT_BIND) hooks = {} if oldNamecall then pcall(hookmetamethod, game, "__namecall", oldNamecall) end restoreGuns() stopFly() for p in pairs(noclipped) do if p.Parent then p.CanCollide = true end end for d in pairs(hiddenFx) do pcall(function() d.Enabled = true end) end if savedLight then for k, v in pairs(savedLight) do if k ~= "ClockTime" then pcall(function() Lighting[k] = v end) end end end local atm = Lighting:FindFirstChildOfClass("Atmosphere") if savedFog then Lighting.FogEnd = savedFog.FogEnd Lighting.FogStart = savedFog.FogStart if atm and savedFog.Density then atm.Density = savedFog.Density atm.Haze = savedFog.Haze end end pcall(espRoot.Destroy, espRoot) pcall(fovGui.Destroy, fovGui) end G.FeatherLongFlight.stop = function() stop() pcall(Window.Unload, Window) end Window:OnUnload(stop)