UNPKG

@drincs/pixi-vn

Version:

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

2 lines 18.3 kB
import {a as a$1}from'./chunk-L4IHQ3VT.mjs';import'./chunk-XSN6P5JL.mjs';import {a}from'./chunk-ZW3MIPMS.mjs';import {l,n}from'./chunk-IWAXXFXE.mjs';import {d,c,j,k}from'./chunk-D45QSSXG.mjs';import {GameUnifier,PixiError}from'@drincs/pixi-vn/core';var C=new a({cacheSize:10}),O;(a=>{function h(l){let u=C.get(l);if(!u){j.error(`Label "${l}" not found`);return}return u}a.get=h;function e(l){if(Array.isArray(l)){l.forEach(u=>e(u));return}C.has(l.id)&&j.info(`Label "${l.id}" already exists, it will be overwritten`),C.set(l.id,l);}a.add=e;function t(){return Array.from(C.values())}a.values=t;function r(l){return C.has(l)}a.has=r;function n(){return Array.from(C.keys())}a.keys=n;})(O||(O={}));var L=O;var i=class i{constructor(){}static get allOpenedLabels(){return GameUnifier.getVariable(l,n.OPENED_LABELS_COUNTER_KEY)||{}}static set allOpenedLabels(e){GameUnifier.setVariable(l,n.OPENED_LABELS_COUNTER_KEY,e);}static getCurrentStepTimesCounterData(e=""){let t=i.currentLabelStepIndex;if(t===null)return j.error("currentLabelStepIndex is null"),null;let r=`${t}${e}`,n$1=i.currentLabelId,a=i._currentLabel;if(!n$1||t===null||!a)return j.error("currentLabelId or currentLabelStepIndex is null or currentLabel not found"),null;let l$1=a.getStepSha(t)||"error",u=GameUnifier.getVariable(l,n.CURRENT_STEP_TIMES_COUNTER_KEY)||{};return u[n$1]||(u[n$1]={}),(!u[n$1][r]||u[n$1][r].stepSha1!=l$1)&&(u[n$1][r]={stepSha1:l$1}),u[n$1][r]}static setCurrentStepTimesCounterData(e="",t){let r=i.currentLabelStepIndex,n$1=r+e,a=i.currentLabelId;if(!a||r===null){j.error("currentLabelId or currentLabelStepIndex is null");return}let l$1=GameUnifier.getVariable(l,n.CURRENT_STEP_TIMES_COUNTER_KEY)||{};l$1[a]||(l$1[a]={}),l$1[a][n$1]=t,GameUnifier.setVariable(l,n.CURRENT_STEP_TIMES_COUNTER_KEY,l$1);}static getCurrentStepTimesCounter(e=""){let t=i._stepCounter,r=i.getCurrentStepTimesCounterData(e);if(!r)return j.error("getCurrentStepTimesCounter obj is null"),0;let n=r.stepCounters||[];return n.find(l=>l===t)||(n.push(t),r.stepCounters=n,i.setCurrentStepTimesCounterData(e,r)),n.length}static getRandomNumber(e,t,r={}){let n=r.nestedId||"";if(r.onceOnly||false){let l=i.getCurrentStepTimesCounterData(n);if(!l)return;let u=l.usedRandomNumbers||{},S=Array.from({length:t-e+1},(R,A)=>A+e).filter(R=>!u[`${e}-${t}`]?.includes(R));if(S.length===0)return;let m=Math.floor(Math.random()*S.length),b=S[m];return u[`${e}-${t}`]||(u[`${e}-${t}`]=[]),u[`${e}-${t}`].push(b),l.usedRandomNumbers=u,i.setCurrentStepTimesCounterData(n,l),b}return Math.floor(Math.random()*(t-e+1))+e}static resetCurrentStepTimesCounter(e=""){let t=i.currentLabelStepIndex,r=t+e,n$1=i.currentLabelId;if(!n$1||t===null){j.error("currentLabelId or currentLabelStepIndex is null");return}let a=GameUnifier.getVariable(l,n.CURRENT_STEP_TIMES_COUNTER_KEY)||{};a[n$1]||(a[n$1]={}),a[n$1][r]={stepCounters:[],stepSha1:""},GameUnifier.setVariable(l,n.CURRENT_STEP_TIMES_COUNTER_KEY,a);}static get allChoicesMade(){return GameUnifier.getVariable(l,n.ALL_CHOICES_MADE_KEY)||[]}static set allChoicesMade(e){GameUnifier.setVariable(l,n.ALL_CHOICES_MADE_KEY,e);}static increaseStepCounter(){i._stepCounter++;}static get openedLabels(){return k(i._openedLabels)}static set openedLabels(e){i._openedLabels=k(e);}static get originalOpenedLabels(){return k(i._originalOpenedLabels)}static set originalOpenedLabels(e){i._originalOpenedLabels=k(e);}static get _currentLabel(){if(i.currentLabelId)return L.get(i.currentLabelId)}static get currentLabelId(){if(i._openedLabels.length>0)return i._openedLabels[i._openedLabels.length-1].label}static get currentLabelStepIndex(){return i._openedLabels.length>0?i._openedLabels[i._openedLabels.length-1].currentStepIndex:null}static addLabelHistory(e,t){let r=i.allOpenedLabels,n=i.allOpenedLabels[e]?.biggestStep||0,a=i.allOpenedLabels[e]?.openCount||0;(!n||n<t)&&(r[e]={biggestStep:t,openCount:a},i.allOpenedLabels=r);}static addChoicesMade(e,t,r,n){let a=i.allChoicesMade,l=a.findIndex(u=>u.labelId===e&&u.stepIndex===t&&u.choiceIndex===n&&u.stepSha1===r);l<0?a.push({labelId:e,stepIndex:t,choiceIndex:n,stepSha1:r,madeTimes:1}):a[l].madeTimes++,i.allChoicesMade=a;}static pushNewLabel(e){if(!L.get(e))throw new PixiError("unregistered_element",`Label ${e} not found`);i._openedLabels.push({label:e,currentStepIndex:0});let r=i.allOpenedLabels,n=i.allOpenedLabels[e]?.biggestStep||0,a=i.allOpenedLabels[e]?.openCount||0;r[e]={biggestStep:n,openCount:a+1},i.allOpenedLabels=r;}static increaseCurrentStepIndex(){if(i._openedLabels.length>0){let e=i._openedLabels[i._openedLabels.length-1];i._openedLabels[i._openedLabels.length-1]={...e,currentStepIndex:e.currentStepIndex+1};}}static set onStepStart(e){i._onStepStart=e;}static get onStepStart(){return async(e,t)=>{let r=[];return i.onLoadingLabel&&e===0&&r.push(i.onLoadingLabel(e,t)),i._onStepStart&&r.push(i._onStepStart(e,t)),await Promise.all(r)}}};d(i,"choiceMadeTemp"),d(i,"lastHistoryStep",null),d(i,"_stepCounter",0),d(i,"_openedLabels",[]),d(i,"_originalOpenedLabels",[]),d(i,"_onStepStart"),d(i,"onLoadingLabel"),d(i,"onStepEnd");var o=i;var _=class{get currentStepTimesCounter(){return o.getCurrentStepTimesCounter()}set currentStepTimesCounter(e){o.resetCurrentStepTimesCounter();}getRandomNumber(e,t,r={}){return o.getRandomNumber(e,t,r)}get stepCounter(){return o._stepCounter}get openedLabels(){return o.openedLabels}get currentLabel(){return o._currentLabel}addStepHistory(e,t={}){let{choiceMade:r,ignoreSameStep:n$1}=t,a,l$1,u,S=GameUnifier.getVariable(l,n.LAST_STEP_GLUED)===this.stepCounter;GameUnifier.getVariable(l,n.LAST_DIALOGUE_ADDED_IN_STEP_MEMORY_KEY)===this.stepCounter&&(a=GameUnifier.getVariable(l,n.CURRENT_DIALOGUE_MEMORY_KEY)),GameUnifier.getVariable(l,n.LAST_MENU_OPTIONS_ADDED_IN_STEP_MEMORY_KEY)===this.stepCounter&&(l$1=GameUnifier.getVariable(l,n.CURRENT_MENU_OPTIONS_MEMORY_KEY)),GameUnifier.getVariable(l,n.LAST_INPUT_ADDED_IN_STEP_MEMORY_KEY)===this.stepCounter&&(u=GameUnifier.getVariable(l,n.CURRENT_INPUT_VALUE_MEMORY_KEY));let m=o.openedLabels,b={currentLabel:o.currentLabelId,dialogue:a,choices:l$1,stepSha1:e,index:this.stepCounter,labelStepIndex:o.currentLabelStepIndex,choiceIndexMade:r,inputValue:u,alreadyMadeChoices:this.alreadyCurrentStepMadeChoices,isGlued:S,openedLabels:m};o.originalOpenedLabels=m,GameUnifier.addHistoryItem(b,{ignoreSameStep:n$1}),o.lastHistoryStep=b,o.increaseStepCounter();}closeCurrentLabel(){if(!o.currentLabelId){j.warn("No label to close");return}if(!this.currentLabel){j.error("currentLabel not found");return}let e=o.openedLabels;e.pop(),o.openedLabels=e,GameUnifier.onLabelClosing(this.openedLabels.length);}closeAllLabels(){for(;o.openedLabels.length>0;)this.closeCurrentLabel(),GameUnifier.onLabelClosing(this.openedLabels.length);}isLabelAlreadyCompleted(e){let t;typeof e=="string"?t=e:t=e.id;let n=o.allOpenedLabels[t]?.biggestStep||0;if(n){let a=L.get(t);if(a)return a.stepCount<=n}return false}get alreadyCurrentStepMadeChoicesObj(){let e=o.currentLabelStepIndex,t=this.currentLabel;if(e===null||!t)return;let r=t.getStepSha(e);return r||(j.warn("stepSha not found, setting to ERROR"),r="error"),o.allChoicesMade.filter(n=>n.labelId===t?.id&&n.stepIndex===e&&n.stepSha1===r)}get alreadyCurrentStepMadeChoices(){return this.alreadyCurrentStepMadeChoicesObj?.map(e=>e.choiceIndex)}get isCurrentStepAlreadyOpened(){let e=o.currentLabelId;if(e){let t=o.allOpenedLabels[e]?.openCount||0;if(o.currentLabelStepIndex&&t>=o.currentLabelStepIndex)return true}return false}getTimesLabelOpened(e){return o.allOpenedLabels[e]?.openCount||0}getTimesChoiceMade(e){return this.alreadyCurrentStepMadeChoicesObj?.find(t=>t.choiceIndex===e)?.madeTimes||0}addCurrentStepToHistory(){this.addStepHistory("dev",{ignoreSameStep:true});}getCanContinue(e){let t=e?.showWarn||false,r=this.choices;return r&&r.length>0?(t&&j.warn("The player must make a choice"),false):this.isRequiredInput?(t&&j.warn("The player must enter a value"),false):true}get canContinue(){return GameUnifier.runningStepsCount!==0?false:this.getCanContinue()}async onStepStart(e,t){let r=[];return e.onStepStart&&r.push(e.onStepStart(t,e)),o.onStepStart&&r.push(o.onStepStart(t,e)),await Promise.all(r)}async onStepEnd(e,t){let r=[];return e.onStepEnd&&r.push(e.onStepEnd(t,e)),o.onStepEnd&&r.push(o.onStepEnd(t,e)),await Promise.all(r)}async continue(e,t={}){let{runNow:r=false,steps:n=1}=t;if(!Number.isFinite(n)){j.warn(`[continue] The parameter steps must be a valid finite number, received: ${n}`);return}if(n<=0){j.warn(`[continue] The parameter steps must be greater than 0, received: ${n}`);return}if(!r&&!this.getCanContinue({showWarn:true}))return;if(!r&&GameUnifier.runningStepsCount!==0){GameUnifier.increaseContinueRequest(n);return}n>1&&GameUnifier.increaseContinueRequest(n-1),GameUnifier.runningStepsCount++;let a;try{GameUnifier.runningStepsCount===1&&await GameUnifier.onPreContinue(),o.increaseCurrentStepIndex(),a=await this.runCurrentStep(e,t);}catch(l){throw j.error("Error continuing",l),l}finally{GameUnifier.runningStepsCount--,a=await this.afterRunCurrentStep(e)||a;}return a}async afterRunCurrentStep(e){if(GameUnifier.runningStepsCount===0&&GameUnifier.continueRequestsCount!==0)return await GameUnifier.processNavigationRequests(e);if(this.openedLabels.length===0){if(GameUnifier.onEnd)return await GameUnifier.onEnd(e,{labelId:"end"});j.error("The end of the game is not managed, so the game is blocked. Read this documentation to know how to manage the end of the game: https://pixi-vn.web.app/start/other-narrative-features.html#how-manage-the-end-of-the-game");}}async runCurrentStep(e,t={}){let{choiceMade:r}=t;if(o.currentLabelId){let n=o.currentLabelStepIndex;if(n===null){j.error("currentLabelStepIndex is null");return}let a=o._currentLabel;if(!a){j.error("currentLabel not found");return}if(a.stepCount>n){try{await this.onStepStart(a,n);}catch(b){j.error("Error running onStepStart",b),this.onStepError&&await this.onStepError(b,e);return}let l=a.getStepById(n);if(!l){j.error("step not found");return}let u=a.getStepSha(n);u||(j.warn("stepSha not found, setting to ERROR"),u="error");let S,m;try{S=await l(e,{labelId:a.id});}catch(b){j.error("Error running step",b),m=b;}try{let b=this.choices;if(b?.length===1&&b[0].autoSelect){let R=b[0];S=await this.selectChoice(R,e);}}catch(b){j.error("Error auto-selecting choice",b),m===void 0&&(m=b);}try{let b=o.lastHistoryStep;r!==void 0&&b&&(u=b.stepSha1,u||(j.warn("stepSha not found, setting to ERROR"),u="error"),o.addChoicesMade(b.currentLabel||"error",typeof b.labelStepIndex=="number"?b.labelStepIndex:-1,b.stepSha1||"error",r),o.choiceMadeTemp=r);}catch(b){j.warn("Error adding choice made to history",b);}try{GameUnifier.runningStepsCount===1&&(o.addLabelHistory(a.id,n),this.addStepHistory(u,{...t,choiceMade:o.choiceMadeTemp}),o.choiceMadeTemp=void 0);}catch(b){j.warn("Error adding step to history",b);}try{this.currentLabel&&await this.onStepEnd(this.currentLabel,o.currentLabelStepIndex||0);}catch(b){j.warn("Error running onStepEnd",b);}return m&&this.onStepError&&await this.onStepError(m,e),S}else {if(this.openedLabels.length>1)return this.closeCurrentLabel(),await this.continue(e,t);if(this.openedLabels.length===1){o.openedLabels=[];return}}}else {if(this.openedLabels.length===0)return;j.error("currentLabelId not found");}}async call(e,t,r){let{choiceMade:n}=r||{},a;typeof e=="string"?a=e:a=e.id,GameUnifier.runningStepsCount++;let l;try{let u=L.get(a);if(!u)throw new PixiError("unregistered_element",`Label ${a} not found`);o.pushNewLabel(u.id),l=await this.runCurrentStep(t,{choiceMade:n});}catch(u){throw j.error("Error calling label",u),u}finally{GameUnifier.runningStepsCount--,l=await this.afterRunCurrentStep(t)||l;}return l}async jump(e,t,r){if(this.stepCounter===0)return await this.call(e,t,r);this.openedLabels.length>0&&this.closeCurrentLabel();let{choiceMade:n}=r||{},a;typeof e=="string"?a=e:a=e.id,GameUnifier.runningStepsCount++;let l;try{let u=L.get(a);if(!u)throw new PixiError("unregistered_element",`Label ${a} not found`);o.pushNewLabel(u.id),l=await this.runCurrentStep(t,{choiceMade:n});}catch(u){throw j.error("Error jumping to label",u),u}finally{GameUnifier.runningStepsCount--,l=await this.afterRunCurrentStep(t)||l;}return l}async selectChoice(e,t){this.choices=void 0;let r=e.type;switch(r){case "call":return await this.call(e.label,{...e.props,...t},{choiceMade:e.choiceIndex});case "jump":return await this.jump(e.label,{...e.props,...t},{choiceMade:e.choiceIndex});case "close":return await this.closeChoiceMenu(e,{...e.props,...t});default:throw j.error(`Type ${r} not found`),new PixiError("invalid_usage",`Type ${r} not found`)}}async closeChoiceMenu(e,t){if(e.type!=="close")throw j.error("For closeChoiceMenu, the type must be close"),new PixiError("invalid_usage","For closeChoiceMenu, the type must be close");let r;return typeof e.choiceIndex=="number"&&(r=e.choiceIndex),e.closeCurrentLabel&&this.closeCurrentLabel(),await this.continue(t,{choiceMade:r})}get onStepError(){return async(e,t)=>{try{await GameUnifier.runOnError(e,t);}catch(r){j.error("Error in onError handler",r);}}}get dialogue(){let e=GameUnifier.getVariable(l,n.CURRENT_DIALOGUE_MEMORY_KEY);if(e)return {...e,character:e.character?GameUnifier.getCharacter(e.character)||e.character:void 0}}set dialogue(e){if(e===void 0){GameUnifier.setVariable(l,n.CURRENT_DIALOGUE_MEMORY_KEY,void 0);return}if((typeof e=="string"||Array.isArray(e))&&(e={text:e}),this.dialogGlue){let t=GameUnifier.getVariable(l,n.CURRENT_DIALOGUE_MEMORY_KEY);if(t){let r=[];Array.isArray(t.text)?r=[...t.text]:r=[t.text],Array.isArray(e.text)?r=[...r,...e.text]:r=[...r,e.text],e.text=r,e.character=e.character||t.character;}GameUnifier.setVariable(l,n.LAST_STEP_GLUED,this.stepCounter),this.dialogGlue=false;}try{GameUnifier.setVariable(l,n.CURRENT_DIALOGUE_MEMORY_KEY,k({...e,character:typeof e.character=="string"?e.character:e.character?.id})),GameUnifier.setVariable(l,n.LAST_DIALOGUE_ADDED_IN_STEP_MEMORY_KEY,this.stepCounter);}catch{throw j.error("DialogueInterface cannot contain functions or classes"),new PixiError("not_json_serializable","ChoiceInterface cannot contain functions or classes")}}get choices(){let e=GameUnifier.getVariable(l,n.CURRENT_MENU_OPTIONS_MEMORY_KEY);if(e){let t=[],r=e.map((a,l)=>({...a,choiceIndex:l})),n=this.alreadyCurrentStepMadeChoices;if(r=r.filter((a,l)=>a.oneTime&&n&&n.includes(l)?false:a.onlyHaveNoChoice?(t.push(a),false):true),r.length>0)return r;if(t.length>0)return [t[0]]}}set choices(e){if(!e||e.length===0){GameUnifier.setVariable(l,n.CURRENT_MENU_OPTIONS_MEMORY_KEY,void 0);return}try{GameUnifier.setVariable(l,n.CURRENT_MENU_OPTIONS_MEMORY_KEY,k(e)),GameUnifier.setVariable(l,n.LAST_MENU_OPTIONS_ADDED_IN_STEP_MEMORY_KEY,this.stepCounter);}catch{throw j.error("ChoiceInterface cannot contain functions or classes"),new PixiError("not_json_serializable","ChoiceInterface cannot contain functions or classes")}}get dialogGlue(){return GameUnifier.getFlag(n.ADD_NEXT_DIALOG_TEXT_INTO_THE_CURRENT_DIALOG_FLAG_KEY)}set dialogGlue(e){GameUnifier.setFlag(n.ADD_NEXT_DIALOG_TEXT_INTO_THE_CURRENT_DIALOG_FLAG_KEY,e);}get inputValue(){return GameUnifier.getVariable(l,n.CURRENT_INPUT_VALUE_MEMORY_KEY)}set inputValue(e){this.removeInputRequest(),GameUnifier.setVariable(l,n.CURRENT_INPUT_VALUE_MEMORY_KEY,e),GameUnifier.setVariable(l,n.LAST_INPUT_ADDED_IN_STEP_MEMORY_KEY,this.stepCounter);}get isRequiredInput(){return GameUnifier.getVariable(l,n.CURRENT_INPUT_INFO_MEMORY_KEY)?.isRequired||false}get inputType(){return GameUnifier.getVariable(l,n.CURRENT_INPUT_INFO_MEMORY_KEY)?.type}requestInput(e,t){e.isRequired=true,GameUnifier.setVariable(l,n.CURRENT_INPUT_INFO_MEMORY_KEY,e),t!==void 0?GameUnifier.setVariable(l,n.CURRENT_INPUT_VALUE_MEMORY_KEY,t):GameUnifier.removeVariable(l,n.CURRENT_INPUT_VALUE_MEMORY_KEY);}removeInputRequest(){GameUnifier.removeVariable(l,n.CURRENT_INPUT_INFO_MEMORY_KEY),GameUnifier.removeVariable(l,n.CURRENT_INPUT_VALUE_MEMORY_KEY);}clear(){o.openedLabels=[],o._stepCounter=0;}export(){return {openedLabels:k(o.openedLabels),stepCounter:this.stepCounter}}async onLoadingLabel(e){let t=this.openedLabels.map(async r=>{let n=[],a=L.get(r.label);return a&&(a.onLoadingLabel&&n.push(a.onLoadingLabel(e,a)),o.onLoadingLabel&&n.push(o.onLoadingLabel(e,a))),await Promise.all(n)});return await Promise.all(t)}async restore(e,t){this.clear();try{o.lastHistoryStep=t,e.hasOwnProperty("openedLabels")?(o.openedLabels=e.openedLabels,o.originalOpenedLabels=o.openedLabels):j.warn("Could not import openedLabels data, so will be ignored"),e.hasOwnProperty("stepCounter")?o._stepCounter=e.stepCounter:j.warn("Could not import stepCounter data, so will be ignored");try{await this.onLoadingLabel(o.currentLabelStepIndex||0);}catch(r){j.error("Error running onLoadingLabel",r);}}catch(r){j.error("Error importing data",r);}}};function Y(h,e,t,r){let n=typeof e=="string"?e:e.id;return {...r,label:n,props:t,text:h,type:r?.type||"call"}}var M="close";function V(h,e){return {...e,type:M,text:h}}var N=c(a$1(),1);var I=class{constructor(e,t){d(this,"id");d(this,"_onStepStart");d(this,"_onLoadingLabel");d(this,"_onStepEnd");this.id=e,this._onStepStart=t?.onStepStart,this._onLoadingLabel=t?.onLoadingLabel,this._onStepEnd=t?.onStepEnd;}get onStepStart(){return async(e,t)=>{if(this._onLoadingLabel&&e===0&&await this._onLoadingLabel(e,t),this._onStepStart)return await this._onStepStart(e,t)}}get onLoadingLabel(){return this._onLoadingLabel}get onStepEnd(){return this._onStepEnd}};var E=class extends I{constructor(t,r,n){super(t,n);d(this,"_steps");this._steps=r;}get stepCount(){return this.steps.length}getStepById(t){return this.steps[t]}get steps(){return typeof this._steps=="function"?this._steps():this._steps}getStepSha(t){if(t<0||t>=this.steps.length)return j.warn("stepSha not found, setting to ERROR"),"error";try{let r=this.steps[t];return (0,N.default)(r.toString().toLocaleLowerCase()).toString()}catch(r){return j.warn("stepSha not found, setting to ERROR",r),"error"}}};function w(h,e,t){let r=new E(h,e,t);return L.add(r),r}var Te=new _; export{M as Close,E as Label,I as LabelAbstract,o as NarrationManagerStatic,L as RegisteredLabels,Te as narration,Y as newChoiceOption,V as newCloseChoiceOption,w as newLabel};