Написание плагинов

-=|УЧЕНИК|=-

вся жизнь,сплошной цирк.
Сообщения
876
Реакции
212
z:
    "myhs command"
    {
        "#format" "{1:i},{2:i}"
        "ru"    "[HeadShot] На самом деле у вас есть {1} headshots! \n Счет идет от. {2} игроков!"
    }

public Action counths(int client, int args)
{
    CPrintToChat(client, "%t", "myhs command", count[client], minplayers.IntValue);
}
Все четко,благодарю
 

Palonez

бб братки
Сообщения
3,035
Реакции
1,837
Что не так? Если внутри OnPluginStart объявить дб - то норм :/
x:
Database gDB;

public void OnPluginStart()
{
    ...
    gDB.Connect(CB, "DBNAME");     //error 177: static method 'Connect' must be invoked via its type (try 'Database.Connect')
                                //ошибка 177: статический метод 'Connect' должен быть вызван через его тип (попробуйте 'Database.Connect')
    ...
}

public void CB(Database db, const char[] czError, any data)
{
    ...
}
g:
Database gDB;

public void OnPluginStart()
{
    ...
    char error[256];
    gDB = SQL_Connect("DBNAME", true, error, sizeof(error));     //так все работает
    ...
}
Решение: Я тупой 🤦‍♂️ нужно было писать прям вот так Database.Connect вместо gDB.Connect
 
Последнее редактирование:

Seton

Участник
Сообщения
44
Реакции
41
Вопрос такой, как сделать подсчет убийств за раунд? (подобие как в кс го)
 

Palonez

бб братки
Сообщения
3,035
Реакции
1,837
Вопрос такой, как сделать подсчет убийств за раунд? (подобие как в кс го)
x:
#include <sourcemod>

int iKills[MAXPLAYERS+1];

public void OnPluginStart()
{
    HookEvent("player_death", EventPlayerDeath);
    HookEvent("round_start", EventRoundStart);
    HookEvent("round_end", EventRoundEnd);
}

public void OnClientConnected(client)
{
    iKills[client] = 0;
}

public void OnClientDisconnect_Post(client)
{
    iKills[client] = 0;
}

public Action EventRoundStart(Event hEvent, const char[] sEvent, bool bdb)
{
    for(int i = 1;i <= MaxClients; i++)
    {
        iKills[i] = 0;
    }
    return Plugin_Continue;
}

public Action EventRoundEnd(Event hEvent, const char[] sEvent, bool bdb)
{
    for(int i = 1;i <= MaxClients; i++)
    {
        PrintToChat(i, "Убийств за раунд: %i", iKills[i]);
    }
    return Plugin_Continue;
}

public Action EventPlayerDeath(Event hEvent, const char[] sEvent, bool bdb)
{
    int iAtk = GetClientOfUserId(hEvent.GetInt("attacker"));
    iKills[iAtk]++;
    return Plugin_Continue;
}
 
Последнее редактирование:

Seton

Участник
Сообщения
44
Реакции
41
x:
#include <sourcemod>

int iKills[MAXPLAYERS+1];

public void OnPluginStart()
{
    HookEvent("player_death", EventPlayerDeath);
    HookEvent("round_start", EventRoundStart);
    HookEvent("round_end", EventRoundEnd);
}

public void OnClientConnected(client)
{
    iKills[client] = 0;
}

public void OnClientDisconnect_Post(client)
{
    iKills[client] = 0;
}

public Action EventRoundStart(Event hEvent, const char[] sEvent, bool bdb)
{
    for(int i = 1;i <= MaxClients; i++)
    {
        iKills[i] = 0;
    }
    return Plugin_Continue;
}

public Action EventRoundEnd(Event hEvent, const char[] sEvent, bool bdb)
{
    for(int i = 1;i <= MaxClients; i++)
    {
        PrintToChat(i, "Убийств за раунд: %i", iKills[i]);
    }
    return Plugin_Continue;
}

public Action EventPlayerDeath(Event hEvent, const char[] sEvent, bool bdb)
{
    int iAtk = GetClientOfUserId(hEvent.GetInt("attacker"));
    iKills[iAtk]++;
    return Plugin_Continue;
}
учитывается убийство от мира, например бомба, тем самым +килл идет в вывод, можно поправить?
 

Palonez

бб братки
Сообщения
3,035
Реакции
1,837
учитывается убийство от мира, например бомба, тем самым +килл идет в вывод, можно поправить?
попробуй

x:
#include <sourcemod>

int iKills[MAXPLAYERS+1];

public void OnPluginStart()
{
    HookEvent("player_death", EventPlayerDeath);
    HookEvent("round_start", EventRoundStart);
    HookEvent("round_end", EventRoundEnd);
}

public void OnClientConnected(client)
{
    iKills[client] = 0;
}

public void OnClientDisconnect_Post(client)
{
    iKills[client] = 0;
}

public Action EventRoundStart(Event hEvent, const char[] sEvent, bool bdb)
{
    for(int i = 1;i <= MaxClients; i++)
    {
        iKills[i] = 0;
    }
    return Plugin_Continue;
}

public Action EventRoundEnd(Event hEvent, const char[] sEvent, bool bdb)
{
    for(int i = 1;i <= MaxClients; i++)
    {
        PrintToChat(i, "Убийств за раунд: %i", iKills[i]);
    }
    return Plugin_Continue;
}

public Action EventPlayerDeath(Event hEvent, const char[] sEvent, bool bdb)
{
    char weapon[20];
    hEvent.GetString("weapon", weapon, sizeof(weapon));
    if(weapon[0] != '\0')
    {
        int iAtk = GetClientOfUserId(hEvent.GetInt("attacker"));
        iKills[iAtk]++;
    }
    return Plugin_Continue;
}
 

Seton

Участник
Сообщения
44
Реакции
41
попробуй

x:
#include <sourcemod>

int iKills[MAXPLAYERS+1];

public void OnPluginStart()
{
    HookEvent("player_death", EventPlayerDeath);
    HookEvent("round_start", EventRoundStart);
    HookEvent("round_end", EventRoundEnd);
}

public void OnClientConnected(client)
{
    iKills[client] = 0;
}

public void OnClientDisconnect_Post(client)
{
    iKills[client] = 0;
}

public Action EventRoundStart(Event hEvent, const char[] sEvent, bool bdb)
{
    for(int i = 1;i <= MaxClients; i++)
    {
        iKills[i] = 0;
    }
    return Plugin_Continue;
}

public Action EventRoundEnd(Event hEvent, const char[] sEvent, bool bdb)
{
    for(int i = 1;i <= MaxClients; i++)
    {
        PrintToChat(i, "Убийств за раунд: %i", iKills[i]);
    }
    return Plugin_Continue;
}

public Action EventPlayerDeath(Event hEvent, const char[] sEvent, bool bdb)
{
    char weapon[20];
    hEvent.GetString("weapon", weapon, sizeof(weapon));
    if(weapon[0] != '\0')
    {
        int iAtk = GetClientOfUserId(hEvent.GetInt("attacker"));
        iKills[iAtk]++;
    }
    return Plugin_Continue;
}
проблема такая же
 

Palonez

бб братки
Сообщения
3,035
Реакции
1,837
проблема такая же
x:
#include <sourcemod>

int iKills[MAXPLAYERS+1];

public void OnPluginStart()
{
    HookEvent("player_death", EventPlayerDeath);
    HookEvent("round_start", EventRoundStart);
    HookEvent("round_end", EventRoundEnd);
}

public void OnClientConnected(client)
{
    iKills[client] = 0;
}

public void OnClientDisconnect_Post(client)
{
    iKills[client] = 0;
}

public Action EventRoundStart(Event hEvent, const char[] sEvent, bool bdb)
{
    for(int i = 1;i <= MaxClients; i++)
    {
        iKills[i] = 0;
    }
    return Plugin_Continue;
}

public Action EventRoundEnd(Event hEvent, const char[] sEvent, bool bdb)
{
    for(int i = 1;i <= MaxClients; i++)
    {
        if(IsClientInGame(i) && !IsFakeClient(i)) PrintToChat(i, "Убийств за раунд: %i", iKills[i]);
    }
    return Plugin_Continue;
}

public Action EventPlayerDeath(Event hEvent, const char[] sEvent, bool bdb)
{
    int iAtk = GetClientOfUserId(hEvent.GetInt("attacker"));
    int iVic = GetClientOfUserId(hEvent.GetInt("userid"));
    if(iAtk != iVic) iKills[iAtk]++;
    return Plugin_Continue;
}
 

Seton

Участник
Сообщения
44
Реакции
41
x:
#include <sourcemod>

int iKills[MAXPLAYERS+1];

public void OnPluginStart()
{
    HookEvent("player_death", EventPlayerDeath);
    HookEvent("round_start", EventRoundStart);
    HookEvent("round_end", EventRoundEnd);
}

public void OnClientConnected(client)
{
    iKills[client] = 0;
}

public void OnClientDisconnect_Post(client)
{
    iKills[client] = 0;
}

public Action EventRoundStart(Event hEvent, const char[] sEvent, bool bdb)
{
    for(int i = 1;i <= MaxClients; i++)
    {
        iKills[i] = 0;
    }
    return Plugin_Continue;
}

public Action EventRoundEnd(Event hEvent, const char[] sEvent, bool bdb)
{
    for(int i = 1;i <= MaxClients; i++)
    {
        if(IsClientInGame(i) && !IsFakeClient(i)) PrintToChat(i, "Убийств за раунд: %i", iKills[i]);
    }
    return Plugin_Continue;
}

public Action EventPlayerDeath(Event hEvent, const char[] sEvent, bool bdb)
{
    int iAtk = GetClientOfUserId(hEvent.GetInt("attacker"));
    int iVic = GetClientOfUserId(hEvent.GetInt("userid"));
    if(iAtk != iVic) iKills[iAtk]++;
    return Plugin_Continue;
}
годно, по красоте все)
 

Nekro

Терра инкогнита
Сообщения
4,025
Реакции
2,260
x:
#include <sourcemod>

int iKills[MAXPLAYERS+1];

public void OnPluginStart()
{
    HookEvent("player_death", EventPlayerDeath);
    HookEvent("round_start", EventRoundStart);
    HookEvent("round_end", EventRoundEnd);
}

public void OnClientConnected(client)
{
    iKills[client] = 0;
}

public void OnClientDisconnect_Post(client)
{
    iKills[client] = 0;
}

public Action EventRoundStart(Event hEvent, const char[] sEvent, bool bdb)
{
    for(int i = 1;i <= MaxClients; i++)
    {
        iKills[i] = 0;
    }
    return Plugin_Continue;
}

public Action EventRoundEnd(Event hEvent, const char[] sEvent, bool bdb)
{
    for(int i = 1;i <= MaxClients; i++)
    {
        if(IsClientInGame(i) && !IsFakeClient(i)) PrintToChat(i, "Убийств за раунд: %i", iKills[i]);
    }
    return Plugin_Continue;
}

public Action EventPlayerDeath(Event hEvent, const char[] sEvent, bool bdb)
{
    int iAtk = GetClientOfUserId(hEvent.GetInt("attacker"));
    int iVic = GetClientOfUserId(hEvent.GetInt("userid"));
    if(iAtk != iVic) iKills[iAtk]++;
    return Plugin_Continue;
}
А зачем хук события Action ?
 

Nekro

Терра инкогнита
Сообщения
4,025
Реакции
2,260
Не знаю. Можно и void, я так обычно делаю или про что речь?
Именно, void и тогда return можно вообще не писать, и строк меньше будет
Сообщения автоматически склеены:

Так же
1. Public void OnClientDisconnect_Post(client)
смесь синтаксиса, тогда лучше int client что бы был чисто новый
2. Библиотека см добавяется компилятором автоматически, ее можно вообще не писать.
3. Почему пост? OnClientDisconnect_Post
Должно быть все нормально, но были случаи что чек не проходил, так как клиента уже не было на сервере. Через раз игрока ловил
 
Последнее редактирование:

Palonez

бб братки
Сообщения
3,035
Реакции
1,837
Можно ли перехватить это сообщение и изменить его?
А клиенту отправить уже свое
1657109797488.png
 

Seton

Участник
Сообщения
44
Реакции
41
Как сделать выбор рандом звука из папки для EmitSoundToAll? Код следующий:

snd:
if(strcmp(file,"")) //EmitSoundToAll(file);
{
    new String:dl[1024];
    Format(dl, sizeof(dl), "sound/%s", file);
    new Handle:dir = OpenDirectory(dl);
    if (dir == INVALID_HANDLE)
        SetFailState("Не удалось открыть \"sound/%s\"", file);
   
    decl String:SoundName[PLATFORM_MAX_PATH], FileType:type;
    while (ReadDirEntry(dir, SoundName, PLATFORM_MAX_PATH, type))
    {
        if (type == FileType_File && StrContains(SoundName, ".ztmp") == -1)
        {
            if (StrContains(SoundName, ".mp3") > 0 || StrContains(SoundName, ".wav") > 0)
            {
                Format(SoundName, PLATFORM_MAX_PATH, "%s/%s", file, SoundName);
                EmitSoundToAll(SoundName);
            }
        }
    }
    CloseHandle(dir);
}
 
Последнее редактирование:

Grey83

не пишу плагины с весны 2022
Сообщения
8,521
Реакции
4,980
@Seton, примерно как-то так:
C-подобный:
if(file[0]) //EmitSoundToAll(file);
{
    new String:dl[1024];
    Format(dl, sizeof(dl), "sound/%s", file);
    new Handle:dir = OpenDirectory(dl);
    if(!dir) SetFailState("Не удалось открыть \"sound/%s\"", file);

    decl String:SoundName[PLATFORM_MAX_PATH], FileType:type, len;
    new Handle:array = CreateArray(ByteCountToCells(PLATFORM_MAX_PATH));
    while(ReadDirEntry(dir, SoundName, PLATFORM_MAX_PATH, type))
    {
        if(type == FileType_File && (len = strlen(SoundName) - 4) > 0
        && (!strcmp(sCvarPath[len], ".mp3") || !strcmp(sCvarPath[len], ".wav")))
        {
            Format(SoundName, PLATFORM_MAX_PATH, "%s/%s", file, SoundName);
            PushArrayString(array, SoundName);
        }
    }
    CloseHandle(dir);

    if((len = GetArraySize(array) - 1) != -1)
    {
        GetArrayString(array, GetRandomInt(0, len), SoundName, sizeof(SoundName));
        EmitSoundToAll(SoundName);
    }
    CloseHandle(array);
}
 

Seton

Участник
Сообщения
44
Реакции
41
Проблема со списком наблюдающих за игроком, выводит список только когда наблюдаешь за игроком с 3-лица, хоть и проверка имеется на 1-лицо, в чем проблема может быть?
Игра: v34
C-подобный:
#pragma semicolon 1

#include <sourcemod>
#include <clientMod>

#define SPECMODE_NONE                 0
#define SPECMODE_FIRSTPERSON         4
#define SPECMODE_3RDPERSON             5
#define SPECMODE_FREELOOK             6

#define UPDATE_INTERVAL 1.0

new Handle:HudHintTimers[MAXPLAYERS+1];
new Handle:sm_speclist_enabled;
new Handle:sm_speclist_allowed;
new Handle:sm_speclist_adminonly;
new bool:g_Enabled;
new bool:g_AdminOnly;
 
public Plugin:myinfo =
{
    name = "Spectator List",
    author = "GoD-Tony",
    description = "View who is spectating you in CS:S",
    version = "1.1.2",
    url = "http://www.sourcemod.net/"
};
//Источники:
//https://forums.alliedmods.net/showthread.php?t=135353
//https://hlmod.ru/threads/spectator-list.1611/
 
public OnPluginStart()
{
    sm_speclist_enabled = CreateConVar("sm_speclist_enabled","1","Включить список наблюдателей для всех игроков по умолчанию?");
                                                                    //Enables the spectator list for all players by default.
    sm_speclist_allowed = CreateConVar("sm_speclist_allowed","1","Разрешать игрокам включать список наблюдателей, когда он выключен по умолчанию?");
                                                                    //Allows players to enable spectator list manually when disabled by default.
    sm_speclist_adminonly = CreateConVar("sm_speclist_adminonly","0","Плагин будет работать только у админов?");
                                                                    //Only admins can use the features of this plugin.
    
    RegConsoleCmd("sm_speclist", Command_SpecList);
    
    HookConVarChange(sm_speclist_enabled, OnConVarChange);
    HookConVarChange(sm_speclist_adminonly, OnConVarChange);
    
    g_Enabled = GetConVarBool(sm_speclist_enabled);
    g_AdminOnly = GetConVarBool(sm_speclist_adminonly);
    
    //AutoExecConfig(true, "speclist", "sl_test");
}

public OnConVarChange(Handle:hCvar, const String:oldValue[], const String:newValue[])
{
    if (hCvar == sm_speclist_enabled)
    {
        g_Enabled = GetConVarBool(sm_speclist_enabled);
        
        if (g_Enabled)
        {
            // Enable timers on all players in game.
            for(new i = 1; i <= MaxClients; i++)
            {
                if (!IsClientInGame(i))
                    continue;
                
                CreateHudHintTimer(i);
            }
        }
        else
        {
            // Kill all of the active timers.
            for(new i = 1; i <= MaxClients; i++)
                KillHudHintTimer(i);
        }
    }
    else if (hCvar == sm_speclist_adminonly)
    {
        g_AdminOnly = GetConVarBool(sm_speclist_adminonly);
        
        if (g_AdminOnly)
        {
            // Kill all of the active timers.
            for(new i = 1; i <= MaxClients; i++)
                KillHudHintTimer(i);
                
            // Enable timers on all admins in game.
            for(new i = 1; i <= MaxClients; i++)
            {
                if (!IsClientInGame(i))
                    continue;
                
                CreateHudHintTimer(i);
            }
        }
    }
}

public OnClientPostAdminCheck(client)
{
    if (g_Enabled)
        CreateHudHintTimer(client);
}

public OnClientDisconnect(client)
{
    KillHudHintTimer(client);
}

// Using 'sm_speclist' to toggle the spectator list per player.
public Action:Command_SpecList(client, args)
{
    if (HudHintTimers[client] != INVALID_HANDLE)
    {
        KillHudHintTimer(client);
        ReplyToCommand(client, "[SM] Список зрителей отключен.");
    }
    else if (g_Enabled || GetConVarBool(sm_speclist_allowed))
    {
        CreateHudHintTimer(client);
        ReplyToCommand(client, "[SM] Список зрителей включен.");
    }
    
    return Plugin_Handled;
}


public Action:Timer_UpdateHudHint(Handle:timer, any:client)
{
    new iSpecModeUser = GetEntProp(client, Prop_Send, "m_iObserverMode");
    new iSpecMode, iTarget, iTargetUser;
    new bool:bDisplayHint = false;
    
    decl String:szText[254];
    szText[0] = '\0';
    
    // Dealing with a client who is in the game and playing.
    if (IsPlayerAlive(client))
    {
        for(new i = 1; i <= MaxClients; i++)
        {
            if (!IsClientInGame(i) || !IsClientObserver(i))
                continue;
                
            iSpecMode = GetEntProp(i, Prop_Send, "m_iObserverMode");
            
            // The client isn't spectating any one person, so ignore them.
            if (iSpecMode != SPECMODE_FIRSTPERSON && iSpecMode != SPECMODE_3RDPERSON)
                continue;
            
            // Find out who the client is spectating.
            iTarget = GetEntPropEnt(i, Prop_Send, "m_hObserverTarget");
            
            // Are they spectating our player?
            if (iTarget == client)
            {
                Format(szText, sizeof(szText), "%s%N\n", szText, i);
                bDisplayHint = true;
            }
        }
    }
    else if (iSpecModeUser == SPECMODE_FIRSTPERSON || iSpecModeUser == SPECMODE_3RDPERSON)
    {
        // Find out who the User is spectating.
        iTargetUser = GetEntPropEnt(client, Prop_Send, "m_hObserverTarget");
        
        if (iTargetUser > 0)
            Format(szText, sizeof(szText), "Наблюдающие за %N:\n", iTargetUser);
        
        for(new i = 1; i <= MaxClients; i++)
        {
            if (!IsClientInGame(i) || !IsClientObserver(i))
                continue;
                
            iSpecMode = GetEntProp(i, Prop_Send, "m_iObserverMode");
            
            // The client isn't spectating any one person, so ignore them.
            if (iSpecMode != SPECMODE_FIRSTPERSON && iSpecMode != SPECMODE_3RDPERSON)
                continue;
            
            // Find out who the client is spectating.
            iTarget = GetEntPropEnt(i, Prop_Send, "m_hObserverTarget");
            
            // Are they spectating the same player as User?
            if (iTarget == iTargetUser)
                Format(szText, sizeof(szText), "%s%N\n", szText, i);
        }
    }
    
    /* We do this to prevent displaying a message
        to a player if no one is spectating them anyway. */
    if (bDisplayHint)
    {
        Format(szText, sizeof(szText), "Наблюдающие за %N:\n%s", client, szText);
        bDisplayHint = false;
    }
    
    //if(CM_GetClientModAuth(client) == CM_Auth_ClientMod) CM_PrintKeyHintText(client, "%s", szText);
    PrintHintText(client, "%s", szText);
    
    return Plugin_Continue;
}

CreateHudHintTimer(client)
{
    // If AdminOnly is enabled, make sure we only create timers on admins.
    new AdminId:admin = GetUserAdmin(client);
    
    if (!g_AdminOnly || (g_AdminOnly && GetAdminFlag(admin, Admin_Generic, Access_Effective)))
        HudHintTimers[client] = CreateTimer(UPDATE_INTERVAL, Timer_UpdateHudHint, client, TIMER_REPEAT|TIMER_FLAG_NO_MAPCHANGE);
}

KillHudHintTimer(client)
{
    if (HudHintTimers[client] != INVALID_HANDLE)
    {
        KillTimer(HudHintTimers[client]);
        HudHintTimers[client] = INVALID_HANDLE;
    }
}
Сообщения автоматически склеены:

Как добавить проверку на флаг указанный в конфиге? (GetUserFlagBits(client) & ReadFlagString(""))

C-подобный:
if(!KvJumpToKey(kvGConfig, steamid))
{
    ...
}
 
Последнее редактирование:

releez-

Участник
Сообщения
101
Реакции
19
Привет всем! Может кто нибудь сделать плагин который включает общий чат в конце раунда. На сервере у меня режим 5на5, и я сделал так чтобы игроки могли разговаривать только со своей командой. Нужно чтобы в конце чат был общим и все могли общаться и ТТ и СТ. Ничего похожего найти не могу на форумах.
 

Palonez

бб братки
Сообщения
3,035
Реакции
1,837
Привет всем! Может кто нибудь сделать плагин который включает общий чат в конце раунда. На сервере у меня режим 5на5, и я сделал так чтобы игроки могли разговаривать только со своей командой. Нужно чтобы в конце чат был общим и все могли общаться и ТТ и СТ. Ничего похожего найти не могу на форумах.
Включать общий чат на пару секунд до начала раунда?
 
Сверху Снизу