Files
2026-03-31 10:27:04 +03:00

185 lines
6.0 KiB
Lua
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
DoomsdayNight = DoomsdayNight or {}
DoomsdayNight.active = false
DoomsdayNight.start_time = 0
DoomsdayNight.participants = {}
DoomsdayNight.spectators = {}
DoomsdayNight.spawn_positions = {}
DoomsdayNight.weapons = {
"tfa_ins2_ak74", "tfa_ins2_m4a1", "tfa_ins2_ak12", "tfa_ins2_m16a4", "tfa_ins2_scar_h_ssr",
"tfa_ins2_m40a1", "tfa_ins2_mosin", "tfa_ins2_svd", "tfa_ins2_m590", "tfa_ins2_toz",
"tfa_ins2_glock_17", "tfa_ins2_m9", "tfa_ins2_makarov", "tfa_ins2_mp5", "tfa_ins2_ump45", "tfa_ins2_mp40"
}
util.AddNetworkString("doomsday_night_notification")
util.AddNetworkString("doomsday_night_hud_update")
function DoomsdayNight:Init()
SetGlobalBool("doomsday_night_active", false)
SetGlobalInt("doomsday_night_start_time", 0)
SetGlobalInt("doomsday_night_alive_count", 0)
self:GenerateSpawnPositions()
end
function DoomsdayNight:GenerateSpawnPositions()
local map = game.GetMap()
local map_positions = {
["gm_construct"] = {
Vector(980, -1500, -79), Vector(-700, 1000, 200), Vector(1500, 800, 100), Vector(-1200, -800, 50)
},
["rp_valkyrie_forest_v1"] = {
Vector(5000, 3000, 200), Vector(-5000, -3000, 150), Vector(8000, -2000, 100), Vector(-8000, 2000, 180)
}
}
self.spawn_positions = map_positions[map] or { Vector(1000, 1000, 100), Vector(-1000, -1000, 100) }
end
function DoomsdayNight:StartEvent(ply)
local players = player.GetAll()
if (#players < 2) then
ply:Notify("Недостаточно игроков для начала Судной Ночи!")
return
end
self.active = true
self.start_time = CurTime()
self.participants = {}
self.spectators = {}
SetGlobalBool("doomsday_night_active", true)
SetGlobalInt("doomsday_night_start_time", CurTime())
for _, player in ipairs(players) do
if (IsValid(player)) then self:PreparePlayer(player) end
end
self:BroadcastMessage("🌙 СУДНАЯ НОЧЬ НАЧАЛАСЬ! 🌙\nСражайтесь до последнего выжившего!\nВыдано случайное оружие.")
timer.Simple(3, function() if (self.active) then self:TeleportPlayers() end end)
self:UpdateHUD()
end
function DoomsdayNight:PreparePlayer(ply)
local steamid = ply:SteamID()
self.participants[steamid] = {
start_pos = ply:GetPos(),
join_time = CurTime(),
kills = 0,
nick = ply:Nick(),
alive = true
}
ply:StripWeapons()
self:GiveRandomWeapons(ply)
end
function DoomsdayNight:GiveRandomWeapons(ply)
if (!IsValid(ply) or !ply:Alive()) then return end
ply:Give("ix_hands")
local weapons_to_give = {}
local used = {}
for i = 1, math.random(2, 3) do
local w = self.weapons[math.random(1, #self.weapons)]
if (!used[w]) then
used[w] = true
table.insert(weapons_to_give, w)
end
end
for _, w_class in ipairs(weapons_to_give) do
local weapon = ply:Give(w_class)
if (IsValid(weapon)) then
ply:GiveAmmo(500, weapon:GetPrimaryAmmoType(), true)
end
end
ply:Give("weapon_frag")
ply:GiveAmmo(2, "Grenade", true)
ply:SetHealth(100)
ply:SetArmor(100)
end
function DoomsdayNight:TeleportPlayers()
local players = {}
for steamid, data in pairs(self.participants) do
local ply = player.GetBySteamID(steamid)
if (IsValid(ply)) then table.insert(players, ply) end
end
local positions = table.Copy(self.spawn_positions)
for i, ply in ipairs(players) do
local spawn_pos = positions[((i - 1) % #positions) + 1]
ply:SetPos(spawn_pos)
ply:SetEyeAngles(Angle(0, math.random(0, 360), 0))
end
SetGlobalInt("doomsday_night_alive_count", #players)
self:BroadcastMessage("⚡ Игроки телепортированы! К БОЮ!")
end
function DoomsdayNight:EndEvent(ply, cancelled)
if (!self.active) then return end
self.active = false
SetGlobalBool("doomsday_night_active", false)
for steamid, _ in pairs(self.spectators) do
local spec_ply = player.GetBySteamID(steamid)
if (IsValid(spec_ply)) then
spec_ply:UnSpectate()
spec_ply:Spawn()
end
end
self:BroadcastMessage(cancelled and "🛑 СУДНАЯ НОЧЬ ОТМЕНЕНА" or "🏆 СУДНАЯ НОЧЬ ЗАВЕРШЕНА")
self.participants = {}
self.spectators = {}
self:UpdateHUD()
end
function DoomsdayNight:OnPlayerKilled(victim, attacker)
if (!self.active) then return end
local data = self.participants[victim:SteamID()]
if (!data) then return end
data.alive = false
if (IsValid(attacker) and attacker:IsPlayer()) then
local attacker_data = self.participants[attacker:SteamID()]
if (attacker_data) then attacker_data.kills = attacker_data.kills + 1 end
end
timer.Simple(2, function()
if (IsValid(victim)) then
self.spectators[victim:SteamID()] = true
victim:Spectate(OBS_MODE_ROAMING)
victim:Notify("👁️ Вы перешли в режим наблюдения до конца ивента.")
end
end)
local alive_count = 0
for _, d in pairs(self.participants) do
if (d.alive) then alive_count = alive_count + 1 end
end
SetGlobalInt("doomsday_night_alive_count", alive_count)
if (alive_count <= 1) then
timer.Simple(3, function() if (self.active) then self:EndEvent() end end)
end
end
function DoomsdayNight:BroadcastMessage(msg)
for _, ply in ipairs(player.GetAll()) do ply:ChatPrint(msg) end
end
function DoomsdayNight:UpdateHUD()
net.Start("doomsday_night_hud_update")
net.WriteBool(self.active)
net.WriteInt(self.start_time, 32)
net.Broadcast()
end
-- Hook aliases for PLUGIN
function PLUGIN:DoomsdayNight_Init() DoomsdayNight:Init() end
function PLUGIN:DoomsdayNight_PlayerDeath(victim, inflictor, attacker) DoomsdayNight:OnPlayerKilled(victim, attacker) end
hook.Add("InitPostEntity", "DoomsdayNight_Init", function() DoomsdayNight:Init() end)