UNPKG

@drincs/pixi-vn

Version:

Pixi'VN is a npm package that provides various features for creating visual novels.

1,500 lines (1,473 loc) 142 kB
'use strict'; var deepDiff = require('deep-diff'); var sha1 = require('crypto-js/sha1'); var pixi_js = require('pixi.js'); var devtools = require('@pixi/devtools'); function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; } var sha1__default = /*#__PURE__*/_interopDefault(sha1); var __defProp = Object.defineProperty; var __defProps = Object.defineProperties; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropDescs = Object.getOwnPropertyDescriptors; var __getOwnPropSymbols = Object.getOwnPropertySymbols; var __hasOwnProp = Object.prototype.hasOwnProperty; var __propIsEnum = Object.prototype.propertyIsEnumerable; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __spreadValues = (a, b) => { for (var prop in b || (b = {})) if (__hasOwnProp.call(b, prop)) __defNormalProp(a, prop, b[prop]); if (__getOwnPropSymbols) for (var prop of __getOwnPropSymbols(b)) { if (__propIsEnum.call(b, prop)) __defNormalProp(a, prop, b[prop]); } return a; }; var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b)); var __decorateClass = (decorators, target, key, kind) => { var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target; for (var i = decorators.length - 1, decorator; i >= 0; i--) if (decorator = decorators[i]) result = (kind ? decorator(target, key, result) : decorator(result)) || result; if (kind && result) __defProp(target, key, result); return result; }; var __async = (__this, __arguments, generator) => { return new Promise((resolve, reject) => { var fulfilled = (value) => { try { step(generator.next(value)); } catch (e) { reject(e); } }; var rejected = (value) => { try { step(generator.throw(value)); } catch (e) { reject(e); } }; var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected); step((generator = generator.apply(__this, __arguments)).next()); }); }; // src/classes/CanvasEvent.ts var CanvasEvent = class { constructor() { /** * Get the id of the event. This variable is used in the system to get the event by id, {@link getEventInstanceById} */ this.id = "event_id_not_set"; this.id = this.constructor.prototype.id; } fn(_event, _element) { throw new Error("[Pixi'VN] The method CanvasEvent.fn() must be overridden"); } }; function getStepSha1(step) { let sha1String = sha1__default.default(step.toString().toLocaleLowerCase()); return sha1String.toString(); } function checkIfStepsIsEqual(step1, step2) { return step1 === step2; } // src/classes/LabelAbstract.ts var LabelAbstract = class { /** * @param id is the id of the label * @param props is the properties of the label */ constructor(id, props) { this._id = id; this._onStepStart = props == null ? void 0 : props.onStepStart; this._onLoadStep = props == null ? void 0 : props.onLoadStep; this._onStepEnd = props == null ? void 0 : props.onStepEnd; this._choiseIndex = props == null ? void 0 : props.choiseIndex; } /** * Get the id of the label. This variable is used in the system to get the label by id, {@link getLabelById} */ get id() { return this._id; } /** * Get the corresponding steps number * @param externalSteps * @returns Numer of corresponding steps, for example, if externalSteps is [ABC, DEF, GHI] and the steps of the label is [ABC, GHT], the result will be 1 */ getCorrespondingStepsNumber(externalSteps) { if (externalSteps.length === 0) { return 0; } let res = 0; externalSteps.forEach((step, index) => { if (checkIfStepsIsEqual(step, this.steps[index])) { res = index; } }); return res; } /** * Is a function that will be executed in {@link Label#onStepStart} and when the user goes back to it or when the user laods a save file. * @returns Promise<void> or void */ get onStepStart() { return (stepIndex, label) => __async(this, null, function* () { if (this._onLoadStep) { yield this._onLoadStep(stepIndex, label); } if (this._onStepStart) { return yield this._onStepStart(stepIndex, label); } }); } /** * Get the function that will be executed a old step is reloaded. A step is reloaded when the user goes back to it or when the user laods a save file. * @returns Promise<void> or void */ get onLoadStep() { return this._onLoadStep; } /** * Is a function that will be executed when the step ends. * @returns Promise<void> or void */ get onStepEnd() { return this._onStepEnd; } get choiseIndex() { return this._choiseIndex; } }; // src/classes/Label.ts var Label = class extends LabelAbstract { /** * @param id is the id of the label * @param steps is the list of steps that the label will perform * @param props is the properties of the label */ constructor(id, steps, props) { super(id, props); this._steps = steps; } /** * Get the steps of the label. */ get steps() { if (typeof this._steps === "function") { return this._steps(); } return this._steps; } }; // src/classes/CloseLabel.ts var CLOSE_LABEL_ID = "__close-label-id__"; function newCloseLabel(choiseIndex) { return new Label(CLOSE_LABEL_ID, [], { choiseIndex }); } // src/decorators/LabelDecorator.ts var registeredLabels = {}; function newLabel(id, steps, props) { if (registeredLabels[id]) { console.info(`[Pixi'VN] Label ${id} already exists, it will be overwritten`); } let label = new Label(id, steps, props); registeredLabels[id] = label; return label; } function getLabelById(id) { let label = registeredLabels[id]; if (!label) { console.error(`[Pixi'VN] Label ${id} not found`); return; } return label; } // src/functions/CanvasUtility.ts function getTextureMemory(texture) { let sourceTexture = texture.source; let textureMemory = { image: sourceTexture.label }; return textureMemory; } function exportCanvasElement(element) { return element.memory; } function importCanvasElement(memory) { let element = getCanvasElementInstanceById(memory.pixivnId); if (element) { element.memory = memory; } else { throw new Error("[Pixi'VN] The element " + memory.pixivnId + " could not be created"); } return element; } // src/classes/canvas/CanvasContainer.ts var CANVAS_CONTAINER_ID = "CanvasContainer"; var CanvasContainer = class extends pixi_js.Container { constructor(options) { super(options); this.pixivnId = CANVAS_CONTAINER_ID; this.pixivnId = this.constructor.prototype.pixivnId || CANVAS_CONTAINER_ID; } get memory() { let memory = getMemoryContainer(this); this.children.forEach((child) => { memory.elements.push(exportCanvasElement(child)); }); return memory; } set memory(value) { setMemoryContainer(this, value); value.elements.forEach((child) => { this.addChild(importCanvasElement(child)); }); } }; function getMemoryContainer(element) { let className = "CanvasContainer"; if (element.hasOwnProperty("pixivnId")) { className = element.pixivnId; } return { pixivnId: className, elements: [], width: element.width, height: element.height, isRenderGroup: element.isRenderGroup, blendMode: element.blendMode, tint: element.tint, alpha: element.alpha, angle: element.angle, renderable: element.renderable, rotation: element.rotation, scale: { x: element.scale.x, y: element.scale.y }, pivot: { x: element.pivot.x, y: element.pivot.y }, position: { x: element.position.x, y: element.position.y }, skew: { x: element.skew.x, y: element.skew.y }, visible: element.visible, x: element.x, y: element.y, boundsArea: element.boundsArea, cursor: element.cursor, eventMode: element.eventMode, interactive: element.interactive, interactiveChildren: element.interactiveChildren, hitArea: element.hitArea }; } function setMemoryContainer(element, memory) { memory.isRenderGroup && (element.isRenderGroup = memory.isRenderGroup); memory.blendMode && (element.blendMode = memory.blendMode); memory.tint && (element.tint = memory.tint); memory.alpha && (element.alpha = memory.alpha); memory.angle && (element.angle = memory.angle); memory.renderable && (element.renderable = memory.renderable); memory.rotation && (element.rotation = memory.rotation); if (memory.scale) { if (typeof memory.scale === "number") { element.scale.set(memory.scale, memory.scale); } else { element.scale.set(memory.scale.x, memory.scale.y); } } if (memory.pivot) { if (typeof memory.pivot === "number") { element.pivot.set(memory.pivot, memory.pivot); } else { element.pivot.set(memory.pivot.x, memory.pivot.y); } } memory.position && element.position.set(memory.position.x, memory.position.y); memory.skew && element.skew.set(memory.skew.x, memory.skew.y); memory.visible && (element.visible = memory.visible); memory.x && (element.x = memory.x); memory.y && (element.y = memory.y); memory.boundsArea && (element.boundsArea = memory.boundsArea); memory.cursor && (element.cursor = memory.cursor); memory.eventMode && (element.eventMode = memory.eventMode); memory.interactive && (element.interactive = memory.interactive); memory.interactiveChildren && (element.interactiveChildren = memory.interactiveChildren); memory.hitArea && (element.hitArea = memory.hitArea); memory.width && (element.width = memory.width); memory.height && (element.height = memory.height); } function getTexture(imageUrl) { return __async(this, null, function* () { if (pixi_js.Assets.cache.has(imageUrl)) { return pixi_js.Assets.get(imageUrl); } return pixi_js.Assets.load(imageUrl).then((texture) => { if (!texture) { console.error("[Pixi'VN] Texture not found", imageUrl); return; } if (!(texture instanceof pixi_js.Texture)) { console.error("[Pixi'VN] File not is a image", imageUrl); return; } return texture; }).catch((e) => { console.error("[Pixi'VN] Error loading image", e); return; }); }); } function getFillGradientFillPattern(prop, propName) { if (!(prop instanceof Object)) { return prop; } console.warn(`[Pixi'VN] CanvasText.style.${propName} is a FillGradient or FillPattern, this is not supported yet.`, prop); return void 0; } function getTextStyle(style) { return { align: style.align, breakWords: style.breakWords, dropShadow: style.dropShadow, fill: getFillGradientFillPattern(style.stroke, "fill"), fontFamily: style.fontFamily, fontSize: style.fontSize, fontStyle: style.fontStyle, fontVariant: style.fontVariant, fontWeight: style.fontWeight, leading: style.leading, letterSpacing: style.letterSpacing, lineHeight: style.lineHeight, padding: style.padding, stroke: getFillGradientFillPattern(style.stroke, "stroke"), textBaseline: style.textBaseline, trim: style.trim, whiteSpace: style.whiteSpace, wordWrap: style.wordWrap, wordWrapWidth: style.wordWrapWidth }; } // src/decorators/EventDecorator.ts var registeredEvents = {}; function eventDecorator(name) { return function(target) { if (!name) { name = target.name; } if (registeredEvents[name]) { console.info(`[Pixi'VN] Event ${name} already exists, it will be overwritten`); } target.prototype.id = name; registeredEvents[name] = target; }; } function getEventTypeById(eventId) { try { let eventType = registeredEvents[eventId]; if (!eventType) { console.error(`[Pixi'VN] Event ${eventId} not found`); return; } new eventType(); return eventType; } catch (e) { console.error(`[Pixi'VN] Error while getting Event ${eventId}`, e); return; } } function getEventInstanceById(eventId) { try { let eventType = registeredEvents[eventId]; if (!eventType) { console.error(`[Pixi'VN] Event ${eventId} not found`); return; } let event = new eventType(); return event; } catch (e) { console.error(`[Pixi'VN] Error while getting Event ${eventId}`, e); return; } } // src/classes/canvas/CanvasSprite.ts var CANVAS_SPRITE_ID = "CanvasSprite"; var CanvasSprite = class _CanvasSprite extends pixi_js.Sprite { constructor(options) { super(options); this.pixivnId = CANVAS_SPRITE_ID; this._onEvents = {}; this.pixivnId = this.constructor.prototype.pixivnId || CANVAS_SPRITE_ID; } get memory() { return getMemorySprite(this); } set memory(value) { setMemorySprite(this, value); } get onEvents() { return this._onEvents; } /** * is same function as on(), but it keeps in memory the children. * @param event The event type, e.g., 'click', 'mousedown', 'mouseup', 'pointerdown', etc. * @param eventClass The class that extends CanvasEvent. * @returns * @example * ```typescript * \@eventDecorator() * export class EventTest extends CanvasEvent<CanvasSprite> { * override fn(event: CanvasEventNamesType, sprite: CanvasSprite): void { * if (event === 'pointerdown') { * sprite.scale.x *= 1.25; * sprite.scale.y *= 1.25; * } * } * } * ``` * * ```typescript * let sprite = addImage("alien", 'https://pixijs.com/assets/eggHead.png') * await sprite.load() * * sprite.eventMode = 'static'; * sprite.cursor = 'pointer'; * sprite.onEvent('pointerdown', EventTest); * * GameWindowManager.addCanvasElement("bunny", sprite); * ``` */ onEvent(event, eventClass) { let id = eventClass.prototype.id; let instance = getEventInstanceById(id); this._onEvents[event] = id; if (instance) { super.on(event, () => { instance.fn(event, this); }); } return this; } /** * on() does not keep in memory the event class, use onEvent() instead * @deprecated * @private * @param event * @param fn * @param context */ on(event, fn, context) { return super.on(event, fn, context); } static from(source, skipCache) { let sprite = pixi_js.Sprite.from(source, skipCache); let mySprite = new _CanvasSprite(); mySprite.texture = sprite.texture; return mySprite; } }; function getMemorySprite(element) { let temp = getMemoryContainer(element); return __spreadProps(__spreadValues({}, temp), { pixivnId: element.pixivnId, textureImage: getTextureMemory(element.texture), anchor: { x: element.anchor.x, y: element.anchor.y }, roundPixels: element.roundPixels, onEvents: element.onEvents }); } function setMemorySprite(element, memory) { setMemoryContainer(element, memory); getTexture(memory.textureImage.image).then((texture) => { if (texture) { element.texture = texture; } }); if (memory.anchor) { if (typeof memory.anchor === "number") { element.anchor.set(memory.anchor, memory.anchor); } else { element.anchor.set(memory.anchor.x, memory.anchor.y); } } memory.roundPixels && (element.roundPixels = memory.roundPixels); for (let event in memory.onEvents) { let id = memory.onEvents[event]; let instance = getEventTypeById(id); if (instance) { element.onEvent(event, instance); } } } // src/classes/canvas/CanvasImage.ts var CANVAS_IMAGE_ID = "CanvasImage"; var CanvasImage = class _CanvasImage extends CanvasSprite { constructor(options, imageLink) { super(options); this.pixivnId = CANVAS_IMAGE_ID; this.imageLink = ""; if (imageLink) { this.imageLink = imageLink; } } get memory() { return __spreadProps(__spreadValues({}, getMemorySprite(this)), { pixivnId: this.pixivnId, imageLink: this.imageLink }); } set memory(memory) { setMemorySprite(this, memory); this.imageLink = memory.imageLink; } static from(source, skipCache) { let sprite = pixi_js.Sprite.from(source, skipCache); let mySprite = new _CanvasImage(); mySprite.texture = sprite.texture; return mySprite; } /** * Load the image from the link and set the texture of the sprite. * @param image The link of the image. If it is not set, it will use the imageLink property. * @returns A promise that resolves when the image is loaded. */ load(image) { return __async(this, null, function* () { if (!image) { image = this.imageLink; } return getTexture(this.imageLink).then((texture) => { if (texture) { this.texture = texture; } }).catch((e) => { console.error("[Pixi'VN] Error into CanvasImage.load()", e); }); }); } }; var CANVAS_TEXT_ID = "CanvasText"; var CanvasText = class extends pixi_js.Text { constructor(options) { super(options); this.pixivnId = CANVAS_TEXT_ID; this._onEvents = {}; this.pixivnId = this.constructor.prototype.pixivnId || CANVAS_TEXT_ID; } get memory() { return getMemoryText(this); } set memory(value) { setMemoryText(this, value); } get onEvents() { return this._onEvents; } /** * is same function as on(), but it keeps in memory the children. * @param event The event type, e.g., 'click', 'mousedown', 'mouseup', 'pointerdown', etc. * @param eventClass The class that extends CanvasEvent. * @returns * @example * ```typescript * \@eventDecorator() * export class EventTest extends CanvasEvent<CanvasText> { * override fn(event: CanvasEventNamesType, text: CanvasText): void { * if (event === 'pointerdown') { * text.scale.x *= 1.25; * text.scale.y *= 1.25; * } * } * } * ``` * * ```typescript * const text = new CanvasText(); * text.text = "Hello World" * * text.eventMode = 'static'; * text.cursor = 'pointer'; * text.onEvent('pointerdown', EventTest); * * GameWindowManager.addCanvasElement("text", text); * ``` */ onEvent(event, eventClass) { let id = eventClass.prototype.id; let instance = getEventInstanceById(id); this._onEvents[event] = id; if (instance) { super.on(event, () => { instance.fn(event, this); }); } return this; } /** * on() does not keep in memory the event class, use onEvent() instead * @deprecated * @private * @param event * @param fn * @param context */ on(event, fn, context) { return super.on(event, fn, context); } }; function getMemoryText(element) { let temp = getMemoryContainer(element); return __spreadProps(__spreadValues({}, temp), { pixivnId: element.pixivnId, anchor: { x: element.anchor.x, y: element.anchor.y }, text: element.text, resolution: element.resolution, style: getTextStyle(element.style), roundPixels: element.roundPixels, onEvents: element.onEvents }); } function setMemoryText(element, memory) { setMemoryContainer(element, memory); if (memory.anchor) { if (typeof memory.anchor === "number") { element.anchor.set(memory.anchor, memory.anchor); } else { element.anchor.set(memory.anchor.x, memory.anchor.y); } } memory.text && (element.text = memory.text); memory.resolution && (element.resolution = memory.resolution); memory.style && (element.style = memory.style); memory.roundPixels && (element.roundPixels = memory.roundPixels); for (let event in memory.onEvents) { let id = memory.onEvents[event]; let instance = getEventTypeById(id); if (instance) { element.onEvent(event, instance); } } } // src/decorators/CanvasElementDecorator.ts var registeredCanvasElement = {}; function canvasElementDecorator(name) { return function(target) { if (registeredCanvasElement[name]) { console.warn(`[Pixi'VN] CanvasElement ${name} already registered`); } target.prototype.pixivnId = name; registeredCanvasElement[name] = target; }; } function getCanvasElementInstanceById(canvasId) { try { let eventType = registeredCanvasElement[canvasId]; if (!eventType) { if (canvasId === CANVAS_CONTAINER_ID) { eventType = CanvasContainer; } else if (canvasId === CANVAS_IMAGE_ID) { eventType = CanvasImage; } else if (canvasId === CANVAS_SPRITE_ID) { eventType = CanvasSprite; } else if (canvasId === CANVAS_TEXT_ID) { eventType = CanvasText; } } if (!eventType) { console.error(`[Pixi'VN] CanvasElement ${canvasId} not found`); return; } let canvasElement = new eventType(); return canvasElement; } catch (e) { console.error(`[Pixi'VN] Error while getting CanvasElement ${canvasId}`, e); return; } } // src/decorators/CharacterDecorator.ts var registeredCharacters = {}; function saveCharacter(character) { if (Array.isArray(character)) { character.forEach((c) => saveCharacter(c)); return; } if (registeredCharacters[character.id]) { console.info(`[Pixi'VN] Character id ${character.id} already exists, it will be overwritten`); } registeredCharacters[character.id] = character; } // src/decorators/TickerDecorator.ts var registeredTickers = {}; function tickerDecorator(name) { return function(target) { if (!name) { name = target.name; } if (registeredTickers[name]) { console.info(`[Pixi'VN] Ticker ${name} already exists, it will be overwritten`); } target.prototype.id = name; registeredTickers[name] = target; }; } function geTickerInstanceById(tickerId, args, duration, priority) { try { let ticker = registeredTickers[tickerId]; if (!ticker) { console.error(`[Pixi'VN] Ticker ${tickerId} not found`); return; } return new ticker(args, duration, priority); } catch (e) { console.error(`[Pixi'VN] Error while getting Ticker ${tickerId}`, e); return; } } // src/types/CloseType.ts var Close = "close"; // src/classes/ChoiceMenuOption.ts var ChoiceMenuOption = class { /** * @param text Text to be displayed in the menu * @param label Label to be opened when the option is selected or the id of the label * @param props Properties to be passed to the label and olther parameters that you can use when get all the choice menu options. It be converted to a JSON string, so it cannot contain functions or classes. * @param type Type of the label to be opened. @default "call" */ constructor(text, label, props, type = "call") { /** * Properties to be passed to the label and olther parameters that you can use when get all the choice menu options. * @example * ```tsx * setChoiceMenuOptions([ * new ChoiceMenuOption("Hello", helloLabel, { disabled: true }), * ]) * return <List> * {getChoiceMenuOptions()?.map((item, index) => { * return ( * <ChoiceButton * disabled={item.props.disabled} * onClick={() => { * afterSelectChoice(item) * }} * > * {item.text} * </ChoiceButton> * ) * })} * </List> * ``` */ this.props = {}; this.text = text; this._label = label; this.type = type; if (props) { this.props = props; } } /** * Label to be opened when the option is selected */ get label() { let label = this._label; if (typeof label === "string") { let res = getLabelById(label); if (res) { label = res; } else { console.error(`Label ${label} not found, so it will be closed`); label = newCloseLabel(); } } return label; } }; var ChoiceMenuOptionClose = class { /** * @param text Text to be displayed in the menu * @param closeCurrentLabel If true, the current label will be closed. @default false */ constructor(text, closeCurrentLabel = false) { /** * Label to be opened when the option is selected */ this.label = newCloseLabel(); /** * Type of the label to be opened */ this.type = Close; /** * Properties to be passed to the label and olther parameters that you can use when get all the choice menu options. * @example * ```tsx * setChoiceMenuOptions([ * new ChoiceMenuOption("Hello", helloLabel, { disabled: true }), * ]) * return <List> * {getChoiceMenuOptions()?.map((item, index) => { * return ( * <ChoiceButton * disabled={item.props.disabled} * onClick={() => { * afterSelectChoice(item) * }} * > * {item.text} * </ChoiceButton> * ) * })} * </List> * ``` */ this.props = {}; this.text = text; this.closeCurrentLabel = closeCurrentLabel; } }; // src/functions/FlagsUtility.ts function setFlag(name, value) { let flags = GameStorageManager.getVariable(GameStorageManager.keysSystem.FLAGS_CATEGORY_KEY) || []; { let index = flags.indexOf(name); if (index > -1) { flags.splice(index, 1); } } GameStorageManager.setVariable(GameStorageManager.keysSystem.FLAGS_CATEGORY_KEY, flags); } function getFlag(name) { let flags = GameStorageManager.getVariable(GameStorageManager.keysSystem.FLAGS_CATEGORY_KEY) || []; return flags.includes(name); } // src/functions/DialogueUtility.ts function setDialogue(props) { let text = ""; let character = void 0; let dialogue; if (typeof props === "string") { text = props; dialogue = new DialogueBaseModel(text, character); } else if (Array.isArray(props)) { text = props.join(); dialogue = new DialogueBaseModel(text, character); } else if (!(props instanceof DialogueBaseModel)) { if (Array.isArray(props.text)) { text = props.text.join(); } else { text = props.text; } if (props.character) { if (typeof props.character === "string") { character = props.character; } else { character = props.character.id; } } dialogue = new DialogueBaseModel(text, character); } else { dialogue = props; } if (getFlag(GameStorageManager.keysSystem.ADD_NEXT_DIALOG_TEXT_INTO_THE_CURRENT_DIALOG_FLAG_KEY)) { let glueDialogue = getDialogue(); if (glueDialogue) { dialogue.text = `${glueDialogue.text}${dialogue.text}`; } setFlag(GameStorageManager.keysSystem.ADD_NEXT_DIALOG_TEXT_INTO_THE_CURRENT_DIALOG_FLAG_KEY); } GameStorageManager.setVariable(GameStorageManager.keysSystem.CURRENT_DIALOGUE_MEMORY_KEY, dialogue); GameStorageManager.setVariable(GameStorageManager.keysSystem.LAST_DIALOGUE_ADDED_IN_STEP_MEMORY_KEY, GameStepManager.lastStepIndex); } function getDialogue() { return GameStorageManager.getVariable(GameStorageManager.keysSystem.CURRENT_DIALOGUE_MEMORY_KEY); } function setChoiceMenuOptions(options) { let value = options.map((option) => { if (option instanceof ChoiceMenuOptionClose) { return { text: option.text, type: Close, closeCurrentLabel: option.closeCurrentLabel }; } return __spreadProps(__spreadValues({}, option), { label: option.label.id }); }); GameStorageManager.setVariable(GameStorageManager.keysSystem.CURRENT_MENU_OPTIONS_MEMORY_KEY, value); GameStorageManager.setVariable(GameStorageManager.keysSystem.LAST_MENU_OPTIONS_ADDED_IN_STEP_MEMORY_KEY, GameStepManager.lastStepIndex); } function getChoiceMenuOptions() { let d = GameStorageManager.getVariable(GameStorageManager.keysSystem.CURRENT_MENU_OPTIONS_MEMORY_KEY); if (d) { let options = []; d.forEach((option, index) => { if (option.type === Close) { let itemLabel = newCloseLabel(index); let choice = new ChoiceMenuOptionClose(option.text, option.closeCurrentLabel); choice.label = itemLabel; options.push(choice); return; } let label = getLabelById(option.label); if (label) { let itemLabel = new Label(label.id, label.steps, { onStepStart: label.onStepStart, choiseIndex: index }); options.push(new ChoiceMenuOption(option.text, itemLabel, option.props, option.type)); } }); return options; } return void 0; } // src/classes/ticker/TickerBase.ts var TickerBase = class { /** * @param args The arguments that you want to pass to the ticker. * @param duration The duration of the ticker in seconds. If is undefined, the step will end only when the animation is finished (if the animation doesn't have a goal to reach then it won't finish). @default undefined * @param priority The priority of the ticker. @default UPDATE_PRIORITY.NORMAL */ constructor(args, duration, priority) { /** * Get the id of the ticker. This variable is used in the system to get the ticker by id, {@link geTickerInstanceById} */ this.id = "ticker_id_not_set"; this.args = args; this.duration = duration; this.priority = priority; this.id = this.constructor.prototype.id; } /** * The method that will be called every frame. * This method should be overridden and you can use GameWindowManager.addCanvasElement() to get the canvas element of the canvas, and edit them. * @param _ticker The ticker that is calling this method * @param _args The arguments that you passed when you added the ticker * @param _tags The tags of the canvas elements that are connected to this ticker * @param _tickerId The id of the ticker. You can use this to get the ticker from the {@link GameWindowManager.currentTickers} */ fn(_ticker, _args, _tags, _tickerId) { throw new Error("[Pixi'VN] The method TickerBase.fn() must be overridden"); } }; // src/classes/ticker/FadeAlphaTicker.ts var FadeAlphaTicker = class extends TickerBase { fn(ticker, args, tags, tickerId) { let type = args.type === void 0 ? "hide" : args.type; let duration = args.duration === void 0 ? 1 : args.duration; let speed = 1 / (duration * 60); let limit = args.limit === void 0 ? type === "hide" ? 0 : 1 : args.limit; let tagToRemoveAfter2 = args.tagToRemoveAfter || []; if (typeof tagToRemoveAfter2 === "string") { tagToRemoveAfter2 = [tagToRemoveAfter2]; } if (type === "hide" && limit < 0) { limit = 0; } if (type === "show" && limit > 1) { limit = 1; } tags.filter((tag) => { var _a; let element = GameWindowManager.getCanvasElement(tag); if (args.startOnlyIfHaveTexture) { if (element && element instanceof pixi_js.Sprite && ((_a = element.texture) == null ? void 0 : _a.label) == "EMPTY") { return false; } } return true; }).forEach((tag) => { let element = GameWindowManager.getCanvasElement(tag); if (element && element instanceof pixi_js.Container) { if (type === "show" && element.alpha < limit) { element.alpha += speed * ticker.deltaTime; } else if (type === "hide" && element.alpha > limit) { element.alpha -= speed * ticker.deltaTime; } if (type === "show" && element.alpha >= limit) { element.alpha = limit; GameWindowManager.onEndOfTicker(tag, this, tagToRemoveAfter2, tickerId); } else if (type === "hide" && element.alpha <= limit) { element.alpha = limit; GameWindowManager.onEndOfTicker(tag, this, tagToRemoveAfter2, tickerId); } } }); } }; FadeAlphaTicker = __decorateClass([ tickerDecorator() ], FadeAlphaTicker); // src/functions/TickerUtility.ts function updateTickerProgression(args, propertyName, progression, valueConvert) { let limit = valueConvert && progression.limit ? valueConvert(progression.limit) : progression.limit; if (args[propertyName] === void 0 || !progression || args[propertyName] === limit) { return; } if (typeof args[propertyName] === "number") { if (progression.type === "linear") { args[propertyName] = getLinearProgression(args[propertyName], progression); } else if (progression.type === "exponential") { args[propertyName] = getExponentialProgression(args[propertyName], progression); } } else if (args[propertyName] !== void 0 && typeof args[propertyName] === "object" && args[propertyName].haveOwnProperty("x") && args[propertyName].haveOwnProperty("y") && typeof args[propertyName].x === "number" && typeof args[propertyName].y === "number") { if (progression.type === "linear") { args[propertyName].x = getLinearProgression(args[propertyName].x, progression); args[propertyName].y = getLinearProgression(args[propertyName].y, progression); } else if (progression.type === "exponential") { args[propertyName].x = getExponentialProgression(args[propertyName].x, progression); args[propertyName].y = getExponentialProgression(args[propertyName].y, progression); } } } function getLinearProgression(number, progression, valueConvert) { let limit = valueConvert && progression.limit ? valueConvert(progression.limit) : progression.limit; let amt = valueConvert ? valueConvert(progression.amt) : progression.amt; if (limit !== void 0) { if (number > limit && amt > 0) { return limit; } else if (number < limit && amt < 0) { return limit; } } return number + amt; } function getExponentialProgression(number, progression, valueConvert) { let limit = valueConvert && progression.limit ? valueConvert(progression.limit) : progression.limit; if (limit !== void 0) { if (number > limit && progression.percentage > 0) { return limit; } else if (number < limit && progression.percentage < 0) { return limit; } } return number + number * progression.percentage; } // src/classes/ticker/MoveTicker.ts var MoveTicker = class extends TickerBase { fn(ticker, args, tags, tickerId) { let xSpeed = 1; let ySpeed = 1; if (args.speed) { if (typeof args.speed === "number") { xSpeed = this.speedConvert(args.speed); ySpeed = this.speedConvert(args.speed); } else { xSpeed = this.speedConvert(args.speed.x); ySpeed = this.speedConvert(args.speed.y); } } let destination = args.destination; let tagToRemoveAfter2 = args.tagToRemoveAfter || []; if (typeof tagToRemoveAfter2 === "string") { tagToRemoveAfter2 = [tagToRemoveAfter2]; } tags.filter((tag) => { var _a; let element = GameWindowManager.getCanvasElement(tag); if (args.startOnlyIfHaveTexture) { if (element && element instanceof pixi_js.Sprite && ((_a = element.texture) == null ? void 0 : _a.label) == "EMPTY") { return false; } } return true; }).forEach((tag) => { let element = GameWindowManager.getCanvasElement(tag); if (element && element instanceof pixi_js.Container) { let xDistance = destination.x - element.x > 0 ? 1 : -1; if (xDistance != 0) { element.x += xDistance * xSpeed * ticker.deltaTime; let newDistance = destination.x - element.x; if (xDistance < 0 && newDistance > 0 || xDistance > 0 && newDistance < 0) { element.x = destination.x; } } let yDistance = destination.y - element.y > 0 ? 1 : -1; if (yDistance != 0) { element.y += yDistance * ySpeed * ticker.deltaTime; let newDistance = destination.y - element.y; if (yDistance < 0 && newDistance > 0 || yDistance > 0 && newDistance < 0) { element.y = destination.y; } } if (element.x == destination.x && element.y == destination.y) { GameWindowManager.onEndOfTicker(tag, this, tagToRemoveAfter2, tickerId); } } }); if (args.speedProgression) updateTickerProgression(args, "speed", args.speedProgression, this.speedConvert); } speedConvert(speed) { return speed / 6; } }; MoveTicker = __decorateClass([ tickerDecorator() ], MoveTicker); var RotateTicker = class extends TickerBase { fn(ticker, args, tags, tickerId) { let speed = this.speedConvert(args.speed === void 0 ? 1 : args.speed); let clockwise = args.clockwise === void 0 ? true : args.clockwise; let tagToRemoveAfter2 = args.tagToRemoveAfter || []; if (typeof tagToRemoveAfter2 === "string") { tagToRemoveAfter2 = [tagToRemoveAfter2]; } tags.filter((tag) => { var _a; let element = GameWindowManager.getCanvasElement(tag); if (args.startOnlyIfHaveTexture) { if (element && element instanceof pixi_js.Sprite && ((_a = element.texture) == null ? void 0 : _a.label) == "EMPTY") { return false; } } return true; }).forEach((tag) => { let element = GameWindowManager.getCanvasElement(tag); if (element && element instanceof pixi_js.Container) { if (clockwise) element.rotation += speed * ticker.deltaTime; else element.rotation -= speed * ticker.deltaTime; if (speed < 1e-5 && !(args.speedProgression && args.speedProgression.type == "linear" && args.speedProgression.amt != 0)) { GameWindowManager.onEndOfTicker(tag, this, tagToRemoveAfter2, tickerId); } } }); if (args.speedProgression) updateTickerProgression(args, "speed", args.speedProgression, this.speedConvert); } speedConvert(speed) { return speed / 60; } }; RotateTicker = __decorateClass([ tickerDecorator() ], RotateTicker); var ZoomTicker = class extends TickerBase { fn(ticker, args, tags, tickerId) { let xSpeed = 0.1; let ySpeed = 0.1; if (args.speed) { if (typeof args.speed === "number") { xSpeed = this.speedConvert(args.speed); ySpeed = this.speedConvert(args.speed); } else { xSpeed = this.speedConvert(args.speed.x); ySpeed = this.speedConvert(args.speed.y); } } let tagToRemoveAfter2 = args.tagToRemoveAfter || []; if (typeof tagToRemoveAfter2 === "string") { tagToRemoveAfter2 = [tagToRemoveAfter2]; } let type = args.type || "zoom"; let xLimit = type === "zoom" ? Infinity : 0; let yLimit = type === "zoom" ? Infinity : 0; if (args.limit) { if (typeof args.limit === "number") { xLimit = args.limit; yLimit = args.limit; } else { xLimit = args.limit.x; yLimit = args.limit.y; } } tags.filter((tag) => { var _a; let element = GameWindowManager.getCanvasElement(tag); if (args.startOnlyIfHaveTexture) { if (element && element instanceof pixi_js.Sprite && ((_a = element.texture) == null ? void 0 : _a.label) == "EMPTY") { return false; } } return true; }).forEach((tag) => { let element = GameWindowManager.getCanvasElement(tag); if (element && element instanceof pixi_js.Container) { if (type === "zoom" && (element.scale.x < xLimit || element.scale.y < yLimit)) { element.scale.x += xSpeed * ticker.deltaTime; element.scale.y += ySpeed * ticker.deltaTime; } else if (type === "unzoom" && (element.scale.x > xLimit || element.scale.y > yLimit)) { element.scale.x -= xSpeed * ticker.deltaTime; element.scale.y -= ySpeed * ticker.deltaTime; } if (type === "zoom") { if (element.scale.x > xLimit) { element.scale.x = xLimit; } if (element.scale.y > yLimit) { element.scale.y = yLimit; } if (element.scale.x >= xLimit && element.scale.y >= yLimit) { element.scale.x = xLimit; element.scale.y = yLimit; this.onEndOfTicker(tag, tickerId, element, tagToRemoveAfter2); } } else if (type === "unzoom") { if (element.scale.x < xLimit) { element.scale.x = xLimit; } if (element.scale.y < yLimit) { element.scale.y = yLimit; } if (element.scale.x <= xLimit && element.scale.y <= yLimit) { element.scale.x = xLimit; element.scale.y = yLimit; this.onEndOfTicker(tag, tickerId, element, tagToRemoveAfter2); } } if (xSpeed < 1e-5 && ySpeed < 1e-5 && !(args.speedProgression && args.speedProgression.type == "linear" && args.speedProgression.amt != 0)) { this.onEndOfTicker(tag, tickerId, element, tagToRemoveAfter2); } } }); if (args.speedProgression) updateTickerProgression(args, "speed", args.speedProgression, this.speedConvert); } speedConvert(speed) { return speed / 60; } onEndOfTicker(tag, tickerId, _element, tagToRemoveAfter2) { GameWindowManager.onEndOfTicker(tag, this, tagToRemoveAfter2, tickerId); } }; ZoomTicker = __decorateClass([ tickerDecorator() ], ZoomTicker); var ZoomInOutTicker = class extends ZoomTicker { constructor(props, duration, priority) { super(props, duration, priority); } onEndOfTicker(tag, tickerId, element, tagToRemoveAfter2) { if (element.children.length > 0) { let elementChild = element.children[0]; GameWindowManager.addCanvasElement(tag, elementChild); } super.onEndOfTicker(tag, tickerId, element, tagToRemoveAfter2); } }; // src/constants.ts var PIXIVN_VERSION = "0.6.14"; var Repeat = "repeat"; function Pause(duration) { return { type: "pause", duration }; } // src/functions/ImageUtility.ts function addImage(tag, imageUrl) { let image = new CanvasImage(); image.imageLink = imageUrl; GameWindowManager.addCanvasElement(tag, image); return image; } function loadImage(canvasImages) { return __async(this, null, function* () { if (!Array.isArray(canvasImages)) { return [canvasImages]; } let promises = Array(canvasImages.length); for (let i = 0; i < canvasImages.length; i++) { promises[i] = getTexture(canvasImages[i].imageLink); } return Promise.all(promises).then((textures) => { return textures.map((texture, index) => { if (texture) { canvasImages[index].texture = texture; return canvasImages[index]; } canvasImages[index].load(); return canvasImages[index]; }); }); }); } function removeCanvasElement(tag) { GameWindowManager.removeCanvasElement(tag); } function showWithDissolveTransition(_0, _1) { return __async(this, arguments, function* (tag, image, props = {}, priority) { var _a; let oldCanvasTag = void 0; if (GameWindowManager.getCanvasElement(tag)) { oldCanvasTag = tag + "_temp_disolve"; GameWindowManager.editCanvasElementTag(tag, oldCanvasTag); } let canvasElement; if (typeof image === "string") { canvasElement = addImage(tag, image); } else { canvasElement = image; GameWindowManager.addCanvasElement(tag, canvasElement); } if (canvasElement instanceof CanvasImage && ((_a = canvasElement.texture) == null ? void 0 : _a.label) == "EMPTY") { yield canvasElement.load(); } canvasElement.alpha = 0; let effect = new FadeAlphaTicker(__spreadProps(__spreadValues({}, props), { type: "show", tagToRemoveAfter: oldCanvasTag, startOnlyIfHaveTexture: true }), 10, priority); GameWindowManager.addTicker(tag, effect); return; }); } function removeWithDissolveTransition(tag, props = {}, priority) { if (typeof tag === "string") { tag = [tag]; } let effect = new FadeAlphaTicker(__spreadProps(__spreadValues({}, props), { type: "hide", tagToRemoveAfter: tag, startOnlyIfHaveTexture: true }), 10, priority); GameWindowManager.addTicker(tag, effect); } function showWithFadeTransition(_0, _1) { return __async(this, arguments, function* (tag, image, props = {}, priority) { var _a; if (!GameWindowManager.getCanvasElement(tag)) { return showWithDissolveTransition(tag, image, props, priority); } let oldCanvasTag = tag + "_temp_fade"; GameWindowManager.editCanvasElementTag(tag, oldCanvasTag); let canvasElement; if (typeof image === "string") { canvasElement = addImage(tag, image); } else { canvasElement = image; GameWindowManager.addCanvasElement(tag, canvasElement); } if (canvasElement instanceof CanvasImage && ((_a = canvasElement.texture) == null ? void 0 : _a.label) == "EMPTY") { yield canvasElement.load(); } canvasElement.alpha = 0; GameWindowManager.addTickersSteps(oldCanvasTag, [ new FadeAlphaTicker(__spreadProps(__spreadValues({}, props), { type: "hide", startOnlyIfHaveTexture: true })) ]); GameWindowManager.addTickersSteps(tag, [ Pause(props.duration || 1), new FadeAlphaTicker(__spreadProps(__spreadValues({}, props), { type: "show", startOnlyIfHaveTexture: true })) ]); }); } function removeWithFadeTransition(tag, props = {}, priority) { return removeWithDissolveTransition(tag, props, priority); } function moveIn(_0, _1) { return __async(this, arguments, function* (tag, image, props = { direction: "right" }, priority) { var _a; let canvasElement; if (typeof image === "string") { canvasElement = addImage(tag, image); } else { canvasElement = image; GameWindowManager.addCanvasElement(tag, canvasElement); } if (canvasElement instanceof CanvasImage && ((_a = canvasElement.texture) == null ? void 0 : _a.label) == "EMPTY") { yield canvasElement.load(); } let destination = { x: canvasElement.x, y: canvasElement.y }; if (props.direction == "up") { canvasElement.y = GameWindowManager.canvasHeight + canvasElement.height; } else if (props.direction == "down") { canvasElement.y = -canvasElement.height; } else if (props.direction == "left") { canvasElement.x = GameWindowManager.canvasWidth + canvasElement.width; } else if (props.direction == "right") { canvasElement.x = -canvasElement.width; } let effect = new MoveTicker(__spreadProps(__spreadValues({}, props), { destination, startOnlyIfHaveTexture: true }), priority); GameWindowManager.addTicker(tag, effect); }); } function moveOut(tag, props = { direction: "right" }, priority) { let canvasElement = GameWindowManager.getCanvasElement(tag); if (!canvasElement) { console.warn("[Pixi'VN] The canvas element is not found."); return; } let destination = { x: canvasElement.x, y: canvasElement.y }; if (props.direction == "up") { destination.y = -canvasElement.height; } else if (props.direction == "down") { destination.y = GameWindowManager.canvasHeight + canvasElement.height; } else if (props.direction == "left") { destination.x = -canvasElement.width; } else if (props.direction == "right") { destination.x = GameWindowManager.canvasWidth + canvasElement.width; } let effect = new MoveTicker(__spreadProps(__spreadValues({}, props), { destination, startOnlyIfHaveTexture: true, tagToRemoveAfter: tag }), priority); GameWindowManager.addTicker(tag, effect); } function zoomIn(_0, _1) { return __async(this, arguments, function* (tag, image, props = { direction: "right" }, priority) { var _a; let canvasElement; if (typeof image === "string") { canvasElement = new CanvasImage({}, image); } else { canvasElement = image; } let container = new CanvasContainer(); container.addChild(canvasElement); container.height = GameWindowManager.canvasHeight; container.width = GameWindowManager.canvasWidth; GameWindowManager.addCanvasElement(tag, container); if (canvasElement instanceof CanvasImage && ((_a = canvasElement.texture) == null ? void 0 : _a.label) == "EMPTY") { yield canvasElement.load(); } if (props.direction == "up") { container.pivot.y = GameWindowManager.canvasHeight; container.pivot.x = GameWindowManager.canvasWidth / 2; container.y = GameWindowManager.canvasHeight; container.x = GameWindowManager.canvasWidth / 2; } else if (props.direction == "down") { container.pivot.y = 0; container.pivot.x = GameWindowManager.canvasWidth / 2; container.y = 0; container.x = GameWindowManager.canvasWidth / 2; } else if (props.direction == "left") { container.pivot.x = GameWindowManager.canvasWidth; container.pivot.y = GameWindowManager.canvasHeight / 2; container.x = GameWindowManager.canvasWidth; container.y = GameWindowManager.canvasHeight / 2; } else if (props.direction == "right") { container.pivot.x = 0; container.pivot.y = GameWindowManager.canvasHeight / 2; container.x = 0; container.y = GameWindowManager.canvasHeight / 2; } container.scale.set(0); let effect = new ZoomInOutTicker(__spreadProps(__spreadValues({}, props), { startOnlyIfHaveTexture: true, type: "zoom", limit: 1 }), priority); GameWindowManager.addTicker(tag, effect); }); } function zoomOut(tag, props = { direction: "right" }, priority) { let canvasElement = GameWindowManager.getCanvasElement(tag); if (!canvasElement) { console.warn("[Pixi'VN] The canvas element is not found."); return; } let container = new CanvasContainer(); container.ad