Иконка ресурса

filipok

Участник
Сообщения
72
Реакции
28
  • Автор ресурса
  • #1

MapLimit
(all standart maps CS:GO version)
Если на сервере мало народу, зачастую играется только часть карты. Но всегда найдется какой-нибудь игрок, который побежит на запрещенную территорию наплевав на правила или просто по незнанию.

Плагин предназначен для того, что бы доходчиво объяснить таким игрокам, что некоторые из зон карты при малом количестве народа запрещены. В случае, когда игрок попадает в запретные зоны, он начинает гореть, в чат выводятся соответствующие уведомления. Если покинуть запретную зону, горение прекращается, если находиться в ней более 3 секунд, вас полностью разоружит (включая нож). В начале каждого раунда игрокам высвечивается напоминание, о том, что для игры разрешена только часть карты.

Установка:
Файл MapLimit.smx загрузите в папку "/csgo/addons/sourcemod/plugins/"
Файл maplimit.ini загрузите в папку "/csgo/addons/sourcemod/configs/"

MAX_PLAYERS_WHITHOUT_MIDDLE - количество игроков на сервере, при котором вся карта становится безопасной для прохода (настраивается в исходнике).
BURY_TIME - время через которое игрок лишится всего оружия, если он находится в запретной зоне.
PHP:
"MapZones"

{
    "de_dust2"
    {
        "Zone_0"    "OutsideTunnel"
        "Zone_1"    "UpperTunnel"
        "Zone_2"    "LowerTunnel"
        "Zone_3"    "Middle"
        "Zone_4"    "MidDoors"
        "Zone_5"    "BDoors"
        "Zone_6"    "BombsiteB"
    }
    "de_mirage"
    {
        "Zone_0"    "SideAlley"
        "Zone_1"    "Middle"
        "Zone_2"    "Tunnel"
        "Zone_3"    "TunnelStairs"
        "Zone_4"    "BackAlley"
        "Zone_5"    "House"
        "Zone_6"    "Apartments"
        "Zone_7"    "Balcony"
        "Zone_8"    "Truck"
        "Zone_9"    "BombsiteB"
        "Zone_10"    "Catwalk"
        "Zone_11"    "Shop"
    }
}
зайдите на сервер, запустите интересующую вас карту, после чего находясь в той зоне, которую хотите запретить введите в консоль sm_place, консоль выдаст ваш ник и название зоны, в которой вы находитесь. Пример (карта de_mirage):
C-подобный:
filip is in BombsiteB
filip is in Shop
filip is in SnipersNest
После чего в файле maplimit.ini создайте блок с название вашей карты и впишите в него названия запрещенных зон:
PHP:
"MapZones"
{
    "de_dust2"
    {
        "Zone_0"    "OutsideTunnel"
        "Zone_1"    "UpperTunnel"
        "Zone_2"    "LowerTunnel"
        "Zone_3"    "Middle"
        "Zone_4"    "MidDoors"
        "Zone_5"    "BDoors"
        "Zone_6"    "BombsiteB"
    }
    "название карты"
    {
        "Zone_0"    "название зоны 1"
        "Zone_1"    "название зоны 2"
        "Zone_2"    "название зоны 3"
                           ..........
                                      и т.д.

    }
}
@AlmazON - отдельная благодарность за неоценимую помощь, советы по оптимизации и разжевывание азов кодинга (мне это больше всего необходимо), ну а фактически за реализацию первой (only de_dust2) версии плагина.

@Серый™, @Саша Шеин - за помощь в поиске и определении ошибок, подсказки (а зачастую готовые решения) по коду плагина, которые помогли сделать его таким, какой он сейчас.

@DarklSide - за идею по развитию плагина в сторону его универсальности (не только карта de_dust2).

Revelation - за совет по реализации универсальности плагина

@nikita1811 - за тестирование, выявление багов, и наполнение maplimit.ini



Буду рад помощи и советам по доработке плагина
Выкладывайте свои зоны
 
Последнее редактирование модератором:

AlmazON

Не путать с самим yand3xmail
Сообщения
5,099
Реакции
2,755
советам по доработке плагина
Event_RoundEnd - нет метода EventHookMode_PostNoCopy.
new String: заменить на char, раз основа на новом синтаксисе, либо тогда уж заменить на decl. Массивы излишне большие, когда проверяется строка раза в 4 меньше. Для void OnPostThinkPost массивы должны быть "постоянными", например, static.
SDKHook лучше делать лишь над тем, у кого бомба (на то есть события), иначе слишком "жирно" выходит для такого плагина.
CreateTimer(2.0, Timer_Callout); - добавить флаг TIMER_FLAG_NO_MAPCHANGE.
Убрать:
PHP:
public void OnClientDisconnect(int client)
{
    SDKUnhook(client, SDKHook_PostThinkPost, OnPostThinkPost);
}
Так как SDKHooks сам по себе это уже делает.
 

filipok

Участник
Сообщения
72
Реакции
28
  • Автор ресурса
  • #3
@AlmazON , огромное спасибо. Плюсануть в репу не могу, не вижу как, тут какая-то странная политика на счет репы... Ну да ладно. Почти все переделал в соответствии с вашими советами. Плагин в первом посте обновил
SDKHook лучше делать лишь над тем, у кого бомба (на то есть события), иначе слишком "жирно" выходит для такого плагина.
Этого делать не стал ввиду того, что на Б бегают не только игроки с бомбой.

Еще один момент пришел в голову: проверять на название карты и если это не даст 2, то останавливать плагин. Есть небольшая загвоздка, я не знаю как остановить плагин сурсмода. Как должно заканчиваться условие?
PHP:
public OnPluginStart()
{
......
    decl String:mapname[64];
    GetCurrentMap(mapname, sizeof(mapname));
    if(!StrEqual(mapname, "de_dust2"))
        ЧЕМ ДОЛЖНО ЗАКАНЧИВАТЬ ЭТО ВЫРАЖЕНИЕ, ЧТО-ТО ТИПА plugin stop?
}
 

September

Участник
Сообщения
5,238
Реакции
2,742
  • Команда форума
  • #4
@AlmazON , огромное спасибо. Плюсануть в репу не могу, не вижу как, тут какая-то странная политика на счет репы... Ну да ладно. Почти все переделал в соответствии с вашими советами. Плагин в первом посте обновил

Этого делать не стал ввиду того, что на Б бегают не только игроки с бомбой.

Еще один момент пришел в голову: проверять на название карты и если это не даст 2, то останавливать плагин. Есть небольшая загвоздка, я не знаю как остановить плагин сурсмода. Как должно заканчиваться условие?
PHP:
public OnPluginStart()
{
......
    decl String:mapname[64];
    GetCurrentMap(mapname, sizeof(mapname));
    if(!StrEqual(mapname, "de_dust2"))
        ЧЕМ ДОЛЖНО ЗАКАНЧИВАТЬ ЭТО ВЫРАЖЕНИЕ, ЧТО-ТО ТИПА plugin stop?
}

Я конечно не скриптер, но может выполнять команду sm plugins unload названиеплагина, хотя если человек переименует плагин, уже не получится. Поэтому мой вариант не катит)
 

Серый™

CS:S Server
Сообщения
2,925
Реакции
1,376
Мой простенький плагинчик, по функциям такой же, но блокировал по другому, меньше моделей на спавн. Для ксс.
PHP:
#pragma semicolon 1
//#pragma tabsize 0

#include <sourcemod>
#include <sdktools>

new String:g_sPos[5][125] =
    {
        "-1727.616577 718.664733 103.031250",
        "-1152.680664 1297.347290 -45.968757",
        "-1323.031250 2220.328369 54.734252",
        "-1323.031250 2219.810791 159.589996",
        "-1295.031250 2595.761230 170.037475"
    };
new bool:g_bEvent = false;

public Plugin:myinfo =
{
    name = "Block prohod dust2",
    author = "Grey™",
    description = "",
    version = "0.2",
    url = "hlmod.ru Skype: wolf-1-ser"
};

public OnPluginStart()
{
    proverka_map();
}

public OnMapStart()
{
    proverka_map();
}

proverka_map()
{
    decl String:sMapName[125];
    GetCurrentMap(sMapName, sizeof(sMapName));
  
    if(StrEqual(sMapName, "de_dust2"))
    {
        if (!g_bEvent)
            g_bEvent = HookEventEx("round_start", OnRoundStart, EventHookMode_PostNoCopy);
    }
    else
        ServerCommand("sm plugins unload Block_prohod_dust2");
}

GetRealClientCount()
{
    new iClients = 0;
  
    for (new i = 1; i <= MaxClients; i++)
    {
        if (IsClientInGame(i) && IsPlayerAlive(i))
            iClients++;
    }
  
    return iClients;
}

public OnRoundStart(Handle:event, const String:name[], bool:dontBroadcast)
{
    new iClients = GetRealClientCount();

    if(iClients < 14)
    {
        decl Float:fPos[3],
             Float:fAng[3] = {0.0, 90.0, 180.0},
             Float:fAng2[3] = {0.0, 180.0, 0.0},
             String:sBufer[3][56],
             String:sModel[125] = "models/props_c17/fence03a.mdl";
        new iProp;
      
        PrecacheModel(sModel);
      
        for(new i = 0; i <= 4; ++i)
        {
            iProp = CreateEntityByName("prop_dynamic_override");
          
            SetEntityModel(iProp, sModel);
            DispatchKeyValue(iProp, "StartDisabled", "false");
            DispatchKeyValue(iProp, "Solid", "6");
            DispatchKeyValue(iProp, "spawnflags", "8");
            DispatchSpawn(iProp);
          
            ExplodeString(g_sPos[i], " ", sBufer, 3, 56);
            fPos[0] = StringToFloat(sBufer[0]);
            fPos[1] = StringToFloat(sBufer[1]);
            fPos[2] = StringToFloat(sBufer[2]);
          
            if(i > 1)
                TeleportEntity(iProp, fPos, fAng2, NULL_VECTOR);
            else
                TeleportEntity(iProp, fPos, fAng, NULL_VECTOR);
        }
    }
}

GetPluginFilename · sourcemod · SourceMod Scripting API Reference
Функция для того чтоб узнать название плагина.
Тема с примером [SM] Plugin load/unload management - AlliedModders
 
Последнее редактирование:

filipok

Участник
Сообщения
72
Реакции
28
  • Автор ресурса
  • #6
@September , а ты оказался прав, @Серый™ так и сделал. @Серый™ , спасибо, дружище. Я пока воспользовался твоим способом:
PHP:
ServerCommand("sm plugins unload MapLimit");
Позже попробую реализовать через GetPluginFilename · sourcemod · SourceMod Scripting API Reference
Исходник в первом посте обновлен.

2Admin, дайте возможность ставить лойсы людям за помощь.
 

AlmazON

Не путать с самим yand3xmail
Сообщения
5,099
Реакции
2,755
ServerCommand("sm plugins unload MapLimit");
Не занимайтесь ерундой, это ненормальный способ остановки плагина. Действия на полную выгрузку и загрузку плагина средствами SM может потребовать куда больше "сил", нежели сбросить нужную переменную или сделать необходимые Unhook'и. К тому же, не исключена ошибка пользователя, который вручную подгрузит плагин.
 

September

Участник
Сообщения
5,238
Реакции
2,742
  • Команда форума
  • #8
@September , а ты оказался прав, @Серый™ так и сделал. @Серый™ , спасибо, дружище. Я пока воспользовался твоим способом:
PHP:
ServerCommand("sm plugins unload MapLimit");
Позже попробую реализовать через GetPluginFilename · sourcemod · SourceMod Scripting API Reference
Исходник в первом посте обновлен.

2Admin, дайте возможность ставить лойсы людям за помощь.

Такой способ подойдет для личного использования. Для массы лучше сделать это как-то другим способом, более правильным. Послушай AlmazONa )
 

DarklSide

Участник
Сообщения
931
Реакции
468
Почему не присвоить плагину универсальности?! Вычеркнуть - "(отбиваем охоту бегать на Б при малом количестве игроков на карте de_dust2)".

Использовать файл (или динамичный квар) - на координаты, и ключ на название карты (или квар в(ы)кл).
После проверки карты (или квара вкл) в OnAutoConfigsBuffered, хукать э(и)венты или sdkhooks и содержать на его состояние булевую - если sdkhooks используется при успешном подключении игрока.
 

filipok

Участник
Сообщения
72
Реакции
28
  • Автор ресурса
  • #10
Не занимайтесь ерундой, это ненормальный способ остановки плагина. Действия на полную выгрузку и загрузку плагина средствами SM может потребовать куда больше "сил", нежели сбросить нужную переменную или сделать необходимые Unhook'и. К тому же, не исключена ошибка пользователя, который вручную подгрузит плагин.
PHP:
new bool:IsCorrectMap;

public OnMapStart(){
    decl String:mapname[128];
    GetCurrentMap(mapname, sizeof(mapname));
    if(!StrEqual(mapname, "de_dust2")){
        IsCorrectMap = true;
    }


public void OnClientPostAdminCheck(int client){
    if(IsCorrectMap){
        SDKHook(client, SDKHook_PostThinkPost, OnPostThinkPost);
    }
}
--- Добавлено позже ---
Почему не присвоить плагину универсальности?! Вычеркнуть - "(отбиваем охоту бегать на Б при малом количестве игроков на карте de_dust2)".

Использовать файл (или динамичный квар) - на координаты, и ключ на название карты (или квар в(ы)кл).
После проверки карты (или квара вкл) в OnAutoConfigsBuffered, хукать э(и)венты или sdkhooks и содержать на его состояние булевую - если sdkhooks используется при успешном подключении игрока.
Немного не понял. В зависимости от карты расставлять блоки в определенных местах? Вы это имели ввиду?
 

AlmazON

Не путать с самим yand3xmail
Сообщения
5,099
Реакции
2,755
Неверно. Наоборот с переменной:
PHP:
new bool:IsCorrectMap;

public OnConfigsExecuted(){
    decl String:mapname[32];
    GetCurrentMap(mapname, sizeof(mapname));
    IsCorrectMap = StrEqual(mapname, "de_dust2");


public void OnClientPostAdminCheck(int client){
    if(IsCorrectMap){
        SDKHook(client, SDKHook_PostThinkPost, OnPostThinkPost);
    }
}
 

DarklSide

Участник
Сообщения
931
Реакции
468
Немного не понял. В зависимости от карты расставлять блоки в определенных местах? Вы это имели ввиду?
Именно, и необходимость добавить ключ (квар) - на дамаг, т.к. хелсы может быть увеличины. Или использовать другой вид наказания, например замарозить, далее телепорт на координаты - до этой зоны.

P.S.: таким способом под спойлер - можно добавлять уже подготовленные конфиги (блок ключей) для нужной карты.
 
Последнее редактирование:

filipok

Участник
Сообщения
72
Реакции
28
  • Автор ресурса
  • #13
@AlmazON , спасибо, исходник в первом посте перезалил.
@DarklSide, я немного недопонимаю вас. Видимо общаемся через гугл переводчик. Может будете по английски говорить?
Общение будет быстрее, если будут куски или наметки кода, я в скриптинге новичок, но пример кода много может объяснить мне.
 

AlmazON

Не путать с самим yand3xmail
Сообщения
5,099
Реакции
2,755
исходник в первом посте перезалил
Есть ещё мелочи:
RegAdminCmd("m" - столь короткая команда - это не нормально, да и приставку sm_ стоит дописать (sm_mlimit, например). В этой же команде массив location[16] может быть мал, ведь ею можно проверять нахождение в локации любой карты (эдак поставить 32).
void OnPostThinkPost(int client) - так и не увидел:
массивы должны быть "постоянными", например, static
Это очень часто вызываемая функция, здесь должно быть минимум кода. А потому, сомневаюсь в необходимости столь частого опроса натива GetClientCount() - лучше заменить одной переменной (тем более, вход всё равно уже регистрируется). Плюс, вспоминая ботов, лучше не хукать их вовсе - они ведь всё равно пойдут, куда не надо...
И так, к размышлению:
PHP:
public Event_RoundStart(Handle:event, const String:name[], bool:dontBroadcast){
    CreateTimer(2.0, Timer_Callout, TIMER_FLAG_NO_MAPCHANGE);
}

public Action Timer_Callout(Handle timer){
    if(( GetClientCount() < MAX_PLAYERS_WHITHOUT_MIDDLE ) && IsCorrectMap){
        PrintHintTextToAll("Проходы на Б и мидл запрещены, на сервере менее %d игроков", MAX_PLAYERS_WHITHOUT_MIDDLE);
    }
    if( GetClientCount() >= (MAX_PLAYERS_WHITHOUT_MIDDLE) && !OneTimeNotify && IsCorrectMap) {
        PrintHintTextToAll("Играет полная карта");
        OneTimeNotify = true;
    }
}
public Action Event_RoundEnd(Handle:event, const String:name[], bool:dontBroadcast){
    if( GetClientCount() < MAX_PLAYERS_WHITHOUT_MIDDLE ){
        OneTimeNotify = false;
    }
}
Целиком заменяется на:
PHP:
public Event_RoundFreezeEnd(Handle:event, const String:name[], bool:dontBroadcast) {
	if ( IsCorrectMap ) {
		if (GetClientCount() < MAX_PLAYERS_WHITHOUT_MIDDLE ) {
			PrintHintTextToAll("Проходы на Б и мидл запрещены, на сервере менее %d игроков", MAX_PLAYERS_WHITHOUT_MIDDLE);
		}
		else {
			PrintHintTextToAll("Играет полная карта");
		}
	}
}
Где Event_RoundFreezeEnd - это round_freeze_end (вызывается через несколько секунд после старта раунда).
 
Последнее редактирование:

filipok

Участник
Сообщения
72
Реакции
28
  • Автор ресурса
  • #15
Есть ещё мелочи:
RegAdminCmd("m" - столь короткая команда - это не нормально, да и приставку sm_ стоит дописать (sm_mlimit, например). В этой же команде массив location[16] может быть мал, ведь ею можно проверять нахождение в локации любой карты (эдак поставить 32).
Сделал.
void OnPostThinkPost(int client) - так и не увидел:
Сорян, поправил)
Это очень часто вызываемая функция, здесь должно быть минимум кода. А потому, сомневаюсь в необходимости столь частого опроса натива GetClientCount() - лучше заменить одной переменной (тем более, вход всё равно уже регистрируется). Плюс, вспоминая ботов, лучше не хукать их вовсе - они ведь всё равно пойдут, куда не надо...
Я так понимаю вот проверка на бота в сурсмоде? IsFakeClient · clients · SourceMod Scripting API Reference
PHP:
new CountPlayers;
...
public void OnClientPostAdminCheck(int client){
    if(IsCorrectMap && !IsFakeClient(client)){
        SDKHook(client, SDKHook_PostThinkPost, OnPostThinkPost);
        CountPlayers = GetClientCount();
    }
}
public void OnPostThinkPost(int client){
    static String:location[32];
    GetEntPropString(client, Prop_Send, "m_szLastPlaceName", location, sizeof(location));
    if( CountPlayers < MAX_PLAYERS_WHITHOUT_MIDDLE ){
...............
Далее по коду при конце раунда и конце фризтайма я оставил GetClientCount() намеренно. Думаю так будет точнее.
И так, к размышлению:
PHP:
public Event_RoundStart(Handle:event, const String:name[], bool:dontBroadcast){
    CreateTimer(2.0, Timer_Callout, TIMER_FLAG_NO_MAPCHANGE);
}

public Action Timer_Callout(Handle timer){
    if(( GetClientCount() < MAX_PLAYERS_WHITHOUT_MIDDLE ) && IsCorrectMap){
        PrintHintTextToAll("Проходы на Б и мидл запрещены, на сервере менее %d игроков", MAX_PLAYERS_WHITHOUT_MIDDLE);
    }
    if( GetClientCount() >= (MAX_PLAYERS_WHITHOUT_MIDDLE) && !OneTimeNotify && IsCorrectMap) {
        PrintHintTextToAll("Играет полная карта");
        OneTimeNotify = true;
    }
}
public Action Event_RoundEnd(Handle:event, const String:name[], bool:dontBroadcast){
    if( GetClientCount() < MAX_PLAYERS_WHITHOUT_MIDDLE ){
        OneTimeNotify = false;
    }
}
Целиком заменяется на:
PHP:
public Event_RoundFreezeEnd(Handle:event, const String:name[], bool:dontBroadcast) {
    if ( IsCorrectMap ) {
        if (GetClientCount() < MAX_PLAYERS_WHITHOUT_MIDDLE ) {
            PrintHintTextToAll("Проходы на Б и мидл запрещены, на сервере менее %d игроков", MAX_PLAYERS_WHITHOUT_MIDDLE);
        }
        else {
            PrintHintTextToAll("Играет полная карта");
        }
    }
}
Где Event_RoundFreezeEnd - это round_freeze_end (вызывается через несколько секунд после старта раунда).
Фишка с Event_RoundFreezeEnd как нельзя лучше сюда вписывается. Инфы про нее не нашел тут SourceMod Scripting API Reference Буду знать, спасибо.
Но весь код не выкидывал. По задумке оповещение о том, что играет вся карта выводится только 1 раз, когда набирается нужное количество игроков, далее оно не выводится. Так что наверное вот так:
PHP:
public Event_RoundStart(Handle:event, const String:name[], bool:dontBroadcast){
    CreateTimer(2.0, Timer_Callout, TIMER_FLAG_NO_MAPCHANGE);
}

public Action Timer_Callout(Handle timer){
    if(( GetClientCount() < MAX_PLAYERS_WHITHOUT_MIDDLE ) && IsCorrectMap){
        PrintHintTextToAll("Проходы на Б и мидл запрещены, на сервере менее %d игроков", MAX_PLAYERS_WHITHOUT_MIDDLE);
    }
    if( GetClientCount() >= (MAX_PLAYERS_WHITHOUT_MIDDLE) && !OneTimeNotify && IsCorrectMap) {
        PrintHintTextToAll("Играет полная карта");
        OneTimeNotify = true;
    }
}
public Action Event_RoundEnd(Handle:event, const String:name[], bool:dontBroadcast){
    if( GetClientCount() < MAX_PLAYERS_WHITHOUT_MIDDLE ){
        OneTimeNotify = false;
    }
}
Заменил на
PHP:
public Event_RoundFreezeEnd(Handle:event, const String:name[], bool:dontBroadcast) {
    if ( IsCorrectMap ) {
        if (GetClientCount() < MAX_PLAYERS_WHITHOUT_MIDDLE){
            PrintHintTextToAll("Проходы на Б и мидл запрещены, на сервере менее %d игроков", MAX_PLAYERS_WHITHOUT_MIDDLE);
        }
        if (GetClientCount() >= (MAX_PLAYERS_WHITHOUT_MIDDLE) && !OneTimeNotify){
            PrintHintTextToAll("Играет полная карта");
            OneTimeNotify = true;
        }
    }
}

public Action Event_RoundEnd(Handle:event, const String:name[], bool:dontBroadcast){
    if( GetClientCount() < MAX_PLAYERS_WHITHOUT_MIDDLE ){
        OneTimeNotify = false;
    }
}
Плагин в первом посте перезалил.
 

AlmazON

Не путать с самим yand3xmail
Сообщения
5,099
Реакции
2,755
вот проверка на бота
Верно.
static большеват, я про массив команды говорил и только. Оффтоп
далее оно не выводится
Если оно столь важно, то тогда так:
PHP:
public Event_RoundFreezeEnd(Handle:event, const String:name[], bool:dontBroadcast) {
    if ( IsCorrectMap ) {
        if (GetClientCount() < MAX_PLAYERS_WHITHOUT_MIDDLE){
            PrintHintTextToAll("Проходы на Б и мидл запрещены, на сервере менее %d игроков", MAX_PLAYERS_WHITHOUT_MIDDLE);
            OneTimeNotify = true;
        }
        else if (OneTimeNotify){
            PrintHintTextToAll("Играет полная карта");
            OneTimeNotify = false;
        }
    }
}
Оффтоп
 
Последнее редактирование:

filipok

Участник
Сообщения
72
Реакции
28
  • Автор ресурса
  • #17
Верно.
static большеват, я про массив команды говорил и только.
Подкорректировал.
Оффтоп
Улетаю сегодня на неделю (работа). Как вернусь, подумаю над этим, спасибо)
Если оно столь важно, то тогда так:
PHP:
public Event_RoundFreezeEnd(Handle:event, const String:name[], bool:dontBroadcast) {
    if ( IsCorrectMap ) {
        if (GetClientCount() < MAX_PLAYERS_WHITHOUT_MIDDLE){
            PrintHintTextToAll("Проходы на Б и мидл запрещены, на сервере менее %d игроков", MAX_PLAYERS_WHITHOUT_MIDDLE);
            OneTimeNotify = true;
        }
        else if (OneTimeNotify){
            PrintHintTextToAll("Играет полная карта");
            OneTimeNotify = false;
        }
    }
}
Оффтоп
Я вот смотрю и поражаюсь, как я не дошел до этого сам? Спасибо)
Там от кода плагина моего ничего не осталось)
Плагин перезалил
--- Добавлено позже ---
А если так сделать?
PHP:
static String:de_dust2[] = {
    "OutsideTunnel",
    "UpperTunnel",
    "LowerTunnel",
    "Middle",
    "MidDoors",
    "BDoors"
};


public void OnPostThinkPost(int client){
    static String:location[16];
    GetEntPropString(client, Prop_Send, "m_szLastPlaceName", location, sizeof(location));
    if( CountPlayers < MAX_PLAYERS_WHITHOUT_MIDDLE &&) ){
        for (new i = 0; i < sizeof(de_dust2); i++){
            if (StrEqual(location, de_dust2[i])){
                PrintToChat(client, "Не ходи на Б!!!");
                if(IsPlayerAlive(client)) IgniteEntity(client, 3.8);
            }
        }
    }

Так не оптимальней?
 

AlmazON

Не путать с самим yand3xmail
Сообщения
5,099
Реакции
2,755
Так не оптимальней?
Лучше, но содержимое цикла не очень хорошо построено: не хватает break хотя бы.
Вообще, может вместо SDKHooks использовать событие player_footstep? Конечно, плохо, что индекс игрока ещё нужно получать, но вызывается куда реже и не требует проверки на "жив/не жив" + не грузит сервер от наблюдателей. Оффтоп
 

alexmy

Участник
Сообщения
284
Реакции
13
Всем привет, возможно использовать этот плагин в L4D как спасение от раша? Конечно если чуток подправить и подстроить?
 

filipok

Участник
Сообщения
72
Реакции
28
  • Автор ресурса
  • #20
@AlmazON , так?
PHP:
/**
использовать этот плагин в L4D как спасение от раша
Credits:

Топик плагина http://hlmod.ru/threads/maplimit-otbivaem-oxotu-begat-na-b-pri-malom-kolichestve-igrokov-na-karte-de_dust2.34302/
Этот плагин не был бы таким солидным и супер мега оптимизированным без помощи пользователей http://hlmod.ru/
Особую благодарность хочу выразить AlmazON. В нынешнем состоянии весь код состоит из его подсказок и советов. От меня тут осталась только идея)
AlmazON, чувак, общение с тобой - бесценный опыт, спасибо.
**/
#pragma semicolon 1
#include <sourcemod>
#include <sdkhooks>
#include <sdktools>

#define PLUGIN_MAINNAME "MapLimit"
#define PLUGIN_NAME "MapLimit"
#define PLUGIN_AUTHOR "filip fixed by AlmazON"
#define PLUGIN_VERSION "2.0.2"

#define MAX_PLAYERS_WHITHOUT_MIDDLE        10

static String:de_dust2[] = {
    "OutsideTunnel",
    "UpperTunnel",
    "LowerTunnel",
    "Middle",
    "MidDoors",
    "BDoors"
};

new bool:OneTimeNotify;
new bool:IsCorrectMap;
new CountPlayers;

public Plugin myinfo = {name = PLUGIN_MAINNAME, author = PLUGIN_AUTHOR, version = PLUGIN_VERSION}
public OnPluginStart()
{
    HookEvent("round_freeze_end", Event_RoundFreezeEnd, EventHookMode_PostNoCopy);
    HookEvent("player_footstep", OnPlayerFootStep, EventHookMode_Post);
    RegAdminCmd("sm_place", WhereAmI, ADMFLAG_BAN);
}

public OnConfigsExecuted(){
    decl String:mapname[32];
    GetCurrentMap(mapname, sizeof(mapname));
    IsCorrectMap = StrEqual(mapname, "de_dust2");
}
//////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////CheckZoneNameComand (for test)/////////////////////////////////////////////////////
public Action:WhereAmI(int client, args){
  
    decl String:location[32];
    GetEntPropString(client, Prop_Send, "m_szLastPlaceName", location, sizeof(location));
    ReplyToCommand(client, "%N is in %s", client, location);
    LogMessage("client %N is in %s", client, location);
}
//////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////
public void OnClientPostAdminCheck(int client){
    if(IsCorrectMap && !IsFakeClient(client)){
        CountPlayers = GetClientCount();
    }
}
public Action:OnPlayerFootStep(Handle:event, const String:name[], bool:dontBroadcast){
    new client = GetClientOfUserId(GetEventInt(event, "userid"));
    static String:location[16];
    GetEntPropString(client, Prop_Send, "m_szLastPlaceName", location, sizeof(location));
    if( CountPlayers < MAX_PLAYERS_WHITHOUT_MIDDLE ){
        for (new i = 0; i < sizeof(de_dust2); i++){
            if (StrEqual(location, de_dust2[i])){
                PrintToChat(client, "Не ходи на Б!!!");
                if(IsPlayerAlive(client)) IgniteEntity(client, 3.8);
                break;
            }
        }
    }
}
////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////оповещения вначале раунда///////////////////////////////////////////////

public Event_RoundFreezeEnd(Handle:event, const String:name[], bool:dontBroadcast) {
    if ( IsCorrectMap ) {
        if (GetClientCount() < MAX_PLAYERS_WHITHOUT_MIDDLE){
            PrintHintTextToAll("Проходы на Б и мидл запрещены, на сервере менее %d игроков", MAX_PLAYERS_WHITHOUT_MIDDLE);
            OneTimeNotify = true;
        }
        else if (OneTimeNotify){
            PrintHintTextToAll("Играет полная карта");
            OneTimeNotify = false;
        }
    }
}
@alexmy, друг я не играл в L4D. И вот эта фраза: "использовать как спасение от раша" непонятна. Что такое раш, можешь пояснить?
 
Сверху Снизу