-- Game: Project Vitruvius -- Time:2026/7/15 --Granting rights:QQ 1990569476 -- Load menu library local repo = "https://raw.githubusercontent.com/deividcomsono/Obsidian/main/" local Library = loadstring(game:HttpGet(repo .. "Library.lua"))() local ThemeManager = loadstring(game:HttpGet(repo .. "addons/ThemeManager.lua"))() local SaveManager = loadstring(game:HttpGet(repo .. "addons/SaveManager.lua"))() local Options = Library.Options local Toggles = Library.Toggles Library.ForceCheckbox = false Library.ShowToggleFrameInKeybinds = true local Window = Library:CreateWindow({ Title = "Project Vitruvius", Footer = "Project Vitruvius", NotifySide = "Right", ShowCustomCursor = true, }) local Tabs = { Combat = Window:AddTab("战斗", "crosshair"), Visuals = Window:AddTab("视觉效果", "eye"), ["UI Settings"] = Window:AddTab("界面设置", "settings"), } --// ========================================== --// Services and globals --// ========================================== local Players = game:GetService("Players") local RunService = game:GetService("RunService") local ReplicatedStorage = game:GetService("ReplicatedStorage") local LocalPlayer = Players.LocalPlayer local Workspace = game:GetService("Workspace") local UserInputService = game:GetService("UserInputService") local Camera = workspace.CurrentCamera -- Remote events local eventsFolder = ReplicatedStorage:FindFirstChild("Events") if not eventsFolder then warn("[Project Vitruvius] Events folder not found") return end local combatEvent = eventsFolder:FindFirstChild("CombatEvent") local hitEvent = eventsFolder:FindFirstChild("HitEvent") if not combatEvent or not hitEvent then warn("[Project Vitruvius] CombatEvent or HitEvent missing") return end -- Fallback server event for blocking local serverEvent = nil local function getServerEvent() if not serverEvent then local mark = ReplicatedStorage:FindFirstChild("Characters") if mark then mark = mark:FindFirstChild("Mark") end if mark then local evts = mark:FindFirstChild("Events") if evts then serverEvent = evts:FindFirstChild("ServerEvent") end end end return serverEvent end print("[Project Vitruvius] Events ready") --// Sound config local soundIds = { Fatality = "rbxassetid://94204395881101", Neverlose = "rbxassetid://8726881116", Gamesense = "rbxassetid://4817809188", Rust = "rbxassetid://1255040462", Ciallo = "rbxassetid://119294117978411", Osu = "rbxassetid://7147454322", Minecraft = "rbxassetid://1053296915", Bow = "rbxassetid://3442683707", } local selectedSoundId = soundIds.Fatality --// Particle color presets (keys match UI dropdown) local colorPresets = { ["红色"] = Color3.fromRGB(255, 50, 50), ["蓝色"] = Color3.fromRGB(50, 150, 255), ["绿色"] = Color3.fromRGB(50, 255, 50), ["黄色"] = Color3.fromRGB(255, 255, 50), ["紫色"] = Color3.fromRGB(200, 50, 255), ["青色"] = Color3.fromRGB(50, 255, 255), ["白色"] = Color3.fromRGB(255, 255, 255), ["橙色"] = Color3.fromRGB(255, 150, 50), } local selectedParticleColor = colorPresets["红色"] local particleShape = "圆形" -- UI dropdown value --// Feature toggles local KillAuraEnabled = false local KillAuraRange = 30 local KillAuraSpeed = 0.04 local KillAuraNotifyCooldown = 0.5 local HitSoundEnabled = false local AttackSilentAimEnabled = false local ParticleEnabled = false local PriorityMode = "距离优先" local MaxTargets = 1 local AutoBlockEnabled = false local BlockDistance = 30 local SilentAimEnabled = false local AntiBlockEnabled = false local AntiBlockCooldown = 0.5 local lastAntiBlockTime = 0 local lastAttackTime = 0 local lastNotifyTime = 0 -- Range attack / hitbox extension local HitboxConfig = { Enabled = false, Size = 15, Transparency = 0.5, Color = Color3.fromRGB(255, 0, 0) } -- Movement overrides local MovementConfig = { FlyEnabled = false, FlySpeed = 50, WalkSpeedEnabled = false, WalkSpeed = 16, JumpEnabled = false, JumpPower = 50 } -- UI toggle references for keybind label updates local killToggleRef = nil local blockToggleRef = nil local antiBlockToggleRef = nil --// ========================================== --// ESP2 settings (Chinese UI labels will be used, keys kept stable) --// ========================================== local ESP2_Settings = { Enabled = false, ShowBox = true, ShowName = true, ShowHealth = true, ShowChams = true, ShowStatus = true, TeamCheck = true, MaxDistance = 5000, BoxColor = Color3.fromRGB(255, 255, 255), BoxColorMode = "固定", NameColor = Color3.fromRGB(255, 255, 255), NameColorMode = "固定", HealthBarColor = Color3.fromRGB(0, 255, 0), HealthBarColorMode = "固定", StatusColor = Color3.fromRGB(255, 255, 100), StatusColorMode = "固定", } local ESP2 = { ScreenGui = nil, PlayerElements = {}, Connections = {}, RenderConnection = nil, FontSize = 11, } --// Enemy state detection local function getEnemyStatus(enemyChar) if not enemyChar then return "空闲" end local boostPhase = enemyChar:FindFirstChild("BoostPhase") if boostPhase and typeof(boostPhase.Value) == "number" then return "冲刺" .. boostPhase.Value .. "阶段" end local flying = enemyChar:FindFirstChild("Flying") if flying and flying.Value == true then return "飞行冲刺" end local blocking = enemyChar:FindFirstChild("Blocking") if blocking and blocking.Value == true then return "防御中" end local currentSkill = enemyChar:FindFirstChild("CurrentSkill") if currentSkill and typeof(currentSkill.Value) == "number" then return "技能" .. currentSkill.Value end local usingSkill = enemyChar:FindFirstChild("UsingSkill") if usingSkill and usingSkill.Value == true then local skillNum = enemyChar:FindFirstChild("SkillNumber") if skillNum then return "技能" .. skillNum.Value end return "技能释放" end local hum = enemyChar:FindFirstChildOfClass("Humanoid") if hum then local state = hum:GetState() local stateName = tostring(state):lower() if stateName:find("running") then return "奔跑中" elseif stateName:find("jumping") then return "跳跃中" elseif stateName:find("falling") then return "下落中" elseif stateName:find("swimming") then return "游泳中" elseif stateName:find("climbing") then return "攀爬中" elseif stateName:find("ragdoll") then return "布娃娃" elseif stateName:find("physics") then return "物理移动" end end return "待机" end --// ESP2 helpers local function ESP2_GetDynamicColor(mode, speed) speed = speed or 2.0 local t = tick() * speed if mode == "循环色相" then return Color3.fromHSV((t % 2) / 2, 1, 1) elseif mode == "瀑布" then local hue = (t % 2) / 2 local brightness = (math.sin(t * 2) + 1) / 2 return Color3.fromHSV(hue, 1, brightness) elseif mode == "波浪" then local r = (math.sin(t * 1.3) + 1) / 2 local g = (math.sin(t * 1.7 + 2) + 1) / 2 local b = (math.sin(t * 2.1 + 4) + 1) / 2 return Color3.new(r, g, b) end return Color3.fromHSV(0, 1, 1) end local function ESP2_GetCurrentColor(mode, fixedColor) if mode == "固定" then return fixedColor end return ESP2_GetDynamicColor(mode) end local function ESP2_FadeOutOnDist(element, distance, maxDist) local maxD = maxDist or ESP2_Settings.MaxDistance local transparency = math.max(0.1, 1 - (distance / maxD)) if element:IsA("TextLabel") then element.TextTransparency = 1 - transparency elseif element:IsA("UIStroke") then element.Transparency = 1 - transparency end end local function ESP2_Create(Class, Properties) local inst = (type(Class) == "string") and Instance.new(Class) or Class for prop, val in pairs(Properties) do inst[prop] = val end return inst end local function CreateESP2ScreenGui() if ESP2.ScreenGui then return end ESP2.ScreenGui = ESP2_Create("ScreenGui", { Parent = game:GetService("CoreGui"), Name = "ESP2Holder", Enabled = true, }) end local function DestroyESP2ForPlayer(plr) local elements = ESP2.PlayerElements[plr] if elements then for _, v in pairs(elements) do if v then pcall(function() v:Destroy() end) end end ESP2.PlayerElements[plr] = nil end end local function CreateESP2ForPlayer(plr) if ESP2.PlayerElements[plr] then return end local sg = ESP2.ScreenGui if not sg then return end local elements = {} elements.Name = ESP2_Create("TextLabel", { Parent = sg, Position = UDim2.new(0.5,0,0,-11), Size = UDim2.new(0,100,0,20), AnchorPoint = Vector2.new(0.5,0.5), BackgroundTransparency = 1, TextColor3 = Color3.fromRGB(255,255,255), Font = Enum.Font.Code, TextSize = ESP2.FontSize, TextStrokeTransparency = 0, TextStrokeColor3 = Color3.fromRGB(0,0,0), RichText = true, Visible = false, }) elements.Status = ESP2_Create("TextLabel", { Parent = sg, Position = UDim2.new(0.5,0,0,11), Size = UDim2.new(0,100,0,20), AnchorPoint = Vector2.new(0.5,0.5), BackgroundTransparency = 1, TextColor3 = Color3.fromRGB(255,255,100), Font = Enum.Font.Code, TextSize = ESP2.FontSize, TextStrokeTransparency = 0, TextStrokeColor3 = Color3.fromRGB(0,0,0), Visible = false, }) elements.Box = ESP2_Create("Frame", { Parent = sg, BackgroundColor3 = Color3.fromRGB(255,255,255), BackgroundTransparency = 1, BorderSizePixel = 0, Visible = false, }) elements.Outline = ESP2_Create("UIStroke", { Parent = elements.Box, Enabled = true, Transparency = 0, Color = Color3.fromRGB(255,255,255), LineJoinMode = Enum.LineJoinMode.Miter, Thickness = 1, }) elements.Healthbar = ESP2_Create("Frame", { Parent = sg, BackgroundColor3 = Color3.fromRGB(0,255,0), BackgroundTransparency = 0, Visible = false, }) elements.BehindHealthbar = ESP2_Create("Frame", { Parent = sg, ZIndex = -1, BackgroundColor3 = Color3.fromRGB(0,0,0), BackgroundTransparency = 0, Visible = false, }) elements.HealthText = ESP2_Create("TextLabel", { Parent = sg, Position = UDim2.new(0.5,0,0,31), Size = UDim2.new(0,100,0,20), AnchorPoint = Vector2.new(0.5,0.5), BackgroundTransparency = 1, TextColor3 = Color3.fromRGB(255,255,255), Font = Enum.Font.Code, TextSize = ESP2.FontSize, TextStrokeTransparency = 0, TextStrokeColor3 = Color3.fromRGB(0,0,0), Visible = false, }) elements.Chams = ESP2_Create("Highlight", { Parent = sg, FillTransparency = 1, OutlineTransparency = 0, OutlineColor = Color3.fromRGB(119,120,255), DepthMode = "AlwaysOnTop", Enabled = false, }) ESP2.PlayerElements[plr] = elements end local function UpdateESP2() local camera = workspace.CurrentCamera if not camera then return end local lp = game.Players.LocalPlayer local maxDist = ESP2_Settings.MaxDistance local boxColor = ESP2_GetCurrentColor(ESP2_Settings.BoxColorMode, ESP2_Settings.BoxColor) local nameColor = ESP2_GetCurrentColor(ESP2_Settings.NameColorMode, ESP2_Settings.NameColor) local healthColor = ESP2_GetCurrentColor(ESP2_Settings.HealthBarColorMode, ESP2_Settings.HealthBarColor) local statusColor = ESP2_GetCurrentColor(ESP2_Settings.StatusColorMode, ESP2_Settings.StatusColor) for plr, elements in pairs(ESP2.PlayerElements) do local shouldHide = true if plr and plr.Character then local char = plr.Character local hrp = char:FindFirstChild("HumanoidRootPart") local hum = char:FindFirstChild("Humanoid") if hrp and hum and hum.Health > 0 then local sameTeam = (ESP2_Settings.TeamCheck and lp.Team == plr.Team and lp.Team ~= nil) if not sameTeam then local pos, onScreen = camera:WorldToScreenPoint(hrp.Position) local dist = (camera.CFrame.Position - hrp.Position).Magnitude if onScreen and dist <= maxDist then shouldHide = false local size = hrp.Size.Y local scaleFactor = (size * camera.ViewportSize.Y) / (pos.Z * 2) local w = 3 * scaleFactor local h = 4.5 * scaleFactor if ESP2_Settings.ShowBox then elements.Box.Position = UDim2.new(0, pos.X - w/2, 0, pos.Y - h/2) elements.Box.Size = UDim2.new(0, w, 0, h) elements.Box.Visible = true elements.Box.BackgroundTransparency = 1 elements.Outline.Color = boxColor elements.Outline.Enabled = true ESP2_FadeOutOnDist(elements.Outline, dist, maxDist) else elements.Box.Visible = false elements.Outline.Enabled = false end if ESP2_Settings.ShowChams then elements.Chams.Adornee = char elements.Chams.Enabled = true elements.Chams.FillColor = Color3.fromRGB(119,120,255) elements.Chams.FillTransparency = 0.8 elements.Chams.OutlineColor = boxColor elements.Chams.OutlineTransparency = 0.5 elements.Chams.DepthMode = "AlwaysOnTop" else elements.Chams.Enabled = false end if ESP2_Settings.ShowName then elements.Name.Text = string.format("%s [%dm]", plr.Name, math.floor(dist)) elements.Name.Position = UDim2.new(0, pos.X, 0, pos.Y - h/2 - 9) elements.Name.TextColor3 = nameColor elements.Name.Visible = true ESP2_FadeOutOnDist(elements.Name, dist, maxDist) else elements.Name.Visible = false end if ESP2_Settings.ShowStatus then local footPos = hrp.Position - Vector3.new(0, 3, 0) local footScreen, _ = camera:WorldToScreenPoint(footPos) elements.Status.Text = "🔄 " .. getEnemyStatus(char) elements.Status.Position = UDim2.new(0, footScreen.X, 0, footScreen.Y) elements.Status.TextColor3 = statusColor elements.Status.Visible = true ESP2_FadeOutOnDist(elements.Status, dist, maxDist) else elements.Status.Visible = false end if ESP2_Settings.ShowHealth then local health = hum.Health / hum.MaxHealth health = math.clamp(health, 0, 1) elements.Healthbar.Position = UDim2.new(0, pos.X - w/2 - 6, 0, pos.Y - h/2 + h * (1 - health)) elements.Healthbar.Size = UDim2.new(0, 2.5, 0, h * health) elements.Healthbar.BackgroundColor3 = healthColor elements.Healthbar.Visible = true elements.BehindHealthbar.Position = UDim2.new(0, pos.X - w/2 - 6, 0, pos.Y - h/2) elements.BehindHealthbar.Size = UDim2.new(0, 2.5, 0, h) elements.BehindHealthbar.Visible = true local healthPercent = math.floor(hum.Health / hum.MaxHealth * 100) elements.HealthText.Position = UDim2.new(0, pos.X - w/2 - 6, 0, pos.Y - h/2 + h * (1 - healthPercent/100) + 3) elements.HealthText.Text = tostring(healthPercent) elements.HealthText.Visible = (hum.Health < hum.MaxHealth) ESP2_FadeOutOnDist(elements.Healthbar, dist, maxDist) ESP2_FadeOutOnDist(elements.BehindHealthbar, dist, maxDist) ESP2_FadeOutOnDist(elements.HealthText, dist, maxDist) else elements.Healthbar.Visible = false elements.BehindHealthbar.Visible = false elements.HealthText.Visible = false end end end end end if shouldHide then for _, v in pairs(elements) do if v and v:IsA("GuiObject") then v.Visible = false end end if elements.Chams then elements.Chams.Enabled = false end end end for plr, _ in pairs(ESP2.PlayerElements) do if not game.Players:FindFirstChild(plr.Name) then DestroyESP2ForPlayer(plr) end end end local function InitESP2Events() if ESP2.Connections.PlayerAdded then return end ESP2.Connections.PlayerAdded = game.Players.PlayerAdded:Connect(function(plr) if plr == game.Players.LocalPlayer then return end CreateESP2ForPlayer(plr) end) ESP2.Connections.PlayerRemoving = game.Players.PlayerRemoving:Connect(function(plr) DestroyESP2ForPlayer(plr) end) for _, plr in ipairs(game.Players:GetPlayers()) do if plr ~= game.Players.LocalPlayer then CreateESP2ForPlayer(plr) end end end local function SetESP2Enabled(enabled) ESP2_Settings.Enabled = enabled if enabled then CreateESP2ScreenGui() InitESP2Events() if not ESP2.RenderConnection then ESP2.RenderConnection = game:GetService("RunService").RenderStepped:Connect(function() if ESP2_Settings.Enabled then UpdateESP2() end end) end else if ESP2.RenderConnection then ESP2.RenderConnection:Disconnect() ESP2.RenderConnection = nil end for plr, elements in pairs(ESP2.PlayerElements) do for _, v in pairs(elements) do if v and v:IsA("GuiObject") then v.Visible = false end end if elements.Chams then elements.Chams.Enabled = false end end if ESP2.ScreenGui then ESP2.ScreenGui:Destroy() ESP2.ScreenGui = nil end end end --// ========================================== --// Particle effects (full original implementation) --// ========================================== local function createParticle(targetPos, color) local char = LocalPlayer.Character if not char then return end local hrp = char:FindFirstChild("HumanoidRootPart") if not hrp then return end local startPos = hrp.Position + Vector3.new(0, 1.5, 0) if particleShape == "圆形" then local part = Instance.new("Part") part.Size = Vector3.new(1, 1, 1) part.Shape = Enum.PartType.Ball part.BrickColor = BrickColor.new(color) part.Material = Enum.Material.Neon part.CanCollide = false part.Anchored = false part.CFrame = CFrame.new(startPos) part.Transparency = 0.2 part.Parent = Workspace local light = Instance.new("PointLight") light.Color = color light.Brightness = 2 light.Range = 5 light.Parent = part local attach = Instance.new("Attachment") attach.Parent = part local particle = Instance.new("ParticleEmitter") particle.Parent = attach particle.Texture = "rbxasset://textures/particles/sparkles_main.dds" particle.Lifetime = NumberRange.new(0.3, 0.6) particle.Rate = 100 particle.VelocityInheritance = 0 particle.SpreadAngle = Vector2.new(30, 30) particle.Speed = NumberRange.new(1, 3) particle.Color = ColorSequence.new(color) particle.Transparency = NumberSequence.new({NumberSequenceKeypoint.new(0,0.5), NumberSequenceKeypoint.new(1,1)}) particle.Size = NumberSequence.new({NumberSequenceKeypoint.new(0,0.5), NumberSequenceKeypoint.new(1,0)}) particle.Enabled = true local duration = 0.4 local startTime = tick() local startCF = part.CFrame local targetCF = CFrame.new(targetPos) local connection connection = RunService.Heartbeat:Connect(function() local elapsed = tick() - startTime local alpha = math.min(elapsed / duration, 1) local eased = alpha * alpha * (3 - 2 * alpha) part.CFrame = startCF:Lerp(targetCF, eased) part.Size = Vector3.new(1, 1, 1) * (1 + eased * 0.5) part.Transparency = 0.2 + eased * 0.3 if alpha >= 1 then connection:Disconnect() local burst = Instance.new("ParticleEmitter") burst.Parent = attach burst.Texture = "rbxasset://textures/particles/sparkles_main.dds" burst.Lifetime = NumberRange.new(0.2, 0.5) burst.Rate = 0 burst.SpreadAngle = Vector2.new(180, 180) burst.Speed = NumberRange.new(2, 6) burst.Color = ColorSequence.new(color) burst.Transparency = NumberSequence.new({NumberSequenceKeypoint.new(0,0), NumberSequenceKeypoint.new(1,1)}) burst.Size = NumberSequence.new({NumberSequenceKeypoint.new(0,0.5), NumberSequenceKeypoint.new(1,0)}) burst.Enabled = true pcall(function() burst:Emit(30) end) task.delay(0.1, function() burst:Destroy() end) task.delay(0.3, function() part:Destroy() end) end end) task.delay(2, function() if connection and connection.Connected then connection:Disconnect() end if part and part.Parent then part:Destroy() end end) elseif particleShape == "云形" then for i = 1, 12 do local offset = Vector3.new( (math.random() - 0.5) * 2, (math.random() - 0.5) * 2, (math.random() - 0.5) * 2 ) local part = Instance.new("Part") part.Size = Vector3.new(0.3, 0.3, 0.3) part.Shape = Enum.PartType.Ball part.BrickColor = BrickColor.new(color) part.Material = Enum.Material.Neon part.CanCollide = false part.Anchored = false part.CFrame = CFrame.new(startPos + offset) part.Transparency = 0.5 part.Parent = Workspace local light = Instance.new("PointLight") light.Color = color light.Brightness = 1 light.Range = 3 light.Parent = part local duration = 0.6 + math.random() * 0.3 local startTime = tick() local startCF = part.CFrame local targetCF = CFrame.new(targetPos + Vector3.new( (math.random()-0.5)*1.5, (math.random()-0.5)*1.5, (math.random()-0.5)*1.5 )) local connection connection = RunService.Heartbeat:Connect(function() local elapsed = tick() - startTime local alpha = math.min(elapsed / duration, 1) local eased = alpha * alpha * (3 - 2 * alpha) part.CFrame = startCF:Lerp(targetCF, eased) part.Transparency = 0.5 + eased * 0.5 if alpha >= 1 then connection:Disconnect() part:Destroy() end end) task.delay(2, function() if connection and connection.Connected then connection:Disconnect() end if part and part.Parent then part:Destroy() end end) end elseif particleShape == "激光" then local function createBeam(offset) local beamPart = Instance.new("Part") beamPart.Size = Vector3.new(0.1, 0.1, 0.1) beamPart.BrickColor = BrickColor.new(color) beamPart.Material = Enum.Material.Neon beamPart.CanCollide = false beamPart.Anchored = false beamPart.Transparency = 0.2 beamPart.Parent = Workspace local light = Instance.new("PointLight") light.Color = color light.Brightness = 3 light.Range = 4 light.Parent = beamPart local startPos2 = startPos + offset local endPos = targetPos + offset local duration = 0.25 local startTime = tick() local startCF = CFrame.new(startPos2, endPos) local connection connection = RunService.Heartbeat:Connect(function() local elapsed = tick() - startTime local alpha = math.min(elapsed / duration, 1) local eased = alpha * alpha * (3 - 2 * alpha) local currentPos = startPos2:Lerp(endPos, eased) local currentCF = CFrame.new(currentPos, endPos) local dist = (endPos - startPos2).Magnitude * eased beamPart.CFrame = currentCF beamPart.Size = Vector3.new(0.15, 0.15, math.max(0.1, dist)) beamPart.Transparency = 0.2 + (1 - eased) * 0.3 if alpha >= 1 then connection:Disconnect() beamPart:Destroy() end end) task.delay(1, function() if connection and connection.Connected then connection:Disconnect() end if beamPart and beamPart.Parent then beamPart:Destroy() end end) end createBeam(Vector3.new(0.5, 0, 0)) createBeam(Vector3.new(-0.5, 0, 0)) end end --// Hit sound local function playHitSound() local sound = Instance.new("Sound") sound.SoundId = selectedSoundId sound.Volume = 0.8 sound.Parent = workspace.CurrentCamera or Workspace sound:Play() task.delay(sound.TimeLength + 0.1, function() sound:Destroy() end) end --// Attack logic local function attackTarget(targetChar) if not targetChar or not targetChar.Parent then return end combatEvent:FireServer("Attack") local args = { { targetChar } } hitEvent:FireServer(unpack(args)) if HitSoundEnabled then playHitSound() end if ParticleEnabled then local root = targetChar:FindFirstChild("HumanoidRootPart") if root then createParticle(root.Position, selectedParticleColor) end end end --// Block local function blockActivate() combatEvent:FireServer("Block", true) local se = getServerEvent() if se then se:FireServer("BlockActivate", true) else warn("[AutoBlock] ServerEvent not found") end end --// Silent aim rotation local function setCharacterFacing(targetPos) local char = LocalPlayer.Character if not char then return end local hrp = char:FindFirstChild("HumanoidRootPart") if not hrp then return end local direction = (targetPos - hrp.Position) * Vector3.new(1, 0, 1) if direction.Magnitude > 0.001 then hrp.CFrame = CFrame.lookAt(hrp.Position, hrp.Position + direction.Unit) end end --// Check if enemy blocking local function isEnemyBlocking(enemyChar) if not enemyChar then return false end local hum = enemyChar:FindFirstChildOfClass("Humanoid") if hum then local success, state = pcall(function() return hum:GetState() end) if success then local stateName = tostring(state):lower() if stateName:find("block") or stateName:find("guard") or stateName:find("defend") then return true end end end local animator = enemyChar:FindFirstChildOfClass("Animator") if animator then for _, track in ipairs(animator:GetPlayingAnimationTracks()) do if track.Animation then local animName = track.Animation.Name:lower() if animName:find("block") or animName:find("guard") or animName:find("defend") then return true end end end end for _, child in ipairs(enemyChar:GetChildren()) do if child:IsA("BoolValue") then local nameLower = child.Name:lower() if nameLower:find("block") or nameLower:find("guard") then if child.Value == true then return true end end end end return false end --// Teleport behind enemy local function teleportBehindEnemy(enemyChar) if not enemyChar then return end local char = LocalPlayer.Character if not char then return end local hrp = char:FindFirstChild("HumanoidRootPart") if not hrp then return end local enemyRoot = enemyChar:FindFirstChild("HumanoidRootPart") if not enemyRoot then return end local enemyPosition = enemyRoot.Position local enemyLookVector = enemyRoot.CFrame.LookVector local behindPos = enemyPosition - enemyLookVector * 3 behindPos = Vector3.new(behindPos.X, enemyPosition.Y, behindPos.Z) hrp.CFrame = CFrame.new(behindPos, enemyPosition) end --// Apply hitbox visuals local function applyHitbox() if not HitboxConfig.Enabled then return end for _, player in ipairs(Players:GetPlayers()) do if player == LocalPlayer then continue end local char = player.Character if char then local hrp = char:FindFirstChild("HumanoidRootPart") if hrp then hrp.Size = Vector3.new(HitboxConfig.Size, HitboxConfig.Size, HitboxConfig.Size) hrp.Transparency = HitboxConfig.Transparency hrp.Color = HitboxConfig.Color hrp.Material = Enum.Material.Neon hrp.CanCollide = false end end end end --// Movement updates (with forced override) local function updateMovement() local char = LocalPlayer.Character if not char then return end local root = char:FindFirstChild("HumanoidRootPart") local hum = char:FindFirstChildOfClass("Humanoid") if not root or not hum then return end -- Fly if MovementConfig.FlyEnabled then hum.PlatformStand = true local moveDir = Vector3.new(0, 0, 0) if UserInputService:IsKeyDown(Enum.KeyCode.W) then moveDir += Camera.CFrame.LookVector end if UserInputService:IsKeyDown(Enum.KeyCode.S) then moveDir -= Camera.CFrame.LookVector end if UserInputService:IsKeyDown(Enum.KeyCode.A) then moveDir -= Camera.CFrame.RightVector end if UserInputService:IsKeyDown(Enum.KeyCode.D) then moveDir += Camera.CFrame.RightVector end if UserInputService:IsKeyDown(Enum.KeyCode.Space) then moveDir += Vector3.new(0,1,0) end if UserInputService:IsKeyDown(Enum.KeyCode.LeftShift) then moveDir -= Vector3.new(0,1,0) end if moveDir.Magnitude > 0 then moveDir = moveDir.Unit end root.AssemblyLinearVelocity = moveDir * MovementConfig.FlySpeed else if hum.PlatformStand then hum.PlatformStand = false end end -- WalkSpeed (forced) if MovementConfig.WalkSpeedEnabled then hum.WalkSpeed = MovementConfig.WalkSpeed end -- JumpPower (forced + UseJumpPower) if MovementConfig.JumpEnabled then pcall(function() hum.UseJumpPower = true end) hum.JumpPower = MovementConfig.JumpPower end end -- Anti-reset connections for WalkSpeed and JumpPower local function setupMovementAntiReset() local char = LocalPlayer.Character or LocalPlayer.CharacterAdded:Wait() local hum = char:WaitForChild("Humanoid") if MovementConfig.WalkSpeedEnabled then hum:GetPropertyChangedSignal("WalkSpeed"):Connect(function() if MovementConfig.WalkSpeedEnabled then hum.WalkSpeed = MovementConfig.WalkSpeed end end) end if MovementConfig.JumpEnabled then pcall(function() hum.UseJumpPower = true end) hum:GetPropertyChangedSignal("JumpPower"):Connect(function() if MovementConfig.JumpEnabled then hum.JumpPower = MovementConfig.JumpPower end end) end end LocalPlayer.CharacterAdded:Connect(function(char) task.wait(0.5) setupMovementAntiReset() end) if LocalPlayer.Character then task.spawn(setupMovementAntiReset) end --// Main heartbeat (combat + movement + hitbox) local function onHeartbeat() -- Combat local char = LocalPlayer.Character if char then local hrp = char:FindFirstChild("HumanoidRootPart") if hrp then local myPos = hrp.Position local now = tick() local enemies = {} local nearestEnemy = nil local nearestDist = math.huge local maxRange = math.max(KillAuraRange, BlockDistance) for _, p in ipairs(Players:GetPlayers()) do if p ~= LocalPlayer then local tChar = p.Character if tChar and tChar.Parent then local tRoot = tChar:FindFirstChild("HumanoidRootPart") if tRoot then local dist = (myPos - tRoot.Position).Magnitude if dist <= maxRange then local hum = tChar:FindFirstChildOfClass("Humanoid") local health = hum and hum.Health or 0 table.insert(enemies, { char = tChar, root = tRoot, dist = dist, health = health }) if dist < nearestDist then nearestDist = dist nearestEnemy = tChar end end end end end end -- Anti-block if AntiBlockEnabled and nearestEnemy and (now - lastAntiBlockTime) >= AntiBlockCooldown then if isEnemyBlocking(nearestEnemy) then teleportBehindEnemy(nearestEnemy) lastAntiBlockTime = now end end -- Auto block if AutoBlockEnabled then local shouldBlock = false for _, info in ipairs(enemies) do if info.dist <= BlockDistance then shouldBlock = true; break end end if shouldBlock then blockActivate() if SilentAimEnabled and nearestEnemy then local root = nearestEnemy:FindFirstChild("HumanoidRootPart") if root then setCharacterFacing(root.Position) end end end end -- Kill aura if KillAuraEnabled and now - lastAttackTime >= KillAuraSpeed then local targets = {} for _, info in ipairs(enemies) do if info.dist <= KillAuraRange then table.insert(targets, info) end end if #targets > 0 then if PriorityMode == "距离优先" then table.sort(targets, function(a,b) return a.dist < b.dist end) elseif PriorityMode == "血量最低" then table.sort(targets, function(a,b) return a.health < b.health end) end local count = math.min(MaxTargets, #targets) local attackedAny = false local shouldNotify = (now - lastNotifyTime) >= KillAuraNotifyCooldown local notified = false for i = 1, count do local info = targets[i] attackTarget(info.char) attackedAny = true if AttackSilentAimEnabled and i == 1 then local root = info.char:FindFirstChild("HumanoidRootPart") if root then setCharacterFacing(root.Position) end end if shouldNotify and not notified then pcall(function() Library:Notify(string.format("攻击 %s (剩余血量: %d)", info.char.Name, math.floor(info.health)), 1.5) end) lastNotifyTime = now notified = true end end if attackedAny then lastAttackTime = now end end end end end updateMovement() applyHitbox() end local mainHeartbeatConnection = RunService.Heartbeat:Connect(onHeartbeat) -- Toggle setters local function setKillAura(state) KillAuraEnabled = state if killToggleRef then killToggleRef:SetValue(state) end end local function setAutoBlock(state) AutoBlockEnabled = state if blockToggleRef then blockToggleRef:SetValue(state) end end local function setAntiBlock(state) AntiBlockEnabled = state if antiBlockToggleRef then antiBlockToggleRef:SetValue(state) end end --// ========================================== --// UI (Chinese labels, English comments) --// ========================================== -- Combat Tab - Left local LeftGroup = Tabs.Combat:AddLeftGroupbox("杀戮光环", "crosshair") local killToggle = LeftGroup:AddToggle("KillAuraToggle", { Text = "启用杀戮光环 []", Default = false, Callback = setKillAura }) killToggleRef = killToggle LeftGroup:AddLabel("快捷键"):AddKeyPicker("KillAuraKeybind", { Default = "", NoUI = false, Text = "设置按键", Mode = "Toggle", Callback = function(key) if key then setKillAura(not KillAuraEnabled) killToggle:SetText("启用杀戮光环 [" .. key .. "]") end end }) LeftGroup:AddSlider("KillAuraRange", { Text = "攻击距离", Default = 30, Min = 5, Max = 50, Rounding = 0, Suffix = " 米", Callback = function(v) KillAuraRange = v end }) LeftGroup:AddSlider("KillAuraSpeed", { Text = "攻击速度", Default = 0.04, Min = 0.01, Max = 0.2, Rounding = 2, Suffix = " 秒", Callback = function(v) KillAuraSpeed = v end }) LeftGroup:AddSlider("KillAuraNotifyCooldown", { Text = "通知冷却", Default = 0.5, Min = 0.1, Max = 2, Rounding = 1, Suffix = " 秒", Callback = function(v) KillAuraNotifyCooldown = v end }) LeftGroup:AddDropdown("PriorityMode", { Text = "攻击优先模式", Values = {"距离优先", "血量最低"}, Default = "距离优先", Callback = function(v) PriorityMode = v end }) LeftGroup:AddSlider("MaxTargets", { Text = "同时攻击人数", Default = 1, Min = 1, Max = 5, Rounding = 0, Suffix = " 人", Callback = function(v) MaxTargets = v end }) LeftGroup:AddToggle("AttackSilentAimToggle", { Text = "攻击时静默朝向", Default = false, Callback = function(v) AttackSilentAimEnabled = v end }) -- Anti-block LeftGroup:AddDivider() LeftGroup:AddLabel("破防瞬移") local antiBlockToggle = LeftGroup:AddToggle("AntiBlockToggle", { Text = "启用破防瞬移", Default = false, Tooltip = "检测到敌人防御时,自动瞬移到敌人背后", Callback = setAntiBlock }) antiBlockToggleRef = antiBlockToggle LeftGroup:AddSlider("AntiBlockCooldown", { Text = "瞬移冷却", Default = 0.5, Min = 0.1, Max = 2, Rounding = 1, Suffix = " 秒", Callback = function(v) AntiBlockCooldown = v end }) -- Hit sound LeftGroup:AddDivider() LeftGroup:AddLabel("命中音效") LeftGroup:AddToggle("HitSoundToggle", { Text = "启用音效", Default = false, Callback = function(v) HitSoundEnabled = v end }) LeftGroup:AddDropdown("HitSoundSelect", { Text = "选择音效", Values = {"Fatality","Neverlose","Gamesense","Rust","Ciallo","Osu","Minecraft","Bow"}, Default = "Fatality", Callback = function(v) selectedSoundId = soundIds[v] end }) -- Particles LeftGroup:AddDivider() LeftGroup:AddLabel("粒子特效") LeftGroup:AddToggle("ParticleToggle", { Text = "启用粒子特效", Default = false, Callback = function(v) ParticleEnabled = v end }) LeftGroup:AddDropdown("ParticleColor", { Text = "选择颜色", Values = {"红色","蓝色","绿色","黄色","紫色","青色","白色","橙色"}, Default = "红色", Callback = function(v) selectedParticleColor = colorPresets[v] end }) LeftGroup:AddDropdown("ParticleShape", { Text = "形状选择", Values = {"圆形","云形","激光"}, Default = "圆形", Callback = function(v) particleShape = v end }) -- Combat Tab - Right local RightGroup = Tabs.Combat:AddRightGroupbox("自动防御", "shield") local blockToggle = RightGroup:AddToggle("AutoBlockToggle", { Text = "启用自动防御 []", Default = false, Callback = setAutoBlock }) blockToggleRef = blockToggle RightGroup:AddLabel("快捷键"):AddKeyPicker("AutoBlockKeybind", { Default = "", NoUI = false, Text = "设置按键", Mode = "Toggle", Callback = function(key) if key then setAutoBlock(not AutoBlockEnabled) blockToggle:SetText("启用自动防御 [" .. key .. "]") end end }) RightGroup:AddSlider("BlockDistance", { Text = "防御距离", Default = 30, Min = 5, Max = 100, Rounding = 0, Suffix = " 米", Callback = function(v) BlockDistance = v end }) RightGroup:AddToggle("SilentAimToggle", { Text = "防御时静默朝向", Default = false, Callback = function(v) SilentAimEnabled = v end }) -- Range Attack local HitboxGroup = Tabs.Combat:AddRightGroupbox("范围攻击", "target") local HitboxToggle = HitboxGroup:AddToggle("HitboxToggle", { Text = "启用范围攻击", Default = false, Callback = function(v) HitboxConfig.Enabled = v end }) HitboxToggle:AddColorPicker("HitboxColorPicker", { Default = HitboxConfig.Color, Title = "颜色", Callback = function(v) HitboxConfig.Color = v end }) HitboxGroup:AddSlider("HitboxSize", { Text = "大小", Default = 15, Min = 1, Max = 50, Rounding = 0, Callback = function(v) HitboxConfig.Size = v end }) HitboxGroup:AddSlider("HitboxTransparency", { Text = "透明度", Default = 0.5, Min = 0, Max = 1, Rounding = 2, Callback = function(v) HitboxConfig.Transparency = v end }) -- Movement local MoveGroup = Tabs.Combat:AddRightGroupbox("移动", "activity") MoveGroup:AddToggle("FlyToggle", { Text = "飞行", Default = false, Callback = function(v) MovementConfig.FlyEnabled = v end }) MoveGroup:AddSlider("FlySpeed", { Text = "飞行速度", Default = 50, Min = 10, Max = 200, Rounding = 0, Callback = function(v) MovementConfig.FlySpeed = v end }) MoveGroup:AddToggle("WalkSpeedToggle", { Text = "行走速度", Default = false, Callback = function(v) MovementConfig.WalkSpeedEnabled = v end }) MoveGroup:AddSlider("WalkSpeed", { Text = "速度", Default = 16, Min = 5, Max = 100, Rounding = 0, Callback = function(v) MovementConfig.WalkSpeed = v end }) MoveGroup:AddToggle("JumpPowerToggle", { Text = "跳跃高度", Default = false, Callback = function(v) MovementConfig.JumpEnabled = v end }) MoveGroup:AddSlider("JumpPower", { Text = "高度", Default = 50, Min = 20, Max = 200, Rounding = 0, Callback = function(v) MovementConfig.JumpPower = v end }) -- Visuals local EspGroup = Tabs.Visuals:AddLeftGroupbox("ESP2 (GIT风格)", "eye") EspGroup:AddToggle("ESP2Toggle", { Text = "启用 ESP2", Default = false, Callback = SetESP2Enabled }) EspGroup:AddToggle("ESP2BoxToggle", { Text = "显示方框", Default = true, Callback = function(v) ESP2_Settings.ShowBox = v end }) EspGroup:AddToggle("ESP2NameToggle", { Text = "显示名字", Default = true, Callback = function(v) ESP2_Settings.ShowName = v end }) EspGroup:AddToggle("ESP2HealthToggle", { Text = "显示血量", Default = true, Callback = function(v) ESP2_Settings.ShowHealth = v end }) EspGroup:AddToggle("ESP2ChamsToggle", { Text = "上色 (Chams)", Default = true, Callback = function(v) ESP2_Settings.ShowChams = v end }) EspGroup:AddToggle("ESP2StatusToggle", { Text = "显示敌人状态", Default = true, Callback = function(v) ESP2_Settings.ShowStatus = v end }) EspGroup:AddToggle("ESP2TeamCheckToggle", { Text = "队伍检测", Default = true, Callback = function(v) ESP2_Settings.TeamCheck = v end }) EspGroup:AddSlider("ESP2MaxDistance", { Text = "最大距离", Default = 5000, Min = 50, Max = 10000, Rounding = 0, Suffix = " 米", Callback = function(v) ESP2_Settings.MaxDistance = v end }) EspGroup:AddDivider() EspGroup:AddLabel("颜色设置(固定/动态)") EspGroup:AddDropdown("ESP2BoxColorMode", { Text = "方框颜色模式", Values = {"固定", "循环色相", "瀑布", "波浪"}, Default = "固定", Callback = function(v) ESP2_Settings.BoxColorMode = v end }) EspGroup:AddDropdown("ESP2BoxColor", { Text = "方框颜色(固定时生效)", Values = {"红色","蓝色","绿色","黄色","紫色","青色","白色","橙色"}, Default = "白色", Callback = function(v) ESP2_Settings.BoxColor = colorPresets[v] end }) EspGroup:AddDropdown("ESP2NameColorMode", { Text = "名字颜色模式", Values = {"固定", "循环色相", "瀑布", "波浪"}, Default = "固定", Callback = function(v) ESP2_Settings.NameColorMode = v end }) EspGroup:AddDropdown("ESP2NameColor", { Text = "名字颜色(固定时生效)", Values = {"红色","蓝色","绿色","黄色","紫色","青色","白色","橙色"}, Default = "白色", Callback = function(v) ESP2_Settings.NameColor = colorPresets[v] end }) EspGroup:AddDropdown("ESP2HealthColorMode", { Text = "血量颜色模式", Values = {"固定", "循环色相", "瀑布", "波浪"}, Default = "固定", Callback = function(v) ESP2_Settings.HealthBarColorMode = v end }) EspGroup:AddDropdown("ESP2HealthColor", { Text = "血量颜色(固定时生效)", Values = {"红色","蓝色","绿色","黄色","紫色","青色","白色","橙色"}, Default = "绿色", Callback = function(v) ESP2_Settings.HealthBarColor = colorPresets[v] end }) EspGroup:AddDropdown("ESP2StatusColorMode", { Text = "状态颜色模式", Values = {"固定", "循环色相", "瀑布", "波浪"}, Default = "固定", Callback = function(v) ESP2_Settings.StatusColorMode = v end }) EspGroup:AddDropdown("ESP2StatusColor", { Text = "状态颜色(固定时生效)", Values = {"红色","蓝色","绿色","黄色","紫色","青色","白色","橙色"}, Default = "黄色", Callback = function(v) ESP2_Settings.StatusColor = colorPresets[v] end }) -- UI Settings local MenuGroup = Tabs["UI Settings"]:AddLeftGroupbox("菜单", "wrench") MenuGroup:AddToggle("KeybindMenuOpen", { Default = false, Text = "打开快捷键菜单", Callback = function(v) Library.KeybindFrame.Visible = v end }) MenuGroup:AddToggle("ShowCustomCursor", { Text = "自定义光标", Default = true, Callback = function(v) Library.ShowCustomCursor = v end }) MenuGroup:AddDropdown("NotificationSide", { Values = {"左侧","右侧"}, Default = "右侧", Callback = function(v) Library:SetNotifySide(v) end }) MenuGroup:AddDropdown("DPIDropdown", { Values = {"50%","75%","100%","125%","150%","175%","200%"}, Default = "100%", Callback = function(v) v = v:gsub("%%","") Library:SetDPIScale(tonumber(v)) end }) MenuGroup:AddDivider() MenuGroup:AddLabel("菜单快捷键"):AddKeyPicker("MenuKeybind", { Default = "RightShift", NoUI = false, Text = "菜单开关" }) MenuGroup:AddButton("卸载", function() Library:Unload() end) Library.ToggleKeybind = Options.MenuKeybind ThemeManager:SetLibrary(Library) SaveManager:SetLibrary(Library) SaveManager:IgnoreThemeSettings() SaveManager:SetIgnoreIndexes({"MenuKeybind"}) ThemeManager:SetFolder("ProjectVitruvius") SaveManager:SetFolder("ProjectVitruvius") SaveManager:SetSubFolder("Config") SaveManager:BuildConfigSection(Tabs["UI Settings"]) ThemeManager:ApplyToTab(Tabs["UI Settings"]) SaveManager:LoadAutoloadConfig() Library:OnUnload(function() mainHeartbeatConnection:Disconnect() SetESP2Enabled(false) print("[Project Vitruvius] Unloaded") end)