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

Palonez

бб братки
Сообщения
3,035
Реакции
1,839
Что не так? Если внутри 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,839
Вопрос такой, как сделать подсчет убийств за раунд? (подобие как в кс го)
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,839
учитывается убийство от мира, например бомба, тем самым +килл идет в вывод, можно поправить?
попробуй

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,839
проблема такая же
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,169
Реакции
2,500
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,169
Реакции
2,500
Не знаю. Можно и void, я так обычно делаю или про что речь?
Именно, void и тогда return можно вообще не писать, и строк меньше будет
Сообщения автоматически склеены:

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

Palonez

бб братки
Сообщения
3,035
Реакции
1,839
Можно ли перехватить это сообщение и изменить его?
А клиенту отправить уже свое
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,805
Реакции
5,254
@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.net/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,839
Привет всем! Может кто нибудь сделать плагин который включает общий чат в конце раунда. На сервере у меня режим 5на5, и я сделал так чтобы игроки могли разговаривать только со своей командой. Нужно чтобы в конце чат был общим и все могли общаться и ТТ и СТ. Ничего похожего найти не могу на форумах.
Включать общий чат на пару секунд до начала раунда?
 

Nekro

Терра инкогнита
Сообщения
4,169
Реакции
2,500
Привет всем! Может кто нибудь сделать плагин который включает общий чат в конце раунда. На сервере у меня режим 5на5, и я сделал так чтобы игроки могли разговаривать только со своей командой. Нужно чтобы в конце чат был общим и все могли общаться и ТТ и СТ. Ничего похожего найти не могу на форумах.
C++:
public void OnPluginsStart()
{
 HookEvent("round_start", evstart);
 HookEvent("round_end", evend)
}

public void evstart(Handle hEv, char[] sName, bool on)
{
 SetConVarInt(FindConVar("sv_alltalk"), 0);
}

public void evend( Handle hEv, char[] sName, bool on)
{
SetConVarInt(FindConVar("sv_alltalk"), 1);
}

Попробуйте, на коленке с телефона..
 
Сверху Снизу