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

RusJJ

Доброе утро девачьки
Сообщения
2,582
Реакции
1,075
@Paranoiiik, можно в OnClientPutInServer узнавать это же время, а потом при выходе отнимать его. Но если не ошибаюсь, при смене карты будет опять вызываться.
 

Hushang

Участник
Сообщения
134
Реакции
26
Здравствуйте, кто подскажет, как сделать так, чтобы в 1 раунде и после мены сторон было 800 долларов, а в остальных раундах по 16к?

исходник:
#pragma semicolon 1

#include <cstrike>

ConVar mp_startmoney;

bool bFirstRound;
int m_iAccount,
    iFirstMoney,
    iDefMoney;

public Plugin:myinfo =
{
        name        = "First round startmoney",
        author        = "Grey83",
        description    = "Changes the initial amount of money for the first round.",
        version        = "1.0.1",
        url            = "https://steamcommunity.com/groups/grey83ds"
};

public void OnPluginStart()
{
    EngineVersion ver = GetEngineVersion();
    if(ver != Engine_CSS && ver != Engine_CSGO) SetFailState("Plugin for CS:S and CS:GO only!");

    m_iAccount = FindSendPropInfo("CCSPlayer", "m_iAccount");

    (mp_startmoney = CreateConVar("sm_startmoney_first", "800", "Сколько денег будет выдавать в первом раунде", _, true, 800.0, true, 16000.0)).AddChangeHook(CVarChange_First);
    iFirstMoney = mp_startmoney.IntValue;

    (mp_startmoney = CreateConVar("sm_startmoney_def", "16000", "Сколько денег будет выдавать в начале каждого из всех остальных раундов", _, true, 800.0, true, 16000.0)).AddChangeHook(CVarChange_Def);
    iDefMoney = mp_startmoney.IntValue;
    
    AutoExecConfig(true, "StartMoney");

    if((mp_startmoney = FindConVar("mp_startmoney")) == null) SetFailState("Can't find ConVar 'mp_startmoney'!");
}

public void CVarChange_First(ConVar convar, const char[] oldValue, const char[] newValue)
{
    convar.IntValue = iFirstMoney;
    if(bFirstRound) mp_startmoney.IntValue = iFirstMoney;
}

public void CVarChange_Def(ConVar convar, const char[] oldValue, const char[] newValue)
{
    convar.IntValue = iDefMoney;
    if(!bFirstRound) mp_startmoney.IntValue = iDefMoney;
}

public void OnMapStart()
{
    bFirstRound = true;
    mp_startmoney.IntValue = iFirstMoney;
}

public Action CS_OnTerminateRound(float& delay, CSRoundEndReason& reason)
{
    static bool start;
    start = (reason == CSRoundEnd_GameStart);
    if(bFirstRound != start)
    {
        bFirstRound = start;
        mp_startmoney.IntValue = bFirstRound ? iFirstMoney : iDefMoney;
        if(m_iAccount > 0) for(int i = 1, diff = iDefMoney - iFirstMoney; i <= MaxClients; i++)
            if(IsClientInGame(i)) SetEntData(i, m_iAccount, GetEntData(i, m_iAccount) + diff);
    }

    return Plugin_Continue;
}
 

Grey83

не пишу плагины с весны 2022
Сообщения
8,521
Реакции
4,980
@Clark Kent, нужно чтобы плагин смены сторон выдавал деньги
Ну или создавал форвард и сообщал о событии смены команд.
Потому что смена команд не хукается ничем, емнип.
 

Madness aka null138

Участник
Сообщения
713
Реакции
734
Здравствуйте, кто подскажет, как сделать так, чтобы в 1 раунде и после мены сторон было 800 долларов, а в остальных раундах по 16к?

исходник:
#pragma semicolon 1

#include <cstrike>

ConVar mp_startmoney;

bool bFirstRound;
int m_iAccount,
    iFirstMoney,
    iDefMoney;

public Plugin:myinfo =
{
        name        = "First round startmoney",
        author        = "Grey83",
        description    = "Changes the initial amount of money for the first round.",
        version        = "1.0.1",
        url            = "https://steamcommunity.com/groups/grey83ds"
};

public void OnPluginStart()
{
    EngineVersion ver = GetEngineVersion();
    if(ver != Engine_CSS && ver != Engine_CSGO) SetFailState("Plugin for CS:S and CS:GO only!");

    m_iAccount = FindSendPropInfo("CCSPlayer", "m_iAccount");

    (mp_startmoney = CreateConVar("sm_startmoney_first", "800", "Сколько денег будет выдавать в первом раунде", _, true, 800.0, true, 16000.0)).AddChangeHook(CVarChange_First);
    iFirstMoney = mp_startmoney.IntValue;

    (mp_startmoney = CreateConVar("sm_startmoney_def", "16000", "Сколько денег будет выдавать в начале каждого из всех остальных раундов", _, true, 800.0, true, 16000.0)).AddChangeHook(CVarChange_Def);
    iDefMoney = mp_startmoney.IntValue;
   
    AutoExecConfig(true, "StartMoney");

    if((mp_startmoney = FindConVar("mp_startmoney")) == null) SetFailState("Can't find ConVar 'mp_startmoney'!");
}

public void CVarChange_First(ConVar convar, const char[] oldValue, const char[] newValue)
{
    convar.IntValue = iFirstMoney;
    if(bFirstRound) mp_startmoney.IntValue = iFirstMoney;
}

public void CVarChange_Def(ConVar convar, const char[] oldValue, const char[] newValue)
{
    convar.IntValue = iDefMoney;
    if(!bFirstRound) mp_startmoney.IntValue = iDefMoney;
}

public void OnMapStart()
{
    bFirstRound = true;
    mp_startmoney.IntValue = iFirstMoney;
}

public Action CS_OnTerminateRound(float& delay, CSRoundEndReason& reason)
{
    static bool start;
    start = (reason == CSRoundEnd_GameStart);
    if(bFirstRound != start)
    {
        bFirstRound = start;
        mp_startmoney.IntValue = bFirstRound ? iFirstMoney : iDefMoney;
        if(m_iAccount > 0) for(int i = 1, diff = iDefMoney - iFirstMoney; i <= MaxClients; i++)
            if(IsClientInGame(i)) SetEntData(i, m_iAccount, GetEntData(i, m_iAccount) + diff);
    }

    return Plugin_Continue;
}
когда то давно писал такой плагин. конечно не проверял, но судя по автору темы плагин рабочий.
 

Grey83

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

babka68

Участник
Сообщения
2,124
Реакции
956
Всем привет,можете накидать пример кода по ниже перечисленному?
У меня есть плагин,который при определенных событиях выдает определенное кол-во ХП,как можно в него добавить ConVar,отвечающий еще за выпадание аптечки,после смерти игрока и она могла давать Хп в зависимости от типа убийства к примеру хеадшот,но не превышало максимального Хп,установленного в ConVar

Пример уже имеющегося кода кода кинут не могу=)
 

Nekro

Терра инкогнита
Сообщения
4,025
Реакции
2,260
Всем привет,можете накидать пример кода по ниже перечисленному?
У меня есть плагин,который при определенных событиях выдает определенное кол-во ХП,как можно в него добавить ConVar,отвечающий еще за выпадание аптечки,после смерти игрока и она могла давать Хп в зависимости от типа убийства к примеру хеадшот,но не превышало максимального Хп,установленного в ConVar

Пример уже имеющегося кода кода кинут не могу=)
Есть же плагин оптечек, его возьми и чекай варианты убийства
 

Hushang

Участник
Сообщения
134
Реакции
26
@Grey83, а если сделать так, по дефолту стоит 30 раундов, смена происходит после 15 раунда, т.е на 16, каким образом можно сделать так, чтобы в 1 и 16 раунде было по 800?
 

RusJJ

Доброе утро девачьки
Сообщения
2,582
Реакции
1,075
@Clark Kent, если в начале раунда сумма побед команд = 0 или = 15, то ставить 800. Наверное.
 

Grey83

не пишу плагины с весны 2022
Сообщения
8,521
Реакции
4,980
@Clark Kent, можно хукать смену команды и при первом спавне после смены команды давать $800.
т.е. даже если войти на сервак посреди игры и зайти за какую-то команду будет $800 при первом возрождении.
М/б и прокатит такое (и не будут ради бабла прыгать м/у командами ^_^).
 

Hushang

Участник
Сообщения
134
Реакции
26
@Grey83, да есть такой момент когда во время пистолетки заходили на сервер и покупали другие оружия
но с вашим плагином такого вроде не наблюдаю, но как реализовать того что вы описали выше, я в sp не силён(
 

Paranoiiik

хачю клиентмод
Сообщения
2,047
Реакции
1,490
C++:
#pragma semicolon 1
#pragma newdecls required

char
    sNick[MAX_NAME_LENGTH],
    sAdminsFlag[16];

public void OnPluginStart()
{
    ConVar cvar;

    cvar = CreateConVar("test_admins_flag",                "b",    "Игрок - Админ");
    cvar.AddChangeHook(CVarChanged_AdminsFlag);
    cvar.GetString(sAdminsFlag, sizeof(sAdminsFlag));

    HookEvent("player_connect",    Event_BlockBroadcast, EventHookMode_Pre);
}

public void CVarChanged_AdminsFlag(ConVar cvar, const char[] oldVal, const char[] newVal)
{
    cvar.GetString(sAdminsFlag, sizeof(sAdminsFlag));
}

public void Event_BlockBroadcast(Event event, const char[] name, bool dontBroadcast)
{
    if(!dontBroadcast)
        event.BroadcastDisabled = true;

    int client = GetClientOfUserId(GetEventInt(event, "userid"));

    if(client && IsClientInGame(client) && !IsFakeClient(client))
    {
        if(GetUserFlagBits(client) & ReadFlagString(sAdminsFlag))    PrintToChatAll("Админ %s заходит на сервер", sNick);
        else                                                         PrintToChatAll("%s заходит на сервер", sNick);
    }
}
Если убрать в начале условия client на 31-й строке, пишет Client index 0 is invalid.
Если оставить, код в условии не выполняется.

По моему скромному предположению - на стадии player_connect нельзя пытаться определить, есть ли у игрока админские флаги.
Так ли это? Подскажите, пожалуйста, если можно определять, то как (примером в виде куска кода)? Понимаю, что, скорее всего, просто неправильно выстраиваю условие (хотя выглядит задача крайне простой (на первый мой взгляд)).
 

xstage

🏹
Сообщения
726
Реакции
754
C++:
#pragma semicolon 1
#pragma newdecls required

char
    sNick[MAX_NAME_LENGTH],
    sAdminsFlag[16];

public void OnPluginStart()
{
    ConVar cvar;

    cvar = CreateConVar("test_admins_flag",                "b",    "Игрок - Админ");
    cvar.AddChangeHook(CVarChanged_AdminsFlag);
    cvar.GetString(sAdminsFlag, sizeof(sAdminsFlag));

    HookEvent("player_connect",    Event_BlockBroadcast, EventHookMode_Pre);
}

public void CVarChanged_AdminsFlag(ConVar cvar, const char[] oldVal, const char[] newVal)
{
    cvar.GetString(sAdminsFlag, sizeof(sAdminsFlag));
}

public void Event_BlockBroadcast(Event event, const char[] name, bool dontBroadcast)
{
    if(!dontBroadcast)
        event.BroadcastDisabled = true;

    int client = GetClientOfUserId(GetEventInt(event, "userid"));

    if(client && IsClientInGame(client) && !IsFakeClient(client))
    {
        if(GetUserFlagBits(client) & ReadFlagString(sAdminsFlag))    PrintToChatAll("Админ %s заходит на сервер", sNick);
        else                                                         PrintToChatAll("%s заходит на сервер", sNick);
    }
}
Если убрать в начале условия client на 31-й строке, пишет Client index 0 is invalid.
Если оставить, код в условии не выполняется.

По моему скромному предположению - на стадии player_connect нельзя пытаться определить, есть ли у игрока админские флаги.
Так ли это? Подскажите, пожалуйста, если можно определять, то как (примером в виде куска кода)? Понимаю, что, скорее всего, просто не правильно выстраиваю условие (хотя выглядит задача крайне простой (на первый мой взгляд)).
Нет смысла хукать player_connect используй функцию OnClientPutInServer
Для проверки на админа можно использовать GetUserFlagBits(int client)
 

Paranoiiik

хачю клиентмод
Сообщения
2,047
Реакции
1,490
используй функцию OnClientPutInServer
Просто мне нужна была именно эта стадия, чтобы печатать сообщение именно при этом событии.
Я отлавливаю момент, когда игрок только начал подключаться (player_connect), когда он уже подключился (OnClientPostAdminCheck), когда сменил команду (player_team) и когда отключился (player_disconnect) - при всех печатаю свои сообщения.
Наличие админ-флагов можно определять только после OnClientPostAdminCheck(). До этого момента, сервер не знает SteamID достоверно.
Ля, вроде такая логичная штука, а я до этого не додумался. Понял, спасибо!
 

babka68

Участник
Сообщения
2,124
Реакции
956
Всем привет,помогите исправить ошибки в модуле


Errors:
L 12/20/2020 - 17:18:12: SourceMod error session started
L 12/20/2020 - 17:18:12: Info (map "de_dust2") (file "/servers/css/1035/cstrike/addons/sourcemod/logs/errors_20201220.log")
L 12/20/2020 - 17:18:12: [SM] Exception reported: Invalid index 0 (count: 0)
L 12/20/2020 - 17:18:12: [SM] Blaming: cssdm/dm_give_ent.smx
L 12/20/2020 - 17:18:12: [SM] Call stack trace:
L 12/20/2020 - 17:18:12: [SM]   [0] GetArrayString
L 12/20/2020 - 17:18:12: [SM]   [1] Line 462, addons\sourcemod\scripting\cssdm\dm_give_ent.sp::OnGiveWeapon
L 12/20/2020 - 17:18:12: [SM]   [2] Line 277, addons\sourcemod\scripting\cssdm\dm_give_ent.sp::OnClientSpawnedPost

277
C-подобный:
OnGiveWeapon(client);
277:
public Action:OnClientSpawnedPost(Handle:timer, any:client)
{
   if (!IsClientInGame(client))return;
   if (!IsPlayerAlive(client))return;
   
   if (!IsFakeClient(client))
   {
       g_tMenu[client] = 0;
       menu_DM_Spawn(client);
   }
   else
   {
       g_iPrimary[client] = -1;
       g_iSecondary[client] = -1;
       OnGiveWeapon(client);
   }
   OnGiveItems(client);
}


462 строка
C-подобный:
GetArrayString(array_Primary, g_iPrimary[client] > -1 ? g_iPrimary[client] : GetRandomInt(0, GetArraySize(array_Primary) - 1), sWeapon, sizeof(sWeapon));

C-подобный:
OnGiveWeapon(client)
{
    new String:sWeapon[64];
    WeaponHandler(client, 0);
    GetArrayString(array_Primary, g_iPrimary[client] > -1 ? g_iPrimary[client] : GetRandomInt(0, GetArraySize(array_Primary) - 1), sWeapon, sizeof(sWeapon));
    GiveClientItem(client, sWeapon);
   
    WeaponHandler(client, 1);
    GetArrayString(array_Secondary, g_iSecondary[client] > -1 ? g_iSecondary[client] : GetRandomInt(0, GetArraySize(array_Secondary) - 1), sWeapon, sizeof(sWeapon));
    GiveClientItem(client, sWeapon);
}
 

romeo7

Участник
Сообщения
189
Реакции
93
Всем привет,помогите исправить ошибки в модуле


Errors:
L 12/20/2020 - 17:18:12: SourceMod error session started
L 12/20/2020 - 17:18:12: Info (map "de_dust2") (file "/servers/css/1035/cstrike/addons/sourcemod/logs/errors_20201220.log")
L 12/20/2020 - 17:18:12: [SM] Exception reported: Invalid index 0 (count: 0)
L 12/20/2020 - 17:18:12: [SM] Blaming: cssdm/dm_give_ent.smx
L 12/20/2020 - 17:18:12: [SM] Call stack trace:
L 12/20/2020 - 17:18:12: [SM]   [0] GetArrayString
L 12/20/2020 - 17:18:12: [SM]   [1] Line 462, addons\sourcemod\scripting\cssdm\dm_give_ent.sp::OnGiveWeapon
L 12/20/2020 - 17:18:12: [SM]   [2] Line 277, addons\sourcemod\scripting\cssdm\dm_give_ent.sp::OnClientSpawnedPost

277
C-подобный:
OnGiveWeapon(client);
277:
public Action:OnClientSpawnedPost(Handle:timer, any:client)
{
   if (!IsClientInGame(client))return;
   if (!IsPlayerAlive(client))return;
 
   if (!IsFakeClient(client))
   {
       g_tMenu[client] = 0;
       menu_DM_Spawn(client);
   }
   else
   {
       g_iPrimary[client] = -1;
       g_iSecondary[client] = -1;
       OnGiveWeapon(client);
   }
   OnGiveItems(client);
}


462 строка
C-подобный:
GetArrayString(array_Primary, g_iPrimary[client] > -1 ? g_iPrimary[client] : GetRandomInt(0, GetArraySize(array_Primary) - 1), sWeapon, sizeof(sWeapon));

C-подобный:
OnGiveWeapon(client)
{
    new String:sWeapon[64];
    WeaponHandler(client, 0);
    GetArrayString(array_Primary, g_iPrimary[client] > -1 ? g_iPrimary[client] : GetRandomInt(0, GetArraySize(array_Primary) - 1), sWeapon, sizeof(sWeapon));
    GiveClientItem(client, sWeapon);
 
    WeaponHandler(client, 1);
    GetArrayString(array_Secondary, g_iSecondary[client] > -1 ? g_iSecondary[client] : GetRandomInt(0, GetArraySize(array_Secondary) - 1), sWeapon, sizeof(sWeapon));
    GiveClientItem(client, sWeapon);
}
(count: 0) Это означает, что массив пуст. Сначала проверьте размер массива. GetArraySize(Handle array) > 0.
 

D1fox

Просто люблю чай
Сообщения
902
Реакции
212
Требуется плагин который будет перехватывать указанные мной звуки.
Функционал:
1. CFG не обязательно
2. В .sp указываешь путь и название которое будет в меню
3. По команде, открывается меню в котором название которое было указано в .sp далее человек может выкл данные звук и тот путь, который был привязан к этому названию больше не воспроизводится у игрока
Пример: sm_music, вид меню:
Звуки сервера HLMOD

1. Музыка в чате (в .sp выглядит +- так, music/chat/hlmod.mp3) и то есть заходим в "Музыка в чате" и в данном под меню есть кнопка "Отключить" после ее нажатия данные звук не играет
1.1 Отключить
2. Звуки событий
2.1 Отключить
Игра: CSGO
SM 1.10
 
Сверху Снизу