Семимахов
30 апреля 2012 в 8:56
Отправлено: 30.04.2012 8:56:35
Ну-с, поскольку желающие предложить свой квест отсутствуют, потому начнём с малого и для начала оживим разбойника Жельванто из Рощи друидов.
Итак, в Хайдауте сидит некий пройдоха и предлагает редким посетителям купить карту местности. Если игрок соглашается купить карту, то после покупки надобно её изучить. Это и будет первым, совсем простым заданием — «Изучить карту».
Для это потребуется:
[list][*]Создание нового квестового предмета и добавление его в общий список таких предметов[/*:m]
[*]Добавление в бар персонажа, посредством которого игрок может получить задание[/*:m]
[*]Добавление реплик для этого персонажа[/*:m]
[*]Получение игроком квестового предмета от него[/*:m]
[*]Создание квеста, как его понимает игра[/*:m]
[*]Описать получение задания игроком, как результата диалога с посетителем бара[/*:m]
[*]Отслеживание выполнения задания с помощью триггера[/*:m]
[*]Описать выполнение задания[/*:m][/list:u]
Первым делом создаём новый квестовый предмет — карту местности:
- Спойлер
- В data\models\questitems есть фото Йери foto.gam и единственная текстура к нему fot.dds. Оно использовалось в демо версии. Кстати, модель этого же фото используется в Меридиане для пары квестовых книжек, только со своими текстурами. А мы чем хуже? Вот их и берём в качестве основы.
Сначала копируем foto.gam и fot.dds в файлы map.gam и map.dds соответственно. Затем модифицируем map.gam с помощью Far. Открываем его с помощью F3 (просмотр), входим в режим редактирования по F6, ищем по F7 «fot.dds», клавишей Ins включаем режим замены символов и заменяем «fot» на «map», сохраняемся по F2. С map.gam всё.
Осталось только поменять текстуру, чтобы вместо Йери показывалась в том или ином виде карта Рощи друидов. Поработать с текстурой обещался ScorpyX .
Итак, считаем, что квестовая карта местности готова. Теперь её надо добавить в общий список квестовых предметов.
Сначала в data\gamedata\gameobjects\questitems.xml внутрь тега <Prototypes /> добавляем новый предмет:
- Код: Ctrl+A, Ctrl+C
<Prototype
Class = "QuestItem"
Name = "quest_map_sacred_grove"
ModelFile = "quest_map"
ResourceType = "QUEST_MAP" />
Здесь:
Class — название класса.
Name — имя квестового предмета. Оно используется для скриптовых манипуляций.
ModelFile — название модели, задаваемое в data\models\animmodels.xml.
ResourceType — тип ресурса, задаваемого в data\gamedata\resourcetypes.xml.
Класс не меняется. Имя, название модели и тип ресурса придумываем сами.
В data\if\diz\model_names.xml внутрь тега <ModelNames /> добавляем название предмета для энциклопедии:
- Код: Ctrl+A, Ctrl+C
<Item
id="quest_map_sacred_grove"
locForm="0"
value="Карта земель друидов" />
В data\if\strings\uidescription.xml внутрь тега <resource /> добавляем описание предмета для энциклопедии:
- Код: Ctrl+A, Ctrl+C
<string
id="quest_map_sacred_grove_diz"
locForm="0"
value="Купленная у одного пройдохи карта земли друидов. Возможно, она поможет мне найти путь к Оракулу." />
Обращаю внимание на необходимую добавку «_diz» к имени карты.
В data\models\animmodels.xml внутрь тега <AnimatedModels /> добавляем модель карты:
- Код: Ctrl+A, Ctrl+C
<model
id="quest_map"
shadow="1"
shadowVolume="0"
windwavy="0"
file="data\models\questitems\map.gam" />
В data\gamedata\resourcetypes.xml внутрь тега <Type Name="QUEST_ITEM" /> добавляем тип ресурса, строку: - Код: Ctrl+A, Ctrl+C
<Type Name="QUEST_MAP" />
В файл data\models\servers.xml и во все 10 файлов начиная с data\maps\r1m1\servers.xml и по data\maps\r4m2\servers.xml внутрь тега <AnimatedModelsServer /> добавляем строки: - Код: Ctrl+A, Ctrl+C
<Item
id="quest_map"
file="data\models\AnimModels.xml" />
Всё, теперь получив карту у Жельванто можно посмотреть её в списке специальных (квестовых) предметов.
Теперь надо поместить Жельванто в бар и указать для него хотя бы одну стартовую реплику:
- Спойлер
- Заготовка для него уже есть. Это в файле data\maps\r3m1\dynamicscene.xml строки:
- Код: Ctrl+A, Ctrl+C
<Object
Name="Razboynic_Bar_Customer1"
Belong="1063"
Prototype="NPC"
ModelName="r1_man"
cfg="54"
SpokenCount="0" />
Но в ней отсутствует строка со стартовыми репликами, потому Жельванто в баре и не показывают.
Чтобы Жельванто появился в баре надо ввести поле helloReplyNames и названия реплик. В нашем случае:
- Код: Ctrl+A, Ctrl+C
<Object
Name="Razboynic_Bar_Customer1"
Belong="1063"
Prototype="NPC"
ModelName="r1_man"
cfg="54"
helloReplyNames="RazVill_Razboynik1_1_N01 RazVill_Razboynik1_2_N01"
SpokenCount="0" />
Здесь:
Name – имя персонажа.
Belong — принадлежность персонажа к группировке, её номер.
Prototype — прототип персонажа, может быть "PLAYER" (игрок) или "NPC" (игровой персонаж).
ModelName — название модели, задаваемое в data\models\animmodels.xml. В данном случае: - Код: Ctrl+A, Ctrl+C
<model
id="r1_man"
file="data\models\Masks\Region1\man\DwellerMenu.gam"
… />
cfg — номер прикида (вида) персонажа. Он конфигруируется с помощью редактора gsmed (Targem Model Editor). В данном случае для модели DwellerMenu.gam в поле Configuration должно стоять 54. Чтобы поменять вид, нужно с помощью gsmed сконфигурировать желаемый облик персонажа, а потом данные из поля Configuration редактора перенести в поле cfg в dynamicscene.xml.
helloReplyNames — стартовые реплики персонажа из файла data\if\diz\dialogsglobal.xml. Названия реплик идут через пробел. Какие из них выдавать, определяется условиями для каждой реплики в dialogsglobal.xml. В нашем случае определим, что RazVill_Razboynik1_1_N01 — реплика для первой встречи с игроком, а RazVill_Razboynik1_2_N01 — для всех последующих.
SpokenCount — счётчик числа обращений к персонажу. Используется для определения, какую реплику из списка в поле helloReplyNames выдавать при выборе игроком данного персонажа в баре. Меняется только скриптом.
Чтобы добавить ещё кого-нибудь в бар, надо просто скопировать весь <Object />, задать своё имя персонажу (Name), добавить его видимое в баре имя в data\maps\r3m1\object_names.xml и, как минимум, поставить новые реплики. Prototype не меняется, всё остальное — по вкусу.
К примеру, изменения в object_names.xml для нового посетителя бара Razboynic_Bar_Customer2: - Код: Ctrl+A, Ctrl+C
<Object
Name="Razboynic_Bar_Customer2"
FullName="Серванто" />
В результате, в баре появляется возможный кандидат для беседы Серванто.
Создаём диалог игрока с Жельванто:
- Спойлер
- Для это используем редактор диалогов и квестов ConversationEditor.exe из пакета SDK.
Запускаем редактор и открываем файл data\if\diz\dialogsglobal.xml. В папке r3m1 диалог с Жельванто называется «У разбойников». Сюда надо добавить вторую стартовую реплику и связать с основным диалогом.
Для каждой реплики в редакторе есть набор полей:
Текст — текст реплики.
Скрипт-условие — логическая операция на языке Lua. Если результат операции true (верно), то эта реплика показывается в окне диалога. Если результат false (ложно), то нет. Если результат для всех реплик false, то персонаж в окне бара вообще не появляется.
Скрипт-результат — набора команд на языке Lua, которые выполняются, когда реплика появляется на экране.
Итак, нажимаем ПКМ (правая кнопка мыши) на папке «У разбойников» и выбираем «Добавить дочернюю реплику NPC».
В поле Текст заместо «...» пишем реплику, с которой Жельванто обращается к игроку при повторном разговоре, если игрок ранее отказался от покупки карты: «Я знал, что ты вернёшься. Без карты тебе на север не проехать. Цена прежняя - 50 монет.»
Чтобы реплика заменила предыдущую, надо просто уйти с этого поля.
Имя реплики в поле Имя формируется автоматически. Поскольку ранее в dynamicscene.xml для Жельванто уже определили название второй реплики, то меняем её на RazVill_Razboynik1_2_N01.
Теперь нужно определить условия при каких выдаётся либо одна, либо другая реплика.
Какие реплики выдавать, а какие нет удобно определять с помощью счётчика числа обращения к персонажу.
Функция GetCurNpc():GetSpokenCount() получает текущее значение счётчика.
Функция GetCurNpc():SetSpokenCount(<число>) меняет значение счётчика.
Начальное значение счётчика можно задать в dynamicscene.xml в поле SpokenCount.
Таким образом можно определять, в какой раз игрок начал диалог с персонажем.
Для реплики "Чужеземец..." в поле Скрипт-условие заносим проверку:
- Код: Ctrl+A, Ctrl+C
GetCurNpc():GetSpokenCount() == 0
Значение "0" первоначально задано в dynamicscene.xml, и если условие выполняется, то значит игрок в первый раз обратился к персонажу, и эта реплика показывается в окне диалога.
Больше нам показывать это реплику "Чужеземец..." не нужно, поэтому в поле Скрипт-результат заносим: - Код: Ctrl+A, Ctrl+C
GetCurNpc():SetSpokenCount(1)
Таким образом задаём новое значение для счётчика — 1, и при следующем разговоре с персонажем результат логической операции в поле Скрипт-условие будет ложным, и реплика показываться не будет.
Для второй стартовой реплики "Я знал..." в поле Скрипт-условие заносим проверку: - Код: Ctrl+A, Ctrl+C
GetCurNpc():GetSpokenCount() == 1
Поскольку при первом раговоре в счётчик числа обращений была записана "1", то при втором и последующем разговорах с персонажем будет показываться только эта реплика, пока мы не поменяем значение счётчика.
Теперь для "Я знал..." надо указать ответные реплики игрока. Это те же самые, которыми игрок отвечает на реплику "Всего лишь 50 монет. Торг неуместен." Поэтому их создавать не нужно, а надо просто прописать их как ответные для второй стартовой реплики. С помощью ConversationEditor этого сделать нельзя, поэтому надо напрямую редактировать dialogsglobal.xml.
Сохраняемся. Из ConversationEditor можно не выходить. Открываем dialogsglobal.xml в каком-нибудь подходящем текстовом редакторе. Я пользуюсь SciTE.exe из пакета SDK.
Находим реплику с именем "RazVill_Razboynik1_1_N05" и копируем поле - Код: Ctrl+A, Ctrl+C
nextReplies="RazVill_Razboynik1_1_N06a RazVill_Razboynik1_1_N06b RazVill_Razboynik1_1_N06c"
в реплику с именем "RazVill_Razboynik1_2_N01".
Копируем без лишних "/>".
Сохраняемся. В ConversationEditor нажимаем кнопку «Перечитать», смотрим диалог и видим, что у "Я знал..." появились ответные реплики.
Теперь осталось только купить карту и попрощаться с Жельванто.
За это отвечают две реплики «Карта мне пригодится. По рукам.» и «Уболтал, чёрт говорливый. Вот твои 50 монет.» У обеих поле Скрипт-результат должно быть одинаковым: - Код: Ctrl+A, Ctrl+C
GetCurNpc():SetSpokenCount(2);
AddQuestItem('quest_map_sacred_grove');
TakeQuest('r3m1_LookAtMap');
EndConversation();
Здесь:
Первая функция записывает в счётчик обращений "2", в результате чего условия показа обеих стартовых реплик становятся ложными, и Жельванто больше в баре не появляется.
Вторая функция добавляет игроку купленную карту в список специальных предметов.
Третья — игрок получает задание «Изучить карту». Именно этой функцией игра и выдаёт игроку квест, а на игровом экране появляется сообщение «Вы получили новое задание».
Последняя — заканчивает диалог.
Теперь создаём сам квест «Изучить карту»:
- Спойлер
- Создаём его с помощью всё того же ConversationEditor.
Нажимаем закладку «Квесты», затем «Открыть файл». Сначала загружаем файл data\gamedata\quests.xml. После этого программа попросит загрузить опциональную информацию для квестов. Она находится в data\if\diz\questinfoglobal.xml. Идём в папку r3m1. Щёлкаем ПКМ на папке «опциональные» и выбираем «Добавить папку». Вводим имя «Изучить карту».
Щёлкаем ПКМ на папке «Изучить карту» и выбираем «Добавить квест».
Появляется квест с автоматически созданным именем. Меняем его на - Код: Ctrl+A, Ctrl+C
r3m1_LookAtMap
В поле «OnTake (Если взят)» заносим: - Код: Ctrl+A, Ctrl+C
TActivate('trLookAtMap');
В этом поле указваются Lua-команды, которые выполняются в случае получения квеста. Таким образом, как только игрок получает квест «Изучить карту», так тут же активируется триггер «trLookAtMap».
Ставим галочку в поле «Опциональные параметры квеста», чтобы они стали доступны.
В поле BriefDiz (Краткое описание) заносим: - Код: Ctrl+A, Ctrl+C
Изучить карту
В поле FullDiz (Полное описание) заносим: - Код: Ctrl+A, Ctrl+C
По случаю мне досталась карта земель друидов. Надо внимательно её изучить, может на ней указан путь к Оракулу.
Сохраняемся.
Во время игры, в списке полученных игроком квестов текст из Краткого описания отображается в левой половине окна, а из Полного описания в правом.
Осталось только сделать триггер, который отслеживает выполнение квеста:
- Спойлер
- В data\maps\r3m1\triggers.xml внутрь тега <triggers /> добавляем триггер:
- Код: Ctrl+A, Ctrl+C
<trigger Name="trLookAtMap" active="0">
<event ObjName="Player1" eventid="GE_TUTORIAL_MAP" />
<script>
CompleteQuestIfTaken( 'r3m1_LookAtMap' )
trigger:Deactivate()
</script>
</trigger>
Этот триггер отслеживает, когда игрок (объект с именем "Player1") выберет вкладку «Карта» и глянет карту местности, то есть ждёт наступление события "GE_TUTORIAL_MAP". Как только игрок откроет карту, так триггер сразу срабатывает и выполняются команды внутри тега <script />.
Команда CompleteQuestIfTaken( 'r3m1_LookAtMap' ) завершает квест «Изучить карту», и игра переводит его в разряд выполненных.
Команда trigger:Deactivate() переводит триггер «trLookAtMap» в неактивное состояние. После этого он перестаёт реагировать на просмотр игроком карты местности.
Чтобы квест правильно заработал, нужно совершить первый
набег заезд в Рощу друидов из Либриума или Хеля.