-- shigaku autogym final update hopefully local Players = game:GetService("Players") local RunService = game:GetService("RunService") local GuiService = game:GetService("GuiService") local VIM = game:GetService("VirtualInputManager") local player = Players.LocalPlayer local playerGui = player:WaitForChild("PlayerGui") local enabled = true local AUTO_LIFT = true -- press the prompt when it says "Lift" local LIFT_COOLDOWN = 1.5 -- seconds between Lift presses local DARK_MAX = 0.35 -- weight text darker than this = trainable (black), lighter = locked (grey) local RETRY_DELAY = 0.35 -- Q/E mode: re-press if a box stays red this long local PRESS_DELAY = 0.09 -- dumbbell: time between Q taps local ZONE_MARGIN = 0.20 -- dumbbell: stop once the fill is this far (0-1) into the grey zone local keys = { Q = Enum.KeyCode.Q, E = Enum.KeyCode.E } local wasRed = { Q = false, E = false } local lastPress = { Q = 0, E = 0 } local boxes = { Q = nil, E = nil } local bar = { fill = nil, zone = nil } local lastZone = { left = nil, w = nil } local mode = nil -- "alt" (Q/E boxes) or "bar" (dumbbell) local liftStatus = "Lift: --" local function isRed(c) return c.R > 0.6 and c.G < 0.4 and c.B < 0.4 end local function isZoneColor(d) local c = d.BackgroundColor3 local mx = math.max(c.R, c.G, c.B) local mn = math.min(c.R, c.G, c.B) local t = d.BackgroundTransparency local eff = mx * (1 - t) + 0.06 * t return mx - mn < 0.08 and eff > 0.3 and eff < 0.95 end local function isLetter(d, letter) if not d:IsA("GuiObject") then return false end if (d:IsA("TextLabel") or d:IsA("TextButton")) then local t = d.Text:gsub("%s", ""):upper() if t == letter then return true end end return d.Name:upper() == letter end local function visibleChain(d) local o = d while o and o ~= playerGui do if o:IsA("GuiObject") and not o.Visible then return false end if o:IsA("ScreenGui") and not o.Enabled then return false end o = o.Parent end return o == playerGui end local function centerOf(d) return Vector2.new(d.AbsolutePosition.X + d.AbsoluteSize.X / 2, d.AbsolutePosition.Y + d.AbsoluteSize.Y / 2) end local function onScreen(d) if d.AbsoluteSize.X <= 0 or d.AbsoluteSize.Y <= 0 then return false end local cam = workspace.CurrentCamera if cam then local c, vp = centerOf(d), cam.ViewportSize if c.X < 0 or c.Y < 0 or c.X > vp.X or c.Y > vp.Y then return false end end local o = d while o and o ~= playerGui do if o:IsA("CanvasGroup") and o.GroupTransparency > 0.9 then return false end o = o.Parent end return true end ---------------------------------------------------------------------- -- dumbbell bar (red fill + grey zone) ---------------------------------------------------------------------- local function pickZone(anc, fill, q, qh, needVisible) local fy = fill.AbsolutePosition.Y + fill.AbsoluteSize.Y / 2 local best, bestDist for _, d in ipairs(anc:GetDescendants()) do if d:IsA("GuiObject") and d ~= fill and not d:IsAncestorOf(q) and d ~= q and d.BackgroundTransparency < 1 and isZoneColor(d) and d.AbsoluteSize.X > 0 and d.AbsoluteSize.Y <= qh and (not needVisible or visibleChain(d)) then local dist = math.abs(d.AbsolutePosition.Y + d.AbsoluteSize.Y / 2 - fy) if dist <= math.max(fill.AbsoluteSize.Y, 6) and (not bestDist or dist < bestDist) then best, bestDist = d, dist end end end return best end local function findBar(q) local qBox = q local p = q.Parent if p and p:IsA("GuiObject") and p.BackgroundTransparency < 1 and p.AbsoluteSize.X <= math.max(q.AbsoluteSize.X, 1) * 2.5 then qBox = p end local qh = qBox.AbsoluteSize.Y local cy = qBox.AbsolutePosition.Y + qh / 2 local anc = q.Parent for _ = 1, 6 do if not anc or anc == playerGui then break end local fill, fillDist for _, d in ipairs(anc:GetDescendants()) do if d:IsA("GuiObject") and d ~= q and not d:IsAncestorOf(q) and not q:IsAncestorOf(d) and visibleChain(d) and d.BackgroundTransparency < 1 and isRed(d.BackgroundColor3) and d.AbsoluteSize.Y > 0 and d.AbsoluteSize.Y < qh * 0.6 then local dist = math.abs(d.AbsolutePosition.Y + d.AbsoluteSize.Y / 2 - cy) if not fillDist or dist < fillDist then fill, fillDist = d, dist end end end if fill then local zone = pickZone(anc, fill, q, qh, true) or pickZone(anc, fill, q, qh, false) if zone then return fill, zone end end anc = anc.Parent end end local function locate() mode, boxes.Q, boxes.E, bar.fill, bar.zone = nil, nil, nil, nil, nil local firstQ for _, q in ipairs(playerGui:GetDescendants()) do if isLetter(q, "Q") and visibleChain(q) then firstQ = firstQ or q local anc = q.Parent for _ = 1, 6 do if not anc or anc == playerGui then break end for _, d in ipairs(anc:GetDescendants()) do if d ~= q and isLetter(d, "E") and visibleChain(d) then mode, boxes.Q, boxes.E = "alt", q, d return end end anc = anc.Parent end end end if firstQ then local fill, zone = findBar(firstQ) if fill and zone then mode, boxes.Q, bar.fill, bar.zone = "bar", firstQ, fill, zone lastZone.left, lastZone.w = zone.AbsolutePosition.X, zone.AbsoluteSize.X end end end local function colorRed(o) if o:IsA("GuiObject") and o.BackgroundTransparency < 1 and isRed(o.BackgroundColor3) then return true end if (o:IsA("ImageLabel") or o:IsA("ImageButton")) and isRed(o.ImageColor3) then return true end return false end local function boxIsRed(obj) if not obj or not obj.Parent then return false end if colorRed(obj) then return true end local p = obj.Parent for _ = 1, 2 do if p and p ~= playerGui and colorRed(p) then return true end p = p and p.Parent end for _, c in ipairs(obj:GetChildren()) do if colorRed(c) then return true end end return false end local function press(letter, obj) lastPress[letter] = tick() if obj and obj:IsA("GuiButton") and getconnections then for _, c in ipairs(getconnections(obj.MouseButton1Click)) do pcall(c.Fire, c) end for _, c in ipairs(getconnections(obj.Activated)) do pcall(c.Fire, c) end end VIM:SendKeyEvent(true, keys[letter], false, game) task.wait(0.05) VIM:SendKeyEvent(false, keys[letter], false, game) end ---------------------------------------------------------------------- -- auto Lift (proximity prompt) + auto weight pick ---------------------------------------------------------------------- local prompts = {} local function trackPrompt(d) if d:IsA("ProximityPrompt") then prompts[d] = true end end for _, d in ipairs(workspace:GetDescendants()) do trackPrompt(d) end workspace.DescendantAdded:Connect(trackPrompt) workspace.DescendantRemoving:Connect(function(d) prompts[d] = nil end) local function promptPos(p) local par = p.Parent if not par then return nil end if par:IsA("BasePart") then return par.Position end if par:IsA("Attachment") then return par.WorldPosition end if par:IsA("Model") then return par:GetPivot().Position end end local function squash(s) local r = s:gsub("%s", "") return r:lower() end local function nearestPrompt() local char = player.Character local hrp = char and char:FindFirstChild("HumanoidRootPart") if not hrp then return nil end local best, bestDist for p in pairs(prompts) do if p.Parent and p.Enabled then local isGym = p.Name:lower():find("gym") or squash(p.ActionText) == "lift" local pos = isGym and promptPos(p) if pos then local dist = (pos - hrp.Position).Magnitude if dist <= p.MaxActivationDistance + 2 and (not bestDist or dist < bestDist) then best, bestDist = p, dist end end end end return best end local function firePrompt(p) if fireproximityprompt then fireproximityprompt(p) else local key = p.KeyboardKeyCode VIM:SendKeyEvent(true, key, false, game) task.wait(p.HoldDuration + 0.1) VIM:SendKeyEvent(false, key, false, game) end end -- weight menu: several "NN LB" rows, black = trainable, grey = locked local function scanWeights() local count, distinct, best, bestNum = 0, {}, nil, -1 for _, d in ipairs(playerGui:GetDescendants()) do if d:IsA("TextLabel") or d:IsA("TextButton") then local n = d.Text:upper():match("^%s*(%d+)%s*LB%s*$") if n and visibleChain(d) and onScreen(d) then n = tonumber(n) count = count + 1 distinct[n] = true local c = d.TextColor3 local dark = math.max(c.R, c.G, c.B) < DARK_MAX and d.TextTransparency < 0.3 if dark and n > bestNum then best, bestNum = d, n end end end end local kinds = 0 for _ in pairs(distinct) do kinds = kinds + 1 end if kinds >= 2 and best then return best, bestNum end end local function findButtonAt(label) local c = centerOf(label) local best, bestArea local function consider(b) if b:IsA("GuiButton") then local p, s = b.AbsolutePosition, b.AbsoluteSize if c.X >= p.X and c.X <= p.X + s.X and c.Y >= p.Y and c.Y <= p.Y + s.Y then local area = s.X * s.Y if not bestArea or area < bestArea then best, bestArea = b, area end end end end local o = label for _ = 1, 4 do if not o or o == playerGui then break end consider(o) for _, d in ipairs(o:GetDescendants()) do consider(d) end o = o.Parent end return best end local function fireButton(b) local fired = false for _, sig in ipairs({ "Activated", "MouseButton1Click" }) do for _, conn in ipairs(getconnections(b[sig])) do pcall(conn.Fire, conn) fired = true end end return fired end local function tapAt(label) local c = centerOf(label) local sg = label:FindFirstAncestorWhichIsA("ScreenGui") local y = c.Y if not (sg and sg.IgnoreGuiInset) then y = y + GuiService:GetGuiInset().Y end VIM:SendMouseButtonEvent(c.X, y, 0, true, game, 0) task.wait(0.05) VIM:SendMouseButtonEvent(c.X, y, 0, false, game, 0) end ---------------------------------------------------------------------- -- toggle button + status ---------------------------------------------------------------------- local gui = Instance.new("ScreenGui") gui.Name = "AutoQE" gui.ResetOnSpawn = false gui.Parent = (gethui and gethui()) or game:GetService("CoreGui") local btn = Instance.new("TextButton") btn.Size = UDim2.new(0, 160, 0, 62) btn.Position = UDim2.new(0, 10, 0.5, 0) btn.BackgroundColor3 = Color3.fromRGB(40, 160, 70) btn.TextColor3 = Color3.new(1, 1, 1) btn.Font = Enum.Font.GothamBold btn.TextSize = 11 btn.Text = "Auto QE: ON" btn.Active = true btn.Draggable = true btn.Parent = gui Instance.new("UICorner", btn) btn.MouseButton1Click:Connect(function() enabled = not enabled btn.BackgroundColor3 = enabled and Color3.fromRGB(40, 160, 70) or Color3.fromRGB(170, 50, 50) end) ---------------------------------------------------------------------- -- main loop: Q/E + dumbbell bar ---------------------------------------------------------------------- local lastScan = 0 RunService.Heartbeat:Connect(function() if not enabled then btn.Text = "Auto QE: OFF" return end local stale if mode == "alt" then stale = not boxes.Q.Parent or not boxes.E.Parent or not visibleChain(boxes.Q) or not visibleChain(boxes.E) elseif mode == "bar" then stale = not boxes.Q.Parent or not bar.fill.Parent or not visibleChain(boxes.Q) or not visibleChain(bar.fill) or tick() - lastScan > 1 else stale = true end if stale and tick() - lastScan > 0.25 then lastScan = tick() locate() wasRed.Q, wasRed.E = false, false end if mode == "bar" then local zoneLeft, zoneW = lastZone.left, lastZone.w if bar.zone and bar.zone.Parent then zoneLeft, zoneW = bar.zone.AbsolutePosition.X, bar.zone.AbsoluteSize.X lastZone.left, lastZone.w = zoneLeft, zoneW end if not zoneLeft then return end local fillRight = bar.fill.AbsolutePosition.X + bar.fill.AbsoluteSize.X local target = zoneLeft + zoneW * ZONE_MARGIN if fillRight < target and tick() - lastPress.Q > PRESS_DELAY then task.spawn(press, "Q", boxes.Q) end local state = "pushing" if fillRight > zoneLeft + zoneW then state = "over" elseif fillRight >= zoneLeft then state = "in zone" end btn.Text = ("Auto QE: ON\nDumbbell: %s\n%s"):format(state, liftStatus) return end local status = {} for letter in pairs(keys) do local obj = boxes[letter] local red = boxIsRed(obj) status[letter] = obj and (red and "red" or "--") or "none" if red and (not wasRed[letter] or tick() - lastPress[letter] > RETRY_DELAY) then task.spawn(press, letter, obj) end wasRed[letter] = red end btn.Text = ("Auto QE: ON\nQ:%s E:%s\n%s"):format(status.Q, status.E, liftStatus) end) ---------------------------------------------------------------------- -- second loop: weight menu first, otherwise press Lift when it says Lift ---------------------------------------------------------------------- local weightAttempts, lastWeightTry, lastLift = 0, 0, 0 task.spawn(function() while true do task.wait(0.2) if not enabled then liftStatus = "Lift: OFF" else local label, num = scanWeights() if label then liftStatus = "Weight: " .. num .. " LB" if tick() - lastWeightTry > 0.8 then lastWeightTry = tick() weightAttempts = weightAttempts + 1 local fired = false if weightAttempts == 1 and getconnections then local b = findButtonAt(label) if b then fired = fireButton(b) end end if not fired then tapAt(label) end end else weightAttempts = 0 local p = AUTO_LIFT and mode == nil and nearestPrompt() if p then liftStatus = "Lift: " .. p.ActionText if squash(p.ActionText) == "lift" and tick() - lastLift > LIFT_COOLDOWN then lastLift = tick() task.spawn(firePrompt, p) end else liftStatus = "Lift: --" end end end end end)