narrat 1.2.1 → 1.3.2

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/lib/index.esm.js CHANGED
@@ -1,4 +1,4 @@
1
- // Version: 1.2.1 - June 25, 2022 14:20:12
1
+ // Version: 1.3.2 - June 26, 2022 18:33:37
2
2
  import 'es6-promise/auto';
3
3
  import { ref, reactive, readonly, defineComponent, openBlock, createElementBlock, normalizeStyle, createElementVNode, createCommentVNode, Fragment, renderList, normalizeClass, createBlock, Transition, withCtx, renderSlot, createTextVNode, computed, resolveComponent, withDirectives, vModelText, toDisplayString, TransitionGroup, createVNode, createApp } from 'vue';
4
4
  import { defineStore, mapState, createPinia } from 'pinia';
@@ -30,7 +30,7 @@ function styleInject(css, ref) {
30
30
  }
31
31
  }
32
32
 
33
- var css_248z = "/*! @import */\n\n/*! modern-normalize v1.0.0 | MIT License | https://github.com/sindresorhus/modern-normalize */\n\n/*\nDocument\n========\n*/\n\n/**\nUse a better box model (opinionated).\n*/\n\n*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\n/**\nUse a more readable tab size (opinionated).\n*/\n\n:root {\n -moz-tab-size: 4;\n -o-tab-size: 4;\n tab-size: 4;\n}\n\n/**\n1. Correct the line height in all browsers.\n2. Prevent adjustments of font size after orientation changes in iOS.\n*/\n\nhtml {\n line-height: 1.15; /* 1 */\n -webkit-text-size-adjust: 100%; /* 2 */\n}\n\n/*\nSections\n========\n*/\n\n/**\nRemove the margin in all browsers.\n*/\n\nbody {\n margin: 0;\n}\n\n/**\nImprove consistency of default fonts in all browsers. (https://github.com/sindresorhus/modern-normalize/issues/3)\n*/\n\nbody {\n font-family:\n\t\tsystem-ui,\n\t\t-apple-system, /* Firefox supports this but not yet `system-ui` */\n\t\t'Segoe UI',\n\t\tRoboto,\n\t\tHelvetica,\n\t\tArial,\n\t\tsans-serif,\n\t\t'Apple Color Emoji',\n\t\t'Segoe UI Emoji';\n}\n\n/*\nGrouping content\n================\n*/\n\n/**\n1. Add the correct height in Firefox.\n2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655)\n*/\n\nhr {\n height: 0; /* 1 */\n color: inherit; /* 2 */\n}\n\n/*\nText-level semantics\n====================\n*/\n\n/**\nAdd the correct text decoration in Chrome, Edge, and Safari.\n*/\n\nabbr[title] {\n -webkit-text-decoration: underline dotted;\n text-decoration: underline dotted;\n}\n\n/**\nAdd the correct font weight in Edge and Safari.\n*/\n\nb,\nstrong {\n font-weight: bolder;\n}\n\n/**\n1. Improve consistency of default fonts in all browsers. (https://github.com/sindresorhus/modern-normalize/issues/3)\n2. Correct the odd 'em' font sizing in all browsers.\n*/\n\ncode,\nkbd,\nsamp,\npre {\n font-family:\n\t\tui-monospace,\n\t\tSFMono-Regular,\n\t\tConsolas,\n\t\t'Liberation Mono',\n\t\tMenlo,\n\t\tmonospace; /* 1 */\n font-size: 1em; /* 2 */\n}\n\n/**\nAdd the correct font size in all browsers.\n*/\n\nsmall {\n font-size: 80%;\n}\n\n/**\nPrevent 'sub' and 'sup' elements from affecting the line height in all browsers.\n*/\n\nsub,\nsup {\n font-size: 75%;\n line-height: 0;\n position: relative;\n vertical-align: baseline;\n}\n\nsub {\n bottom: -0.25em;\n}\n\nsup {\n top: -0.5em;\n}\n\n/*\nTabular data\n============\n*/\n\n/**\n1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297)\n2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016)\n*/\n\ntable {\n text-indent: 0; /* 1 */\n border-color: inherit; /* 2 */\n}\n\n/*\nForms\n=====\n*/\n\n/**\n1. Change the font styles in all browsers.\n2. Remove the margin in Firefox and Safari.\n*/\n\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n font-family: inherit; /* 1 */\n font-size: 100%; /* 1 */\n line-height: 1.15; /* 1 */\n margin: 0; /* 2 */\n}\n\n/**\nRemove the inheritance of text transform in Edge and Firefox.\n1. Remove the inheritance of text transform in Firefox.\n*/\n\nbutton,\nselect { /* 1 */\n text-transform: none;\n}\n\n/**\nCorrect the inability to style clickable types in iOS and Safari.\n*/\n\nbutton,\n[type='button'],\n[type='reset'] {\n -webkit-appearance: button;\n}\n\n/**\nRemove the inner border and padding in Firefox.\n*/\n\n/**\nRestore the focus styles unset by the previous rule.\n*/\n\n/**\nRemove the additional ':invalid' styles in Firefox.\nSee: https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737\n*/\n\n/**\nRemove the padding so developers are not caught out when they zero out 'fieldset' elements in all browsers.\n*/\n\nlegend {\n padding: 0;\n}\n\n/**\nAdd the correct vertical alignment in Chrome and Firefox.\n*/\n\nprogress {\n vertical-align: baseline;\n}\n\n/**\nCorrect the cursor style of increment and decrement buttons in Safari.\n*/\n\n/**\n1. Correct the odd appearance in Chrome and Safari.\n2. Correct the outline style in Safari.\n*/\n\n[type='search'] {\n -webkit-appearance: textfield; /* 1 */\n outline-offset: -2px; /* 2 */\n}\n\n/**\nRemove the inner padding in Chrome and Safari on macOS.\n*/\n\n/**\n1. Correct the inability to style clickable types in iOS and Safari.\n2. Change font properties to 'inherit' in Safari.\n*/\n\n/*\nInteractive\n===========\n*/\n\n/*\nAdd the correct display in Chrome and Safari.\n*/\n\nsummary {\n display: list-item;\n}\n\n/**\n * Manually forked from SUIT CSS Base: https://github.com/suitcss/base\n * A thin layer on top of normalize.css that provides a starting point more\n * suitable for web applications.\n */\n\n/**\n * Removes the default spacing and border for appropriate elements.\n */\n\nblockquote,\ndl,\ndd,\nh1,\nh2,\nh3,\nh4,\nh5,\nh6,\nhr,\nfigure,\np,\npre {\n margin: 0;\n}\n\nbutton {\n background-color: transparent;\n background-image: none;\n}\n\n/**\n * Work around a Firefox/IE bug where the transparent `button` background\n * results in a loss of the default `button` focus styles.\n */\n\nbutton:focus {\n outline: 1px dotted;\n outline: 5px auto -webkit-focus-ring-color;\n}\n\nfieldset {\n margin: 0;\n padding: 0;\n}\n\nol,\nul {\n list-style: none;\n margin: 0;\n padding: 0;\n}\n\n/**\n * Tailwind custom reset styles\n */\n\n/**\n * 1. Use the user's configured `sans` font-family (with Tailwind's default\n * sans-serif font stack as a fallback) as a sane default.\n * 2. Use Tailwind's default \"normal\" line-height so the user isn't forced\n * to override it to ensure consistency even when using the default theme.\n */\n\nhtml {\n font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, \"Noto Sans\", sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\"; /* 1 */\n line-height: 1.5; /* 2 */\n}\n\n/**\n * Inherit font-family and line-height from `html` so users can set them as\n * a class directly on the `html` element.\n */\n\nbody {\n font-family: inherit;\n line-height: inherit;\n}\n\n/**\n * 1. Prevent padding and border from affecting element width.\n *\n * We used to set this in the html element and inherit from\n * the parent element for everything else. This caused issues\n * in shadow-dom-enhanced elements like <details> where the content\n * is wrapped by a div with box-sizing set to `content-box`.\n *\n * https://github.com/mozdevs/cssremedy/issues/4\n *\n *\n * 2. Allow adding a border to an element by just adding a border-width.\n *\n * By default, the way the browser specifies that an element should have no\n * border is by setting it's border-style to `none` in the user-agent\n * stylesheet.\n *\n * In order to easily add borders to elements by just setting the `border-width`\n * property, we change the default border-style for all elements to `solid`, and\n * use border-width to hide them instead. This way our `border` utilities only\n * need to set the `border-width` property instead of the entire `border`\n * shorthand, making our border utilities much more straightforward to compose.\n *\n * https://github.com/tailwindcss/tailwindcss/pull/116\n */\n\n*,\n::before,\n::after {\n box-sizing: border-box; /* 1 */\n border-width: 0; /* 2 */\n border-style: solid; /* 2 */\n border-color: #e5e7eb; /* 2 */\n}\n\n/*\n * Ensure horizontal rules are visible by default\n */\n\nhr {\n border-top-width: 1px;\n}\n\n/**\n * Undo the `border-style: none` reset that Normalize applies to images so that\n * our `border-{width}` utilities have the expected effect.\n *\n * The Normalize reset is unnecessary for us since we default the border-width\n * to 0 on all elements.\n *\n * https://github.com/tailwindcss/tailwindcss/issues/362\n */\n\nimg {\n border-style: solid;\n}\n\ntextarea {\n resize: vertical;\n}\n\ninput::-moz-placeholder, textarea::-moz-placeholder {\n color: #9ca3af;\n}\n\ninput:-ms-input-placeholder, textarea:-ms-input-placeholder {\n color: #9ca3af;\n}\n\ninput::placeholder,\ntextarea::placeholder {\n color: #9ca3af;\n}\n\nbutton {\n cursor: pointer;\n}\n\ntable {\n border-collapse: collapse;\n}\n\nh1,\nh2,\nh3,\nh4,\nh5,\nh6 {\n font-size: inherit;\n font-weight: inherit;\n}\n\n/**\n * Reset links to optimize for opt-in styling instead of\n * opt-out.\n */\n\na {\n color: inherit;\n text-decoration: inherit;\n}\n\n/**\n * Reset form element properties that are easy to forget to\n * style explicitly so you don't inadvertently introduce\n * styles that deviate from your design system. These styles\n * supplement a partial reset that is already applied by\n * normalize.css.\n */\n\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n padding: 0;\n line-height: inherit;\n color: inherit;\n}\n\n/**\n * Use the configured 'mono' font family for elements that\n * are expected to be rendered with a monospace font, falling\n * back to the system monospace stack if there is no configured\n * 'mono' font family.\n */\n\npre,\ncode,\nkbd,\nsamp {\n font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace;\n}\n\n/**\n * Make replaced elements `display: block` by default as that's\n * the behavior you want almost all of the time. Inspired by\n * CSS Remedy, with `svg` added as well.\n *\n * https://github.com/mozdevs/cssremedy/issues/14\n */\n\nimg,\nsvg,\nvideo,\ncanvas,\naudio,\niframe,\nembed,\nobject {\n display: block;\n vertical-align: middle;\n}\n\n/**\n * Constrain images and videos to the parent width and preserve\n * their instrinsic aspect ratio.\n *\n * https://github.com/mozdevs/cssremedy/issues/14\n */\n\nimg,\nvideo {\n max-width: 100%;\n height: auto;\n}\n\n.container {\n width: 100%;\n}\n\n@media (min-width: 640px) {\n .container {\n max-width: 640px;\n }\n}\n\n@media (min-width: 768px) {\n .container {\n max-width: 768px;\n }\n}\n\n@media (min-width: 1024px) {\n .container {\n max-width: 1024px;\n }\n}\n\n@media (min-width: 1280px) {\n .container {\n max-width: 1280px;\n }\n}\n\n@media (min-width: 1536px) {\n .container {\n max-width: 1536px;\n }\n}\n\n.bg-gray-800 {\n --tw-bg-opacity: 1;\n background-color: rgba(31, 41, 55, var(--tw-bg-opacity));\n}\n\n.border {\n border-width: 1px;\n}\n\n.flex {\n display: flex;\n}\n\n.table {\n display: table;\n}\n\n.grid {\n display: grid;\n}\n\n.hidden {\n display: none;\n}\n\n.flex-row {\n flex-direction: row;\n}\n\n.flex-col {\n flex-direction: column;\n}\n\n.flex-grow {\n flex-grow: 1;\n}\n\n.flex-shrink {\n flex-shrink: 1;\n}\n\n.list-disc {\n list-style-type: disc;\n}\n\n.absolute {\n position: absolute;\n}\n\n.resize {\n resize: both;\n}\n\n* {\n --tw-shadow: 0 0 #0000;\n}\n\n* {\n --tw-ring-inset: var(--tw-empty,/*!*/ /*!*/);\n --tw-ring-offset-width: 0px;\n --tw-ring-offset-color: #fff;\n --tw-ring-color: rgba(59, 130, 246, 0.5);\n --tw-ring-offset-shadow: 0 0 #0000;\n --tw-ring-shadow: 0 0 #0000;\n}\n\n.table-auto {\n table-layout: auto;\n}\n\n.line-through {\n text-decoration: line-through;\n}\n\n.w-full {\n width: 100%;\n}\n\n.gap-4 {\n gap: 1rem;\n}\n\n.grid-cols-3 {\n grid-template-columns: repeat(3, minmax(0, 1fr));\n}\n\n.transform {\n --tw-translate-x: 0;\n --tw-translate-y: 0;\n --tw-rotate: 0;\n --tw-skew-x: 0;\n --tw-skew-y: 0;\n --tw-scale-x: 1;\n --tw-scale-y: 1;\n transform: translateX(var(--tw-translate-x)) translateY(var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n\n.transition {\n transition-property: background-color, border-color, color, fill, stroke, opacity, box-shadow, transform;\n transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\n transition-duration: 150ms;\n}\n\n@-webkit-keyframes spin {\n to {\n transform: rotate(360deg);\n }\n}\n\n@keyframes spin {\n to {\n transform: rotate(360deg);\n }\n}\n\n@-webkit-keyframes ping {\n 75%, 100% {\n transform: scale(2);\n opacity: 0;\n }\n}\n\n@keyframes ping {\n 75%, 100% {\n transform: scale(2);\n opacity: 0;\n }\n}\n\n@-webkit-keyframes pulse {\n 50% {\n opacity: .5;\n }\n}\n\n@keyframes pulse {\n 50% {\n opacity: .5;\n }\n}\n\n@-webkit-keyframes bounce {\n 0%, 100% {\n transform: translateY(-25%);\n -webkit-animation-timing-function: cubic-bezier(0.8,0,1,1);\n animation-timing-function: cubic-bezier(0.8,0,1,1);\n }\n\n 50% {\n transform: none;\n -webkit-animation-timing-function: cubic-bezier(0,0,0.2,1);\n animation-timing-function: cubic-bezier(0,0,0.2,1);\n }\n}\n\n@keyframes bounce {\n 0%, 100% {\n transform: translateY(-25%);\n -webkit-animation-timing-function: cubic-bezier(0.8,0,1,1);\n animation-timing-function: cubic-bezier(0.8,0,1,1);\n }\n\n 50% {\n transform: none;\n -webkit-animation-timing-function: cubic-bezier(0,0,0.2,1);\n animation-timing-function: cubic-bezier(0,0,0.2,1);\n }\n}\n\n:root {\n --bg-color: #131720;\n --text-color: #d9e1f2;\n --primary: hsl(255, 30%, 55%);\n --focus: hsl(210, 90%, 50%);\n --secondary: #42b983;\n --border-color: hsla(0, 0%, 100%, 0.2);\n --light-1: hsl(210, 30%, 40%);\n --light-2: hsl(255, 30%, 50%);\n --light-background: linear-gradient(to right, var(--light-1), var(--light-2));\n --shadow-1: hsla(236, 50%, 50%, 0.3);\n --shadow-2: hsla(236, 50%, 50%, 0.4);\n --hud-background: rgba(0, 0, 0, 0.4);\n --hud-text-color: var(--text-color);\n --notifications-bg: darkslateblue;\n --skills-text-background: rgba(0, 0, 0, 0.5);\n --skills-text-color: var(--text-color);\n --skills-level-background: rgba(0, 0, 0, 0.5);\n --skills-level-color: orange;\n --skills-xp-bar-height: 40px;\n --skill-check-name-color: orange;\n --skill-check-difficulty: orange;\n --skill-check-success: green;\n --skill-check-failed: red;\n --skill-check-color: orange;\n --dialog-choice-color: orange;\n --dialog-choice-hover-color: var(--text-color);\n --inventory-text-background: rgba(0, 0, 0, 0.5);\n --inventory-text-color: var(--text-color);\n --inventory-amount-background: rgba(0, 0, 0, 0.5);\n --inventory-amount-color: orange;\n --quest-title-color: yellow;\n --completed-quest-title-color: grey;\n --objective-in-progress-color: white;\n --objective-completed-color: grey;\n}\n\n.list-item {\n display: inline-block;\n margin-right: 10px;\n}\n\n.list-enter-active,\r\n.list-leave-active {\n transition: all 0.3s ease;\n}\n\n/* .list-move {\r\n transition: transform 0.3s ease;\r\n} */\n\n.list-enter-from,\r\n.list-leave-to {\n opacity: 0;\n transform: translateX(300px);\n}\n\n.notification-item {\n display: inline-block;\n margin-right: 10px;\n}\n\n.notification-enter-active,\r\n.notification-leave-active {\n transition: all 0.3s ease;\n}\n\n/* .notification-move {\r\n transition: transform 0.3s ease;\r\n} */\n\n.notification-enter-from,\r\n.notification-leave-to {\n opacity: 0;\n transform: translateY(-300px);\n}\n\n.fade-enter-active,\r\n.fade-leave-active {\n transition: opacity 0.3s ease;\n}\n\n.fade-enter-from,\r\n.fade-leave-to {\n opacity: 0;\n}\n\n.fade-in-enter-active {\n transition: opacity 0.1s ease;\n}\n\n.fade-in-enter-from {\n opacity: 0;\n}\n\nbody {\n padding: 0;\n margin: 0;\n font-family: Arial, sans-serif;\n background-color: black;\n}\n\n.select {\n background: var(--light-background);\n padding: 10px;\n}\n\n.option {\n background-color: var(--light-2);\n padding: 5px;\n color: var(--text-color);\n}\n\n.button {\n background: var(--light-background);\n color: var(--text-color);\n box-shadow: 0.4rem 0.4rem 2.4rem 0.2rem var(--shadow-1);\n border-radius: 100px;\n padding: 10px;\n font-weight: 800;\n font-size: 16px;\n margin: 10px;\n transition: 0.2s;\n}\n\n.button:focus,\r\n.button:hover {\n transform: translateY(-0.2rem);\n box-shadow: 0 0 2.4rem 0.2rem var(--shadow-2);\n}\n\n.input {\n background: var(--light-background);\n color: var(--text-color);\n box-shadow: 0.4rem 0.4rem 2.4rem 0.2rem var(--shadow-1);\n border-radius: 100px;\n padding: 10px;\n font-weight: 800;\n font-size: 16px;\n margin: 10px;\n transition: 0.2s;\n}\n\n.input:focus,\r\n.input:hover {\n transform: translateY(-0.2rem);\n box-shadow: 0 0 2.4rem 0.2rem var(--shadow-2);\n}\n\na {\n color: pink;\n text-decoration: underline;\n}\n\nth,\r\ntd {\n padding: 4px;\n border: 1px solid var(--text-color);\n text-align: center;\n}\n\n#game-holder {\n width: 100vw;\n height: 100vh;\n padding: 0;\n margin: 0;\n top: 0;\n left: 0;\n background-color: black;\n display: flex;\n align-items: center;\n justify-content: center;\n min-height: -webkit-fill-available;\n}\n\n.title {\n font-size: 30px;\n font-weight: 700;\n text-align: center;\n}\n\n.container {\n padding: 20px;\n}\n\nh1,\r\nh2,\r\nh3,\r\nh4 {\n font-weight: 700;\n}\n\nh1 {\n font-size: 30px;\n}\n\nh2 {\n font-size: 26px;\n}\n\nh3 {\n font-size: 24px;\n}\n\nhr.solid {\n border: 1px solid var(--text-color);\n margin-top: 30px;\n margin-bottom: 30px;\n}\n\n.card-1 {\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);\n transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);\n}\n\n.card-1:hover {\n box-shadow: 0 14px 28px rgba(0, 0, 0, 0.25), 0 10px 10px rgba(0, 0, 0, 0.22);\n}\n\n.card-2 {\n box-shadow: 0 3px 6px rgba(0, 0, 0, 0.16), 0 3px 6px rgba(0, 0, 0, 0.23);\n}\n\n.card-3 {\n box-shadow: 0 10px 20px rgba(0, 0, 0, 0.19), 0 6px 6px rgba(0, 0, 0, 0.23);\n}\n\n.card-4 {\n box-shadow: 0 14px 28px rgba(0, 0, 0, 0.25), 0 10px 10px rgba(0, 0, 0, 0.22);\n}\n\n.card-5 {\n box-shadow: 0 19px 38px rgba(0, 0, 0, 0.3), 0 15px 12px rgba(0, 0, 0, 0.22);\n}\n\n.dialog-choice {\n transition: 0.2s;\n}\n\n.dialog-choice:hover {\n transform: scale(1.05, 1.05);\n transform-origin: center;\n}\n\n/* Somewhat arcane CSS to force the hover color to override the child style.\r\nOtherwise hovering choices doesn't change the color of skill check prompts. */\n\n.dialog-choice:not(:hover) > .skill-check-name,\r\n.passive-skill-check > .skill-check-name {\n color: var(--skill-check-name-color);\n}\n\n.dialog-choice:not(:hover) > .skill-check-difficulty,\r\n.passive-skill-check > .skill-check-difficulty {\n color: var(--skill-check-difficulty);\n}\n\n.skill-check-difficulty {\n font-weight: 700;\n}\n\n.dialog-choice:not(:hover) > .skill-check-success,\r\n.passive-skill-check > .skill-check-success {\n color: var(--skill-check-success);\n}\n\n.dialog-choice:not(:hover) > .skill-check-failed,\r\n.passive-skill-check > .skill-check-failed {\n color: var(--skill-check-failed);\n}\n\n.dialog-choice:not(:hover) > .skill-check,\r\n.passive-skill-check.skill-check {\n color: var(--skill-check-color);\n}\n\n.narrat-canvas {\n position: absolute;\n height: 100%;\n top: 0;\n left: 0;\n}\n\n/* Looks ugly */\n\n/* @keyframes strike-anim {\r\n 0% {\r\n width: 0;\r\n }\r\n 100% {\r\n width: 100%;\r\n }\r\n}\r\n.strike-anim {\r\n position: relative;\r\n}\r\n.strike-anim::after {\r\n content: ' ';\r\n position: absolute;\r\n top: 50%;\r\n left: 0;\r\n width: 100%;\r\n height: 1px;\r\n background: var(--text-color);\r\n animation-name: strike-anim;\r\n animation-duration: 0.5s;\r\n animation-timing-function: linear;\r\n animation-iteration-count: 1;\r\n animation-fill-mode: forwards;\r\n} */\n\n#touchTrigger {\n pointer-events: none;\n}\n\n@media (min-width: 640px) {\n}\n\n@media (min-width: 768px) {\n}\n\n@media (min-width: 1024px) {\n}\n\n@media (min-width: 1280px) {\n}\n\n@media (min-width: 1536px) {\n}\r\n";
33
+ var css_248z = "/*! @import */\n\n/*! modern-normalize v1.0.0 | MIT License | https://github.com/sindresorhus/modern-normalize */\n\n/*\nDocument\n========\n*/\n\n/**\nUse a better box model (opinionated).\n*/\n\n*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\n/**\nUse a more readable tab size (opinionated).\n*/\n\n:root {\n -moz-tab-size: 4;\n -o-tab-size: 4;\n tab-size: 4;\n}\n\n/**\n1. Correct the line height in all browsers.\n2. Prevent adjustments of font size after orientation changes in iOS.\n*/\n\nhtml {\n line-height: 1.15; /* 1 */\n -webkit-text-size-adjust: 100%; /* 2 */\n}\n\n/*\nSections\n========\n*/\n\n/**\nRemove the margin in all browsers.\n*/\n\nbody {\n margin: 0;\n}\n\n/**\nImprove consistency of default fonts in all browsers. (https://github.com/sindresorhus/modern-normalize/issues/3)\n*/\n\nbody {\n font-family:\n\t\tsystem-ui,\n\t\t-apple-system, /* Firefox supports this but not yet `system-ui` */\n\t\t'Segoe UI',\n\t\tRoboto,\n\t\tHelvetica,\n\t\tArial,\n\t\tsans-serif,\n\t\t'Apple Color Emoji',\n\t\t'Segoe UI Emoji';\n}\n\n/*\nGrouping content\n================\n*/\n\n/**\n1. Add the correct height in Firefox.\n2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655)\n*/\n\nhr {\n height: 0; /* 1 */\n color: inherit; /* 2 */\n}\n\n/*\nText-level semantics\n====================\n*/\n\n/**\nAdd the correct text decoration in Chrome, Edge, and Safari.\n*/\n\nabbr[title] {\n -webkit-text-decoration: underline dotted;\n text-decoration: underline dotted;\n}\n\n/**\nAdd the correct font weight in Edge and Safari.\n*/\n\nb,\nstrong {\n font-weight: bolder;\n}\n\n/**\n1. Improve consistency of default fonts in all browsers. (https://github.com/sindresorhus/modern-normalize/issues/3)\n2. Correct the odd 'em' font sizing in all browsers.\n*/\n\ncode,\nkbd,\nsamp,\npre {\n font-family:\n\t\tui-monospace,\n\t\tSFMono-Regular,\n\t\tConsolas,\n\t\t'Liberation Mono',\n\t\tMenlo,\n\t\tmonospace; /* 1 */\n font-size: 1em; /* 2 */\n}\n\n/**\nAdd the correct font size in all browsers.\n*/\n\nsmall {\n font-size: 80%;\n}\n\n/**\nPrevent 'sub' and 'sup' elements from affecting the line height in all browsers.\n*/\n\nsub,\nsup {\n font-size: 75%;\n line-height: 0;\n position: relative;\n vertical-align: baseline;\n}\n\nsub {\n bottom: -0.25em;\n}\n\nsup {\n top: -0.5em;\n}\n\n/*\nTabular data\n============\n*/\n\n/**\n1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297)\n2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016)\n*/\n\ntable {\n text-indent: 0; /* 1 */\n border-color: inherit; /* 2 */\n}\n\n/*\nForms\n=====\n*/\n\n/**\n1. Change the font styles in all browsers.\n2. Remove the margin in Firefox and Safari.\n*/\n\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n font-family: inherit; /* 1 */\n font-size: 100%; /* 1 */\n line-height: 1.15; /* 1 */\n margin: 0; /* 2 */\n}\n\n/**\nRemove the inheritance of text transform in Edge and Firefox.\n1. Remove the inheritance of text transform in Firefox.\n*/\n\nbutton,\nselect { /* 1 */\n text-transform: none;\n}\n\n/**\nCorrect the inability to style clickable types in iOS and Safari.\n*/\n\nbutton,\n[type='button'],\n[type='reset'] {\n -webkit-appearance: button;\n}\n\n/**\nRemove the inner border and padding in Firefox.\n*/\n\n/**\nRestore the focus styles unset by the previous rule.\n*/\n\n/**\nRemove the additional ':invalid' styles in Firefox.\nSee: https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737\n*/\n\n/**\nRemove the padding so developers are not caught out when they zero out 'fieldset' elements in all browsers.\n*/\n\nlegend {\n padding: 0;\n}\n\n/**\nAdd the correct vertical alignment in Chrome and Firefox.\n*/\n\nprogress {\n vertical-align: baseline;\n}\n\n/**\nCorrect the cursor style of increment and decrement buttons in Safari.\n*/\n\n/**\n1. Correct the odd appearance in Chrome and Safari.\n2. Correct the outline style in Safari.\n*/\n\n[type='search'] {\n -webkit-appearance: textfield; /* 1 */\n outline-offset: -2px; /* 2 */\n}\n\n/**\nRemove the inner padding in Chrome and Safari on macOS.\n*/\n\n/**\n1. Correct the inability to style clickable types in iOS and Safari.\n2. Change font properties to 'inherit' in Safari.\n*/\n\n/*\nInteractive\n===========\n*/\n\n/*\nAdd the correct display in Chrome and Safari.\n*/\n\nsummary {\n display: list-item;\n}\n\n/**\n * Manually forked from SUIT CSS Base: https://github.com/suitcss/base\n * A thin layer on top of normalize.css that provides a starting point more\n * suitable for web applications.\n */\n\n/**\n * Removes the default spacing and border for appropriate elements.\n */\n\nblockquote,\ndl,\ndd,\nh1,\nh2,\nh3,\nh4,\nh5,\nh6,\nhr,\nfigure,\np,\npre {\n margin: 0;\n}\n\nbutton {\n background-color: transparent;\n background-image: none;\n}\n\n/**\n * Work around a Firefox/IE bug where the transparent `button` background\n * results in a loss of the default `button` focus styles.\n */\n\nbutton:focus {\n outline: 1px dotted;\n outline: 5px auto -webkit-focus-ring-color;\n}\n\nfieldset {\n margin: 0;\n padding: 0;\n}\n\nol,\nul {\n list-style: none;\n margin: 0;\n padding: 0;\n}\n\n/**\n * Tailwind custom reset styles\n */\n\n/**\n * 1. Use the user's configured `sans` font-family (with Tailwind's default\n * sans-serif font stack as a fallback) as a sane default.\n * 2. Use Tailwind's default \"normal\" line-height so the user isn't forced\n * to override it to ensure consistency even when using the default theme.\n */\n\nhtml {\n font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, \"Noto Sans\", sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\"; /* 1 */\n line-height: 1.5; /* 2 */\n}\n\n/**\n * Inherit font-family and line-height from `html` so users can set them as\n * a class directly on the `html` element.\n */\n\nbody {\n font-family: inherit;\n line-height: inherit;\n}\n\n/**\n * 1. Prevent padding and border from affecting element width.\n *\n * We used to set this in the html element and inherit from\n * the parent element for everything else. This caused issues\n * in shadow-dom-enhanced elements like <details> where the content\n * is wrapped by a div with box-sizing set to `content-box`.\n *\n * https://github.com/mozdevs/cssremedy/issues/4\n *\n *\n * 2. Allow adding a border to an element by just adding a border-width.\n *\n * By default, the way the browser specifies that an element should have no\n * border is by setting it's border-style to `none` in the user-agent\n * stylesheet.\n *\n * In order to easily add borders to elements by just setting the `border-width`\n * property, we change the default border-style for all elements to `solid`, and\n * use border-width to hide them instead. This way our `border` utilities only\n * need to set the `border-width` property instead of the entire `border`\n * shorthand, making our border utilities much more straightforward to compose.\n *\n * https://github.com/tailwindcss/tailwindcss/pull/116\n */\n\n*,\n::before,\n::after {\n box-sizing: border-box; /* 1 */\n border-width: 0; /* 2 */\n border-style: solid; /* 2 */\n border-color: #e5e7eb; /* 2 */\n}\n\n/*\n * Ensure horizontal rules are visible by default\n */\n\nhr {\n border-top-width: 1px;\n}\n\n/**\n * Undo the `border-style: none` reset that Normalize applies to images so that\n * our `border-{width}` utilities have the expected effect.\n *\n * The Normalize reset is unnecessary for us since we default the border-width\n * to 0 on all elements.\n *\n * https://github.com/tailwindcss/tailwindcss/issues/362\n */\n\nimg {\n border-style: solid;\n}\n\ntextarea {\n resize: vertical;\n}\n\ninput::-moz-placeholder, textarea::-moz-placeholder {\n color: #9ca3af;\n}\n\ninput:-ms-input-placeholder, textarea:-ms-input-placeholder {\n color: #9ca3af;\n}\n\ninput::placeholder,\ntextarea::placeholder {\n color: #9ca3af;\n}\n\nbutton {\n cursor: pointer;\n}\n\ntable {\n border-collapse: collapse;\n}\n\nh1,\nh2,\nh3,\nh4,\nh5,\nh6 {\n font-size: inherit;\n font-weight: inherit;\n}\n\n/**\n * Reset links to optimize for opt-in styling instead of\n * opt-out.\n */\n\na {\n color: inherit;\n text-decoration: inherit;\n}\n\n/**\n * Reset form element properties that are easy to forget to\n * style explicitly so you don't inadvertently introduce\n * styles that deviate from your design system. These styles\n * supplement a partial reset that is already applied by\n * normalize.css.\n */\n\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n padding: 0;\n line-height: inherit;\n color: inherit;\n}\n\n/**\n * Use the configured 'mono' font family for elements that\n * are expected to be rendered with a monospace font, falling\n * back to the system monospace stack if there is no configured\n * 'mono' font family.\n */\n\npre,\ncode,\nkbd,\nsamp {\n font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace;\n}\n\n/**\n * Make replaced elements `display: block` by default as that's\n * the behavior you want almost all of the time. Inspired by\n * CSS Remedy, with `svg` added as well.\n *\n * https://github.com/mozdevs/cssremedy/issues/14\n */\n\nimg,\nsvg,\nvideo,\ncanvas,\naudio,\niframe,\nembed,\nobject {\n display: block;\n vertical-align: middle;\n}\n\n/**\n * Constrain images and videos to the parent width and preserve\n * their instrinsic aspect ratio.\n *\n * https://github.com/mozdevs/cssremedy/issues/14\n */\n\nimg,\nvideo {\n max-width: 100%;\n height: auto;\n}\n\n.container {\n width: 100%;\n}\n\n@media (min-width: 640px) {\n .container {\n max-width: 640px;\n }\n}\n\n@media (min-width: 768px) {\n .container {\n max-width: 768px;\n }\n}\n\n@media (min-width: 1024px) {\n .container {\n max-width: 1024px;\n }\n}\n\n@media (min-width: 1280px) {\n .container {\n max-width: 1280px;\n }\n}\n\n@media (min-width: 1536px) {\n .container {\n max-width: 1536px;\n }\n}\n\n.bg-gray-800 {\n --tw-bg-opacity: 1;\n background-color: rgba(31, 41, 55, var(--tw-bg-opacity));\n}\n\n.border {\n border-width: 1px;\n}\n\n.flex {\n display: flex;\n}\n\n.table {\n display: table;\n}\n\n.grid {\n display: grid;\n}\n\n.hidden {\n display: none;\n}\n\n.flex-row {\n flex-direction: row;\n}\n\n.flex-col {\n flex-direction: column;\n}\n\n.flex-grow {\n flex-grow: 1;\n}\n\n.flex-shrink {\n flex-shrink: 1;\n}\n\n.list-disc {\n list-style-type: disc;\n}\n\n.absolute {\n position: absolute;\n}\n\n.resize {\n resize: both;\n}\n\n* {\n --tw-shadow: 0 0 #0000;\n}\n\n* {\n --tw-ring-inset: var(--tw-empty,/*!*/ /*!*/);\n --tw-ring-offset-width: 0px;\n --tw-ring-offset-color: #fff;\n --tw-ring-color: rgba(59, 130, 246, 0.5);\n --tw-ring-offset-shadow: 0 0 #0000;\n --tw-ring-shadow: 0 0 #0000;\n}\n\n.table-auto {\n table-layout: auto;\n}\n\n.line-through {\n text-decoration: line-through;\n}\n\n.w-full {\n width: 100%;\n}\n\n.gap-4 {\n gap: 1rem;\n}\n\n.grid-cols-3 {\n grid-template-columns: repeat(3, minmax(0, 1fr));\n}\n\n.transform {\n --tw-translate-x: 0;\n --tw-translate-y: 0;\n --tw-rotate: 0;\n --tw-skew-x: 0;\n --tw-skew-y: 0;\n --tw-scale-x: 1;\n --tw-scale-y: 1;\n transform: translateX(var(--tw-translate-x)) translateY(var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n\n.transition {\n transition-property: background-color, border-color, color, fill, stroke, opacity, box-shadow, transform;\n transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\n transition-duration: 150ms;\n}\n\n@-webkit-keyframes spin {\n to {\n transform: rotate(360deg);\n }\n}\n\n@keyframes spin {\n to {\n transform: rotate(360deg);\n }\n}\n\n@-webkit-keyframes ping {\n 75%, 100% {\n transform: scale(2);\n opacity: 0;\n }\n}\n\n@keyframes ping {\n 75%, 100% {\n transform: scale(2);\n opacity: 0;\n }\n}\n\n@-webkit-keyframes pulse {\n 50% {\n opacity: .5;\n }\n}\n\n@keyframes pulse {\n 50% {\n opacity: .5;\n }\n}\n\n@-webkit-keyframes bounce {\n 0%, 100% {\n transform: translateY(-25%);\n -webkit-animation-timing-function: cubic-bezier(0.8,0,1,1);\n animation-timing-function: cubic-bezier(0.8,0,1,1);\n }\n\n 50% {\n transform: none;\n -webkit-animation-timing-function: cubic-bezier(0,0,0.2,1);\n animation-timing-function: cubic-bezier(0,0,0.2,1);\n }\n}\n\n@keyframes bounce {\n 0%, 100% {\n transform: translateY(-25%);\n -webkit-animation-timing-function: cubic-bezier(0.8,0,1,1);\n animation-timing-function: cubic-bezier(0.8,0,1,1);\n }\n\n 50% {\n transform: none;\n -webkit-animation-timing-function: cubic-bezier(0,0,0.2,1);\n animation-timing-function: cubic-bezier(0,0,0.2,1);\n }\n}\n\n:root {\n --bg-color: #131720;\n --text-color: #d9e1f2;\n --primary: hsl(255, 30%, 55%);\n --focus: hsl(210, 90%, 50%);\n --secondary: #42b983;\n --border-color: hsla(0, 0%, 100%, 0.2);\n --light-1: hsl(210, 30%, 40%);\n --light-2: hsl(255, 30%, 50%);\n --light-background: linear-gradient(to right, var(--light-1), var(--light-2));\n --shadow-1: hsla(236, 50%, 50%, 0.3);\n --shadow-2: hsla(236, 50%, 50%, 0.4);\n --hud-background: rgba(0, 0, 0, 0.4);\n --hud-text-color: var(--text-color);\n --notifications-bg: darkslateblue;\n --skills-text-background: rgba(0, 0, 0, 0.5);\n --skills-text-color: var(--text-color);\n --skills-level-background: rgba(0, 0, 0, 0.5);\n --skills-level-color: orange;\n --skills-xp-bar-height: 40px;\n --skill-check-name-color: orange;\n --skill-check-difficulty: orange;\n --skill-check-success: green;\n --skill-check-failed: red;\n --skill-check-color: orange;\n --dialog-choice-color: orange;\n --dialog-choice-hover-color: var(--text-color);\n --inventory-text-background: rgba(0, 0, 0, 0.5);\n --inventory-text-color: var(--text-color);\n --inventory-amount-background: rgba(0, 0, 0, 0.5);\n --inventory-amount-color: orange;\n --quest-title-color: yellow;\n --completed-quest-title-color: grey;\n --objective-in-progress-color: white;\n --objective-completed-color: grey;\n}\n\n.list-item {\n display: inline-block;\n margin-right: 10px;\n}\n\n.list-enter-active,\n.list-leave-active {\n transition: all 0.3s ease;\n}\n\n/* .list-move {\n transition: transform 0.3s ease;\n} */\n\n.list-enter-from,\n.list-leave-to {\n opacity: 0;\n transform: translateX(300px);\n}\n\n.notification-item {\n display: inline-block;\n margin-right: 10px;\n}\n\n.notification-enter-active,\n.notification-leave-active {\n transition: all 0.3s ease;\n}\n\n/* .notification-move {\n transition: transform 0.3s ease;\n} */\n\n.notification-enter-from,\n.notification-leave-to {\n opacity: 0;\n transform: translateY(-300px);\n}\n\n.fade-enter-active,\n.fade-leave-active {\n transition: opacity 0.3s ease;\n}\n\n.fade-enter-from,\n.fade-leave-to {\n opacity: 0;\n}\n\n.fade-in-enter-active {\n transition: opacity 0.1s ease;\n}\n\n.fade-in-enter-from {\n opacity: 0;\n}\n\nbody {\n padding: 0;\n margin: 0;\n font-family: Arial, sans-serif;\n background-color: black;\n}\n\n.select {\n background: var(--light-background);\n padding: 10px;\n}\n\n.option {\n background-color: var(--light-2);\n padding: 5px;\n color: var(--text-color);\n}\n\n.button {\n background: var(--light-background);\n color: var(--text-color);\n box-shadow: 0.4rem 0.4rem 2.4rem 0.2rem var(--shadow-1);\n border-radius: 100px;\n padding: 10px;\n font-weight: 800;\n font-size: 16px;\n margin: 10px;\n transition: 0.2s;\n}\n\n.button:focus,\n.button:hover {\n transform: translateY(-0.2rem);\n box-shadow: 0 0 2.4rem 0.2rem var(--shadow-2);\n}\n\n.disabled {\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none;\n pointer-events: none;\n}\n\n.button.disabled {\n box-shadow: unset;\n color: grey;\n background: var(--border-color);\n}\n\n.input {\n background: var(--light-background);\n color: var(--text-color);\n box-shadow: 0.4rem 0.4rem 2.4rem 0.2rem var(--shadow-1);\n border-radius: 100px;\n padding: 10px;\n font-weight: 800;\n font-size: 16px;\n margin: 10px;\n transition: 0.2s;\n}\n\n.input:focus,\n.input:hover {\n transform: translateY(-0.2rem);\n box-shadow: 0 0 2.4rem 0.2rem var(--shadow-2);\n}\n\na {\n color: pink;\n text-decoration: underline;\n}\n\nth,\ntd {\n padding: 4px;\n border: 1px solid var(--text-color);\n text-align: center;\n}\n\n#game-holder {\n width: 100vw;\n height: 100vh;\n padding: 0;\n margin: 0;\n top: 0;\n left: 0;\n background-color: black;\n display: flex;\n align-items: center;\n justify-content: center;\n min-height: -webkit-fill-available;\n}\n\n.title {\n font-size: 30px;\n font-weight: 700;\n text-align: center;\n}\n\n.container {\n padding: 20px;\n}\n\nh1,\nh2,\nh3,\nh4 {\n font-weight: 700;\n}\n\nh1 {\n font-size: 30px;\n}\n\nh2 {\n font-size: 26px;\n}\n\nh3 {\n font-size: 24px;\n}\n\nhr.solid {\n border: 1px solid var(--text-color);\n margin-top: 30px;\n margin-bottom: 30px;\n}\n\n.card-1 {\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);\n transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);\n}\n\n.card-1:hover {\n box-shadow: 0 14px 28px rgba(0, 0, 0, 0.25), 0 10px 10px rgba(0, 0, 0, 0.22);\n}\n\n.card-2 {\n box-shadow: 0 3px 6px rgba(0, 0, 0, 0.16), 0 3px 6px rgba(0, 0, 0, 0.23);\n}\n\n.card-3 {\n box-shadow: 0 10px 20px rgba(0, 0, 0, 0.19), 0 6px 6px rgba(0, 0, 0, 0.23);\n}\n\n.card-4 {\n box-shadow: 0 14px 28px rgba(0, 0, 0, 0.25), 0 10px 10px rgba(0, 0, 0, 0.22);\n}\n\n.card-5 {\n box-shadow: 0 19px 38px rgba(0, 0, 0, 0.3), 0 15px 12px rgba(0, 0, 0, 0.22);\n}\n\n.dialog-choice {\n transition: 0.2s;\n}\n\n.dialog-choice:hover {\n transform: scale(1.05, 1.05);\n transform-origin: center;\n}\n\n/* Somewhat arcane CSS to force the hover color to override the child style.\nOtherwise hovering choices doesn't change the color of skill check prompts. */\n\n.dialog-choice:not(:hover) > .skill-check-name,\n.passive-skill-check > .skill-check-name {\n color: var(--skill-check-name-color);\n}\n\n.dialog-choice:not(:hover) > .skill-check-difficulty,\n.passive-skill-check > .skill-check-difficulty {\n color: var(--skill-check-difficulty);\n}\n\n.skill-check-difficulty {\n font-weight: 700;\n}\n\n.dialog-choice:not(:hover) > .skill-check-success,\n.passive-skill-check > .skill-check-success {\n color: var(--skill-check-success);\n}\n\n.dialog-choice:not(:hover) > .skill-check-failed,\n.passive-skill-check > .skill-check-failed {\n color: var(--skill-check-failed);\n}\n\n.dialog-choice:not(:hover) > .skill-check,\n.passive-skill-check.skill-check {\n color: var(--skill-check-color);\n}\n\n.narrat-canvas {\n position: absolute;\n height: 100%;\n top: 0;\n left: 0;\n}\n\n/* Looks ugly */\n\n/* @keyframes strike-anim {\n 0% {\n width: 0;\n }\n 100% {\n width: 100%;\n }\n}\n.strike-anim {\n position: relative;\n}\n.strike-anim::after {\n content: ' ';\n position: absolute;\n top: 50%;\n left: 0;\n width: 100%;\n height: 1px;\n background: var(--text-color);\n animation-name: strike-anim;\n animation-duration: 0.5s;\n animation-timing-function: linear;\n animation-iteration-count: 1;\n animation-fill-mode: forwards;\n} */\n\n#touchTrigger {\n pointer-events: none;\n}\n\n@media (min-width: 640px) {\n}\n\n@media (min-width: 768px) {\n}\n\n@media (min-width: 1024px) {\n}\n\n@media (min-width: 1280px) {\n}\n\n@media (min-width: 1536px) {\n}\n";
34
34
  styleInject(css_248z);
35
35
 
36
36
  const f=ref([]),v=ref(null),m=ref(null),g=ref(null),h=reactive({current:""}),y=[],b=ref(!1),k=readonly(f),w=readonly(v),M=readonly(m),q=readonly(g),x=readonly(h),$=(e=w.value)=>{h.current=e;const t=k.value.findIndex((t=>t.name===e)),n=k.value.map((e=>e.name));for(let a=0;a<n.length;a++){if(a>0&&a<n.length-1){const e=n[a]+"Minus",r=n[a]+"Plus";h[e]=t<=a,h[r]=t>=a;}h[n[a]]=n[a]===e;}},V=(e=M.value)=>{h.orientation=e,h.isLandscape="landscape"===e,h.isPortrait="portrait"===e;},O=(e=q.value||"light")=>{h.theme=e,h.isDark="dark"===e,h.isLight="light"===e;};function j(e,t){if("undefined"==typeof window||!window.matchMedia)return !1;if("undefined"!=typeof window&&!window.matchMedia)return console.error("Vue3 Mq: No MatchMedia support detected in this browser. Responsive breakpoints not available."),!1;{b.value=!0;const n=window.matchMedia(e),a=({matches:e})=>{e&&t();};y.push({mql:n,cb:a});n.addEventListener&&"function"==typeof n.addEventListener?n.addEventListener("change",a):n.addListener(a),a(n);}}var L=Object.freeze({__proto__:null,[Symbol.toStringTag]:"Module",bootstrap5:{xs:0,sm:576,md:768,lg:992,xl:1200,xxl:1400},bootstrap4:{xs:0,sm:576,md:768,lg:992,xl:1200},bootstrap3:{xs:0,sm:768,md:992,lg:1200},vuetify:{xs:0,sm:600,md:960,lg:1264,xl:1904},tailwind:{xs:0,sm:640,md:768,lg:1024,xl:1280,xxl:1536},devices:{phone:0,tablet:768,laptop:1370,desktop:1906}});const T=e=>{if(!e||"object"!=typeof e)return !1;const t=[];for(let n in e){const a=parseFloat(e[n]);n&&"string"==typeof n?/^[^a-z]/i.test(n)||/[^a-zA-Z0-9_]/.test(n)?console.warn(`Vue3 Mq: "${n}" is an invalid breakpoint key. Breakpoint keys must start with a letter and contain only alphanumeric characters and underscores. Skipping.`):!a&&0!==a||isNaN(a)||a<0?console.warn(`Vue3 Mq: "${n}: ${e[n]}" is not a valid breakpoint. Breakpoints should be a number of zero or above. Skipping.`):t.push({name:n,min:a}):console.warn(`Vue3 Mq: Invalid or missing breakpoint key (${JSON.stringify(n)}). Skipping.`);}t.some((e=>0===e.min))||console.warn("Vue3 Mq: You have not declared a breakpoint with a minimum value of 0. There may be screen sizes to which Vue3Mq does not respond.");return new Set(t.map((e=>e.min))).size<t.length&&console.warn("Vue3 Mq: Your breakpoint configuration contains duplicate values. Behaviour may be unpredictable."),0!==t.length&&t.sort(((e,t)=>e.min-t.min))};function R({breakpoints:e,preset:t}){const n=(e=>{if("string"==typeof e&&L[e])return L[e];{const t=Object.keys(L);return console.error(`Vue3 Mq: "${e}" is not a valid preset. Available options are: ${t.join(", ")}`),!1}})(t),a=T(e);if(!1===n&&!a)throw new TypeError("Vue3 Mq: You must provide a valid preset, or valid breakpoint settings.");var r;r=a||T(n),f.value=r,function(){for(;y.length>0;){const e=y.shift();if(e&&"object"==typeof e){const{mql:t,cb:n}=e;t.addEventListener&&"function"==typeof t.addEventListener?t.removeEventListener("change",n):t.removeListener(n);}}}(),(()=>{const e=Object.keys(h);for(let t of e)delete h[t];$(),V(),O();})();const o=k.value.reduce(((e,t,n,a)=>{const r=`(min-width: ${t.min}px)`,o=n<a.length-1?`(max-width: ${a[n+1].min-1}px)`:null,i=r+(o?" and "+o:"");return Object.assign(e,{[t.name]:i})}),{});for(const i in o){j(o[i],(()=>{$(i);}));}["portrait","landscape"].forEach((e=>{j(`(orientation: ${e})`,(()=>{V(e);}));})),["light","dark"].forEach((e=>{j(`(prefers-color-scheme: ${e})`,(()=>{O(e);}));}));}var N={install:(e,{preset:t="bootstrap5",breakpoints:n,defaultBreakpoint:a,defaultOrientation:r="landscape",defaultTheme:o}={})=>{try{const l=!1===["landscape","portrait"].includes(s=r)?(console.error(`Vue3 Mq: "${s}" is not a valid default orientation. Reverting to unset value.`),null):s,u=((e=null)=>!1===["dark","light"].includes(e)&&null!==e?(console.error(`Vue3 Mq: "${e}" is not a valid default theme. Reverting to unset value.`),null):e)(o);i=a,v.value=i,(e=>{m.value=e;})(l),(e=>{g.value=e;})(u),e.provide("mq",x),e.provide("updateBreakpoints",R),R({breakpoints:n,preset:t});}catch(l){console.error(l);}var i,s;}};
@@ -98,6 +98,11 @@ const defaultConfig = {
98
98
  },
99
99
  hudStats: {},
100
100
  items: {},
101
+ interactionTags: {
102
+ default: {
103
+ onlyInteractOutsideOfScripts: true,
104
+ },
105
+ },
101
106
  quests: {},
102
107
  };
103
108
 
@@ -3560,203 +3565,6 @@ function randomId() {
3560
3565
  return `${Date.now() - Math.floor(Math.random() * 99999999)}`;
3561
3566
  }
3562
3567
 
3563
- // Create a pinia store named dialog with a state using the type DialogState, with actions addDialog and clearDialog
3564
- const useDialogStore = defineStore('dialog', {
3565
- state: () => ({
3566
- dialog: [],
3567
- }),
3568
- actions: {
3569
- generateSaveData() {
3570
- return {
3571
- dialog: this.dialog,
3572
- };
3573
- },
3574
- loadSaveData(data) {
3575
- this.dialog = data.dialog;
3576
- },
3577
- addDialog(dialog) {
3578
- this.dialog.push({
3579
- ...dialog,
3580
- interactive: dialog.interactive ?? false,
3581
- id: randomId(),
3582
- });
3583
- },
3584
- clearDialog() {
3585
- this.dialog.splice(0, this.dialog.length);
3586
- },
3587
- reset() {
3588
- this.dialog = [];
3589
- },
3590
- },
3591
- });
3592
-
3593
- var isMergeableObject = function isMergeableObject(value) {
3594
- return isNonNullObject(value)
3595
- && !isSpecial(value)
3596
- };
3597
-
3598
- function isNonNullObject(value) {
3599
- return !!value && typeof value === 'object'
3600
- }
3601
-
3602
- function isSpecial(value) {
3603
- var stringValue = Object.prototype.toString.call(value);
3604
-
3605
- return stringValue === '[object RegExp]'
3606
- || stringValue === '[object Date]'
3607
- || isReactElement(value)
3608
- }
3609
-
3610
- // see https://github.com/facebook/react/blob/b5ac963fb791d1298e7f396236383bc955f916c1/src/isomorphic/classic/element/ReactElement.js#L21-L25
3611
- var canUseSymbol = typeof Symbol === 'function' && Symbol.for;
3612
- var REACT_ELEMENT_TYPE = canUseSymbol ? Symbol.for('react.element') : 0xeac7;
3613
-
3614
- function isReactElement(value) {
3615
- return value.$$typeof === REACT_ELEMENT_TYPE
3616
- }
3617
-
3618
- function emptyTarget(val) {
3619
- return Array.isArray(val) ? [] : {}
3620
- }
3621
-
3622
- function cloneUnlessOtherwiseSpecified(value, options) {
3623
- return (options.clone !== false && options.isMergeableObject(value))
3624
- ? deepmerge(emptyTarget(value), value, options)
3625
- : value
3626
- }
3627
-
3628
- function defaultArrayMerge(target, source, options) {
3629
- return target.concat(source).map(function(element) {
3630
- return cloneUnlessOtherwiseSpecified(element, options)
3631
- })
3632
- }
3633
-
3634
- function getMergeFunction(key, options) {
3635
- if (!options.customMerge) {
3636
- return deepmerge
3637
- }
3638
- var customMerge = options.customMerge(key);
3639
- return typeof customMerge === 'function' ? customMerge : deepmerge
3640
- }
3641
-
3642
- function getEnumerableOwnPropertySymbols(target) {
3643
- return Object.getOwnPropertySymbols
3644
- ? Object.getOwnPropertySymbols(target).filter(function(symbol) {
3645
- return target.propertyIsEnumerable(symbol)
3646
- })
3647
- : []
3648
- }
3649
-
3650
- function getKeys(target) {
3651
- return Object.keys(target).concat(getEnumerableOwnPropertySymbols(target))
3652
- }
3653
-
3654
- function propertyIsOnObject(object, property) {
3655
- try {
3656
- return property in object
3657
- } catch(_) {
3658
- return false
3659
- }
3660
- }
3661
-
3662
- // Protects from prototype poisoning and unexpected merging up the prototype chain.
3663
- function propertyIsUnsafe(target, key) {
3664
- return propertyIsOnObject(target, key) // Properties are safe to merge if they don't exist in the target yet,
3665
- && !(Object.hasOwnProperty.call(target, key) // unsafe if they exist up the prototype chain,
3666
- && Object.propertyIsEnumerable.call(target, key)) // and also unsafe if they're nonenumerable.
3667
- }
3668
-
3669
- function mergeObject(target, source, options) {
3670
- var destination = {};
3671
- if (options.isMergeableObject(target)) {
3672
- getKeys(target).forEach(function(key) {
3673
- destination[key] = cloneUnlessOtherwiseSpecified(target[key], options);
3674
- });
3675
- }
3676
- getKeys(source).forEach(function(key) {
3677
- if (propertyIsUnsafe(target, key)) {
3678
- return
3679
- }
3680
-
3681
- if (propertyIsOnObject(target, key) && options.isMergeableObject(source[key])) {
3682
- destination[key] = getMergeFunction(key, options)(target[key], source[key], options);
3683
- } else {
3684
- destination[key] = cloneUnlessOtherwiseSpecified(source[key], options);
3685
- }
3686
- });
3687
- return destination
3688
- }
3689
-
3690
- function deepmerge(target, source, options) {
3691
- options = options || {};
3692
- options.arrayMerge = options.arrayMerge || defaultArrayMerge;
3693
- options.isMergeableObject = options.isMergeableObject || isMergeableObject;
3694
- // cloneUnlessOtherwiseSpecified is added to `options` so that custom arrayMerge()
3695
- // implementations can use it. The caller may not replace it.
3696
- options.cloneUnlessOtherwiseSpecified = cloneUnlessOtherwiseSpecified;
3697
-
3698
- var sourceIsArray = Array.isArray(source);
3699
- var targetIsArray = Array.isArray(target);
3700
- var sourceAndTargetTypesMatch = sourceIsArray === targetIsArray;
3701
-
3702
- if (!sourceAndTargetTypesMatch) {
3703
- return cloneUnlessOtherwiseSpecified(source, options)
3704
- } else if (sourceIsArray) {
3705
- return options.arrayMerge(target, source, options)
3706
- } else {
3707
- return mergeObject(target, source, options)
3708
- }
3709
- }
3710
-
3711
- deepmerge.all = function deepmergeAll(array, options) {
3712
- if (!Array.isArray(array)) {
3713
- throw new Error('first argument should be an array')
3714
- }
3715
-
3716
- return array.reduce(function(prev, next) {
3717
- return deepmerge(prev, next, options)
3718
- }, {})
3719
- };
3720
-
3721
- var deepmerge_1 = deepmerge;
3722
-
3723
- var cjs = deepmerge_1;
3724
-
3725
- // Create a pinia store named hud with a state using the type HudState, and save type HudSave, with actions:
3726
- // setupHudStats(stats: { [key: string]: HudStatConfig }): Iterates the stats argument to add new stats to the state
3727
- // setStat(stat: string, value: number): Sets the value of a stat
3728
- // addStat(stat: string, value: number): Adds a value to a stat
3729
- // generateSaveData(): Function that generates a HudSave object from the data in the state
3730
- // loadSaveData(data: HudSave): Function that loads the data into the state
3731
- const useHud = defineStore('hud', {
3732
- state: () => ({
3733
- hudStats: {},
3734
- }),
3735
- actions: {
3736
- setupHudStats(stats) {
3737
- for (const stat in stats) {
3738
- this.hudStats[stat] = {
3739
- value: stats[stat].startingValue,
3740
- };
3741
- }
3742
- },
3743
- setStat(stat, value) {
3744
- this.hudStats[stat].value = value;
3745
- },
3746
- addStat(stat, value) {
3747
- this.hudStats[stat].value += value;
3748
- },
3749
- generateSaveData() {
3750
- return {
3751
- hudStats: this.hudStats,
3752
- };
3753
- },
3754
- loadSaveData(data) {
3755
- this.hudStats = cjs(this.hudStats, data.hudStats);
3756
- },
3757
- },
3758
- });
3759
-
3760
3568
  // Generate a pinia store named notifications with a state using the type NotificationsState, and save type NotificationsSave, with actions:
3761
3569
  // addNotification(text: string): Adds a new notification to the state, and deletes it after a timeout
3762
3570
  // deleteNotification(id: string): Deletes a notification from the state
@@ -3785,15 +3593,18 @@ const useNotifications = defineStore('notifications', {
3785
3593
  const useInventory = defineStore('inventory', {
3786
3594
  state: () => ({
3787
3595
  items: {},
3596
+ interactionTags: {},
3788
3597
  }),
3789
3598
  actions: {
3790
3599
  generateSaveData() {
3791
3600
  return {
3792
3601
  items: this.items,
3602
+ interactionTags: this.interactionTags,
3793
3603
  };
3794
3604
  },
3795
3605
  loadSaveData(save) {
3796
3606
  this.items = { ...this.items, ...save.items };
3607
+ this.interactionTags = { ...save.interactionTags };
3797
3608
  },
3798
3609
  setupItems(items) {
3799
3610
  Object.keys(items).forEach((key) => {
@@ -3819,6 +3630,49 @@ const useInventory = defineStore('inventory', {
3819
3630
  }
3820
3631
  useNotifications().addNotification(`Received item: ${getItemConfig(item.id).name} x ${item.amount}`);
3821
3632
  },
3633
+ enableInteraction(tag) {
3634
+ if (!tag) {
3635
+ tag = 'default';
3636
+ }
3637
+ this.interactionTags[tag] = {
3638
+ blockedInteraction: false,
3639
+ };
3640
+ },
3641
+ disableInteraction(tag) {
3642
+ if (!tag) {
3643
+ tag = 'default';
3644
+ }
3645
+ this.interactionTags[tag] = {
3646
+ blockedInteraction: true,
3647
+ };
3648
+ },
3649
+ onScriptStart() {
3650
+ const tags = getConfig().interactionTags;
3651
+ Object.keys(tags).forEach((tag) => {
3652
+ const conf = tags[tag];
3653
+ if (conf.onlyInteractOutsideOfScripts) {
3654
+ this.disableInteraction(tag);
3655
+ }
3656
+ });
3657
+ },
3658
+ onScriptEnd() {
3659
+ const tags = getConfig().interactionTags;
3660
+ Object.keys(tags).forEach((tag) => {
3661
+ const conf = tags[tag];
3662
+ if (conf.onlyInteractOutsideOfScripts) {
3663
+ this.enableInteraction(tag);
3664
+ }
3665
+ });
3666
+ },
3667
+ isInteractionTagBlocked(tag) {
3668
+ if (!tag) {
3669
+ tag = 'default';
3670
+ }
3671
+ if (this.interactionTags[tag]) {
3672
+ return this.interactionTags[tag].blockedInteraction;
3673
+ }
3674
+ return false;
3675
+ },
3822
3676
  remove(item) {
3823
3677
  const existingItem = this.getExistingItem(item.id);
3824
3678
  if (existingItem) {
@@ -3838,93 +3692,6 @@ const useInventory = defineStore('inventory', {
3838
3692
  },
3839
3693
  });
3840
3694
 
3841
- // Create a pinia store named skills with a state using the type Skills, with actions:
3842
- // setupSkillCheck(skillCheck: SkillCheckState, id: string)
3843
- // passSkillCheck(skillCheckId: string)
3844
- // failSkillCheck(skillCheckId: string)
3845
- // generateSaveData(): Function that generates a Skills object from the data in the state
3846
- // loadSaveData(data: Skills): Function that loads the data into the state
3847
- // setupSkills(skills: { [key: string]: SkillData})
3848
- // addXp(skill: string, xp: number): Adds xp to a skill, increases skill level if it reaches the max xp defined in the skillOptions.xpPerLevel key of the config
3849
- // incrementSkill(skill: string, amount: number): Increments the level of a skill by amount
3850
- const useSkills = defineStore('skills', {
3851
- state: () => ({
3852
- skillChecks: {},
3853
- skills: {},
3854
- }),
3855
- actions: {
3856
- setupSkillCheck(skillCheck, id) {
3857
- this.skillChecks[id] = skillCheck;
3858
- },
3859
- passSkillCheck(skillCheckId) {
3860
- this.skillChecks[skillCheckId].passed = true;
3861
- this.skillChecks[skillCheckId].available = false;
3862
- },
3863
- failSkillCheck(skillCheckId) {
3864
- this.skillChecks[skillCheckId].passed = false;
3865
- this.skillChecks[skillCheckId].available = false;
3866
- },
3867
- generateSaveData() {
3868
- return {
3869
- skillChecks: this.skillChecks,
3870
- skills: this.skills,
3871
- };
3872
- },
3873
- loadSaveData(data) {
3874
- this.skillChecks = cjs(this.skillChecks, data.skillChecks);
3875
- this.skills = cjs(this.skills, data.skills);
3876
- },
3877
- setupSkills(skills) {
3878
- // Adds each skill in the skills object to the skills state. Add default values for startingLevel and xp of 0 if those keys are missing.
3879
- for (const skill in skills) {
3880
- this.skills[skill] = {
3881
- level: skills[skill].startingLevel || 0,
3882
- xp: 0,
3883
- };
3884
- }
3885
- },
3886
- addXp(skill, xp) {
3887
- const skillData = this.skills[skill];
3888
- skillData.xp += xp;
3889
- if (skillData.xp >= getConfig().skillOptions.xpPerLevel) {
3890
- skillData.xp = 0;
3891
- skillData.level++;
3892
- this.levelledUp(skill);
3893
- }
3894
- },
3895
- incrementSkill(skill, amount) {
3896
- this.skills[skill].level += amount;
3897
- this.levelledUp(skill);
3898
- },
3899
- levelledUp(skill) {
3900
- const skillName = getConfig().skills[skill].name;
3901
- const skillLevel = this.skills[skill].level;
3902
- useNotifications().addNotification(`Your skill in ${skillName} is now level ${skillLevel}`);
3903
- },
3904
- },
3905
- });
3906
-
3907
- function getFile(url) {
3908
- return new Promise((resolve, reject) => {
3909
- // Set up our HTTP request
3910
- const xhr = new XMLHttpRequest();
3911
- // Setup our listener to process completed requests
3912
- xhr.onload = function () {
3913
- // Process our return data
3914
- if (xhr.status >= 200 && xhr.status < 300) {
3915
- // This will run when the request is successful
3916
- resolve(xhr.responseText);
3917
- }
3918
- else {
3919
- reject(xhr.status);
3920
- // This will run when it's not
3921
- }
3922
- };
3923
- xhr.open('GET', url);
3924
- xhr.send();
3925
- });
3926
- }
3927
-
3928
3695
  const everyObject = (object, predicate) => {
3929
3696
  for (const key in object) {
3930
3697
  if (!predicate(object[key])) {
@@ -4000,26 +3767,248 @@ const useQuests = defineStore('quests', {
4000
3767
  }
4001
3768
  useNotifications().addNotification(`Quest completed: ${getQuestConfig(questId).title}`);
4002
3769
  },
4003
- isQuestCompleted(questId) {
4004
- const quest = this.getQuest(questId);
4005
- return everyObject(quest.objectives, (objective) => objective.state === 'completed');
3770
+ isQuestCompleted(questId) {
3771
+ const quest = this.getQuest(questId);
3772
+ return everyObject(quest.objectives, (objective) => objective.state === 'completed');
3773
+ },
3774
+ removeQuest(id) {
3775
+ delete this.quests[id];
3776
+ },
3777
+ generateSaveData() {
3778
+ return {
3779
+ quests: {
3780
+ ...this.quests,
3781
+ },
3782
+ };
3783
+ },
3784
+ loadSaveData(data) {
3785
+ this.quests = data.quests;
3786
+ },
3787
+ },
3788
+ });
3789
+
3790
+ var isMergeableObject = function isMergeableObject(value) {
3791
+ return isNonNullObject(value)
3792
+ && !isSpecial(value)
3793
+ };
3794
+
3795
+ function isNonNullObject(value) {
3796
+ return !!value && typeof value === 'object'
3797
+ }
3798
+
3799
+ function isSpecial(value) {
3800
+ var stringValue = Object.prototype.toString.call(value);
3801
+
3802
+ return stringValue === '[object RegExp]'
3803
+ || stringValue === '[object Date]'
3804
+ || isReactElement(value)
3805
+ }
3806
+
3807
+ // see https://github.com/facebook/react/blob/b5ac963fb791d1298e7f396236383bc955f916c1/src/isomorphic/classic/element/ReactElement.js#L21-L25
3808
+ var canUseSymbol = typeof Symbol === 'function' && Symbol.for;
3809
+ var REACT_ELEMENT_TYPE = canUseSymbol ? Symbol.for('react.element') : 0xeac7;
3810
+
3811
+ function isReactElement(value) {
3812
+ return value.$$typeof === REACT_ELEMENT_TYPE
3813
+ }
3814
+
3815
+ function emptyTarget(val) {
3816
+ return Array.isArray(val) ? [] : {}
3817
+ }
3818
+
3819
+ function cloneUnlessOtherwiseSpecified(value, options) {
3820
+ return (options.clone !== false && options.isMergeableObject(value))
3821
+ ? deepmerge(emptyTarget(value), value, options)
3822
+ : value
3823
+ }
3824
+
3825
+ function defaultArrayMerge(target, source, options) {
3826
+ return target.concat(source).map(function(element) {
3827
+ return cloneUnlessOtherwiseSpecified(element, options)
3828
+ })
3829
+ }
3830
+
3831
+ function getMergeFunction(key, options) {
3832
+ if (!options.customMerge) {
3833
+ return deepmerge
3834
+ }
3835
+ var customMerge = options.customMerge(key);
3836
+ return typeof customMerge === 'function' ? customMerge : deepmerge
3837
+ }
3838
+
3839
+ function getEnumerableOwnPropertySymbols(target) {
3840
+ return Object.getOwnPropertySymbols
3841
+ ? Object.getOwnPropertySymbols(target).filter(function(symbol) {
3842
+ return target.propertyIsEnumerable(symbol)
3843
+ })
3844
+ : []
3845
+ }
3846
+
3847
+ function getKeys(target) {
3848
+ return Object.keys(target).concat(getEnumerableOwnPropertySymbols(target))
3849
+ }
3850
+
3851
+ function propertyIsOnObject(object, property) {
3852
+ try {
3853
+ return property in object
3854
+ } catch(_) {
3855
+ return false
3856
+ }
3857
+ }
3858
+
3859
+ // Protects from prototype poisoning and unexpected merging up the prototype chain.
3860
+ function propertyIsUnsafe(target, key) {
3861
+ return propertyIsOnObject(target, key) // Properties are safe to merge if they don't exist in the target yet,
3862
+ && !(Object.hasOwnProperty.call(target, key) // unsafe if they exist up the prototype chain,
3863
+ && Object.propertyIsEnumerable.call(target, key)) // and also unsafe if they're nonenumerable.
3864
+ }
3865
+
3866
+ function mergeObject(target, source, options) {
3867
+ var destination = {};
3868
+ if (options.isMergeableObject(target)) {
3869
+ getKeys(target).forEach(function(key) {
3870
+ destination[key] = cloneUnlessOtherwiseSpecified(target[key], options);
3871
+ });
3872
+ }
3873
+ getKeys(source).forEach(function(key) {
3874
+ if (propertyIsUnsafe(target, key)) {
3875
+ return
3876
+ }
3877
+
3878
+ if (propertyIsOnObject(target, key) && options.isMergeableObject(source[key])) {
3879
+ destination[key] = getMergeFunction(key, options)(target[key], source[key], options);
3880
+ } else {
3881
+ destination[key] = cloneUnlessOtherwiseSpecified(source[key], options);
3882
+ }
3883
+ });
3884
+ return destination
3885
+ }
3886
+
3887
+ function deepmerge(target, source, options) {
3888
+ options = options || {};
3889
+ options.arrayMerge = options.arrayMerge || defaultArrayMerge;
3890
+ options.isMergeableObject = options.isMergeableObject || isMergeableObject;
3891
+ // cloneUnlessOtherwiseSpecified is added to `options` so that custom arrayMerge()
3892
+ // implementations can use it. The caller may not replace it.
3893
+ options.cloneUnlessOtherwiseSpecified = cloneUnlessOtherwiseSpecified;
3894
+
3895
+ var sourceIsArray = Array.isArray(source);
3896
+ var targetIsArray = Array.isArray(target);
3897
+ var sourceAndTargetTypesMatch = sourceIsArray === targetIsArray;
3898
+
3899
+ if (!sourceAndTargetTypesMatch) {
3900
+ return cloneUnlessOtherwiseSpecified(source, options)
3901
+ } else if (sourceIsArray) {
3902
+ return options.arrayMerge(target, source, options)
3903
+ } else {
3904
+ return mergeObject(target, source, options)
3905
+ }
3906
+ }
3907
+
3908
+ deepmerge.all = function deepmergeAll(array, options) {
3909
+ if (!Array.isArray(array)) {
3910
+ throw new Error('first argument should be an array')
3911
+ }
3912
+
3913
+ return array.reduce(function(prev, next) {
3914
+ return deepmerge(prev, next, options)
3915
+ }, {})
3916
+ };
3917
+
3918
+ var deepmerge_1 = deepmerge;
3919
+
3920
+ var cjs = deepmerge_1;
3921
+
3922
+ // Create a pinia store named skills with a state using the type Skills, with actions:
3923
+ // setupSkillCheck(skillCheck: SkillCheckState, id: string)
3924
+ // passSkillCheck(skillCheckId: string)
3925
+ // failSkillCheck(skillCheckId: string)
3926
+ // generateSaveData(): Function that generates a Skills object from the data in the state
3927
+ // loadSaveData(data: Skills): Function that loads the data into the state
3928
+ // setupSkills(skills: { [key: string]: SkillData})
3929
+ // addXp(skill: string, xp: number): Adds xp to a skill, increases skill level if it reaches the max xp defined in the skillOptions.xpPerLevel key of the config
3930
+ // incrementSkill(skill: string, amount: number): Increments the level of a skill by amount
3931
+ const useSkills = defineStore('skills', {
3932
+ state: () => ({
3933
+ skillChecks: {},
3934
+ skills: {},
3935
+ }),
3936
+ actions: {
3937
+ setupSkillCheck(skillCheck, id) {
3938
+ this.skillChecks[id] = skillCheck;
3939
+ },
3940
+ passSkillCheck(skillCheckId) {
3941
+ this.skillChecks[skillCheckId].passed = true;
3942
+ this.skillChecks[skillCheckId].available = false;
4006
3943
  },
4007
- removeQuest(id) {
4008
- delete this.quests[id];
3944
+ failSkillCheck(skillCheckId) {
3945
+ this.skillChecks[skillCheckId].passed = false;
3946
+ this.skillChecks[skillCheckId].available = false;
4009
3947
  },
4010
3948
  generateSaveData() {
4011
3949
  return {
4012
- quests: {
4013
- ...this.quests,
4014
- },
3950
+ skillChecks: this.skillChecks,
3951
+ skills: this.skills,
4015
3952
  };
4016
3953
  },
4017
3954
  loadSaveData(data) {
4018
- this.quests = data.quests;
3955
+ this.skillChecks = cjs(this.skillChecks, data.skillChecks);
3956
+ this.skills = cjs(this.skills, data.skills);
3957
+ },
3958
+ setupSkills(skills) {
3959
+ // Adds each skill in the skills object to the skills state. Add default values for startingLevel and xp of 0 if those keys are missing.
3960
+ for (const skill in skills) {
3961
+ this.skills[skill] = {
3962
+ level: skills[skill].startingLevel || 0,
3963
+ xp: 0,
3964
+ };
3965
+ }
3966
+ },
3967
+ addXp(skill, xp) {
3968
+ const skillData = this.skills[skill];
3969
+ if (!skillData) {
3970
+ error(`Skill ${skill} doesn't exist`);
3971
+ }
3972
+ skillData.xp += xp;
3973
+ if (skillData.xp >= getConfig().skillOptions.xpPerLevel) {
3974
+ skillData.xp = 0;
3975
+ skillData.level++;
3976
+ this.levelledUp(skill);
3977
+ }
3978
+ },
3979
+ incrementSkill(skill, amount) {
3980
+ this.skills[skill].level += amount;
3981
+ this.levelledUp(skill);
3982
+ },
3983
+ levelledUp(skill) {
3984
+ const skillName = getConfig().skills[skill].name;
3985
+ const skillLevel = this.skills[skill].level;
3986
+ useNotifications().addNotification(`Your skill in ${skillName} is now level ${skillLevel}`);
4019
3987
  },
4020
3988
  },
4021
3989
  });
4022
3990
 
3991
+ function getFile(url) {
3992
+ return new Promise((resolve, reject) => {
3993
+ // Set up our HTTP request
3994
+ const xhr = new XMLHttpRequest();
3995
+ // Setup our listener to process completed requests
3996
+ xhr.onload = function () {
3997
+ // Process our return data
3998
+ if (xhr.status >= 200 && xhr.status < 300) {
3999
+ // This will run when the request is successful
4000
+ resolve(xhr.responseText);
4001
+ }
4002
+ else {
4003
+ reject(xhr.status);
4004
+ // This will run when it's not
4005
+ }
4006
+ };
4007
+ xhr.open('GET', url);
4008
+ xhr.send();
4009
+ });
4010
+ }
4011
+
4023
4012
  // Create a pinia store named screens with a state using the type ScreenState, with actions:
4024
4013
  // setScreen(screen: string): Sets the current screen to the given screen
4025
4014
  // setButtons(buttons: { [key: string]: ButtonConfig }): Adds buttons to the buttons state by using the values in the buttons config object
@@ -4311,6 +4300,7 @@ const useVM = defineStore('vm', {
4311
4300
  data: {},
4312
4301
  lastLabel: 'main',
4313
4302
  script: {},
4303
+ labelStack: ['main'],
4314
4304
  }),
4315
4305
  actions: {
4316
4306
  generateSaveData() {
@@ -4387,6 +4377,7 @@ const useVM = defineStore('vm', {
4387
4377
  newStack.label = this.currentStack.label;
4388
4378
  }
4389
4379
  this.stack.push(newStack);
4380
+ return this.runLine();
4390
4381
  },
4391
4382
  async nextLine() {
4392
4383
  if (this.stack.length === 0) {
@@ -4414,6 +4405,7 @@ const useVM = defineStore('vm', {
4414
4405
  this.stack.splice(this.stack.length - 1, 1);
4415
4406
  },
4416
4407
  finishGame() {
4408
+ useInventory().onScriptEnd();
4417
4409
  const mainStore = useMain();
4418
4410
  if (mainStore.options.debug) {
4419
4411
  const dialogStore = useDialogStore();
@@ -4425,8 +4417,24 @@ const useVM = defineStore('vm', {
4425
4417
  },
4426
4418
  async runLine() {
4427
4419
  const cmd = this.currentLine;
4420
+ useInventory().onScriptStart();
4428
4421
  await runCommand(cmd);
4429
4422
  },
4423
+ async runLabelFunction(label, comeBackToSameLine) {
4424
+ if (comeBackToSameLine) {
4425
+ this.currentStack.currentIndex--;
4426
+ }
4427
+ const branch = this.script[label];
4428
+ if (!branch) {
4429
+ console.error(`Label ${branch} doesn't exist`);
4430
+ }
4431
+ const stack = {
4432
+ currentIndex: 0,
4433
+ branch: branch,
4434
+ label,
4435
+ };
4436
+ await this.addStack(stack);
4437
+ },
4430
4438
  runLabel(label) {
4431
4439
  const branch = this.script[label];
4432
4440
  if (!branch) {
@@ -4455,6 +4463,93 @@ const useVM = defineStore('vm', {
4455
4463
  },
4456
4464
  });
4457
4465
 
4466
+ function processText(text) {
4467
+ const vmStore = useVM();
4468
+ const skillStore = useSkills();
4469
+ return text.replace(/%{[^}]*}/g, (match) => {
4470
+ const key = match.substr(2, match.length - 3);
4471
+ const searchableState = {
4472
+ data: vmStore.data,
4473
+ skills: skillStore.skills,
4474
+ items: useInventory().items,
4475
+ quests: useQuests().quests,
4476
+ };
4477
+ const [obj, newKey] = findDataHelper(searchableState, key);
4478
+ return obj[newKey];
4479
+ });
4480
+ }
4481
+
4482
+ // Create a pinia store named dialog with a state using the type DialogState, with actions addDialog and clearDialog
4483
+ const useDialogStore = defineStore('dialog', {
4484
+ state: () => ({
4485
+ dialog: [],
4486
+ }),
4487
+ actions: {
4488
+ generateSaveData() {
4489
+ return {
4490
+ dialog: this.dialog,
4491
+ };
4492
+ },
4493
+ loadSaveData(data) {
4494
+ this.dialog = data.dialog;
4495
+ },
4496
+ addDialog(dialog) {
4497
+ this.dialog.push({
4498
+ ...dialog,
4499
+ interactive: dialog.interactive ?? false,
4500
+ id: randomId(),
4501
+ text: processText(dialog.text),
4502
+ });
4503
+ },
4504
+ clearDialog() {
4505
+ this.dialog.splice(0, this.dialog.length);
4506
+ },
4507
+ reset() {
4508
+ this.dialog = [];
4509
+ },
4510
+ },
4511
+ getters: {
4512
+ currentDialog() {
4513
+ return this.dialog[this.dialog.length - 1];
4514
+ },
4515
+ },
4516
+ });
4517
+
4518
+ // Create a pinia store named hud with a state using the type HudState, and save type HudSave, with actions:
4519
+ // setupHudStats(stats: { [key: string]: HudStatConfig }): Iterates the stats argument to add new stats to the state
4520
+ // setStat(stat: string, value: number): Sets the value of a stat
4521
+ // addStat(stat: string, value: number): Adds a value to a stat
4522
+ // generateSaveData(): Function that generates a HudSave object from the data in the state
4523
+ // loadSaveData(data: HudSave): Function that loads the data into the state
4524
+ const useHud = defineStore('hud', {
4525
+ state: () => ({
4526
+ hudStats: {},
4527
+ }),
4528
+ actions: {
4529
+ setupHudStats(stats) {
4530
+ for (const stat in stats) {
4531
+ this.hudStats[stat] = {
4532
+ value: stats[stat].startingValue,
4533
+ };
4534
+ }
4535
+ },
4536
+ setStat(stat, value) {
4537
+ this.hudStats[stat].value = value;
4538
+ },
4539
+ addStat(stat, value) {
4540
+ this.hudStats[stat].value += value;
4541
+ },
4542
+ generateSaveData() {
4543
+ return {
4544
+ hudStats: this.hudStats,
4545
+ };
4546
+ },
4547
+ loadSaveData(data) {
4548
+ this.hudStats = cjs(this.hudStats, data.hudStats);
4549
+ },
4550
+ },
4551
+ });
4552
+
4458
4553
  function createSkillCheckState() {
4459
4554
  const skillCheck = {
4460
4555
  passed: false,
@@ -4608,6 +4703,7 @@ function conditionFunction(condition) {
4608
4703
  skillChecks: skillStore.skillChecks,
4609
4704
  stats: useHud().hudStats,
4610
4705
  items: inventory.items,
4706
+ quests: useQuests().quests,
4611
4707
  itemAmount: (id) => {
4612
4708
  return useInventory().getItemAmount(id);
4613
4709
  },
@@ -4680,9 +4776,9 @@ async function runCommand(cmd, choices) {
4680
4776
  catch (err) {
4681
4777
  logger.log(`Error at: `, vmStore.currentStack.label);
4682
4778
  console.error(err);
4683
- error(`Narrat script runtime error at <span class="error-filename">${cmd.fileName}:${cmd.line + 1}</span>
4684
- <b>${err}</b>
4685
- Script: ${cmd.code}
4779
+ error(`Narrat script runtime error at <span class="error-filename">${cmd.fileName}:${cmd.line + 1}</span>
4780
+ <b>${err}</b>
4781
+ Script: ${cmd.code}
4686
4782
  Label: ${vmStore.currentStack.label}`);
4687
4783
  }
4688
4784
  }
@@ -4728,8 +4824,7 @@ async function playerAnswered(choiceIndex) {
4728
4824
  branch: newBranch,
4729
4825
  };
4730
4826
  const vmStore = useVM();
4731
- vmStore.addStack(newStack);
4732
- vmStore.runLine();
4827
+ return vmStore.addStack(newStack);
4733
4828
  }
4734
4829
  else {
4735
4830
  vmStore.nextLine();
@@ -4874,7 +4969,12 @@ const useMain = defineStore('main', {
4874
4969
  this.modal = false;
4875
4970
  },
4876
4971
  toggleMenu() {
4877
- this.flowState = this.flowState === 'menu' ? 'playing' : 'menu';
4972
+ if (this.modal) {
4973
+ this.modal = false;
4974
+ }
4975
+ else {
4976
+ this.modal = 'menu';
4977
+ }
4878
4978
  },
4879
4979
  pause() {
4880
4980
  this.paused = true;
@@ -5187,7 +5287,7 @@ function render(_ctx, _cache, $props, $setup, $data, $options) {
5187
5287
  ], 4))
5188
5288
  }
5189
5289
 
5190
- var css_248z$1 = ".dialog-title {\n font-size: 20px;\n font-weight: bold;\n}\n\n.dialog-text {\n font-size: 16px;\n}\n\n.dialog-box {\n /* border-radius: 10px; */\n /* border: 1px solid #a8a8a8; */\n color: var(--text-color);\n /* background-color: #2e2e2e; */\n padding: 10px;\n padding-left: 2em;\n margin-bottom: 10px;\n}\n\n.dialog-choice {\n color: var(--dialog-choice-color);\n}\n\n.dialog-choice:hover {\n color: var(--dialog-choice-hover-color);\n cursor: pointer;\n}\n\n.buttons-container {\n width: 100%;\n padding: 10px;\n display: flex;\n justify-content: space-evenly;\n align-items: stretch;\n box-sizing: border-box;\n}\n\n.interact-button {\n cursor: pointer;\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none;\n height: 50px;\n color: var(--text-color);\n border: 1px solid black;\n font-weight: bold;\n font-size: 24px;\n text-align: center;\n flex-grow: 2;\n display: flex;\n align-items: center;\n justify-content: center;\n box-sizing: border-box;\n}\n\n.interact-button:not(:last-child) {\n margin-right: 10px;\n}\r\n";
5290
+ var css_248z$1 = ".dialog-title {\n font-size: 20px;\n font-weight: bold;\n}\n\n.dialog-text {\n font-size: 16px;\n}\n\n.dialog-box {\n /* border-radius: 10px; */\n /* border: 1px solid #a8a8a8; */\n color: var(--text-color);\n /* background-color: #2e2e2e; */\n padding: 10px;\n padding-left: 2em;\n margin-bottom: 10px;\n}\n\n.dialog-choice {\n color: var(--dialog-choice-color);\n}\n\n.dialog-choice:hover {\n color: var(--dialog-choice-hover-color);\n cursor: pointer;\n}\n\n.buttons-container {\n width: 100%;\n padding: 10px;\n display: flex;\n justify-content: space-evenly;\n align-items: stretch;\n box-sizing: border-box;\n}\n\n.interact-button {\n cursor: pointer;\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none;\n height: 50px;\n color: var(--text-color);\n border: 1px solid black;\n font-weight: bold;\n font-size: 24px;\n text-align: center;\n flex-grow: 2;\n display: flex;\n align-items: center;\n justify-content: center;\n box-sizing: border-box;\n}\n\n.interact-button:not(:last-child) {\n margin-right: 10px;\n}\n";
5191
5291
  styleInject(css_248z$1);
5192
5292
 
5193
5293
  script.render = render;
@@ -5234,7 +5334,7 @@ function render$1(_ctx, _cache, $props, $setup, $data, $options) {
5234
5334
  ], 4))
5235
5335
  }
5236
5336
 
5237
- var css_248z$2 = ".dialog-picture {\n position: absolute;\n width: 80px;\n height: 80px;\n border: 2px solid white;\n border-radius: 10px;\n background-color: grey;\n z-index: 99;\n}\n\n.dialog-picture img {\n width: 100%;\n height: 100%;\n}\r\n";
5337
+ var css_248z$2 = ".dialog-picture {\n position: absolute;\n width: 80px;\n height: 80px;\n border: 2px solid white;\n border-radius: 10px;\n background-color: grey;\n z-index: 99;\n}\n\n.dialog-picture img {\n width: 100%;\n height: 100%;\n}\n";
5238
5338
  styleInject(css_248z$2);
5239
5339
 
5240
5340
  script$1.render = render$1;
@@ -5288,7 +5388,7 @@ function render$2(_ctx, _cache, $props, $setup, $data, $options) {
5288
5388
  }))
5289
5389
  }
5290
5390
 
5291
- var css_248z$3 = ".modal-mask {\n position: absolute;\n z-index: 9998;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n background-color: rgba(0, 0, 0, 0.5);\n transition: opacity 0.3s ease;\n display: flex;\n flex-direction: column;\n flex-shrink: 2 2;\n align-items: center;\n justify-content: center;\n}\n\n.modal-container {\n min-width: 300px;\n max-width: 90vw;\n max-height: 100%;\n overflow-y: hidden;\n margin: 10px auto;\n padding: 20px 30px;\n border-radius: 5px;\n transition: all 0.3s ease;\n font-family: Helvetica, Arial, sans-serif;\n background: linear-gradient(to right, hsl(210, 30%, 20%), hsl(255, 30%, 25%));\n display: flex;\n flex-direction: column;\n}\n\n.modal-header {\n position: relative;\n}\n\n.modal-header h3 {\n flex-shrink: 0;\n margin-top: 0;\n color: var(--secondary);\n}\n\n.modal-body {\n margin: 20px 0;\n overflow-y: auto;\n flex-shrink: 2;\n}\n\n.modal-default-button {\n float: right;\n}\n\n/*\r\n * The following styles are auto-applied to elements with\r\n * transition=\"modal\" when their visibility is toggled\r\n * by Vue.js.\r\n *\r\n * You can easily play with the modal transition by editing\r\n * these styles.\r\n */\n\n.modal-enter {\n opacity: 0;\n}\n\n.modal-leave-active {\n opacity: 0;\n}\n\n.modal-enter .modal-container,\r\n.modal-leave-active .modal-container {\n transform: scale(1.1);\n}\n\n.close-button {\n border: 1px solid var(--text-color);\n border-radius: 50px;\n font-size: 30px;\n font-weight: 700;\n position: absolute;\n right: -20px;\n top: -10px;\n width: 50px;\n height: 50px;\n}\n\n.close-button:hover {\n background-color: var(--focus);\n}\r\n";
5391
+ var css_248z$3 = ".modal-mask {\n position: absolute;\n z-index: 9998;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n background-color: rgba(0, 0, 0, 0.5);\n transition: opacity 0.3s ease;\n display: flex;\n flex-direction: column;\n flex-shrink: 2 2;\n align-items: center;\n justify-content: center;\n}\n\n.modal-container {\n min-width: 300px;\n max-width: 90vw;\n max-height: 100%;\n overflow-y: hidden;\n margin: 10px auto;\n padding: 20px 30px;\n border-radius: 5px;\n transition: all 0.3s ease;\n font-family: Helvetica, Arial, sans-serif;\n background: linear-gradient(to right, hsl(210, 30%, 20%), hsl(255, 30%, 25%));\n display: flex;\n flex-direction: column;\n}\n\n.modal-header {\n position: relative;\n}\n\n.modal-header h3 {\n flex-shrink: 0;\n margin-top: 0;\n color: var(--secondary);\n}\n\n.modal-body {\n margin: 20px 0;\n overflow-y: auto;\n flex-shrink: 2;\n}\n\n.modal-default-button {\n float: right;\n}\n\n/*\n * The following styles are auto-applied to elements with\n * transition=\"modal\" when their visibility is toggled\n * by Vue.js.\n *\n * You can easily play with the modal transition by editing\n * these styles.\n */\n\n.modal-enter {\n opacity: 0;\n}\n\n.modal-leave-active {\n opacity: 0;\n}\n\n.modal-enter .modal-container,\n.modal-leave-active .modal-container {\n transform: scale(1.1);\n}\n\n.close-button {\n border: 1px solid var(--text-color);\n border-radius: 50px;\n font-size: 30px;\n font-weight: 700;\n position: absolute;\n right: -20px;\n top: -10px;\n width: 50px;\n height: 50px;\n}\n\n.close-button:hover {\n background-color: var(--focus);\n}\n";
5292
5392
  styleInject(css_248z$3);
5293
5393
 
5294
5394
  script$2.render = render$2;
@@ -7196,6 +7296,9 @@ var script$3 = defineComponent({
7196
7296
  this.showDebug = true;
7197
7297
  const vmStore = useVM();
7198
7298
  const mainStore = useMain();
7299
+ const questsStore = useQuests();
7300
+ const inventoryStore = useInventory();
7301
+ const skillsStore = useSkills();
7199
7302
  this.$nextTick(() => {
7200
7303
  // eslint-disable-next-line no-unused-vars
7201
7304
  const _variablesEditor = new xJ({
@@ -7203,10 +7306,20 @@ var script$3 = defineComponent({
7203
7306
  props: {
7204
7307
  content: {
7205
7308
  text: undefined,
7206
- json: this.variables,
7309
+ json: {
7310
+ data: this.variables,
7311
+ quests: questsStore.quests,
7312
+ items: inventoryStore.items,
7313
+ skills: skillsStore.skills,
7314
+ skillChecks: skillsStore.skillChecks,
7315
+ }
7207
7316
  },
7208
7317
  onChange: (updatedContent) => {
7209
- vmStore.overrideData(updatedContent.json);
7318
+ vmStore.overrideData(updatedContent.json.data);
7319
+ questsStore.quests = updatedContent.json.quests;
7320
+ inventoryStore.items = updatedContent.json.items;
7321
+ skillsStore.skills = updatedContent.json.skills;
7322
+ skillsStore.skillChecks = updatedContent.json.skillChecks;
7210
7323
  },
7211
7324
  },
7212
7325
  });
@@ -7532,7 +7645,7 @@ function render$3(_ctx, _cache, $props, $setup, $data, $options) {
7532
7645
  ]))
7533
7646
  }
7534
7647
 
7535
- var css_248z$4 = ".debug-menu {\n z-index: 9999;\n}\n\n.debug-button {\n position: fixed;\n bottom: 10px;\n right: 10px;\n padding: 5px;\n}\n\n.error-message {\n color: orangered;\n margin-top: 10px;\n margin-bottom: 10px;\n}\n\n.error-filename {\n color: grey;\n text-decoration: underline;\n}\n\n.debug-menu-container {\n width: 100%;\n}\n\n.search-result {\n border: 1px solid var(--text-color);\n padding: 10px;\n font-weight: 700;\n font-size: 20px;\n width: 100;\n}\n\n.jump-menu-container {\n width: 80%;\n}\n\n.debug-info {\n position: fixed;\n background-color: rgba(0, 0, 0, 0.6);\n border: 1px dotted var(--text-color);\n top: 0;\n left: 0;\n padding: 5px;\n}\n\n.variables-viewer {\n height: 100%;\n}\r\n";
7648
+ var css_248z$4 = ".debug-menu {\n z-index: 9999;\n}\n\n.debug-button {\n position: fixed;\n bottom: 10px;\n right: 10px;\n padding: 5px;\n}\n\n.error-message {\n color: orangered;\n margin-top: 10px;\n margin-bottom: 10px;\n}\n\n.error-filename {\n color: grey;\n text-decoration: underline;\n}\n\n.debug-menu-container {\n width: 100%;\n}\n\n.search-result {\n border: 1px solid var(--text-color);\n padding: 10px;\n font-weight: 700;\n font-size: 20px;\n width: 100;\n}\n\n.jump-menu-container {\n width: 80%;\n}\n\n.debug-info {\n position: fixed;\n background-color: rgba(0, 0, 0, 0.6);\n border: 1px dotted var(--text-color);\n top: 0;\n left: 0;\n padding: 5px;\n}\n\n.variables-viewer {\n height: 100%;\n}\n";
7536
7649
  styleInject(css_248z$4);
7537
7650
 
7538
7651
  script$3.render = render$3;
@@ -7589,7 +7702,7 @@ function render$4(_ctx, _cache, $props, $setup, $data, $options) {
7589
7702
  ]))
7590
7703
  }
7591
7704
 
7592
- var css_248z$5 = ".volume-label {\n /* margin: 5px 20px; */\n margin-right: 10px;\n font-size: 20px;\n font-weight: 700;\n}\n\n.volume-controls {\n font-size: 25px;\n display: flex;\n align-items: center;\n justify-content: center;\n margin: 0 20px;\n}\n\n.volume-slider {\n width: 200px;\n background-color: blue;\n}\r\n";
7705
+ var css_248z$5 = ".volume-label {\n /* margin: 5px 20px; */\n margin-right: 10px;\n font-size: 20px;\n font-weight: 700;\n}\n\n.volume-controls {\n font-size: 25px;\n display: flex;\n align-items: center;\n justify-content: center;\n margin: 0 20px;\n}\n\n.volume-slider {\n width: 200px;\n background-color: blue;\n}\n";
7593
7706
  styleInject(css_248z$5);
7594
7707
 
7595
7708
  script$4.render = render$4;
@@ -7647,7 +7760,7 @@ function render$5(_ctx, _cache, $props, $setup, $data, $options) {
7647
7760
  ], 4))
7648
7761
  }
7649
7762
 
7650
- var css_248z$6 = ".hud {\n position: absolute;\n right: 0;\n top: 0;\n display: flex;\n flex-direction: row-reverse;\n z-index: 3;\n}\n\n.hud-stat {\n border: 1px dotted white;\n background-color: var(--hud-background);\n color: var(--hud-text-color);\n padding: 5px;\n}\n\n.hud-icon {\n display: inline-block;\n height: 1em;\n}\n\n.hud-text {\n margin-left: 5px;\n}\r\n";
7763
+ var css_248z$6 = ".hud {\n position: absolute;\n right: 0;\n top: 0;\n display: flex;\n flex-direction: row-reverse;\n z-index: 3;\n}\n\n.hud-stat {\n border: 1px dotted white;\n background-color: var(--hud-background);\n color: var(--hud-text-color);\n padding: 5px;\n}\n\n.hud-icon {\n display: inline-block;\n height: 1em;\n}\n\n.hud-text {\n margin-left: 5px;\n}\n";
7651
7764
  styleInject(css_248z$6);
7652
7765
 
7653
7766
  script$5.render = render$5;
@@ -7684,7 +7797,7 @@ function render$6(_ctx, _cache, $props, $setup, $data, $options) {
7684
7797
  ]))
7685
7798
  }
7686
7799
 
7687
- var css_248z$7 = "#loading-bar {\n position: relative;\n width: 40vw;\n height: 100px;\n border-radius: 50px;\n background: black;\n}\n\n#inner-loading-bar {\n height: 100%;\n border-radius: 50px 0px 0px 50px;\n background: var(--light-background);\n}\n\n#loading-text {\n z-index: 99999;\n display: flex;\n align-items: center;\n justify-content: space-around;\n position: absolute;\n width: 100%;\n height: 100%;\n top: 0;\n}\r\n";
7800
+ var css_248z$7 = "#loading-bar {\n position: relative;\n width: 40vw;\n height: 100px;\n border-radius: 50px;\n background: black;\n}\n\n#inner-loading-bar {\n height: 100%;\n border-radius: 50px 0px 0px 50px;\n background: var(--light-background);\n}\n\n#loading-text {\n z-index: 99999;\n display: flex;\n align-items: center;\n justify-content: space-around;\n position: absolute;\n width: 100%;\n height: 100%;\n top: 0;\n}\n";
7688
7801
  styleInject(css_248z$7);
7689
7802
 
7690
7803
  script$6.render = render$6;
@@ -7717,27 +7830,11 @@ function render$7(_ctx, _cache, $props, $setup, $data, $options) {
7717
7830
  }))
7718
7831
  }
7719
7832
 
7720
- var css_248z$8 = ".notifications-holder {\n position: fixed;\n top: 0;\n right: 0;\n padding: 10px;\n display: flex;\n flex-direction: column-reverse;\n align-items: center;\n pointer-events: none;\n}\n\n.notification {\n margin-top: 10px;\n margin-bottom: 10px;\n border-radius: 10px;\n padding: 15px;\n background: var(--notifications-bg);\n width: 40vh;\n text-align: center;\n}\r\n";
7833
+ var css_248z$8 = ".notifications-holder {\n position: fixed;\n top: 0;\n right: 0;\n padding: 10px;\n display: flex;\n flex-direction: column-reverse;\n align-items: center;\n pointer-events: none;\n}\n\n.notification {\n margin-top: 10px;\n margin-bottom: 10px;\n border-radius: 10px;\n padding: 15px;\n background: var(--notifications-bg);\n width: 40vh;\n text-align: center;\n}\n";
7721
7834
  styleInject(css_248z$8);
7722
7835
 
7723
7836
  script$7.render = render$7;
7724
7837
 
7725
- function processText(text) {
7726
- const vmStore = useVM();
7727
- const skillStore = useSkills();
7728
- return text.replace(/%{[^}]*}/g, (match) => {
7729
- const key = match.substr(2, match.length - 3);
7730
- const searchableState = {
7731
- data: vmStore.data,
7732
- skills: skillStore.skills,
7733
- items: useInventory().items,
7734
- quests: useQuests().quests,
7735
- };
7736
- const [obj, newKey] = findDataHelper(searchableState, key);
7737
- return obj[newKey];
7738
- });
7739
- }
7740
-
7741
7838
  function aspectRatioFit(screenWidth, screenHeight, gameWidth, gameHeight) {
7742
7839
  const widthRatio = screenWidth / gameWidth;
7743
7840
  const heightRatio = screenHeight / gameHeight;
@@ -7942,7 +8039,7 @@ function render$8(_ctx, _cache, $props, $setup, $data, $options) {
7942
8039
  ]))
7943
8040
  }
7944
8041
 
7945
- var css_248z$9 = ".menu-content {\n text-align: center;\n}\n\n.menu-toggle-button {\n margin: 0;\n padding: 2px;\n border-radius: 5px;\n}\n\n.menu-toggle-button:not(:last-child) {\n margin-right: 10px;\n}\n\n.menu-modal {\n width: 500px;\n}\r\n";
8042
+ var css_248z$9 = ".menu-content {\n text-align: center;\n}\n\n.menu-toggle-button {\n margin: 0;\n padding: 2px;\n border-radius: 5px;\n}\n\n.menu-toggle-button:not(:last-child) {\n margin-right: 10px;\n}\n\n.menu-modal {\n width: 500px;\n}\n";
7946
8043
  styleInject(css_248z$9);
7947
8044
 
7948
8045
  script$8.render = render$8;
@@ -7952,7 +8049,9 @@ var script$9 = defineComponent({
7952
8049
  Modal: script$2,
7953
8050
  VolumeControls: script$4,
7954
8051
  },
7955
- props: {},
8052
+ props: {
8053
+ close: Function,
8054
+ },
7956
8055
  data() { },
7957
8056
  mounted() { },
7958
8057
  methods: {
@@ -7960,9 +8059,6 @@ var script$9 = defineComponent({
7960
8059
  window.close();
7961
8060
  // quit
7962
8061
  },
7963
- close() {
7964
- this.$emit('close');
7965
- },
7966
8062
  mainMenu() {
7967
8063
  useMain().menuReturn();
7968
8064
  this.close();
@@ -8010,7 +8106,7 @@ function render$9(_ctx, _cache, $props, $setup, $data, $options) {
8010
8106
  }, 8, ["onClose"]))
8011
8107
  }
8012
8108
 
8013
- var css_248z$a = ".quit-button {\n margin: 20px;\n text-align: center;\n}\r\n";
8109
+ var css_248z$a = ".quit-button {\n margin: 20px;\n text-align: center;\n}\n";
8014
8110
  styleInject(css_248z$a);
8015
8111
 
8016
8112
  script$9.render = render$9;
@@ -8026,7 +8122,7 @@ var script$a = defineComponent({
8026
8122
  VolumeControls: script$4,
8027
8123
  },
8028
8124
  props: {
8029
- close: (() => { }),
8125
+ close: Function,
8030
8126
  },
8031
8127
  data() {
8032
8128
  return {
@@ -8077,20 +8173,17 @@ var script$a = defineComponent({
8077
8173
  });
8078
8174
 
8079
8175
  const _hoisted_1$9 = /*#__PURE__*/createElementVNode("h3", { class: "title" }, "Skills", -1);
8080
- const _hoisted_2$7 = { class: "menu-content" };
8081
- const _hoisted_3$4 = {
8176
+ const _hoisted_2$7 = {
8082
8177
  key: 0,
8083
8178
  class: "skills-container"
8084
8179
  };
8085
- const _hoisted_4$3 = ["onClick"];
8086
- const _hoisted_5$3 = { class: "skill-title" };
8087
- const _hoisted_6$3 = { class: "skill-xp-container" };
8088
- const _hoisted_7$2 = { class: "skill-xp-text" };
8089
- const _hoisted_8$1 = { class: "skill-level" };
8090
- const _hoisted_9$1 = {
8091
- key: 1,
8092
- class: "flex flex-row skill-description-container"
8093
- };
8180
+ const _hoisted_3$4 = ["onClick"];
8181
+ const _hoisted_4$3 = { class: "skill-title" };
8182
+ const _hoisted_5$3 = { class: "skill-xp-container" };
8183
+ const _hoisted_6$3 = { class: "skill-xp-text" };
8184
+ const _hoisted_7$2 = { class: "skill-level" };
8185
+ const _hoisted_8$1 = { key: 1 };
8186
+ const _hoisted_9$1 = { class: "flex flex-row skill-description-container" };
8094
8187
  const _hoisted_10$1 = { class: "flex skill-left" };
8095
8188
  const _hoisted_11$1 = { class: "flex skill-right" };
8096
8189
  const _hoisted_12$1 = /*#__PURE__*/createElementVNode("hr", { class: "hr-solid" }, null, -1);
@@ -8107,35 +8200,31 @@ function render$a(_ctx, _cache, $props, $setup, $data, $options) {
8107
8200
  _hoisted_1$9
8108
8201
  ]),
8109
8202
  body: withCtx(() => [
8110
- createElementVNode("div", _hoisted_2$7, [
8111
- (!_ctx.chosenSkill)
8112
- ? (openBlock(), createElementBlock("div", _hoisted_3$4, [
8113
- (openBlock(true), createElementBlock(Fragment, null, renderList(_ctx.skillsToDisplay, (skill, key) => {
8114
- return (openBlock(), createElementBlock("button", {
8115
- onClick: () => _ctx.clickSkill(key),
8116
- class: "skill-display",
8117
- style: normalizeStyle(_ctx.getSkillStyle(key)),
8118
- key: key
8119
- }, [
8120
- createElementVNode("h3", _hoisted_5$3, toDisplayString(_ctx.getSkillName(key)), 1),
8121
- createElementVNode("div", _hoisted_6$3, [
8122
- createElementVNode("div", {
8123
- class: "skill-xp-bar",
8124
- style: normalizeStyle(_ctx.xpBarWidth(skill.xp))
8125
- }, null, 4),
8126
- createElementVNode("h3", _hoisted_7$2, toDisplayString(skill.xp) + " / " + toDisplayString(_ctx.xpPerLevel) + " XP ", 1)
8127
- ]),
8128
- createElementVNode("h3", _hoisted_8$1, toDisplayString(skill.level), 1)
8129
- ], 12, _hoisted_4$3))
8130
- }), 128))
8131
- ]))
8132
- : (typeof _ctx.chosenSkill === 'string')
8133
- ? (openBlock(), createElementBlock("div", _hoisted_9$1, [
8203
+ (!_ctx.chosenSkill)
8204
+ ? (openBlock(), createElementBlock("div", _hoisted_2$7, [
8205
+ (openBlock(true), createElementBlock(Fragment, null, renderList(_ctx.skillsToDisplay, (skill, key) => {
8206
+ return (openBlock(), createElementBlock("button", {
8207
+ onClick: () => _ctx.clickSkill(key),
8208
+ class: "skill-display",
8209
+ style: normalizeStyle(_ctx.getSkillStyle(key)),
8210
+ key: key
8211
+ }, [
8212
+ createElementVNode("h3", _hoisted_4$3, toDisplayString(_ctx.getSkillName(key)), 1),
8213
+ createElementVNode("div", _hoisted_5$3, [
8214
+ createElementVNode("div", {
8215
+ class: "skill-xp-bar",
8216
+ style: normalizeStyle(_ctx.xpBarWidth(skill.xp))
8217
+ }, null, 4),
8218
+ createElementVNode("h3", _hoisted_6$3, toDisplayString(skill.xp) + " / " + toDisplayString(_ctx.xpPerLevel) + " XP", 1)
8219
+ ]),
8220
+ createElementVNode("h3", _hoisted_7$2, toDisplayString(skill.level), 1)
8221
+ ], 12, _hoisted_3$4))
8222
+ }), 128))
8223
+ ]))
8224
+ : (typeof _ctx.chosenSkill === 'string')
8225
+ ? (openBlock(), createElementBlock("div", _hoisted_8$1, [
8226
+ createElementVNode("div", _hoisted_9$1, [
8134
8227
  createElementVNode("div", _hoisted_10$1, [
8135
- createElementVNode("button", {
8136
- class: "button",
8137
- onClick: _cache[0] || (_cache[0] = (...args) => (_ctx.closeSkill && _ctx.closeSkill(...args)))
8138
- }, "Back"),
8139
8228
  createElementVNode("div", {
8140
8229
  class: "skill-display",
8141
8230
  style: normalizeStyle(_ctx.getSkillStyle(_ctx.chosenSkill))
@@ -8147,15 +8236,19 @@ function render$a(_ctx, _cache, $props, $setup, $data, $options) {
8147
8236
  createElementVNode("h3", null, "Level: " + toDisplayString(_ctx.skills[_ctx.chosenSkill].level), 1),
8148
8237
  createElementVNode("p", null, toDisplayString(_ctx.skillConf[_ctx.chosenSkill].description), 1)
8149
8238
  ])
8150
- ]))
8151
- : createCommentVNode("", true)
8152
- ])
8239
+ ]),
8240
+ createElementVNode("button", {
8241
+ class: "button",
8242
+ onClick: _cache[0] || (_cache[0] = (...args) => (_ctx.closeSkill && _ctx.closeSkill(...args)))
8243
+ }, toDisplayString('<--'))
8244
+ ]))
8245
+ : createCommentVNode("", true)
8153
8246
  ]),
8154
8247
  _: 1
8155
8248
  }, 8, ["onClose"]))
8156
8249
  }
8157
8250
 
8158
- var css_248z$b = ".skills-modal {\n width: 800px;\n}\n\n.skills-container {\n display: grid;\n grid-auto-rows: auto;\n grid-template-columns: repeat(3, 1fr);\n grid-gap: 20px 20px;\n}\n\n.skill-display {\n width: 200px;\n height: 300px;\n position: relative;\n background-size: cover;\n}\n\n.skill-title {\n position: absolute;\n bottom: 0px;\n text-align: center;\n width: 100%;\n color: var(--skills-text-color);\n background: var(--skills-text-background);\n}\n\n.skill-level {\n position: absolute;\n top: 0;\n right: 0;\n font-weight: 700;\n font-size: 25px;\n color: var(--skills-level-color);\n width: var(--skills-xp-bar-height);\n height: var(--skills-xp-bar-height);\n background-color: var(--skills-level-background);\n}\n\n.skill-description-container {\n justify-content: space-between;\n align-items: center;\n}\n\n.skill-left {\n flex-direction: column;\n}\n\n.skill-right {\n flex-direction: column;\n align-items: baseline;\n}\n\n.skill-xp-container {\n position: absolute;\n top: 0;\n left: 0;\n height: var(--skills-xp-bar-height);\n width: calc(100% - var(--skills-xp-bar-height));\n background-color: rgba(0, 0, 0, 0.5);\n}\n\n.skill-xp-bar {\n position: absolute;\n top: 0;\n left: 0;\n width: 50%;\n height: 100%;\n background-color: rgba(0, 0, 250, 0.5);\n}\n\n.skill-xp-text {\n z-index: 2;\n}\r\n";
8251
+ var css_248z$b = ".skills-modal {\n width: 800px;\n}\n\n.skills-container {\n display: grid;\n grid-auto-rows: auto;\n grid-template-columns: repeat(3, 1fr);\n grid-gap: 20px 20px;\n}\n\n.skill-display {\n width: 200px;\n height: 300px;\n position: relative;\n background-size: cover;\n}\n\n.skill-title {\n position: absolute;\n bottom: 0px;\n text-align: center;\n width: 100%;\n color: var(--skills-text-color);\n background: var(--skills-text-background);\n}\n\n.skill-level {\n position: absolute;\n top: 0;\n right: 0;\n font-weight: 700;\n font-size: 25px;\n color: var(--skills-level-color);\n width: var(--skills-xp-bar-height);\n height: var(--skills-xp-bar-height);\n background-color: var(--skills-level-background);\n}\n\n.skill-description-container {\n justify-content: space-between;\n align-items: stretch;\n}\n\n.skill-left {\n flex-direction: column;\n border: 1px dashed white;\n padding: 10px;\n justify-content: center;\n}\n\n.skill-right {\n border: 1px dashed white;\n flex-direction: column;\n align-items: baseline;\n flex-grow: 2;\n align-items: baseline;\n}\n\n.skill-xp-container {\n position: absolute;\n top: 0;\n left: 0;\n height: var(--skills-xp-bar-height);\n width: calc(100% - var(--skills-xp-bar-height));\n background-color: rgba(0, 0, 0, 0.5);\n}\n\n.skill-xp-bar {\n position: absolute;\n top: 0;\n left: 0;\n width: 50%;\n height: 100%;\n background-color: rgba(0, 0, 250, 0.5);\n}\n\n.skill-xp-text {\n z-index: 2;\n}\n";
8159
8252
  styleInject(css_248z$b);
8160
8253
 
8161
8254
  script$a.render = render$a;
@@ -8163,14 +8256,16 @@ script$a.render = render$a;
8163
8256
  var script$b = defineComponent({
8164
8257
  setup() {
8165
8258
  const store = useInventory();
8259
+ const dialogStore = useDialogStore();
8166
8260
  const items = computed(() => store.items);
8167
- return { items };
8261
+ const currentlyChoosing = computed(() => dialogStore.currentDialog.choices);
8262
+ return { items, currentlyChoosing };
8168
8263
  },
8169
8264
  components: {
8170
8265
  Modal: script$2,
8171
8266
  },
8172
8267
  props: {
8173
- close: (() => { }),
8268
+ close: Function,
8174
8269
  },
8175
8270
  data() {
8176
8271
  return {
@@ -8187,12 +8282,40 @@ var script$b = defineComponent({
8187
8282
  getItemName(item) {
8188
8283
  return this.itemConf[item].name;
8189
8284
  },
8285
+ getItemConf(item) {
8286
+ return this.itemConf[item];
8287
+ },
8190
8288
  clickItem(item) {
8191
8289
  this.chosenId = item;
8192
8290
  },
8193
8291
  closeItem() {
8194
8292
  this.chosenId = false;
8195
8293
  },
8294
+ useItem() {
8295
+ if (this.canUseChosenItem) {
8296
+ const onUse = this.chosenItemConf.onUse;
8297
+ this.close();
8298
+ if (onUse.action === 'jump') {
8299
+ useVM().runLabel(onUse.label);
8300
+ }
8301
+ else if (onUse.action === 'run_label') {
8302
+ useVM().runLabelFunction(onUse.label, true);
8303
+ }
8304
+ else {
8305
+ error(`Unknown action ${onUse.action}`);
8306
+ }
8307
+ }
8308
+ },
8309
+ canUseItem(item) {
8310
+ const conf = this.itemConf[item.id];
8311
+ if (conf &&
8312
+ conf.onUse &&
8313
+ !useInventory().isInteractionTagBlocked(conf.tag) &&
8314
+ !this.currentlyChoosing) {
8315
+ return true;
8316
+ }
8317
+ return false;
8318
+ },
8196
8319
  },
8197
8320
  computed: {
8198
8321
  itemsToDisplay() {
@@ -8210,6 +8333,9 @@ var script$b = defineComponent({
8210
8333
  }
8211
8334
  return null;
8212
8335
  },
8336
+ canUseChosenItem() {
8337
+ return this.canUseItem(this.chosenItem);
8338
+ },
8213
8339
  chosenItemConf() {
8214
8340
  if (this.chosenId) {
8215
8341
  return this.itemConf[this.chosenId];
@@ -8223,18 +8349,15 @@ var script$b = defineComponent({
8223
8349
  });
8224
8350
 
8225
8351
  const _hoisted_1$a = /*#__PURE__*/createElementVNode("h3", { class: "title" }, "Inventory", -1);
8226
- const _hoisted_2$8 = { class: "menu-content" };
8227
- const _hoisted_3$5 = {
8352
+ const _hoisted_2$8 = {
8228
8353
  key: 0,
8229
8354
  class: "inventory-container"
8230
8355
  };
8231
- const _hoisted_4$4 = ["onClick"];
8232
- const _hoisted_5$4 = { class: "item-title" };
8233
- const _hoisted_6$4 = { class: "item-amount" };
8234
- const _hoisted_7$3 = {
8235
- key: 1,
8236
- class: "flex flex-row item-description-container"
8237
- };
8356
+ const _hoisted_3$5 = ["onClick"];
8357
+ const _hoisted_4$4 = { class: "item-title" };
8358
+ const _hoisted_5$4 = { class: "item-amount" };
8359
+ const _hoisted_6$4 = { key: 1 };
8360
+ const _hoisted_7$3 = { class: "flex flex-row item-description-container" };
8238
8361
  const _hoisted_8$2 = { class: "flex item-left" };
8239
8362
  const _hoisted_9$2 = { class: "flex item-right" };
8240
8363
  const _hoisted_10$2 = /*#__PURE__*/createElementVNode("hr", { class: "hr-solid" }, null, -1);
@@ -8256,28 +8379,24 @@ function render$b(_ctx, _cache, $props, $setup, $data, $options) {
8256
8379
  _hoisted_1$a
8257
8380
  ]),
8258
8381
  body: withCtx(() => [
8259
- createElementVNode("div", _hoisted_2$8, [
8260
- (!_ctx.chosenItem && Object.keys(_ctx.itemsToDisplay).length > 0)
8261
- ? (openBlock(), createElementBlock("div", _hoisted_3$5, [
8262
- (openBlock(true), createElementBlock(Fragment, null, renderList(_ctx.itemsToDisplay, (item) => {
8263
- return (openBlock(), createElementBlock("button", {
8264
- onClick: () => _ctx.clickItem(item.id),
8265
- class: "item-display",
8266
- style: normalizeStyle(_ctx.getItemStyle(item.id)),
8267
- key: item.id
8268
- }, [
8269
- createElementVNode("h3", _hoisted_5$4, toDisplayString(_ctx.getItemName(item.id)), 1),
8270
- createElementVNode("h3", _hoisted_6$4, toDisplayString(item.amount), 1)
8271
- ], 12, _hoisted_4$4))
8272
- }), 128))
8273
- ]))
8274
- : (typeof _ctx.chosenId === 'string')
8275
- ? (openBlock(), createElementBlock("div", _hoisted_7$3, [
8382
+ (!_ctx.chosenItem && Object.keys(_ctx.itemsToDisplay).length > 0)
8383
+ ? (openBlock(), createElementBlock("div", _hoisted_2$8, [
8384
+ (openBlock(true), createElementBlock(Fragment, null, renderList(_ctx.itemsToDisplay, (item) => {
8385
+ return (openBlock(), createElementBlock("button", {
8386
+ onClick: () => _ctx.clickItem(item.id),
8387
+ class: "item-display",
8388
+ style: normalizeStyle(_ctx.getItemStyle(item.id)),
8389
+ key: item.id
8390
+ }, [
8391
+ createElementVNode("h3", _hoisted_4$4, toDisplayString(_ctx.getItemName(item.id)), 1),
8392
+ createElementVNode("h3", _hoisted_5$4, toDisplayString(item.amount), 1)
8393
+ ], 12, _hoisted_3$5))
8394
+ }), 128))
8395
+ ]))
8396
+ : (typeof _ctx.chosenId === 'string')
8397
+ ? (openBlock(), createElementBlock("div", _hoisted_6$4, [
8398
+ createElementVNode("div", _hoisted_7$3, [
8276
8399
  createElementVNode("div", _hoisted_8$2, [
8277
- createElementVNode("button", {
8278
- class: "button",
8279
- onClick: _cache[0] || (_cache[0] = (...args) => (_ctx.closeItem && _ctx.closeItem(...args)))
8280
- }, "Back"),
8281
8400
  createElementVNode("div", {
8282
8401
  class: "item-display",
8283
8402
  style: normalizeStyle(_ctx.getItemStyle(_ctx.chosenId))
@@ -8287,17 +8406,25 @@ function render$b(_ctx, _cache, $props, $setup, $data, $options) {
8287
8406
  createElementVNode("h2", null, toDisplayString(_ctx.getItemName(_ctx.chosenId)), 1),
8288
8407
  _hoisted_10$2,
8289
8408
  createElementVNode("h3", null, "Amount: " + toDisplayString(_ctx.chosenItem.amount), 1),
8290
- createElementVNode("p", null, toDisplayString(_ctx.chosenItemConf.description), 1)
8409
+ createElementVNode("p", null, toDisplayString(_ctx.chosenItemConf.description), 1),
8410
+ createElementVNode("button", {
8411
+ onClick: _cache[0] || (_cache[0] = (...args) => (_ctx.useItem && _ctx.useItem(...args))),
8412
+ class: normalizeClass(["button", _ctx.canUseChosenItem ? '' : 'disabled'])
8413
+ }, " Use ", 2)
8291
8414
  ])
8292
- ]))
8293
- : (openBlock(), createElementBlock("div", _hoisted_11$2, _hoisted_13$1))
8294
- ])
8415
+ ]),
8416
+ createElementVNode("button", {
8417
+ class: "button",
8418
+ onClick: _cache[1] || (_cache[1] = (...args) => (_ctx.closeItem && _ctx.closeItem(...args)))
8419
+ }, toDisplayString('<--'))
8420
+ ]))
8421
+ : (openBlock(), createElementBlock("div", _hoisted_11$2, _hoisted_13$1))
8295
8422
  ]),
8296
8423
  _: 1
8297
8424
  }, 8, ["onClose"]))
8298
8425
  }
8299
8426
 
8300
- var css_248z$c = ".inventory-modal {\n width: 800px;\n min-height: 50%;\n}\n\n.inventory-container {\n display: grid;\n grid-auto-rows: auto;\n grid-template-columns: repeat(3, 1fr);\n grid-gap: 20px 20px;\n}\n\n.item-display {\n width: 200px;\n height: 300px;\n position: relative;\n background-repeat: no-repeat;\n background-size: contain;\n}\n\n.item-title {\n position: absolute;\n bottom: 0px;\n text-align: center;\n width: 100%;\n color: var(--inventory-text-color);\n background: var(--inventory-text-background);\n}\n\n.item-amount {\n position: absolute;\n top: 0;\n right: 0;\n font-weight: 700;\n font-size: 25px;\n color: var(--inventory-amount-color);\n width: 40px;\n height: 40px;\n background-color: var(--inventory-amount-background);\n}\n\n.item-description-container {\n justify-content: space-between;\n align-items: center;\n}\n\n.item-left {\n flex-direction: column;\n}\n\n.item-right {\n flex-direction: column;\n align-items: baseline;\n}\r\n";
8427
+ var css_248z$c = ".inventory-modal {\n width: 800px;\n min-height: 50%;\n}\n\n.inventory-container {\n display: grid;\n grid-auto-rows: auto;\n grid-template-columns: repeat(3, 1fr);\n grid-gap: 20px 20px;\n}\n\n.item-display {\n width: 200px;\n height: 300px;\n position: relative;\n background-repeat: no-repeat;\n background-size: contain;\n}\n\n.item-title {\n position: absolute;\n bottom: 0px;\n text-align: center;\n width: 100%;\n color: var(--inventory-text-color);\n background: var(--inventory-text-background);\n}\n\n.item-amount {\n position: absolute;\n top: 0;\n right: 0;\n font-weight: 700;\n font-size: 25px;\n color: var(--inventory-amount-color);\n width: 40px;\n height: 40px;\n background-color: var(--inventory-amount-background);\n}\n\n.item-description-container {\n justify-content: space-between;\n align-items: stretch;\n}\n\n.item-left {\n border: 1px dashed white;\n flex-direction: column;\n padding: 10px;\n justify-content: center;\n}\n\n.item-right {\n border: 1px dashed white;\n flex-direction: column;\n flex-grow: 2;\n align-items: baseline;\n padding: 10px;\n}\n";
8301
8428
  styleInject(css_248z$c);
8302
8429
 
8303
8430
  script$b.render = render$b;
@@ -8314,7 +8441,7 @@ var script$c = defineComponent({
8314
8441
  },
8315
8442
  },
8316
8443
  props: {
8317
- close: (() => { }),
8444
+ close: Function,
8318
8445
  },
8319
8446
  methods: {
8320
8447
  getQuestData(questId) {
@@ -8393,10 +8520,10 @@ function render$c(_ctx, _cache, $props, $setup, $data, $options) {
8393
8520
  key: quest.id
8394
8521
  }, [
8395
8522
  createElementVNode("div", {
8396
- class: normalizeClass(["quest-header",
8397
- quest.state === 'completed'
8398
- ? 'quest-completed'
8399
- : 'quest-in-progress'
8523
+ class: normalizeClass(["quest-header",
8524
+ quest.state === 'completed'
8525
+ ? 'quest-completed'
8526
+ : 'quest-in-progress'
8400
8527
  ])
8401
8528
  }, [
8402
8529
  createElementVNode("h3", _hoisted_3$6, toDisplayString(_ctx.getQuestData(quest.id).title) + " " + toDisplayString(_ctx.getDisplayTextForQuestState(quest)), 1)
@@ -8410,10 +8537,10 @@ function render$c(_ctx, _cache, $props, $setup, $data, $options) {
8410
8537
  key: objective.id
8411
8538
  }, [
8412
8539
  createElementVNode("p", {
8413
- class: normalizeClass(["quest-objective-description",
8414
- objective.state === 'completed'
8415
- ? 'quest-objective-completed'
8416
- : 'quest-objctive-in-progress'
8540
+ class: normalizeClass(["quest-objective-description",
8541
+ objective.state === 'completed'
8542
+ ? 'quest-objective-completed'
8543
+ : 'quest-objctive-in-progress'
8417
8544
  ])
8418
8545
  }, toDisplayString(_ctx.getObjectiveData(quest.id, objective.id).description), 3)
8419
8546
  ]))
@@ -8429,7 +8556,7 @@ function render$c(_ctx, _cache, $props, $setup, $data, $options) {
8429
8556
  }, 8, ["onClose"]))
8430
8557
  }
8431
8558
 
8432
- var css_248z$d = "/* Write CSS for this vue component */\n\n.quests-modal {\n width: 100%;\n min-height: 50%;\n}\n\n/* CSS for .quest-header with row flex */\n\n.quest-header {\n display: flex;\n flex-direction: row;\n align-items: center;\n}\n\n.quest-display {\n}\n\n.quest-title {\n font-size: 1.5rem;\n font-weight: bold;\n margin-bottom: 0.5rem;\n}\n\n.quest-completed {\n color: var(--completed-quest-title-color);\n}\n\n.quest-in-progress {\n color: var(--quest-title-color);\n}\n\n.quest-state {\n font-size: 1.25rem;\n font-weight: bold;\n margin-bottom: 0.5rem;\n}\n\n.quest-description {\n font-size: 1.1rem;\n text-align: justify;\n font-style: italic;\n margin-bottom: 0.5rem;\n}\n\n.quest-objectives-container {\n margin-left: 10px;\n}\n\n.quest-objective-completed {\n color: var(--objective-completed-color);\n text-decoration: line-through;\n}\n\n.quest-objective-in-progress {\n color: var(--objective-in-progress-color);\n}\n\n.quest-objective-description {\n font-size: 1rem;\n margin-bottom: 0.5rem;\n}\r\n";
8559
+ var css_248z$d = "/* Write CSS for this vue component */\n\n.quests-modal {\n width: 100%;\n min-height: 50%;\n}\n\n/* CSS for .quest-header with row flex */\n\n.quest-header {\n display: flex;\n flex-direction: row;\n align-items: center;\n}\n\n.quest-display {\n}\n\n.quest-title {\n font-size: 1.5rem;\n font-weight: bold;\n margin-bottom: 0.5rem;\n}\n\n.quest-completed {\n color: var(--completed-quest-title-color);\n}\n\n.quest-in-progress {\n color: var(--quest-title-color);\n}\n\n.quest-state {\n font-size: 1.25rem;\n font-weight: bold;\n margin-bottom: 0.5rem;\n}\n\n.quest-description {\n font-size: 1.1rem;\n text-align: justify;\n font-style: italic;\n margin-bottom: 0.5rem;\n}\n\n.quest-objectives-container {\n margin-left: 10px;\n}\n\n.quest-objective-completed {\n color: var(--objective-completed-color);\n text-decoration: line-through;\n}\n\n.quest-objective-in-progress {\n color: var(--objective-in-progress-color);\n}\n\n.quest-objective-description {\n font-size: 1rem;\n margin-bottom: 0.5rem;\n}\n";
8433
8560
  styleInject(css_248z$d);
8434
8561
 
8435
8562
  script$c.render = render$c;
@@ -8719,7 +8846,7 @@ var script$d = defineComponent({
8719
8846
  }
8720
8847
  return {
8721
8848
  title,
8722
- text: processText(dialogKey.text),
8849
+ text: dialogKey.text,
8723
8850
  styleId: dialogKey.speaker,
8724
8851
  choices: dialogKey.choices,
8725
8852
  old: index < this.dialog.length - 1,
@@ -8771,26 +8898,26 @@ function render$d(_ctx, _cache, $props, $setup, $data, $options) {
8771
8898
  (_ctx.modal === 'skills')
8772
8899
  ? (openBlock(), createBlock(_component_Skills, {
8773
8900
  key: 0,
8774
- onClose: _ctx.closeModal
8775
- }, null, 8, ["onClose"]))
8901
+ close: _ctx.closeModal
8902
+ }, null, 8, ["close"]))
8776
8903
  : createCommentVNode("", true),
8777
8904
  (_ctx.modal === 'inventory')
8778
8905
  ? (openBlock(), createBlock(_component_Inventory, {
8779
8906
  key: 1,
8780
- onClose: _ctx.closeModal
8781
- }, null, 8, ["onClose"]))
8907
+ close: _ctx.closeModal
8908
+ }, null, 8, ["close"]))
8782
8909
  : createCommentVNode("", true),
8783
8910
  (_ctx.modal === 'quests')
8784
8911
  ? (openBlock(), createBlock(_component_Quests, {
8785
8912
  key: 2,
8786
- onClose: _ctx.closeModal
8787
- }, null, 8, ["onClose"]))
8913
+ close: _ctx.closeModal
8914
+ }, null, 8, ["close"]))
8788
8915
  : createCommentVNode("", true),
8789
8916
  (_ctx.modal === 'menu')
8790
8917
  ? (openBlock(), createBlock(_component_MainMenu, {
8791
8918
  key: 3,
8792
- onClose: _ctx.closeModal
8793
- }, null, 8, ["onClose"]))
8919
+ close: _ctx.closeModal
8920
+ }, null, 8, ["close"]))
8794
8921
  : createCommentVNode("", true),
8795
8922
  createVNode(Transition, { name: "fade" }, {
8796
8923
  default: withCtx(() => [
@@ -8877,7 +9004,7 @@ function render$d(_ctx, _cache, $props, $setup, $data, $options) {
8877
9004
  ], 4))
8878
9005
  }
8879
9006
 
8880
- var css_248z$e = "#app {\n background-color: var(--bg-color);\n width: 100%;\n height: 100%;\n position: absolute;\n display: flex;\n flex-direction: row;\n align-items: center;\n justify-content: center;\n color: var(--text-color);\n box-sizing: border-box;\n overflow: hidden;\n transform-origin: center center;\n}\n\n.game {\n background-color: var(--bg-color);\n position: relative;\n display: flex;\n flex-direction: row;\n align-items: center;\n justify-content: space-between;\n width: 100%;\n height: 100%;\n box-sizing: border-box;\n overflow: hidden;\n}\n\n.interact-button {\n height: 50px;\n border: 1px solid black;\n font-weight: bold;\n font-size: 20px;\n text-align: center;\n flex-grow: 2;\n display: flex;\n align-items: center;\n justify-content: center;\n box-sizing: border-box;\n}\n\n.interact-button:not(:last-child) {\n margin-right: 10px;\n}\n\n.dialog-container {\n flex-shrink: 2;\n /* padding: 20px; */\n min-height: 100%;\n width: 100%;\n background-color: (var(--bg-color));\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n justify-content: flex-end;\n align-items: center;\n overflow-x: hidden;\n}\n\n.dialog {\n overflow-y: auto;\n overflow-x: hidden;\n position: relative;\n -ms-overflow-style: none; /* IE and Edge */\n scrollbar-width: none; /* Firefox */\n}\n\n.dialog::-webkit-scrollbar {\n display: none; /* webkit */\n}\n\n.dialog * {\n overflow-anchor: none;\n}\n\n.background {\n margin: 0;\n}\n\n#background-canvas {\n height: 100%;\n}\n\n.anchor {\n overflow-anchor: auto;\n height: 1px;\n}\n\n.menu-toggle {\n position: fixed;\n bottom: 0px;\n right: 15%;\n z-index: 2;\n}\n\n#game-title-container {\n margin-bottom: 50px;\n}\n\n#game-title-text {\n text-align: center;\n font-size: 50px;\n}\n\n.menu-button {\n font-size: 25px;\n}\r\n";
9007
+ var css_248z$e = "#app {\n background-color: var(--bg-color);\n width: 100%;\n height: 100%;\n position: absolute;\n display: flex;\n flex-direction: row;\n align-items: center;\n justify-content: center;\n color: var(--text-color);\n box-sizing: border-box;\n overflow: hidden;\n transform-origin: center center;\n}\n\n.game {\n background-color: var(--bg-color);\n position: relative;\n display: flex;\n flex-direction: row;\n align-items: center;\n justify-content: space-between;\n width: 100%;\n height: 100%;\n box-sizing: border-box;\n overflow: hidden;\n}\n\n.interact-button {\n height: 50px;\n border: 1px solid black;\n font-weight: bold;\n font-size: 20px;\n text-align: center;\n flex-grow: 2;\n display: flex;\n align-items: center;\n justify-content: center;\n box-sizing: border-box;\n}\n\n.interact-button:not(:last-child) {\n margin-right: 10px;\n}\n\n.dialog-container {\n flex-shrink: 2;\n /* padding: 20px; */\n min-height: 100%;\n width: 100%;\n background-color: (var(--bg-color));\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n justify-content: flex-end;\n align-items: center;\n overflow-x: hidden;\n}\n\n.dialog {\n overflow-y: auto;\n overflow-x: hidden;\n position: relative;\n -ms-overflow-style: none; /* IE and Edge */\n scrollbar-width: none; /* Firefox */\n}\n\n.dialog::-webkit-scrollbar {\n display: none; /* webkit */\n}\n\n.dialog * {\n overflow-anchor: none;\n}\n\n.background {\n margin: 0;\n}\n\n#background-canvas {\n height: 100%;\n}\n\n.anchor {\n overflow-anchor: auto;\n height: 1px;\n}\n\n.menu-toggle {\n position: fixed;\n bottom: 0px;\n right: 15%;\n z-index: 2;\n}\n\n#game-title-container {\n margin-bottom: 50px;\n}\n\n#game-title-text {\n text-align: center;\n font-size: 50px;\n}\n\n.menu-button {\n font-size: 25px;\n}\n";
8881
9008
  styleInject(css_248z$e);
8882
9009
 
8883
9010
  script$d.render = render$d;
@@ -9164,8 +9291,7 @@ const ifFunction = async (cmd) => {
9164
9291
  branch: newBranch,
9165
9292
  currentIndex: 0,
9166
9293
  };
9167
- vmStore.addStack(newStack);
9168
- return vmStore.runLine();
9294
+ return vmStore.addStack(newStack);
9169
9295
  }
9170
9296
  return vmStore.nextLine();
9171
9297
  };
@@ -9390,8 +9516,7 @@ const addItemPlugin = new CommandPlugin('add_item', async (cmd) => {
9390
9516
  amount,
9391
9517
  });
9392
9518
  return useVM().nextLine();
9393
- }, generateParser('add_item'));
9394
-
9519
+ }, generateParser('add_item'));
9395
9520
  // Write a CommandPlugin for removeing items to the inventory store
9396
9521
  const removeItemPlugin = new CommandPlugin('remove_item', async (cmd) => {
9397
9522
  const id = cmd.args[0];
@@ -9402,7 +9527,21 @@ const removeItemPlugin = new CommandPlugin('remove_item', async (cmd) => {
9402
9527
  amount,
9403
9528
  });
9404
9529
  return useVM().nextLine();
9405
- }, generateParser('remove_item'));
9530
+ }, generateParser('remove_item'));
9531
+ // Write a CommandPlugin for enabling an interactiongTag in the inventory store
9532
+ const enableInteractionPlugin = new CommandPlugin('enable_interaction', async (cmd) => {
9533
+ const tag = cmd.args[0];
9534
+ const inventory = useInventory();
9535
+ inventory.enableInteraction(tag);
9536
+ return useVM().nextLine();
9537
+ }, generateParser('enable_interaction'));
9538
+ // Write a CommandPlugin for disabling an interactiongTag in the inventory store
9539
+ const disableInteractionPlugin = new CommandPlugin('disable_interaction', async (cmd) => {
9540
+ const tag = cmd.args[0];
9541
+ const inventory = useInventory();
9542
+ inventory.disableInteraction(tag);
9543
+ return useVM().nextLine();
9544
+ }, generateParser('disable_interaction'));
9406
9545
 
9407
9546
  // Write a CommandPlugin for starting a quest with the useQuests quests store
9408
9547
  const startQuestPlugin = new CommandPlugin('start_quest', async (cmd) => {
@@ -9439,8 +9578,16 @@ const completeQuestPlugin = new CommandPlugin('complete_quest', async (cmd) => {
9439
9578
  return useVM().nextLine();
9440
9579
  }, generateParser('complete_quest'));
9441
9580
 
9581
+ // Write a CommandPlugin for running a label using the runLabelFunction of the useVM store
9582
+ const runLabelPlugin = new CommandPlugin('run_label', async (cmd) => {
9583
+ const label = cmd.args[0];
9584
+ if (!label) {
9585
+ error(`run_label command needs a label to argument run`);
9586
+ }
9587
+ await useVM().runLabelFunction(label);
9588
+ }, generateParser('run_label'));
9589
+
9442
9590
  function registerBaseCommands(vm) {
9443
- vm.addCommand(addItemPlugin);
9444
9591
  vm.addCommand(addLevelPlugin);
9445
9592
  vm.addCommand(addStatPlugin);
9446
9593
  vm.addCommand(addXpPlugin);
@@ -9452,7 +9599,6 @@ function registerBaseCommands(vm) {
9452
9599
  vm.addCommand(notifyPlugin);
9453
9600
  vm.addCommand(pauseCommand);
9454
9601
  vm.addCommand(playCommand);
9455
- vm.addCommand(removeItemPlugin);
9456
9602
  vm.addCommand(setButtonCommand);
9457
9603
  vm.addCommand(setScreenCommand);
9458
9604
  vm.addCommand(setStatCommand);
@@ -9461,11 +9607,19 @@ function registerBaseCommands(vm) {
9461
9607
  vm.addCommand(talkCommand);
9462
9608
  vm.addCommand(textCommandPlugin);
9463
9609
  vm.addCommand(waitCommand);
9610
+ // functions and labels
9611
+ vm.addCommand(jumpCommand);
9612
+ vm.addCommand(runLabelPlugin);
9464
9613
  // Quests
9465
9614
  vm.addCommand(startQuestPlugin);
9466
9615
  vm.addCommand(startObjectivePlugin);
9467
9616
  vm.addCommand(completeObjectivePlugin);
9468
9617
  vm.addCommand(completeQuestPlugin);
9618
+ // Inventory
9619
+ vm.addCommand(addItemPlugin);
9620
+ vm.addCommand(removeItemPlugin);
9621
+ vm.addCommand(enableInteractionPlugin);
9622
+ vm.addCommand(disableInteractionPlugin);
9469
9623
  }
9470
9624
 
9471
9625
  class NarratPlugin {
@@ -9508,7 +9662,7 @@ async function startApp(config, options) {
9508
9662
  });
9509
9663
  registerBaseCommands(vm);
9510
9664
  logManager.setupDebugger(options.debug);
9511
- console.log('%c Narrat game engine – 1.2.1 - June 25, 2022 14:20:12', 'background: #222; color: #bada55');
9665
+ console.log('%c Narrat game engine – 1.3.2 - June 26, 2022 18:33:37', 'background: #222; color: #bada55');
9512
9666
  vm.callHook('onNarratSetup');
9513
9667
  app.mount('#game-holder');
9514
9668
  if (options.debug) {