Добро пожаловать на Pro Pawn - Портал о PAWN-скриптинге.
Показано с 1 по 6 из 6
  1. #1
    Аватар для gangzone.ini
    Пользователь

    Статус
    Оффлайн
    Регистрация
    15.06.2014
    Сообщений
    651
    Репутация:
    106 ±

    Как сделать поиск разделителя для команды /todo

    Возник вопрос по созданию команды /todo , с выводом текста

    PHP код:
    CMD:todo(playeridparams[])
    {
        if(
    sscanf(params"p<*>s[128]s[64]"params[0], params[1])) return SendClientMessage(playeridCOLOR_WHITE, !" Введите: /todo [текст] * [действие]");
    //    else if(sscanf(params, "%s'*'%s", params[0], params[1])) return SendClientMessage(playerid, COLOR_GREY, !"Используейте символ '*' для разделения. Пример: /todo привет * протянул руку");

        
    totalstring[0] = EOS;
        
    format(totalstringsizeof(totalstring), " %s {C2A2DA}- сказал(а) %s, %s"params[0], pInfo[playerid][pName], params[1]);
        
    SendActionMessage(playerid0xC8C8C8FFtotalstring15.0);
        return 
    true;

    Если с проверкой sscanf(params, "%s'*'%s", params[0], params[1] - ничего не происходит
    Если без проверки , /todo *a b текст проходит , а нужно /todo a * b , как так сделать ?
    Так же , текст не корректно выводиться , например /todo a*b , выводит "ab * b"
    Последний раз редактировалось gangzone.ini; 21.11.2019 в 15:07.

  2. #2
    Аватар для DeimoS
    Модератор?

    Статус
    Оффлайн
    Регистрация
    27.01.2014
    Адрес
    Восточный Мордор
    Сообщений
    5,588
    Репутация:
    1984 ±
    Во-первых, твоя команда не будет работать, ибо второй параметр, куда ты записываешь действие, перезапишет первый параметр, куда ты записываешь текст. "params" - это одномерный массив. И когда ты указываешь "params[1]" - это означает, что запись текста в массив начнётся с первой ячейки, а не то, что вдруг появится какой-то отдельный массив и в него запишется текст.

    Во-вторых, проще сделать так:
    1. CMD:todo(playerid, params[])
    2. {
    3. new find_pos = strfind(params, "*");
    4. if(find_pos == -1)
    5. return SendClientMessage(playerid, COLOR_WHITE, !" Введите: /todo [текст] * [действие]");
    6. params[find_pos] = '\0';
    7.  
    8. format(totalstring, sizeof(totalstring),
    9. " %s {C2A2DA}- сказал(а) %s, %s", params, pInfo[playerid][pName], params[find_pos+1]);
    10. SendActionMessage(playerid, 0xC8C8C8FF, totalstring, 15.0);
    11. return true;
    12. }

    Ибо и никакие дополнительные массивы вводить не нужно, и возиться с настройками sscanf
    Связаться со мной в VK можно через личные сообщения этой группы
    Заказы не принимаю

    Широко известно, что идеи стоят 0.8333 цента каждая (исходя из рыночной цены 10 центов за дюжину).
    Великих идей полно, на них нет спроса.
    Воплощение идеи в законченную игру требует долгой работы,
    таланта, терпения и креативности, не говоря уж о затратах денег, времени и ресурсов.
    Предложить идею просто, воплотить – вот в чём проблема

    Steve Pavlina

  3. Пользователь сказал cпасибо:
    gangzone.ini (21.11.2019)
  4. #3
    Аватар для gangzone.ini
    Пользователь

    Статус
    Оффлайн
    Регистрация
    15.06.2014
    Сообщений
    651
    Репутация:
    106 ±
    Цитата Сообщение от DeimoS Посмотреть сообщение
    Во-первых, твоя команда не будет работать, ибо второй параметр, куда ты записываешь действие, перезапишет первый параметр, куда ты записываешь текст. "params" - это одномерный массив. И когда ты указываешь "params[1]" - это означает, что запись текста в массив начнётся с первой ячейки, а не то, что вдруг появится какой-то отдельный массив и в него запишется текст.

    Во-вторых, проще сделать так:
    1. CMD:todo(playerid, params[])
    2. {
    3. new find_pos = strfind(params, "*");
    4. if(find_pos == -1)
    5. return SendClientMessage(playerid, COLOR_WHITE, !" Введите: /todo [текст] * [действие]");
    6. params[find_pos] = '\0';
    7.  
    8. format(totalstring, sizeof(totalstring),
    9. " %s {C2A2DA}- сказал(а) %s, %s", params, pInfo[playerid][pName], params[find_pos+1]);
    10. SendActionMessage(playerid, 0xC8C8C8FF, totalstring, 15.0);
    11. return true;
    12. }

    Ибо и никакие дополнительные массивы вводить не нужно, и возиться с настройками sscanf
    В любом месте можно поставить *
    /todo * a a

  5. #4
    Аватар для DeimoS
    Модератор?

    Статус
    Оффлайн
    Регистрация
    27.01.2014
    Адрес
    Восточный Мордор
    Сообщений
    5,588
    Репутация:
    1984 ±
    Цитата Сообщение от gangzone.ini Посмотреть сообщение
    В любом месте можно поставить *
    /todo * a a
    Ну так проверяй размер текста в params и params[find_pos+1].

    1. CMD:todo(playerid, params[])
    2. {
    3. new find_pos = strfind(params, "*");
    4. if(find_pos == -1)
    5. return SendClientMessage(playerid, COLOR_WHITE, !" Введите: /todo [текст] * [действие]");
    6. params[find_pos] = '\0';
    7. if(!strlen(params) || !strlen(params[find_pos+1]))
    8. return SendClientMessage(playerid, COLOR_WHITE, !" Введите: /todo [текст] * [действие]");
    9.  
    10. format(totalstring, sizeof(totalstring),
    11. " %s {C2A2DA}- сказал(а) %s, %s", params, pInfo[playerid][pName], params[find_pos+1]);
    12. SendActionMessage(playerid, 0xC8C8C8FF, totalstring, 15.0);
    13. return true;
    14. }
    Последний раз редактировалось DeimoS; 21.11.2019 в 16:34.
    Связаться со мной в VK можно через личные сообщения этой группы
    Заказы не принимаю

    Широко известно, что идеи стоят 0.8333 цента каждая (исходя из рыночной цены 10 центов за дюжину).
    Великих идей полно, на них нет спроса.
    Воплощение идеи в законченную игру требует долгой работы,
    таланта, терпения и креативности, не говоря уж о затратах денег, времени и ресурсов.
    Предложить идею просто, воплотить – вот в чём проблема

    Steve Pavlina

  6. Пользователь сказал cпасибо:
    gangzone.ini (21.11.2019)
  7. #5
    Аватар для SteveStage
    Пользователь

    Статус
    Оффлайн
    Регистрация
    05.10.2019
    Адрес
    Планета Земля
    Сообщений
    318
    Репутация:
    7 ±
    Лично я использую такую конструкцию:

    1. CMD:todo(playerid, params[])
    2. {
    3.  
    4. new
    5. text[21],
    6. action[31];
    7.  
    8. if(sscanf(params, "p<*>s[21]s[31]", text, action))
    9. return SCM(playerid, COLOR_YELLOW, !"Образец отыгровки фразы с действием: /todo [phrase]*[action]");
    10. if(text[20] != EOS)
    11. return SCM(playerid, COLOR_YELLOW, !"Максимальная длина реплики в отыгровке фразы с действием: 20 символов!");
    12. if(action[30] != EOS)
    13. return SCM(playerid, COLOR_YELLOW, !"Максимальная длина действия в отыгровке фразы с действием: 30 символов!");
    14. if(strlen(text) < 2)
    15. return SCM(playerid, COLOR_YELLOW, !"Минимальная длина отыгровки фразы в отыгровке фразы с действием: 2 символа!");
    16. if(strlen(action) < 2)
    17. return SCM(playerid, COLOR_YELLOW, !"Минимальная длина отыгровки действия в отыгровке фразы с действием: 2 символа!");
    18.  
    19. static const
    20. fmt_str[] = "'%s' - сказал%s %s, %s";
    21.  
    22. new
    23. str[sizeof(fmt_str)-6+MAX_PLAYER_NAME+30+20+1+1];
    24.  
    25. format(str, sizeof(str), fmt_str, text, (player[playerid][pSex] == 1) ? ("") : ("а"), GetName(playerid), action);
    26. ProxDetector(playerid, 20.0, COLOR_ACTION, str);
    27. SetPlayerChatBubble(playerid, str, COLOR_ACTION, 20.0, 4000);
    28. return true;
    29. }


    Не знаю насчет оптимизации, но багов с выводом текста не обнаружено

    Также такой вариант (многовато переменных)

    1. CMD:todo(playerid, params[])
    2. {
    3. new
    4. text[21],
    5. space[2],
    6. action[31];
    7. if(sscanf(params, "s[21]s[2]s[31]", text, space, action))
    8. return SCM(playerid, COLOR_YELLOW, !"Образец отыгровки фразы с действием: /todo [phrase] * [action]");
    9. if(!strcmp(text, "*") || !strcmp(action, "*") || strcmp(space, "*"))
    10. return SCM(playerid, COLOR_YELLOW, !"Образец отыгровки фразы с действием: /todo [phrase] * [action]");
    11. if(text[20] != EOS)
    12. return SCM(playerid, COLOR_YELLOW, !"Максимальная длина реплики в /todo: 20 символов!");
    13. if(action[30] != EOS)
    14. return SCM(playerid, COLOR_YELLOW, !"Максимальная длина действия в /todo: 30 символов!");
    15. if(strlen(text) < 2)
    16. return SCM(playerid, COLOR_YELLOW, !"Минимальная длина фразы в /todo: 2 символа!");
    17. if(strlen(action) < 2)
    18. return SCM(playerid, COLOR_YELLOW, !"Минимальная длина действия в /todo: 2 символа!");
    19.  
    20. static const
    21. fmt_str[] = "'%s' - сказал%s %s, %s";
    22. new
    23. str[sizeof(fmt_str)-6+MAX_PLAYER_NAME+30+20+1+1];
    24. format(str, sizeof(str), fmt_str, text, (player[playerid][pSex] == 1) ? ("") : ("а"), GetName(playerid), action);
    25.  
    26. ProxDetector(playerid, 20.0, COLOR_ACTION, str);
    27. SetPlayerChatBubble(playerid, str, COLOR_ACTION, 20.0, 4000);
    28. return true;
    29. }


    P.S. У последнего варианта есть баг - во фразе и действии нельзя ставить пробелы, иначе способ разделения фразы, действия и * пробелами собъется

    Решение к багу 2 варианта - убрать массив space, удалить эту проверку

    1. if(!strcmp(text, "*") || !strcmp(action, "*") || strcmp(space, "*"))
    2. return SCM(playerid, COLOR_YELLOW, !"Образец отыгровки фразы с действием: /todo [phrase] * [action]");


    И заменить

    1. if(sscanf(params, "s[21]s[2]s[31]", text, space, action))
    2. return SCM(playerid, COLOR_YELLOW, !"Образец отыгровки фразы с действием: /todo [phrase] * [action]");


    на

    1. if(sscanf(params, "s[21]'*'s[31]", text, action))
    2. return SCM(playerid, COLOR_YELLOW, !"Образец отыгровки фразы с действием: /todo [phrase] * [action]");
    Последний раз редактировалось DeimoS; 21.11.2019 в 20:18.

  8. #6
    Аватар для DeimoS
    Модератор?

    Статус
    Оффлайн
    Регистрация
    27.01.2014
    Адрес
    Восточный Мордор
    Сообщений
    5,588
    Репутация:
    1984 ±
    Я выше уже дал рабочий вариант, который, к тому же, проще и оптимизированнее твоего)
    Судя по благодарности под моим постом, автор темы получил ответ на свой вопрос, поэтому закрываю тему.
    Связаться со мной в VK можно через личные сообщения этой группы
    Заказы не принимаю

    Широко известно, что идеи стоят 0.8333 цента каждая (исходя из рыночной цены 10 центов за дюжину).
    Великих идей полно, на них нет спроса.
    Воплощение идеи в законченную игру требует долгой работы,
    таланта, терпения и креативности, не говоря уж о затратах денег, времени и ресурсов.
    Предложить идею просто, воплотить – вот в чём проблема

    Steve Pavlina

 

 

Информация о теме

Пользователи, просматривающие эту тему

Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •