Плагин для очистки инвентаря в конце раунда [РЕШЕНО]

EXPLOS1VE

Участник
Сообщения
26
Реакции
2
Операционная система
Linux
Ищу плагин который выбрасывает всë из инвентаря в конце раунда
 
Последнее редактирование:

Max Rhine

Участник
Сообщения
172
Реакции
29
Нужен плагин который будет очищать первый и второй слоты после победы одной из команд, т.е. в конце раунда [AWP и DEAGLE]
Если есть опыт, то можете ознакомиться с форумом пользователя wS, там много ценной информации. Или заказать плагин у скриптеров.
 

EXPLOS1VE

Участник
Сообщения
26
Реакции
2
@Max Rhine, я пересмотрел проблему на сервере, всë решается легче. Будет достаточно выбросить всë из слотов, осталось найти как это сделать
 

EXPLOS1VE

Участник
Сообщения
26
Реакции
2
оружие должно удаляться или выбрасываться ДО начала рауна т. е. в конце, а не в начале раунда
 

Max Rhine

Участник
Сообщения
172
Реакции
29
С помощью HookEvent ловишь событие round_end ( вроде ) и вставляешь подобный код:

C-подобный:
new weapon = GetPlayerWeaponSlot(client, 0);
 if (weapon > MaxClients) CS_DropWeapon(client, weapon, true, false);

Но лучше удалить оружие.

C-подобный:
new weapon = GetPlayerWeaponSlot(client, 0);
 if (weapon > MaxClients) RemovePlayerItem(client, weapon)
Можно юзать цикл для GetPlayerWeaponSlot и не писать лишний код для каждого типа оружия.

GetPlayerWeaponSlot(client, <номер>);
0 - автомат
1 - пистолет
2 - нож
3 - граната
4 - бомба c4
 

khood

Участник
Сообщения
214
Реакции
51
@Max Rhine, мне кажется я что то делаю не так :/
C++:
#include <sourcemod>

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

public Action Event_RoundEnd(Event event, const char[] name, bool dontBroadcast)
{
    for (int i = 1; i <= MaxClients; i++)
    {
        if (IsClientInGame(i))
        {
            int client = i;
            ClientCommand(client, "strip");
        }
    }
    return Plugin_Handled;
}
 
Последнее редактирование:

Grey83

не пишу плагины с весны 2022
Сообщения
8,520
Реакции
4,979
@EXPLOS1VE, попробуй так:
C-подобный:
#include <cstrike>
#include <sdktools_entinput>
#include <sdktools_functions>

enum
{
    Slot_Primary = 0,
    Slot_Secondary,
    Slot_Knife,
    Slot_Grenade,
    Slot_C4,
    Slot_None
};

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

public void Event_RoundEnd(Event event, const char[] name, bool dontBroadcast)
{
    for(int i = 1, j, wpn; i <= MaxClients; ++i) if(IsClientInGame(i) && IsPlayerAlive(i))
    {
        for(j = Slot_Primary; j < Slot_None; j++)
        {
            while((wpn = GetPlayerWeaponSlot(i, j)) != -1)
            {
                if(RemovePlayerItem(i, wpn))
                {
#if SOURCEMOD_V_MAJOR < 2 && SOURCEMOD_V_MINOR < 10
                    AcceptEntityInput(wpn, "Kill");
#else
                    RemoveEntity(wpn);
#endif
                }
            }
        }
        GivePlayerItem(i, "weapon_knife");
    }
}
Сообщения автоматически склеены:

C-подобный:
int client = i;
ClientCommand(client, "strip");
А это нафига?
Чем тебе вариант ClientCommand(i, "strip"); не угодил
 

Nekro

Терра инкогнита
Сообщения
4,025
Реакции
2,260
Всё ж намного проще... без лишнего кода и мусора
1. А IsClientSourceTV может быть жив? Если нет, то зачем проверять его вообще?
2. А разве в событие конца раунда, есть этот эвент?
GetClientOfUserId(GetEventInt(event, "userid"));
3. Смесь старого и нового синтаксиса
public void OnPluginStart()
против
public Action:Event_RoundEnd
4. А если
GetClientOfUserId(GetEventInt(event, "userid"))
То это не означает что игрок точно онлайн ? Зачем тогда проверка IsClientInGame

C++:
#include <sdktools>

public Plugin myinfo =
{
    name = "RemoveWeapons",
    author = "MaxRhine",
    version = "16.09.2023",
    url = "https://t.me/maxongg"
};


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

public Action:Event_RoundEnd(Handle:event, const String:name[], bool:dontBroadcast)
{
    new client = GetClientOfUserId(GetEventInt(event, "userid"));
    if (IsClientInGame(client) && !IsClientSourceTV(client) && IsPlayerAlive(client))
    {
        for (int i = 0; i <= 4; i++)
        {
            RemovePlayerItem(client, GetPlayerWeaponSlot(client, i)!= -1);
            GivePlayerItem(client, "weapon_knife");
        }
    }
}
Сообщения автоматически склеены:

Тогда уж как то так

C++:
#include <sdktools_functions>

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

void Event_RoundEnd(Event hEvent, const char[] name, bool dontBroadcast)
{
    for(int i = 1; i <= MaxClients; i++) if(IsClientInGame(i) && IsPlayerAlive(i))
    {
        for (int j; j < 5; j++) if(j != 2 && GetPlayerWeaponSlot(i, j) != -1)
        {
            RemovePlayerItem(i, j);
        }
    }
}
 
Последнее редактирование:

Palonez

бб братки
Сообщения
3,035
Реакции
1,837
1. А IsClientSourceTV может быть жив? Если нет, то зачем проверять его вообще?
2. А разве в событие конца раунда, есть этот эвент?
GetClientOfUserId(GetEventInt(event, "userid"));
3. Смесь старого и нового синтаксиса
public void OnPluginStart()
против
public Action:Event_RoundEnd
4. А если
GetClientOfUserId(GetEventInt(event, "userid"))
То это не означает что игрок точно онлайн ? Зачем тогда проверка IsClientInGame

C++:
#include <sdktools>

public Plugin myinfo =
{
    name = "RemoveWeapons",
    author = "MaxRhine",
    version = "16.09.2023",
    url = "https://t.me/maxongg"
};


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

public Action:Event_RoundEnd(Handle:event, const String:name[], bool:dontBroadcast)
{
    new client = GetClientOfUserId(GetEventInt(event, "userid"));
    if (IsClientInGame(client) && !IsClientSourceTV(client) && IsPlayerAlive(client))
    {
        for (int i = 0; i <= 4; i++)
        {
            RemovePlayerItem(client, GetPlayerWeaponSlot(client, i)!= -1);
            GivePlayerItem(client, "weapon_knife");
        }
    }
}
Сообщения автоматически склеены:

Тогда уж как то так

C++:
#include <sdktools_functions>

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

void Event_RoundEnd(Event hEvent, const char[] name, bool dontBroadcast)
{
    for(int i = 1; i <= MaxClients; i++) if(IsClientInGame(i) && IsPlayerAlive(i))
    {
        for (int j; j < 5; j++) if(j != 2 && GetPlayerWeaponSlot(i, j) != -1)
        {
            RemovePlayerItem(i, j);
        }
    }
}
public в ивенте забыл, он должен быть
 

Grey83

не пишу плагины с весны 2022
Сообщения
8,520
Реакции
4,979
Если просто последовательно забирать по одной штуке оружие из каждого из слотов, то как минимум могут остаться несколько гранат, т.к. они все в одном слоте (а вы забираете только одну 😎).
А в CS:GO добавилось оружие помимо гранат, которое может находится в одном и том же слоте.

И да, прекращайте заставлять писать ChatGPT плагины за себя: в событии конца раунда нет поля «userid». =D
Сообщения автоматически склеены:

без лишнего кода и мусора
Ну давай разберём твой код:
  1. Строка17: public Action:Event_RoundEnd()
    Action нам требуется только в случае необходимости изменить или заблокировать событие.
    Нам же это не требуется, поэтому там должно быть public Event_RoundEnd() в случае старого синтаксиса или public void Event_RoundEnd() в случае нового. Поэтому ещё можно в строке 14 добавить флаг EventHookMode_PostNoCopy, говорящий соурсмоду, что мы не планируем получать никакие данные от хука события.
    Кроме того компиляторы SM1.11+ будут ругаться если такая функция (с указанием какого-то типа, кроме void) не будет ничего возвращать.
  2. Строка 19: new client = GetClientOfUserId(GetEventInt(event, "userid"));
    Как я сказал выше, в этом событии отсутствует такое поле:
    Даже в CS:GO его нет:
    Т.е. дальше код в хуке события просто не будет выполняться.
  3. Строка 20: if (IsClientInGame(client) && !IsClientSourceTV(client) && IsPlayerAlive(client)) При всём при этом у нас client равен 0, а проверки валидности индекса (должен быть больше 0) я тут не вижу.
    Проверка IsClientSourceTV() в наличии, но что-то не вижу IsClientReplay(). Хотя тут было бы достаточно и получения команды клиента: GetClientTeam(client) > 1
  4. Строка 22: for (int i = 0; i <= 4; i++) Тут всё нормально (точно так же как у меня проверяются все 5 слотов), но int i = 0; делать не обязательно: достаточно просто int i;, т.к. в SM (как минимум в 1.6 уже было) присваивает переменным при создании значение равное нулю (для любых типов; у float - 0.0, у Handle - INVALID_HANDLE и т.д.).
    Разве что в старых версиях SM было decl которое в отличии от new не задавало значение, а только выделяло память для переменной и в значении там был мусор при использовании decl. В новых версиях SM (начиная с 1.7, наверное) decl и new компилятор читает как new.
  5. Строка 25: GivePlayerItem(client, "weapon_knife"); на кой в каждой итерации цикла прохода по слотам выдавать нож ума не приложу. В лучшем случае у игрока после такого будет под ногами валяться 5 ножей. Эта строка должна выполняться после завершения цикла.
Ещё можно вместо #include <sdktools> написать #include <sdktools_functions>, т.к. нам не нужны все прочие функции, содержащиеся в остальных инклюдах SDKTools.
И ещё за счет этого скомпиленный плагин будет меньше:
C-подобный:
//// clean sdktools_functions.sp
//
// Code size:         3968 bytes
// Data size:         2404 bytes
// Stack/heap size:      16468 bytes
// Total requirements:   22840 bytes
//
// Compilation Time: 0,23 sec
// ----------------------------------------

//// clean sdktools.sp
//
// Code size:         3968 bytes
// Data size:         2448 bytes
// Stack/heap size:      16468 bytes
// Total requirements:   22884 bytes
//
// Compilation Time: 0,27 sec
// ----------------------------------------

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

Max Rhine

Участник
Сообщения
172
Реакции
29
А в CS:GO добавилось оружие помимо гранат, которое может находится в одном и том же слоте.
Писал по сути на ксс, но учту этот момент в будущем.
Т.е. дальше код в хуке события просто не будет выполняться
Это понял уже, как и 5-й пункт)
Ещё можно вместо #include <sdktools> написать #include <sdktools_functions>, т.к. нам не нужны все прочие функции, содержащиеся в остальных инклюдах SDKTools.
И ещё за счет этого скомпиленный плагин будет меньше:
Дело привычки, как мне кажется и не имеет смысла. Ради пары байтов... в ущерб удобству. Тогда уж можно создать кастомный inc, убрав все ненужные функции. Или лучше использовать нативы напрямую с этих же inc, вместо #include <sdktools_functions>?))
#include <cstrike> #include <sdktools_entinput> #include <sdktools_functions>
Ну серьёзно.. мою невнимательность все заметили.
Тогда уж как то так
Всё тот же нерабочий кусок 💩😂
photo_2023-09-17_16-58-49.jpg
В любом случае, всем спасибо за критику. Кое-что новое таки узнал.
 

Grey83

не пишу плагины с весны 2022
Сообщения
8,520
Реакции
4,979
Или лучше использовать нативы напрямую с этих же inc, вместо #include <sdktools_functions>?
Компилятор просто записывает в тело плагина все перечисленные инклюды (инклюд sourcemod дописывается автоматически независимо от того указан ли он в исходнике).
Так что, в принципе, можно и так сделать.
Сообщения автоматически склеены:

Кое-что новое таки узнал.
Если почитать AM и HLMod можно много чего узнать. В справочнике по API соурсмода (новый, старый синтаксисы) или прямо в файлах инклюдов тоже есть много информации.
 

EXPLOS1VE

Участник
Сообщения
26
Реакции
2
@Grey83, Во время кастомных раундов не выдаётся обратно нож, для этого есть фикс?
Или можно как то отключить встроенную очистку плагина Custom Rounds?
 

Grey83

не пишу плагины с весны 2022
Сообщения
8,520
Реакции
4,979
@EXPLOS1VE, хз, нужно смотреть код плагина кастомных раундов.

Можно ещё просто не очищать слот, в котором хранится нож (в CS:GO там ещё как минимум тазер хранится):
for(j = Slot_Primary; j < Slot_None; j++)
==>
for(j = Slot_Primary; j < Slot_None; j++) if(j != Slot_Knife) (и удалить строку 38 с выдачей ножа)
 

EXPLOS1VE

Участник
Сообщения
26
Реакции
2
В том то и прикол, на сервере присутсвует кастомный рануд на зевсах, но уничтожения зевса отдельно оставляет неприятную пустую модельку в руках.
Поэтому и спросил можно ли как то поставить твой плагин вместого того что встроен в Custom Rounds
 

Max Rhine

Участник
Сообщения
172
Реакции
29
В справочнике по API соурсмода (новый, старый синтаксисы) или прямо в файлах инклюдов тоже есть много информации
Когда-то пытался учиться по справочнику. Это было интересно и в то же время непонятно😂 Пришлось учиться методом проб и ошибок, разумеется в консоли 😂😂 В любом случае ещё раз спасибо, попробую изучить.
 
Сверху Снизу