Создание диалогов (полный обзор) — различия между версиями — S.T.A.L.K.E.R. Inside Wiki

Создание диалогов (полный обзор) — различия между версиями

Материал из S.T.A.L.K.E.R. Inside Wiki

Перейти к: навигация, поиск
(EaTHRlpycQMrFlinJka)
Строка 1: Строка 1:
'''Статья в процессе написания...'''
+
6Hg6fm  <a href="http://kvzwbksamvjn.com/">kvzwbksamvjn</a>, [url=http://yukomvspdute.com/]yukomvspdute[/url], [link=http://wyexoybopbqb.com/]wyexoybopbqb[/link], http://aprxmnkkuwwb.com/
 
+
===Общие данные===
+
 
+
В диалогах обычно задействуются три .xml-файла:
+
 
+
* character_desc_x.xml
+
* dialogs_x.xml
+
* stable_dialogs_x.xml
+
 
+
В них нам важны, соотвественно, списки присвоения диалогов персонажам, структуры диалогов и текстовые массивы для фраз.
+
 
+
===Структура фраз===
+
 
+
В общем виде диалог выглядит так:
+
 
+
 
+
'''диалог 001'''<br><br>'''фраза 0'''<br>
+
''"Так, чего хотел-то?"''<br>
+
следующие фразы: '''1'''<br><br>'''фраза 1'''<br>
+
''"Задание для тебя есть. Возьмешься?"''<br>
+
следующие фразы: '''21, 22'''<br><br>'''фраза 21'''<br>
+
''"Ну, давай."''<br>
+
следующие фразы: '''3'''<br><br>'''фраза 22'''<br>
+
''"Не, иди к черту."''<br>
+
следующие фразы: '''нет'''<br>
+
действие: '''выйти из диалога'''<br><br>[фраза 3 и дальнейшее продолжение...]<br><br>'''конец диалога'''
+
 
+
 
+
В файлах эта структура записывается следующим образом:
+
 
+
<xml>
+
<dialog id="escape_trader_letat_gusi">
+
<phrase_list>
+
 
+
<phrase id="0">
+
<text>Так, чего хотел-то?</text>
+
<next>1</next>
+
</phrase>
+
 
+
<phrase id="1">
+
<text>Задание для тебя есть. Возьмешься?</text>
+
<next>21</next>
+
<next>22</next>
+
</phrase>
+
 
+
<phrase id="21">
+
<text>Ну, давай.</text>
+
<next>3</next>
+
</phrase>
+
 
+
<phrase id="22">
+
<text>Не, иди к черту.</text>
+
<action>dialogs.break_dialog</action>
+
</phrase>
+
 
+
[...]
+
 
+
</phrase_list>
+
</dialog>
+
</xml>
+
 
+
Разберемся подробнее.
+
 
+
Во-первых, принадлежность фраз.
+
Они могут принадлежать или игроку, или NPC, причем:
+
 
+
* фраза, принадлежащая игроку, всегда идет первой, а за ней уже по древу диалога игра понимает, чья фраза кому принадлежит (например, у нас 0, 21, 22 - игрока; а 1, 3 - NPC)
+
* только у фразы, принадлежащей NPC, можно выбрать несколько вариантов ответа игрока
+
 
+
Впрочем, и у фразы игрока можно сделать несколько вариантов ответов, но поскольку компьютер не обладает способностью самостоятельно выбирать, то каждый из вариантов должен быть заранее определен по условиям выбора (например, по наличию у игрока какого-нибудь предмета, или количества денег, или репутации и т.д.), причем условия выбора различных вариантов никогда не должны одновременно становиться подходящими. Это мы разберем позднее.
+
 
+
Во-вторых, структура фразы.
+
Простейшая фраза выглядит так:
+
 
+
<xml>
+
<phrase id="0">    -- открывающий тег с ID фразы
+
<text>Привет.</text>    -- текст фразы
+
<next>1</next>    -- ссылка на следующую фразу
+
</phrase>    -- закрытие тега фразы
+
</xml>
+
 
+
Но есть возможность строить и такие фразы (в данном случае она принадлежит NPC, а игрок на неё будет давать ответ):
+
 
+
<xml>
+
<phrase id="1">
+
<give_info>propusk_given</give_info> -- выдача инфопорции (см. объяснение №1 ниже)
+
<text>Вот, держи пропуск. Теперь тебе охранник позволит войти.</text>
+
<action>dialogs.give_propusk_item</action> -- ссылка на скрипт (см. объяснение №2 ниже)
+
<next>21</next>
+
<next>22</next>
+
<next>23</next>
+
</phrase>
+
</xml>
+
 
+
* 1. Здесь у нас выдается [[Инфопорция|инфопорция]], которая может потом использоваться в различных местах (например, её наличие может проверяться каким-нибудь охранником - и если она есть, то он, скажем, отойдет и пропустит игрока внутрь). Важно понимать отличие инфопорции от предмета. Инфопорция - это ''факт наличия'' пропуска, а лежащий в инвентаре пропуск - ''материальный предмет''. Можно, кстати, обойтись и без инфопорций, впоследствии пользуясь скриптами, проверяющими инвентарь игрока и ищущими нужный предмет, но этот способ сложен и нам пока не понадобится.
+
 
+
* 2. Это скрипт, выдающий игроку предмет "пропуск" в инвентарь. Ссылка на скрипты дается в формате имя_файла.имя_функции.
+
 
+
Как видите, фраза, в которой некий NPC выдает игроку пропуск, позволяющий пройти дальше, достаточно сложна.
+
 
+
Вот еще один пример (здесь она принадлежит игроку):
+
 
+
<xml>
+
<phrase id="4">
+
<has_info>propusk_given</has_info> -- проверка на наличие инфопорции propusk_given
+
<text>Да, пропуск у меня есть.</text>
+
<action>dialogs.break_dialog</action> -- ссылка на скрипт, завершающий диалог
+
</phrase>
+
</xml>
+
 
+
Здесь у нас фраза из диалога игрока с NPC - та, что после вопроса NPC "А пропуск у тебя есть?". Это один из вариантов ответа на неё. Особенность в том, что этот вариант не появится, если пропуска у вас на самом деле нет - она появляется только при наличии нужной инфопорции (за это отвечает строка с <has_info>).
+
 
+
Далее, поподробнее остановимся на задании условий появления фразы.<br>
+
Способов это сделать - два.
+
 
+
    * проверка на наличие инфопорций
+
    * проверка через скриптовую функцию
+
 
+
Первый метод мы видели выше, а второй - гораздо более комплексный и многофункциональный. Он запускает скрипт, который проводит проверку определенных вещей, и возвращает true/false. Простой пример - NPC требует денег (скажем, 5000 рублей), а нам нужно, чтобы ответная фраза игрока "Вот, держи свои 5000.", могла быть доступна для выбора, только если у нас действительно есть эти деньги. Для этого пишем такую фразу:
+
 
+
<xml>
+
<phrase id="8">
+
<text>Вот, держи, ровно 5000.</text>
+
<precondition>dialogs.actor_have_5000</precondition> -- вызываем условие (см. объяснение №1 ниже)
+
<action>dialogs.transfer_5000</action> -- передача денег скриптом (см. объяснение №2 ниже)
+
<next>9</next>
+
</phrase>
+
</xml>
+
 
+
* 1. Этот скрипт который проверяет наличие денег: если было возвращено true, то фраза доступна.
+
* 2. Вызываем другой скрипт, действие - он осуществляет саму передачу денег.
+
 
+
Да, кстати, порядок расстановки тегов внутри фразы не играет никакой роли - они все выполняются одновременно. Единственное - <next> всегда последний. Еще одно - есть второй вид проверки на инфопорцию - он наоборот, проверяет её отсутствие. Применяется точно так же, но называется не has_info, а dont_has_info.
+
 
+
Итак, что у нас есть:
+
 
+
* '''<phrase id="..."></phrase>''' - общий тег фразы, задание номера фразы
+
* '''<nowiki><text>...</text></nowiki>''' - тег, содержащий текст фразы
+
* '''<give_info>...</give_info>''' - выдача инфопорции с именем, записанным в теге
+
* '''<has_info>...</has_info>''' - проверка на наличие инфопорции с именем, записанным в теге
+
* '''<dont_has_info>...</dont_has_info>''' - проверка на отсутствие инфопорции с именем, записанным в теге
+
* '''<precondition>...</precondition>''' - запуск скрипта, возвращающего true или false в зависимости от чего-либо (скриптовая проверка)
+
* '''<action>...</action>''' - запуск скрипта
+
* '''<next>...</next>''' - тег ссылки на следующую фразу
+
 
+
 
+
В первой версии - достаточно просто окна с формами для ввода этих параметров. А программа на основе введенных данных будет собирать фразу. Например, на основе вот таких введенных в поля данных:
+
 
+
Номер фразы: '''12'''<br><br>Текст: ''Да, там сейчас база военных.<br>Я не в курсе, сколько их там точно, но<br>могу сказать, не меньше, чем один два отряда.''<br><br>Выдать инфопорцию: '''info_about_military_base'''<br><br>Проверить наличие инфопорции: '''info_1'''<br>Проверить отсутствие инфопорции: '''нет'''<br>Проверить через скрипт: '''dialogs.is_npc_a_friend'''<br>Совершить действие: '''dialogs.break_dialog'''<br><br>Номера следующих фраз: '''13'''<br><br>
+
 
+
Нам нужна вот такая запись:
+
 
+
<xml>
+
<phrase id="12">
+
<has_info>info_1</has_info>
+
<text>Да, там сейчас база военных. Я не в курсе, сколько их там точно [...]</text>
+
<precondition>dialogs.is_npc_a_friend</precondition>
+
<action>dialogs.break_dialog</action>
+
<give_info>info_about_military_base</give_info>
+
<next>13</next>
+
</phrase>
+
</xml>
+
 
+
===Текстовые (строковые) массивы===
+
 
+
Мы упустили один важный нюанс, критичный для крупных диалогов.
+
 
+
<xml>
+
<phrase id="54">
+
<text>Здравствуй, сталкер. Чем я могу помочь тебе?</text>
+
<next>55</next>
+
</phrase>
+
</xml>
+
 
+
Мы записывали текст фразы в <'''text>...</text>'''. Это, безусловно, удобно, но на самом деле - может привести к проблемам. Дело в том, что таким образом можно использовать только короткие фразы. Стоит ввести в тег длинный текст, и игра... так сказать, не переварит наш диалог.
+
 
+
Поэтому нужно использовать не тексты, а ссылки на них. Работает это так:
+
 
+
[[Изображение:Text massive explain.jpg]]
+
 
+
То есть фразу мы записываем так:
+
 
+
<xml>
+
<phrase id="54">
+
<text>my_text_1</text>
+
<next>55</next>
+
</phrase>
+
</xml>
+
 
+
А в игре видим нормальный текст - игра по названию my_text_1 находит его в массиве.<br>
+
Массивы (для русскоязычной версии игры) находятся в папке:
+
 
+
<pre>S.T.A.L.K.E.R\gamedata\config\text\rus</pre>
+
 
+
Нужные вам тексты фраз вы можете прописывать в любом из находящихся там .xml-файлов, их разделение на специализации - чисто формальное. Лучше всего держать тексты всех ваших диалогов в одном месте, поэтому выберите один файл - этим вы упростите работу тем, кто будет скрещивать ваш мод с другими.
+
 
+
Запись текста происходит в такой форме:
+
 
+
<xml>
+
<string id="my_text_1"> -- в заголовке указывается имя текста, которое вызывается из диалога
+
<text>Здравствуй, сталкер. Чем я могу помочь тебе?</text> -- собственно, сам текст
+
</string>
+
</xml>
+
 
+
===Диалоги===
+
 
+
Ну что же, структуру фраз мы полностью разобрали. Теперь попробуем собрать из них полноценный диалог. Для начала выберем жертву для экспериментов - Сидорович вполне подойдет :)
+
 
+
Откроем папку:
+
 
+
<pre>S.T.A.L.K.E.R\gamedata\config\gameplay</pre>
+
 
+
Сейчас нас интересует файл '''character_desc_escape.xml''', хранящий профили персонажей с локации "Кордон" (остальные файлы названы по аналогичной системе - вместо '''escape''', соответственно, идет название других уровней). Открываем его и видим профиль Сидоровича '''escape_trader''' - он находится в самом начале файла.
+
 
+
<xml>
+
<specific_character id="escape_trader" no_random = "1">
+
<name>escape_trader_name</name>
+
<icon>ui_npc_u_trader</icon>
+
<bio>escape_trader_bio</bio>
+
 
+
<class>trader</class>
+
<community>trader</community>
+
<visual>actors\trader\trader</visual>
+
 
+
<rank>330</rank>
+
<reputation>23</reputation>
+
<money min="100000" max="100000" infinitive="1"/>
+
<supplies>
+
[spawn] \n
+
wpn_knife \n
+
</supplies>
+
 
+
<start_dialog>escape_trader_start_dialog</start_dialog>
+
<actor_dialog>escape_trader_talk_info</actor_dialog>
+
<actor_dialog>escape_trader_jobs</actor_dialog>
+
<actor_dialog>tm_trader_dialog</actor_dialog>
+
<actor_dialog>tm_trader_reward</actor_dialog>
+
<actor_dialog>escape_trader_done_blockpost_box</actor_dialog>
+
</specific_character>
+
</xml>
+
 
+
Подробный разбор параметров профиля мы делать не будем - для этого существует [[Редактирование_NPC|отдельная статья]]. Сейчас нас интересуют теги <actor_dialog>...</actor_dialog>, ссылающиеся на доступные у этого NPC диалоги. Добавим в этот список и ссылку на наш будущий диалог:
+
 
+
<xml>
+
<start_dialog>escape_trader_start_dialog</start_dialog>
+
<actor_dialog>my_dialog_1</actor_dialog>
+
<actor_dialog>escape_trader_talk_info</actor_dialog>
+
<actor_dialog>escape_trader_jobs</actor_dialog>
+
<actor_dialog>tm_trader_dialog</actor_dialog>
+
<actor_dialog>tm_trader_reward</actor_dialog>
+
<actor_dialog>escape_trader_done_blockpost_box</actor_dialog>
+
</xml>
+
 
+
Далее добавим в любой диалоговый файл, например, в '''dialogs_escape.xml''', следующий диалог:
+
 
+
<xml>
+
<dialog id="my_dialog_1">
+
<precondition>my_script_for_dialogs.my_function_1</precondition> -- условия можно вызывать и здесь
+
<phrase_list>
+
<phrase id="0"> -- фразы Меченого
+
<text>my_text_0</text> -- "Ага, вот эти ребята..."
+
<next>1</next>
+
</phrase>
+
<phrase id="1"> -- фразы Сидоровича
+
<text>my_text_1</text> -- "Ненене!!! Нет, Меченый, нет!"
+
<next>2</next>
+
</phrase>
+
<phrase id="2">
+
<text>my_text_2</text> -- "Я делаю особую, уличную магию. Кто хочет увидеть немного магии?"
+
<next>3</next>
+
</phrase>
+
<phrase id="3">           
+
<text>my_text_3</text> -- "Что я тебе, Толик какой-нибудь? Целый день у этих идиотов из лагеря
+
<next>4</next>            разный хлам скупал, устал, хочу просто отдохнуть..."
+
</phrase>
+
<phrase id="4">
+
<text>my_text_4</text> -- "И что купил?"
+
<next>5</next>
+
</phrase>
+
<phrase id="5">
+
<text>my_text_5</text> -- "Я купил зеленый свитер, если ты так хочешь знать! Сорок долларов,
+
<next>6</next>            между прочим."
+
</phrase>
+
<phrase id="6">
+
<text>my_text_6</text> -- "Зеленый свитер? А ты уверен, что не купил тедди-бир?"
+
<next>7</next>
+
</phrase>
+
<phrase id="7">
+
<text>my_text_7</text> -- "Тедди-бир?... ТЕДДИ-БИР!!! Где мой зеленый свитер, ты что делаешь, демон?!"
+
<next>8</next>
+
</phrase>
+
<phrase id="8">
+
<text>my_text_8</text> -- "Ладно, ладно... еще один фокус. Будь добр, взгляни на телевизор
+
<next>9</next>            рядом с тобой. Что он показывает?"
+
</phrase>
+
<phrase id="9">
+
<text>my_text_9</text> -- "Билд 1154!!! Ты что делаешь, демон, ты что делаешь?! Проваливай отсюда!"
+
<next>10</next>
+
</phrase>
+
<phrase id="10">         
+
<text>my_text_10</text> -- "Ладно."
+
<action>dialogs.break_dialog</action> -- выход из диалога
+
</phrase>
+
</phrase_list>
+
</dialog>
+
</xml>
+
 
+
Для начала лучше попробовать свои силы в простом линейном диалоге вроде этого.<br>
+
Да, и не забудьте добавить строки с текстовыми фразами в массив.<br><br>
+
* Если вам неясно, что за ахинея написана в текстах, вам [http://ru.youtube.com/watch?v=CdTIQ6BVlvw&feature=related сюда] xD
+
 
+
=== "Динамические диалоги" ===
+
 
+
Выше был изложен вариант написания простых диалогов вопрос-ответ. Но в этой части статьи я расскажу как написать "динамические диалоги", которые предполагают выбор ответа не только ГГ, но и НПС с которым мы говорим. Рассчитано на опытных пользователей диалога.
+
 
+
Вообще урок это копия предыдущей статьи, с той лишь небольшой разницей, что у как и у ГГ, так и у НПС будет несколько вариантов ответов. Получившаяся структура диалога:
+
 
+
<xml>
+
<dialog id="название диалога">
+
<phrase_list>
+
<phrase id="0">
+
<text>слушаю</text>
+
<next>10</next>
+
</phrase>
+
<phrase id="10">
+
<text>Привет, как дела?</text>
+
<next>1</next>
+
<next>2</next>
+
<next>3</next>
+
</phrase>
+
<phrase id="1">
+
<text>Отлично!</text>
+
<next>11</next>
+
</phrase>
+
<phrase id="2">
+
<text>Нормик, что хотел?</text>
+
<next>21</next>
+
</phrase>
+
<phrase id="3">
+
<text>Плохо, иди отсюда(</text>
+
<action>dialogs.break_dialog</action>
+
</phrase>
+
<phrase id="11">
+
<text>Это хорошо =)</text>
+
</phrase>
+
<phrase id="21">
+
<text>Да вот {....}</text>
+
</phrase>
+
[и так далее]
+
</phrase_list>
+
</dialog>
+
</xml>
+
Ну вот как-то так. Рассмотрим наиболее интересную часть:
+
<xml>
+
<phrase id="10">
+
<text>Привет, как дела?</text>
+
<next>1</next>
+
<next>2</next>
+
<next>3</next>
+
</xml>
+
Здесь мы предоставляем выбор дальнейшего диалога для НПС, причём в этой структуре его выбор получается абсолютно рандомным.
+
Скриншоты: [[Изображение:Dialog02.jpg|950px]]
+
 
+
 
+
[[Изображение:Dialog01.jpg|950px]]
+
+
Можно прописать установки и проверки для ответов, например, можно реализовать возможность отдавания ненужных вещей какому-нибудь нпс, тогда структура будет выглядеть примерно так(писать полностью не буду, только фразы):
+
<xml>
+
ГГ: Привет, у меня тут есть некоторые вещи, взгляни, нужно что?
+
НПС ответ1: (проверка на АК-47) Да, мне нужна эта пушка!
+
НПС ответ2: (проверка на консервы) Ух как кушать хочется, можешь мне дать консерву?
+
НПС ответ3: (без предпроверки) Есть ли у тебя водка?
+
ГГ на ответ 1 и 2: Да, держи!
+
ГГ на ответ 3: (проверка) Держи/ Извини, нету((
+
</xml>
+
 
+
Ну и напоследок скажу, что можно даже управлять вероятностью ответа НПС на фразу ГГ, если прописать несколько <next>номер ответа</next>. Например, если написать:
+
<xml>
+
 
+
<next>1</next>
+
<next>3</next>
+
<next>3</next>
+
<next>3</next>
+
 
+
</xml>
+
То вероятность ответа "3" будет составлять 75%
+
 
+
P.S.: Это не просто увлекательная и интересная вещь, но и очень уж трудоёмкая - у меня день уходил на создание простого диалога. Для огромной модификации только на диалоги нужно человек 20-30. Но зато одних диалогов хватит чтобы впечатлить! Аналогов быть не должно, а сама игра использует этот приём только в ЗП и то в 2-х местах(на Затоне, другие локации не глядел).
+
 
+
==Дополнительные сведения по диалогам==
+
 
+
==Скрипт-генерируемые диалоги==
+
 
+
[[Категория:Конфигурационные_файлы]]
+

Версия 16:49, 28 февраля 2011

6Hg6fm <a href="http://kvzwbksamvjn.com/">kvzwbksamvjn</a>, [url=http://yukomvspdute.com/]yukomvspdute[/url], [link=http://wyexoybopbqb.com/]wyexoybopbqb[/link], http://aprxmnkkuwwb.com/

Другие места
LANGUAGE