Седьмая часть.

В этой части мы разберем файл module_dialogs.py, самый большой файл в модульной системе и один из самых важных, поскольку содержит все диалоги МиБа. Любой новый диалог, которой вы создадите войдет в этот файл. Также файл содержит специальные служебные диалоги, их используют войска, не (совсем) обладющие собственными диалогами.

7.1 Разбор файла  module_dialogs.py.

Файл начинается со списка dialogs = [, он сопровожден первой частью диалога из игры – заявления констебля Харека касательно речных пиратов (прим: как уже неоднократно упоминалось, документация устарела. Никакого констебля Харека Вы не найдете.) (прим 2: в модульной системе Warband такого диалога нет вообще, но как пример имеет шансы на жизнь) Важный факт - система выбирает первую строку из файла module_dialogs.py и проверяет относительно каждой детали, составляющей текущую игровую ситуацию, надо ли выводить эту строку на экран. Если да, то выводит ее, если нет, то двигается дальше, ко второй строчке. Т.е. если есть две линии диалога, соответствующие игровой ситуации, приоритет получит та, что расположенна выше. Далее по тексту, вы найдете более подробное объяснение.

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

Пример записи реплики:

  [trp_constable_hareck,"start", [], "What do you want?", "constable_hareck_talk",[]],

Это простая запись, она хорошо послужит нам в качестве примера. Она (запись) делает все, что должна делать реплика; при обращении к констеблю Хареку внутри сцены, она выводит на экран текст “What do you want?” (“Что ты хочешь?”),  а затем, после клика левой кнопкой мышки, выводит стартовое окно диалога "constable_hareck_talk".

Разбор записи реплики:

1) Идентификатор собеседника. Конкретная персона или отряд, которые игрок должен встретить для начала диалога.
2) Статус вызова реплики. Определяет когда/где текст будет выведен на экран.
3) Блок условий. Блок дополнительных условий (помимо статуса вызова), который должен быть выполнен, для вывода текста на экран. Это должен быть блок операций.
4) Текст диалога. Текст, который появится в игре.
5) Статус завершения реплики. Определяет, что случится после вывода этого текста.
6) Блок последствий. Операции, которые произведутся после того, как щелкнете мышкой. Это должен быть блок операций.

Разбор записи констебля Харека

1) Идентификатор собеседника = trp_constable_hareck
2) Статус вызова реплики = "start"
3) Блок условий = []
4) Текст диалога = "What do you want?"
5) Статус завершения реплики = "constable_hareck_talk"
6) Блок последствий = []

Важная деталь, которую стоит отметить - статусы реплики. Здесь мы копнем чуть глубже.

Статус завершения реплики ("constable_hareck_talk") это то, что ведет переход от одной реплики к другой (от записи к записи). Статус завершения диалога может быть всем, чем захотите -- но обязана существовать другая запись с соответсвующим, парным статусом вызова реплики. Для примера, если мы сделали запись, имеющую статус завершения "blue_oyster", это отправит нас к записи со статусом вызова "blue_oyster".  Обязано выдерживаться строгое соответветсвие; если соответствующей пары нету, то build_module.bat выдаст ошибку при попытке собрать мод.

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

Для остановки разговора вы должны использовать статус завершения "close_window".

Для начала разговора существует несколько специальных статусов вызова:

- "start" -- применяется когда беседа инициирована внутри сцены (Разговор с НПС).
- "party_encounter" -- применяется в случае столкновения с другим отрядом на глобальной карте .
- “party_relieved" -- применяется если игрок окажет помощь отряду ведущему битву, сражение должно быть выигранно.
- "prisoner_liberated" -- применяется когда игрок победил вражеский отряд,  держащий в плену одного или более hero (диалог с освобождёнными hero). (прим: метка "hero" описывалась в предыдущих частях)
- "enemy_defeated"  -- применяется когда игрок победил вражеский отряд под предводительством типа hero (диалог с пленёнными hero).
- "event_triggered" – применяется когда диалог инициирован какой либо операцией, но не внутри сцены.
- "member_chat" -- применяется когда разговариваешь с членами своей группы.
- "prisoner_chat" -- применяется когда игрок разговаривает с пленными своей группы.

Каждый статус вызова реплики оформлен для специфической ситуации. Запись реплики не будет рассмотрена системой если нет ситуации, соответствующей ее (записи) статусу вызова.

Т.к. разобранная нами запись инициируется обращением к констеблю Хареку, она обладает статусом вызова "start".

7.2. Блоки условий и последствий.

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

В этом разделе мы разберем как задействовать весь спектр возможностей интерфейса диалогов. А после этого мы изучим как создавать комплексные диалоги.

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

Во-первых, игрок должен разговаривать с нужным персонажем. Реплика с trp_constable_hareck не будет выведена на экран если игрок обращается, скажем, к trp_ramun_the_slave_trader (Рамуну работорговцу). А вот константа anyone может быть использована для реплики, которая должна появляться всякий раз, когда игрок обращается к кому-либо.

Второе, статус вызова реплики должен быть в соответствие с ситуацией -- или реплика будет инициирована одним из статусов вызова (таким как start), или же реплика последует в соответствии со статусом завершения предыдущей реплики. Если статус вызова реплики не имеет спецификации (в поле статуса вызова ничего нет), она (реплика) не будет использоваться нигде.

Втретьих, похожая логика действует и на блок условий. Пока все из перечисленных в записи условий реплики не будут удовлетворенны, реплика не будет рассмотрена системой как вариант для вывода на экран. И если блок условий или статус вызова реплики ошибочны, у вас возникнут проблемы; одно из двух – либо build_module.bat выдаст ошибку, либо реплика просто повиснет по ходу игры, так как система не будет в состоянии найти следущую запись для активации.

По этой причине будьте осторожны с блоком условий. Убедитесь что вы не сломали ваш диалог “вживив” в него блок условий с неточными установками.

Если все работает гармонично, блок условий может стать мощным инструментом в ваших руках. В него можно включить блоки ветвления (try blocks): внутри блока условий можно описать операцию, и использовать её результат в качестве условия для вывода реплики (всё это будет в том же блоке условий). Для этого можете задавать обычные и строковые регистры, чтобы использовать их в качестве параметра для операции внутри блока условий данной записи реплики. Это не так сложно как может показаться из вышенаписанного, и всё это мы с вами сейчас по очереди рассмотрим и опробуем.

Изучим использование блока условий внутри записи из самого начала module_dialogs.py:
Этот диалог:

[trp_constable_hareck,"start", [(eq,"$constable_announcement",0)],
"Hear me, people of Zendar, for I bear a message from our town's lord and protector, Count Arrasies.\
As you know, bands of river pirates have infested the vicinity of our town.\
These lawless villains devastate our realm, pillaging, robbing and murdering the innocent.\
The mischief and suffering caused by these scum has become intolerable.\
Thus, our good Count has found it necessary to call to arms his honest and law-abiding subjects against these murderous villains.",
   "constable_hareck_introduce_1",[(assign,"$constable_announcement",1)]],
  [trp_constable_hareck,"constable_hareck_introduce_1", [],
"People of Zendar, our Count invites you to serve him in this cause.\
Those of you that volunteer now will be equipped with arms and armor at the Count's expense\
and shall be granted the right to hunt down the river pirates, ending their miserable lives by death or imprisonment,\
and keeping their ill-gotten gains to yourselves without tax or tribute.\
Moreover, you will be paid a reward of 20 denars from the Count's treasury for every river pirate group you vanquish.", "close_window",[]],

  [trp_constable_hareck,"start", [], "What do you want?", "constable_hareck_talk",[]],

  [trp_constable_hareck|plyr,"constable_hareck_talk", [(eq,"$quest_accepted_zendar_river_pirates",0)],
"I want to sign up to hunt down the river pirates.", "constable_hareck_signup_1",[]],
  [trp_constable_hareck,"constable_hareck_signup_1", [], "Have you worked as a manhunter before?", "constable_hareck_signup_2",[]],
  [trp_constable_hareck|plyr,"constable_hareck_signup_2", [], "Yes I have.", "constable_hareck_signup_3",[]],
  [trp_constable_hareck|plyr,"constable_hareck_signup_2", [], "Not really. But I learn quickly", "constable_hareck_signup_3",[]],
  [trp_constable_hareck,"constable_hareck_signup_3", [],
"That's more than enough for me. Well then. I charge you to hunt down river pirates around Zendar,\
and give you this shield from the Count's armory.\
May God make you victorious.", "constable_hareck_signup_4",[(assign,"$quest_accepted_zendar_river_pirates",1),
                                                             (str_store_string, s2, "@Constable Hareck asked you to hunt down the river pirates that plague the country around Zendar.\
He promised to pay you 20 denars for each river pirate party you eliminate."),
                                                             (call_script, "script_start_quest", "qst_hunt_down_river_pirates", "$g_talk_troop"),
                                                             (troop_add_item, "trp_player","itm_wooden_shield",imod_battered)]],
  [trp_constable_hareck|plyr,"constable_hareck_signup_4", [], "Is that all?", "constable_hareck_signup_5",[]],
  [trp_constable_hareck,"constable_hareck_signup_5", [], "What else do you want, a good luck kiss?\
Now stop chattering and go kill some outlaws. You have to work hard to deserve that shield.", "close_window",[]],
 
  [trp_constable_hareck,"sell_prisoner_outlaws_finished", [], "Well done my {boy/girl}. .", "close_window",[]],
 
  [trp_constable_hareck|plyr,"constable_hareck_talk", [
      (store_num_parties_destroyed_by_player, ":num_river_pirates_destroyed", "pt_river_pirates"),
      (val_min,":num_river_pirates_destroyed",num_max_river_pirates),
      (lt,"$river_pirates_paid_for",":num_river_pirates_destroyed")],
   "I have hunted down some river pirates.", "pay_for_river_pirates",[]],
  [trp_constable_hareck,"pay_for_river_pirates", [],
   "Yes, my scouts informed me. That should make them think twice before wandering near Zendar! Anyway, the reward is 20 denars for every river pirate party. Here is your money, as promised.",
   "pay_for_river_pirates_2",[(store_num_parties_destroyed_by_player, ":num_river_pirates_destroyed", "pt_river_pirates"),
                              (val_min,":num_river_pirates_destroyed",num_max_river_pirates),
                              (store_sub,":river_pirate_bounty",":num_river_pirates_destroyed","$river_pirates_paid_for"),
                              (val_mul,":river_pirate_bounty",20),
                              (troop_add_gold,"trp_player",":river_pirate_bounty"),
                              (assign,"$river_pirates_paid_for",":num_river_pirates_destroyed")]],
  [trp_constable_hareck|plyr,"pay_for_river_pirates_2", [],
   "Thank you, sir.", "pay_for_river_pirates_3",[]],
  [trp_constable_hareck,"pay_for_river_pirates_3", [(neq,"$quest_complete_zendar_river_pirates",0),(eq,"$quest_complete_zendar_river_pirates_ack",0)],
"You certainly deserved your pay. Thanks to hunters like you most of the river pirates have been dealt with.\
The few remaining do not pose a threat any longer. So I thank you in the name of the town of Zendar. You did a mighty good job.","constable_hareck_reward_1",[[add_xp_as_reward,100],[call_script, "script_end_quest", "qst_hunt_down_river_pirates"],[assign,"$quest_complete_zendar_river_pirates_ack",1]]],
  [trp_constable_hareck|plyr,"constable_hareck_reward_1", [], "Thank you sir. But does that mean you won't be paying any more rewards?", "constable_hareck_reward_2",[]],
  [trp_constable_hareck,"constable_hareck_reward_2", [], "You got that right.\
The truth is, the count's accountant has found out that rewards cost him more than the pirates do.\
So, that means no more rewards for those filthy pirates.\
Nothing is stopping you from taking your own reward from their packs and hideouts, though.", "close_window",[]],
  [trp_constable_hareck,"pay_for_river_pirates_3", [], "Ah, yes... Well... good luck.", "close_window",[]],
 
  [trp_constable_hareck|plyr,"constable_hareck_talk", [], "Nothing. Good-bye.", "close_window",[]],

Разбор диалога:

  [trp_constable_hareck,"start", [(eq,"$constable_announcement",0)]
  # eq - "equal" - "равно"

Здесь есть лишь одно условие (операция eq), требующее чтобы переменная "$constable_announcement" была равна 0. Смысл в том, что все регистры и переменные в начале игры равны нулю. Если вы посмотрите на окончание этой записи (на блок последствий), то заметите следующее:

  "constable_hareck_introduce_1",[(assign,"$constable_announcement",1)]]

После того, как реплика выведена на экран, операция assign (присвоить) задаёт переменной "$constable_announcement" значение 1. Другими словами, появившись раз, эта реплика никогда не отобразится вновь – после выполнения блока последствий значение перменной "$constable_announcement" уже отличное от 0. Теперь система будет игнорировать эту запись и вместо нее пойдет к следущей записи, расположенной в списке ниже и также удовлетворяющей нужным условиям:

  [trp_constable_hareck,"start", [], "What do you want?", "constable_hareck_talk",[]],

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

7.3 Добавление диалогов.

Наконец у нас появилась возможность сделать Джоффри несколько уникальных реплик и связать их в уникальный диалог. Но, как и в module_troops.py, вы не можете просто добавить новые записи в конец файла. Окончание python-овского списка в module_dialogs.py состоит из служебных реплик, они вызываются по умолчанию для войск и героев, не обладающих своими уникальными репликами. И так как система в поисках соответствия сканирует файл сверху вниз, все реплики, добавленные после служебных, будут проигрорированны.

Рекомендуется добавлять новые реплики сразу после фразы:

# Random quests
######################################################

Начнем с создания вступительной реплики Джоффри. Таким образом, мы сможем набраться опыта, прежде чем приступим к работе с полноценными квестами. 

Скопируйте нижеследующую запись и вставьте в module_dialogs.py в место, рекомендованое выше:

  [trp_geoffrey,"start", [], "What? What do you want? Leave me be, {sir/wench}, I have no time for beggars.", "geoffrey_talk",[]],
  (“Вам что-то надо? Оставьте меня в покое, {сударь/сударыня}, у меня нет времени для попрошаек”)

Это первая реплика нашего диалога. Она активируется с помощью статуса вызова "start" и произносится Джоффри. Приводит к вызову реплики со статусом вызова "geoffrey_talk". Также, система отобразит обращение “сударь” или “сударыня” в зависимости от пола персонажа игрока.

Далее мы сделаем реплику, следущую сразу за первой и произносимую игроком. Скопируйте и вставьте в файл вслед за нашей первой записью следущую:

  [trp_geoffrey|plyr,"geoffrey_talk", [], "Nothing, never you mind.", "close_window",[]],
  (“Ничего особенного, не бери в голову.”

Эта линия диалога будет выведена на экран сразу после первой, и будет произносится игроком. Она обладает статусом завершения диалога "close_window", т.е. прервает беседу сразу после своего вывода, при нажатии левой кнопки мыши. Метка |plyr означает что говорит игрок.

Как мы уже объясняли выше, добавление сразу нескольких записей реплик, произносимых игроком и обладающих одинаковым статусом вызова, приведет к “суммированию” этих записей в виде меню с разными вариантами ответа, ведущими диалог в разные ветки.  Еще раз напоминаю, что это работает лишь с репликами, произносимыми игроком. Скопируйте следущие записи и вставьте их в файл module_dialogs.py:

  [trp_geoffrey|plyr,"geoffrey_talk", [], "And who are you supposed to be?", "geoffrey_talk_2",[]],
  ”И кто же ты такой?
  [trp_geoffrey,"geoffrey_talk_2", [], "Why, I'm Geoffrey Eaglescourt, son of the Baron Eaglescourt! Leader of the Red Riders, bane of bandits, and crusher of pirates!", "geoffrey_talk_3",[]],
  ”Что же, я Джоффри Иглскорт (дословно – орел ощипанный), сын барона Иглскорта! Лидер Красных Всадников, гроза бандитов и сокрушитель пиратов!”
  [trp_geoffrey|plyr,"geoffrey_talk_3", [], "Oh, I see. And how many pirates have you killed?", "geoffrey_talk_4",[]],
  "О да, я вижу. И сколько пиратов сокрушила ваша светлость?"
  [trp_geoffrey,"geoffrey_talk_4", [], "See for yourself! I scalp every one of the dogs I kill. They are my battle trophies.", "geoffrey_talk_5",[]],
  "Смотри сам! Я снимаю скальп с каждого из тех псов, убитых мною. Их скальпы -  мои боевые трофеи.”
  [trp_geoffrey|plyr,"geoffrey_talk_5", [], "That's nice. I'll be going now.", "close_window",[]],
  "Как здорово. Ну я пошел."

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

  [trp_geoffrey|plyr,"geoffrey_talk_5", [(check_quest_active,"qst_speak_with_troublemakers"),(eq,"$geoffrey_duel",0)], "Really? Those scalps look suspiciously like horse tails to me.", "geoffrey_hostile",[]],
  "Правда? А вон тот скальп разве не похож на лошадиную голову?”
  [trp_geoffrey|plyr,"geoffrey_talk", [(check_quest_active,"qst_speak_with_troublemakers"),(eq,"$geoffrey_duel",0)], "You look familiar. Haven't I seen your face in a pigsty before?", "geoffrey_hostile",[]],
  "Ты выглядишь знакомо. Слушай, может я уже видел твою харю в свинарнике?"

Эти две реплики создадут дополнительные варианты ответа для игрока, со статусами вызова "geoffrey_talk_5"  и “geoffrey_talk" соответственно. Техничекси не важно в каком месте файла module_dialogs.py вы вставите записи диалога игрока с одинаковыми статусами вызова. Система найдет их всех и, если требования блока условий были выполенны, добавит в меню, к остальным вариантам ответа. Но лучше все-таки, располагать записи как можно ближе к друг другу, это сделает ваш код читаемым и легкомодифицируемым для вас.

Примечательное свойство наших двух новых линий – это блок условий. Обе реплики появятся только в том случае, если квест "qst_speak_with_troublemakers" активен и значение переменной "$geoffrey_duel" равно 0. Если хоть какое-то из условий не выполняется, реплики не будут отображены. Теперь скопируйте и вставьте последние несколько записей:

  [trp_geoffrey,"geoffrey_hostile", [], "What?! I'll see you dead for that insult, peasant! Don't you know who I am?", "geoffrey_hostile_2",[]],
  "Что?! Ты сдохнешь за это оскорбление, крестьянин! Ты что, не знаешь кто я такой?!”
  [trp_geoffrey|plyr,"geoffrey_hostile_2", [], "No . . . Was I supposed to remember?", "geoffrey_hostile_3",[]],
  (Нет... А я должен знать?)
  [trp_geoffrey,"geoffrey_hostile_3", [], "Why, I'm Geoffrey Eaglescourt, son of the Baron Eaglescourt, and you have delivered the gravest insult to my family's honour! I demand satisfaction! Meet me outside the town walls tonight, or you will be known a coward to every man in this countryside. Good day, {sirrah/wench}.", "geoffrey_hostile_4",[]],
  “Что же, я Джоффри Иглскорт, сын барона Иглскорта, и ты нанес смертельное оскорбление моей фамильной чести! Я требую сатисфакции! Встреть меня сегодня ночью за городскими стенами или каждый человек в окрестностях Зендара будет знать, что ты трус! Доброго дня, {сударь/сударыня}.”
  [trp_geoffrey|plyr,"geoffrey_hostile_4", [], "Charming lad. Tonight, eh . . . ? I shouldn't miss it . . .", "close_window",[(assign,"$geoffrey_duel",1)]],
  "Прелестный пацанчик. Сегодня ночью, значит?... Надо бы не пропустить...”

Этими строками мы закончим наш диалог. Теперь у нас есть беседа с некоторым количеством условий и последствий, непосредственно связанных с квестом. Мы вплотную подошли к записи квестовой линии диалога; но мы еще не прописали условия, позволяющие игроку активировать квест в диалоге с констеблем Хареком. Мы сделаем это в следующем разделе.

7.4. Диалоги и квесты.

Добавляя ветки диалога к уже существующей беседе, мы должны быть очень осторожны, необходимо правильно совместить наши новые реплики с написаными ранее. Помните, что система сканирует файл module_dialogs.py сверху вниз; не забывайте проверять ваш блок условий; следите за правильностью синтаксиса ваших записей. Одно упущение может повлиять на работу всего блока кода. Не ленитесь конструировать ваш модуль заново (щелкать на файл module.bat), это поможет сразу же выявить синтаксические ошибки.

Сначала мы добавим одну новую запись для Джоффри, и проследите, что вы вставили ее как минимум на строку выше любой другой из линий диалога Джоффри (это важно). Это приведет к тому, что линия диалога будет обработанна первой, и если игровая ситуация соответствует ее блоку условий и статусу вызова, то именно она и только она будет выведена на экран (все это касательно линий диалога, произносимых не игроком).   

В настоящий момент первая из веток диалога Джоффри это:

  [trp_geoffrey,"start", [], "What? What do you want? Leave me be, {sir/wench}, I have no time for beggars.", "geoffrey_talk",[]],
  “Вам что-то надо? Оставьте меня в покое, {сударь/сударыня}, у меня нет времени для попрошаек”

Теперь, скопируйте и вставьте следущее, перед упомянутой выше записью:

  [trp_geoffrey,"start", [(eq,"$geoffrey_duel",1)], "Begone! I have nothing to say to you, varlet.", "close_window",[]],
  ”Пшел прочь! Мне не о чем разговаривать с тобой, каналья.”

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

Последняя запись беседы с Констеблем Хареком это:

  [trp_constable_hareck|plyr,"constable_hareck_talk", [], "Nothing. Good-bye.", "close_window",[]],
  ”Ничего. Всего хорошего.”

Статус вызова "constable_hareck_talk" принадлежит к статусу вызова меню диалога с набором разных вариантов ответа для игрока, из которых данная запись является последним ответом в списке. Для того чтобы эта запись в меню выбора ответов (вариант ответа ведущий к завершению диалога) оставалась последней мы должны добавить нашу новую линию диалога перед ней.

Скопируйте и вставьте следущее перед вышеупомянотой записью:

  [trp_constable_hareck|plyr,"constable_hareck_talk", [(neg|check_quest_active,"qst_speak_with_troublemakers"),(neg|check_quest_finished,"qst_speak_with_troublemakers")], "Is something wrong? You look worried.", "constable_hareck_troublemakers",[]],
  "Все в порядке? Ты выглядишь обеспокоенным.”

Эта запись не будет отображена если квест "qst_speak_with_troublemakers" активен или завершен. Реализуется с помощью операции отрицания “neg” привязанной к проверке активности и завершенности квеста "qst_speak_with_troublemakers" в поле статуса вызова. К примеру, если для истинности операции сравнения “eq” требуется, чтобы два значения были равны друг другу, то для истинности комбинированной операции отрицания-сравнения “neg|eq” значения должны отличаться.

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

  [trp_constable_hareck,"constable_hareck_troublemakers", [], "Oh, it's nothing, just . . .", "constable_hareck_troublemakers_2",[]],
  ”О...Все в порядке, просто...”
  [trp_constable_hareck|plyr,"constable_hareck_troublemakers_2", [], "You can tell me, sir.", "constable_hareck_troublemakers_3",[]],
  "Ты можешь мне довериться, сэр"
  [trp_constable_hareck,"constable_hareck_troublemakers_3", [], "No harm in it, I suppose. The trouble is, a few of the town's young nobles . . . spoiled dandies and fops, the lot of them . . . they've decided that suddenly they're men to be respected, and that they should 'take matters into their own hands', to 'take action where the official government has failed'. They say they're going to kill all the river pirates that have been troubling Zendar of late. Of course, they've not actually gone out to fight any river pirates, but they've been making a great ruckus in town and there's not a thing I can do about it.", "constable_hareck_troublemakers_4",[]],
  "Да ничего особенного не произошло, я полагаю. Есть несколько мололых дворян... избалованые пижоны и щеглы, в большинстве своем... они вдруг решили, что являются уважаемыми людьми и что должны взять дела в городе в собственные руки. Дела, где по их мнению городские власти не справляются. Они говорят: “Мы убьем всех речных пиратов в окрестностях Зендара!” Конечно же  никто из них не собирается идти сражаться с пиратами, но они поднимают слишком много шума в городе и я ничего не могу с этим поделать.”
  [trp_constable_hareck|plyr,"constable_hareck_troublemakers_4", [], "Hmm . . . Would there be a reward for solving this problem?", "constable_hareck_troublemakers_5",[]],
  ”Хмм... А полагается ли награда, за решение этой проблемы?”
  [trp_constable_hareck,"constable_hareck_troublemakers_5", [], "What? What are you saying?", "constable_hareck_troublemakers_6",[]],
  ”Что? О чем ты говоришь?"
  [trp_constable_hareck|plyr,"constable_hareck_troublemakers_6", [], "Nothing, sir. However, it sounds to me like a neutral third party might be just what you need. I could talk to them.", "constable_hareck_troublemakers_7",[]],
  ”Ничего, сэр. Просто мне кажется,что нейтральная третья сторона это, то что тебе нужно. Я мог бы поговорить с ними.”
  [trp_constable_hareck,"constable_hareck_troublemakers_7", [], "Heh. Well, you can try, friend. If you manage to do any good, I'll even throw in a few coins for getting the sand out of my breeches. Their leader is a boy named Geoffrey, spends most of his time on watered-down ale and whores in the Happy Boar. Chances are you'll find him there.", "constable_hareck_troublemakers_8",[]],
  "Хех. Что же, ты можешь попытаться, друг. И если ты хорошо управишься с этим делом, я даже подкину несколько монет за то, что ты сдул песок с моих бриджей. Их лидер, это мальчишка по имени Джоффри, он тратит  большую часть времени на эль и проституток. Все шансы, что ты встретишь его в трактире Счастливый Вепрь.“
  [trp_constable_hareck|plyr,"constable_hareck_troublemakers_8", [], "Thank you, constable. I shall return.", "close_window",[(setup_quest_text,"qst_speak_with_troublemakers"),(start_quest,"qst_speak_with_troublemakers")]],
  "Благодарю, констэбль. Я еще вернусь за деньгами.”

  [trp_constable_hareck|plyr,"constable_hareck_talk", [(check_quest_active,"qst_speak_with_troublemakers"),(eq,"$geoffrey_duel",2)], "Constable, I've taken care of the toublemakers for you. They shouldn't be a worry any longer.", "constable_hareck_troublemakers_10",[]],
  "Констэбль, я позаботился о вашей проблемме. Эти нарушителя порядка вас больше не побеспокоят.”
    [trp_constable_hareck,"constable_hareck_troublemakers_10", [], "Truly? Thank God! A few more days and I would've thrown them all into a cell and thrown away the key. Here, take this. You've earned it.", "constable_hareck_troublemakers_11",[(troop_add_gold,"trp_player",100),(add_xp_as_reward,750),(succeed_quest,"qst_speak_with_troublemakers")]],
  ”Правда? Слава Богу! Еще несколько дней и я бы запер их тюремную камеру, а ключ от дверей выбросил бы куда подальше. Вот, возьми это. Ты честно заработал эти деньги.”
  [trp_constable_hareck|plyr,"constable_hareck_troublemakers_11", [], "My pleasure, constable. If you've any other jobs that need doing, please let me know. Farewell.", "close_window",[]],
  ”Моя благодарность, констэбль. Если у тебя появится другое задание, дай мне знать. До встречи”

  [trp_constable_hareck|plyr,"constable_hareck_talk", [(check_quest_active,"qst_speak_with_troublemakers"),(eq,"$geoffrey_duel",3)], "Constable, I failed. I'm sorry.", "constable_hareck_troublemakers_15",[]],
  ”Констэбль, я потерпел неудачу. Сожалею.”
  [trp_constable_hareck,"constable_hareck_troublemakers_15", [], "Oh . . . Oh well. I suppose you did the best you could. Thanks anyway, friend. Perhaps some other job will suit you better. I shall let you know when I have any. Farewell.", "close_window",[(fail_quest,"qst_speak_with_troublemakers")]],
  ”О... Ну что-же, я полагаю ты сделал все возможное. Спасибо в любом случае, друг. Может с другими заданиями ты справишься лучше. Я дам тебе знать, если у меня появится что-то. До встречи.”

Первый блок активирует квест и объясняет его детали. Второй блок - окончание квеста с приятной маленькой наградой в виде золота и опыта, требует наличия у переменной "$geoffrey_duel" значения 2, которое появится только в случае победы над Джоффри. Третий блок задает окончание квеста, если игрок не смог победить Джоффри, что означает отсутствие награды.

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