narrat 2.3.4 → 2.3.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/narrat.es.js +2 -4
- package/dist/narrat.es.js.map +1 -1
- package/dist/narrat.umd.js +1 -1
- package/dist/narrat.umd.js.map +1 -1
- package/package.json +1 -1
package/dist/narrat.umd.js
CHANGED
|
@@ -206,7 +206,7 @@ Only state can be modified.`);a[0]="$state",Uu=!1,r.set(o,a,r.state.value),Uu=!0
|
|
|
206
206
|
Found in store "${S.$id}".`),p&&o&&n.hydrate&&n.hydrate(S.$state,p),l=!0,f=!0,S}function qi(t,e,n){let r,i;const o=typeof e=="function";typeof t=="string"?(r=t,i=o?n:e):(i=t,r=t.id);function a(s,u){const l=w.getCurrentInstance();if(s=(process.env.NODE_ENV==="test"&&Ec&&Ec._testing?null:s)||l&&w.inject(rI),s&&Oc(s),process.env.NODE_ENV!=="production"&&!Ec)throw new Error(`[\u{1F34D}]: getActivePinia was called with no active Pinia. Did you forget to install pinia?
|
|
207
207
|
const pinia = createPinia()
|
|
208
208
|
app.use(pinia)
|
|
209
|
-
This will fail in production.`);s=Ec,s._s.has(r)||(o?Ny(r,e,i,s):gI(r,i,s),process.env.NODE_ENV!=="production"&&(a._pinia=s));const f=s._s.get(r);if(process.env.NODE_ENV!=="production"&&u){const c="__hot:"+r,d=o?Ny(c,e,i,s,!0):gI(c,fo({},i),s,!0);u._hotUpdate(d),delete s.state.value[c],s._s.delete(c)}if(process.env.NODE_ENV!=="production"&&Ja&&l&&l.proxy&&!u){const c=l.proxy,d="_pStores"in c?c._pStores:c._pStores={};d[r]=f}return f}return a.$id=r,a}function Wo(t,e){return Array.isArray(e)?e.reduce((n,r)=>(n[r]=function(){return t(this.$pinia)[r]},n),{}):Object.keys(e).reduce((n,r)=>(n[r]=function(){const i=t(this.$pinia),o=e[r];return typeof o=="function"?o.call(this,i):i[o]},n),{})}const yI=["music","ambiant","sound"],Py=_Y(yI),$r=qi("audio",{state:()=>{const t=new Map;for(const e in Py)t.set(e,{channels:[],options:{volume:1}});return{modes:t,masterVolume:1}},actions:{stopAll(){this.modes.forEach(t=>{t.channels.forEach((e,n)=>{e&&(this.actuallyStopChannel(e),t.channels[n]=null)})})},async stopChannel(t,e){const n=this.getAudioChannel(t,e);if(!!n){if(this.setAudioChannel(t,e,null),ft().audioOptions.musicFadeOutTime){const r=Gu(n.audio);r&&r.fade(r.volume(n.howlerId),0,ft().audioOptions.musicFadeOutTime*1e3,n.howlerId),await lo(ft().audioOptions.musicFadeOutTime*1e3)}this.actuallyStopChannel(n)}},async pauseChannel(t,e){const n=this.getAudioChannel(t,e);if(!n)return;const r=Gu(n.audio);if(!r){_n(`Could not find audio ${n.audio}`);return}r.pause(n.howlerId)},async playChannel(t,e,n){const r=this.getAudioChannel(t,n);if(t==="sound")return this.actuallyPlayChannel(t,n,e);r&&r.audio!==e?await this.changeChannel(t,e,n):r&&r.audio===e||await this.actuallyPlayChannel(t,n,e)},async changeChannel(t,e,n){this.getAudioChannel(t,n)&&t!=="sound"&&await this.stopChannel(t,n),await this.actuallyPlayChannel(t,n,e)},actuallyStopChannel(t){eX(t.audio,t.howlerId)},getAudioChannel(t,e){return this.modes.get(t).channels[e]||null},setAudioChannel(t,e,n){this.modes.get(t).channels[e]=n},async actuallyPlayChannel(t,e,n){const r=Gu(n);if(!r){_n(`Could not find audio ${n}`);return}if(t!=="sound"){const i=r.play();r.volume(0,i),r.pause(i),this.setAudioChannel(t,e,{audio:n,howlerId:i}),await lo(ft().audioOptions.musicFadeInDelay*1e3);const o=this.getAudioChannel(t,e);o!==null&&o.audio===n&&(r.play(i),r.fade(0,this.modeVolume(t),ft().audioOptions.musicFadeInTime*1e3,i))}else if(t==="sound"){const i=r.play();r.volume(this.modeVolume(t),i),this.setAudioChannel(t,e,{audio:n,howlerId:i})}},reloadAudio(t){for(const e in t.modes){if(e==="sound")continue;const n=e;this.modes.get(n).options=t.modes[n].options;for(const r in t.modes[n].channels){const i=t.modes[n].channels[r];i&&(this.actuallyPlayChannel(n,Number(r),i.audio),this.setAudioChannel(n,Number(r),i))}}},stopSound(t){const e=Gu(t);e&&e.stop()},generateSaveData(){const t={};for(const e in Py)t[e]=this.modes.get(e);return{modes:t,masterVolume:this.masterVolume}},loadSaveData(t){this.masterVolume=t.masterVolume},reset(){this.stopAll()},setModeVolume(t,e){const n=this.modes.get(t);n.options.volume=e;for(const r in n.channels){const i=n.channels[r];if(i){const o=Gu(i.audio);o&&o.volume(this.modeVolume(t),i.howlerId)}}},setMasterVolume(t){this.masterVolume=t,Ua.Howler.volume(t)},modeVolume(t){return this.masterVolume*this.modes.get(t).options.volume}}}),bI={};Ua.Howler.volume(.5);let Ly={};async function XY(t){Ji.log("Loading audio");const e=[];Ua.Howler.volume(t.audioOptions.volume);for(const n in t.music){const r={loop:!0,...t.music[n]};t.audio[n]=r,console.warn("Music config is deprecated, instead you can now add musics to the `audio` config as they behave the same as other sounds!")}for(const n in t.sound)t.audio[n]=t.sound[n];for(const n in t.audio){const r=t.audio[n];r.src||(r.src=r.path,r.path||console.error(`Audio config for ${n} doesn't have any \`src\` value to find the file`),console.warn("Using `path` for audio and musics is deprecated. Please replace `path` with `src` in your config file!")),e.push(ZY(n,t.audio[n]))}return t.audioTriggers&&(Ly=t.audioTriggers),Promise.all(e)}function Xh(t){Ly[t]&&$r().playChannel("sound",Ly[t],0)}async function ZY(t,e){return new Promise((n,r)=>{Ji.log(`Loading audio ${e.src}`);const i=new Ua.Howl({...e,src:Hu(e.src)});i.load(),bI[t]=i,n()})}function eX(t,e){const n=Gu(t);if(!n){_n(`Could not find music ${t}`);return}n.stop(e)}function Gu(t){return bI[t]}let Dy;function tX(t){Dy=t}function Ry(t){return Dy.characters[t]}function nX(t,e){const n=Ry(t);if(e||(e="default"),n.sprites)return`${Dy.config.imagesPath}${n.sprites[e]}`}function Zh(t){return t?Ry(t).style||{}:{}}const kI={};let wI=0,xI=0;function rX(t){return Ji.log("Loading images"),new Promise((e,n)=>{if(Object.keys(t.images).length<1){e();return}for(const r in t.images){const i=t.images[r];ep(r,i,e,n)}for(const r in t.screens){const i=t.screens[r];if(i.background&&!t.images[i.background]&&ep(i.background,i.background,e,n),i.buttons)for(const o in i.buttons){const a=i.buttons[o];typeof a=="object"&&a.background&&!t.images[a.background]&&ep(a.background,a.background,e,n)}}for(const r in t.buttons){const i=t.buttons[r];typeof i=="object"&&i.background&&!t.images[i.background]&&ep(i.background,i.background,e,n)}})}function ep(t,e,n,r){if(kI[t])return;wI++,Ji.log(`Loading image ${t} at ${e}`);const i=new Image;i.onload=()=>{xI+=1,kI[t]=i,Ji.log(`Loaded image ${t} successfully`),xI>=wI&&(Ji.log("All images loaded"),n())},i.onerror=o=>{_n(`Failed to load image ${t} at ${e}`,o),r(o)},i.src=Hu(e)}function Mc(){return`${Date.now()}-${Math.floor(Math.random()*1e11)}-${Math.floor(Math.random()*1e11)}`}const jI="gameSave",tp="###_--_~=:;_JUMP",By="###_--_~=:;_RETURN",iX="###_--_~=:;_OK",np="###_--_~=:;_STOP";function oX(t){return t===tp||t===By||t===iX||t===np}const aX="2.3.4",sX=new Date("2022-08-05T17:20:36.401Z");function _I(t){if(typeof t=="object"){const e=t;if(e.version||!e.slots)return!0;if(e.slots)return!1}throw new Error("Invalid save file")}const uX=(t,e)=>{const n={};for(const r in t)n[r]=e(t[r]);return n},SI=(t,e)=>{const n={};for(const r in t)e(t[r])&&(n[r]=t[r]);return n},lX="1.3.0";let qn;function Tc(){var t;if(qn)return qn;if(qn)throw new Error("Invalid save file");{const e=localStorage.getItem(jI);if(e&&typeof JSON.parse(e)=="object"){const n=JSON.parse(e);try{if(_I(n))qn={slots:[n],slotsCounter:1};else if(n&&!_I(n))qn=n,qn.slotsCounter=(t=qn.slotsCounter)!=null?t:0;else throw new Error("Invalid save file")}catch{qn={slots:[],slotsCounter:0}}}else qn={slots:[],slotsCounter:0}}return qn.slots=qn.slots.filter(e=>e!==null),qn.slots.forEach((e,n)=>pX(e,n)),qn}function CI(t,e){const n=fX(e);qn.slots[n]?qn.slots[n]=t:(qn.slotsCounter++,qn.slots.push(t)),zy()}function cX(t){qn.lastSaveSlot=t}function zy(){localStorage.setItem(jI,JSON.stringify(qn))}function $I(){return Mc()}function fX(t){return qn.slots.findIndex(e=>e.metadata.id===t)}function rp(t){return qn.slots.find(e=>e.metadata.id===t)}function Fy(){return qn.slots.find(t=>t.metadata.slotType==="auto")}function dX(t){const e=qn.slots.findIndex(n=>n.metadata.id===t);qn.slots.splice(e,1),zy()}function hX(t,e){const n=rp(t);n&&(n.metadata.name=e),zy()}function pX(t,e){if(!!t){if(t.version==="1.0.0"&&(t.metadata={saveDate:new Date().toISOString()},t.version="1.1.0"),t.version==="1.1.0"){const n=t;if(n.audio.currentMusic){const r=AI();r.modes.music.channels[0]={audio:n.audio.currentMusic,howlerId:0},t.audio=r}else t.audio=AI();t.version="1.2.0"}t.version==="1.2.0"&&(t.metadata.name=`Game Save ${e+1}`,t.metadata.slotType="auto",t.metadata.id=Mc(),t.metadata.createdCounter=e,t.version="1.3.0")}}function vX(){return{saveDate:new Date().toISOString(),name:"New Save",slotType:"auto",id:Mc(),createdCounter:qn.slotsCounter+1}}function AI(){var e;return{modes:uX(Py,n=>({channels:[],options:{volume:1}})),masterVolume:(e=ft().audioOptions.volume)!=null?e:1}}var mX=function(e){return gX(e)&&!yX(e)};function gX(t){return!!t&&typeof t=="object"}function yX(t){var e=Object.prototype.toString.call(t);return e==="[object RegExp]"||e==="[object Date]"||wX(t)}var bX=typeof Symbol=="function"&&Symbol.for,kX=bX?Symbol.for("react.element"):60103;function wX(t){return t.$$typeof===kX}function xX(t){return Array.isArray(t)?[]:{}}function Ic(t,e){return e.clone!==!1&&e.isMergeableObject(t)?Ku(xX(t),t,e):t}function jX(t,e,n){return t.concat(e).map(function(r){return Ic(r,n)})}function _X(t,e){if(!e.customMerge)return Ku;var n=e.customMerge(t);return typeof n=="function"?n:Ku}function SX(t){return Object.getOwnPropertySymbols?Object.getOwnPropertySymbols(t).filter(function(e){return t.propertyIsEnumerable(e)}):[]}function EI(t){return Object.keys(t).concat(SX(t))}function OI(t,e){try{return e in t}catch{return!1}}function CX(t,e){return OI(t,e)&&!(Object.hasOwnProperty.call(t,e)&&Object.propertyIsEnumerable.call(t,e))}function $X(t,e,n){var r={};return n.isMergeableObject(t)&&EI(t).forEach(function(i){r[i]=Ic(t[i],n)}),EI(e).forEach(function(i){CX(t,i)||(OI(t,i)&&n.isMergeableObject(e[i])?r[i]=_X(i,n)(t[i],e[i],n):r[i]=Ic(e[i],n))}),r}function Ku(t,e,n){n=n||{},n.arrayMerge=n.arrayMerge||jX,n.isMergeableObject=n.isMergeableObject||mX,n.cloneUnlessOtherwiseSpecified=Ic;var r=Array.isArray(e),i=Array.isArray(t),o=r===i;return o?r?n.arrayMerge(t,e,n):$X(t,e,n):Ic(e,n)}Ku.all=function(e,n){if(!Array.isArray(e))throw new Error("first argument should be an array");return e.reduce(function(r,i){return Ku(r,i,n)},{})};var AX=Ku,ip=AX;const Uo=qi("hud",{state:()=>({hudStats:{}}),actions:{setupHudStats(t){for(const e in t)this.hudStats[e]={value:t[e].startingValue}},setStat(t,e){this.hudStats[t].value=e},addStat(t,e){this.hudStats[t].value+=e},getStat(t){return this.hudStats[t]},getStatValue(t){return this.hudStats[t].value},generateSaveData(){return{hudStats:this.hudStats}},loadSaveData(t){this.hudStats=ip(this.hudStats,t.hudStats)}}}),Si=qi("notifications",{state:()=>({notifications:{},enabled:!0}),actions:{async addNotification(t){if(!this.enabled)return;t=Wy(t);const e=`${Date.now()}-${Math.random()*1e4}`;this.notifications[e]={text:t},ft().notifications.alsoPrintInDialogue&&HI(`[NOTIFICATION] ${t}`),await lo(ft().notifications.timeOnScreen*1e3),this.deleteNotification(e)},deleteNotification(t){delete this.notifications[t]},disableNotifications(){this.enabled=!1;for(const t in this.notifications)this.deleteNotification(t)},enableNotifications(){this.enabled=!0}}}),kr=qi("inventory",{state:()=>({items:{},interactionTags:{}}),actions:{generateSaveData(){return{items:this.items,interactionTags:this.interactionTags}},loadSaveData(t){this.items={...this.items,...t.items},this.interactionTags={...t.interactionTags}},setupItems(t){Object.keys(t).forEach(e=>{this.items[e]={amount:0,id:e}})},hasItem(t,e){var n;return e||(e=1),((n=this.items[t])==null?void 0:n.amount)>=e},getExistingItem(t){return this.items[t]},getItemAmount(t){var e;return((e=this.getExistingItem(t))==null?void 0:e.amount)||0},add(t){const e=this.getExistingItem(t.id);e?e.amount+=t.amount:this.items[t.id]={...t},Si().addNotification(`Received item: ${Z8(t.id).name} x ${t.amount}`)},enableInteraction(t){t||(t="default"),this.interactionTags[t]={blockedInteraction:!1}},disableInteraction(t){t||(t="default"),this.interactionTags[t]={blockedInteraction:!0}},onScriptStart(){const t=ft().interactionTags;Object.keys(t).forEach(e=>{t[e].onlyInteractOutsideOfScripts&&this.disableInteraction(e)})},onScriptEnd(){const t=ft().interactionTags;Object.keys(t).forEach(e=>{t[e].onlyInteractOutsideOfScripts&&this.enableInteraction(e)})},isInteractionTagBlocked(t){return t||(t="default"),this.interactionTags[t]?this.interactionTags[t].blockedInteraction:!1},remove(t){const e=this.getExistingItem(t.id);e&&(e.amount-=t.amount,Si().addNotification(`Lost item: ${Z8(t.id).name} x ${t.amount}`),e.amount<=0&&this.deleteItem(t.id))},deleteItem(t){this.getExistingItem(t)&&(this.items[t].amount=0)}}}),Fr=qi("quests",{state:()=>({quests:{}}),actions:{getQuest(t){const e=this.quests[t];if(e)return e;{const n=`Quest ${t} doesn't exist!`;throw _n(n),new Error(n)}},getObjective(t,e){const n=this.getQuest(t);if(!n){const o=`Quest ${t} doesn't exist!`;throw _n(o),new Error(o)}const r=n.objectives[e];if(r)return r;const i=`Objective ${e} doesn't exist in quest ${t}!`;throw _n(i),new Error(i)},setupQuests(t){for(const e of Object.keys(t)){const n=t[e];this.quests[e]={id:e,state:"hidden",objectives:{}};for(const r of Object.keys(n.objectives)){const i=n.objectives[r];this.quests[e].objectives[r]={id:r,state:i.hidden?"hidden":"unlocked"}}}},startQuest(t){const e=this.getQuest(t);e?(e.state="unlocked",Si().addNotification(`Started quest: ${Uh(t).title}`)):_n(`Quest ${t} doesn't exist!`)},startObjective(t,e){const n=this.getObjective(t,e);n?(n.state="unlocked",Si().addNotification(`New quest objective: ${$y(t,e).description}`)):_n(`Objective ${e} doesn't exist in quest ${t}!`)},completeObjective(t,e){const n=this.getObjective(t,e);n?(n.state="completed",Si().addNotification(`Completed quest objective: ${$y(t,e).description}`)):_n(`Objective ${e} doesn't exist in quest ${t}!`)},completeQuest(t,e){const n=this.getQuest(t);n?(n.state="completed",n.ending=e,Si().addNotification(`Completed quest: ${Uh(t).title}`)):_n(`Quest ${t} doesn't exist!`)},isQuestCompleted(t){const e=this.getQuest(t);return e?e.state==="completed":!1},isObjectiveCompleted(t,e){const n=this.getObjective(t,e);return n?n.state==="completed":!1},isQuestStarted(t){const e=this.getQuest(t);return e&&e.state==="unlocked"},isObjectiveStarted(t,e){return this.getObjective(t,e).state==="unlocked"},removeQuest(t){delete this.quests[t]},generateSaveData(){return{quests:{...this.quests}}},loadSaveData(t){this.quests=t.quests}}}),ho=qi("screens",{state:()=>({layers:[{screen:"default"}],buttons:{}}),actions:{setScreen(t,e,n){return new Promise(r=>{var s;const i=this.layers[e||0];let o;const a=(s=i==null?void 0:i.screen)!=null?s:null;if(a===t){r();return}n&&(o=Q8(n,a,r)),this.layers[e||0]={screen:t,transition:o},o||r()})},finishTransition(t){const e=this.layers[t];if(!e)_n(`Tried to finish transition on layer ${t} but it doesn't exist`);else if(e.transition){const n=e.transition.resolve;delete e.transition,n()}},transitionScreen(t,e,n){return this.setScreen(t,n!=null?n:0,e)},emptyLayer(t,e){return new Promise(n=>{const r=this.layers[t];if(!r){eZ(`Tried to empty layer ${t} but it doesn't exist`);return}if(e){const i=r.screen,o=Q8(e,i,n);r.transition=o}r.screen=null,e||n()})},setButtons(t){const{buttons:e,screens:n,images:r}=t;for(const i in e)this.buttons[i]={state:e[i].enabled};for(const i in n)if(n[i].buttons){const o=n[i];o.background&&r[o.background]&&(o.background=r[o.background]);for(const a in o.buttons){const s=o.buttons[a];typeof s=="object"&&(e[s.id]=s,o.buttons[a]=s.id,this.buttons[s.id]={state:s.enabled})}}},changeButton(t,e){this.buttons[t].state=e},generateSaveData(){return{layers:this.layers.filter(t=>t).map(t=>{var e;return(e=t.screen)!=null?e:null}),buttons:this.buttons}},loadSaveData(t){this.layers=t.layers.map(e=>({screen:e})),this.buttons=ip(this.buttons,t.buttons)}},getters:{nonEmptyLayers(t){return t.layers.filter(e=>e&&e.screen)}}}),MI=new l1;MI.setupDebugger(!1);const Hi=MI.logger;function EX(t,e,n){const r={fileName:n,currentLine:0,error:(a,s)=>t(r,a,s),processCommandsFunction:Vy,indentSize:0};r.indentSize=RX(r,e);const i=PX(r,e);r.currentLine=0,Hi.log(i);const o={};for(const a of i){a.code.search(":")===-1&&r.error(a.line,"First indentation level should only be used to specify labels");const u=a.code.replace(":","").split(/ +/g),l=u[0],f=u.slice(1);a.branch||r.error(a.line,"This line should have a branch but doesn't"),o[l]={branch:Vy(r,a.branch,void 0),args:f}}return o}function Vy(t,e,n){const r=t.currentLine,i={processCommandsFunction:Vy,parserContext:t,lines:e,currentLine:0,line:e[0]},o=[];if(!e){let a=0;return n&&(a=n.line),t.error(a,"Processing of command failed because the current branch has no lines inside"),[]}for(;i.currentLine<e.length;){const a=e[i.currentLine];i.line=a;const s=TI(t,a,a.expression),u=Hn.commands[s.command.operator];let l=u==null?void 0:u.parser;l||(l=Hn.commands.text.parser),Hi.log(Hn.commands.text);const{newLine:f}=l(i,s);i.currentLine=f,t.currentLine=r+f,o.push(s)}return o}function TI(t,e,n){Hi.log(n),typeof n[0]!="string"&&t.error(e.line,"Expression operator should be a string");const r={code:e.code,fileName:t.fileName,line:e.line,command:{staticOptions:{},commandType:n[0],operator:n[0],args:n.slice(1).map(a=>OX(t,e,a)),options:{}}},i=n[0];if(!Hn.commands[i]){const a=["else","success","failure"];!zX(i)&&!a.includes(i)&&t.error(e.line,`Unknown command ${i}`)}return r}function OX(t,e,n){return Array.isArray(n)?TI(t,e,n):n}function MX(t){return t==="true"?!0:t==="false"?!1:t==="undefined"?void 0:t===null?null:isNaN(Number(t))?t:Number(t)}function TX(t,e){e.charAt(e.length-1)===":"&&(e=e.substr(0,e.length-1));const n=IX(e),[r]=NI(t,n);return r}function IX(t){const e=/(["'])(?:\\\1|.)*?\1/g,n=[];let r;for(;(r=e.exec(t))!=null;)n.push(r);let i=0,o=[];for(const a of n){const s=a.index;if(s>i){const l=t.substr(i,s-i),f=II(l);o=[...o,...f]}const u=a[0].replace(/\\/g,"");o.push(`$$"${u.substring(1,u.length-1)}`),i=s+a[0].length}return o=[...o,...II(t.substr(i))],o.push(")"),o}function II(t){t=t.replace(/: *$/g,"");let e=t.split(" ").filter(n=>n);return e=e.reduce((n,r)=>[...n,...r.split(/(\(|\))/g)].filter(i=>i&&i),[]),e.map(n=>MX(n))}function NI(t,e){Hi.log("===============");let n=[],r=0,i=PI(e)+r,o=qy(e)+r;for(Hi.log(`Parsing expression: ${e}`),Hi.log(`Parenthesis start index: ${i} - end: ${o}`);i!==-1&&o>i;){n=[...n,...e.slice(r,i)];const u=e.slice(i+1);Hi.log(`Found a sub expression. Before: ${n} - After: ${u}`),r=i;const[l,f]=NI(t,u),c=r+f;n.push(l),r=c+1;const d=e.slice(r);Hi.log(`Sub expression came back: ${l} - rest of string: ${d}`),i=PI(d),i!==-1&&(i+=r),o=qy(d),o!==-1&&(o+=r)}o!==-1&&Hi.log("Found parenthesis end before new opening parenthesis, close this expression");const a=qy(e.slice(r))+r;if(a===-1)return t.error(t.currentLine,'Expression is not closed (missing ")" closing parenthesis)'),[n,a];const s=e.slice(r,a);return Hi.log(`End of expression: ${a} - ${s}`),Hi.log("==================="),n=[...n,...s],NX(t,n),[n,a+1]}function NX(t,e){e.length<1&&t.error(t.currentLine,"Expression is empty")}function PI(t){return t.findIndex(e=>e==="(")}function qy(t){return t.findIndex(e=>e===")")}function PX(t,e){const n=e.split(/\r?\n|$/).map(i=>{const o=i.search(/ *\/\//g);return o!==-1?i.substr(0,o):i});return LI(t,n,0,0).lines}function LI(t,e,n,r){let i=!0,o=n;const a=[];for(;i&&!(o>=e.length);){let s=e[o];if(s.search(/^\s*$/)!==-1)o++;else{const u=DX(t,s);if(s=s.substring(u*t.indentSize),LX(t,u,o),u<r)i=!1;else if(u>r){(a.length===0||u-r!==1)&&t.error(o,"Wrong double indentation");const l=LI(t,e,o,u);a[a.length-1].branch=l.lines,o=l.endLine}else{const l=TX(t,s),f={code:s,indentation:u,line:o,expression:l};a.push(f),o++,t.currentLine=o}}}return{lines:a,endLine:o}}function LX(t,e,n){e%1!==0&&t.error(n,`Indentation level of ${e} incorrect. Expected indentation of ${t.indentSize} spaces for this file.`)}function DX(t,e){return e.search(/[^ ]/)/t.indentSize}function RX(t,e){const n=/\n( *)/,r=e.match(n);return!r||r.length<2?(t.error(0,"Can't detect indentation level. Make sure you indent with at least 2 spaces and consistently"),0):(Hi.log(r),r[1].length)}const fn=qi("vm",{state:()=>({stack:[],data:{},lastLabel:"main",script:{},labelStack:["main"],commandsWaitingForPlayerAnswer:[],hasJumped:!1}),actions:{generateSaveData(){return{lastLabel:this.lastLabel,data:this.data}},loadSaveData(t){this.lastLabel=t.lastLabel,this.data=t.data},setReturnValue(t){this.currentFrame.returnValue=t},waitForPlayerAnswer(t){this.commandsWaitingForPlayerAnswer.push(t)},popAnswerQueue(){return this.commandsWaitingForPlayerAnswer.pop()},addScopedVariable(t,e){this.currentFrame&&(this.currentFrame.scope[t]=e)},async loadScripts(t){const e=[];for(const a of t)e.push(K8(Wa(a)));const n=await Promise.all(e),r=Date.now();let i={};for(const a in n){const s=n[a];i={...i,...EX((u,l,f)=>ZX(u,l,f),s,t[a])}}const o=Date.now();Ji.log(`script parsed in ${o-r} ms`),this.setScript(i)},start(){this.setStack({currentIndex:0,branchData:{branch:this.script.main.branch},label:"main"}),this.setStack({currentIndex:0,branchData:{branch:this.script.main.branch},label:"main"})},setLastLabel(t){this.lastLabel=t},reset(){this.stack=[],this.data={},this.hasJumped=!0,this.setStack({currentIndex:0,branchData:{branch:this.script.main.branch},label:"main"})},setScript(t){this.script=t},overrideData(t){this.data=t},setStack(t){this.stack=[];const e=this.frameOptionsToFrame(t);this.lastLabel=t.label,this.stack.push(e)},frameOptionsToFrame(t){const e=t.branchData,n={...t,blocks:[],scope:{},returnValue:null};if(this.addBlock(n,{branchData:e,currentIndex:t.currentIndex}),t.scope&&(n.scope=t.scope),t.args&&t.branchData.args)for(const[r,i]of t.branchData.args.entries())t.args.length>r&&(n.scope[i]=t.args[r]);return n},addBlock(t,e){t.blocks.push(e)},async addAndRunBlock(t){const e=this.currentFrame;if(!e)throw new Error("No frame to add block to");return this.addBlock(e,t),await this.runBlock()},setData(t,e){const n=Qu();DI(n,t,e)},addInstruction(t,e){const n=Qu();RI(n,t,e)},addFrame(t){if(!t.label)if(this.currentFrame)t.label=this.currentFrame.label;else throw new Error("Tried to add a new frame but no label was passed and there is no current frame label");const e=this.frameOptionsToFrame(t);this.stack.push(e)},async addAndRunFrame(t){return await this.addFrame(t),await this.runFrame()},async runFrame(){if(!this.currentFrame)throw new Error("Tried to run a frame but there is no current frame");let e;for(;this.currentBlock;){const n=await this.runBlock();if(n===tp||n===np)return this.cleanFrame(),n;if(n===By)return this.cleanFrame()}return this.cleanFrame(),e},cleanFrame(){const t=this.currentFrame,{returnValue:e}=t;return this.stack.splice(this.stack.length-1,1),e},async runBlock(){const t=this.currentBlock;if(!t)throw new Error("Tried to run a block but there is no current block");let e;for(;this.currentLine;){if(e=await this.runLineOnly(),oX(e))return this.cleanBlock(),e;t.currentIndex++}return this.cleanBlock(),e},cleanBlock(){this.currentFrame.blocks.splice(this.currentFrame.blocks.length-1,1)},async runGame(){let t=await this.runFrame();for(;t===tp;){const e=this.jumpTarget;if(!e){_n("Tried to jump but no target was set");return}this.hasJumped=!0,this.setStack(e),await nn().autoSaveGame({}),t=await this.runFrame()}t!==np&&this.stack.length===0&&this.reachedEndOfScript()},async nextLineOnly(){return this.stack.length===0||this.isBlockFinished()?!1:(this.currentBlock.currentIndex++,!0)},isBlockFinished(){return!this.currentBlock||this.currentBlock&&this.currentBlock.currentIndex>=this.currentBlock.branchData.branch.length},reachedEndOfScript(){if(ft().gameFlow.labelToJumpOnScriptEnd&&this.lastLabel!==ft().gameFlow.labelToJumpOnScriptEnd){this.jumpToLabel(ft().gameFlow.labelToJumpOnScriptEnd);return}if(kr().onScriptEnd(),nn().options.debug){const e=ni();ft().debugging.showScriptFinishedMessage&&e.addDialog({speaker:"game",text:"[DEBUG] Game Script is finished. This is the end of the game flow. This message only appears in debug mode."})}},async runLineOnly(){const t=this.currentLine;if(!t){_n("There is no line of script to run.");return}return kr().onScriptStart(),await WI(t)},async runLabelFunction(t,...e){const n=this.script[t];if(!n){_n(`Tried to run a label that doesn't exist: ${t}`);return}const r={currentIndex:0,branchData:n,label:t,args:e};return this.addAndRunFrame(r)},runCustomFrame(t){this.addAndRunFrame(t)},async jumpToLabel(t,...e){const n=this.script[t];if(!n){_n(`Label ${t} doesn't exist. Is the file with this label added in the list of script files to load in the config?`);return}t!==this.lastLabel&&(this.hasJumped=!0),this.setLastLabel(t),this.setStack({currentIndex:0,branchData:n,args:e,label:t}),await nn().autoSaveGame({}),this.runGame()},async runThenGoBackToPreviousDialog(t,...e){const n=ni(),r=n.dialog[n.dialog.length-1],i=await this.runLabelFunction(t,...e);return n.dialog.push(r),i}},getters:{currentFrame(t){return t.stack[t.stack.length-1]},scope(){var t,e;return(e=(t=this.currentFrame)==null?void 0:t.scope)!=null?e:{}},currentBlock(){const t=this.currentFrame;return t?t.blocks[t.blocks.length-1]:void 0},currentLine(){const t=this.currentBlock;if(t&&t.branchData.branch.length>t.currentIndex)return t.branchData.branch[t.currentIndex]},commandWaitingForAnswer(){if(this.commandsWaitingForPlayerAnswer.length>0)return this.commandsWaitingForPlayerAnswer[0]}}});function Hy(t,e){const n=e.split(".");let r=t;const i=n.length-1;let o=n[0],a=0;for(a=0;a<i;a++)o=n[a],r[o]||(r[o]={}),r=r[o];return o=n[a],[r,o]}function BX(t,e){const n=e.split(".");let r=t;const i=n.length-1;let o=n[0],a=0;for(a=0;a<i;a++)o=n[a],r[o]||(r[o]={}),r=r[o];return o=n[a],typeof r[o]>"u"&&(r[o]=null),[r,o]}function DI(t,e,n){const[r,i]=Hy(t,e);r[i]=n}function RI(t,e,n){const[r,i]=Hy(t,e),o=r[i]||0;r[i]=n+o}function Qu(){const t=fn(),e=pr(),n=ho(),r=kr(),i=fn().scope,o={data:t.data,skills:e.skills,buttons:n.buttons,items:r.items,quests:Fr().quests,stats:Uo().hudStats,scope:i,config:ft(),gameOptions:nn().options};return new Proxy(o,{get:(s,u,l)=>{const f=fn().scope,c=fn().data;return typeof f[u]<"u"?f[u]:typeof c[u]<"u"?c[u]:Reflect.get(s,u,l)},set:(s,u,l,f)=>{const c=fn().scope,d=fn().data;if(typeof c[u]<"u")c[u]=l;else{if(typeof s[u]<"u")return Reflect.set(s,u,l,f);typeof l=="object"?d[u]={}:d[u]=l}return!0}})}function Wy(t){return t.replace(/%{[^}]*}/g,e=>{const n=e.substr(2,e.length-3),r=Qu(),[i,o]=Hy(r,n);return i[o]})}const BI=/\$\$"/,zX=t=>typeof t=="string"&&t.search(BI)===0,ni=qi("dialog",{state:()=>({dialog:[]}),actions:{generateSaveData(){return{dialog:this.dialog}},loadSaveData(t){this.dialog=t.dialog},addDialog(t){var e;this.dialog.push({...t,interactive:(e=t.interactive)!=null?e:!1,id:Mc(),text:Wy(t.text)})},clearDialog(){this.dialog.splice(0,this.dialog.length)},reset(){this.dialog=[]}},getters:{currentDialog(){return this.dialog[this.dialog.length-1]}}});function FX(t,e){return t-e*ft().skillChecks.skillMultiplier}function zI(t,e){const n=FX(t,e),r=ft().skillChecks;let i=!1,o=0,a=r.difficultyText[0][1];for(;!i;)r.difficultyText.length>o&&n>=r.difficultyText[o][0]?a=r.difficultyText[o][1]:i=!0,o++;return a}function VX({skill:t,skillCheckId:e,value:n}){const r=pr(),i=r.getSkillCheck(e),o=Y8(t),a=r.skills[t].level,s=zI(n,a);let u=!0,l=`<span class='skill-check'>[<span class='skill-check-name'>${o.name}</span> - `;return i.happened?i.succeeded?l="":(u=!1,l+=` <span class='skill-check-difficulty'>${s}</span> - <span class='skill-check-failed'>FAILED</span>]</span>`):l+=` <span class='skill-check-difficulty'>${s}</span>]</span>`,{difficultyText:l,allowed:u}}function qX(t,e){const n=pr(),r=Y8(e.skill),i=zI(e.value,n.skills[e.skill].level);return`<span class='passive-skill-check skill-check'>[<span class='skill-check-name'>${r.name}</span> - <span class='skill-check-difficulty'>${i}</span> - ${t?'<span class="skill-check-success">Success</span>':'<span class="skill-check-failed">Failure</span>'}]</span>`}function HX(t){const{skillChecks:e}=ft(),n=pr(),r=Math.floor(Math.random()*e.rollRange),i=n.skills[t].level*e.skillMultiplier,o=r+i;return Ji.log(`[SKILL CHECK] Roll: ${o}. (Base roll: ${r}, modifier: ${i} - Skill level: ${n.skills[t].level})`),{roll:o,unmodifiedRoll:r}}function WX(t){const{skills:e,skillChecks:n}=ft();let r=!0;const{roll:i}=HX(t.skill);i<=n.failureChance-1&&(r=!1);const o=e[t.skill];return i<t.value&&(r=!1),Ji.log(`[SKILL CHECK ${o.name}]: ${r?"\u2705":"\u274C"}`,`(${t.id}) - ${i}/${t.value}`),Xh(r?"onSkillCheckSuccess":"onSkillCheckFailure"),r}function FI(t){const e=pr(),n=e.getSkillCheck(t.id);if(n&&n.happened)return n;const r=WX(t);return HI(qX(r,t)),r?e.passSkillCheck(t.id,t.hideAfterRoll):e.failSkillCheck(t.id,t.hideAfterRoll),e.getSkillCheck(t.id)}function UX(t){const e=t.options,n=t.staticOptions,r=!!e.condition;if(Ji.log(r),r)return n.success;if(!r&&n.failure)return n.failure}function VI(t){return typeof t=="object"}function qI(t){return typeof t=="string"&&t.search(/\$/)===0}function HI(t){const e={speaker:"game",text:t,interactive:!1};ni().addDialog(e)}async function Uy(t){ni().addDialog(t)}function JX(t,e){if(e<t.length)return t[e]}class GX{constructor(){Ai(this,"plugins",[]);Ai(this,"pinia");Ai(this,"commands",{})}addCommand(e){this.commands[e.keyword]=e}addPlugin(e){if(this.plugins.push(e),e.customCommands)for(const n of e.customCommands)this.addCommand(n)}callHook(e,...n){for(const r of this.plugins)typeof r[e]=="function"&&r[e](...n)}customStores(){const e=[];for(const n of this.plugins)if(n.customStores)for(const r in n.customStores)e.push([r,n.customStores[r](this.pinia)]);return e}}const Hn=new GX;async function WI(t,e){var r;const n=fn();try{return await Jy(t,e)}catch(i){console.error(i),console.error(t),_n(`Narrat script runtime error at <span class="error-filename">${t.fileName}:${t.line+1}</span>
|
|
209
|
+
This will fail in production.`);s=Ec,s._s.has(r)||(o?Ny(r,e,i,s):gI(r,i,s),process.env.NODE_ENV!=="production"&&(a._pinia=s));const f=s._s.get(r);if(process.env.NODE_ENV!=="production"&&u){const c="__hot:"+r,d=o?Ny(c,e,i,s,!0):gI(c,fo({},i),s,!0);u._hotUpdate(d),delete s.state.value[c],s._s.delete(c)}if(process.env.NODE_ENV!=="production"&&Ja&&l&&l.proxy&&!u){const c=l.proxy,d="_pStores"in c?c._pStores:c._pStores={};d[r]=f}return f}return a.$id=r,a}function Wo(t,e){return Array.isArray(e)?e.reduce((n,r)=>(n[r]=function(){return t(this.$pinia)[r]},n),{}):Object.keys(e).reduce((n,r)=>(n[r]=function(){const i=t(this.$pinia),o=e[r];return typeof o=="function"?o.call(this,i):i[o]},n),{})}const yI=["music","ambiant","sound"],Py=_Y(yI),$r=qi("audio",{state:()=>{const t=new Map;for(const e in Py)t.set(e,{channels:[],options:{volume:1}});return{modes:t,masterVolume:1}},actions:{stopAll(){this.modes.forEach(t=>{t.channels.forEach((e,n)=>{e&&(this.actuallyStopChannel(e),t.channels[n]=null)})})},async stopChannel(t,e){const n=this.getAudioChannel(t,e);if(!!n){if(this.setAudioChannel(t,e,null),ft().audioOptions.musicFadeOutTime){const r=Gu(n.audio);r&&r.fade(r.volume(n.howlerId),0,ft().audioOptions.musicFadeOutTime*1e3,n.howlerId),await lo(ft().audioOptions.musicFadeOutTime*1e3)}this.actuallyStopChannel(n)}},async pauseChannel(t,e){const n=this.getAudioChannel(t,e);if(!n)return;const r=Gu(n.audio);if(!r){_n(`Could not find audio ${n.audio}`);return}r.pause(n.howlerId)},async playChannel(t,e,n){const r=this.getAudioChannel(t,n);if(t==="sound")return this.actuallyPlayChannel(t,n,e);r&&r.audio!==e?await this.changeChannel(t,e,n):r&&r.audio===e||await this.actuallyPlayChannel(t,n,e)},async changeChannel(t,e,n){this.getAudioChannel(t,n)&&t!=="sound"&&await this.stopChannel(t,n),await this.actuallyPlayChannel(t,n,e)},actuallyStopChannel(t){eX(t.audio,t.howlerId)},getAudioChannel(t,e){return this.modes.get(t).channels[e]||null},setAudioChannel(t,e,n){this.modes.get(t).channels[e]=n},async actuallyPlayChannel(t,e,n){const r=Gu(n);if(!r){_n(`Could not find audio ${n}`);return}if(t!=="sound"){const i=r.play();r.volume(0,i),r.pause(i),this.setAudioChannel(t,e,{audio:n,howlerId:i}),await lo(ft().audioOptions.musicFadeInDelay*1e3);const o=this.getAudioChannel(t,e);o!==null&&o.audio===n&&(r.play(i),r.fade(0,this.modeVolume(t),ft().audioOptions.musicFadeInTime*1e3,i))}else if(t==="sound"){const i=r.play();r.volume(this.modeVolume(t),i),this.setAudioChannel(t,e,{audio:n,howlerId:i})}},reloadAudio(t){for(const e in t.modes){if(e==="sound")continue;const n=e;this.modes.get(n).options=t.modes[n].options;for(const r in t.modes[n].channels){const i=t.modes[n].channels[r];i&&(this.actuallyPlayChannel(n,Number(r),i.audio),this.setAudioChannel(n,Number(r),i))}}},stopSound(t){const e=Gu(t);e&&e.stop()},generateSaveData(){const t={};for(const e in Py)t[e]=this.modes.get(e);return{modes:t,masterVolume:this.masterVolume}},loadSaveData(t){this.masterVolume=t.masterVolume},reset(){this.stopAll()},setModeVolume(t,e){const n=this.modes.get(t);n.options.volume=e;for(const r in n.channels){const i=n.channels[r];if(i){const o=Gu(i.audio);o&&o.volume(this.modeVolume(t),i.howlerId)}}},setMasterVolume(t){this.masterVolume=t,Ua.Howler.volume(t)},modeVolume(t){return this.masterVolume*this.modes.get(t).options.volume}}}),bI={};Ua.Howler.volume(.5);let Ly={};async function XY(t){Ji.log("Loading audio");const e=[];Ua.Howler.volume(t.audioOptions.volume);for(const n in t.music){const r={loop:!0,...t.music[n]};t.audio[n]=r,console.warn("Music config is deprecated, instead you can now add musics to the `audio` config as they behave the same as other sounds!")}for(const n in t.sound)t.audio[n]=t.sound[n];for(const n in t.audio){const r=t.audio[n];r.src||(r.src=r.path,r.path||console.error(`Audio config for ${n} doesn't have any \`src\` value to find the file`),console.warn("Using `path` for audio and musics is deprecated. Please replace `path` with `src` in your config file!")),e.push(ZY(n,t.audio[n]))}return t.audioTriggers&&(Ly=t.audioTriggers),Promise.all(e)}function Xh(t){Ly[t]&&$r().playChannel("sound",Ly[t],0)}async function ZY(t,e){return new Promise((n,r)=>{Ji.log(`Loading audio ${e.src}`);const i=new Ua.Howl({...e,src:Hu(e.src)});i.load(),bI[t]=i,n()})}function eX(t,e){const n=Gu(t);if(!n){_n(`Could not find music ${t}`);return}n.stop(e)}function Gu(t){return bI[t]}let Dy;function tX(t){Dy=t}function Ry(t){return Dy.characters[t]}function nX(t,e){const n=Ry(t);if(e||(e="default"),n.sprites)return`${Dy.config.imagesPath}${n.sprites[e]}`}function Zh(t){return t?Ry(t).style||{}:{}}const kI={};let wI=0,xI=0;function rX(t){return Ji.log("Loading images"),new Promise((e,n)=>{if(Object.keys(t.images).length<1){e();return}for(const r in t.images){const i=t.images[r];ep(r,i,e,n)}for(const r in t.screens){const i=t.screens[r];if(i.background&&!t.images[i.background]&&ep(i.background,i.background,e,n),i.buttons)for(const o in i.buttons){const a=i.buttons[o];typeof a=="object"&&a.background&&!t.images[a.background]&&ep(a.background,a.background,e,n)}}for(const r in t.buttons){const i=t.buttons[r];typeof i=="object"&&i.background&&!t.images[i.background]&&ep(i.background,i.background,e,n)}})}function ep(t,e,n,r){if(kI[t])return;wI++,Ji.log(`Loading image ${t} at ${e}`);const i=new Image;i.onload=()=>{xI+=1,kI[t]=i,Ji.log(`Loaded image ${t} successfully`),xI>=wI&&(Ji.log("All images loaded"),n())},i.onerror=o=>{_n(`Failed to load image ${t} at ${e}`,o),r(o)},i.src=Hu(e)}function Mc(){return`${Date.now()}-${Math.floor(Math.random()*1e11)}-${Math.floor(Math.random()*1e11)}`}const jI="gameSave",tp="###_--_~=:;_JUMP",By="###_--_~=:;_RETURN",iX="###_--_~=:;_OK",np="###_--_~=:;_STOP";function oX(t){return t===tp||t===By||t===iX||t===np}const aX="2.3.5",sX=new Date("2022-08-05T17:29:07.175Z");function _I(t){if(typeof t=="object"){const e=t;if(e.version||!e.slots)return!0;if(e.slots)return!1}throw new Error("Invalid save file")}const uX=(t,e)=>{const n={};for(const r in t)n[r]=e(t[r]);return n},SI=(t,e)=>{const n={};for(const r in t)e(t[r])&&(n[r]=t[r]);return n},lX="1.3.0";let qn;function Tc(){var t;if(qn)return qn;if(qn)throw new Error("Invalid save file");{const e=localStorage.getItem(jI);if(e&&typeof JSON.parse(e)=="object"){const n=JSON.parse(e);try{if(_I(n))qn={slots:[n],slotsCounter:1};else if(n&&!_I(n))qn=n,qn.slotsCounter=(t=qn.slotsCounter)!=null?t:0;else throw new Error("Invalid save file")}catch{qn={slots:[],slotsCounter:0}}}else qn={slots:[],slotsCounter:0}}return qn.slots=qn.slots.filter(e=>e!==null),qn.slots.forEach((e,n)=>pX(e,n)),qn}function CI(t,e){const n=fX(e);qn.slots[n]?qn.slots[n]=t:(qn.slotsCounter++,qn.slots.push(t)),zy()}function cX(t){qn.lastSaveSlot=t}function zy(){localStorage.setItem(jI,JSON.stringify(qn))}function $I(){return Mc()}function fX(t){return qn.slots.findIndex(e=>e.metadata.id===t)}function rp(t){return qn.slots.find(e=>e.metadata.id===t)}function Fy(){return qn.slots.find(t=>t.metadata.slotType==="auto")}function dX(t){const e=qn.slots.findIndex(n=>n.metadata.id===t);qn.slots.splice(e,1),zy()}function hX(t,e){const n=rp(t);n&&(n.metadata.name=e),zy()}function pX(t,e){if(!!t){if(t.version==="1.0.0"&&(t.metadata={saveDate:new Date().toISOString()},t.version="1.1.0"),t.version==="1.1.0"){const n=t;if(n.audio.currentMusic){const r=AI();r.modes.music.channels[0]={audio:n.audio.currentMusic,howlerId:0},t.audio=r}else t.audio=AI();t.version="1.2.0"}t.version==="1.2.0"&&(t.metadata.name=`Game Save ${e+1}`,t.metadata.slotType="auto",t.metadata.id=Mc(),t.metadata.createdCounter=e,t.version="1.3.0")}}function vX(){return{saveDate:new Date().toISOString(),name:"New Save",slotType:"auto",id:Mc(),createdCounter:qn.slotsCounter+1}}function AI(){var e;return{modes:uX(Py,n=>({channels:[],options:{volume:1}})),masterVolume:(e=ft().audioOptions.volume)!=null?e:1}}var mX=function(e){return gX(e)&&!yX(e)};function gX(t){return!!t&&typeof t=="object"}function yX(t){var e=Object.prototype.toString.call(t);return e==="[object RegExp]"||e==="[object Date]"||wX(t)}var bX=typeof Symbol=="function"&&Symbol.for,kX=bX?Symbol.for("react.element"):60103;function wX(t){return t.$$typeof===kX}function xX(t){return Array.isArray(t)?[]:{}}function Ic(t,e){return e.clone!==!1&&e.isMergeableObject(t)?Ku(xX(t),t,e):t}function jX(t,e,n){return t.concat(e).map(function(r){return Ic(r,n)})}function _X(t,e){if(!e.customMerge)return Ku;var n=e.customMerge(t);return typeof n=="function"?n:Ku}function SX(t){return Object.getOwnPropertySymbols?Object.getOwnPropertySymbols(t).filter(function(e){return t.propertyIsEnumerable(e)}):[]}function EI(t){return Object.keys(t).concat(SX(t))}function OI(t,e){try{return e in t}catch{return!1}}function CX(t,e){return OI(t,e)&&!(Object.hasOwnProperty.call(t,e)&&Object.propertyIsEnumerable.call(t,e))}function $X(t,e,n){var r={};return n.isMergeableObject(t)&&EI(t).forEach(function(i){r[i]=Ic(t[i],n)}),EI(e).forEach(function(i){CX(t,i)||(OI(t,i)&&n.isMergeableObject(e[i])?r[i]=_X(i,n)(t[i],e[i],n):r[i]=Ic(e[i],n))}),r}function Ku(t,e,n){n=n||{},n.arrayMerge=n.arrayMerge||jX,n.isMergeableObject=n.isMergeableObject||mX,n.cloneUnlessOtherwiseSpecified=Ic;var r=Array.isArray(e),i=Array.isArray(t),o=r===i;return o?r?n.arrayMerge(t,e,n):$X(t,e,n):Ic(e,n)}Ku.all=function(e,n){if(!Array.isArray(e))throw new Error("first argument should be an array");return e.reduce(function(r,i){return Ku(r,i,n)},{})};var AX=Ku,ip=AX;const Uo=qi("hud",{state:()=>({hudStats:{}}),actions:{setupHudStats(t){for(const e in t)this.hudStats[e]={value:t[e].startingValue}},setStat(t,e){this.hudStats[t].value=e},addStat(t,e){this.hudStats[t].value+=e},getStat(t){return this.hudStats[t]},getStatValue(t){return this.hudStats[t].value},generateSaveData(){return{hudStats:this.hudStats}},loadSaveData(t){this.hudStats=ip(this.hudStats,t.hudStats)}}}),Si=qi("notifications",{state:()=>({notifications:{},enabled:!0}),actions:{async addNotification(t){if(!this.enabled)return;t=Wy(t);const e=`${Date.now()}-${Math.random()*1e4}`;this.notifications[e]={text:t},ft().notifications.alsoPrintInDialogue&&HI(`[NOTIFICATION] ${t}`),await lo(ft().notifications.timeOnScreen*1e3),this.deleteNotification(e)},deleteNotification(t){delete this.notifications[t]},disableNotifications(){this.enabled=!1;for(const t in this.notifications)this.deleteNotification(t)},enableNotifications(){this.enabled=!0}}}),kr=qi("inventory",{state:()=>({items:{},interactionTags:{}}),actions:{generateSaveData(){return{items:this.items,interactionTags:this.interactionTags}},loadSaveData(t){this.items={...this.items,...t.items},this.interactionTags={...t.interactionTags}},setupItems(t){Object.keys(t).forEach(e=>{this.items[e]={amount:0,id:e}})},hasItem(t,e){var n;return e||(e=1),((n=this.items[t])==null?void 0:n.amount)>=e},getExistingItem(t){return this.items[t]},getItemAmount(t){var e;return((e=this.getExistingItem(t))==null?void 0:e.amount)||0},add(t){const e=this.getExistingItem(t.id);e?e.amount+=t.amount:this.items[t.id]={...t},Si().addNotification(`Received item: ${Z8(t.id).name} x ${t.amount}`)},enableInteraction(t){t||(t="default"),this.interactionTags[t]={blockedInteraction:!1}},disableInteraction(t){t||(t="default"),this.interactionTags[t]={blockedInteraction:!0}},onScriptStart(){const t=ft().interactionTags;Object.keys(t).forEach(e=>{t[e].onlyInteractOutsideOfScripts&&this.disableInteraction(e)})},onScriptEnd(){const t=ft().interactionTags;Object.keys(t).forEach(e=>{t[e].onlyInteractOutsideOfScripts&&this.enableInteraction(e)})},isInteractionTagBlocked(t){return t||(t="default"),this.interactionTags[t]?this.interactionTags[t].blockedInteraction:!1},remove(t){const e=this.getExistingItem(t.id);e&&(e.amount-=t.amount,Si().addNotification(`Lost item: ${Z8(t.id).name} x ${t.amount}`),e.amount<=0&&this.deleteItem(t.id))},deleteItem(t){this.getExistingItem(t)&&(this.items[t].amount=0)}}}),Fr=qi("quests",{state:()=>({quests:{}}),actions:{getQuest(t){const e=this.quests[t];if(e)return e;{const n=`Quest ${t} doesn't exist!`;throw _n(n),new Error(n)}},getObjective(t,e){const n=this.getQuest(t);if(!n){const o=`Quest ${t} doesn't exist!`;throw _n(o),new Error(o)}const r=n.objectives[e];if(r)return r;const i=`Objective ${e} doesn't exist in quest ${t}!`;throw _n(i),new Error(i)},setupQuests(t){for(const e of Object.keys(t)){const n=t[e];this.quests[e]={id:e,state:"hidden",objectives:{}};for(const r of Object.keys(n.objectives)){const i=n.objectives[r];this.quests[e].objectives[r]={id:r,state:i.hidden?"hidden":"unlocked"}}}},startQuest(t){const e=this.getQuest(t);e?(e.state="unlocked",Si().addNotification(`Started quest: ${Uh(t).title}`)):_n(`Quest ${t} doesn't exist!`)},startObjective(t,e){const n=this.getObjective(t,e);n?(n.state="unlocked",Si().addNotification(`New quest objective: ${$y(t,e).description}`)):_n(`Objective ${e} doesn't exist in quest ${t}!`)},completeObjective(t,e){const n=this.getObjective(t,e);n?(n.state="completed",Si().addNotification(`Completed quest objective: ${$y(t,e).description}`)):_n(`Objective ${e} doesn't exist in quest ${t}!`)},completeQuest(t,e){const n=this.getQuest(t);n?(n.state="completed",n.ending=e,Si().addNotification(`Completed quest: ${Uh(t).title}`)):_n(`Quest ${t} doesn't exist!`)},isQuestCompleted(t){const e=this.getQuest(t);return e?e.state==="completed":!1},isObjectiveCompleted(t,e){const n=this.getObjective(t,e);return n?n.state==="completed":!1},isQuestStarted(t){const e=this.getQuest(t);return e&&e.state==="unlocked"},isObjectiveStarted(t,e){return this.getObjective(t,e).state==="unlocked"},removeQuest(t){delete this.quests[t]},generateSaveData(){return{quests:{...this.quests}}},loadSaveData(t){this.quests=t.quests}}}),ho=qi("screens",{state:()=>({layers:[{screen:"default"}],buttons:{}}),actions:{setScreen(t,e,n){return new Promise(r=>{var s;const i=this.layers[e||0];let o;const a=(s=i==null?void 0:i.screen)!=null?s:null;if(a===t){r();return}n&&(o=Q8(n,a,r)),this.layers[e||0]={screen:t,transition:o},o||r()})},finishTransition(t){const e=this.layers[t];if(!e)_n(`Tried to finish transition on layer ${t} but it doesn't exist`);else if(e.transition){const n=e.transition.resolve;delete e.transition,n()}},transitionScreen(t,e,n){return this.setScreen(t,n!=null?n:0,e)},emptyLayer(t,e){return new Promise(n=>{const r=this.layers[t];if(!r){eZ(`Tried to empty layer ${t} but it doesn't exist`);return}if(e){const i=r.screen,o=Q8(e,i,n);r.transition=o}r.screen=null,e||n()})},setButtons(t){const{buttons:e,screens:n,images:r}=t;for(const i in e)this.buttons[i]={state:e[i].enabled};for(const i in n)if(n[i].buttons){const o=n[i];o.background&&r[o.background]&&(o.background=r[o.background]);for(const a in o.buttons){const s=o.buttons[a];typeof s=="object"&&(e[s.id]=s,o.buttons[a]=s.id,this.buttons[s.id]={state:s.enabled})}}},changeButton(t,e){this.buttons[t].state=e},generateSaveData(){return{layers:this.layers.filter(t=>t).map(t=>{var e;return(e=t.screen)!=null?e:null}),buttons:this.buttons}},loadSaveData(t){this.layers=t.layers.map(e=>({screen:e})),this.buttons=ip(this.buttons,t.buttons)}},getters:{nonEmptyLayers(t){return t.layers.filter(e=>e)}}}),MI=new l1;MI.setupDebugger(!1);const Hi=MI.logger;function EX(t,e,n){const r={fileName:n,currentLine:0,error:(a,s)=>t(r,a,s),processCommandsFunction:Vy,indentSize:0};r.indentSize=RX(r,e);const i=PX(r,e);r.currentLine=0,Hi.log(i);const o={};for(const a of i){a.code.search(":")===-1&&r.error(a.line,"First indentation level should only be used to specify labels");const u=a.code.replace(":","").split(/ +/g),l=u[0],f=u.slice(1);a.branch||r.error(a.line,"This line should have a branch but doesn't"),o[l]={branch:Vy(r,a.branch,void 0),args:f}}return o}function Vy(t,e,n){const r=t.currentLine,i={processCommandsFunction:Vy,parserContext:t,lines:e,currentLine:0,line:e[0]},o=[];if(!e){let a=0;return n&&(a=n.line),t.error(a,"Processing of command failed because the current branch has no lines inside"),[]}for(;i.currentLine<e.length;){const a=e[i.currentLine];i.line=a;const s=TI(t,a,a.expression),u=Hn.commands[s.command.operator];let l=u==null?void 0:u.parser;l||(l=Hn.commands.text.parser),Hi.log(Hn.commands.text);const{newLine:f}=l(i,s);i.currentLine=f,t.currentLine=r+f,o.push(s)}return o}function TI(t,e,n){Hi.log(n),typeof n[0]!="string"&&t.error(e.line,"Expression operator should be a string");const r={code:e.code,fileName:t.fileName,line:e.line,command:{staticOptions:{},commandType:n[0],operator:n[0],args:n.slice(1).map(a=>OX(t,e,a)),options:{}}},i=n[0];if(!Hn.commands[i]){const a=["else","success","failure"];!zX(i)&&!a.includes(i)&&t.error(e.line,`Unknown command ${i}`)}return r}function OX(t,e,n){return Array.isArray(n)?TI(t,e,n):n}function MX(t){return t==="true"?!0:t==="false"?!1:t==="undefined"?void 0:t===null?null:isNaN(Number(t))?t:Number(t)}function TX(t,e){e.charAt(e.length-1)===":"&&(e=e.substr(0,e.length-1));const n=IX(e),[r]=NI(t,n);return r}function IX(t){const e=/(["'])(?:\\\1|.)*?\1/g,n=[];let r;for(;(r=e.exec(t))!=null;)n.push(r);let i=0,o=[];for(const a of n){const s=a.index;if(s>i){const l=t.substr(i,s-i),f=II(l);o=[...o,...f]}const u=a[0].replace(/\\/g,"");o.push(`$$"${u.substring(1,u.length-1)}`),i=s+a[0].length}return o=[...o,...II(t.substr(i))],o.push(")"),o}function II(t){t=t.replace(/: *$/g,"");let e=t.split(" ").filter(n=>n);return e=e.reduce((n,r)=>[...n,...r.split(/(\(|\))/g)].filter(i=>i&&i),[]),e.map(n=>MX(n))}function NI(t,e){Hi.log("===============");let n=[],r=0,i=PI(e)+r,o=qy(e)+r;for(Hi.log(`Parsing expression: ${e}`),Hi.log(`Parenthesis start index: ${i} - end: ${o}`);i!==-1&&o>i;){n=[...n,...e.slice(r,i)];const u=e.slice(i+1);Hi.log(`Found a sub expression. Before: ${n} - After: ${u}`),r=i;const[l,f]=NI(t,u),c=r+f;n.push(l),r=c+1;const d=e.slice(r);Hi.log(`Sub expression came back: ${l} - rest of string: ${d}`),i=PI(d),i!==-1&&(i+=r),o=qy(d),o!==-1&&(o+=r)}o!==-1&&Hi.log("Found parenthesis end before new opening parenthesis, close this expression");const a=qy(e.slice(r))+r;if(a===-1)return t.error(t.currentLine,'Expression is not closed (missing ")" closing parenthesis)'),[n,a];const s=e.slice(r,a);return Hi.log(`End of expression: ${a} - ${s}`),Hi.log("==================="),n=[...n,...s],NX(t,n),[n,a+1]}function NX(t,e){e.length<1&&t.error(t.currentLine,"Expression is empty")}function PI(t){return t.findIndex(e=>e==="(")}function qy(t){return t.findIndex(e=>e===")")}function PX(t,e){const n=e.split(/\r?\n|$/).map(i=>{const o=i.search(/ *\/\//g);return o!==-1?i.substr(0,o):i});return LI(t,n,0,0).lines}function LI(t,e,n,r){let i=!0,o=n;const a=[];for(;i&&!(o>=e.length);){let s=e[o];if(s.search(/^\s*$/)!==-1)o++;else{const u=DX(t,s);if(s=s.substring(u*t.indentSize),LX(t,u,o),u<r)i=!1;else if(u>r){(a.length===0||u-r!==1)&&t.error(o,"Wrong double indentation");const l=LI(t,e,o,u);a[a.length-1].branch=l.lines,o=l.endLine}else{const l=TX(t,s),f={code:s,indentation:u,line:o,expression:l};a.push(f),o++,t.currentLine=o}}}return{lines:a,endLine:o}}function LX(t,e,n){e%1!==0&&t.error(n,`Indentation level of ${e} incorrect. Expected indentation of ${t.indentSize} spaces for this file.`)}function DX(t,e){return e.search(/[^ ]/)/t.indentSize}function RX(t,e){const n=/\n( *)/,r=e.match(n);return!r||r.length<2?(t.error(0,"Can't detect indentation level. Make sure you indent with at least 2 spaces and consistently"),0):(Hi.log(r),r[1].length)}const fn=qi("vm",{state:()=>({stack:[],data:{},lastLabel:"main",script:{},labelStack:["main"],commandsWaitingForPlayerAnswer:[],hasJumped:!1}),actions:{generateSaveData(){return{lastLabel:this.lastLabel,data:this.data}},loadSaveData(t){this.lastLabel=t.lastLabel,this.data=t.data},setReturnValue(t){this.currentFrame.returnValue=t},waitForPlayerAnswer(t){this.commandsWaitingForPlayerAnswer.push(t)},popAnswerQueue(){return this.commandsWaitingForPlayerAnswer.pop()},addScopedVariable(t,e){this.currentFrame&&(this.currentFrame.scope[t]=e)},async loadScripts(t){const e=[];for(const a of t)e.push(K8(Wa(a)));const n=await Promise.all(e),r=Date.now();let i={};for(const a in n){const s=n[a];i={...i,...EX((u,l,f)=>ZX(u,l,f),s,t[a])}}const o=Date.now();Ji.log(`script parsed in ${o-r} ms`),this.setScript(i)},start(){this.setStack({currentIndex:0,branchData:{branch:this.script.main.branch},label:"main"}),this.setStack({currentIndex:0,branchData:{branch:this.script.main.branch},label:"main"})},setLastLabel(t){this.lastLabel=t},reset(){this.stack=[],this.data={},this.hasJumped=!0,this.setStack({currentIndex:0,branchData:{branch:this.script.main.branch},label:"main"})},setScript(t){this.script=t},overrideData(t){this.data=t},setStack(t){this.stack=[];const e=this.frameOptionsToFrame(t);this.lastLabel=t.label,this.stack.push(e)},frameOptionsToFrame(t){const e=t.branchData,n={...t,blocks:[],scope:{},returnValue:null};if(this.addBlock(n,{branchData:e,currentIndex:t.currentIndex}),t.scope&&(n.scope=t.scope),t.args&&t.branchData.args)for(const[r,i]of t.branchData.args.entries())t.args.length>r&&(n.scope[i]=t.args[r]);return n},addBlock(t,e){t.blocks.push(e)},async addAndRunBlock(t){const e=this.currentFrame;if(!e)throw new Error("No frame to add block to");return this.addBlock(e,t),await this.runBlock()},setData(t,e){const n=Qu();DI(n,t,e)},addInstruction(t,e){const n=Qu();RI(n,t,e)},addFrame(t){if(!t.label)if(this.currentFrame)t.label=this.currentFrame.label;else throw new Error("Tried to add a new frame but no label was passed and there is no current frame label");const e=this.frameOptionsToFrame(t);this.stack.push(e)},async addAndRunFrame(t){return await this.addFrame(t),await this.runFrame()},async runFrame(){if(!this.currentFrame)throw new Error("Tried to run a frame but there is no current frame");let e;for(;this.currentBlock;){const n=await this.runBlock();if(n===tp||n===np)return this.cleanFrame(),n;if(n===By)return this.cleanFrame()}return this.cleanFrame(),e},cleanFrame(){const t=this.currentFrame,{returnValue:e}=t;return this.stack.splice(this.stack.length-1,1),e},async runBlock(){const t=this.currentBlock;if(!t)throw new Error("Tried to run a block but there is no current block");let e;for(;this.currentLine;){if(e=await this.runLineOnly(),oX(e))return this.cleanBlock(),e;t.currentIndex++}return this.cleanBlock(),e},cleanBlock(){this.currentFrame.blocks.splice(this.currentFrame.blocks.length-1,1)},async runGame(){let t=await this.runFrame();for(;t===tp;){const e=this.jumpTarget;if(!e){_n("Tried to jump but no target was set");return}this.hasJumped=!0,this.setStack(e),await nn().autoSaveGame({}),t=await this.runFrame()}t!==np&&this.stack.length===0&&this.reachedEndOfScript()},async nextLineOnly(){return this.stack.length===0||this.isBlockFinished()?!1:(this.currentBlock.currentIndex++,!0)},isBlockFinished(){return!this.currentBlock||this.currentBlock&&this.currentBlock.currentIndex>=this.currentBlock.branchData.branch.length},reachedEndOfScript(){if(ft().gameFlow.labelToJumpOnScriptEnd&&this.lastLabel!==ft().gameFlow.labelToJumpOnScriptEnd){this.jumpToLabel(ft().gameFlow.labelToJumpOnScriptEnd);return}if(kr().onScriptEnd(),nn().options.debug){const e=ni();ft().debugging.showScriptFinishedMessage&&e.addDialog({speaker:"game",text:"[DEBUG] Game Script is finished. This is the end of the game flow. This message only appears in debug mode."})}},async runLineOnly(){const t=this.currentLine;if(!t){_n("There is no line of script to run.");return}return kr().onScriptStart(),await WI(t)},async runLabelFunction(t,...e){const n=this.script[t];if(!n){_n(`Tried to run a label that doesn't exist: ${t}`);return}const r={currentIndex:0,branchData:n,label:t,args:e};return this.addAndRunFrame(r)},runCustomFrame(t){this.addAndRunFrame(t)},async jumpToLabel(t,...e){const n=this.script[t];if(!n){_n(`Label ${t} doesn't exist. Is the file with this label added in the list of script files to load in the config?`);return}t!==this.lastLabel&&(this.hasJumped=!0),this.setLastLabel(t),this.setStack({currentIndex:0,branchData:n,args:e,label:t}),await nn().autoSaveGame({}),this.runGame()},async runThenGoBackToPreviousDialog(t,...e){const n=ni(),r=n.dialog[n.dialog.length-1],i=await this.runLabelFunction(t,...e);return n.dialog.push(r),i}},getters:{currentFrame(t){return t.stack[t.stack.length-1]},scope(){var t,e;return(e=(t=this.currentFrame)==null?void 0:t.scope)!=null?e:{}},currentBlock(){const t=this.currentFrame;return t?t.blocks[t.blocks.length-1]:void 0},currentLine(){const t=this.currentBlock;if(t&&t.branchData.branch.length>t.currentIndex)return t.branchData.branch[t.currentIndex]},commandWaitingForAnswer(){if(this.commandsWaitingForPlayerAnswer.length>0)return this.commandsWaitingForPlayerAnswer[0]}}});function Hy(t,e){const n=e.split(".");let r=t;const i=n.length-1;let o=n[0],a=0;for(a=0;a<i;a++)o=n[a],r[o]||(r[o]={}),r=r[o];return o=n[a],[r,o]}function BX(t,e){const n=e.split(".");let r=t;const i=n.length-1;let o=n[0],a=0;for(a=0;a<i;a++)o=n[a],r[o]||(r[o]={}),r=r[o];return o=n[a],typeof r[o]>"u"&&(r[o]=null),[r,o]}function DI(t,e,n){const[r,i]=Hy(t,e);r[i]=n}function RI(t,e,n){const[r,i]=Hy(t,e),o=r[i]||0;r[i]=n+o}function Qu(){const t=fn(),e=pr(),n=ho(),r=kr(),i=fn().scope,o={data:t.data,skills:e.skills,buttons:n.buttons,items:r.items,quests:Fr().quests,stats:Uo().hudStats,scope:i,config:ft(),gameOptions:nn().options};return new Proxy(o,{get:(s,u,l)=>{const f=fn().scope,c=fn().data;return typeof f[u]<"u"?f[u]:typeof c[u]<"u"?c[u]:Reflect.get(s,u,l)},set:(s,u,l,f)=>{const c=fn().scope,d=fn().data;if(typeof c[u]<"u")c[u]=l;else{if(typeof s[u]<"u")return Reflect.set(s,u,l,f);typeof l=="object"?d[u]={}:d[u]=l}return!0}})}function Wy(t){return t.replace(/%{[^}]*}/g,e=>{const n=e.substr(2,e.length-3),r=Qu(),[i,o]=Hy(r,n);return i[o]})}const BI=/\$\$"/,zX=t=>typeof t=="string"&&t.search(BI)===0,ni=qi("dialog",{state:()=>({dialog:[]}),actions:{generateSaveData(){return{dialog:this.dialog}},loadSaveData(t){this.dialog=t.dialog},addDialog(t){var e;this.dialog.push({...t,interactive:(e=t.interactive)!=null?e:!1,id:Mc(),text:Wy(t.text)})},clearDialog(){this.dialog.splice(0,this.dialog.length)},reset(){this.dialog=[]}},getters:{currentDialog(){return this.dialog[this.dialog.length-1]}}});function FX(t,e){return t-e*ft().skillChecks.skillMultiplier}function zI(t,e){const n=FX(t,e),r=ft().skillChecks;let i=!1,o=0,a=r.difficultyText[0][1];for(;!i;)r.difficultyText.length>o&&n>=r.difficultyText[o][0]?a=r.difficultyText[o][1]:i=!0,o++;return a}function VX({skill:t,skillCheckId:e,value:n}){const r=pr(),i=r.getSkillCheck(e),o=Y8(t),a=r.skills[t].level,s=zI(n,a);let u=!0,l=`<span class='skill-check'>[<span class='skill-check-name'>${o.name}</span> - `;return i.happened?i.succeeded?l="":(u=!1,l+=` <span class='skill-check-difficulty'>${s}</span> - <span class='skill-check-failed'>FAILED</span>]</span>`):l+=` <span class='skill-check-difficulty'>${s}</span>]</span>`,{difficultyText:l,allowed:u}}function qX(t,e){const n=pr(),r=Y8(e.skill),i=zI(e.value,n.skills[e.skill].level);return`<span class='passive-skill-check skill-check'>[<span class='skill-check-name'>${r.name}</span> - <span class='skill-check-difficulty'>${i}</span> - ${t?'<span class="skill-check-success">Success</span>':'<span class="skill-check-failed">Failure</span>'}]</span>`}function HX(t){const{skillChecks:e}=ft(),n=pr(),r=Math.floor(Math.random()*e.rollRange),i=n.skills[t].level*e.skillMultiplier,o=r+i;return Ji.log(`[SKILL CHECK] Roll: ${o}. (Base roll: ${r}, modifier: ${i} - Skill level: ${n.skills[t].level})`),{roll:o,unmodifiedRoll:r}}function WX(t){const{skills:e,skillChecks:n}=ft();let r=!0;const{roll:i}=HX(t.skill);i<=n.failureChance-1&&(r=!1);const o=e[t.skill];return i<t.value&&(r=!1),Ji.log(`[SKILL CHECK ${o.name}]: ${r?"\u2705":"\u274C"}`,`(${t.id}) - ${i}/${t.value}`),Xh(r?"onSkillCheckSuccess":"onSkillCheckFailure"),r}function FI(t){const e=pr(),n=e.getSkillCheck(t.id);if(n&&n.happened)return n;const r=WX(t);return HI(qX(r,t)),r?e.passSkillCheck(t.id,t.hideAfterRoll):e.failSkillCheck(t.id,t.hideAfterRoll),e.getSkillCheck(t.id)}function UX(t){const e=t.options,n=t.staticOptions,r=!!e.condition;if(Ji.log(r),r)return n.success;if(!r&&n.failure)return n.failure}function VI(t){return typeof t=="object"}function qI(t){return typeof t=="string"&&t.search(/\$/)===0}function HI(t){const e={speaker:"game",text:t,interactive:!1};ni().addDialog(e)}async function Uy(t){ni().addDialog(t)}function JX(t,e){if(e<t.length)return t[e]}class GX{constructor(){Ai(this,"plugins",[]);Ai(this,"pinia");Ai(this,"commands",{})}addCommand(e){this.commands[e.keyword]=e}addPlugin(e){if(this.plugins.push(e),e.customCommands)for(const n of e.customCommands)this.addCommand(n)}callHook(e,...n){for(const r of this.plugins)typeof r[e]=="function"&&r[e](...n)}customStores(){const e=[];for(const n of this.plugins)if(n.customStores)for(const r in n.customStores)e.push([r,n.customStores[r](this.pinia)]);return e}}const Hn=new GX;async function WI(t,e){var r;const n=fn();try{return await Jy(t,e)}catch(i){console.error(i),console.error(t),_n(`Narrat script runtime error at <span class="error-filename">${t.fileName}:${t.line+1}</span>
|
|
210
210
|
<b>${i}</b>
|
|
211
211
|
Script: ${t.code}
|
|
212
212
|
Label: ${((r=n.currentFrame)==null?void 0:r.label)||"none"}`)}}async function KX(t,e){const n=t.command,r=Hn.commands[n.commandType];if(r){const i={args:[],options:{},operator:n.operator,staticOptions:n.staticOptions,code:t.code,commandType:n.commandType,fileName:t.fileName,line:t.line},o=r.argTypes;i.options={};for(const[a,s]of n.args.entries()){let u;if(VI(s))u=await Jy(s,e);else if(typeof s=="string")if(s.search(BI)===0)u=s.substring(3);else if(qI(s)){const l=Qu(),f=BX(l,s.substring(1));if(f){const[c,d]=f;u=c[d]}else u=s}else u=s;else u=s;if(i.args.push(u),Array.isArray(o)&&o.length>a){const l=o[a];u!==null&&(i.options[l.name]=u)}}return i}else throw new Error(`${n.commandType} is not a valid command`)}async function Jy(t,e){const n=await KX(t,e),r=Hn.commands[n.commandType];if(r)return await r.run(n,e);throw new Error(`${n.commandType} is not a valid command`)}async function QX(t){Xh("onPlayerAnswered");const e=fn(),n=e.popAnswerQueue(),r=e.currentLine;try{if(n){const i=Hn.commands[n.commandType];if(i)return await i.processPlayerAnswer(n,t)}}catch(i){console.error(i),_n(`Error after player answer at ${r.fileName}:${r.line+1} (${r.code}<br /> - Error: ${i}`)}}const Ga=qi("rendering",{state:()=>({screenHeight:window.innerHeight,screenWidth:window.innerWidth,canvasWidth:window.innerWidth,canvasHeight:window.innerHeight,renderRatio:1,topOffset:0,leftOffset:0,layoutMode:"horizontal"}),actions:{updateScreenSize(t,e,n){this.screenHeight=e,this.screenWidth=t,this.renderRatio=1,this.topOffset=0,this.leftOffset=0,t<ft().layout.verticalLayoutThreshold?this.layoutMode="vertical":this.layoutMode="horizontal"}}});class UI{constructor(){Ai(this,"listeners",{})}on(e,n){return this.listeners[e]||this.addEventToMap(e),this.listeners[e].add(n),n}off(e,n){return this.listeners[e]&&this.listeners[e].delete(n),n}once(e,n){const r=(...i)=>{this.off(e,r),n(...i)};return this.on(e,r)}emit(e,...n){this.listeners[e]&&this.listeners[e].forEach(r=>r(...n))}clear(){Object.keys(this.listeners).forEach(e=>{delete this.listeners[e]})}addEventToMap(e){this.listeners[e]=new Set}}const Ka=qi("menu",{state:()=>({buttons:[],modal:!1}),getters:{showSkills(){return Object.entries(ft().skills).length>0},showInventory(){return Object.entries(ft().items).length>0},showQuests(){return Object.entries(ft().quests).length>0},buttonsToShow(t){return t.buttons.map(e=>{const n=ft().menuButtons[e.id]||{};return{...e,...n}}).filter(e=>e.condition?e.condition():!0)}},actions:{setup(){},addMenuOption(t){this.buttons.push(t)},openModal(t){this.modal=t},closeModal(){this.modal=!1},toggleMenu(){this.modal?this.modal=!1:this.modal="menu"}}});function YX(){return{baseAssetsPath:"",baseDataPath:"",charactersPath:"data/characters.json",configPath:"data/config.json",logging:!1,debug:!1}}class XX extends UI{}const nn=qi("main",{state:()=>({ready:!1,playing:!1,errors:[],playTime:{start:0,previousPlaytime:0},saveSlot:"",flowState:"engine-splash",modal:!1,paused:!1,options:{baseAssetsPath:"",baseDataPath:"",charactersPath:"data/characters.json",configPath:"data/config.json",logging:!1,debug:!1},loading:{step:"Loading",percentage:.1,loaded:!1},alerts:[],saving:null,listener:new XX}),actions:{async setup(){var n;const t=ft(),e=t.scripts;$r().setMasterVolume((n=t.audioOptions.volume)!=null?n:1),await fn().loadScripts(e),Ka().setup();for(const[,r]of Hn.customStores())if(r.setup){const i=r.setup();SY(i)&&await i}this.resetAllStores()},async engineLoading(){this.loading.step="Characters";const t=await fa(this.options.charactersPath);await tX(t),this.loading.percentage=.2,this.loading.step="Data",this.loading.percentage=.3,this.loading.step="Images",await rX(ft()),this.loading.percentage=.7,this.loading.step="Audio",await XY(ft()),Hn.callHook("onAssetsLoaded"),this.loading.percentage=.95,this.loading.step="Starting...",await this.setup(),Hn.callHook("onGameSetup"),this.loading.loaded=!0,this.listener.emit("gameLoaded")},async alert(t,e){return new Promise(n=>{this.alerts.push({title:t,text:e,resolver:n,id:Mc()})})},closeAlert(t){const e=this.alerts.findIndex(n=>n.id===t);e!==-1&&(this.alerts[e].resolver(),this.alerts.splice(e,1))},startMachine(){$r().stopAll(),Xh("onPressStart"),fn().start(),this.ready=!0,this.startPlaying(),Hn.callHook("onGameStart"),this.setFlowState("playing")},setSaveSlot(t){this.saveSlot=t,cX(t)},async startGame(t){if(ft().saves.mode==="manual"){const e=Fy();e&&(t=e.metadata.id)}this.setSaveSlot(t),this.startMachine(),await this.autoSaveGame({slotId:t}),fn().runGame()},async loadGame(t,e){if(ft().saves.mode==="manual"){const n=Fy();n&&(e=n.metadata.id)}if(this.setSaveSlot(e),this.startMachine(),t&&(this.setLoadedData(t),$r().reloadAudio(t.audio),fn().jumpToLabel(t.vm.lastLabel)),ft().saves.mode==="manual"){const n=Fy();n&&this.setSaveSlot(n.metadata.id)}},manualSave({saveName:t,withPrompt:e}){return new Promise(n=>{fn().hasJumped?this.saving={name:t,withPrompt:e,resolver:n}:n()})},finishManualSave(t,e){var n,r;if(!this.saving){_n("Trying to save but there is no saving request!");return}if(!e||!t){this.saving.resolver(),this.saving=null;return}this.saveData?(CI({...this.saveData,main:{...this.saveData.main,playTime:Fc(this.playTime.start,this.playTime.previousPlaytime)},metadata:{...this.saveData.metadata,id:t.slotId,name:(r=(n=this.saving)==null?void 0:n.name)!=null?r:`Manual Save #${Tc().slotsCounter+1}`,slotType:"manual",saveDate:new Date().toISOString(),createdCounter:Tc().slotsCounter+1}},t.slotId),this.alert("Success","Game saved!")):_n("There was no data to save!"),this.saving.resolver(),this.saving=null},playerAnswered(t){QX(t)},menuReturn(){this.reset(),this.setFlowState("menu"),ft().audioOptions.defaultMusic&&$r().playChannel("music",ft().audioOptions.defaultMusic,0)},createError(t){this.errors.push({text:t,type:"error"})},createWarning(t){this.errors.push({text:t,type:"warning"})},clearErrors(){this.errors=[]},setFlowState(t){this.flowState=t},openModal(t){this.modal=t},closeModal(){this.modal=!1},toggleMenu(){this.modal?this.modal=!1:this.modal="menu"},pause(){this.paused=!0},unpause(){this.paused=!1},setOptions(t){this.options=t},startPlaying(){this.playing=!0,this.playTime.start=Date.now()},reset(){this.ready=!1,this.errors=[],this.modal=!1,this.paused=!1,fn().reset(),$r().reset(),this.resetAllStores(),this.playing=!1,this.ready=!0},resetAllStores(){const t=ho(),e=ft();t.setButtons(e),pr().setupSkills(e.skills),Uo().setupHudStats(e.hudStats),kr().setupItems(e.items),Fr().setupQuests(e.quests),Hn.customStores().forEach(([a,s])=>{s.reset&&s.reset()})},generateSaveData(){return{playTime:Fc(this.playTime.start,this.playTime.previousPlaytime)}},loadSaveData(t){this.playTime.previousPlaytime=t.playTime},autoSaveGame({slotId:t,name:e}){const n=t!=null?t:this.saveSlot,r=rp(n),i=vX();r?(i.name=r.metadata.name,i.slotType=r.metadata.slotType):i.name=e!=null?e:`Autosave ${Tc().slotsCounter+1}`,ft().saves.mode==="manual"&&(i.name="Autosave",i.createdCounter=0),i.id=n;const o=ho(),a=pr(),s=ni(),u=fn(),l=nn(),f=Uo(),c=$r(),d=kr(),h={version:lX,screen:o.generateSaveData(),skills:a.generateSaveData(),dialog:s.generateSaveData(),vm:u.generateSaveData(),main:l.generateSaveData(),hud:f.generateSaveData(),audio:c.generateSaveData(),inventory:d.generateSaveData(),quests:Fr().generateSaveData(),metadata:i};Hn.customStores().forEach(([p,v])=>{if(v.save){const m=v.save();m&&(h[p]=m)}}),this.saveData=h,CI(h,this.saveSlot)},setLoadedData(t){const e=ho(),n=pr(),r=ni(),i=fn(),o=nn(),a=Uo(),s=$r(),u=kr();e.loadSaveData(t.screen),n.loadSaveData(t.skills),r.loadSaveData(t.dialog),i.loadSaveData(t.vm),o.loadSaveData(t.main),a.loadSaveData(t.hud),s.loadSaveData(t.audio),u.loadSaveData(t.inventory),Fr().loadSaveData(t.quests),Hn.customStores().forEach(([l,f])=>{f.load&&f.load(t[l])})},getAllStates(){return{main:this,screens:ho(),skills:pr(),dialog:ni(),vm:fn(),hud:Uo(),audio:$r(),rendering:Ga(),notifications:Si(),inventory:kr(),quests:Fr()}},overrideStates(t){const e=this.getAllStates();for(const n in t){const r=t[n];Object.assign(e[n],r)}}},getters:{isInGame(t){return t.flowState==="playing"}}});function ZX(t,e,n){console.error(`Parser error: ${t.fileName}:${t.currentLine}`,n);const r=`[Parser Error] in <span class="error-filename">${t.fileName}:${e+1}</span> - <b>${n}</b>`;_n(r)}function _n(t,...e){const n=nn();console.error(t,...e),t=t.replace(/[\r\n]/g,`
|