Главная | Комментарии | О проекте
Чтение RSS
Суперсайт
Главная Контакты Карта сайта Добавить в избранное
  • Кто OnLine

    Всего на сайте: 9
    Гостей: 4
    Пользователи: - отсутствуют
    Роботы: robot Bot, crawl Bot, Yahoo Bot, Yandex Bot, Google AdSense

    Опрос пользователей

    Для какого мода Вы пишите плагины?

    • Популярное

    Рекомендуем

    • AMX Mod X
    • up.org.ua

    Наши друзья


  • Автор: Admin Дата: 28-09-2011, 08:34 Просмотров: 10648

    Ограничение использования команд,функций по раундам

    В последнее время очень часто спрашивают: "Как сделать, что бы команду можно было использовать не чаще чем в N раундов?"
    В принципе ни чего сложного нет, нужно всего лишь проверять сколько прошло раундов с последнего использования и в зависимости от количества разрешать или запрещать использования функции.

    Для организации это процесса нам потребуется знание следующих функций:
    plugin_init
    register_event
    register_cvar
    register_clcmd - Не обязательно, но желательно.
    get_cvar_num
    client_print - Тоже не обязательно.


    Немного простой теории:

    Раз вы читаете эту строчку, будем считать что вы изучили необходимые функции и готовы приступить к изучению процесса ограничения использования чего либо по раундам.

    Для начала давайте подумаем, что должна делать функция и что для этого надо:
    1. Она должна считать количество раундов,для этого нам надо:
      • Отловить момент начала раунда
      • Прибавить к счетчику раундов 1

    2. Из выше сказанного возникает переменная, в которой будем считать количество раундов
    3. Должна быть функция, где мы будем проверять, можно или нет использовать команду которую хотим ограничить
    4. Для удобной настройки, должен быть квар, изменяющий ограничение по раундам

    Вроде все, или что то забыл? Как вы думаете? Попробуйте отвернуться и на листочке сами продумать что вам для этого нужно.
    Понимание процесса - залог успеха.

    Теперь нужно подумать, как все это будет работать, так как если мы не представляем себе как зажечь спичку, мы ее можем долго чиркать о коробок где нет специальной полоски и спичка не зажжется. Тут примерно так же.
    1. Каждый раунд прибавлять по единице к глобальной переменной ( глобальная - зарегистрированная не внутри функции, и ее вызвать может любая функция в любой момент времени)
    2. Когда мы захотим использовать функцию, которую хотим ограничить, нужно сделать проверку: Прошло ли необходимое количество раундов, после последнего использования
      • Если да то: Выполнить команду и обнулить счетчик, что бы он заново начал считать раунды
      • Если нет то: Вывести сообщение о том через сколько раундов можно будет использовать данную команду, функцию и т.д.



    Ну как, понимание немного приходит? В обще pawn очень логичный язык и все монжно начертить на бумаге, попробуйте, мне лично часто помогает способ рисования работы функции на бумаге.

    Приступим к написанию плагина:
    Первое что нам нужно сделать - отловить события начала раунда с помощью функции register_event, которую необходимо использовать внутри plugin_init.
    Затем сразу же зарегистрируем квар, для удобной настройки плагина с помощью register_cvar, и тестовую команду с помощью register_clcmd и наконец получим в глобальную переменную значение нашего квара.

    В итоге получим следующий код:


    /* Plugin generated by AMXX-Studio */

    #include <amxmodx>
    #include <amxmisc>

    #define PLUGIN "Restriction of usage of function on rounds"
    #define VERSION "1.0"
    #define AUTHOR "Admin"

    //Регистрация глобальной переменной для нашего счетчика
    new g_Round_counter

    public plugin_init() {
        register_plugin(PLUGIN, VERSION, AUTHOR) //не имеет прямого отношения к нашей задачи

        register_event("HLTV", "RoundStart", "a", "1=0", "2=0")
        register_cvar("amx_f_every_rounds","3")
        register_clcmd("say /test","Counter_check")
        
        g_Round_counter = get_cvar_num("amx_f_every_rounds")
    }
    }


    На этом конфиг плагина готов, идем дальше.
    Создаем функцию внутри которой к нашей переменной, в момент начала нового раунда будет прибавляться по единице
    public RoundStart(){
        //g_Round_counter++ тоже самое что g_Round_counter = g_Round_counter + 1
        g_Round_counter++
    }


    И завершает наш плагин тестовая функция с проверкой на ограничение, которая вызывается с помощью команды say /test.
    Внутри которой есть условие:
    Если счетчик больше или равен квару, то выполняется код( это значит что прошло необходимое количество раундов что бы использовать команду или функцию и т.п.). Для примера там вывод текстового сообщения, и обязательно обнуляем счетчик. Что не даст еще раз использовать в этом раунде нашу команду и еще ближайшие 3 ( такое значение нашего квара).

    Если же вы хотите что бы на протяжении этого раунда можно было использовать функцию неограниченное число раз, то придется добавить еще переменных, и отловить событие конца раунда, и функции вызванной событием конца раунда проверять дополнительные переменные и если они отвечают условиям, то обнулять счетчик.

    public Counter_check(id){
        
        if(g_Round_counter >= get_cvar_num("amx_f_every_rounds")){
            
            //add you code
            //Выполняется если счетчик достиг нужное значение или более

            //Для примера вывод сообщения
            client_print(id,print_chat,"Exec you function")
            
            g_Round_counter = 0
        }else{
        
            //add you code
            //Выполняется если счетчик не достиг нужного значения
            
            //Для примера вывод сообщения
            client_print(id,print_chat,"To use function wait %d rounds",get_cvar_num("amx_f_every_rounds")-g_Round_counter)
        }
    }

    В место
    client_print(id,print_chat,"Exec you function")

    Можно сразу же поставить имя вашей функции например
    my_function(id)

    И скрипт перейдет к выполнению вашей функции.
    Внимание: Это при условии что вы все функции и переменные перенесли в свой плагин.

    Вот так, будет выглядеть весь код:
    /* Plugin generated by AMXX-Studio */

    #include <amxmodx>
    #include <amxmisc>

    #define PLUGIN "Restriction of usage of function on rounds"
    #define VERSION "1.0"
    #define AUTHOR "Admin"

    new g_Round_counter

    public plugin_init() {
        register_plugin(PLUGIN, VERSION, AUTHOR)
        register_event("HLTV", "RoundStart", "a", "1=0", "2=0")
        register_cvar("amx_f_every_rounds","3")
        
        register_clcmd("say /test","Counter_check")
        
        g_Round_counter = get_cvar_num("amx_f_every_rounds")
    }
    public RoundStart(){
        g_Round_counter++
    }
    public Counter_check(id){
        
        if(g_Round_counter >= get_cvar_num("amx_f_every_rounds")){
            
            //add you code
            //Выполняется если счетчик достиг нужное значение или более

            //Для примера вывод сообщения
            client_print(id,print_chat,"Exec you function")
            
            g_Round_counter = 0
        }else{
        
            //add you code
            //Выполняется если счетчик не достиг нужного значения
            
            //Для примера вывод сообщения
            client_print(id,print_chat,"To use function wait %d rounds",get_cvar_num("amx_f_every_rounds")-g_Round_counter)
        }
    }


    Как этот код перенести в ваш плагин:
    Ни чего сложно, если вы не спешили и изучили все функции с которым мы работали, но если нет, то вот вам решение данной задачи:
    1. Добавить глобальную переменную
      new g_Round_counter

    2. В каждом плагине уже есть функция plugin_init По этому вам необходимо перенести туда лишь эти строки:
        register_event("HLTV", "RoundStart", "a", "1=0", "2=0")  register_cvar("amx_f_every_rounds","3")  register_clcmd("say /test","Counter_check")  g_Round_counter = get_cvar_num("amx_f_every_rounds")

      Внимательно посмотрите, не зарегистрировано ли уже событие старта раунда. Если оно уже зарег-но, то вам нет необходимости его регистрировать заново.
    3. Если событие старта раунда не зарегистрировано: Найти закрывающую скобку функции plugin_init, в нашем примере это 20 строка. И со следующей строки добавить
      public RoundStart(){
          g_Round_counter++
      }

      Если же зарегистрировано, то просто в добавить
      g_Round_counter++
      в самом начале, после открывающей кавычки {
    4. Ищем функцию в коде плагина, или место внутри какой то функции, что хотим ограничить, и там вставляем этот код:
          if(g_Round_counter >= get_cvar_num("amx_f_every_rounds")){

              
              g_Round_counter = 0
          }else{
          
              client_print(id,print_chat,"To use function wait %d rounds",get_cvar_num("amx_f_every_rounds")-g_Round_counter)
          }

      При этом, весь код, который мы хотел ограничить, должен оказаться между
      if(g_Round_counter >= get_cvar_num("amx_f_every_rounds")){ и
      g_Round_counter = 0
      }else{

    Вот и все, если вы вникли в сам процесс, то вам не составит сложности настроить данный пример под себя.
    Уважаемый посетитель, Вы зашли на сайт как незарегистрированный пользователь.
    Мы рекомендуем Вам зарегистрироваться либо войти на сайт под своим именем.
    Ограничение использования команд,функций по раундам
    arwel

    --
    ICQ: --
    Публикаций: 0
    Комментариев: 0
    Репутация: -  0  +

    Ух , отлично. Спасибо. А возможно ли сделать, чтобы ограничивало функцию с другого плагина?
    Admin

    30.07.2011
    ICQ: 980500
    Публикаций: 507
    Комментариев: 333
    Репутация: -  56  +

    Прочитай внимательнее:
    Как этот код перенести в ваш плагин:
    --------------------
    arwel

    --
    ICQ: --
    Публикаций: 0
    Комментариев: 0
    Репутация: -  0  +

    А точно wink

    А вообще такое возможно ?
    Admin

    30.07.2011
    ICQ: 980500
    Публикаций: 507
    Комментариев: 333
    Репутация: -  56  +

    Возможно что? Ограничивало в другом плагине?
    Да возможно. Да и разными способами, вопрос только в их правильности и удобстве.
    --------------------
    arwel

    --
    ICQ: --
    Публикаций: 0
    Комментариев: 0
    Репутация: -  0  +

    Мне надо чтобы ограничивало в zombie_plague возможность админам делать немесисом и выжевшим раз в 3 раунда. Я сделал, всё работает, но почему-то сервер падает при смене карты.В логах нет ни одной ошибки, просто вырубается.

    Ах да. Забыл сказать. Локальный сервер не падал при тестированию.

    А нет, всё работает wink Видимо что-то глюкнуло. Извините за беспокойствие.
    Admin

    30.07.2011
    ICQ: 980500
    Публикаций: 507
    Комментариев: 333
    Репутация: -  56  +

    Вот и хорошо.
    Если есть вопросы, на которые нужно написать подобную статейку, пишите в личку.
    И если моих знаний будет достаточно, то я обязательно напишу.
    --------------------
    arwel

    --
    ICQ: --
    Публикаций: 0
    Комментариев: 0
    Репутация: -  0  +

    Окей. Спасибо за создание такого портала:) А то инфы в интернете не очень много...
    pokibob

    --
    ICQ: --
    Публикаций: 0
    Комментариев: 0
    Репутация: -  0  +

    Спасибо этой статье и автору) наконецто ограничил свой плагин =)
    Greenberg

    --
    ICQ: --
    Публикаций: 0
    Комментариев: 0
    Репутация: -  0  +

    вот вот мне тоже так плиз///
    и самое главное куда это все дело писать???
    новый плагин или
    в какойто плагин
    и как сделать временной отчет
    Admin

    30.07.2011
    ICQ: 980500
    Публикаций: 507
    Комментариев: 333
    Репутация: -  56  +

    Greenberg, для начала изучи основы.
    Переделывать плагины или дописывать в них другие функции это не ко мне.

    Я могу ответить на конкретно поставленные вопросы и то в меру моих знаний.
    --------------------

    Информация

    Посетители, находящиеся в группе Гости, не могут оставлять комментарии к данной публикации.
Наверх

Реклама