PLUGIN.name = "Parachute System" PLUGIN.author = "V92 (Портирован для Helix)" PLUGIN.description = "Система парашютов в стиле Battlefield 2 для безопасного приземления" -- Конфигурация ix.config.Add("parachuteMode", 0, "Режим доступа к парашюту: -1=Отключен, 0=Все, 1=Админы, 2=Супер-админы", nil, { data = {min = -1, max = 2}, category = "Parachute System" }) ix.config.Add("parachuteVolume", 0.7, "Громкость звука полёта на парашюте", nil, { data = {min = 0.2, max = 1.0, decimals = 1}, category = "Parachute System" }) ix.config.Add("parachuteSpeedBack", 300, "Скорость при движении назад", nil, { data = {min = 200, max = 500}, category = "Parachute System" }) ix.config.Add("parachuteSpeedNormal", 375, "Скорость без управления", nil, { data = {min = 250, max = 600}, category = "Parachute System" }) ix.config.Add("parachuteSpeedForward", 450, "Скорость при движении вперёд", nil, { data = {min = 300, max = 700}, category = "Parachute System" }) ix.config.Add("parachuteReloadTime", 20, "Время перезарядки парашюта (секунды)", nil, { data = {min = 5, max = 60}, category = "Parachute System" }) ix.config.Add("parachuteMinVelocity", -600, "Минимальная скорость падения для активации", nil, { data = {min = -1000, max = -100}, category = "Parachute System" }) -- Регистрация звуков sound.Add({ ["name"] = "VNT_ParachuteZ_DetachClip", ["channel"] = CHAN_BODY, ["volume"] = 1.0, ["level"] = 50, ["pitch"] = {90, 110}, ["sound"] = {"npc/combine_soldier/zipline_clip1.wav", "npc/combine_soldier/zipline_clip2.wav"} }) sound.Add({ ["name"] = "VNT_ParachuteZ_BF2_Deploy", ["channel"] = CHAN_BODY, ["volume"] = 1.0, ["level"] = 75, ["pitch"] = {105, 110}, ["sound"] = {"v92/bf2/vehicles/air/parachute/parachute_deploy.wav"} }) sound.Add({ ["name"] = "VNT_ParachuteZ_BF2_Idle", ["channel"] = CHAN_STATIC, ["volume"] = 1.0, ["level"] = 75, ["pitch"] = {100}, ["sound"] = {"v92/bf2/vehicles/air/parachute/parachute_ride_loop.wav"} }) if SERVER then -- Загрузка workshop контента --resource.AddWorkshop("105699464") -- Координаты смещения для сущностей парашюта local ActiveParachute = {10, 0, 100} local LandedParachute = {-100, 50, 10} local DitchedParachute = {10, 0, 0} function PLUGIN:KeyPress(ply, key) if not ply:Alive() or not IsValid(ply) then return end if not IsValid(ply:GetActiveWeapon()) then return end if ply:GetActiveWeapon():GetClass() ~= "parachute_swep" then return end local reloadTime = ix.config.Get("parachuteReloadTime", 20) local minVel = ix.config.Get("parachuteMinVelocity", -600) if ((ply:GetNW2Int("r_parachute") or 0) <= CurTime()) and (key == IN_ATTACK and ply:IsValid()) and not (ply:GetMoveType() == MOVETYPE_NOCLIP or ply:InVehicle() or ply:OnGround() or ply.Parachuting == true or ply:GetVelocity().z > minVel) then ply.EndParaTime = nil ply.Parachuting = true net.Start("ParachuteState") net.WriteBool(ply.Parachuting) net.Send(ply) ply.FlarePara = 1 ply:ViewPunch(Angle(35, 0, 0)) local Para = ents.Create("v92_zchute_bf2_active") Para:SetOwner(ply) Para:SetPos(ply:GetPos() + ply:GetForward() * ActiveParachute[1] + ply:GetRight() * ActiveParachute[2] + ply:GetUp() * ActiveParachute[3]) Para:SetAngles(ply:GetAngles()) Para:Spawn() Para:Activate() end end function PLUGIN:Think() local mode = ix.config.Get("parachuteMode", 0) -- Если отключено if mode == -1 then return end local speedBack = ix.config.Get("parachuteSpeedBack", 300) local speedNormal = ix.config.Get("parachuteSpeedNormal", 375) local speedForward = ix.config.Get("parachuteSpeedForward", 450) for k, v in pairs(player.GetAll()) do -- Проверка прав доступа if (mode == 1 and not v:IsAdmin()) or (mode == 2 and not v:IsSuperAdmin()) then if v.Parachuting then v.Parachuting = false end return end if v.Parachuting == true then -- Приземление if (v.EndParaTime and CurTime() >= v.EndParaTime and v:OnGround() == true) or v:WaterLevel() > 0 or v:GetMoveType() == MOVETYPE_LADDER then v.EndParaTime = nil v.Parachuting = false net.Start("ParachuteState") net.WriteBool(v.Parachuting) net.Send(v) v.FlarePara = 1 v:ViewPunch(Angle(-16, 0, 0)) local ParaLand = ents.Create("v92_zchute_bf2_land") ParaLand:SetOwner(v) ParaLand:SetPos(v:GetPos() + v:GetForward() * LandedParachute[1] + v:GetRight() * LandedParachute[2] + v:GetUp() * LandedParachute[3]) ParaLand:SetAngles(v:GetAngles() + Angle(0, 270, 0)) ParaLand:Spawn() ParaLand:Activate() end -- Управление скоростью спуска if v:KeyDown(IN_USE) and v.FlarePara > 0.4 then v.FlarePara = v.FlarePara - 0.005 if v.FlarePara < 0.4 then v.FlarePara = 0.4 end end -- Управление направлением if v:KeyDown(IN_FORWARD) then v:SetLocalVelocity(v:GetForward() * speedForward * v.FlarePara * 1.1 - v:GetUp() * 320 * v.FlarePara) elseif v:KeyDown(IN_BACK) then v:SetLocalVelocity(v:GetForward() * speedBack * v.FlarePara * 1.1 - v:GetUp() * 320 * v.FlarePara) else v:SetLocalVelocity(v:GetForward() * speedNormal * v.FlarePara * 1.1 - v:GetUp() * 320 * v.FlarePara) end -- Отцепление парашюта (Ctrl + Shift) if (v:KeyDown(IN_DUCK) and v:KeyDown(IN_WALK) and v.Parachuting == true) or not (v:Alive() or IsValid(v)) then v.Parachuting = false net.Start("ParachuteState") net.WriteBool(v.Parachuting) net.Send(v) v.FlarePara = 1 v:ViewPunch(Angle(-15, 0, 0)) local ParaDitch = ents.Create("v92_zchute_bf2_abandon") ParaDitch:SetOwner(v) ParaDitch:SetPos(v:GetPos() + v:GetForward() * DitchedParachute[1] + v:GetRight() * DitchedParachute[2] + v:GetUp() * DitchedParachute[3]) ParaDitch:SetAngles(v:GetAngles()) ParaDitch:Spawn() ParaDitch:Activate() end -- Касание земли if v:OnGround() and v.Parachuting == true and not v.EndParaTime then v.EndParaTime = CurTime() + 0.25 net.Start("ParachuteState") net.WriteBool(false) net.Send(v) v:ViewPunch(Angle(7, 0, 0)) end end end end util.AddNetworkString("ParachuteState") end function PLUGIN:Initialize() print("[Parachute System] Система парашютов загружена!") print("[Parachute System] Используйте ЛКМ для раскрытия, Ctrl+Shift для отцепления") end ix.util.Include("cl_plugin.lua")