Command_Say помогите разобраться.

cfgmazda

Участник
Сообщения
53
Реакции
34
Подскажите что я сделал не так.
суть скрипта когда игрок пишет команду к примеру:
держи target 15
должны передаваться игровые монеты.

из Command_Say args не передаются в GiveCoins.
как исправить?

PHP:
new client_coins[MAXPLAYERS+1];

public OnPluginStart() {
    RegConsoleCmd("say", Command_Say);
    RegConsoleCmd("say_team", Command_Say);
    RegConsoleCmd("say2", Command_Say);
}
public Action:Command_Say(client, args)
{
    decl String:text[192];
    if (!GetCmdArgString(text, sizeof(text))) {
        return Plugin_Continue;
    }
    
    new startidx;
    if(text[strlen(text)-1] == '"') {
        text[strlen(text)-1] = '\0';
        startidx = 1;
    }
    
    if (text[startidx] == '!' || text[startidx] == '/')  {
        startidx++;
    }
    
    if (StrEqual(text[startidx], "give", true)
    || StrEqual(text[startidx], "дать", true)
    || StrEqual(text[startidx], "держи", true)
    || StrEqual(text[startidx], "передать", true)
    || StrEqual(text[startidx], "отдать", true)
    || StrEqual(text[startidx], "подарить", true)) {
        GiveCoins(client, args);
        return Plugin_Handled;
    }
    return Plugin_Continue;
}

GiveCoins(client, args) {
    new String:arg[65], String:arg2[20];
    GetCmdArg(1, arg, sizeof(arg));
    new coins;
    
    if (args < 2) {
        ReplyToCommand(client, "%t %t", "Prefix", "Wrong Command");
        return 0;
    }
    
    if (args >= 2 && GetCmdArg(2, arg2, sizeof(arg2))) {
        coins = StringToInt(arg2);
        GetCmdArg(1, arg1, sizeof(arg2));
    }
    if (coins == 0 || coins < 0) {
        ReplyToCommand(client, "%t %t", "Prefix", "Need set coins more 0");
        return 0;
    }
    if (coins > client_coins[client]) {
        ReplyToCommand(client, "%t %t", "Prefix", "No Coins");
        return 0;
    }
    new String:target_name[MAX_TARGET_LENGTH];
    new target_list[MAXPLAYERS], target_count;
    new bool:tn_is_ml;
    
    if ((target_count = ProcessTargetString(
            arg,
            client,
            target_list,
            MAXPLAYERS,
            COMMAND_FILTER_NO_BOTS|COMMAND_FILTER_CONNECTED,
            target_name,
            sizeof(target_name),
            tn_is_ml)) <= 0) 
    {
        ReplyToTargetError(client, target_count);
        return 0;
    }
    
    for (new i = 0; i < target_count; i++) {
        g_deathrunpoints[target_list[i]] += coins;
        g_deathrunpoints[client] -= coins;
        SavePoints(target_list[i]);
    }
    
    decl String:Giver[128];
    GetClientName(client, Giver, sizeof(Giver));
    
    if (tn_is_ml) {
        PrintToChatAll("\x04%t \x01%s %t %s, \x03%d \x01%t!", "Prefix", Giver, "Give to", target_name, coins, "Name Coins");
    } else {
        PrintToChatAll("\x04%t \x01%s %t %s, \x03%d \x01%t!", "Prefix", Giver, "Give to", target_name, coins, "Name Coins");
    }
    return 0;
}
 

Reiko1231

AlexTheRegent
Сообщения
508
Реакции
1,336
По идее это должно быть как-то так (не проверял, но компилировал - одна ошибка - "неизвестная функция SavePoints()":
C-подобный:
new iClientCoins[MAXPLAYERS+1];

public OnPluginStart()
{
    // Команды say, say2, say_team уже существуют и второй раз
    // их не надо регистрировать. Достаточно добавить листенер.
    AddCommandListener(Listener_Say, "say");
    AddCommandListener(Listener_Say, "say2");
    AddCommandListener(Listener_Say, "say_team");
}

public Action:Listener_Say(iClient, const String:sCommand[], iArgs)
{
    // получаем первый аргумент
    decl String:sArg1[32];
    GetCmdArg(1, sArg1, sizeof(sArg1) - 1);
    
    // если это give или дать (для русского текст РегИсТр ВАЖЕН! даже
    // если поставить caseSensetive на false, толку от этого не будет.
    if ( StrEqual(sArg1, "give", false) || StrEqual(sArg1, "дать") )
    {
        // если в команде не три аргумента (give-кому-сколько)
        if ( GetCmdArgs() != 3 )
        {
            // пишем об ошибке
            PrintToChat(iClient, "wrong input");
            return Plugin_Handled;
        }
        
        // получаем цель и передаваемое количество кредитов
        decl String:sTarget[32], String:sTargetName[MAX_TARGET_LENGTH], String:sAmount[8],
             iTargetList[MAXPLAYERS], iTargetCount, bool:bTnIsMl, iAmount;
        GetCmdArg(2, sTarget, sizeof(sTarget) - 1);
        GetCmdArg(3, sAmount, sizeof(sAmount) - 1);
        
        // если передают неверное число кредитов (больше имеющихся или отрицательное количество)
        iAmount = StringToInt(sAmount);
        if ( iAmount > iClientCoins[iClient] || iAmount <= 0 )
        {
            // выводим об этом сообщение
            PrintToChat(iClient, "not enough money");
            return Plugin_Handled;
        }
        
        // ищем цели, удовлетворяющие вводу (userid, name, @aliases)
        if ((iTargetCount = ProcessTargetString(
                            sTarget,
                            iClient,
                            iTargetList,
                            MAXPLAYERS,
                            COMMAND_FILTER_NO_BOTS|COMMAND_FILTER_CONNECTED,
                            sTargetName,
                            sizeof(sTargetName),
                            bTnIsMl)) <= 0) 
        {
            // если цели не были найдены
            PrintToChat(iClient, "target not found");
            return Plugin_Handled;
        }
        
        // получаем имя передающего
        decl String:sClientName[32], String:sIName[32];
        GetClientName(iClient, sClientName, sizeof(sClientName) - 1);
        // по всем игрокам из найденных
        for ( new i = 0; i < iTargetCount; i++ )
        {
            // передаем кредиты
            iClientCoins[iTargetList[i]] += iAmount;
            // отнимаем кредиты
            iClientCoins[iClient] -= iAmount;
            // сохраняем получателю кредиты
            SavePoints(iTargetList[i]);
            
            // выводим сообщение всем о передаче кредитов
            GetClientName(iClient, sIName, sizeof(sIName) - 1);
            PrintToChatAll("%s gived to %s %d credits", sClientName, sIName, iAmount);
        }
        // сохраняем кредиты передавшего
        SavePoints(iClient);
        
        return Plugin_Handled;
    }
    
    // иначе пропускаем сообщение в чат
    return Plugin_Continue;
}
 

cfgmazda

Участник
Сообщения
53
Реакции
34
тоже самое... что и у меня когда я пишу give сервер отвечает: wrong input
если добавить еще 1 аргумент give player или 2 аргумента give player 5 он пишет мой текст и не выполняет никаких действий.
 

Reiko1231

AlexTheRegent
Сообщения
508
Реакции
1,336
Моя ошибка, не знал, что при командах в чат сказанное идет целым аргументом. Так же исправил логическую ошибку при проверке на правильность введенного значения передаваемых кредитов - т.к. используется ProcessTargetString, то можно передавать как give @all 100, и при 100 кредитах будет передано (100*количество игроков на сервере), и можно было уйти в минус.
C-подобный:
new g_iClientCoins[MAXPLAYERS+1];

public OnPluginStart()
{
    // Команды say, say2, say_team уже существуют и второй раз
    // их не надо регистрировать. Достаточно добавить листенер.
    AddCommandListener(Listener_Say, "say");
    AddCommandListener(Listener_Say, "say2");
    AddCommandListener(Listener_Say, "say_team");
}

public Action:Listener_Say(iClient, const String:sCommand[], iArgs)
{
    // получаем строку аргументов
    decl String:sText[128], String:sArg1[32];
    GetCmdArgString(sText, sizeof(sText) - 1);
    // убираем кавычки с начала и конца строки аргументов
    StripQuotes(sText);
    
    // извлекаем из строки аргументов первое слово (до пробела)
    // для данной задачи не нужно использовать ExplodeString, т.к.
    // нужно всего лишь два раза "разрезать" строку, значит найдем
    // позицию первого пробела и позже найдем для последнего
    // позиция первого пробела
    new iFirstPos = FindCharInString(sText, ' ') + 1;
    // помещаем в sArg1 первое слово
    strcopy(sArg1, iFirstPos, sText);
    
    // если это give или дать (для русского текст РегИсТр ВАЖЕН! даже
    // если поставить caseSensetive на false, толку от этого не будет.
    if ( StrEqual(sArg1, "give", false) || StrEqual(sArg1, "дать") )
    {
        // теперь извлекаем второе "слово" и третье. второе в кавычках, т.к. 
        // это будет то, что находится между первым и последним пробелом
        decl String:sTarget[32], String:sAmount[8];
        // позиция последнего пробела
        new iLastPos = FindCharInString(sText, ' ', true) + 1;
        // второе "слово"
        strcopy(sTarget, iLastPos - iFirstPos, sText[iFirstPos]);
        // и третье
        strcopy(sAmount, strlen(sText) - iLastPos + 1, sText[iLastPos]);
        
        // всё, что нужно для создания массива целей
        decl String:sTargetName[MAX_TARGET_LENGTH], iTargetList[MAXPLAYERS], 
             iTargetCount, bool:bTnIsMl, iAmount, iTotal;
        
        // ищем цели, удовлетворяющие вводу (userid, name, @aliases)
        if ((iTargetCount = ProcessTargetString(
                            sTarget,
                            iClient,
                            iTargetList,
                            MAXPLAYERS,
                            COMMAND_FILTER_NO_BOTS|COMMAND_FILTER_CONNECTED,
                            sTargetName,
                            sizeof(sTargetName),
                            bTnIsMl)) <= 0) 
        {
            // если цели не были найдены
            PrintToChat(iClient, "target not found");
            return Plugin_Handled;
        }
        
        // если передают неверное число кредитов (больше имеющихся или отрицательное количество
        iAmount = StringToInt(sAmount);
        // т.к. передаем массиву, то проверять надо на (количество целей * передаваемый размер)
        // а не на только передаваемый размер
        iTotal = iAmount * iTargetCount;
        if ( iTotal > g_iClientCoins[iClient] || iTotal <= 0 )
        {
            // выводим об этом сообщение
            PrintToChat(iClient, "not enough money");
            return Plugin_Handled;
        }
        
        // получаем имя передающего
        decl String:sClientName[32], String:sIName[32];
        GetClientName(iClient, sClientName, sizeof(sClientName) - 1);
        // по всем игрокам из найденных
        for ( new i = 0; i < iTargetCount; i++ )
        {
            // передаем кредиты
            g_iClientCoins[iTargetList[i]] += iAmount;
            // отнимаем кредиты
            g_iClientCoins[iClient] -= iAmount;
            // сохраняем получателю кредиты
            SavePoints(iTargetList[i]);
            
            // выводим сообщение всем о передаче кредитов
            GetClientName(iClient, sIName, sizeof(sIName) - 1);
            PrintToChatAll("%s gived to %s %d credits", sClientName, sIName, iAmount);
        }
        // сохраняем кредиты передавшего
        SavePoints(iClient);
        return Plugin_Handled;
    }
    
    return Plugin_Continue;
}
 
Последнее редактирование:
Сверху Снизу