Плагин random CT

teafest

Участник
Сообщения
202
Реакции
34
Операционная система
Linux
Добрый день.
Есть сервер пряток css v34
Подскажите, есть ли плагин, который бы каждый раунд перекидывал за КТ рандомного игрока из Террористов, а тот кто до этого был КТ перекидывался за Терров. Ну то есть каждый раунд новый КТ?
 

gibs

Фитиль народного волненья
Сообщения
722
Реакции
407
Мошенник
Это плагин на пару строчек

C:
#pragma semicolon 1

#include <sourcemod>
#include <cstrike>

#pragma newdecls required

public void OnPluginStart()
{
    HookEvent("round_end", Event_RoundEnd, EventHookMode_PostNoCopy);
}

public void Event_RoundEnd(Event event, const char[] name, bool dontBroadcast)
{
    int rand_t = GetRandomPlayer(CS_TEAM_T);
    int rand_ct = GetRandomPlayer(CS_TEAM_CT);
    
    if(rand_t != 0 && rand_ct != 0)
    {
        CS_SwitchTeam(rand_t, CS_TEAM_CT);
        CS_SwitchTeam(rand_ct, CS_TEAM_T);
    }
}

int GetRandomPlayer(int team)
{
    int[] clients = new int[MaxClients];
    int total = 0;
    
    for (int client = 1; client <= MaxClients; ++client)
    {
        if(!IsClientInGame(client) || GetClientTeam(client) != team)
            continue;
        
        clients[total++] = client;
    }
    
    if(total == 0)
        return 0;
    
    return clients[GetRandomInt(0, total - 1)];
}
 

Grey83

не пишу плагины с весны 2022
Сообщения
8,521
Реакции
4,980
Можно было короче написать:
C-подобный:
#pragma semicolon 1
#pragma newdecls required

#include <cstrike>

public void OnPluginStart()
{
    HookEvent("round_end", Event_RoundEnd, EventHookMode_PostNoCopy);
}

public void Event_RoundEnd(Event event, const char[] name, bool dontBroadcast)
{
    static int t, ct;
    if((t = GetRandomPlayer(CS_TEAM_T)) && (ct = GetRandomPlayer(CS_TEAM_CT)))
    {
        CS_SwitchTeam(t, CS_TEAM_CT);
        CS_SwitchTeam(ct, CS_TEAM_T);
    }
}

stock int GetRandomPlayer(int team)
{
    static int clients[MAXPLAYERS], total, i;
    for(i = 1, total = 0; i <= MaxClients; ++i) if(IsClientInGame(i) && GetClientTeam(i) == team) clients[++total] = i;
    return total ? clients[GetRandomInt(1, total)] : 0;
}
 

teafest

Участник
Сообщения
202
Реакции
34
Это плагин на пару строчек

C:
#pragma semicolon 1

#include <sourcemod>
#include <cstrike>

#pragma newdecls required

public void OnPluginStart()
{
    HookEvent("round_end", Event_RoundEnd, EventHookMode_PostNoCopy);
}

public void Event_RoundEnd(Event event, const char[] name, bool dontBroadcast)
{
    int rand_t = GetRandomPlayer(CS_TEAM_T);
    int rand_ct = GetRandomPlayer(CS_TEAM_CT);
  
    if(rand_t != 0 && rand_ct != 0)
    {
        CS_SwitchTeam(rand_t, CS_TEAM_CT);
        CS_SwitchTeam(rand_ct, CS_TEAM_T);
    }
}

int GetRandomPlayer(int team)
{
    int[] clients = new int[MaxClients];
    int total = 0;
  
    for (int client = 1; client <= MaxClients; ++client)
    {
        if(!IsClientInGame(client) || GetClientTeam(client) != team)
            continue;
      
        clients[total++] = client;
    }
  
    if(total == 0)
        return 0;
  
    return clients[GetRandomInt(0, total - 1)];
}
Спасибо огромное, кажется работает. Именно так как нужно.
Сообщения автоматически склеены:

Можно было короче написать:
C-подобный:
#pragma semicolon 1
#pragma newdecls required

#include <cstrike>

public void OnPluginStart()
{
    HookEvent("round_end", Event_RoundEnd, EventHookMode_PostNoCopy);
}

public void Event_RoundEnd(Event event, const char[] name, bool dontBroadcast)
{
    static int t, ct;
    if((t = GetRandomPlayer(CS_TEAM_T)) && (ct = GetRandomPlayer(CS_TEAM_CT)))
    {
        CS_SwitchTeam(t, CS_TEAM_CT);
        CS_SwitchTeam(ct, CS_TEAM_T);
    }
}

stock int GetRandomPlayer(int team)
{
    static int clients[MAXPLAYERS], total, i;
    for(i = 1, total = 0; i <= MaxClients; ++i) if(IsClientInGame(i) && GetClientTeam(i) == team) clients[++total] = i;
    return total ? clients[GetRandomInt(1, total)] : 0;
}
Я пока воспользовался плагином выше, но если вдруг что-то будет не так попробуйю этот. Спасбио вам огромное что откликнулись. Я уже и не ждал что помогут)
 

Grey83

не пишу плагины с весны 2022
Сообщения
8,521
Реакции
4,980
Я, собственно, только немного оптимизировал и упростил код, который gibs написал
 

teafest

Участник
Сообщения
202
Реакции
34
Я, собственно, только немного оптимизировал и упростил код, который gibs написал
Спасибо огромное за это. Я честно пол интернета перерыл что бы подобный плагин найти, а тут аж целых 2 практически сразу)
 

helper2011

Участник
Сообщения
10
Реакции
9
Оптимизация оптимизацией, но все таки clients[MAXPLAYERS] нужно заменить на clients[MAXPLAYERS + 1]
 

gibs

Фитиль народного волненья
Сообщения
722
Реакции
407
Мошенник
А зачем вам статическая область для чего-то, что вызывается в лучшем случае минимум раз в две минуты? Ладно бы что-то постоянное, чтобы не создавать переменные в стеке.
В вашем случае вы занимаетесь не просто чушью, а вредной "оптимизацией". К тому же важно уделять внимание читаемости кода. Нагромоздить на кучу, лишь бы меньше занимало, далеко не всегда является полезным.
 

Grey83

не пишу плагины с весны 2022
Сообщения
8,521
Реакции
4,980
Оптимизация оптимизацией, но все таки clients[MAXPLAYERS] нужно заменить на clients[MAXPLAYERS + 1]
Почему это вдруг, консоль тоже может менять команду, что ли?
А зачем вам статическая область для чего-то, что вызывается в лучшем случае минимум раз в две минуты?
Обычно предпочитаю делать так для массивов. Вместо decl. Можешь убрать static и мало что изменится, кроме времени, которое будет тратиться на создание переменных и места занимаемого этими переменными в памяти (в принципе, что то, что другое - мизер).
Ладно бы что-то постоянное, чтобы не создавать переменные в стеке.
Например?

Вообще под оптимизацией я подразумевал то, что не производится поиск спецназовцев, если не найдено ни одного террориста. =)
Ну и то, что убрал динамический массив, из-за которого могут быть проблемы с памятью при использовании версии SM ниже 1.11 (в ней вроде эту проблему пофиксили).
 

gibs

Фитиль народного волненья
Сообщения
722
Реакции
407
Мошенник
Почему это вдруг, консоль тоже может менять команду, что ли?
Обычно предпочитаю делать так для массивов. Вместо decl. Можешь убрать static и мало что изменится, кроме времени, которое будет тратиться на создание переменных и места занимаемого этими переменными в памяти (в принципе, что то, что другое - мизер).Например?

Вообще под оптимизацией я подразумевал то, что не производится поиск спецназовцев, если не найдено ни одного террориста. =)
Ну и то, что убрал динамический массив, из-за которого могут быть проблемы с памятью при использовании версии SM ниже 1.11 (в ней вроде эту проблему пофиксили).
Смысл в том, что не стоит лезть в чужой огород, если тебя об этом никто не просит. Это минимум не красиво.
Во-первых, ты допустил ошибку и твой офигенный оптимизированный вариант работать не будет из-за твоей невнимательности.
Ну а во-вторых, мне так нравится писать, это мои личные предпочтения. К примеру, я отдаю предпочтения магической переменной MaxClients, нежели макросу MAXPLAYERS, именно по-этому я использую динамический массив. А по поводу кривизны механизма динамических массивов ничего не слышал. У сорспавна нету кучи. Память выделяется на стеке, что и позволяет освобождать её при выходе из функции. Единственный возможный косяк только со стек поинтером и даже удивительно, что его допустили. Но это опять же, если верить твоим словам.
А вот если бы я допустил ошибку, тогда да, тут уже стоит как-то меня поправить.
 

Grey83

не пишу плагины с весны 2022
Сообщения
8,521
Реакции
4,980
ты допустил ошибку и твой офигенный оптимизированный вариант работать не будет из-за твоей невнимательности.
Просвети меня, гуру, почему это мой код работать не будет.
Мне очень любопытно.
 

maestro200614

Участник
Сообщения
27
Реакции
3
Можно было короче написать:
C-подобный:
#pragma semicolon 1
#pragma newdecls required

#include <cstrike>

public void OnPluginStart()
{
    HookEvent("round_end", Event_RoundEnd, EventHookMode_PostNoCopy);
}

public void Event_RoundEnd(Event event, const char[] name, bool dontBroadcast)
{
    static int t, ct;
    if((t = GetRandomPlayer(CS_TEAM_T)) && (ct = GetRandomPlayer(CS_TEAM_CT)))
    {
        CS_SwitchTeam(t, CS_TEAM_CT);
        CS_SwitchTeam(ct, CS_TEAM_T);
    }
}

stock int GetRandomPlayer(int team)
{
    static int clients[MAXPLAYERS], total, i;
    for(i = 1, total = 0; i <= MaxClients; ++i) if(IsClientInGame(i) && GetClientTeam(i) == team) clients[++total] = i;
    return total ? clients[GetRandomInt(1, total)] : 0;
}
а куда это писать
 

Grey83

не пишу плагины с весны 2022
Сообщения
8,521
Реакции
4,980
@maestro200614, в блокнот
Сообщения автоматически склеены:

После чего сохраняешь текст в файл с любыми именем и расширением ".sp" в кодировке UTF-8 без BOM.
Ну а дельше следуешь гайду:
 

_wS_

Участник
Сообщения
383
Реакции
760
Грэюс, а почему выше не согласился про MAXPLAYERS + 1?)
Если на сервере MAXPLAYERS игроков и они все в одной команде, то clients[++total] выдаст:
[SM] Exception reported: Array index out-of-bounds (index 65, limit 65)
🐮
 

Grey83

не пишу плагины с весны 2022
Сообщения
8,521
Реакции
4,980
@_wS_, потому что clients[] - это массив для хранения индексов игроков и там по определению не может понадобиться MAXPLAYERS+1 ячеек (как минимум потому, что туда не попадёт clientid равный 0).
Кроме того туда будут записаны clientid игроков только одной команды.
Я как-то сильно сомневаюсь, что в одной команде будут все игроки на сервере и сервер будет заполнен при этом на все 64 слота (кроме того, MAXPLAYERS равен 65, емнип).

Если уж так сильно переживать за размер массива, то лучше в цикле задать для total значение "-1", а для return использовать GetRandomInt(0, total) после сравнения total с "-1".

Как-то так.
 

_wS_

Участник
Сообщения
383
Реакции
760
потому что clients[] - это массив для хранения индексов игроков и там по определению не может понадобиться MAXPLAYERS+1 ячеек (как минимум потому, что туда не попадёт clientid равный 0).
Проверь работу функции GetRandomPlayer выше, вырезав "if(IsClientInGame(i) && GetClientTeam(i) == team)", что будет равносильному тому, как если бы все игроки прошли эту проверку, и ты увидишь 🐴 Проблемы не было бы, если было бы clients[total++], а в функции clients[++total] 🐢 Кнеш шанс, что ошибка всплывёт, мал, но люди выше были правы, недочёт то есть 🦧
 

Похожие темы

Ответы
1
Просмотры
245
  • Закрыта
Неактуально Bot path fix
Ответы
1
Просмотры
Ответы
21
Просмотры
Сверху Снизу