Difference: JmcTutorial (5 vs. 6)

Revision 62009-11-14 - Dr_046Lance

Line: 1 to 1
 
META TOPICPARENT name="ClientList"
Источник оригинала на английском языке:
http://mudlogs.foghaven.net/mudlogs.php?article=jmctutorial
Оригинальное название: "JMC Tutorial - Version 1.0"
Авторы оригинального текста: Derek и Jasper

Changed:
<
<
Перевод: Dr.Lance, 16.06.2009 г.-29.06.2009 г., 25.10.2009 г.
>
>
Перевод: Dr.Lance, 16.06.2009 г.-29.06.2009 г., 25.10.2009 г.-14.11.2009 г.
  [Оригинальный текст учебника изложен моноширинным шрифтом без иллюстраций. Возможно, это сделано для того, чтобы
Line: 93 to 93
  9.3) Используем ячейки панели статуса 9.4) Используем звук, чтобы привлечь внимание
Changed:
<
<
10) Ведение логов 10.1) Для чего нужно вести логи 10.2) Пишем лог в файл 10.3) Закрываем файл лога 10.4) Где хранятся логи
>
>
10) Ведение логов 10.1) Для чего нужно вести логи 10.2) Пишем лог в файл 10.3) Закрываем файл лога 10.4) Где хранятся логи

11) Условные выражения 11.1) Выражения с ключевым словом if (команда #if) 11.2) Используем условные выражения 11.3) Математика в JMC 11.4) Используем математические выражения

12) Регулярные выражения 12.1) Что такое "регулярные выражения" и для чего они нужны 12.2) Создание простейших регулярных выражений 12.3) Подробнее о регулярных выражениях

 
Changed:
<
<
11) Условные выражения 11.1) Выражения с ключевым словом if (команда #if) 11.2) Используем условные выражения 11.3) Математика в JMC 11.4) Используем математические выражения

12) Регулярные выражения 12.1) Что такое "регулярные выражения" и для чего они нужны 12.2) Создание простейших регулярных выражений 12.3) Подробнее о регулярных выражениях

13) Заключение

>
>
13) Заключение
  Замечание авторов: где не оговаривается специально, по умолчанию считается, что тексты примеров вводятся в командной строке клиента.
Line: 1090 to 1090
 Думаю, всем понятно, как это работает. Если нашего персонажа сбили, мы получим звуковой сигнал, если, конечно, наш компьютер оборудован звуковой системой.
Added:
>
>
10) Ведение логов
10.1) Чем полезно ведение логов

Когда мы исследуем новую зону или хотим знать, как добраться до зоны, куда нас постоянно таскает лидер, удобно иметь текстовую версию всех событий в игре, чтобы позже можно было проанализировать ее. Также иногда хочется сохранить записи о самых больших и интересных битвах между игроками. На все эти случаи JMC имеет команду для ведения логов в текстовых файлах.

Пожалуйста, заметьте, что пока JMC не умеет писать в лог ваши подстановки или сообщения от команды #showme, или текст, выводящийся в дополнительное окно. То, что пишется в файлы логов, есть в точности то, что приходит от игрового сервера, без изменений. 10.2) Запуск записи лога в файл

Сделать это очень просто. Когда у вас появляется желание начать писать лог прохождения зоны, вы, очевидно, захотите дать этому логу определенное имя, чтобы в будущем можно было бы быстро отыскать этот лог среди других. Приведем пример:

#log {Подземелье.txt}

После ввода этой команды в правом нижнем углу окна JMC во втором окне-иконке появится значок открытой папки, который показывает, что файл лога открыт и лог пишется в файл. 10.3) Закрываем файл лога

Нет нужды постоянно писать лог или писать все в один файл. Поэтому, после того, как зона пройдена или битва закончилась, файл лога можно закрыть. Чтобы сделать это, от вас НЕ ТРЕБУЕТСЯ указывать имя файла лога. Нужно просто ввести:

#log

Эта команда закроет текущий файл лога. 10.4) Где хранятся логи

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

ЗАМЕЧАНИЕ: у команды записи логов в файлы имеется параметр, определяющий два способа записи лога в файл: overwrite (запись поверх старого лога) и append (запись добавлением к старому логу). Если этот параметр не указывать, лог пишется способом overwrite. При этом, если вы начинаете писать лог в файл с таким именем, которое уже имеет ранее записанный файл, то старый лог будет стерт, а поверх него будет записан новый лог. При использовании способа append в случае совпадения названий файлов логов новый лог будет записан в файл со старым логом, сразу после окончания старого лога. Вот как использовать эти способы:

#log Подземелье.txt append #log Подземелье.txt overwrite

Еще раз: overwrite -- это значение по умолчанию и его не обязательно вводить. 11) Условные выражения


11.1) Выражения с ключевым словом if (команда #if)

Выражения с ключевым словом if -- очень удобная штука. Они позволяют нам запускать какие-то действия только при наступлении определенных обстоятельств. Также такие выражения известны как "условные выражения". Помните, что JMC поддерживает только числовые сравнения. 11.2) Используем условные выражения

КОМАНДА: #if СИНТАКСИС: #if {указанное здесь -- правда} {команды к исполнению}

Перед разбором примеров нужно пояснить несколько вещей. Во-первых, мы должны знать, как связывать несколько объектов JMC друг с другом. Это, конечно, актуально и для других глав этого учебника, но здесь это особенно важно. Ниже мы рассмотрим некоторые операторы сравнения и различия между ними, вплоть до самых незначительных.

Вы можете делать прямые сравнения, которые обозначаются символами: < > <= >= = (меньше, больше, меньше или равно, больше или равно, равно, не равно).

ПРИМЕРЫ:

#if {$деньги >= 50} {разделить монеты} #if {$жизнь < 20} {зачитать свиток возврата} #if {$уровень == 30} {веселиться;выход;4;мойпароль} #if {$ПК = 20} {вопить}

Замечание: часто встречается ошибка при применении оператора "равно" -- вместо "==" люди пишут "=". Это неправильно. В языках программирования одиночный символ "=" используется в качестве оператора присвоения значения переменной, поэтому в качестве оператора "равно" решили использовать двойной знак "==".

В условных выражениях можно использовать оператор "И" (обозначается как "&&"):

#if {$ПКразрешен = 1 && $деньги = 0} {рычать}

Также можно использовать оператор "ИЛИ" (обозначается "||"):

#if {$естьавтоматически = 1 || $голод = 1} {есть все}

Вот еще один короткий пример, как можно использовать условное выражение.

#alias {ограблениевкл} {#variable {ограбление} {1}} #alias {ограблениевыкл} {#variable {ограбление} {0}}

Введите: ограблениевкл

#action {%0 отдал концы! Мир праху его.} {#if {$ограбление == 1} {взять все.монеты труп}}

Теперь, из-за того, что мы сначала установили переменную "ограбление" в 1 ("включили"), когда моб или персонаж умирает, наш персонаж автоматически крадет монеты с трупа умершего. Если мы введем команду "ограблениевыкл", то наш персонаж перестанет автоматически грабить трупы, так как переменная "ограбление" уже не будет равна 1 и условие в триггере перестанет срабатывать. 11.3) Математика в JMC

Математика в JMC может оказаться немного не тем, что вы ожидаете. Однако, для любого, кто имеет хотя бы небольшой опыт программирования, не будет слишком сложным приспособиться. Тем, кто раньше не программировал, будет немного труднее. Основная концепция математики в JMC аналогична концепции целочисленной математики в языках программирования. Например, если мы будем делить 3 на 5, то получим в результате 0. Тогда как в обычной математике результат будет равен 0.6. Мы не будем расписывать вам здесь формулы, но поймите, что вы можете обойти эту проблему, применив перед делением умножение, чтобы сделать значения подходящими для целочисленного деления. 11.4) Используем математические выражения

КОМАНДА: #math СИНТАКСИС: #math {переменная для результата} {матем.выражение}

ПРИМЕР:

#variable {всего_монет} {0} #action {^Тут %0 монет.} {#math {всего_монет} {$всего_монет + %%0}} #alias {украдено монет} {jmc.Showme {yellow} {ВСЕГО МОНЕТ УКРАДЕНО: $всего_монет}}

На первый взгляд все это выглядит немного путано, но давайте разберемся, что происходит. Первое, что мы делаем -- это создаем переменную для хранения общего количества украденных монет и устанавливаем ее в ноль. Затем мы создаем триггер для сообщения, которое выдает игра после того, как нашему персонажу удалось выбить из врага немного монет. Этот триггер выполняет математические вычисления. Итак, после ключевого слова #math в фигурных скобках мы указываем переменную для результата математического выражения, а затем указываем само это математическое выражение. Здесь вы можете воскликнуть: "Минуточку! В этом математическом выражении используется та же самая переменная, в которой мы храним результат этого самого выражения". Причина этого в том, что мы хотим, чтобы при каждом вычислении выражения новый результат вычисления записывался поверх старого и тем самым затирал бы его. В последней части примера мы создаем алиас, который просто выводит общее количество украденных монет на экран. Давайте поглядим, как это работает:

99H 99V 99X 99C:N> Тут 10 монет. 99H 99V 99X 99C:N> украдено монет ВСЕГО МОНЕТ УКРАДЕНО: 10 12) Регулярные выражения


12.1) Что такое "регулярные выражения" и для чего они нужны

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

Вместо использования частевых переменных вроде %0, %3 и т.д., JMC позволяет нам использовать совершенно другой метод подстройки триггеров под целевой текст от игрового сервера -- это использование "регулярных выражений" ("Regular Expressions" или кратко -- "RegEx"). Это очень точный и очень гибкий метод описания целевого текста. 12.2) Создание простейших регулярных выражений

Регулярные выражения в основном используются в триггерах (#action).

СИНТАКСИС: #action {/регулярное выражение/} {действия, которые будут выполнены}

Символы косой черты ("/") обозначают начало и конец регулярного выражения. Например:

#action {/Уличный кот самодовольно урчит/} {к !огненный шторм! кот}

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

Специальные символы обычно обозначаются обратной косой чертой ("\"). Вот некоторые из специальных символов: \w, \d, \s (это самые общеизвестные).

\w - любой алфавитный символ, не являющийся пробЕльным (примеры: любая буква, любая цифра или символ подчеркивания "_"); \s - любой пробЕльный символ (примеры: пробел, символ табуляции); \d - любая цифра (примеры: 0, 1, 2 и т.д.).

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

"+" - означает, что символ, после которого стоит это обозначение, появится в строке-оригинале в этом месте один или более раз подряд; "*" - означает, что символ, после которого стоит это обозначение, либо вообще не появится в строке-оригинале в этом месте, либо появится один или более раз подряд.

Хорошо, посмотрим теперь, как это все используется. Давайте рассмотрим очередной пример:

#action {/Тут \d+ монет/} {завопить} ^^^ | Этот шаблон соответствует любому количеству любых цифр, идущих подряд (без десятичной точки). Спецсимвол \d означает любую цифру, а обозначаение "+" после этого спецсимвола означает, как уже было сказано выше, появление в строке-оригинале символа, после которого идет это обозначение, один или более раз подряд.

А вот что нужно писать, если мы хотим подстроить триггер под кого-то, входящего в комнату:

#action {/\w+ пришел с \w+/} {зачитать свиток возврата}

Методами, которые мы рассматривали ранее, мы не могли описать такой триггер так, чтобы он учитывал только персонажей с именами, состоящими из одного слова, а не из двух, трех и т.д. Этот пример с регулярным выражением учитывает только прибытие в комнату персонажей с однословными именами: последовательность \w+ будет соответствовать, например, персонажу с именем "Петя", но не мобу "Горный козел", так как словосочетание "Горный козел" содержит пробельный символ -- пробел, разделяющий наименование "Горный козел" на два слова.

Теперь, чтобы выделить из целевого текста некую содержащуюся в нем информацию (как мы делали, используя частевые переменные %0, %1 и т.д.) для дальнейшего использования, достаточно ограничить эту инфомацию круглыми скобками:

#action {/Тут (\d+) монет/} {разделить %0}

Этот триггер сработает при появлении целевого текста от игрового сервера, причем информация, соответствующая последовательности \d+, выделенной круглыми скобками в шаблоне, будет сохранена в частевой переменной %0 и деньги будут поделены между членами группы по команде "разделить" во второй части триггера.

Последовательное применение выделения информации круглыми скобками в одной строке-шаблоне триггера поместит эту информацию в частевые переменные %1, %2 и т.д., чтобы можно было использовать эту информацию во второй части триггера:

#action {/(\w+) пришел с (\w+)/} {ггруппа %0 пришел с %1!!}

Точно также, как при использовании частевых переменных в строке-шаблоне, мы можем обеспечить безопасность нашего триггера с помощью специального символа-якоря "^":

#action {/^(\w+) пришел с (\w+)/} {ггруппа %0 пришел с %1!!}

Все это хорошо и прекрасно, но триггеры, написанные нами ранее с применением частевых переменных, справлялись с этими задачами не хуже. Чем же лучше использование регулярных выражений? Способ с регулярными выражениями более гибок. Предположим, нам требуется триггер, срабатывающий на строку, содержащую подряд 2 пробела, 4-6 букв, 2 цифры, 6 пробелов и еще одну цифру. Пишем следующее:

#action {/\s\s\w{4,6}\d\d\s{6}\d/} {завопить}

Задача, которая казалась невыполнимой, решается легко и элегантно.

Замечание: обозначение вида {а,б} работает подобно "*" или "+", за тем исключением, что здесь задается диапазон, от "а" до "б" -- число раз, которое может появится символ, после которого стоит это обозначение, в целевой строке. В приведенном примере мы задаем число возможных повторений символа \w в целевой строке от 4 до 6 раз.

Несмотря на приемы применения регулярных выражений, продемонстрированные выше, проблемы все таки остаются. У большинства мобов имена состоят больше, чем из одного слова. Например: "гигантский синий кендер из преисподней" -- шесть слов. Как мы можем выделить многословное имя из целевой строки, не зная заранее, сколько слов в нем будет?

Для этого можно использовать еще один спецсимвол, который применяется, чтобы обозначить в шаблоне что угодно: буквы, пробелы, цифры. Этот спецсимвол - точка ".".

Предположим, мы хотим выделить из целевой строки имя любого моба, прибывающего с запада:

#action {/^(.+) пришел с запада./} {крикнуть %0 здесь!}

Таким манером мы выделили последовательность из 1 или более любых символов и сохранили ее в частевой переменной %0, которую использовали во второй части триггера. Но что это за точка в конце предложения? В общем-то, она сработает и здесь, так как будет соответствовать точке, которая ставится в конце целевой строки.

Некоторые символы, вроде "[", "]", "\", "(", ")", нельзя найти в целевой строке триггера, полученной от игрового сервера, просто указав их как обычные символы в строке-шаблоне триггера. Если же вы попытаетесь это сделать, то получите сообщение об ошибке, так как интерпретатор регулярных выражений посчитает их за служебные символы команд, а не за простой текст от игрового сервера. Что же делать, если все таки вам понадобится подстроить триггер под текст с такими символами? Поместите перед такими (служебными) символами символ обратной косой черты "\":

\] - такое обозначение в строке-шаблоне будет соответствовать символу "]" в строке-оригинале, полученной от игрового сервера; \. - аналогично - такое обозначение в строке-шаблоне будет соответствовать символу "." в строке-оригинале, полученной от игрового сервера.

Вспомните обратную косую черту в обозначениях спецсимволов типа \s, \w, \d - это и было сделано, чтобы JMC не путал обычные буквы "s", "w", "d" со спецсимволами.

Предположим, вы хотите подстроить ваш триггер под следующую строку-оригинал от игрового сервера и сохранить некоторые значения из нее в частевых переменных:

У вас 4141(6951) стальных монет.

Это можно сделать следующим образом:

#action {У вас (\d+)\((\d+)\) стальных монет\.} {завопить}

Надеемся, что к этому моменту вы уже получили какое-то первичное понимание, зачем нужны и как использовать регулярные выражения. Разобраться в них порою бывает нелегко, и часто необходимо бывает потратить некоторое время, чтобы приобрести практический опыт их использования. Несмотря на эти трудности, не откидывайте регулярные выражения в сторону, они незаменимы! 12.3) Подробнее о регулярных выражениях

Выше мы уже ознакомились с несколькими примерами, показывающими, как можно использовать регулярные выражения. На самом деле, это всего лишь малая часть их возможностей. Следующие примеры покажут, что еще можно делать с помощью регулярных выражений.

Обозначение: [] Квадратными скобками в регулярных выражениях обозначают начало и конец контейнера, содержащего все варианты символа, который может появиться в этом месте строки-оригинала, полученной от игрового сервера.

Предположим, от игрового сервера получена следующая строка:

Фотонный реактор подготовлен: Д

Вот как можно подстроить наш триггер под эту строку:

#action {/Фотонный реактор подготовлен: [ДН]/} {завопить}

Этот триггер сработает, если после двоеточия появится либо "Д", либо "Н", но не сработает, если появится "д", либо "н", либо какой-то другой символ. Если информацию о готовности реактора нужно сохранить в частевой переменной, можно окружить квадратные скобки круглыми, как мы делали ранее: ([ДН]).

Обозначение: {#} или {#,#} Как вы видели в предыдущей главе, такое обозначение определяет диапазон количества раз, какое целевой символ может повториться подряд в этом месте строки-оригинала, полученной от игрового сервера.

Приведем пример. Предположим, вы получили от игрового сервера строку, показывающую, сколько боеприпаса осталось в вашем оружии:

Боеприпасы[XXXXXXXXXX----]

Предположим, вы хотите получить звуковой сигнал, когда на прогрессоре боеприпаса останется 2-3 деления. Это можно настроить так:

#action {/Боеприпасы\[X{2,3}\-+\]/} {#beep}

Замечание: квадратные скобки в этом примере предваряются символом обратной косой черты, чтобы дать понять JMC, что это не служебные символы, а символы строки-оригинала от игрового сервера. Точно также на всякий случай символ дефиса тоже предварен символом обратной косой черты (так как я не уверен, является ли он служебным символом). Символ "+" после символа дефиса означает, как уже говорилось ранее, что символ дефиса может появиться в строке-оригинале один и более раз. Наконец, если бы вы хотели, к примеру, получить звуковой сигнал, когда на прогрессоре останется точно 3 деления, достаточно было бы в строке-шаблоне указать обозначение "{3}".

Обозначение: \b Это еще один спецсимвол, который расшифровывается как "граница" (по-английски "border"). Предположим, вы хотите подстроить ваш триггер под игрока с именем "Бам", но не с именем "Бамбук". Это можно сделать так:

#action {/Бам\b.* стоит здесь./} {улыбнуться Бам}

Замечание: обозначение ".*" соответствует любому тексту между обозначением границы и словами "стоит здесь".

К примеру, этот триггер сработает на следующие строки-оригиналы:

Бам, могучий кендер, стоит здесь. Бам, мужчина-кендер, стоит здесь. Бам стоит здесь.

Но не сработает на вот эту строку-оригинал:

Бамбук стоит здесь.

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

Еще одна интересная особенность регулярных выражений -- это символ вертикальной черты "|". Он нужен для задания списков альтернатив. Он действует аналогично символу "||" ("или") в языках программирования. Например, можно настроить триггер следующим образом:

#action {^Здесь стоит дерево, увешанное спелыми (яблоками|апрельсинами).} {обобрать дерево}

Этот триггер сработает на строки:

Здесь стоит дерево, увешанное спелыми яблоками. Здесь стоит дерево, увешанное спелыми апельсинами.

Списки альтернатив - очень гибкий инструмент для анализа текста от игрового сервера. 13) Заключение


 
Changed:
<
<
...продолжение следует...
>
>
Программирование с помощью командного языка JMC -- это очень большая тема. Этот учебник лишь обеспечивает вас базовыми знаниями об инструментах, которые можно использовать в клиентах для игры в текстовых многопользовательских мирах. Клиент для таких игр -- это очень гибкая штука, но его мощь, в конце концов, зависит, в основном, от силы воображения игрока. Надеемся, что вы сможете скомбинировать все те приемы, о которых здесь было рассказано, чтобы вы смогли выстроить свои собственные уникальные профили, которые в итоге и помогут вам получить от игры больше удовольствия.
  Замечания по учебнику можно высказать в специальной теме форума.
 
This site is powered by the TWiki collaboration platform Copyright © by the contributing authors. All material on this collaboration platform is the property of the contributing authors.