import { RawMessage, Player } from "@minecraft/server"; import { ActionFormData, MessageFormData } from "@minecraft/server-ui"; import { DisplayCondition } from "lazuli-common"; /** * Create an article. * @category Need Registry */ export class Article { constructor( /** * Id of the article. */ public readonly id: string, /** * Title of the article. */ public title: string | RawMessage, /** * Body of the article, support RawMessage. */ public body: string | RawMessage, /** * Icon path of the article. */ public iconPath?: string, /** * If true, articles will be unlocked in the {@link ArticleCollection} after reading it. */ public needUnlock = true ) {} /** * Display the reading to a player. */ display(player: Player): void { if (!this.checkUnlock(player)) this.unlock(player); const FORM = new ActionFormData() .title(this.title) .body(this.body) .button({ translate: "gui.ok" }); FORM.show(player); } /** * Registry the prop. * @deprecated Use `Register.articleRegistry()` to registry the prop */ protected register() { console.warn("[Lazuli] The register method was deprecated!"); } /** * Unlock the article to article collection. * @param player */ unlock(player: Player) { player.addTag(`articleUnlock:${this.id}`); } /** * Check the article whether it is unlocked or not to article collection. * @param player */ checkUnlock(player: Player) { if (!this.needUnlock) { return true; } else { return player.hasTag(`articleUnlock:${this.id}`); } } } /** * Create an article with chapters. * @category Need Registry */ export class ChapterArticle extends Article { constructor( /** * Id of the article. */ public readonly id: string, /** * Title of the article. */ public title: string | RawMessage, /** * Body of the article, support RawMessage. */ public body: string | RawMessage, /** * Chapters of the article. */ public chapters: ChapterData[], /** * Icon path of the article. */ public iconPath?: string, /** * If true, articles will be unlocked in the {@link ArticleCollection} after reading it. */ public needUnlock = true ) { super(id, title, body, iconPath, needUnlock); } /** * Display the reading to a player. */ display(player: Player): void { if (!this.checkUnlock(player)) this.unlock(player); const FORM = new ActionFormData().title(this.title).body(this.body); this.chapters.forEach((chapter) => { FORM.button(chapter.title, chapter.iconPath); }); FORM.show(player).then((response) => { if (response.canceled || response.selection === undefined) { return; } const CHAPTER_FORM = new ActionFormData() .title(this.chapters[response.selection].title) .body(this.chapters[response.selection].body) .button({ translate: "gui.ok" }); CHAPTER_FORM.show(player); }); } } /** * Create an article collection. * It likes {@link ChapterArticle}, but support article unlock. * @category Need Registry */ export class ArticleCollection { constructor( /** * Id of the collection. */ public readonly id: string, /** * Title of the collection. */ public title: string | RawMessage, /** * Body of the collection. */ public body: string | RawMessage, /** * Control when collection is displayed. */ public displayCondition: DisplayCondition, /** * Articles in the collection. */ public articles: (Article | ChapterArticle)[] ) {} /** * Display the reading to a player. */ display(player: Player): void { let articleList: (Article | ChapterArticle)[] = []; const MAIN_FORM = new ActionFormData().title(this.title).body(this.body); this.articles.forEach((article) => { if (article.checkUnlock(player)) { MAIN_FORM.button(article.title, article.iconPath); articleList.push(article); } }); if (articleList.length === 0) { const WARNING_FORM = new MessageFormData() .title({ translate: "article.nothing.title" }) .body({ translate: "article.nothing.body" }) .button1({ translate: "gui.ok" }) .button2({ translate: "gui.close" }); WARNING_FORM.show(player); } else { MAIN_FORM.show(player).then((response) => { if (response.canceled || response.selection === undefined) { return; } articleList[response.selection].display(player); }); } } /** * Registry the prop. * @deprecated Use `Register.articleRegistry()` to registry the prop */ protected register() { console.warn("[Lazuli] The register method was deprecated!"); } } /** * Data of chapters. */ export interface ChapterData { /** * Title of the chapter. */ title: string | RawMessage; /** * Body of the Chapter. */ body: string | RawMessage; /** * Icon path of the chapter. */ iconPath?: string; }