Перейти к основному содержимому

Создание квестов

webapp_banner.jpg

Пример квеста

EliteMobs поставляется с готовым файлом test_quest.yml, который будет разобран здесь как простой образец формата квеста.

Пользовательские квесты находятся в папке ~plugins/EliteMobs/customquests!

test_quest.yml

isEnabled: true
customObjectives:
Objective1:
amount: '1'
filename: test_boss.yml
objectiveType: KILL_CUSTOM
customRewards:
- filename=magmaguys_toothpick.yml:amount=1:chance=1
name: "&aKill the Test Boss"
questLore:
- "&cEnd the test boss'' reign of terror!"

create_quest_quest.jpg

Если интерфейс ваших квестов выглядит иначе, вы можете изменить его, чтобы он соответствовал показанному, с помощью команды /em alt.

Этот пример квеста даст игрокам задание убить 1 test_boss.yml. (Фактическое имя босса, отображаемое в трекере квестов, будет взято из поля name:, заданного в test_boss.yml.) А в награду за выполнение квеста они получат 1 Magmaguy's Toothpick.

Создание пользовательских квестов

isEnabled

Задаёт, включён ли квест.

KeyValuesDefault
isEnabledBooleantrue
Пример
isEnabled: true

customObjectives

Задаёт цели квеста.

KeyValuesDefault
customObjectivesSpecial [1]none

Примечание: если в качестве цели вы используете многофазового босса, то цель должна указывать на первую фазу в качестве объекта.

Примеры

KILL_CUSTOM:

customObjectives:
Objective1:
amount: '1'
filename: my_cool_boss.yml
objectiveType: KILL_CUSTOM

DIALOG:

customObjectives:
Objective1:
dialog:
- "&a[Dialog NPC] &fCome here often?"
- "&7&oI should eat more apples."
filename: dialog_npc.yml
npcName: Dialog NPC
location: at dialog location.
objectiveType: DIALOG

FETCH_ITEM:

customObjectives:
Objective1:
amount: '99'
itemName: Red Apples
filename: my_quest_item_red_apples.yml
objectiveType: FETCH_ITEM

ARENA:

customObjectives:
Objective1:
objectiveType: ARENA
filename: my_arena.yml
name: "Complete the Arena"

create_quest_objective.jpg

Special [1]

Развернуть таблицу

Пользовательские цели создаются с использованием следующих значений:

KeyDescription
objectiveTypeЗадаёт тип цели, который она представляет. Допустимые значения: KILL_CUSTOM, FETCH_ITEM, DIALOG и ARENA. KILL_CUSTOM означает, что квест предполагает убийство определённого пользовательского босса, FETCH_ITEM означает, что квест предполагает получение определённого пользовательского предмета, DIALOG означает, что квест предполагает разговор с NPC, а ARENA означает, что квест предполагает прохождение определённой арены.
filenameЗадаёт имя файла пользовательского босса, пользовательского предмета, которого игрок должен убить / получить, NPC, с которым нужно поговорить, или арены, которую нужно пройти. Обязательно — цель без filename отбрасывается с предупреждением в консоли.
amountЗадаёт количество пользовательских боссов, которых нужно убить, или предметов, которые нужно получить. По умолчанию 1, если не указано. Игнорируется для DIALOG (всегда 1) и ARENA.
dialogТолько для DIALOG — реплики, которые NPC произносит, когда игрок с ним разговаривает.
locationТолько для DIALOG — произвольная текстовая подсказка о том, где находится NPC; показывается как $location в строке-сводке меню квестов.
name / npcName / itemNameТри взаимозаменяемых имени для одного и того же поля: отображаемое имя цели в трекере квестов и меню. Только для визуального отображения — используйте то, что лучше читается для данного типа цели. Для FETCH_ITEM его отсутствие приводит к откату на name, заданное в файле пользовательского предмета.

Каждая цель находится под собственным ключом внутри customObjectives (Objective1, Objective2, ...), а её поля — это обычные ключи YAML. Более старые файлы квестов, использовавшие однострочный строковый формат KILL_CUSTOM:filename=X.yml:amount=Y, автоматически преобразуются в эту раскладку при первой загрузке и сохраняются обратно на диск.

Поведение FETCH_ITEM

Прогресс FETCH_ITEM пересчитывается по инвентарю игрока всякий раз, когда он поднимает или выбрасывает предмет, при принятии квеста и при попытке его сдать — поэтому предметы, полученные до принятия квеста, тоже засчитываются. При сдаче игрок всё ещё должен держать требуемое количество: если нет, сдача отменяется. При успешной сдаче предметы квеста изымаются из инвентаря игрока.


customRewards

Задаёт награды за квест.

KeyValuesDefault
customRewardsУниверсальный формат лута EliteMobsnone
Пример
customRewards:
- currencyAmount=50:amount=1:chance=0.05
- material=COOKED_COD:amount=3:chance=1.0
- filename=magmaguys_toothpick.yml:amount=1:chance=1.0

create_quest_rewards.jpg

Примечание: пользовательские квесты не генерируют награды автоматически. Если вы оставите customRewards пустым, квест ничего не даст при завершении, поэтому всегда определяйте награды явно. (Автоматические награды, масштабируемые по уровню — валюта и предметы на основе сложности квеста, — применяются только к процедурно генерируемым Динамическим квестам, а не к пользовательским квестам, заданным в конфиге.)

Награды за квест выдаются напрямую: предметы попадают сразу в инвентарь игрока (всё, что не помещается, выбрасывается ему под ноги), а валюта добавляется к его балансу. Чтобы выполнять команды при завершении, используйте questCompleteCommands, а не запись лута command=.


questAcceptPermission

Задаёт право (permission), которое должно быть у игрока, чтобы он мог принять квест.

KeyValuesDefault
questAcceptPermissionStringnone
Пример
questAcceptPermission: elitequest.my_permission

questAcceptPermissions

Задаёт права (permissions), которые должны быть у игрока, чтобы он мог принять квест.

KeyValuesDefault
questAcceptPermissionsString Listnone
Пример
questAcceptPermissions: 
- elitequest.my_previous_quest_one.yml
- elitequest.my_previous_quest_two.yml

questLockoutPermission

Задаёт право (permission), которое игрок получит после завершения квеста и которое заблокирует ему повторное выполнение квеста. Если не указано, право блокировки не назначается, и квест остаётся доступным.

KeyValuesDefault
questLockoutPermissionStringnone
Пример
questLockoutPermission: elitequest.my_quest.yml

questLockoutMinutes

Задаёт, сколько минут игроку придётся ждать, прежде чем он сможет выполнить квест снова.

KeyValuesDefault
questLockoutMinutesInteger-1(квест никогда не повторяется)

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

  • Любое значение выше 0 использует трекер блокировки по времени. Игрок заблокирован для этого квеста на указанное число минут после его сдачи, ему сообщается, сколько осталось, когда он пытается взять квест снова, а questLockoutPermission игнорируется при проверке доступности.
  • 0 или меньше откатывается на устаревший маркер questLockoutPermission, который выдаётся навсегда при завершении. Если questLockoutPermission тоже не задан, квест остаётся повторяемым.
Пример
questLockoutMinutes: 60

name

Задаёт имя квеста. Принимает цветовые коды.

KeyValuesDefault
nameStringnone
Пример
name: "&aMy Great Quest Name"

questLore

Задаёт описание (lore) квеста, которое будет отображаться во внутриигровом меню квестов.

KeyValuesDefault
questLoreString Listnone
Пример
questLore:
- "Interesting lore sentence."
- "Yet another interesting lore sentence."

create_quest_lore.jpg


temporaryPermissions

Задаёт права, которые назначаются игроку до тех пор, пока он не сдаст квест.

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

KeyValuesDefault
temporaryPermissionsString Listnone
Пример
temporaryPermissions:
- elitequest.item_that_should_drop_only_during_quest.yml

questAcceptDialog

Задаёт реплики, которые появляются в чате при принятии квеста.

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

KeyValuesDefault
questAcceptDialogString Listnone
Пример
questAcceptDialog:
- "My hero! You are so helpful!"
- "I wish you the best of luck!"

create_quest_accept.jpg


questCompleteMessage

Задаёт реплики, показываемые при сдаче квеста. Если включены боссбары диалогов квестов (useQuestDialogueBossBars в QuestsConfig), они отрисовываются в диалоговом окне; иначе отправляются в чат. Игроки Bedrock всегда получают версию для чата.

KeyValuesDefault
questCompleteMessageString Listnone
Пример
questCompleteMessage:
- "My hero! You have completed my difficult quest!"
- "As a reward you can have this loaf of bread!"

create_quest_complete.jpg


questCompleteCommands

Задаёт команды, которые будут выполнены при завершении квеста. Команды отправляются из консоли, поэтому не включайте ведущий слеш и не рассчитывайте на наличие у игрока прав на них.

Поддерживаемые плейсхолдеры: $player для имени игрока, $getWorld для имени мира, в котором он находится, и $getX, $getY, $getZ для координат его местоположения.

KeyValuesDefault
questCompleteCommandsString Listnone
Пример
questCompleteCommands:
- say $player has finished a quest at $getX, $getY, $getZ!
- give $player diamond 1

create_quest_commands.jpg


turnInNPC

Задаёт имя файла NPC, с которым игрокам нужно поговорить/взаимодействовать, чтобы завершить квест. Это не обязательно тот же NPC, который выдал квест.

KeyValuesDefault
turnInNPCFilenamenone
Пример
turnInNPC: my_cool_quest_npc.yml

Выдача квестов

Чтобы назначить квест NPC, который будет выдавать его игрокам, нужно настроить файл NPC, а не файл квеста.

В конфигурационном файле вашего NPC (~/plugins/EliteMobs/npcs/) добавьте:

interactionType: CUSTOM_QUEST_GIVER
questFileName: my_quest.yml

Для NPC, которые выдают несколько квестов:

interactionType: CUSTOM_QUEST_GIVER
questFileName:
- quest_one.yml
- quest_two.yml

interactionType: CUSTOM_QUEST_GIVER обязателен — без него NPC полностью игнорирует questFileName.

Подробнее о настройке NPC см. документацию по созданию NPC.


trackable

Задаёт, будет ли квест использовать трекер квестов.

KeyValuesDefault
trackableBooleantrue
Пример
trackable: true

questLevel

Задаёт уровень квеста. Это всего лишь визуальный ориентир, чтобы игроки могли понять, насколько сложным будет квест. Это никак не изменяет уровни босса, предметов или другие уровни.

KeyValuesDefault
questLevelInteger0
Пример
questLevel: 10

create_quest_level.jpg


questAcceptSound

Задаёт звук, который воспроизводится при принятии квеста. Можно воспроизводить как звуки Minecraft, так и звуки из ресурс-пака. Когда он не задан, EliteMobs вместо него проигрывает глобальный звук принятия квеста из SoundsConfig.

KeyValuesDefault
questAcceptSoundStringnone
Пример
questAcceptSound: entity.experience_orb.pickup

create_quest_level.jpg


questCompleteSound

Задаёт звук, который воспроизводится при завершении квеста (его сдаче). Можно воспроизводить как звуки Minecraft, так и звуки из ресурс-пака. Когда он не задан, EliteMobs вместо него проигрывает глобальный звук завершения квеста из SoundsConfig.

KeyValuesDefault
questCompleteSoundStringnone
Пример
questCompleteSound: entity.player.levelup

create_quest_level.jpg


Поддержка локализации

Следующие поля поддерживают локализацию для многоязычных серверов:

  • name
  • questLore
  • questAcceptDialog
  • questCompleteMessage
  • Внутри каждой записи customObjectives: dialog, npcName и location

Это позволяет вам предоставлять переводы для разных языков на вашем сервере.


Разрешения

Как упоминалось в таблицах выше, права обычно представляют собой Strings или String Lists. Но давайте рассмотрим подробнее, как вы будете использовать их для блокировки и разблокировки квестов.

Важно: questAcceptPermission и questAcceptPermissions не являются узлами плагина прав. EliteMobs проверяет собственные внутренние маркеры квестов, которые игрок получает только за завершение квеста, чей questLockoutPermission совпадает. Выдача той же строки через LuckPerms или любой другой плагин прав не разблокирует квест. (temporaryPermissions — другое дело: они привязываются как настоящие узлы прав на всё время, пока квест активен, поэтому с ними работает ограничение предметов через permission.)

Допустим, вы создаёте quest_3 в запланированной серии квестов и не хотите, чтобы игроки могли взять quest_3 до того, как они завершат quest_2. Мы настроили бы файл квеста так:

questAcceptPermission: elitequest.quest_2.yml
questLockoutPermission: elitequest.quest_3.yml

Установив questAcceptPermissions в значение elitequest.quest_2.yml, мы теперь не позволяем игрокам брать quest_3.yml до того, как они завершат quest_2.yml.
Установив questLockoutPermission в значение elitequest.quest_3.yml, мы запретили игрокам получать этот квест, пока он уже есть у них в трекере или если они уже его завершили. Это не позволяет игрокам повторять квест.

Если вы хотите сделать квест, который становится доступен только после того, как игроки завершат серию квестов, то вы настроили бы файл квеста так:

questAcceptPermissions: 
- elitequest.quest_2.yml
- elitequest.quest_3.yml
- elitequest.quest_4.yml

Если вы хотите, чтобы игроки могли получать определённые предметы только при наличии нужного активного квеста, то мы можем сделать это с помощью temporaryPermissions. Мы создадим право в файле квеста с помощью temporaryPermissions, а затем создадим соответствующее право в файле предмета с помощью permission.

Например, мы откроем наш файл квеста и добавим следующее:

temporaryPermissions: 
- elitequest.my_cool_item.yml

Затем мы откроем файл предмета, в нашем случае my_cool_item.yml, и добавим следующее:

permission: elitequest.my_cool_item.yml

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

Динамические квесты

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

Как они работают

  • Уровень (тир) квеста: тир динамического квеста игрока определяется на основе его боевого уровня: tier = combatLevel / 5, ограничено диапазоном от 1 до 20. Например, игрок с боевым уровнем 45 получит динамические квесты 9-го тира. Сами квесты (и их награды) масштабируются под фактический боевой уровень игрока, который ограничен диапазоном от 1 до 100.
  • 3 квеста на тир: для каждого из 20 тиров квестов система генерирует ровно 3 случайные цели квестов за раз. Игрокам предлагаются 3 квеста, соответствующие их текущему тиру.
  • Цикл автообновления: пул целей динамических квестов перегенерируется каждые 60 секунд (каждые 1200 тиков). При обновлении пула новые цели заменяют старые, давая игрокам сменяющийся набор заданий.
  • Адаптация к динамическим подземельям: когда игрок входит в динамическое подземелье с определённым выбором уровня, все его активные динамические квесты адаптируются под уровень мобов подземелья. Уровень квеста, цели и отображаемое имя обновляются соответствующим образом, чтобы квесты оставались актуальными для содержимого подземелья.

Группы и общий зачёт убийств

Задания всегда остаются личными, но после зачёта убийства участнику другие участники онлайн в том же мире и в пределах sharedProgressRange (по умолчанию 128 блоков в Party.yml) получают прогресс совпадающих активных целей на убийство. Предметы сбора, диалоги NPC и цели арен не разделяются; игроки в несвязанном активном инстансе исключены. См. систему групп.