local TAG = "SitAny_" local PLUGIN = PLUGIN CreateClientConVar("sitting_use_walk", "1.00", true, true, "Требовать шаг для сидения", 0, 1) CreateClientConVar("sitting_force_left_alt", "0", true, true, "Использовать левый Alt как шаг для сидения", 0, 1) CreateClientConVar("sitting_allow_on_me", "1.00", true, true, "Разрешить другим садиться на вас", 0, 1) local useAlt = GetConVar("sitting_use_walk") local forceBinds = GetConVar("sitting_force_left_alt") local function ShouldSit(ply) return hook.Run("ShouldSit", ply) end local arrow, drawScale, traceDist = Material("widgets/arrow.png"), 0.1, 20 local traceScaled = traceDist / drawScale local function StartSit(trace) local wantedAng = nil local cancelled = false local start = CurTime() local ply = LocalPlayer() hook.Add("PostDrawOpaqueRenderables", TAG .. "PostDrawOpaqueRenderables", function(depth, skybox) if CurTime() - start <= 0.25 then return end if trace.StartPos:Distance(ply:EyePos()) > 10 then cancelled, wantedAng = true, nil hook.Remove("PostDrawOpaqueRenderables", TAG .. "PostDrawOpaqueRenderables") return end local vec = util.IntersectRayWithPlane(ply:EyePos(), ply:EyeAngles():Forward(), trace.HitPos, Vector(0, 0, 1)) if not vec then return end local posOnPlane = WorldToLocal(vec, Angle(0, 90, 0), trace.HitPos, Angle(0, 0, 0)) local testVec = posOnPlane:GetNormal() * traceScaled local currentAng = (trace.HitPos - vec):Angle() wantedAng = currentAng if posOnPlane:Length() < 2 then wantedAng = nil return end if wantedAng then local goodSit = SitAnywhere.CheckValidAngForSit(trace.HitPos, trace.HitNormal:Angle(), wantedAng.y) if not goodSit then wantedAng = nil end cam.Start3D2D(trace.HitPos + Vector(0, 0, 1), Angle(0, 0, 0), drawScale) surface.SetDrawColor(goodSit and Color(255, 255, 255, 255) or Color(255, 0, 0, 255)) surface.SetMaterial(arrow) surface.DrawTexturedRectRotated(testVec.x * 0.5, testVec.y * -0.5, 2 / drawScale, traceScaled, currentAng.y + 90) cam.End3D2D() end end) return function() hook.Remove("PostDrawOpaqueRenderables", TAG .. "PostDrawOpaqueRenderables") if cancelled then return end if CurTime() - start < 0.25 then RunConsoleCommand("sit") return end if wantedAng then net.Start("SitAnywhere") net.WriteInt(SitAnywhere.NET.SitWantedAng, 4) net.WriteFloat(wantedAng.y) net.WriteVector(trace.StartPos) net.WriteVector(trace.Normal) net.SendToServer() wantedAng = nil end end end local function DoSit(trace) if not trace.Hit then return end local surfaceAng = trace.HitNormal:Angle() + Angle(-270, 0, 0) local playerTrace = not trace.HitWorld and IsValid(trace.Entity) and trace.Entity:IsPlayer() local goodSit = SitAnywhere.GetAreaProfile(trace.HitPos + Vector(0, 0, 0.1), 24, true) if math.abs(surfaceAng.pitch) >= 15 or not goodSit or playerTrace then RunConsoleCommand("sit") return end local valid = SitAnywhere.ValidSitTrace(LocalPlayer(), trace) if not valid then return end return StartSit(trace) end local currSit concommand.Add("+sit", function(ply, cmd, args) if currSit then return end if not IsValid(ply) or not ply.GetEyeTrace then return end currSit = DoSit(ply:GetEyeTrace()) end) concommand.Add("-sit", function(ply, cmd, args) if currSit then currSit() currSit = nil end end) function PLUGIN:KeyPress(ply, key) if not IsFirstTimePredicted() and not game.SinglePlayer() then return end if currSit then return end if key ~= IN_USE then return end local good = not useAlt:GetBool() local alwaysSit = ShouldSit(ply) if forceBinds:GetBool() then if useAlt:GetBool() and input.IsKeyDown(KEY_LALT) then good = true end else if useAlt:GetBool() and ply:KeyDown(IN_WALK) then good = true end end if ix.config.Get("sitForceNoWalk", false) then good = true end if alwaysSit == true then good = true elseif alwaysSit == false then good = false end if not good then return end local trace = LocalPlayer():GetEyeTrace() if trace.Hit then currSit = DoSit(trace) hook.Add("KeyRelease", TAG .. "KeyRelease", function(releasePly, releaseKey) if not IsFirstTimePredicted() and not game.SinglePlayer() then return end if ply ~= releasePly or releaseKey ~= IN_USE then return end hook.Remove("KeyRelease", TAG .. "KeyRelease") if not currSit then return end currSit() currSit = nil end) end end hook.Add("ShouldDrawLocalPlayer", "SitAnywhere_DrawLocalPlayer", function(ply) if not IsValid(ply) then return end local veh = ply:GetVehicle() if IsValid(veh) and veh:GetClass() == "prop_vehicle_prisoner_pod" and veh:GetNWBool("playerdynseat", false) then return true end end)