クエスト
server.questパッケージ内にQuestクラスを継承したクラスを作成することで登録できます。
細かい実装の具合はQuestGiveMeMeatや各種KDocを参照してください
作成
メインクエストであればquest.define.mainパッケージ内に、サブであればquest.define.subパッケージ内に作成して下さい。
class ExampleQuest: Quest(override val questId: VQuestId) : Quest(emptyList()/* 報酬リスト */) {
/* quest.sub.example_quest.start_section.description にてセクションの説明を設定できます */
val startSection = section(
"start_section",
listOf(ObjectiveLocation(WorldType.TERRESTRIAL, Vec3d.ZERO))
) {
QuestTrigger.None { // トリガーなし->手動で発動させないといけない
{ player ->
/* sectionTranslationKey == このセクションのi18nキー(quest.sub.example_quest.start_section) */
SimpleConversation(sectionTranslationKey, player) { // 会話の設定
onFinished = {
secondSection.markAchieved(player) // 会話終了時に次のセクションを開始
}
Chat(sectionTranslationKey)
}
}
}
}
val secondSection = section(
"second_section",
listOf(ObjectiveLocation(WorldType.TERRESTRIAL, Vec3d.ZERO)),
) {
LEntityTypes.NPC_ENTITY_TYPE { // it: EntityType<*> インタラクト可能なNPCがトリガーになる
{ player ->
if (player.inventory.count(LItems.REQUIRED_ITEM) >= 10)
SimpleConversation(I18n.entity(it)/* 会話のタイトルをNPC_ENTITY_TYPEの名前にする */, player) {
onFinished = {
endSection.markAchieved(player)
}
Chat(sectionTranslationKey)
}
} else {
SimpleConversation(I18n.entity(it), player) {
// quest.sub.example_quest.second_section.not_enougthが会話キーとなる
Chat(sectionTranslationKey("not_enougth"))
}
}
}
}
}
val endSection = endSection("end_section", emptyList())
}
class Quests<R : UsesQuestRegistry>(injects: R) {
...
val EXAMPLE_QUEST = injects.questRegistry.sub("example_quest", ::ExampleQuest)
}
section(ID, 目的地, セクション中のトリガー): 始め及び中間の進捗を表します。endSection(ID, 追加報酬, セクション中のトリガー(optional)): クエストが完了したことを表します。
注意事項
- 実際のセクションの流れと、セクションの親子関係関係が異なることのないようにしてください。
- セクションが分岐した場合、親子関係の都合上後のセクションで合流させることはできません。