Будет ли работать баланс?

Q

Qujeck

PHP:
#include <sourcemod>
#include <clients>
#include <events>
#include <timers>
#include <cstrike>   
#include <halflife>
#include <events>
#include <console>
public OnMapStart()
{
    int ValueCt ;
    int ValueT ;
    int ClientInGameOnServer ;
        for(int i; ++i <= MaxClients;)
        {
            if(IsClientInGame(i) && !IsFakeClient(i))
            {
                ClientInGameOnServer++;
                switch(GetClientTeam(i))
                {
                    case 3:
                        {
                        ValueT++;
                        break;
                        }
                    case 2:
                        {
                        ValueCt++;
                        break;
                        }
                }
            }
        }
    int ValueTPlus6 = ValueT;
    ValueTPlus6 + 6;
    
        for(--ValueTPlus6 >=ValueCt)
        {
            GetRandomInt(1, ClientInGameOnServer);
            int Random = GetRandomInt;
                if(IsClientInGame(Random) && GetClientTeam(Random) == 2 && !IsFakeClient(Random))
                {
                ChangeClientTeam(Random, 3);
                CS_RespawnPlayer(Random);
                ValueCt + 1;
                }
        }
        
 
    
}
Будет ли работать баланс в начале каждого раунда, или нет?
 

Grey83

не пишу плагины с весны 2022
Сообщения
8,569
Реакции
5,071
Будет ли работать баланс в начале каждого раунда, или нет?
не будет
потому что
у тебя остановится перебор игроков при нахождении первого игрока, который находится в игре, не является ботом и при этом находящимся в команде террористов либо контр-террористов

в первую очередь тебе нужно убрать команду break из цикла, т.к. у тебя с этой командой число игроков одной команды всегда будет равно единице, а другой - нулю (в зависимости от того игрок какой команды встретится при переборе раньше)
for(--ValueTPlus6 >=ValueCt)
O RLY?! этот код компилится?

Я бы посоветовал при первом переборе заносить игроков в командах в массивы, а потом, после сравнения количества игроков в командах, посчитать сколько нужно переместить игроков и из какой команды.
После этого только использовать внутри цикла генератор случайных чисел для выбора игрока для переноса в противоположную команду.
И считать нужно не при запуске карты (потому что игроки в этот момент ещё не успели выбрать команду), а после начала раунда.

в общем код у тебя должен выглядеть примерно вот так:
PHP:
#include <cstrike>    // чисто для удобства

static const DIFFERENCE = 6;    // на сколько меньше должно быть игроков в команде террористов,
                                // чтобы не было нужно перекидывать их в противоположную команду

public void OnPluginStart()
{
    HookEvent("round_start", OnRoundStart, EventHookMode_PostNoCopy);
}

public void OnRoundStart(Event event, const char[] name, bool dontBroadcast)
{
    int players[3][MAXPLAYERS+1];
    for(int i; ++i <= MaxClients;)
    {
        if(IsClientInGame(i) && !IsFakeClient(i))
        {
            switch(GetClientTeam(i))
            {
                case CS_TEAM_T:
                {
                    players[0][0]++;                // нулевой игрок всегда консоль и эта ячейка не будет менять своё значение,
                                                    // поэтому мы можем использовать эту ячейку как нам будет угодно
                    players[0][players[0][0]]++;    // начиная со второй ячейки записываем ID игроков в массив
                }
                case CS_TEAM_CT:
                {
                    players[1][0]++;
                    players[1][players[1][0]]++;
                }
            }
        }
    }

    players[2][0] = DIFFERENCE + players[0][0] - players[1][0];    // считаем разницу м/у командами,
                                                                // учитывая балансное значение DIFFERENCE
    if(players[2][0] < 1) return;                    // если террористов меньше на DIFFERENCE+ человек, то ничего не делаем
                                                    // иначе начинаем перемещать игроков
    players[2][0] = RoundToCeil(players[2][0]/2);    // сначала определяем сколько нужно игроков переместить, чтобы уравновесить команды

    int i, target;
    while(i < players[0][0])    // мы начинаем с нуля поэтому и не '<='
    {
        target = GetRandomInt(1, players[0][0]);    // выбираем случайного террориста для перемещения в противоположную команду
        for(int j = 1; ++j <= i;)    // перебираем массив перемещённых игроков,
                                    // чтобы узнать перемещали ли мы уже этого игрока или нет
        {
            if(i &&                                    // если это не первая итерация
                target == players[2][j]) continue;    // и мы уже перемещали этого игрока, то пропускаем следующий код

            i++;                                    // если же нет, то переходим к следующему игроку
            players[2][i] = target;                    // заносим этого игрока в массив, чтобы при следующих итерациях
                                                    // мы не выбрали его снова
            ChangeClientTeam(target, CS_TEAM_CT);    // и перемещаем его в противоположную команду
            CS_RespawnPlayer(target);                // после чего возрождаем его
        }
    }
}
 

Вложения

  • balance.sp
    3.1 КБ · Просмотры: 6
  • balance.smx
    4.4 КБ · Просмотры: 1
Последнее редактирование:
Q

Qujeck

не будет
потому что

в первую очередь тебе нужно убрать команду break из цикла, т.к. у тебя с этой командой число игроков одной команды всегда будет равно единице, а другой - нулю (в зависимости от того игрок какой команды встретится при переборе раньше)O RLY?! этот код компилится?

Я бы посоветовал при первом переборе заносить игроков в командах в массивы, а потом, после сравнения количества игроков в командах, посчитать сколько нужно переместить игроков и из какой команды.
После этого только использовать внутри цикла генератор случайных чисел для выбора игрока для переноса в противоположную команду.
И считать нужно не при запуске карты (потому что игроки в этот момент ещё не успели выбрать команду), а после начала раунда.

в общем код у тебя должен выглядеть примерно вот так:
PHP:
#include <cstrike>    // чисто для удобства

static const DIFFERENCE = 6;    // на сколько меньше должно быть игроков в команде террористов,
                                // чтобы не было нужно перекидывать их в противоположную команду

public void OnPluginStart()
{
    HookEvent("round_start", OnRoundStart, EventHookMode_PostNoCopy);
}

public void OnRoundStart(Event event, const char[] name, bool dontBroadcast)
{
    int players[3][MAXPLAYERS+1];
    for(int i; ++i <= MaxClients;)
    {
        if(IsClientInGame(i) && !IsFakeClient(i))
        {
            switch(GetClientTeam(i))
            {
                case CS_TEAM_T:
                {
                    players[0][0]++;                // нулевой игрок всегда консоль и эта ячейка не будет менять своё значение,
                                                    // поэтому мы можем использовать эту ячейку как нам будет угодно
                    players[0][players[0][0]]++;    // начиная со второй ячейки записываем ID игроков в массив
                }
                case CS_TEAM_CT:
                {
                    players[1][0]++;
                    players[1][players[1][0]]++;
                }
            }
        }
    }

    players[2][0] = DIFFERENCE + players[0][0] - players[1][0];    // считаем разницу м/у командами,
                                                                // учитывая балансное значение DIFFERENCE
    if(players[2][0] < 1) return;                    // если террористов меньше на DIFFERENCE+ человек, то ничего не делаем
                                                    // иначе начинаем перемещать игроков
    players[2][0] = RoundToCeil(players[2][0]/2);    // сначала определяем сколько нужно игроков переместить, чтобы уравновесить команды

    int i, target;
    while(i < players[0][0])    // мы начинаем с нуля поэтому и не '<='
    {
        target = GetRandomInt(1, players[0][0]);    // выбираем случайного террориста для перемещения в противоположную команду
        for(int j = 1; ++j <= i;)    // перебираем массив перемещённых игроков,
                                    // чтобы узнать перемещали ли мы уже этого игрока или нет
        {
            if(i &&                                    // если это не первая итерация
                target == players[2][j]) continue;    // и мы уже перемещали этого игрока, то пропускаем следующий код

            i++;                                    // если же нет, то переходим к следующему игроку
            players[2][i] = target;                    // заносим этого игрока в массив, чтобы при следующих итерациях
                                                    // мы не выбрали его снова
            ChangeClientTeam(target, CS_TEAM_CT);    // и перемещаем его в противоположную команду
            CS_RespawnPlayer(target);                // после чего возрождаем его
        }
    }
}
Спасибо ))
--- Добавлено позже ---
не будет
потому что

в первую очередь тебе нужно убрать команду break из цикла, т.к. у тебя с этой командой число игроков одной команды всегда будет равно единице, а другой - нулю (в зависимости от того игрок какой команды встретится при переборе раньше)O RLY?! этот код компилится?

Я бы посоветовал при первом переборе заносить игроков в командах в массивы, а потом, после сравнения количества игроков в командах, посчитать сколько нужно переместить игроков и из какой команды.
После этого только использовать внутри цикла генератор случайных чисел для выбора игрока для переноса в противоположную команду.
И считать нужно не при запуске карты (потому что игроки в этот момент ещё не успели выбрать команду), а после начала раунда.

в общем код у тебя должен выглядеть примерно вот так:
PHP:
#include <cstrike>    // чисто для удобства

static const DIFFERENCE = 6;    // на сколько меньше должно быть игроков в команде террористов,
                                // чтобы не было нужно перекидывать их в противоположную команду

public void OnPluginStart()
{
    HookEvent("round_start", OnRoundStart, EventHookMode_PostNoCopy);
}

public void OnRoundStart(Event event, const char[] name, bool dontBroadcast)
{
    int players[3][MAXPLAYERS+1];
    for(int i; ++i <= MaxClients;)
    {
        if(IsClientInGame(i) && !IsFakeClient(i))
        {
            switch(GetClientTeam(i))
            {
                case CS_TEAM_T:
                {
                    players[0][0]++;                // нулевой игрок всегда консоль и эта ячейка не будет менять своё значение,
                                                    // поэтому мы можем использовать эту ячейку как нам будет угодно
                    players[0][players[0][0]]++;    // начиная со второй ячейки записываем ID игроков в массив
                }
                case CS_TEAM_CT:
                {
                    players[1][0]++;
                    players[1][players[1][0]]++;
                }
            }
        }
    }

    players[2][0] = DIFFERENCE + players[0][0] - players[1][0];    // считаем разницу м/у командами,
                                                                // учитывая балансное значение DIFFERENCE
    if(players[2][0] < 1) return;                    // если террористов меньше на DIFFERENCE+ человек, то ничего не делаем
                                                    // иначе начинаем перемещать игроков
    players[2][0] = RoundToCeil(players[2][0]/2);    // сначала определяем сколько нужно игроков переместить, чтобы уравновесить команды

    int i, target;
    while(i < players[0][0])    // мы начинаем с нуля поэтому и не '<='
    {
        target = GetRandomInt(1, players[0][0]);    // выбираем случайного террориста для перемещения в противоположную команду
        for(int j = 1; ++j <= i;)    // перебираем массив перемещённых игроков,
                                    // чтобы узнать перемещали ли мы уже этого игрока или нет
        {
            if(i &&                                    // если это не первая итерация
                target == players[2][j]) continue;    // и мы уже перемещали этого игрока, то пропускаем следующий код

            i++;                                    // если же нет, то переходим к следующему игроку
            players[2][i] = target;                    // заносим этого игрока в массив, чтобы при следующих итерациях
                                                    // мы не выбрали его снова
            ChangeClientTeam(target, CS_TEAM_CT);    // и перемещаем его в противоположную команду
            CS_RespawnPlayer(target);                // после чего возрождаем его
        }
    }
}
А зачем sp файл и smx
&
--- Добавлено позже ---
не будет
потому что

в первую очередь тебе нужно убрать команду break из цикла, т.к. у тебя с этой командой число игроков одной команды всегда будет равно единице, а другой - нулю (в зависимости от того игрок какой команды встретится при переборе раньше)O RLY?! этот код компилится?

Я бы посоветовал при первом переборе заносить игроков в командах в массивы, а потом, после сравнения количества игроков в командах, посчитать сколько нужно переместить игроков и из какой команды.
После этого только использовать внутри цикла генератор случайных чисел для выбора игрока для переноса в противоположную команду.
И считать нужно не при запуске карты (потому что игроки в этот момент ещё не успели выбрать команду), а после начала раунда.

в общем код у тебя должен выглядеть примерно вот так:
PHP:
#include <cstrike>    // чисто для удобства

static const DIFFERENCE = 6;    // на сколько меньше должно быть игроков в команде террористов,
                                // чтобы не было нужно перекидывать их в противоположную команду

public void OnPluginStart()
{
    HookEvent("round_start", OnRoundStart, EventHookMode_PostNoCopy);
}

public void OnRoundStart(Event event, const char[] name, bool dontBroadcast)
{
    int players[3][MAXPLAYERS+1];
    for(int i; ++i <= MaxClients;)
    {
        if(IsClientInGame(i) && !IsFakeClient(i))
        {
            switch(GetClientTeam(i))
            {
                case CS_TEAM_T:
                {
                    players[0][0]++;                // нулевой игрок всегда консоль и эта ячейка не будет менять своё значение,
                                                    // поэтому мы можем использовать эту ячейку как нам будет угодно
                    players[0][players[0][0]]++;    // начиная со второй ячейки записываем ID игроков в массив
                }
                case CS_TEAM_CT:
                {
                    players[1][0]++;
                    players[1][players[1][0]]++;
                }
            }
        }
    }

    players[2][0] = DIFFERENCE + players[0][0] - players[1][0];    // считаем разницу м/у командами,
                                                                // учитывая балансное значение DIFFERENCE
    if(players[2][0] < 1) return;                    // если террористов меньше на DIFFERENCE+ человек, то ничего не делаем
                                                    // иначе начинаем перемещать игроков
    players[2][0] = RoundToCeil(players[2][0]/2);    // сначала определяем сколько нужно игроков переместить, чтобы уравновесить команды

    int i, target;
    while(i < players[0][0])    // мы начинаем с нуля поэтому и не '<='
    {
        target = GetRandomInt(1, players[0][0]);    // выбираем случайного террориста для перемещения в противоположную команду
        for(int j = 1; ++j <= i;)    // перебираем массив перемещённых игроков,
                                    // чтобы узнать перемещали ли мы уже этого игрока или нет
        {
            if(i &&                                    // если это не первая итерация
                target == players[2][j]) continue;    // и мы уже перемещали этого игрока, то пропускаем следующий код

            i++;                                    // если же нет, то переходим к следующему игроку
            players[2][i] = target;                    // заносим этого игрока в массив, чтобы при следующих итерациях
                                                    // мы не выбрали его снова
            ChangeClientTeam(target, CS_TEAM_CT);    // и перемещаем его в противоположную команду
            CS_RespawnPlayer(target);                // после чего возрождаем его
        }
    }
}
А так же где найти события тот же round_start ?
 

Grey83

не пишу плагины с весны 2022
Сообщения
8,569
Реакции
5,071
где найти события
вот здесь
А вообще их всегда можно посмотреть в res-файлах в папке ...\%папка_игры%\resource\ под названием что-то типа ModEvents.res
зачем sp файл и smx
исходник и скомпилированный плагин, чтобы не было претензий, что плагин не компилируется
 
Сверху Снизу