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

NeLifeASkazka

Участник
Сообщения
128
Реакции
70
Добрый день. Подскажите пожалуйста, почему выдает ошибку:
L 08/28/2024 - 13:58:14: [SM] Exception reported: Invalid WeaponID passed for this game
L 08/28/2024 - 13:58:14: [SM] Blaming: test.smx
L 08/28/2024 - 13:58:14: [SM] Call stack trace:
L 08/28/2024 - 13:58:14: [SM] [0] CS_GetWeaponPrice
L 08/28/2024 - 13:58:14: [SM] [1] Line 14, D:\ONEdRIVE\Desktop\�����������\1.11 scripting\test.sp::CS_OnCSWeaponDrop
C-подобный:
#include <cstrike>

int g_iCountDropWeapon[MAXPLAYERS + 1],
    g_iWeaponDropValue[MAXPLAYERS + 1];

public void OnPluginStart()
{
    HookEvent("round_start", Events_Round, EventHookMode_PostNoCopy);
}

public Action CS_OnCSWeaponDrop(int iClient, int iIndex)
{
    g_iCountDropWeapon[iClient]++;
    int iMoney = CS_GetWeaponPrice(iClient, view_as<CSWeaponID>(iIndex)); (ТУТ ОШИБКА)
    g_iWeaponDropValue[iClient] += iMoney;
}

public void OnClientDisconnect(int iClient)
{
    g_iCountDropWeapon[iClient] = g_iWeaponDropValue[iClient] = 0;
}

public Action Events_Round(Event hEvent, const char[] sName, bool bDontBroadcast)
{
    for (int i = 1; i <= MaxClients; i++)
    {
        g_iCountDropWeapon[i] = g_iWeaponDropValue[i] = 0;
    }
}

Пример использования функции CS_GetWeaponPrice(iClient, view_as<CSWeaponID>(iIndex)); брал из weapon_restrict, там ошибки нет, у меня есть

Попробуй так:

code:
public Action CS_OnCSWeaponDrop(int iClient, int iIndex){
    g_iCountDropWeapon[iClient]++;

    int iDefinitionIndex = GetEntProp(iIndex, Prop_Send, "m_iItemDefinitionIndex");
    
    CSWeaponID cs_WeaponId = CS_ItemDefIndexToID(iDefinitionIndex);
    
    if(cs_WeaponId != CSWeapon_NONE){
        int iMoney = CS_GetWeaponPrice(iClient, cs_WeaponId);
        g_iWeaponDropValue[iClient] += iMoney;
    }

    return Plugin_Continue;
}
 

7pElllHuK

Участник
Сообщения
1,416
Реакции
465
Попробуй так:

code:
public Action CS_OnCSWeaponDrop(int iClient, int iIndex){
    g_iCountDropWeapon[iClient]++;

    int iDefinitionIndex = GetEntProp(iIndex, Prop_Send, "m_iItemDefinitionIndex");
   
    CSWeaponID cs_WeaponId = CS_ItemDefIndexToID(iDefinitionIndex);
   
    if(cs_WeaponId != CSWeapon_NONE){
        int iMoney = CS_GetWeaponPrice(iClient, cs_WeaponId);
        g_iWeaponDropValue[iClient] += iMoney;
    }

    return Plugin_Continue;
}
[SM] Exception reported: Property "m_iItemDefinitionIndex" not found (entity 41/weapon_glock)
34 css
 

NeLifeASkazka

Участник
Сообщения
128
Реакции
70
[SM] Exception reported: Property "m_iItemDefinitionIndex" not found (entity 41/weapon_glock)
34 css
Тогда, думаю, только так:
code:
public int GetWeaponPrice(int weapon){
    static const char cWeapPrices[][][] = {
        { "weapon_usp",       "500"  },
        { "weapon_glock",     "400"  },
        { "weapon_p228",      "600"  },
        { "weapon_deagle",    "650"  },
        { "weapon_fiveseven", "750"  },
        { "weapon_elite",     "800"  },
        { "weapon_tmp",       "1250" },
        { "weapon_ump45",     "1700" },
        { "weapon_mac10",     "1400" },
        { "weapon_mp5navy",   "1500" },
        { "weapon_p90",       "2350" },
        { "weapon_famas",     "2250" },
        { "weapon_galil",     "2000" },
        { "weapon_m4a1",      "3100" },
        { "weapon_ak47",      "2700" },
        { "weapon_aug",       "3500" },
        { "weapon_sg552",     "3500" },
        { "weapon_scout",     "2750" },
        { "weapon_awp",       "4750" },
        { "weapon_g3sg1",     "5000" },
        { "weapon_sg550",     "4200" },
        { "weapon_m249",      "5750" },
        { "weapon_m3",        "1700" },
        { "weapon_xm1014",    "3000" },
    };
    
    char classname[32]; GetEntityClassname(weapon, classname, sizeof(classname));
    for(int x = 0; x < sizeof(cWeapPrices); x++){
        if(StrEqual(classname, cWeapPrices[x][0], false)){
            return StringToInt(cWeapPrices[x][1]);
        }
    }
    return -1;
}
 

Grey83

не пишу плагины с весны 2022
Сообщения
8,521
Реакции
4,980
@NeLifeASkazka, я бы цены в int хранил, а не в char.
Ну и в char убрал «weapon_».

А лучше загнал бы эти данные в StringMap и избавился от цикла со StringEqual().
 

7pElllHuK

Участник
Сообщения
1,416
Реакции
465
Тогда, думаю, только так:
code:
public int GetWeaponPrice(int weapon){
    static const char cWeapPrices[][][] = {
        { "weapon_usp",       "500"  },
        { "weapon_glock",     "400"  },
        { "weapon_p228",      "600"  },
        { "weapon_deagle",    "650"  },
        { "weapon_fiveseven", "750"  },
        { "weapon_elite",     "800"  },
        { "weapon_tmp",       "1250" },
        { "weapon_ump45",     "1700" },
        { "weapon_mac10",     "1400" },
        { "weapon_mp5navy",   "1500" },
        { "weapon_p90",       "2350" },
        { "weapon_famas",     "2250" },
        { "weapon_galil",     "2000" },
        { "weapon_m4a1",      "3100" },
        { "weapon_ak47",      "2700" },
        { "weapon_aug",       "3500" },
        { "weapon_sg552",     "3500" },
        { "weapon_scout",     "2750" },
        { "weapon_awp",       "4750" },
        { "weapon_g3sg1",     "5000" },
        { "weapon_sg550",     "4200" },
        { "weapon_m249",      "5750" },
        { "weapon_m3",        "1700" },
        { "weapon_xm1014",    "3000" },
    };
   
    char classname[32]; GetEntityClassname(weapon, classname, sizeof(classname));
    for(int x = 0; x < sizeof(cWeapPrices); x++){
        if(StrEqual(classname, cWeapPrices[x][0], false)){
            return StringToInt(cWeapPrices[x][1]);
        }
    }
    return -1;
}
Чуть позже проверю. Спасибо большое
 

_wS_

Участник
Сообщения
383
Реакции
760
- По логике, стоимость оружия лучше получать через CS_GetWeaponPrice, чтобы другие plugins могли её изменить в CS_OnGetWeaponPrice.
- В CS_OnCSWeaponDrop выброс оружия может быть заблокирован, поэтому надёжнее использовать SDKHook_WeaponDropPost.

PHP:
stock CSWeaponID WeaponIndexToId(int weapon)
{
    char classname[24];
    return GetEdictClassname(weapon, classname, sizeof(classname)) ? CS_AliasToWeaponID(classname) : CSWeapon_NONE;
}

public Action CS_OnCSWeaponDrop(int iClient, int iIndex)
{
    ++g_iCountDropWeapon[iClient];

    CSWeaponID id = WeaponIndexToId(iIndex);
    if (id) {
        g_iWeaponDropValue[iClient] += CS_GetWeaponPrice(iClient, id);
    }

    return Plugin_Continue;
}
 

7pElllHuK

Участник
Сообщения
1,416
Реакции
465
- По логике, стоимость оружия лучше получать через CS_GetWeaponPrice, чтобы другие plugins могли её изменить в CS_OnGetWeaponPrice.
- В CS_OnCSWeaponDrop выброс оружия может быть заблокирован, поэтому надёжнее использовать SDKHook_WeaponDropPost.

PHP:
stock CSWeaponID WeaponIndexToId(int weapon)
{
    char classname[24];
    return GetEdictClassname(weapon, classname, sizeof(classname)) ? CS_AliasToWeaponID(classname) : CSWeapon_NONE;
}

public Action CS_OnCSWeaponDrop(int iClient, int iIndex)
{
    ++g_iCountDropWeapon[iClient];

    CSWeaponID id = WeaponIndexToId(iIndex);
    if (id) {
        g_iWeaponDropValue[iClient] += CS_GetWeaponPrice(iClient, id);
    }

    return Plugin_Continue;
}
Огромное спасибо, все замечательно работает, я до такого способа бы в жизни не догадался
 

7pElllHuK

Участник
Сообщения
1,416
Реакции
465

khood

Участник
Сообщения
214
Реакции
51
Здравствуйте Подскажите, пожалуйста, как можно определить, на какой точке установлена бомба? A - B
 

Grey83

не пишу плагины с весны 2022
Сообщения
8,521
Реакции
4,980
@khood, я когда-то вроде такой код писал.
Вот тут код глянь:
 

khood

Участник
Сообщения
214
Реакции
51
@khood, я когда-то вроде такой код писал.
Вот тут код глянь:
Благодарю 👍
 

7pElllHuK

Участник
Сообщения
1,416
Реакции
465
Доброй утро, подскажите пожалуйста, можно ли как-то автоматически проверять стоит ли на сервере Clientmod API для того чтоб выводить цвета из colors в случае отсутствия CM API?
Я нашел 2 варианта
1 - в ручную менять значение #define (пример ниже)
2 - проверять наличие плагина ClienMod.smx и при его присутствии выводить цвета для игроков с CM

Первый вариант не особо удобный, хочется автоматизировать данный процесс, а 2 будет выполнять лишние действия (искать нужный нам плагин)

Пример 1 варианта:
#undef REQUIRE_EXTENSIONS
#tryinclude <clientmod>
#tryinclude <clientmod/multicolors>
#tryinclude <colors>

#define MODE 1        // 1 - cliemtmod
                    // 2 - colors

#if MODE == 1
    #if !defined _clientmod_included
    #error Where is FUCKING ClientMod?
    #endif

#else
    if MODE == 2
    #if !defined _colors_included
    #error Where is FUCKING Colors?
    #endif

#else
#error Выберите значение от 1 до 2
#endif

public void OnPluginStart()
{
    RegConsoleCmd("sm_donate", Command_Menu);
}

public Action Command_Menu(int iClient, int iArgs)
{
    #if MODE == 1
    MC_PrintToChat(iClient, "{aqua}Цвета дя CM");
    C_PrintToChat(iClient, "{red}CM Но для ксс");

    #else
    CPrintToChat("{red} Цвета для ксс");
    #endif

    return Plugin_Handled;
}
 

Grey83

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

Вроде в самих инклюдах раскраски для клиентмода было определение кому какое сообщение слать.
 

7pElllHuK

Участник
Сообщения
1,416
Реакции
465
@7pElllHuK, ты в коде проверяешь есть ли у компилятора инклюд клиентмода.

Вроде в самих инклюдах раскраски для клиентмода было определение кому какое сообщение слать.
Там оно есть, пробовал просто подключать библиотеки км, но без КМ АПИ ничего не выводится
 

Ice_Sochi

Участник
Сообщения
709
Реакции
413
@7pElllHuK я точно не знаю, ибо не сталкивался с подобными конструкциями, но если б сам делал, для начала попробовал бы натыкать что-то такое.


Еще нужно используемые нативы клиентмода отметить как опциональные (MarkNativeAsOptional), по памяти с телефона не вспомню правильно:
#undef REQUIRE_EXTENSIONS
#tryinclude <clientmod>
#tryinclude <clientmod/multicolors>
#tryinclude <colors>

bool bCM = true;

#if !defined _clientmod_included
    bCM = false;
#endif

public void OnPluginStart()
{
    RegConsoleCmd("sm_donate", Command_Menu);
}

public Action Command_Menu(int iClient, int iArgs)
{
    if(bCM && CM_IsClientModUser(iClient)) //не помню точно саму проверку на км игрока, вроде там еще есть аргумент
    {
        MC_PrintToChat(iClient, "{aqua}Цвета дя CM");
    }
    else C_PrintToChat(iClient, "{red}Цвета не для км");

    return Plugin_Handled;
}
 

Grey83

не пишу плагины с весны 2022
Сообщения
8,521
Реакции
4,980
@Ice_Sochi, у тебя не скомпилится, если нет инклюдов клиентмода.
Компилятору нужно #if...#endif
 
Сверху Снизу