shuoumaaa423
Участник
- Сообщения
- 1
- Реакции
- 0
Так же интересуют и другие полезные плагины для cw/mix сервера.
Исходник можно?Держи,тестируй. Не все допилено - но вроде работает)
Основные функции для игроков
1. Система сбора игроков
Автоматическая готовность при входе на сервер
Ручная готовность через !ready или !r
Снятие готовности через !unready или !ur
Счётчик игроков в hostname: [Ожидание 5] CSrating | Mix server
2. Выбор команд
Автоматический выбор 2 капитанов из готовых игроков
Капитаны по очереди выбирают игроков в команды
Меню выбора с никами игроков (нельзя выбрать себя)
Для режима 1v1 - автоматическое распределение без выбора
3. Управление матчем
!pause - поставить паузу (2 на команду)
!unpause - снять паузу
!sub - запросить замену (капитан выбирает замену из спектров)
!score - показать текущий счёт
!match - информация о матче
4. Меню команд
!menu или !help - открывает главное меню
Быстрый доступ ко всем функциям
Админские команды в меню (только для админов)
Настройки матча (для админов)
Форматы игры:
1v1 (2 игрока) - без выбора капитанов, авто-старт
2v2 (4 игрока)
3v3 (6 игроков)
5v5 (10 игроков) - по умолчанию
Форматы раундов:
MR9 (18 раундов)
MR12 (24 раунда)
MR15 (30 раундов) - по умолчанию
Админские команды:
sm_start - принудительный старт матча
sm_restart - рестарт матча
sm_cancel - отмена матча
sm_setscore <CT> <T> - установить счёт
sm_forcepause - принудительная пауза
sm_matchsettings - меню настроек матча
Автоматические функции
1. Управление AllTalk
Лобби/сбор: sv_alltalk 1 (все слышат всех)
Матч: sv_alltalk 0 (только своя команда)
Конец матча: sv_alltalk 1 (возврат)
2. Смена сторон
Автоматическая смена сторон после первого перерыва (MR15 - после 15 раундов)
Используется mp_switchteams 1
3. Овертайм
Автоматический запуск при ничьей после основных раундов
6 раундов за один овертайм (настраивается)
4. Автоотмена матча
1v1: если игрок вышел - матч сразу отменяется
Другие режимы: если осталось меньше 70% игроков - матч отменяется
5. Голосование за карту
Запускается автоматически через 10 секунд после окончания матча
Использует mapchooser.smx если установлен
Иначе - встроенное меню голосования
Реклама и уведомления
Система рекламы:
Настраиваемая реклама в чате
Интервал: 60 секунд между сообщениями
Цвета: {red}, {lightgreen}, {default}
Конфиг: csrating_adverts.cfg
Уведомления:
Приветствие новым игрокам с подсказкой !menu
Сообщения о готовности игроков
Сообщения о выборе капитанов и игроков
Предупреждения о паузах, заменах
Информация о победителе в конце матча
Меньше настроек и гемора. Делал для себя- так что не принуждаю использоватьИсходник можно?
И для чего делать прототип вармикса
/**
* CSrating Match Plugin для CS:Source
* Версия: 3.3 - РУССКИЙ ЯЗЫК CS:S
*/
#include <sourcemod>
#include <sdktools>
#include <cstrike>
#pragma semicolon 1
#define PLUGIN_VERSION "3.3.0"
#define MAX_ADVERTS 50
enum MatchState
{
STATE_LOBBY = 0,
STATE_CAPTAIN_PICK,
STATE_PLAYER_PICK,
STATE_LIVE,
STATE_HALFTIME,
STATE_OVERTIME,
STATE_FINISHED
}
new MatchState:g_iMatchState;
new g_iCTScore;
new g_iTScore;
new g_iCurrentRound;
new g_iOvertimeCount;
new g_iCaptainTeam;
new g_iPickOrder;
new g_iPlayersReady;
new g_iPauseCount[2];
new bool:g_bIsPaused;
new bool:g_bPlayerReady[MAXPLAYERS + 1];
new g_iPlayerTeam[MAXPLAYERS + 1];
new g_iCaptains[2];
new g_iTeamSize[2];
new g_iSubRequests[MAXPLAYERS + 1];
char g_sOriginalHostname[256];
new g_iMatchAdmin;
new g_iAdvertCount;
new g_iCurrentAdvert;
char g_sAdvertText[MAX_ADVERTS][256];
new Handle:g_hDatabase;
new g_iMaxRounds;
new g_iRoundsPerHalf;
new g_iOvertimeRounds;
new g_iPlayersPerTeam;
public Plugin:myinfo =
{
name = "CSrating Match System",
author = "CSrating.ru",
description = "Система матчмейкинга для CS:Source",
version = PLUGIN_VERSION,
url = "https://csrating.ru"
};
public OnPluginStart()
{
RegConsoleCmd("sm_ready", Command_Ready, "Готовность");
RegConsoleCmd("sm_r", Command_Ready, "Готовность");
RegConsoleCmd("sm_unready", Command_Unready, "Не готов");
RegConsoleCmd("sm_ur", Command_Unready, "Не готов");
RegConsoleCmd("sm_pause", Command_Pause, "Пауза");
RegConsoleCmd("sm_unpause", Command_Unpause, "Снять паузу");
RegConsoleCmd("sm_score", Command_Score, "Счет");
RegConsoleCmd("sm_sub", Command_Sub, "Замена");
RegConsoleCmd("sm_match", Command_MatchInfo, "Инфо");
RegConsoleCmd("sm_menu", Command_Menu, "Меню");
RegConsoleCmd("sm_help", Command_Menu, "Помощь");
RegAdminCmd("sm_start", Command_Start, ADMFLAG_GENERIC, "Старт");
RegAdminCmd("sm_restart", Command_Restart, ADMFLAG_GENERIC, "Рестарт");
RegAdminCmd("sm_setscore", Command_SetScore, ADMFLAG_GENERIC, "Счет");
RegAdminCmd("sm_forcepause", Command_ForcePause, ADMFLAG_GENERIC, "Пауза");
RegAdminCmd("sm_cancel", Command_Cancel, ADMFLAG_GENERIC, "Отмена");
RegAdminCmd("sm_matchsettings", Command_MatchSettings, ADMFLAG_GENERIC, "Настройки");
AutoExecConfig(true, "csrating_match");
ServerCommand("sv_timeout 65");
ServerCommand("sv_kick_bots 0");
ConnectToDatabase();
LoadAdverts();
char hostname[256];
ConVar cvHostname = FindConVar("hostname");
if (cvHostname != null)
{
GetConVarString(cvHostname, hostname, sizeof(hostname));
if (strlen(hostname) > 0)
{
strcopy(g_sOriginalHostname, sizeof(g_sOriginalHostname), hostname);
}
else
{
strcopy(g_sOriginalHostname, sizeof(g_sOriginalHostname), "CSrating Server");
}
}
HookEvent("player_disconnect", Event_PlayerDisconnect);
HookEvent("round_start", Event_RoundStart);
HookEvent("round_end", Event_RoundEnd);
g_iMatchState = STATE_LOBBY;
g_iCTScore = 0;
g_iTScore = 0;
g_iCurrentRound = 0;
g_iOvertimeCount = 0;
g_iPlayersReady = 0;
g_bIsPaused = false;
g_iTeamSize[0] = 0;
g_iTeamSize[1] = 0;
g_iMatchAdmin = 0;
LoadConfig();
CountPlayers();
UpdateServerHostname();
if (g_iAdvertCount > 0)
{
CreateTimer(60.0, Timer_ShowAdvert, _, TIMER_REPEAT);
}
PrintToServer("[CSrating] Плагин загружен! Версия %s", PLUGIN_VERSION);
}
public OnPluginEnd()
{
ConVar cvHostname = FindConVar("hostname");
if (cvHostname != null)
{
SetConVarString(cvHostname, g_sOriginalHostname);
}
ConVar cvAlltalk = FindConVar("sv_alltalk");
if (cvAlltalk != null)
{
SetConVarInt(cvAlltalk, 0);
}
}
public OnMapStart()
{
g_iMatchState = STATE_LOBBY;
g_iCTScore = 0;
g_iTScore = 0;
g_iCurrentRound = 0;
g_iOvertimeCount = 0;
g_iPlayersReady = 0;
g_bIsPaused = false;
g_iTeamSize[0] = 0;
g_iTeamSize[1] = 0;
g_iMatchAdmin = 0;
for (new i = 1; i <= MaxClients; i++)
{
g_bPlayerReady[i] = false;
g_iPlayerTeam[i] = 0;
g_iSubRequests[i] = 0;
}
CreateTimer(2.0, Timer_CountPlayers);
CreateTimer(5.0, Timer_RemoveFog);
SetAllTalk(true);
}
public Action:Timer_RemoveFog(Handle:timer)
{
RemoveFogFromMap();
return Plugin_Stop;
}
RemoveFogFromMap()
{
new ent = -1;
while ((ent = FindEntityByClassname(ent, "env_fog_controller")) != -1)
{
if (IsValidEntity(ent))
{
AcceptEntityInput(ent, "TurnOff");
}
}
ent = -1;
while ((ent = FindEntityByClassname(ent, "env_smokestack")) != -1)
{
if (IsValidEntity(ent))
{
AcceptEntityInput(ent, "TurnOff");
}
}
}
public OnClientPostAdminCheck(client)
{
if (IsFakeClient(client)) return;
if (CheckCommandAccess(client, "sm_start", ADMFLAG_GENERIC, false))
{
if (g_iMatchAdmin == 0 || !IsClientInGame(g_iMatchAdmin))
{
g_iMatchAdmin = client;
PrintToChat(client, "\x04[CSrating] \x01Вы управляете матчем! Используйте \x03!menu\x01.");
PrintToChatAll("\x04[CSrating] \x01Админ \x03%N \x01управляет матчем!", client);
}
}
if (g_iMatchState == STATE_LOBBY && !g_bPlayerReady[client])
{
g_bPlayerReady[client] = true;
g_iPlayersReady++;
PrintToChatAll("\x04[CSrating] \x03%N \x01готов! (\x02%d/%d\x01)",
client, g_iPlayersReady, g_iPlayersPerTeam * 2);
UpdateServerHostname();
if (g_iPlayersReady >= g_iPlayersPerTeam * 2)
{
CreateTimer(3.0, Timer_StartCaptainPick);
}
}
}
public OnClientDisconnect(client)
{
if (IsFakeClient(client)) return;
if (client == g_iMatchAdmin)
{
g_iMatchAdmin = 0;
FindNewMatchAdmin();
}
if (g_bPlayerReady[client])
{
g_bPlayerReady[client] = false;
g_iPlayersReady--;
if (g_iPlayersReady < 0) g_iPlayersReady = 0;
}
if (g_iMatchState == STATE_LIVE || g_iMatchState == STATE_OVERTIME)
{
if (g_iPlayerTeam[client] > 0)
{
new playersInTeams = 0;
for (new i = 1; i <= MaxClients; i++)
{
if (IsClientInGame(i) && !IsFakeClient(i) && g_iPlayerTeam[i] > 0)
{
playersInTeams++;
}
}
new totalNeeded = g_iPlayersPerTeam * 2;
new minPlayers = RoundToCeil(Float:totalNeeded * 0.7);
if (g_iPlayersPerTeam == 1)
{
PrintToChatAll("\x04[CSrating] \x01Игрок вышел! Матч отменен!");
ResetMatch();
return;
}
if (playersInTeams < minPlayers)
{
PrintToChatAll("\x04[CSrating] \x01Слишком много игроков вышло! Матч отменен!");
ResetMatch();
return;
}
}
}
g_iPlayerTeam[client] = 0;
g_iSubRequests[client] = 0;
UpdateServerHostname();
}
FindNewMatchAdmin()
{
for (new i = 1; i <= MaxClients; i++)
{
if (IsClientInGame(i) && !IsFakeClient(i))
{
if (CheckCommandAccess(i, "sm_start", ADMFLAG_GENERIC, false))
{
g_iMatchAdmin = i;
PrintToChatAll("\x04[CSrating] \x01Админ \x03%N \x01управляет!", i);
return;
}
}
}
}
CountPlayers()
{
g_iPlayersReady = 0;
for (new i = 1; i <= MaxClients; i++)
{
if (IsClientInGame(i) && !IsFakeClient(i) && IsClientConnected(i))
{
g_bPlayerReady[i] = true;
g_iPlayersReady++;
}
}
UpdateServerHostname();
}
public Action:Timer_CountPlayers(Handle:timer)
{
CountPlayers();
return Plugin_Stop;
}
public ConnectToDatabase()
{
if (SQL_CheckConfig("sourcebans"))
{
char error[256];
g_hDatabase = SQL_Connect("sourcebans", true, error, sizeof(error));
if (g_hDatabase == INVALID_HANDLE)
{
LogError("[CSrating] Ошибка БД: %s", error);
}
}
}
LoadAdverts()
{
g_iAdvertCount = 0;
char configPath[256];
BuildPath(Path_SM, configPath, sizeof(configPath), "configs/csrating_adverts.cfg");
if (!FileExists(configPath))
{
PrintToServer("[CSrating] Конфиг рекламы не найден!");
return;
}
new Handle:kv = CreateKeyValues("Adverts");
FileToKeyValues(kv, configPath);
if (KvGotoFirstSubKey(kv))
{
do
{
if (g_iAdvertCount >= MAX_ADVERTS) break;
char text[256];
KvGetString(kv, "text", text, sizeof(text), "");
if (strlen(text) > 0)
{
strcopy(g_sAdvertText[g_iAdvertCount], 256, text);
g_iAdvertCount++;
}
}
while (KvGotoNextKey(kv));
}
CloseHandle(kv);
PrintToServer("[CSrating] Загружено %d реклам", g_iAdvertCount);
}
// ИСПРАВЛЕНО: цвета для CS:S
public Action:Timer_ShowAdvert(Handle:timer)
{
if (g_iAdvertCount == 0) return Plugin_Continue;
if (g_iCurrentAdvert >= g_iAdvertCount)
{
g_iCurrentAdvert = 0;
}
char advert[256];
strcopy(advert, sizeof(advert), g_sAdvertText[g_iCurrentAdvert]);
// ЦВЕТА CS:SOURCE:
// \x01 = обычный (серый)
// \x02 = зеленый
// \x03 = желтый (ник игрока)
// \x04 = зеленый (olive)
// КРАСНОГО ЦВЕТА НЕТ в CS:S через чат!
ReplaceString(advert, sizeof(advert), "{red}", "\x04");
ReplaceString(advert, sizeof(advert), "{default}", "\x01");
ReplaceString(advert, sizeof(advert), "{lightgreen}", "\x04");
ReplaceString(advert, sizeof(advert), "{green}", "\x04");
ReplaceString(advert, sizeof(advert), "{olive}", "\x04");
ReplaceString(advert, sizeof(advert), "{teamcolor}", "\x03");
PrintToChatAll("%s", advert);
g_iCurrentAdvert++;
return Plugin_Continue;
}
LoadConfig()
{
char configPath[256];
BuildPath(Path_SM, configPath, sizeof(configPath), "configs/csrating_match.cfg");
if (FileExists(configPath))
{
new Handle:kv = CreateKeyValues("CSratingMatch");
FileToKeyValues(kv, configPath);
char configHostname[256];
KvGetString(kv, "Hostname", configHostname, sizeof(configHostname), "");
g_iMaxRounds = KvGetNum(kv, "MaxRounds", 30);
g_iRoundsPerHalf = KvGetNum(kv, "RoundsPerHalf", 15);
g_iOvertimeRounds = KvGetNum(kv, "OvertimeRounds", 6);
g_iPlayersPerTeam = KvGetNum(kv, "PlayersPerTeam", 5);
CloseHandle(kv);
if (strlen(configHostname) > 0)
{
strcopy(g_sOriginalHostname, sizeof(g_sOriginalHostname), configHostname);
}
}
else
{
g_iMaxRounds = 30;
g_iRoundsPerHalf = 15;
g_iOvertimeRounds = 6;
g_iPlayersPerTeam = 5;
strcopy(g_sOriginalHostname, sizeof(g_sOriginalHostname), "CSrating Server");
}
}
SetAllTalk(bool:enable)
{
ConVar cvAlltalk = FindConVar("sv_alltalk");
if (cvAlltalk != null)
{
SetConVarInt(cvAlltalk, enable ? 1 : 0);
}
}
UpdateServerHostname()
{
char hostname[256];
switch (g_iMatchState)
{
case STATE_LOBBY:
{
new remaining = (g_iPlayersPerTeam * 2) - g_iPlayersReady;
if (remaining < 0) remaining = 0;
Format(hostname, sizeof(hostname), "%s [Ожидание %d]", g_sOriginalHostname, remaining);
}
case STATE_CAPTAIN_PICK, STATE_PLAYER_PICK:
{
Format(hostname, sizeof(hostname), "%s [Выбор]", g_sOriginalHostname);
}
case STATE_LIVE, STATE_HALFTIME:
{
Format(hostname, sizeof(hostname), "[CT %d - %d T] %s", g_iCTScore, g_iTScore, g_sOriginalHostname);
}
case STATE_OVERTIME:
{
Format(hostname, sizeof(hostname), "[OT %d - %d] %s", g_iCTScore, g_iTScore, g_sOriginalHostname);
}
case STATE_FINISHED:
{
Format(hostname, sizeof(hostname), "[Завершен %d:%d] %s", g_iCTScore, g_iTScore, g_sOriginalHostname);
}
}
ConVar cvHostname = FindConVar("hostname");
if (cvHostname != null)
{
SetConVarString(cvHostname, hostname);
}
}
public Action:Command_Menu(client, args)
{
if (client == 0) return Plugin_Handled;
ShowMainMenu(client);
return Plugin_Handled;
}
public Action:Command_MatchSettings(client, args)
{
if (client == 0) return Plugin_Handled;
if (!CheckCommandAccess(client, "sm_start", ADMFLAG_GENERIC, false))
{
PrintToChat(client, "\x04[CSrating] \x01Нет доступа!");
return Plugin_Handled;
}
ShowMatchSettingsMenu(client);
return Plugin_Handled;
}
ShowMainMenu(client)
{
new Handle:menu = CreateMenu(MenuHandler_MainMenu);
char title[128];
Format(title, sizeof(title), "CSrating Match\nВерсия: %s", PLUGIN_VERSION);
SetMenuTitle(menu, title);
if (g_iMatchState == STATE_LOBBY)
{
if (g_bPlayerReady[client])
{
AddMenuItem(menu, "unready", "Не готов");
}
else
{
AddMenuItem(menu, "ready", "Готов");
}
}
AddMenuItem(menu, "score", "Счет");
AddMenuItem(menu, "match", "Инфо о матче");
if (g_iMatchState == STATE_LIVE)
{
AddMenuItem(menu, "pause", "Пауза");
AddMenuItem(menu, "unpause", "Снять паузу");
AddMenuItem(menu, "sub", "Замена");
}
if (CheckCommandAccess(client, "sm_start", ADMFLAG_GENERIC, false))
{
AddMenuItem(menu, "", "----- Админ -----", ITEMDRAW_DISABLED);
AddMenuItem(menu, "settings", "Настройки матча");
if (g_iMatchState == STATE_LOBBY)
{
AddMenuItem(menu, "admin_start", "Принуд. старт");
}
AddMenuItem(menu, "admin_restart", "Рестарт");
AddMenuItem(menu, "admin_cancel", "Отмена");
}
SetMenuExitButton(menu, true);
DisplayMenu(menu, client, MENU_TIME_FOREVER);
}
ShowMatchSettingsMenu(client)
{
new Handle:menu = CreateMenu(MenuHandler_MatchSettings);
char title[128];
Format(title, sizeof(title), "Настройки матча\nТекущие: MR%d | %dv%d",
g_iMaxRounds / 2, g_iPlayersPerTeam, g_iPlayersPerTeam);
SetMenuTitle(menu, title);
AddMenuItem(menu, "rounds_mr15", "Раунды: MR15 (30)");
AddMenuItem(menu, "rounds_mr12", "Раунды: MR12 (24)");
AddMenuItem(menu, "rounds_mr9", "Раунды: MR9 (18)");
AddMenuItem(menu, "players_1v1", "Игроки: 1v1 (2)");
AddMenuItem(menu, "players_2v2", "Игроки: 2v2 (4)");
AddMenuItem(menu, "players_3v3", "Игроки: 3v3 (6)");
AddMenuItem(menu, "players_5v5", "Игроки: 5v5 (10)");
SetMenuExitButton(menu, true);
DisplayMenu(menu, client, MENU_TIME_FOREVER);
}
public MenuHandler_MainMenu(Handle:menu, MenuAction:action, param1, param2)
{
if (action == MenuAction_Select)
{
char info[32];
GetMenuItem(menu, param2, info, sizeof(info));
if (StrEqual(info, "ready"))
{
FakeClientCommand(param1, "sm_ready");
CreateTimer(0.5, Timer_ReopenMenu, GetClientUserId(param1));
}
else if (StrEqual(info, "unready"))
{
FakeClientCommand(param1, "sm_unready");
CreateTimer(0.5, Timer_ReopenMenu, GetClientUserId(param1));
}
else if (StrEqual(info, "score"))
{
FakeClientCommand(param1, "sm_score");
CreateTimer(0.5, Timer_ReopenMenu, GetClientUserId(param1));
}
else if (StrEqual(info, "match"))
{
FakeClientCommand(param1, "sm_match");
CreateTimer(0.5, Timer_ReopenMenu, GetClientUserId(param1));
}
else if (StrEqual(info, "pause"))
{
FakeClientCommand(param1, "sm_pause");
}
else if (StrEqual(info, "unpause"))
{
FakeClientCommand(param1, "sm_unpause");
}
else if (StrEqual(info, "sub"))
{
FakeClientCommand(param1, "sm_sub");
}
else if (StrEqual(info, "settings"))
{
ShowMatchSettingsMenu(param1);
}
else if (StrEqual(info, "admin_start"))
{
FakeClientCommand(param1, "sm_start");
}
else if (StrEqual(info, "admin_restart"))
{
FakeClientCommand(param1, "sm_restart");
}
else if (StrEqual(info, "admin_cancel"))
{
FakeClientCommand(param1, "sm_cancel");
}
}
else if (action == MenuAction_End)
{
CloseHandle(menu);
}
return 0;
}
public MenuHandler_MatchSettings(Handle:menu, MenuAction:action, param1, param2)
{
if (action == MenuAction_Select)
{
char info[32];
GetMenuItem(menu, param2, info, sizeof(info));
if (StrEqual(info, "rounds_mr15"))
{
g_iMaxRounds = 30;
g_iRoundsPerHalf = 15;
PrintToChatAll("\x04[CSrating] \x01Админ \x03%N \x01установил: MR15", param1);
}
else if (StrEqual(info, "rounds_mr12"))
{
g_iMaxRounds = 24;
g_iRoundsPerHalf = 12;
PrintToChatAll("\x04[CSrating] \x01Админ \x03%N \x01установил: MR12", param1);
}
else if (StrEqual(info, "rounds_mr9"))
{
g_iMaxRounds = 18;
g_iRoundsPerHalf = 9;
PrintToChatAll("\x04[CSrating] \x01Админ \x03%N \x01установил: MR9", param1);
}
else if (StrEqual(info, "players_1v1"))
{
g_iPlayersPerTeam = 1;
PrintToChatAll("\x04[CSrating] \x01Админ \x03%N \x01установил: 1v1", param1);
UpdateServerHostname();
}
else if (StrEqual(info, "players_2v2"))
{
g_iPlayersPerTeam = 2;
PrintToChatAll("\x04[CSrating] \x01Админ \x03%N \x01установил: 2v2", param1);
UpdateServerHostname();
}
else if (StrEqual(info, "players_3v3"))
{
g_iPlayersPerTeam = 3;
PrintToChatAll("\x04[CSrating] \x01Админ \x03%N \x01установил: 3v3", param1);
UpdateServerHostname();
}
else if (StrEqual(info, "players_5v5"))
{
g_iPlayersPerTeam = 5;
PrintToChatAll("\x04[CSrating] \x01Админ \x03%N \x01установил: 5v5", param1);
UpdateServerHostname();
}
CreateTimer(0.5, Timer_ReopenMenu, GetClientUserId(param1));
}
else if (action == MenuAction_End)
{
CloseHandle(menu);
}
return 0;
}
public Action:Timer_ReopenMenu(Handle:timer, any:userid)
{
new client = GetClientOfUserId(userid);
if (client > 0 && IsClientInGame(client))
{
ShowMainMenu(client);
}
return Plugin_Stop;
}
public Action:Command_Ready(client, args)
{
if (g_iMatchState != STATE_LOBBY)
{
PrintToChat(client, "\x04[CSrating] \x01Матч уже начался!");
return Plugin_Handled;
}
if (!g_bPlayerReady[client])
{
g_bPlayerReady[client] = true;
g_iPlayersReady++;
PrintToChatAll("\x04[CSrating] \x03%N \x01готов! (\x02%d/%d\x01)",
client, g_iPlayersReady, g_iPlayersPerTeam * 2);
UpdateServerHostname();
if (g_iPlayersReady >= g_iPlayersPerTeam * 2)
{
CreateTimer(3.0, Timer_StartCaptainPick);
}
}
else
{
PrintToChat(client, "\x04[CSrating] \x01Вы уже готовы!");
}
return Plugin_Handled;
}
public Action:Command_Unready(client, args)
{
if (g_iMatchState != STATE_LOBBY)
{
PrintToChat(client, "\x04[CSrating] \x01Матч уже начался!");
return Plugin_Handled;
}
if (g_bPlayerReady[client])
{
g_bPlayerReady[client] = false;
g_iPlayersReady--;
if (g_iPlayersReady < 0) g_iPlayersReady = 0;
PrintToChatAll("\x04[CSrating] \x03%N \x01не готов! (\x02%d/%d\x01)",
client, g_iPlayersReady, g_iPlayersPerTeam * 2);
UpdateServerHostname();
}
else
{
PrintToChat(client, "\x04[CSrating] \x01Вы и так не готовы!");
}
return Plugin_Handled;
}
public Action:Command_Pause(client, args)
{
if (g_iMatchState != STATE_LIVE)
{
PrintToChat(client, "\x04[CSrating] \x01Матч не идет!");
return Plugin_Handled;
}
new team = GetClientTeam(client);
new teamIndex = (team == CS_TEAM_CT) ? 0 : 1;
if (g_iPauseCount[teamIndex] >= 2)
{
PrintToChat(client, "\x04[CSrating] \x01Нет пауз!");
return Plugin_Handled;
}
if (g_bIsPaused)
{
PrintToChat(client, "\x04[CSrating] \x01Уже на паузе!");
return Plugin_Handled;
}
g_bIsPaused = true;
g_iPauseCount[teamIndex]++;
ServerCommand("mp_pause_match");
PrintToChatAll("\x04[CSrating] \x03%N \x01поставил паузу! (\x02%d/2\x01 осталось)",
client, g_iPauseCount[teamIndex]);
return Plugin_Handled;
}
public Action:Command_Unpause(client, args)
{
if (!g_bIsPaused)
{
PrintToChat(client, "\x04[CSrating] \x01Не на паузе!");
return Plugin_Handled;
}
g_bIsPaused = false;
ServerCommand("mp_unpause_match");
PrintToChatAll("\x04[CSrating] \x03%N \x01снял паузу!", client);
return Plugin_Handled;
}
public Action:Command_Score(client, args)
{
PrintToChat(client, "\x04[CSrating] \x01Счет: \x03CT %d - %d T\x01 | Раунд: \x02%d/%d",
g_iCTScore, g_iTScore, g_iCurrentRound, g_iMaxRounds);
return Plugin_Handled;
}
public Action:Command_Sub(client, args)
{
if (g_iMatchState != STATE_LIVE)
{
PrintToChat(client, "\x04[CSrating] \x01Только во время матча!");
return Plugin_Handled;
}
if (g_iPlayerTeam[client] == 0)
{
PrintToChat(client, "\x04[CSrating] \x01Не в команде!");
return Plugin_Handled;
}
g_iSubRequests[client] = 1;
PrintToChatAll("\x04[CSrating] \x03%N \x01запросил замену!", client);
ShowSubMenuToCaptain(client);
return Plugin_Handled;
}
public Action:Command_MatchInfo(client, args)
{
char stateName[64];
switch (g_iMatchState)
{
case STATE_LOBBY: strcopy(stateName, sizeof(stateName), "Лобби");
case STATE_CAPTAIN_PICK: strcopy(stateName, sizeof(stateName), "Выбор капитанов");
case STATE_PLAYER_PICK: strcopy(stateName, sizeof(stateName), "Набор команд");
case STATE_LIVE: strcopy(stateName, sizeof(stateName), "Матч");
case STATE_HALFTIME: strcopy(stateName, sizeof(stateName), "Перерыв");
case STATE_OVERTIME: strcopy(stateName, sizeof(stateName), "Овертайм");
case STATE_FINISHED: strcopy(stateName, sizeof(stateName), "Завершен");
}
PrintToChat(client, "\x04[CSrating] \x01Состояние: \x03%s\x01 | Счет: \x02CT %d - %d T | Игроки: %d/%d",
stateName, g_iCTScore, g_iTScore, g_iPlayersReady, g_iPlayersPerTeam * 2);
return Plugin_Handled;
}
public Action:Command_Start(client, args)
{
if (g_iMatchState != STATE_LOBBY)
{
PrintToChat(client, "\x04[CSrating] \x01Матч уже начался!");
return Plugin_Handled;
}
CountPlayers();
PrintToChatAll("\x04[CSrating] \x01Админ \x03%N \x01принудительно начал!", client);
PrintToChatAll("\x04[CSrating] \x01Игроков: \x02%d", g_iPlayersReady);
CreateTimer(1.0, Timer_StartCaptainPick);
return Plugin_Handled;
}
public Action:Command_Restart(client, args)
{
PrintToChatAll("\x04[CSrating] \x01Админ \x03%N \x01перезапустил!", client);
ResetMatch();
return Plugin_Handled;
}
public Action:Command_SetScore(client, args)
{
if (args < 2)
{
PrintToChat(client, "Использование: sm_setscore <CT> <T>");
return Plugin_Handled;
}
char arg1[16], arg2[16];
GetCmdArg(1, arg1, sizeof(arg1));
GetCmdArg(2, arg2, sizeof(arg2));
g_iCTScore = StringToInt(arg1);
g_iTScore = StringToInt(arg2);
PrintToChatAll("\x04[CSrating] \x01Счет установлен: \x03CT %d - %d T", g_iCTScore, g_iTScore);
UpdateServerHostname();
return Plugin_Handled;
}
public Action:Command_ForcePause(client, args)
{
if (g_bIsPaused)
{
g_bIsPaused = false;
ServerCommand("mp_unpause_match");
PrintToChatAll("\x04[CSrating] \x01Админ снял паузу!");
}
else
{
g_bIsPaused = true;
ServerCommand("mp_pause_match");
PrintToChatAll("\x04[CSrating] \x01Админ поставил паузу!");
}
return Plugin_Handled;
}
public Action:Command_Cancel(client, args)
{
PrintToChatAll("\x04[CSrating] \x01Админ \x03%N \x01отменил!", client);
ResetMatch();
return Plugin_Handled;
}
public Action:Timer_StartCaptainPick(Handle:timer)
{
CountPlayers();
if (g_iPlayersReady < 2)
{
PrintToChatAll("\x04[CSrating] \x01Нужно 2 игрока!");
return Plugin_Stop;
}
new captainCount = 0;
if (g_iPlayersPerTeam == 1)
{
for (new i = 1; i <= MaxClients && captainCount < 2; i++)
{
if (IsClientInGame(i) && !IsFakeClient(i) && g_bPlayerReady[i])
{
if (captainCount == 0)
{
CS_SwitchTeam(i, CS_TEAM_CT);
g_iPlayerTeam[i] = CS_TEAM_CT;
}
else
{
CS_SwitchTeam(i, CS_TEAM_T);
g_iPlayerTeam[i] = CS_TEAM_T;
}
captainCount++;
}
}
PrintToChatAll("\x04[CSrating] \x011v1 матч начинается!");
CreateTimer(2.0, Timer_StartMatch);
return Plugin_Stop;
}
g_iMatchState = STATE_CAPTAIN_PICK;
UpdateServerHostname();
PrintToChatAll("\x04[CSrating] \x01%d игроков готовы! Выбор капитанов...", g_iPlayersReady);
for (new i = 1; i <= MaxClients; i++)
{
if (IsClientInGame(i) && !IsFakeClient(i) && g_bPlayerReady[i])
{
CS_SwitchTeam(i, CS_TEAM_SPECTATOR);
}
}
captainCount = 0;
for (new i = 1; i <= MaxClients && captainCount < 2; i++)
{
if (IsClientInGame(i) && !IsFakeClient(i) && g_bPlayerReady[i])
{
g_iCaptains[captainCount] = i;
captainCount++;
}
}
if (captainCount < 2)
{
PrintToChatAll("\x04[CSrating] \x01Ошибка: нужно 2 капитана!");
ResetMatch();
return Plugin_Stop;
}
PrintToChatAll("\x04[CSrating] \x01Капитаны: \x03%N \x01и \x03%N",
g_iCaptains[0], g_iCaptains[1]);
CreateTimer(2.0, Timer_StartPlayerPick);
return Plugin_Stop;
}
public Action:Timer_StartPlayerPick(Handle:timer)
{
g_iMatchState = STATE_PLAYER_PICK;
g_iPickOrder = 0;
g_iCaptainTeam = CS_TEAM_CT;
PrintToChatAll("\x04[CSrating] \x01Капитан \x03%N \x01(CT) выбирает!", g_iCaptains[0]);
ShowCaptainPickMenu(g_iCaptains[0]);
return Plugin_Stop;
}
ShowCaptainPickMenu(captain)
{
new Handle:menu = CreateMenu(MenuHandler_CaptainPick);
SetMenuTitle(menu, "Выберите игрока");
for (new i = 1; i <= MaxClients; i++)
{
if (i == captain) continue;
if (IsClientInGame(i) && !IsFakeClient(i) && g_bPlayerReady[i] && g_iPlayerTeam[i] == 0)
{
char info[16];
IntToString(i, info, sizeof(info));
char playerName[MAX_NAME_LENGTH];
GetClientName(i, playerName, sizeof(playerName));
AddMenuItem(menu, info, playerName);
}
}
DisplayMenu(menu, captain, MENU_TIME_FOREVER);
}
public MenuHandler_CaptainPick(Handle:menu, MenuAction:action, param1, param2)
{
if (action == MenuAction_Select)
{
char info[16];
GetMenuItem(menu, param2, info, sizeof(info));
new selectedPlayer = StringToInt(info);
if (g_iCaptainTeam == CS_TEAM_CT)
{
g_iPlayerTeam[selectedPlayer] = CS_TEAM_CT;
g_iTeamSize[0]++;
PrintToChatAll("\x04[CSrating] \x03%N \x01выбрал \x03%N \x01в CT!", param1, selectedPlayer);
}
else
{
g_iPlayerTeam[selectedPlayer] = CS_TEAM_T;
g_iTeamSize[1]++;
PrintToChatAll("\x04[CSrating] \x03%N \x01выбрал \x03%N \x01в T!", param1, selectedPlayer);
}
new totalPlayers = g_iTeamSize[0] + g_iTeamSize[1];
new playersNeeded = g_iPlayersPerTeam * 2;
if (totalPlayers >= playersNeeded)
{
PrintToChatAll("\x04[CSrating] \x01Команды собраны! Старт через 5 сек...");
CreateTimer(5.0, Timer_StartMatch);
}
else
{
g_iCaptainTeam = (g_iCaptainTeam == CS_TEAM_CT) ? CS_TEAM_T : CS_TEAM_CT;
g_iPickOrder = 1 - g_iPickOrder;
new nextCaptain = g_iCaptains[g_iPickOrder];
char teamName[8];
strcopy(teamName, sizeof(teamName), (g_iCaptainTeam == CS_TEAM_CT) ? "CT" : "T");
PrintToChatAll("\x04[CSrating] \x01Капитан \x03%N \x01(%s) выбирает!", nextCaptain, teamName);
ShowCaptainPickMenu(nextCaptain);
}
}
else if (action == MenuAction_End)
{
CloseHandle(menu);
}
return 0;
}
ShowSubMenuToCaptain(leavingPlayer)
{
new team = g_iPlayerTeam[leavingPlayer];
new captainIndex = (team == CS_TEAM_CT) ? 0 : 1;
new captain = g_iCaptains[captainIndex];
if (!IsClientInGame(captain)) return;
new Handle:menu = CreateMenu(MenuHandler_SubPick);
SetMenuTitle(menu, "Выберите замену");
for (new i = 1; i <= MaxClients; i++)
{
if (IsClientInGame(i) && !IsFakeClient(i) && GetClientTeam(i) == CS_TEAM_SPECTATOR)
{
char info[16];
IntToString(i, info, sizeof(info));
char playerName[MAX_NAME_LENGTH];
GetClientName(i, playerName, sizeof(playerName));
AddMenuItem(menu, info, playerName);
}
}
DisplayMenu(menu, captain, MENU_TIME_FOREVER);
}
public MenuHandler_SubPick(Handle:menu, MenuAction:action, param1, param2)
{
if (action == MenuAction_Select)
{
char info[16];
GetMenuItem(menu, param2, info, sizeof(info));
new newPlayer = StringToInt(info);
new leavingPlayer = 0;
for (new i = 1; i <= MaxClients; i++)
{
if (g_iSubRequests[i] == 1)
{
leavingPlayer = i;
break;
}
}
if (leavingPlayer > 0)
{
new team = g_iPlayerTeam[leavingPlayer];
g_iPlayerTeam[newPlayer] = team;
g_iPlayerTeam[leavingPlayer] = 0;
g_iSubRequests[leavingPlayer] = 0;
CS_SwitchTeam(leavingPlayer, CS_TEAM_SPECTATOR);
if (team == CS_TEAM_CT)
{
CS_SwitchTeam(newPlayer, CS_TEAM_CT);
}
else
{
CS_SwitchTeam(newPlayer, CS_TEAM_T);
}
PrintToChatAll("\x04[CSrating] \x01Замена: \x03%N \x01вышел, \x03%N \x01зашел!", leavingPlayer, newPlayer);
}
}
else if (action == MenuAction_End)
{
CloseHandle(menu);
}
return 0;
}
public Action:Timer_StartMatch(Handle:timer)
{
g_iMatchState = STATE_LIVE;
g_iCurrentRound = 1;
g_iCTScore = 0;
g_iTScore = 0;
g_iPauseCount[0] = 0;
g_iPauseCount[1] = 0;
g_bIsPaused = false;
UpdateServerHostname();
for (new i = 1; i <= MaxClients; i++)
{
if (IsClientInGame(i) && !IsFakeClient(i) && g_iPlayerTeam[i] > 0)
{
if (g_iPlayerTeam[i] == CS_TEAM_CT)
{
CS_SwitchTeam(i, CS_TEAM_CT);
}
else if (g_iPlayerTeam[i] == CS_TEAM_T)
{
CS_SwitchTeam(i, CS_TEAM_T);
}
}
}
ServerCommand("mp_maxrounds %d", g_iMaxRounds);
ServerCommand("mp_startmoney 800");
ServerCommand("mp_restartgame 1");
SetAllTalk(false);
PrintToChatAll("\x04[CSrating] \x01МАТЧ НАЧАЛСЯ!");
PrintToChatAll("\x04[CSrating] \x01Формат: MR%d | %dv%d", g_iMaxRounds / 2, g_iPlayersPerTeam, g_iPlayersPerTeam);
PrintToChatAll("\x04[CSrating] \x01AllTalk выключен!");
return Plugin_Stop;
}
public Event_PlayerDisconnect(Handle:event, const String:name[], bool:dontBroadcast)
{
}
public Event_RoundStart(Handle:event, const String:name[], bool:dontBroadcast)
{
if (g_iMatchState == STATE_LIVE || g_iMatchState == STATE_OVERTIME)
{
g_iCurrentRound++;
UpdateServerHostname();
}
}
public Event_RoundEnd(Handle:event, const String:name[], bool:dontBroadcast)
{
if (g_iMatchState != STATE_LIVE && g_iMatchState != STATE_OVERTIME) return;
new winner = GetEventInt(event, "winner");
if (winner == CS_TEAM_CT)
{
g_iCTScore++;
}
else if (winner == CS_TEAM_T)
{
g_iTScore++;
}
UpdateServerHostname();
PrintToChatAll("\x04[CSrating] \x01Счет: \x03CT %d - %d T", g_iCTScore, g_iTScore);
if (g_iCTScore == g_iRoundsPerHalf || g_iTScore == g_iRoundsPerHalf)
{
if (g_iOvertimeCount == 0)
{
g_iMatchState = STATE_HALFTIME;
PrintToChatAll("\x04[CSrating] \x01ПЕРЕРЫВ - Смена сторон через 5 сек...");
ServerCommand("mp_switchteams 1");
ServerCommand("mp_restartgame 1");
CreateTimer(5.0, Timer_ContinueAfterHalftime);
return;
}
}
new maxRounds = g_iMaxRounds + (g_iOvertimeCount * g_iOvertimeRounds * 2);
new winScore = (maxRounds / 2) + 1;
if (g_iCTScore >= winScore || g_iTScore >= winScore)
{
EndMatch();
}
else if (g_iCurrentRound >= maxRounds)
{
if (g_iCTScore == g_iTScore)
{
g_iOvertimeCount++;
g_iMatchState = STATE_OVERTIME;
PrintToChatAll("\x04[CSrating] \x01ОВЕРТАЙМ %d!", g_iOvertimeCount);
}
else
{
EndMatch();
}
}
}
public Action:Timer_ContinueAfterHalftime(Handle:timer)
{
g_iMatchState = STATE_LIVE;
PrintToChatAll("\x04[CSrating] \x01Матч продолжается!");
return Plugin_Stop;
}
EndMatch()
{
g_iMatchState = STATE_FINISHED;
UpdateServerHostname();
char winner[32];
if (g_iCTScore > g_iTScore)
{
strcopy(winner, sizeof(winner), "CT");
}
else if (g_iTScore > g_iCTScore)
{
strcopy(winner, sizeof(winner), "T");
}
else
{
strcopy(winner, sizeof(winner), "Ничья");
}
PrintToChatAll("\x04[CSrating] \x01МАТЧ ЗАВЕРШЕН!");
PrintToChatAll("\x04[CSrating] \x01Победитель: \x03%s", winner);
PrintToChatAll("\x04[CSrating] \x01Итоговый счет: \x03CT %d - %d T", g_iCTScore, g_iTScore);
SetAllTalk(true);
PrintToChatAll("\x04[CSrating] \x01Голосование за карту через 10 сек...");
CreateTimer(10.0, Timer_StartMapVote);
CreateTimer(30.0, Timer_ResetAfterMatch);
}
public Action:Timer_StartMapVote(Handle:timer)
{
if (FindPluginByFile("mapchooser.smx") != INVALID_HANDLE)
{
PrintToChatAll("\x04[CSrating] \x01Голосование за карту!");
ServerCommand("sm_mapvote");
}
else
{
ShowMapVoteMenu();
}
return Plugin_Stop;
}
ShowMapVoteMenu()
{
new Handle:menu = CreateMenu(MenuHandler_MapVote);
SetMenuTitle(menu, "Голосование за карту:");
AddMenuItem(menu, "de_dust2", "de_dust2");
AddMenuItem(menu, "de_inferno", "de_inferno");
AddMenuItem(menu, "de_nuke", "de_nuke");
AddMenuItem(menu, "de_train", "de_train");
SetMenuExitButton(menu, false);
for (new i = 1; i <= MaxClients; i++)
{
if (IsClientInGame(i) && !IsFakeClient(i))
{
DisplayMenu(menu, i, 20);
}
}
}
public MenuHandler_MapVote(Handle:menu, MenuAction:action, param1, param2)
{
if (action == MenuAction_Select)
{
char map[64];
GetMenuItem(menu, param2, map, sizeof(map));
PrintToChatAll("\x04[CSrating] \x03%N \x01выбрал \x04%s", param1, map);
CreateTimer(15.0, Timer_ChangeMap);
}
else if (action == MenuAction_End)
{
CloseHandle(menu);
}
return 0;
}
public Action:Timer_ChangeMap(Handle:timer)
{
PrintToChatAll("\x04[CSrating] \x01Смена карты через 5 сек...");
CreateTimer(5.0, Timer_DoChangeMap);
return Plugin_Stop;
}
public Action:Timer_DoChangeMap(Handle:timer)
{
ServerCommand("changelevel de_dust2");
return Plugin_Stop;
}
public Action:Timer_ResetAfterMatch(Handle:timer)
{
ResetMatch();
return Plugin_Stop;
}
ResetMatch()
{
g_iMatchState = STATE_LOBBY;
g_iCTScore = 0;
g_iTScore = 0;
g_iCurrentRound = 0;
g_iOvertimeCount = 0;
g_iPlayersReady = 0;
g_bIsPaused = false;
g_iTeamSize[0] = 0;
g_iTeamSize[1] = 0;
g_iPauseCount[0] = 0;
g_iPauseCount[1] = 0;
for (new i = 1; i <= MaxClients; i++)
{
g_bPlayerReady[i] = false;
g_iPlayerTeam[i] = 0;
g_iSubRequests[i] = 0;
}
CountPlayers();
ServerCommand("mp_maxrounds 0");
SetAllTalk(true);
PrintToChatAll("\x04[CSrating] \x01Матч сброшен. Ожидание...");
}
А чего вперемешку синтаксисы в коде? Натырено из разных плагинов, что ли?Делал для себя
ИИА чего вперемешку синтаксисы в коде? Натырено из разных плагинов, что ли?
Была идея давать бан за выход,потом отказался.И нафига коннектиться к БД sourcebans, если это вообще ни для чего не используется (ну кроме того, чтобы сыпать в лог ошибок сообщение при каждом старте плагина, когда такой БД не существует на сервере)?
//// отрефактореный.sp
//
// Code size: 34736 bytes
// Data size: 22756 bytes
// Stack/heap size: 16992 bytes
// Total requirements: 74484 bytes
//
// Compilation Time: 0,16 sec
// ----------------------------------------
//// оригинальный.sp
//
// Code size: 35208 bytes
// Data size: 23776 bytes
// Stack/heap size: 16992 bytes
// Total requirements: 75976 bytes
//
// Compilation Time: 0,19 sec
// ----------------------------------------
Искусственный интеллект думает по своему) Если скинешь потом правленый исходник,буду благодарен) Я не силен в создании плагинов,решил через ИИ вот сделать)Пока ещё только начал чистить код (а на всё это времени может уйти - мама не горюй) и вот такие результаты пока:Выношу потихоньку создание массивов из циклов наружу и прочие правки непотребного.C-подобный://// отрефактореный.sp // // Code size: 34736 bytes // Data size: 22756 bytes // Stack/heap size: 16992 bytes // Total requirements: 74484 bytes // // Compilation Time: 0,16 sec // ---------------------------------------- //// оригинальный.sp // // Code size: 35208 bytes // Data size: 23776 bytes // Stack/heap size: 16992 bytes // Total requirements: 75976 bytes // // Compilation Time: 0,19 sec // ----------------------------------------
Ну и код пока сократился до 1270 строк.
Помимо этого префикс для чата, дефолтное имя сервера и список карт для голосования перемещены в начало исходника для удобства правки.
//// отрефрактореное.sp
//
// Code size: 33492 bytes
// Data size: 22560 bytes
// Stack/heap size: 16992 bytes
// Total requirements: 73044 bytes
//
// Compilation Time: 0,17 sec
// ----------------------------------------
ИИ делает, человек за ним переделывает все полностью) Красавчик!Ещё почистил косяки всякие и перевёл на новый синтаксис:Теперь исходник имеет 1197 строк.C-подобный://// отрефрактореное.sp // // Code size: 33492 bytes // Data size: 22560 bytes // Stack/heap size: 16992 bytes // Total requirements: 73044 bytes // // Compilation Time: 0,17 sec // ----------------------------------------
Но там ещё переписывать есть что (то же полностью нерабочее голосование или рекламные сообщения в статичном строковом массиве).
Сообщения автоматически склеены:
Вообще надо бы добавить поддержку переводов для сообщений в чат и добавить расцветку чата вместо реализованой расцветки чата для CS:Sv34 (т.е. сильно урезаной). И перевести значения переменных из файла конфига в квары. Ну и некоторые константы сделать настраиваемыми (префиксы и дефолтное имя сервера).
Ещё не переработал создание и обработку меню матча, но там сравнительно немного работы.
Сообщения автоматически склеены:
В общем состояние плагина на этот момент