add sborka

This commit is contained in:
2026-03-31 10:27:04 +03:00
commit f5e5f56c84
2345 changed files with 382127 additions and 0 deletions

View File

@@ -0,0 +1,5 @@
include("shared.lua")
function ENT:Draw()
self:DrawModel()
end

View File

@@ -0,0 +1,51 @@
AddCSLuaFile("cl_init.lua")
AddCSLuaFile("shared.lua")
include("shared.lua")
function ENT:Initialize()
self:SetModel("models/sw/shared/airdrop_large.mdl")
self:SetSolid(SOLID_VPHYSICS)
self:PhysicsInit(SOLID_VPHYSICS)
self:SetUseType(SIMPLE_USE)
local phys = self:GetPhysicsObject()
if (IsValid(phys)) then
phys:Wake()
end
end
function ENT:Use(activator)
if (IsValid(activator) and activator:IsPlayer()) then
if (self.opened) then return end
self.opened = true
local weaponClass = self.ixWeapon or "tacrp_m320"
local character = activator:GetCharacter()
local inventory = character and character:GetInventory()
if (inventory and !isnumber(inventory) and ix.item.list[weaponClass]) then
inventory:Add(weaponClass)
ix.util.Notify("Вы получили " .. (ix.item.list[weaponClass].name or weaponClass) .. " из аирдропа.", activator)
else
activator:Give(weaponClass)
ix.util.Notify("Вы получили " .. (self.ixWeapon or "неизвестное оружие") .. " из аирдропа.", activator)
end
if (IsValid(self.ixSmoke)) then
self.ixSmoke:Remove()
end
local effect = EffectData()
effect:SetOrigin(self:GetPos())
effect:SetScale(1)
util.Effect("Explosion", effect)
self:Remove()
end
end
function ENT:OnTakeDamage(damage)
if (damage:GetDamage() > 50) then
self:Use(damage:GetAttacker())
end
end

View File

@@ -0,0 +1,6 @@
ENT.Type = "anim"
ENT.Base = "base_gmodentity"
ENT.PrintName = "Airdrop"
ENT.Category = "Helix"
ENT.Spawnable = false
ENT.AdminOnly = true

View File

@@ -0,0 +1,92 @@
local PLUGIN = PLUGIN
PLUGIN.name = "Airdrop"
PLUGIN.author = "Scripty"
PLUGIN.description = "Airdrop plugin."
ix.config.Add("airdropPlaneModel", "models/il76/il_76_fly.mdl", "Модель самолета для аирдропа.", nil, {
category = "Airdrop"
})
ix.config.Add("airstrikePlaneModel", "models/gunkov2056/su25.mdl", "Модель самолета для авиаудара.", nil, {
category = "Airdrop"
})
ix.config.Add("airdropMinInterval", 3600, "Минимальный интервал между аирдропами (в секундах).", nil, {
data = {min = 60, max = 86400},
category = "Airdrop"
})
ix.config.Add("airdropMaxInterval", 7200, "Максимальный интервал между аирдропами (в секундах).", nil, {
data = {min = 60, max = 86400},
category = "Airdrop"
})
ix.config.Add("airdropWeapons", [[tacrp_io_degala
tacrp_io_fiveseven
tacrp_mr96
tacrp_pdw
tacrp_superv
tacrp_sd_aac_hb
tacrp_ak_ak12
tacrp_ak_an94
tacrp_sg551
tacrp_io_xm8car
tacrp_hk417
tacrp_io_scarh
tacrp_mg4
tacrp_io_xm8lmg
tacrp_io_sg550r
tacrp_io_sl8
tacrp_io_sg550
tacrp_io_vss
tacrp_as50
tacrp_ex_hecate
tacrp_civ_m320]], "Список оружия, которое может выпасть из аирдропа (каждое с новой строки).", nil, {
category = "Airdrop"
})
ix.config.Add("airstrikeMinInterval", 1800, "Минимальный интервал между авиаударами (в секундах).", nil, {
data = {min = 60, max = 86400},
category = "Airdrop"
})
ix.config.Add("airstrikeMaxInterval", 3600, "Максимальный интервал между авиаударами (в секундах).", nil, {
data = {min = 60, max = 86400},
category = "Airdrop"
})
ix.command.Add("AirdropForce", {
description = "Принудительно вызвать случайный аирдроп.",
privilege = "Manage Airdrops",
superAdminOnly = true,
OnRun = function(self, client)
PLUGIN:SpawnAirdrop()
ix.util.Notify("Аирдроп был вызван администратором.", nil, "all")
end
})
ix.command.Add("AirdropGive", {
description = "Вызвать аирдроп с конкретным оружием.",
privilege = "Manage Airdrops",
superAdminOnly = true,
arguments = {
ix.type.string
},
OnRun = function(self, client, weapon)
PLUGIN:SpawnAirdrop(weapon)
ix.util.Notify("Аирдроп с " .. weapon .. " был вызван администратором.", nil, "all")
end
})
ix.command.Add("AirstrikeForce", {
description = "Принудительно вызвать авиаудар.",
privilege = "Manage Airdrops",
superAdminOnly = true,
OnRun = function(self, client)
PLUGIN:SpawnAirstrike()
ix.util.Notify("Авиаудар был вызван администратором.", nil, "all")
end
})
ix.util.Include("sv_plugin.lua")

View File

@@ -0,0 +1,329 @@
local PLUGIN = PLUGIN
-- Координаты баз для запрета авиаударов
local BASE_RF = {
min = Vector(-12686, 4350, -10000),
max = Vector(-8714, 12126, 10000)
}
local BASE_UK = {
min = Vector(9778, 2972, -10000),
max = Vector(13576, 10852, 10000)
}
local function IsInBase(pos)
if (pos:WithinAABox(BASE_RF.min, BASE_RF.max)) then return true end
if (pos:WithinAABox(BASE_UK.min, BASE_UK.max)) then return true end
return false
end
function PLUGIN:SpawnAirdrop(weapon)
local center = Vector(0, 0, 0)
local players = player.GetAll()
if (#players > 0) then
local targetPlayer = players[math.random(#players)]
center = targetPlayer:GetPos()
end
local angle = math.random(0, 360)
local radian = math.rad(angle)
local altitude = math.random(2000, 2500)
local startPos = center + Vector(math.cos(radian) * 15000, math.sin(radian) * 15000, 0)
startPos.z = altitude
local endPos = center - Vector(math.cos(radian) * 15000, math.sin(radian) * 15000, 0)
endPos.z = altitude
util.PrecacheModel(ix.config.Get("airdropPlaneModel", "models/gunkov2056/su25.mdl"))
local plane = ents.Create("prop_dynamic")
plane:SetModel(ix.config.Get("airdropPlaneModel", "models/gunkov2056/su25.mdl"))
plane:SetPos(startPos)
local angles = (endPos - startPos):Angle()
plane:SetAngles(angles)
plane:SetMoveType(MOVETYPE_FLY)
plane:Spawn()
plane:Activate()
print("[Airdrop] Спавн самолета: " .. plane:GetModel() .. " на " .. tostring(startPos))
local speed = 2500
local distance = startPos:Distance(endPos)
local duration = distance / speed
local dropFrac = math.Rand(0.45, 0.55)
local dropped = false
local startTime = CurTime()
plane:EmitSound("su25/su25.wav", 150, 100, 1, CHAN_AUTO)
timer.Create("AirdropPlaneMove_" .. plane:EntIndex(), 0.05, 0, function()
if (!IsValid(plane)) then return end
local elapsed = CurTime() - startTime
local frac = elapsed / duration
if (frac >= 1) then
plane:StopSound("su25/su25.wav")
plane:Remove()
timer.Remove("AirdropPlaneMove_" .. plane:EntIndex())
return
end
plane:SetPos(LerpVector(frac, startPos, endPos))
if (!dropped and frac >= dropFrac) then
dropped = true
self:DropCrate(plane:GetPos(), weapon)
end
end)
end
function PLUGIN:SpawnAirstrike()
ix.util.Notify("Внимание! Обнаружена воздушная угроза. Авиаудар через 30 секунд!", nil, "all")
timer.Simple(30, function()
local targetPos = Vector(0, 0, 0)
local players = player.GetAll()
local attempts = 0
-- Ищем валидную точку для удара (не в базе)
repeat
if (#players > 0) then
targetPos = players[math.random(#players)]:GetPos()
else
targetPos = Vector(math.random(-10000, 10000), math.random(-10000, 10000), 0)
end
attempts = attempts + 1
until (!IsInBase(targetPos) or attempts > 10)
if (IsInBase(targetPos)) then return end -- Отмена если не нашли безопасную точку
local angle = math.random(0, 360)
local radian = math.rad(angle)
local altitude = math.random(2000, 2500)
local startPos = targetPos + Vector(math.cos(radian) * 15000, math.sin(radian) * 15000, 0)
startPos.z = altitude
local endPos = targetPos - Vector(math.cos(radian) * 15000, math.sin(radian) * 15000, 0)
endPos.z = altitude
util.PrecacheModel(ix.config.Get("airstrikePlaneModel", "models/gunkov2056/su25.mdl"))
local plane = ents.Create("prop_dynamic")
plane:SetModel(ix.config.Get("airstrikePlaneModel", "models/gunkov2056/su25.mdl"))
plane:SetPos(startPos)
plane:SetAngles((endPos - startPos):Angle())
plane:SetMoveType(MOVETYPE_FLY)
plane:Spawn()
plane:Activate()
print("[Airstrike] Спавн самолета: " .. plane:GetModel() .. " на " .. tostring(startPos))
local speed = 3000
local duration = startPos:Distance(endPos) / speed
local dropped = false
local startTime = CurTime()
plane:EmitSound("su25/su25.wav", 150, 100, 1, CHAN_AUTO)
timer.Create("AirstrikePlaneMove_" .. plane:EntIndex(), 0.05, 0, function()
if (!IsValid(plane)) then return end
local elapsed = CurTime() - startTime
local frac = elapsed / duration
if (frac >= 1) then
plane:StopSound("su25/su25.wav")
plane:Remove()
timer.Remove("AirstrikePlaneMove_" .. plane:EntIndex())
return
end
plane:SetPos(LerpVector(frac, startPos, endPos))
if (!dropped and frac >= 0.5) then
dropped = true
self:DropBomb(plane:GetPos(), plane:GetForward() * speed)
end
end)
end)
end
function PLUGIN:DropBomb(pos, velocity)
local bomb = ents.Create("sw_bomb_fab250m62_v3")
if (!IsValid(bomb)) then
-- Если энтити нет, создадим обычный взрыв для теста
local exp = ents.Create("env_explosion")
exp:SetPos(pos)
exp:SetKeyValue("iMagnitude", "300")
exp:Spawn()
exp:Fire("Explode", 0, 0)
return
end
bomb:SetPos(pos)
bomb:SetAngles(velocity:Angle())
bomb:Spawn()
bomb:Activate()
local phys = bomb:GetPhysicsObject()
if (IsValid(phys)) then
phys:SetVelocity(velocity)
end
end
function PLUGIN:DropCrate(pos, weapon)
if (!weapon) then
local weaponsConfig = ix.config.Get("airdropWeapons", "")
local weapons = {}
if (type(weaponsConfig) == "string" and weaponsConfig:Trim() != "") then
for _, v in pairs(string.Split(weaponsConfig, "\n")) do
local s = v:Trim()
if (s != "") then
table.insert(weapons, s)
end
end
end
-- Если конфиг пустой или старый, берем список по умолчанию
if (#weapons == 0) then
weapons = {
"tacrp_io_degala",
"tacrp_io_fiveseven",
"tacrp_mr96",
"tacrp_pdw",
"tacrp_superv",
"tacrp_sd_aac_hb",
"tacrp_ak_ak12",
"tacrp_ak_an94",
"tacrp_sg551",
"tacrp_io_xm8car",
"tacrp_hk417",
"tacrp_io_scarh",
"tacrp_mg4",
"tacrp_io_xm8lmg",
"tacrp_io_sg550r",
"tacrp_io_sl8",
"tacrp_io_sg550",
"tacrp_io_vss",
"tacrp_as50",
"tacrp_ex_hecate",
"tacrp_civ_m320"
}
end
weapon = weapons[math.random(#weapons)]
end
local crate = ents.Create("ix_airdrop")
if (!IsValid(crate)) then
print("[Airdrop] ОШИБКА: Не удалось создать энтити ix_airdrop!")
return
end
crate:SetPos(pos)
crate:SetAngles(Angle(0, math.random(0, 360), 0))
crate:Spawn()
crate.ixWeapon = weapon
-- Создаем парашют
util.PrecacheModel("models/jessev92/bf2/parachute.mdl")
local parachute = ents.Create("prop_dynamic")
parachute:SetModel("models/jessev92/bf2/parachute.mdl")
parachute:SetPos(crate:GetPos() + Vector(0, 0, 50))
parachute:SetParent(crate)
parachute:Spawn()
crate.ixParachute = parachute
local phys = crate:GetPhysicsObject()
if (IsValid(phys)) then
phys:Wake()
phys:SetVelocity(Vector(0, 0, -200)) -- Скорость падения
phys:SetDragCoefficient(5)
phys:SetAngleDragCoefficient(100)
end
local function StartSmoke()
if (!IsValid(crate)) then return end
local smoke = ents.Create("env_smokestack")
smoke:SetPos(crate:GetPos())
smoke:SetAngles(Angle(-90, 0, 0))
smoke:SetKeyValue("InitialState", "1")
smoke:SetKeyValue("rendercolor", "255 100 0")
smoke:SetKeyValue("renderamt", "255")
smoke:SetKeyValue("SmokeMaterial", "particle/smokesprites_0001.vmt")
smoke:SetKeyValue("BaseSpread", "20")
smoke:SetKeyValue("SpreadSpeed", "10")
smoke:SetKeyValue("Speed", "80")
smoke:SetKeyValue("StartSize", "30")
smoke:SetKeyValue("EndSize", "120")
smoke:SetKeyValue("Rate", "40")
smoke:SetKeyValue("JetLength", "300")
smoke:Spawn()
smoke:Activate()
smoke:SetParent(crate)
crate.ixSmoke = smoke
ix.util.Notify("Аирдроп приземлился! Ищите оранжевый дым.", nil, "all")
end
-- Принудительно держим ящик ровно во время падения
timer.Create("AirdropUpright_" .. crate:EntIndex(), 0.1, 0, function()
if (!IsValid(crate)) then
timer.Remove("AirdropUpright_" .. crate:EntIndex())
return
end
local phys = crate:GetPhysicsObject()
if (IsValid(phys) and phys:IsMotionEnabled()) then
crate:SetAngles(Angle(0, crate:GetAngles().y, 0))
phys:SetAngleVelocity(Vector(0, 0, 0))
else
timer.Remove("AirdropUpright_" .. crate:EntIndex())
end
end)
timer.Create("AirdropLand_" .. crate:EntIndex(), 0.2, 0, function()
if (!IsValid(crate)) then
timer.Remove("AirdropLand_" .. crate:EntIndex())
return
end
local phys = crate:GetPhysicsObject()
if (!IsValid(phys)) then return end
-- Если скорость мала или мы коснулись земли
local tr = util.TraceLine({
start = crate:GetPos() + Vector(0, 0, 10),
endpos = crate:GetPos() - Vector(0, 0, 40),
filter = crate
})
if (tr.Hit or phys:GetVelocity():Length() < 5) then
phys:EnableMotion(false)
crate:SetPos(tr.HitPos)
crate:SetAngles(Angle(0, crate:GetAngles().y, 0))
if (IsValid(crate.ixParachute)) then
crate.ixParachute:Remove()
end
StartSmoke()
timer.Remove("AirdropLand_" .. crate:EntIndex())
timer.Remove("AirdropUpright_" .. crate:EntIndex())
end
end)
timer.Simple(900, function()
if (IsValid(crate)) then
if (IsValid(crate.ixSmoke)) then crate.ixSmoke:Remove() end
crate:Remove()
end
end)
end
function PLUGIN:Initialize()
self:SetupAirdropTimer()
self:SetupAirstrikeTimer()
end
function PLUGIN:SetupAirdropTimer()
local delay = math.random(ix.config.Get("airdropMinInterval", 3600), ix.config.Get("airdropMaxInterval", 7200))
timer.Create("ixAirdropTimer", delay, 1, function()
self:SpawnAirdrop()
self:SetupAirdropTimer()
end)
end
function PLUGIN:SetupAirstrikeTimer()
local delay = math.random(ix.config.Get("airstrikeMinInterval", 1800), ix.config.Get("airstrikeMaxInterval", 3600))
timer.Create("ixAirstrikeTimer", delay, 1, function()
self:SpawnAirstrike()
self:SetupAirstrikeTimer()
end)
end