From 0a5549887025a5ff8d39206c274d3a513577058f Mon Sep 17 00:00:00 2001 From: Black Ram <67595890+BlackRam-oss@users.noreply.github.com> Date: Thu, 27 Jun 2024 22:37:56 +0200 Subject: [PATCH] OnStartEndStageQuest --- package-lock.json | 8 +- package.json | 4 +- src/classes/quest/Quest.ts | 572 +++++++++++++++--------------- src/classes/quest/Stage.ts | 16 +- src/functions/QuestFunctions.ts | 4 +- src/interface/quest/QuestProps.ts | 6 +- src/interface/quest/StageProps.ts | 6 +- 7 files changed, 305 insertions(+), 311 deletions(-) diff --git a/package-lock.json b/package-lock.json index 527e1a8..e01e810 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "0.2.7", "license": "GPL-3.0", "devDependencies": { - "@drincs/nqtr": "^0.2.6", + "@drincs/nqtr": "^0.2.7", "@types/react": "^18.3.3", "ts-node": "^10.9.2", "tsup": "^8.1.0", @@ -33,9 +33,9 @@ } }, "node_modules/@drincs/nqtr": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/@drincs/nqtr/-/nqtr-0.2.6.tgz", - "integrity": "sha512-iE4bbq5LYxBz4k6bZRezBK+Vhg8ZAUBQCy69JyGV6oAEPvuRJDa+u7kJ4TChLNFdzFe7fMwAIpPd/6aplDZeGg==", + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/@drincs/nqtr/-/nqtr-0.2.7.tgz", + "integrity": "sha512-AyrnW33A5YNOEFE3iLoTYV7saHJH1IB7GMWiNsQkZnksW5OeRhyTYpZZLXLbZPK65PNoSdiJR7MNFaQjvPioFw==", "dev": true, "peerDependencies": { "@drincs/pixi-vn": ">=0.3.0" diff --git a/package.json b/package.json index 89e5902..35bcc6f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@drincs/nqtr", - "version": "0.2.7", + "version": "0.2.8", "description": "A complete system introducing the concepts of location, time and event, producing the framework of a not-quite-point-and-click adventure game.", "main": "./dist/index.js", "module": "./dist/index.mjs", @@ -23,7 +23,7 @@ }, "homepage": "https://github.com/DRincs-Productions/nqtr-pixi-vn#readme", "devDependencies": { - "@drincs/nqtr": "^0.2.6", + "@drincs/nqtr": "^0.2.7", "@types/react": "^18.3.3", "ts-node": "^10.9.2", "tsup": "^8.1.0", diff --git a/src/classes/quest/Quest.ts b/src/classes/quest/Quest.ts index 9ef0ee6..70e1918 100644 --- a/src/classes/quest/Quest.ts +++ b/src/classes/quest/Quest.ts @@ -1,289 +1,283 @@ -import { GraphicItemType, OnEndStageQuest, OnRenderGraphicItemProps, OnStartStageQuest } from "@drincs/nqtr/dist/override"; -import { StoredClassModel } from "@drincs/pixi-vn"; -import { QuestProps } from "../../interface"; -import Stage, { StageQuest } from "./Stage"; - -const QUEST_CATEGORY = "__nqtr-quest__" - -export default class Quest extends StoredClassModel { - constructor(id: string, stages: Stage[], props: QuestProps) { - super(QUEST_CATEGORY, id) - this._stages = stages - this._name = props.name || "" - this._description = props.description || "" - this._renderIcon = props.renderIcon - this._renderImage = props.renderImage - this._isInDevelopment = props.isInDevelopment || false - this._onStart = props.onStart - this._onNextStage = props.onNextStage - } - - private _stages: Stage[] - /** - * The stages of the quest. - */ - get stages(): StageQuest[] { - return this._stages.map((stage, index) => { - return new StageQuest(stage.id, stage) - }) - } - - private _name: string - /** - * The name of the quest. - */ - get name(): string { - return this._name - } - - private _description: string - /** - * The description of the quest. - */ - get description(): string { - return this._description - } - - private _renderIcon?: GraphicItemType | ((room: Quest, props: OnRenderGraphicItemProps) => GraphicItemType) - /** - * The function for rendering the icon of the quest. - */ - get renderIcon(): ((props: OnRenderGraphicItemProps) => GraphicItemType) | undefined { - let render = this._renderIcon - if (render === undefined) { - return undefined - } - if (typeof render === "function") { - return (props: OnRenderGraphicItemProps) => { - return render(this, props) - } - } - return (props: OnRenderGraphicItemProps) => render - } - - private _renderImage?: GraphicItemType | ((room: Quest, props: OnRenderGraphicItemProps) => GraphicItemType) - /** - * The function for rendering the image of the quest. - */ - get renderImage(): ((props: OnRenderGraphicItemProps) => GraphicItemType) | undefined { - let render = this._renderImage - if (render === undefined) { - return undefined - } - if (typeof render === "function") { - return (props: OnRenderGraphicItemProps) => { - return render(this, props) - } - } - return (props: OnRenderGraphicItemProps) => render - } - - private _isInDevelopment: boolean - /** - * If the quest is in development. - */ - get isInDevelopment(): boolean { - return this._isInDevelopment - } - - /** - * The index of the current stage. - */ - get currentStageIndex(): number | undefined { - return this.getStorageProperty('currentStageIndex') - } - private set currentStageIndex(value: number | undefined) { - this.setStorageProperty('currentStageIndex', value) - } - - /** - * The current stage. - */ - get currentStage(): StageQuest | undefined { - let index = this.currentStageIndex - if (index === undefined || index >= this.stages.length) { - return undefined - } - return this.stages[index] - } - - /** - * If the quest is started. - */ - get started(): boolean { - return this.currentStageIndex !== undefined - } - - /** - * If the quest is completed. - */ - get completed(): boolean { - if (this.currentStageIndex === undefined) { - return false - } - return this.currentStageIndex > this.stages.length - 1 - } - - private _onStart?: (stage: Quest, props: OnStartStageQuest) => void - /** - * The function that will be called when the quest starts. - */ - get onStart(): undefined | ((props: OnStartStageQuest) => void) { - let onStart = this._onStart - if (onStart === undefined) { - return undefined - } - return (props: OnStartStageQuest) => onStart(this, props) - } - - private _onNextStage?: (stage: Quest, props: OnEndStageQuest) => void - /** - * The function that will be called when the quest goes to the next stage. - */ - get onNextStage(): undefined | ((props: OnEndStageQuest) => void) { - let onNext = this._onNextStage - if (onNext === undefined) { - return undefined - } - return (props: OnEndStageQuest) => onNext(this, props) - } - - /** - * Start the quest. - * @param props The properties for the start stage. If you not want to pass any property, you can pass an {}. - * @returns - */ - start(props: OnStartStageQuest): void { - if (this.started) { - console.warn(`[NQTR] Quest ${this.id} is already started`) - return - } - if (this.stages.length === 0) { - console.error(`[NQTR] Quest ${this.id} has no stages`) - return - } - this.currentStageIndex = 0 - let currentStage = this.currentStage - if (currentStage && currentStage.start) { - this.onStart && this.onStart(props) - return currentStage.start(props) - } - else { - console.error(`[NQTR] Quest ${this.id} has no start stage`) - } - } - - /** - * Go to the next stage if the current stage is completed. - * If you want to force the change of stage, use goNextStage. - * @param startProps The properties for the start stage. If you not want to pass any property, you can pass an {}. - * @param endProps The properties for the end stage. If you not want to pass any property, you can pass an {}. - * @returns true if the stage was changed, false otherwise. - */ - tryToGoNextStage( - startProps: OnStartStageQuest, - endProps: OnEndStageQuest - ): boolean { - if (!this.started) { - return false - } - if (this.completed) { - return false - } - let currentStage = this.currentStage - if (!currentStage) { - console.error(`[NQTR] Quest ${this.id} has no current stage`) - return false - } - if (currentStage.completed) { - return this.goNextStage(startProps, endProps) - } - return false - } - - /** - * Complete the current stage and go to the next stage. - * If you want to go to the next stage only if the current stage is completed, use tryToGoNextStage. - * @param startProps The properties for the start stage. If you not want to pass any property, you can pass an {}. - * @param endProps The properties for the end stage. If you not want to pass any property, you can pass an {}. - * @returns true if the stage was changed, false otherwise. - */ - completeCurrentStageAndGoNext( - startProps: OnStartStageQuest, - endProps: OnEndStageQuest - ): boolean { - let currentStage = this.currentStage - if (!currentStage) { - console.error(`[NQTR] Quest ${this.id} has no current stage`) - return false - } - currentStage.completed = true - return this.goNextStage(startProps, endProps) - } - - /** - * Go to the next stage without checking if the current stage is completed. - * If you want to go to the next stage only if the current stage is completed, use tryToGoNextStage. - * @param startProps - * @param endProps - * @returns returns true if the stage was changed, false otherwise. - */ - goNextStage( - startProps: OnStartStageQuest, - endProps: OnEndStageQuest - ): boolean { - if (!this.started) { - console.warn(`[NQTR] Quest ${this.id} is not started`) - return false - } - if (this.completed) { - console.warn(`[NQTR] Quest ${this.id} is already completed`) - return false - } - let prevStage = this.currentStage - let currentStageIndex = this.currentStageIndex - if (!prevStage || currentStageIndex === undefined) { - console.error(`[NQTR] Quest ${this.id} has no current stage`) - return false - } - this.currentStageIndex = currentStageIndex + 1 - this.onNextStage && this.onNextStage(endProps) - if (prevStage && prevStage.onEnd) { - prevStage.onEnd(endProps) - } - let nextCurrentStage = this.currentStage - if (nextCurrentStage) { - nextCurrentStage.inizialize() - if (this.currentStageMustStart) { - this.startCurrentStage(startProps) - } - } - - return true - } - - /** - * If the current stage must start. It is true if the current stage is not started, can start and not completed. - */ - get currentStageMustStart(): boolean { - let currentStage = this.currentStage - if (!currentStage) { - return false - } - return !currentStage.started && currentStage.canStart && !currentStage.completed - } - - /** - * Start the current stage. - * @param props The properties for the start stage. If you not want to pass any property, you can pass an {}. - */ - startCurrentStage(props: OnStartStageQuest): void { - let newCurrentStage = this.currentStage - if (newCurrentStage && this.currentStageMustStart) { - newCurrentStage.start(props) - } - else { - console.warn(`[NQTR] Quest ${this.id} can't start the current stage`) - } - } -} +import { GraphicItemType, OnRenderGraphicItemProps, OnStartEndStageQuest } from "@drincs/nqtr/dist/override"; +import { StoredClassModel } from "@drincs/pixi-vn"; +import { QuestProps } from "../../interface"; +import Stage, { StageQuest } from "./Stage"; + +const QUEST_CATEGORY = "__nqtr-quest__" + +export default class Quest extends StoredClassModel { + constructor(id: string, stages: Stage[], props: QuestProps) { + super(QUEST_CATEGORY, id) + this._stages = stages + this._name = props.name || "" + this._description = props.description || "" + this._renderIcon = props.renderIcon + this._renderImage = props.renderImage + this._isInDevelopment = props.isInDevelopment || false + this._onStart = props.onStart + this._onNextStage = props.onNextStage + } + + private _stages: Stage[] + /** + * The stages of the quest. + */ + get stages(): StageQuest[] { + return this._stages.map((stage, index) => { + return new StageQuest(stage.id, stage) + }) + } + + private _name: string + /** + * The name of the quest. + */ + get name(): string { + return this._name + } + + private _description: string + /** + * The description of the quest. + */ + get description(): string { + return this._description + } + + private _renderIcon?: GraphicItemType | ((room: Quest, props: OnRenderGraphicItemProps) => GraphicItemType) + /** + * The function for rendering the icon of the quest. + */ + get renderIcon(): ((props: OnRenderGraphicItemProps) => GraphicItemType) | undefined { + let render = this._renderIcon + if (render === undefined) { + return undefined + } + if (typeof render === "function") { + return (props: OnRenderGraphicItemProps) => { + return render(this, props) + } + } + return (props: OnRenderGraphicItemProps) => render + } + + private _renderImage?: GraphicItemType | ((room: Quest, props: OnRenderGraphicItemProps) => GraphicItemType) + /** + * The function for rendering the image of the quest. + */ + get renderImage(): ((props: OnRenderGraphicItemProps) => GraphicItemType) | undefined { + let render = this._renderImage + if (render === undefined) { + return undefined + } + if (typeof render === "function") { + return (props: OnRenderGraphicItemProps) => { + return render(this, props) + } + } + return (props: OnRenderGraphicItemProps) => render + } + + private _isInDevelopment: boolean + /** + * If the quest is in development. + */ + get isInDevelopment(): boolean { + return this._isInDevelopment + } + + /** + * The index of the current stage. + */ + get currentStageIndex(): number | undefined { + return this.getStorageProperty('currentStageIndex') + } + private set currentStageIndex(value: number | undefined) { + this.setStorageProperty('currentStageIndex', value) + } + + /** + * The current stage. + */ + get currentStage(): StageQuest | undefined { + let index = this.currentStageIndex + if (index === undefined || index >= this.stages.length) { + return undefined + } + return this.stages[index] + } + + /** + * If the quest is started. + */ + get started(): boolean { + return this.currentStageIndex !== undefined + } + + /** + * If the quest is completed. + */ + get completed(): boolean { + if (this.currentStageIndex === undefined) { + return false + } + return this.currentStageIndex > this.stages.length - 1 + } + + private _onStart?: (stage: Quest, props: OnStartEndStageQuest) => void + /** + * The function that will be called when the quest starts. + */ + get onStart(): undefined | ((props: OnStartEndStageQuest) => void) { + let onStart = this._onStart + if (onStart === undefined) { + return undefined + } + return (props: OnStartEndStageQuest) => onStart(this, props) + } + + private _onNextStage?: (stage: Quest, props: OnStartEndStageQuest) => void + /** + * The function that will be called when the quest goes to the next stage. + */ + get onNextStage(): undefined | ((props: OnStartEndStageQuest) => void) { + let onNext = this._onNextStage + if (onNext === undefined) { + return undefined + } + return (props: OnStartEndStageQuest) => onNext(this, props) + } + + /** + * Start the quest. + * @param props The properties for the start stage. If you not want to pass any property, you can pass an {}. + * @returns + */ + start(props: OnStartEndStageQuest): void { + if (this.started) { + console.warn(`[NQTR] Quest ${this.id} is already started`) + return + } + if (this.stages.length === 0) { + console.error(`[NQTR] Quest ${this.id} has no stages`) + return + } + this.currentStageIndex = 0 + let currentStage = this.currentStage + if (currentStage && currentStage.start) { + this.onStart && this.onStart(props) + return currentStage.start(props) + } + else { + console.error(`[NQTR] Quest ${this.id} has no start stage`) + } + } + + /** + * Go to the next stage if the current stage is completed. + * If you want to force the change of stage, use goNextStage. + * @param props The properties. If you not want to pass any property, you can pass an {}. + * @returns true if the stage was changed, false otherwise. + */ + tryToGoNextStage( + props: OnStartEndStageQuest, + ): boolean { + if (!this.started) { + return false + } + if (this.completed) { + return false + } + let currentStage = this.currentStage + if (!currentStage) { + console.error(`[NQTR] Quest ${this.id} has no current stage`) + return false + } + if (currentStage.completed) { + return this.goNextStage(props) + } + return false + } + + /** + * Complete the current stage and go to the next stage. + * If you want to go to the next stage only if the current stage is completed, use tryToGoNextStage. + * @param props The properties. If you not want to pass any property, you can pass an {}. + * @returns true if the stage was changed, false otherwise. + */ + completeCurrentStageAndGoNext( + props: OnStartEndStageQuest, + ): boolean { + let currentStage = this.currentStage + if (!currentStage) { + console.error(`[NQTR] Quest ${this.id} has no current stage`) + return false + } + currentStage.completed = true + return this.goNextStage(props) + } + + /** + * Go to the next stage without checking if the current stage is completed. + * If you want to go to the next stage only if the current stage is completed, use tryToGoNextStage. + * @param props The properties. If you not want to pass any property, you can pass an {}. + * @returns returns true if the stage was changed, false otherwise. + */ + goNextStage( + props: OnStartEndStageQuest, + ): boolean { + if (!this.started) { + console.warn(`[NQTR] Quest ${this.id} is not started`) + return false + } + if (this.completed) { + console.warn(`[NQTR] Quest ${this.id} is already completed`) + return false + } + let prevStage = this.currentStage + let currentStageIndex = this.currentStageIndex + if (!prevStage || currentStageIndex === undefined) { + console.error(`[NQTR] Quest ${this.id} has no current stage`) + return false + } + this.currentStageIndex = currentStageIndex + 1 + this.onNextStage && this.onNextStage(props) + if (prevStage && prevStage.onEnd) { + prevStage.onEnd(props) + } + let nextCurrentStage = this.currentStage + if (nextCurrentStage) { + nextCurrentStage.inizialize() + if (this.currentStageMustStart) { + this.startCurrentStage(props) + } + } + + return true + } + + /** + * If the current stage must start. It is true if the current stage is not started, can start and not completed. + */ + get currentStageMustStart(): boolean { + let currentStage = this.currentStage + if (!currentStage) { + return false + } + return !currentStage.started && currentStage.canStart && !currentStage.completed + } + + /** + * Start the current stage. + * @param props The properties for the start stage. If you not want to pass any property, you can pass an {}. + */ + startCurrentStage(props: OnStartEndStageQuest): void { + let newCurrentStage = this.currentStage + if (newCurrentStage && this.currentStageMustStart) { + newCurrentStage.start(props) + } + else { + console.warn(`[NQTR] Quest ${this.id} can't start the current stage`) + } + } +} diff --git a/src/classes/quest/Stage.ts b/src/classes/quest/Stage.ts index 67708bc..0cde366 100644 --- a/src/classes/quest/Stage.ts +++ b/src/classes/quest/Stage.ts @@ -1,4 +1,4 @@ -import { GraphicItemType, OnEndStageQuest, OnRenderGraphicItemProps, OnStartStageQuest } from "@drincs/nqtr/dist/override"; +import { GraphicItemType, OnRenderGraphicItemProps, OnStartEndStageQuest } from "@drincs/nqtr/dist/override"; import { StoredClassModel, getFlag } from "@drincs/pixi-vn"; import { StageProps } from "../../interface"; import StageFlags from "../../interface/quest/StageFlags"; @@ -119,28 +119,28 @@ export default class Stage extends StoredClassModel implements StageProps { // function - private _onStart?: (stage: Stage, props: OnStartStageQuest) => void + private _onStart?: (stage: Stage, props: OnStartEndStageQuest) => void /** * The function that will be called when the stage starts. */ - get onStart(): undefined | ((props: OnStartStageQuest) => void) { + get onStart(): undefined | ((props: OnStartEndStageQuest) => void) { let onStart = this._onStart if (onStart === undefined) { return undefined } - return (props: OnStartStageQuest) => onStart(this, props) + return (props: OnStartEndStageQuest) => onStart(this, props) } - private _onEnd?: (stage: Stage, props: OnEndStageQuest) => void + private _onEnd?: (stage: Stage, props: OnStartEndStageQuest) => void /** * The function that will be called when the stage ends. */ - get onEnd(): undefined | ((props: OnEndStageQuest) => void) { + get onEnd(): undefined | ((props: OnStartEndStageQuest) => void) { let onEnd = this._onEnd if (onEnd === undefined) { return undefined } - return (props: OnEndStageQuest) => onEnd(this, props) + return (props: OnStartEndStageQuest) => onEnd(this, props) } } @@ -248,7 +248,7 @@ export class StageQuest extends Stage { /** * The function that will be called when the stage starts. */ - start(props: OnStartStageQuest) { + start(props: OnStartEndStageQuest) { if (this.canStart) { this.started = true if (this.onStart) { diff --git a/src/functions/QuestFunctions.ts b/src/functions/QuestFunctions.ts index d02d47c..0fa9eeb 100644 --- a/src/functions/QuestFunctions.ts +++ b/src/functions/QuestFunctions.ts @@ -1,10 +1,10 @@ -import { OnStartStageQuest } from "@drincs/nqtr/dist/override"; +import { OnStartEndStageQuest } from "@drincs/nqtr/dist/override"; import { registeredQuests } from "../decorators/QuestDecorator"; /** * Start the quests that must start on the current stage. */ -export function startMustStartStageQuests(props: OnStartStageQuest) { +export function startMustStartStageQuests(props: OnStartEndStageQuest) { Object.entries(registeredQuests).forEach(([_, quest]) => { if (quest.currentStageMustStart) { quest.startCurrentStage(props) diff --git a/src/interface/quest/QuestProps.ts b/src/interface/quest/QuestProps.ts index 92ace04..8e3797d 100644 --- a/src/interface/quest/QuestProps.ts +++ b/src/interface/quest/QuestProps.ts @@ -1,4 +1,4 @@ -import { GraphicItemType, OnEndStageQuest, OnRenderGraphicItemProps, OnStartStageQuest } from "@drincs/nqtr/dist/override" +import { GraphicItemType, OnRenderGraphicItemProps, OnStartEndStageQuest } from "@drincs/nqtr/dist/override" import Quest from "../../classes/quest/Quest" export default interface QuestProps { @@ -40,9 +40,9 @@ export default interface QuestProps { /** * The function that will be executed when the quest starts. */ - onStart?: (quest: Quest, props: OnStartStageQuest) => void + onStart?: (quest: Quest, props: OnStartEndStageQuest) => void /** * The function that will be executed when a stage end in the quest. */ - onNextStage?: (quest: Quest, props: OnEndStageQuest) => void + onNextStage?: (quest: Quest, props: OnStartEndStageQuest) => void } diff --git a/src/interface/quest/StageProps.ts b/src/interface/quest/StageProps.ts index 89a5ca7..b6446b1 100644 --- a/src/interface/quest/StageProps.ts +++ b/src/interface/quest/StageProps.ts @@ -1,4 +1,4 @@ -import { GraphicItemType, OnEndStageQuest, OnRenderGraphicItemProps, OnStartStageQuest } from "@drincs/nqtr/dist/override" +import { GraphicItemType, OnRenderGraphicItemProps, OnStartEndStageQuest } from "@drincs/nqtr/dist/override" import { Goal, Stage } from "../../classes" import { QuestsRequiredType } from "../../types" import StageFlags from "./StageFlags" @@ -67,9 +67,9 @@ export default interface StageProps { /** * The function that will be executed when the stage starts. */ - onStart?: (stage: Stage, props: OnStartStageQuest) => void + onStart?: (stage: Stage, props: OnStartEndStageQuest) => void /** * The function that will be executed when the stage ends. */ - onEnd?: (stage: Stage, props: OnEndStageQuest) => void + onEnd?: (stage: Stage, props: OnStartEndStageQuest) => void }