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,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