#include <sourcemod>
#include <sdktools>
#pragma newdecls required
#pragma semicolon 1
#define MAX_BLOCKS 128
ConVar h_Block_min_player;
KeyValues kv_list;
char s_MapName[64];
int g_iEntities[MAX_BLOCKS];
int g_iEntCount = 0;
public Plugin myinfo = {
name = "Blocker passes (lite version)",
author = "Google AI",
version = "1"
};
public void OnPluginStart() {
h_Block_min_player = CreateConVar("sm_bp_minplayer", "10", "Мин. игроков для открытия");
HookEvent("round_start", OnRoundStart);
AutoExecConfig(true, "Blocker");
}
public void OnMapStart() {
GetCurrentMap(s_MapName, sizeof(s_MapName));
if (kv_list != null) delete kv_list;
kv_list = new KeyValues("blocker_passes");
char path[PLATFORM_MAX_PATH];
BuildPath(Path_SM, path, sizeof(path), "../../cfg/sourcemod/blocker_passes/%s.txt", s_MapName);
if (!FileExists(path)) CreateDust2Config(path);
if (!kv_list.ImportFromFile(path)) {
PrintToServer("[Blocker] Ошибка импорта конфига: %s", s_MapName);
}
g_iEntCount = 0;
}
public void OnRoundStart(Event event, const char[] name, bool dontBroadcast) {
// 1. Сначала всегда удаляем старые пропсы прошлого раунда
RemoveBlocks();
// 2. Проверяем количество игроков (люди + боты)
int clients = CountAllPlayers();
int limit = h_Block_min_player.IntValue;
// 3. Если игроков меньше лимита — ставим заграждения
if (clients < limit) {
PrintToServer("[Blocker] Раунд начался. Игроков: %d. Закрываем проходы.", clients);
SpawnBlocks();
} else {
PrintToServer("[Blocker] Раунд начался. Игроков: %d. Проходы открыты.", clients);
}
}
int CountAllPlayers() {
int count = 0;
for (int i = 1; i <= MaxClients; i++) {
if (IsClientInGame(i)) {
int team = GetClientTeam(i);
if (team == 2 || team == 3) count++;
}
}
return count;
}
void SpawnBlocks() {
if (kv_list == null || !kv_list.GotoFirstSubKey()) return;
g_iEntCount = 0;
do {
char Model[PLATFORM_MAX_PATH], sColor[32];
float pos[3], ang[3];
int color[4];
kv_list.GetVector("position", pos);
kv_list.GetVector("Angles", ang);
kv_list.GetString("Model", Model, sizeof(Model));
kv_list.GetString("Colors", sColor, sizeof(sColor), "255 255 255 255");
int ent = CreateEntityByName("prop_dynamic_override");
if (ent != -1) {
if (!IsModelPrecached(Model)) PrecacheModel(Model);
SetEntityModel(ent, Model);
DispatchKeyValue(ent, "Solid", "6");
DispatchSpawn(ent);
TeleportEntity(ent, pos, ang, NULL_VECTOR);
if (StringToColor(sColor, color)) {
SetEntityRenderColor(ent, color[0], color[1], color[2], color[3]);
SetEntityRenderMode(ent, RENDER_TRANSCOLOR);
}
if (g_iEntCount < MAX_BLOCKS) {
g_iEntities[g_iEntCount++] = EntIndexToEntRef(ent);
}
}
} while (kv_list.GotoNextKey());
kv_list.Rewind();
}
void RemoveBlocks() {
for (int i = 0; i < g_iEntCount; i++) {
int ent = EntRefToEntIndex(g_iEntities[i]);
if (ent != INVALID_ENT_REFERENCE && IsValidEntity(ent)) {
AcceptEntityInput(ent, "Kill");
}
}
g_iEntCount = 0;
}
bool StringToColor(const char[] str, int color[4]) {
char s[4][16];
if (ExplodeString(str, " ", s, 4, 16) == 4) {
for(int i=0; i<4; i++) color[i] = StringToInt(s[i]);
return true;
}
return false;
}
void CreateDust2Config(const char[] path) {
char dir[PLATFORM_MAX_PATH];
BuildPath(Path_SM, dir, sizeof(dir), "../../cfg/sourcemod/blocker_passes/");
if (!DirExists(dir)) CreateDirectory(dir, 511);
File hFile = OpenFile(path, "w");
if (hFile != null) {
hFile.WriteLine("\"blocker_passes\"\n{");
WriteEntry(hFile, "1", "-527.55 1375.84 -111.96", "540.0 180.0 270.0", "models/props_c17/fence03a.mdl");
WriteEntry(hFile, "2", "-527.44 1473.13 -111.96", "540.0 180.0 90.0", "models/props_c17/fence03a.mdl");
WriteEntry(hFile, "3", "-1232.98 -847.13 178.92", "540.0 180.0 0.0", "models/props_c17/fence03a.mdl");
WriteEntry(hFile, "4", "-1234.24 -847.79 273.46", "360.0 180.0 0.0", "models/props_c17/fence03a.mdl");
WriteEntry(hFile, "5", "-1233.79 -718.87 273.45", "0.0 180.0 0.0", "models/props_c17/fence03a.mdl");
WriteEntry(hFile, "6", "-1232.87 -718.31 178.26", "180.0 180.0 0.0", "models/props_c17/fence03a.mdl");
WriteEntry(hFile, "7", "-1102.90 -591.73 273.06", "0.0 90.0 0.0", "models/props_c17/fence03a.mdl");
WriteEntry(hFile, "8", "-1102.19 -591.72 177.39", "180.0 450.0 0.0", "models/props_c17/fence03a.mdl");
WriteEntry(hFile, "9", "-243.93 2112.18 -72.85", "180.0 180.0 0.0", "models/props_c17/fence03a.mdl");
WriteEntry(hFile, "10", "-245.29 2240.18 -73.41", "180.0 180.0 0.0", "models/props_c17/fence03a.mdl");
WriteEntry(hFile, "11", "-406.36 1638.58 -78.14", "539.15 335.14 90.0", "models/props_c17/fence03a.mdl");
hFile.WriteLine("}");
delete hFile;
}
}
void WriteEntry(File file, const char[] id, const char[] pos, const char[] ang, const char[] model) {
file.WriteLine(" \"%s\"\n {\n \"position\" \"%s\"\n \"Angles\" \"%s\"\n \"Model\" \"%s\"\n \"Colors\" \"255 255 255 255\"\n \"UnLockNnm\" \"10\"\n }", id, pos, ang, model);
}