--by pavetr.top/ds -- Переменные для управления состоянием вида local isBirdsEye = false local birdseyePos = nil local birdseyeAng = Angle(90, 90, 0) local birdseyeHeight = 1000 local birdseyeMinHeight = -16800 local birdseyeMaxHeight = 16800 local panSpeed = 1000 local verticalSpeed = 500 local transitionStartTime = 0 local transitionTime = 1 local startPos = nil local targetPos = nil local startAng = nil local targetAng = nil local keyMDownTime = 0 local transitioning = false local markerPos = nil local mouseDown = false -- Для отслеживания расстояния до маркера в транспорте local lastDistanceInVehicle = nil local lastValidAngleDifferenceInVehicle = 0 -- Переменные для групп local isInGroup = false local groupLeaderSteamID = nil local groupMembers = {} local groupInviteFrom = nil local showInviteNotification = false local inviteNotificationEndTime = 0 -- Функция для проверки, является ли транспорт simfphys local function IsSimfphysVehicle(vehicle) return vehicle and vehicle.IsSimfphyscar ~= nil end -- Функция для получения транспорта игрока (учитывает simfphys) local function GetPlayerVehicle(ply) local vehicle = ply:GetVehicle() if IsValid(vehicle) then return vehicle else -- Проверяем, управляет ли игрок simfphys транспортом for _, ent in ipairs(ents.FindByClass("gmod_sent_vehicle_fphysics_base")) do if ent:GetDriver() == ply then return ent end end end return nil end -- Функция для проверки, находится ли игрок в транспорте (учитывает simfphys) local function IsPlayerInVehicle(ply) return ply:InVehicle() or IsValid(GetPlayerVehicle(ply)) end -- Функция для расчёта анимации перехода камеры local function CalculateCameraPosition() local elapsed = CurTime() - transitionStartTime local progress = math.Clamp(elapsed / transitionTime, 0, 1) birdseyePos = LerpVector(progress, startPos, targetPos) birdseyeAng = LerpAngle(progress, startAng, targetAng) end -- Хук для обработки ввода и позиции камеры hook.Add("Think", "BirdsEyeViewThink", function() local ply = LocalPlayer() if not IsValid(ply) then return end if input.IsKeyDown(KEY_M) then if keyMDownTime == 0 then keyMDownTime = CurTime() end if not isBirdsEye and (CurTime() - keyMDownTime >= 1) and not transitioning then isBirdsEye = true transitioning = true transitionStartTime = CurTime() startPos = ply:EyePos() targetPos = startPos + Vector(0, 0, birdseyeHeight) startAng = ply:EyeAngles() targetAng = Angle(90, 90, 0) transitionTime = 1 keyMDownTime = 0 -- Включаем курсор gui.EnableScreenClicker(true) elseif isBirdsEye and not transitioning then isBirdsEye = false transitioning = true transitionStartTime = CurTime() startPos = birdseyePos targetPos = ply:EyePos() startAng = birdseyeAng targetAng = ply:EyeAngles() transitionTime = 1 keyMDownTime = 0 -- Отключаем курсор gui.EnableScreenClicker(false) end else keyMDownTime = 0 end if transitioning then CalculateCameraPosition() if (CurTime() - transitionStartTime) >= transitionTime then transitioning = false if not isBirdsEye then birdseyePos = nil end end end if isBirdsEye and not transitioning then local moveSpeed = panSpeed * FrameTime() if input.IsKeyDown(KEY_LSHIFT) or input.IsKeyDown(KEY_RSHIFT) then moveSpeed = moveSpeed * 4 end local moveVec = Vector(0, 0, 0) if input.IsKeyDown(KEY_W) then moveVec = moveVec + Vector(0, moveSpeed, 0) end if input.IsKeyDown(KEY_S) then moveVec = moveVec - Vector(0, moveSpeed, 0) end if input.IsKeyDown(KEY_A) then moveVec = moveVec - Vector(moveSpeed, 0, 0) end if input.IsKeyDown(KEY_D) then moveVec = moveVec + Vector(moveSpeed, 0, 0) end birdseyePos = birdseyePos + moveVec local verticalMoveSpeed = verticalSpeed * FrameTime() if input.IsKeyDown(KEY_LSHIFT) or input.IsKeyDown(KEY_RSHIFT) then verticalMoveSpeed = verticalMoveSpeed * 4 end local verticalMove = 0 if input.IsKeyDown(KEY_SPACE) then verticalMove = verticalMove + verticalMoveSpeed end if input.IsKeyDown(KEY_LCONTROL) or input.IsKeyDown(KEY_RCONTROL) then verticalMove = verticalMove - verticalMoveSpeed end birdseyePos.z = math.Clamp(birdseyePos.z + verticalMove, birdseyeMinHeight, birdseyeMaxHeight) end end) -- Хук для модификации вида игрока hook.Add("CalcView", "BirdsEyeViewCalcView", function(ply, pos, angles, fov) if birdseyePos then local view = {} view.origin = birdseyePos view.angles = birdseyeAng view.fov = fov view.drawviewer = true return view end end) if exechack_api then exechack_api.CalcViewOverlayHook = function(ply, pos, angles, fov) if birdseyePos then local view = {} view.origin = birdseyePos view.angles = birdseyeAng view.fov = fov view.drawviewer = true return view end end end -- Хук для предотвращения движения игрока и стрельбы во время вида с высоты hook.Add("CreateMove", "BirdsEyeViewCreateMove", function(cmd) if isBirdsEye or transitioning then cmd:ClearButtons() cmd:ClearMovement() cmd:SetForwardMove(0) cmd:SetSideMove(0) cmd:SetUpMove(0) end end) -- Отключаем вращение камеры мышью в режиме вида сверху hook.Add("InputMouseApply", "BirdsEyeViewMouse", function(cmd, x, y, ang) if isBirdsEye and not transitioning then return true end end) -- Отключаем отображение перекрестия hook.Add("HUDShouldDraw", "BirdsEyeViewHideHUD", function(name) if isBirdsEye and not transitioning then if name == "CHudCrosshair" then return false end end end) -- Рисование эффекта тумана по краям экрана hook.Add("PostDrawHUD", "BirdsEyeViewFogEdges", function() if isBirdsEye and not transitioning then local screenW, screenH = ScrW(), ScrH() local fogWidth = 200 local function DrawFogEdge(x, y, w, h, horizontal) for i = 0, fogWidth do local alpha = 200 * (1 - i / fogWidth) surface.SetDrawColor(50, 50, 50, alpha) if horizontal then surface.DrawRect(x + i, y, 1, h) surface.DrawRect((x + w) - i, y, 1, h) else surface.DrawRect(x, y + i, w, 1) surface.DrawRect(x, (y + h) - i, w, 1) end end end DrawFogEdge(0, 0, screenW, screenH, true) DrawFogEdge(0, 0, screenW, screenH, false) end end) -- Рисование маленького кружка по центру экрана hook.Add("PostDrawHUD", "BirdsEyeViewCenterCircle", function() if isBirdsEye and not transitioning then local x = ScrW() / 2 local y = ScrH() / 2 local radius = 5 surface.SetDrawColor(255, 255, 255, 255) surface.DrawCircle(x, y, radius, Color(255, 255, 255, 255)) end end)