Создание диалогов (полный обзор)
Материал из Mod Wiki.
Версия 09:12, 5 июля 2008 (править) BAC9-FLCL (Обсуждение | вклад) ← К предыдущему изменению |
Версия 09:12, 5 июля 2008 (править) (отменить) BAC9-FLCL (Обсуждение | вклад) К следующему изменению → |
||
Строка 98: | Строка 98: | ||
</source> | </source> | ||
- | * 1. здесь у нас выдается [[ | + | * 1. здесь у нас выдается [[Инфопорция|инфопорция]] которая может потом использоваться в различных местах (например, её наличие может проверяться каким-нибудь охранником - и если она есть, то он, скажем, отойдет и пропустит игрока внутрь). |
Как видите, фраза, в которой некий NPC выдает игроку пропуск, позволяющий пройти дальше, достаточно сложна. | Как видите, фраза, в которой некий NPC выдает игроку пропуск, позволяющий пройти дальше, достаточно сложна. |
Версия 09:12, 5 июля 2008
Статья в процессе написания...
Общие данные
В диалогах обычно задействуются три .xml-файла:
- character_desc_x.xml
- dialogs_x.xml
- stable_dialogs_x.xml
(где x - название уровня)
Главными являются файлы dialogs_x.xml, на них, собственно, и будет направлена основная работа инструмента. В этих файлах хранится структура, скелет диалога. Кстати, x - это не обязательно название уровня. В принципе, диалоги можно помещать абсолютно произвольно, просто по локациям - это удобней для последующей работы.
Структура фраз
В общем виде диалог выглядит так:
диалог 001
фраза 0
"Так, чего хотел-то?"
следующие фразы: 1
фраза 1
"Задание для тебя есть. Возьмешься?"
следующие фразы: 21, 22
фраза 21
"Ну, давай."
следующие фразы: 3
фраза 22
"Не, иди к черту."
следующие фразы: нет
действие: выйти из диалога
[фраза 3 и дальнейшее продолжение...]
конец диалога
В файлах эта структура записывается следующим образом:
<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>
Разберемся подробнее.
Во-первых, принадлежность фраз. Они могут принадлежать или игроку, или NPC, причем:
- фраза, принадлежащая игроку, всегда идет первой, а за ней уже по древу диалога игра понимает, чья фраза кому принадлежит (например, у нас 0, 21, 22 - игрока; а 1, 3 - NPC)
- только у фразы, принадлежащей NPC, можно выбрать несколько вариантов ответа игрока
Впрочем, и у фразы игрока можно сделать несколько вариантов ответов, но поскольку компьютер не обладает способностью самостоятельно выбирать, то каждый из вариантов должен быть заранее определен по условиям выбора (например, по наличию у игрока какого-нибудь предмета, или количества денег, или репутации и т.д.), причем условия выбора различных вариантов никогда не должны одновременно становиться подходящими. Это мы разберем позднее.
Во-вторых, структура фразы. Простейшая фраза выглядит так:
<phrase id="0"> -- открывающий тег с ID фразы <text>Привет.</text> -- текст фразы <next>1</next> -- ссылка на следующую фразу </phrase> -- закрытие тега фразы
Но есть возможность строить и такие фразы (в данном случае она принадлежит NPC, а игрок на неё будет давать ответ):
<phrase id="1"> <give_info>propusk_given</give_info> -- выдача инфопорции (см. объяснение ниже) <text>Вот, держи пропуск. Теперь тебе охранник позволит войти.</text> <action>dialogs.give_a_weapon</action> -- ссылка на скрипт, выдающий игроку пропуск в инвентарь; дается в формате имя_файла.имя_функции <next>21</next> <next>22</next> <next>23</next> </phrase>
- 1. здесь у нас выдается инфопорция которая может потом использоваться в различных местах (например, её наличие может проверяться каким-нибудь охранником - и если она есть, то он, скажем, отойдет и пропустит игрока внутрь).
Как видите, фраза, в которой некий NPC выдает игроку пропуск, позволяющий пройти дальше, достаточно сложна.
Вот еще один пример (здесь она принадлежит игроку):
<phrase id="4"> <has_info>propusk_given</has_info> -- проверка на наличие инфопорции propusk_given <text>Да, пропуск у меня есть.</text> <action>dialogs.break_dialog</action> -- ссылка на скрипт, завершающий диалог </phrase>
Здесь у нас фраза из диалога игрока с NPC - после вопроса NPC "А пропуск у тебя есть?" фраза 4, с вариантом ответа "Да, пропуск у меня есть.", появится только при соблюдении условия.
Далее, поподробнее остановимся на задании условий появления фразы. Способов это сделать - два.
* проверка на наличие инфопорций * проверка через скриптовую функцию
Первый метод мы видели выше, а второй - гораздо более комплексный и многофункциональный. Он запускает скрипт, который проводит проверку определенных вещей, и возвращает true/false. Простой пример - NPC требует денег (скажем, 5000 рублей), а нам нужно, чтобы ответная фраза игрока "Вот, держи, ровно 5000.", могла быть доступна для выбора, только если у нас действительно есть эти деньги. Для этого пишем такую фразу:
<phrase id="8"> <text>Вот, держи, ровно 5000.</text> <precondition>dialogs.actor_have_5000</precondition> -- запускается скрипт, который проверяет наличие денег: если было возвращено true, то фраза доступна <action>dialogs.transfer_5000</action> -- ну, раз деньги действительно есть, то по нажатию на эту фразу они будут переданы - с помощью этого действия <next>9</next> </phrase>
Да, кстати, порядок расстановки тегов внутри фразы не играет никакой роли - они все выполняются одновременно. Единственное - <next> всегда последний. Еще нюанс: все эти условия можно использовать только в фразах игрока.
А, да, есть еще второй вид проверки на инфопорцию - он наоборот, проверяет её отсутствие. Применяется точно так же, но называется не has_info, а dont_has_info.
Итак, что у нас есть:
* <phrase id="..."></phrase> * <text>...</text> * <give_info>...</give_info> * <has_info>...</has_info> * <dont_has_info>...</dont_has_info> * <precondition>...</precondition> * <action>...</action> * <next>...</next>
В первой версии - достаточно просто окна с формами для ввода этих параметров. А программа на основе введенных данных будет собирать фразу.
Например, на основе вот таких введенных в поля данных:
Номер фразы: 12 Текст: Да, там сейчас база военных. Я не в курсе, сколько их там, но могу сказать, военных там не меньше, чем один взвод.
Выдать инфопорцию: info_about_military_base
Проверить наличие инфопорции: info_1 Проверить отсутствие инфопорции: нет Проверить через скрипт: dialogs.is_npc_a_friend Совершить действие: dialogs.break_dialog
Номера следующих фраз: 13
Он должен сгенерировать такой код:
<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>