Система создания квестов (Quests API)
Назначение системы: Создание единого интерфейса взаимодействия игроков с квестами в игре. Создание единой базы квестов, которую можно использовать в том числе на справочном сайте по всем квестам, предметам и тп. Возможность создания некой рейтинговой системы вида "2е место - Линдир 400/700 квестов". Упрощение создания общеупотребительных квестов до минимального конфига на языке yaml. Создание фреймворка на базе которого можно строить квесты произвольной сложности и логики с помощью скриптового языка типа dg scripts.
Особенности
* - помечены пункты исключенные из первой версии
Формат квеста
Необязательные блоки и поля отмечены курсивом. Обязательные жирным цветом (если секция куда вложены параметры не отмечена жирным, то отмеченные жирным параметры обязательны в пределах этой секции, т.е если она указана). Варианты значений отделены знаком ‘|’. Знаком # - помечены комменты. Подчеркнуты значения по умолчанию.
- vnum: номер квеста (vnum)
*extends: номер базового квеста
level: уровень квеста
title: название квеста
description: Описание квеста. Предистория, что нужно сделать, где.
type: Соло|Группа|Рейд
period: Одноразовый|РазВДень|ПоМереСбора|РазВРесетЗоны
begin_mob_vnum: vnum моба который выдает квест
end_mob_vnum: vnum моба который принимает квест
sharable: 1|0
events:
greeting:
speech: [line1, line2, ..., lineN]
offer:
type: Соло|Группа
quest: номер квеста|Этот|Следующий
ask: Спрашивать|НеСпрашивать
progress: аналогично
completion: аналогично
start: аналогично
timeout: время в секундах на выполнение квеста
prerequisites:
quests: [quest1, quest2, ..., questN]
classes: [class1, class2, ...,classN]
align: [СВЕТ, ТЬМА]
provided:
- vnum: номер предмета1
- vnum: номер предмета2
#...
automate:
death:
- obj_vnum: номер предмета
mob_vnum: номер моба
percent: <процент загрузки>|100
loot: Случайному|Всем
#...
objectives:
type: УбитьМоба|ПринестиКвестПредметы|ПринестиЛюбойИлиВсеПредметы| ОтнестиПредмет|Ручной|Фраза|Поговорить
tasks:
# блоки далее зависят от objectives.type
# УбитьМоба
- vnum: номер моба которого надо убить
count: сколько убить|1
#...
# ПринестиКвестПредметы, ПринестиЛюбойИлиВсеПредметы
- vnum: номер предмета
corpse_mob_vnum: номер моба из которого труп (vnum должно быть -1)
count: кол-во предметов|1
#...
# ОтнестиПредмет - без параметров
# Ручной - objectives задаются описательно. Автоматической проверки на выполнение не проиходит.
# Нужно для реализации произвольной логики выполнения квеста в триггерах.
- name: objective1 (Название задачи для ссылки в триггерах)
description: Описание задачи, отображается в блоке Задачи информации о квесте
#...
# Фраза
- phrase: строка|regexp
# ...
# Поговорить – без параметров
reward:
money: кол-во денег|Авто
exp: кол-во экспы|Авто
slava: кол-во славы|Авто
maxing:
money: число до макса|5 + уровень
slava: число до макса|5 + уровень
exp: число до макса|5 + уровень
items:
type: ОдинИз|Случайный|Все
# ОдинИз, Все
items:
- vnum: номер предмета в награду
#...
# Случайный
percent: процент получения вообще предмета|100
items:
- vnum: номер предмета в награду
#...
Описание полей и блоков квеста
vnum
обязательное
Уникальный номер квеста. Обычно формируется как номер_зоны + порядковый номер.
Используется в частности для создания цепочек квестов.
extends
Конструкция для наследования квеста. Чтобы в серии похожих квестов не надо было каждый раз указывать повторяющиеся поля, а только переопределить нужные.
Номер может быть только один и квест должен быть загружен ДО наследования.
level
обязательное
Уровень квеста. Взять квест можно на уровне (level-3). Также определяет цвет квеста:
красный: текущий левел меньше уровня квеста более чем на 4 (оч. высокая сложность)
желтый: текущий левел -3..+3 от уровня квеста (нормальная сложность)
зеленый: текущий левел +4..+10 от уровня квеста (легкий)
серый: текущий левел +11 и выше от уровня квеста (элементарный)
От уровня также зависит кол-во награды в виде монет и экспы если не задано вручную.
Также: зеленые и серые квесты не предлагаются игрокам по событиям и секции offer.
title
обязательное
Название квеста. Длина не более 5-8 слов.
description
обязательное
Описание квеста. Здесь можно описать предисторию, зачем дали этот квест и почему выбрали именно тебя. В общих чертах описать где выполнять этот квест (для лоу квестов с точными данными) и куда идти сдавать.
type
Тип квеста. Значение одно из: Соло|Группа|*Рейд (по умолчанию Соло)
От типа квеста зависит пока только автоматический расчет награды.
period
Переодичность выполнения квеста. Значения: Одноразовый|РазВДень|ПоМереСбора|РазВРесетЗоны (по умолчанию Одноразовый)
Одноразовый - выполнить можно единожды за жизнь персонажа
РазВДень - Периодический. Выполнять можно раз в день (время с выполнения предыдущего должно быть больше 24 часов). Одновременно можно делать не более 1 периодического квеста у одного квестодателя (если есть квест за предыдущий день, нельзя взять новые, нужно отменить старый)
ПоМереСбора - Периодический. В objectives надо указавать, что надо приносить, чтобы получить награду. Для реализации квестов типа “За каждые 10 трупов бабочек я дам тебе 1 монету”.
РазВРесетЗоны - Периодический. Квест автоматически фейлится если ресетится зона. Квест данного типа взять можно только 1 квест на зону. При взятии кем-то, всем в группе предлагается этот квест если sharable=1 и type = Группа (процедура автопредложения квеста в соотвествующем разделе). Квест такого типа не сохраняется в ренте.
begin_mob_vnum
vnum моба который выдает данный квест. Если вы указываете greeting и прочие события, то убедитесь, что квест выдает тот, кто может говорить :)
Если это поле не указано, то квест никем не выдается. *Выдавать его можно с помощью, например, триггеров.
end_mob_vnum
vnum моба принимающего выполнение квеста. Если это поле не указано, то считается равным begin_mob_vnum. *В случае если не указано ни end ни begin, квест заканчивать надо триггерно.
sharable
Значение: 0|1
Можно ли расшарить данный квест согрупнику (если он соотвествует требованиям)
По умолчанию 1
events
Блок с событиями и *callback функциями (пока не реализовано). Используется для интерактивного привествия квестодателем, реакции на некоторые события. Описание событий:
timeout
Значение число больше 0. Собственно время в течение которого необходимо выполнить квест. Если не успеть, квест будет автоматически провален. Время задается в секундах, но работает как абсолютное смещение. Т.е зайдя на ренту и выйдя на следующий день квест будет автоматически профейлен. В описании квеста пишется сколько времени будет на выполнение или сколько осталось если квест взят.
prerequisites
Требования для взятия этого квеста. Чтобы взять квест, нужно удовлетворять всем требованиям плюс требованию по уровню (см level)
provided
Список предметов, которые даются игроку вместе с взятием этого квеста. Например, письмо, ключ и тп. Для квестов отличных от РазВРесетЗоны нельзя делать в качестве предметов предметы удаляемые с ресетом зоны и не рентящиеся.
automate
Секция автоматизации стандартных действий в квестах.
objectives
обязательное
Задачи квеста. Что необходимо сделать, чтобы квест автоматически выполнился и его можно было сдать.
reward
Секция награды за выполнение квеста. Награда дается _каждому_, кто выполнил и сдал этот квест. Если нужно дать, например, одну буку на всю группу это делается через триггер типа QuestEvent на событие completion.
money: кол-во монет|Авто, 0 – не выдаются деньги. Авто – автоматический расчет.
exp: кол-во экспы|Авто, 0 – не дается экспа. Авто – автоматический расчет.
slava: кол-во славы|Авто. 0 - не дается слава. Авто – автоматический расчет.
Значения по умолчанию зависят от периодичности квеста:
maxing – Секция конфигурирования параметров замакса награды в квесте
items - Если этот блок указан, то за выполнение квеста полагается предмет или несколько предметов.
Триггерное API
К char/mob добавляется набор новых функций:
Флаг: q
Тип триггера: монстр
Описание: Триггер этого типа вызывается у моба выдающего квест или у моба принимающего квест, когда срабатывает событие квеста. Т.е аттачить триггер к другим мобам смысла нет.
Аргумент: Не используется
Числовой аргумент: Шанс, что триггер будет запущен (0-100)
Возвращаемое значение: Не используется
Переменные:
quest_vnum – номер квеста
event - тип события (одно из events)
self – моб выдающий или принимающий задание
actor - персонаж который вызвал событие квеста
Советы для билдеров
Некоторые пока общие советы по созданию квестов.
Все новые квесты ДОЛЖНЫ проходить через новую систему. По возможности также необходимо переделывать старые квесты, чтобы они были под контролем этой системы.
Квесты должны быть по большей части локальные, т.е находится недалеко от места их выполнения, к примеру:
Квесты должны быть на 90% одноразовыми и состоять из нескольких шагов. На последнем шаге выдавать награду получше: вещи
По возможности все квесты “РазВДень” должны открываться цепочками одноразовых.
Общие советы
1. Большой квест в зоне необходимо разбивать на несколько мелких частей, каждая из которых выполняет задачи одного типа
2. уровень квеста задается как уровень самого старшего моба в квесте минус 2
3. тип=группа ставится на квесты если в них надо убить босса и где в одиночку даже зеленый квест не сделать (большие гопы мобов и тп). В частности все зоны для 30х являются групповыми.
4. Один моб-квестодатель дает одновременно только один периодический квест игроку. Т.е у одного моба можно только по очереди делать повторяемые квесты.
5. Один моб-квестодатель не должен одновременно давать более 3-4х квестов
Примеры
Это не совсем рабочие примеры, многие параметры проставлены пока от фонаря.
Рабочие примеры можно посмотреть в файле 040.quest в серверной версии для билдеров.
0. Минимальный квест
Убить бабочку на дереве. Моб 2105 не выдает никаких привествий. При сдаче квеста получаем немного денег и экспы.
- vnum: 2100
begin_mob_vnum: 2105
level: 3
title: "Убить бабочку на дереве"
description:
"На дереве живет большая бабочка, которая прилетает на грядки с капустой
и откладывает яйца из которых потом появляются гусеницы и
едят мою капусту.\n\n
Иди и убей эту бабочку.
Найти ее можно на севере от площади, в ветвях дерева."
objectives:
type: УбитьМоба
tasks:
- vnum: 2106
1. мальчик на дереве
Реализация квеста по новой системе (без триггеров) с некоторой модификацией логики. За первый сданный квест дается большая награда:
- vnum: 2100
begin_mob_vnum: 2109
level: 4
title: "Очищение дерева от насекомых"
period: Одноразовый
events:
greeting:
speech:
- Привет, $n!
Отец велел мне перебить этих противных насекомых!
Он обещал мне по 2 монеты за каждого! Но я сломал свою рогатку...
ВО! ЗНАЧИТ ТАК!
Ты мне приносишь труп жучка, червяка или паучка
А я даю тебе 1 монету за каждого! По рукам?!
- Как брать и сдавать задание - СПРАВКА ЗАДАНИЕ
progress:
speech:
- |
Но ты еще не убил$k нужного количества!
Иди и поторопись!
completion:
speech: ["Спасибо! Ты мне сильно помог$y! Можешь теперь приносить мне любое кол-во трупов этих насекомых и я будут тебе давать 1 монету за каждого!"]
description: |
Мальчик на дереве дает 1 монету за каждый труп жучка, червяка или паучка.
objectives:
type: ПринестиКвестПредметы
tasks:
- vnum: -1
corpse_mob_vnum: 2108
- vnum: -1
corpse_mob_vnum: 2109
- vnum: -1
corpse_mob_vnum: 2110
reward:
money: 15
- vnum: 2101
begin_mob_vnum: 2109
level: 5
period: ПоМереСбора
title: "Очищение дерева от насекомых"
description: "Мальчик на дереве дает 1 монету за каждый труп жучка, червяка или паучка."
prerequsites:
quests: [2100]
objectives:
type: ПринестиЛюбойИлиВсеПредметы
tasks:
- vnum: -1
corpse_mob_vnum: 2108
- vnum: -1
corpse_mob_vnum: 2109
- vnum: -1
corpse_mob_vnum: 2110
reward:
money: 1
Как работает:
- В комнату с мальчиком заходит или телепортируется игрок
- Если игрок не делал квеста 2100, то перед мальчиком горит желтый восклицательный знак и мальчик выдает привествие (greeting event)
- мальчик перестает что либо брать себе в инвентарь
- если игрок соглашается на квест, то пишет “взять или получить” и получает задание:
Ваш журнал заданий обновлен: Новое задание “Очищение дерева от насекомых”
- задания список:
#2100 “Очищение дерева от насекомых”
- задания инф 2100
Задание: Очищение дерева от насекомых
Описание: ...
Задачи:
1. Принести 1 труп жучка
2. Принести 1 труп паучка
3. Принести 1 труп червяка
Награда:
15 монет
- Идем убиваем мобов, собираем нужные трупы. После сбора необходимого числа трупов появляются надпись:
Журнал задний обновлен: Задание “Очищение дерева” выполнено
задания список
#2100 “Очищение дерева от насекомых” (Выполнен)
задания инф 2100
Задание: Очищение дерева от насекомых
Описание: ...
Задачи:
1. Принести 1 труп жучка (выполнено)
2. Принести 1 труп паучка (выполнено)
3. Принести 1 труп червяка (выполнено)
Награда:
15 монет
- Идем к мальчику. У мальчика перед именем появляется желтый знак вопроса. Пишем “сдать”. Мальчик говорит:
Спасибо! Ты мне сильно помог$y! Можешь теперь приносить мне любое кол-во трупов этих насекомых и я будут тебе давать 1 монету за каждого!
- Собираем трупы, приносим, пишем сдать, получаем награду. Взять квест с типом “ПоМереСбора” нельзя.
2. Вы должны найти и убить Драконицу молнию
Все автоквесты конвертируются в список, типа такого (без триггеров):
- vnum: 3001
type: Группа
level: 30
begin_mob_vnum: <квестер_мт_vnum>
period: РазВДень
title: "Убить драконицу Молнию"
description: |
Огненно-красная драконица начала совершать
нападения на наши стада. Она безжалостно убила
пастухов, защищающих стада. Надо убить драконицу прежде,
чем она обречет нас на голодную зиму."
objectives:
type: УбитьМоба
tasks:
- vnum: 21013
reward:
slava: Авто
Как работает:
- Приходим к автоквестеру. У него горит синий [!]
- пишем “список”. Получаем список заданий которые можно взять.
- берем задание, например, получить 7855 или получить убить драконицу молнию
Журнал заданий обновлен: Новое задание “Убить драконицу молнию”.
- Выполнять его можно любое кол-во времени, но не чаще раза в день. Т.е после выполнения, этот квест нельзя взять в течение дня.
- Убиваем драконицу.
Журнал заданий обновлен: Задание “Убить драконицу молнию” выполнено.
- Идем к автоквестеру. Перед ним горит синий знак [?]
- пишем доложить, получаем награду.
3. сова
убиваешь сову, с нее выпадает камушек
несеш камушек старику
он дает 100 монет
Реализация по новой системе (без триггеров):
- vnum: <vnum квеста>
end_mob_vnum: <vnum_старика>
level: 5
period: ПоМереСбора
title: "Необычный камушек"
description: "Вы нашли необычный камушек? Отдайте его знающему старику, может быть его это заинтересует."
events:
completion:
speech: ["Благодарю тебя $N! Это весьма интеерсный камушек, вот держи награду."]
objectives:
type: ПринестиЛюбойИлиВсеПредметы
tasks:
- vnum: <номер камушка>
reward:
money: 100
exp: 0
Как работает:
- выбиваем из совы камушек
- идем к старику, перед ним горит синий знак [?] (если камушка нет, горит серый знак вопроса)
- пишем сдать
Старик сказал: “Благодарю тебя Линдир! Это весьма интеерсный камушек, вот держи награду.”
Вы получили 100 монет.
- у старика перед именем теперь горит серый знак вопроса
- если набрать список
#vnum “Необычный камушек”
- информация #vnum
Задание: Необычный камушек
Описание: Вы нашли необычный камушек? Отдайте его знающему старику, может быть его это заинтересует.
Награда: 100 монет, 0 опыта