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

Тема в разделе "Программирование / Скриптинг", создана пользователем cfgmazda, 2 дек 2013.

  1. cfgmazda

    cfgmazda

    Сообщения:
    53
    Симпатии:
    35
    Подскажите что я сделал не так.
    суть скрипта когда игрок пишет команду к примеру:
    держи 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(clientargs)
    {
        
    decl String:text[192];
        if (!
    GetCmdArgString(textsizeof(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(clientargs);
            return 
    Plugin_Handled;
        }
        return 
    Plugin_Continue;
    }

    GiveCoins(clientargs) {
        new 
    String:arg[65], String:arg2[20];
        
    GetCmdArg(1argsizeof(arg));
        new 
    coins;
        
        if (
    args 2) {
            
    ReplyToCommand(client"%t %t""Prefix""Wrong Command");
            return 
    0;
        }
        
        if (
    args >= && GetCmdArg(2arg2sizeof(arg2))) {
            
    coins StringToInt(arg2);
            
    GetCmdArg(1arg1sizeof(arg2));
        }
        if (
    coins == || 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(clienttarget_count);
            return 
    0;
        }
        
        for (new 
    0target_counti++) {
            
    g_deathrunpoints[target_list[i]] += coins;
            
    g_deathrunpoints[client] -= coins;
            
    SavePoints(target_list[i]);
        }
        
        
    decl String:Giver[128];
        
    GetClientName(clientGiversizeof(Giver));
        
        if (
    tn_is_ml) {
            
    PrintToChatAll("\x04%t \x01%s %t %s, \x03%d \x01%t!""Prefix"Giver"Give to"target_namecoins"Name Coins");
        } else {
            
    PrintToChatAll("\x04%t \x01%s %t %s, \x03%d \x01%t!""Prefix"Giver"Give to"target_namecoins"Name Coins");
        }
        return 
    0;
    }
     
  2. Reiko1231

    Reiko1231 AlexTheRegent

    Сообщения:
    235
    Симпатии:
    568
    По идее это должно быть как-то так (не проверял, но компилировал - одна ошибка - "неизвестная функция SavePoints()":
    Код:
    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;
    }
     
    NagarD нравится это.
  3. cfgmazda

    cfgmazda

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

    Reiko1231 AlexTheRegent

    Сообщения:
    235
    Симпатии:
    568
    Моя ошибка, не знал, что при командах в чат сказанное идет целым аргументом. Так же исправил логическую ошибку при проверке на правильность введенного значения передаваемых кредитов - т.к. используется ProcessTargetString, то можно передавать как give @all 100, и при 100 кредитах будет передано (100*количество игроков на сервере), и можно было уйти в минус.
    Код:
    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;
    }
     
    Последнее редактирование: 2 дек 2013
    gravestal, cfgmazda, White Wolf и 3 другим нравится это.
  5. cfgmazda

    cfgmazda

    Сообщения:
    53
    Симпатии:
    35
    супер, спасибо.