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.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
  'use strict';
3
3
 
4
4
  Object.defineProperty(exports, '__esModule', { value: true });
@@ -34,7 +34,7 @@ function styleInject(css, ref) {
34
34
  }
35
35
  }
36
36
 
37
- 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";
37
+ 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";
38
38
  styleInject(css_248z);
39
39
 
40
40
  const f=vue.ref([]),v=vue.ref(null),m=vue.ref(null),g=vue.ref(null),h=vue.reactive({current:""}),y=[],b=vue.ref(!1),k=vue.readonly(f),w=vue.readonly(v),M=vue.readonly(m),q=vue.readonly(g),x=vue.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;}};
@@ -102,6 +102,11 @@ const defaultConfig = {
102
102
  },
103
103
  hudStats: {},
104
104
  items: {},
105
+ interactionTags: {
106
+ default: {
107
+ onlyInteractOutsideOfScripts: true,
108
+ },
109
+ },
105
110
  quests: {},
106
111
  };
107
112
 
@@ -3564,203 +3569,6 @@ function randomId() {
3564
3569
  return `${Date.now() - Math.floor(Math.random() * 99999999)}`;
3565
3570
  }
3566
3571
 
3567
- // Create a pinia store named dialog with a state using the type DialogState, with actions addDialog and clearDialog
3568
- const useDialogStore = pinia.defineStore('dialog', {
3569
- state: () => ({
3570
- dialog: [],
3571
- }),
3572
- actions: {
3573
- generateSaveData() {
3574
- return {
3575
- dialog: this.dialog,
3576
- };
3577
- },
3578
- loadSaveData(data) {
3579
- this.dialog = data.dialog;
3580
- },
3581
- addDialog(dialog) {
3582
- this.dialog.push({
3583
- ...dialog,
3584
- interactive: dialog.interactive ?? false,
3585
- id: randomId(),
3586
- });
3587
- },
3588
- clearDialog() {
3589
- this.dialog.splice(0, this.dialog.length);
3590
- },
3591
- reset() {
3592
- this.dialog = [];
3593
- },
3594
- },
3595
- });
3596
-
3597
- var isMergeableObject = function isMergeableObject(value) {
3598
- return isNonNullObject(value)
3599
- && !isSpecial(value)
3600
- };
3601
-
3602
- function isNonNullObject(value) {
3603
- return !!value && typeof value === 'object'
3604
- }
3605
-
3606
- function isSpecial(value) {
3607
- var stringValue = Object.prototype.toString.call(value);
3608
-
3609
- return stringValue === '[object RegExp]'
3610
- || stringValue === '[object Date]'
3611
- || isReactElement(value)
3612
- }
3613
-
3614
- // see https://github.com/facebook/react/blob/b5ac963fb791d1298e7f396236383bc955f916c1/src/isomorphic/classic/element/ReactElement.js#L21-L25
3615
- var canUseSymbol = typeof Symbol === 'function' && Symbol.for;
3616
- var REACT_ELEMENT_TYPE = canUseSymbol ? Symbol.for('react.element') : 0xeac7;
3617
-
3618
- function isReactElement(value) {
3619
- return value.$$typeof === REACT_ELEMENT_TYPE
3620
- }
3621
-
3622
- function emptyTarget(val) {
3623
- return Array.isArray(val) ? [] : {}
3624
- }
3625
-
3626
- function cloneUnlessOtherwiseSpecified(value, options) {
3627
- return (options.clone !== false && options.isMergeableObject(value))
3628
- ? deepmerge(emptyTarget(value), value, options)
3629
- : value
3630
- }
3631
-
3632
- function defaultArrayMerge(target, source, options) {
3633
- return target.concat(source).map(function(element) {
3634
- return cloneUnlessOtherwiseSpecified(element, options)
3635
- })
3636
- }
3637
-
3638
- function getMergeFunction(key, options) {
3639
- if (!options.customMerge) {
3640
- return deepmerge
3641
- }
3642
- var customMerge = options.customMerge(key);
3643
- return typeof customMerge === 'function' ? customMerge : deepmerge
3644
- }
3645
-
3646
- function getEnumerableOwnPropertySymbols(target) {
3647
- return Object.getOwnPropertySymbols
3648
- ? Object.getOwnPropertySymbols(target).filter(function(symbol) {
3649
- return target.propertyIsEnumerable(symbol)
3650
- })
3651
- : []
3652
- }
3653
-
3654
- function getKeys(target) {
3655
- return Object.keys(target).concat(getEnumerableOwnPropertySymbols(target))
3656
- }
3657
-
3658
- function propertyIsOnObject(object, property) {
3659
- try {
3660
- return property in object
3661
- } catch(_) {
3662
- return false
3663
- }
3664
- }
3665
-
3666
- // Protects from prototype poisoning and unexpected merging up the prototype chain.
3667
- function propertyIsUnsafe(target, key) {
3668
- return propertyIsOnObject(target, key) // Properties are safe to merge if they don't exist in the target yet,
3669
- && !(Object.hasOwnProperty.call(target, key) // unsafe if they exist up the prototype chain,
3670
- && Object.propertyIsEnumerable.call(target, key)) // and also unsafe if they're nonenumerable.
3671
- }
3672
-
3673
- function mergeObject(target, source, options) {
3674
- var destination = {};
3675
- if (options.isMergeableObject(target)) {
3676
- getKeys(target).forEach(function(key) {
3677
- destination[key] = cloneUnlessOtherwiseSpecified(target[key], options);
3678
- });
3679
- }
3680
- getKeys(source).forEach(function(key) {
3681
- if (propertyIsUnsafe(target, key)) {
3682
- return
3683
- }
3684
-
3685
- if (propertyIsOnObject(target, key) && options.isMergeableObject(source[key])) {
3686
- destination[key] = getMergeFunction(key, options)(target[key], source[key], options);
3687
- } else {
3688
- destination[key] = cloneUnlessOtherwiseSpecified(source[key], options);
3689
- }
3690
- });
3691
- return destination
3692
- }
3693
-
3694
- function deepmerge(target, source, options) {
3695
- options = options || {};
3696
- options.arrayMerge = options.arrayMerge || defaultArrayMerge;
3697
- options.isMergeableObject = options.isMergeableObject || isMergeableObject;
3698
- // cloneUnlessOtherwiseSpecified is added to `options` so that custom arrayMerge()
3699
- // implementations can use it. The caller may not replace it.
3700
- options.cloneUnlessOtherwiseSpecified = cloneUnlessOtherwiseSpecified;
3701
-
3702
- var sourceIsArray = Array.isArray(source);
3703
- var targetIsArray = Array.isArray(target);
3704
- var sourceAndTargetTypesMatch = sourceIsArray === targetIsArray;
3705
-
3706
- if (!sourceAndTargetTypesMatch) {
3707
- return cloneUnlessOtherwiseSpecified(source, options)
3708
- } else if (sourceIsArray) {
3709
- return options.arrayMerge(target, source, options)
3710
- } else {
3711
- return mergeObject(target, source, options)
3712
- }
3713
- }
3714
-
3715
- deepmerge.all = function deepmergeAll(array, options) {
3716
- if (!Array.isArray(array)) {
3717
- throw new Error('first argument should be an array')
3718
- }
3719
-
3720
- return array.reduce(function(prev, next) {
3721
- return deepmerge(prev, next, options)
3722
- }, {})
3723
- };
3724
-
3725
- var deepmerge_1 = deepmerge;
3726
-
3727
- var cjs = deepmerge_1;
3728
-
3729
- // Create a pinia store named hud with a state using the type HudState, and save type HudSave, with actions:
3730
- // setupHudStats(stats: { [key: string]: HudStatConfig }): Iterates the stats argument to add new stats to the state
3731
- // setStat(stat: string, value: number): Sets the value of a stat
3732
- // addStat(stat: string, value: number): Adds a value to a stat
3733
- // generateSaveData(): Function that generates a HudSave object from the data in the state
3734
- // loadSaveData(data: HudSave): Function that loads the data into the state
3735
- const useHud = pinia.defineStore('hud', {
3736
- state: () => ({
3737
- hudStats: {},
3738
- }),
3739
- actions: {
3740
- setupHudStats(stats) {
3741
- for (const stat in stats) {
3742
- this.hudStats[stat] = {
3743
- value: stats[stat].startingValue,
3744
- };
3745
- }
3746
- },
3747
- setStat(stat, value) {
3748
- this.hudStats[stat].value = value;
3749
- },
3750
- addStat(stat, value) {
3751
- this.hudStats[stat].value += value;
3752
- },
3753
- generateSaveData() {
3754
- return {
3755
- hudStats: this.hudStats,
3756
- };
3757
- },
3758
- loadSaveData(data) {
3759
- this.hudStats = cjs(this.hudStats, data.hudStats);
3760
- },
3761
- },
3762
- });
3763
-
3764
3572
  // Generate a pinia store named notifications with a state using the type NotificationsState, and save type NotificationsSave, with actions:
3765
3573
  // addNotification(text: string): Adds a new notification to the state, and deletes it after a timeout
3766
3574
  // deleteNotification(id: string): Deletes a notification from the state
@@ -3789,15 +3597,18 @@ const useNotifications = pinia.defineStore('notifications', {
3789
3597
  const useInventory = pinia.defineStore('inventory', {
3790
3598
  state: () => ({
3791
3599
  items: {},
3600
+ interactionTags: {},
3792
3601
  }),
3793
3602
  actions: {
3794
3603
  generateSaveData() {
3795
3604
  return {
3796
3605
  items: this.items,
3606
+ interactionTags: this.interactionTags,
3797
3607
  };
3798
3608
  },
3799
3609
  loadSaveData(save) {
3800
3610
  this.items = { ...this.items, ...save.items };
3611
+ this.interactionTags = { ...save.interactionTags };
3801
3612
  },
3802
3613
  setupItems(items) {
3803
3614
  Object.keys(items).forEach((key) => {
@@ -3823,6 +3634,49 @@ const useInventory = pinia.defineStore('inventory', {
3823
3634
  }
3824
3635
  useNotifications().addNotification(`Received item: ${getItemConfig(item.id).name} x ${item.amount}`);
3825
3636
  },
3637
+ enableInteraction(tag) {
3638
+ if (!tag) {
3639
+ tag = 'default';
3640
+ }
3641
+ this.interactionTags[tag] = {
3642
+ blockedInteraction: false,
3643
+ };
3644
+ },
3645
+ disableInteraction(tag) {
3646
+ if (!tag) {
3647
+ tag = 'default';
3648
+ }
3649
+ this.interactionTags[tag] = {
3650
+ blockedInteraction: true,
3651
+ };
3652
+ },
3653
+ onScriptStart() {
3654
+ const tags = getConfig().interactionTags;
3655
+ Object.keys(tags).forEach((tag) => {
3656
+ const conf = tags[tag];
3657
+ if (conf.onlyInteractOutsideOfScripts) {
3658
+ this.disableInteraction(tag);
3659
+ }
3660
+ });
3661
+ },
3662
+ onScriptEnd() {
3663
+ const tags = getConfig().interactionTags;
3664
+ Object.keys(tags).forEach((tag) => {
3665
+ const conf = tags[tag];
3666
+ if (conf.onlyInteractOutsideOfScripts) {
3667
+ this.enableInteraction(tag);
3668
+ }
3669
+ });
3670
+ },
3671
+ isInteractionTagBlocked(tag) {
3672
+ if (!tag) {
3673
+ tag = 'default';
3674
+ }
3675
+ if (this.interactionTags[tag]) {
3676
+ return this.interactionTags[tag].blockedInteraction;
3677
+ }
3678
+ return false;
3679
+ },
3826
3680
  remove(item) {
3827
3681
  const existingItem = this.getExistingItem(item.id);
3828
3682
  if (existingItem) {
@@ -3842,93 +3696,6 @@ const useInventory = pinia.defineStore('inventory', {
3842
3696
  },
3843
3697
  });
3844
3698
 
3845
- // Create a pinia store named skills with a state using the type Skills, with actions:
3846
- // setupSkillCheck(skillCheck: SkillCheckState, id: string)
3847
- // passSkillCheck(skillCheckId: string)
3848
- // failSkillCheck(skillCheckId: string)
3849
- // generateSaveData(): Function that generates a Skills object from the data in the state
3850
- // loadSaveData(data: Skills): Function that loads the data into the state
3851
- // setupSkills(skills: { [key: string]: SkillData})
3852
- // 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
3853
- // incrementSkill(skill: string, amount: number): Increments the level of a skill by amount
3854
- const useSkills = pinia.defineStore('skills', {
3855
- state: () => ({
3856
- skillChecks: {},
3857
- skills: {},
3858
- }),
3859
- actions: {
3860
- setupSkillCheck(skillCheck, id) {
3861
- this.skillChecks[id] = skillCheck;
3862
- },
3863
- passSkillCheck(skillCheckId) {
3864
- this.skillChecks[skillCheckId].passed = true;
3865
- this.skillChecks[skillCheckId].available = false;
3866
- },
3867
- failSkillCheck(skillCheckId) {
3868
- this.skillChecks[skillCheckId].passed = false;
3869
- this.skillChecks[skillCheckId].available = false;
3870
- },
3871
- generateSaveData() {
3872
- return {
3873
- skillChecks: this.skillChecks,
3874
- skills: this.skills,
3875
- };
3876
- },
3877
- loadSaveData(data) {
3878
- this.skillChecks = cjs(this.skillChecks, data.skillChecks);
3879
- this.skills = cjs(this.skills, data.skills);
3880
- },
3881
- setupSkills(skills) {
3882
- // 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.
3883
- for (const skill in skills) {
3884
- this.skills[skill] = {
3885
- level: skills[skill].startingLevel || 0,
3886
- xp: 0,
3887
- };
3888
- }
3889
- },
3890
- addXp(skill, xp) {
3891
- const skillData = this.skills[skill];
3892
- skillData.xp += xp;
3893
- if (skillData.xp >= getConfig().skillOptions.xpPerLevel) {
3894
- skillData.xp = 0;
3895
- skillData.level++;
3896
- this.levelledUp(skill);
3897
- }
3898
- },
3899
- incrementSkill(skill, amount) {
3900
- this.skills[skill].level += amount;
3901
- this.levelledUp(skill);
3902
- },
3903
- levelledUp(skill) {
3904
- const skillName = getConfig().skills[skill].name;
3905
- const skillLevel = this.skills[skill].level;
3906
- useNotifications().addNotification(`Your skill in ${skillName} is now level ${skillLevel}`);
3907
- },
3908
- },
3909
- });
3910
-
3911
- function getFile(url) {
3912
- return new Promise((resolve, reject) => {
3913
- // Set up our HTTP request
3914
- const xhr = new XMLHttpRequest();
3915
- // Setup our listener to process completed requests
3916
- xhr.onload = function () {
3917
- // Process our return data
3918
- if (xhr.status >= 200 && xhr.status < 300) {
3919
- // This will run when the request is successful
3920
- resolve(xhr.responseText);
3921
- }
3922
- else {
3923
- reject(xhr.status);
3924
- // This will run when it's not
3925
- }
3926
- };
3927
- xhr.open('GET', url);
3928
- xhr.send();
3929
- });
3930
- }
3931
-
3932
3699
  const everyObject = (object, predicate) => {
3933
3700
  for (const key in object) {
3934
3701
  if (!predicate(object[key])) {
@@ -4004,26 +3771,248 @@ const useQuests = pinia.defineStore('quests', {
4004
3771
  }
4005
3772
  useNotifications().addNotification(`Quest completed: ${getQuestConfig(questId).title}`);
4006
3773
  },
4007
- isQuestCompleted(questId) {
4008
- const quest = this.getQuest(questId);
4009
- return everyObject(quest.objectives, (objective) => objective.state === 'completed');
3774
+ isQuestCompleted(questId) {
3775
+ const quest = this.getQuest(questId);
3776
+ return everyObject(quest.objectives, (objective) => objective.state === 'completed');
3777
+ },
3778
+ removeQuest(id) {
3779
+ delete this.quests[id];
3780
+ },
3781
+ generateSaveData() {
3782
+ return {
3783
+ quests: {
3784
+ ...this.quests,
3785
+ },
3786
+ };
3787
+ },
3788
+ loadSaveData(data) {
3789
+ this.quests = data.quests;
3790
+ },
3791
+ },
3792
+ });
3793
+
3794
+ var isMergeableObject = function isMergeableObject(value) {
3795
+ return isNonNullObject(value)
3796
+ && !isSpecial(value)
3797
+ };
3798
+
3799
+ function isNonNullObject(value) {
3800
+ return !!value && typeof value === 'object'
3801
+ }
3802
+
3803
+ function isSpecial(value) {
3804
+ var stringValue = Object.prototype.toString.call(value);
3805
+
3806
+ return stringValue === '[object RegExp]'
3807
+ || stringValue === '[object Date]'
3808
+ || isReactElement(value)
3809
+ }
3810
+
3811
+ // see https://github.com/facebook/react/blob/b5ac963fb791d1298e7f396236383bc955f916c1/src/isomorphic/classic/element/ReactElement.js#L21-L25
3812
+ var canUseSymbol = typeof Symbol === 'function' && Symbol.for;
3813
+ var REACT_ELEMENT_TYPE = canUseSymbol ? Symbol.for('react.element') : 0xeac7;
3814
+
3815
+ function isReactElement(value) {
3816
+ return value.$$typeof === REACT_ELEMENT_TYPE
3817
+ }
3818
+
3819
+ function emptyTarget(val) {
3820
+ return Array.isArray(val) ? [] : {}
3821
+ }
3822
+
3823
+ function cloneUnlessOtherwiseSpecified(value, options) {
3824
+ return (options.clone !== false && options.isMergeableObject(value))
3825
+ ? deepmerge(emptyTarget(value), value, options)
3826
+ : value
3827
+ }
3828
+
3829
+ function defaultArrayMerge(target, source, options) {
3830
+ return target.concat(source).map(function(element) {
3831
+ return cloneUnlessOtherwiseSpecified(element, options)
3832
+ })
3833
+ }
3834
+
3835
+ function getMergeFunction(key, options) {
3836
+ if (!options.customMerge) {
3837
+ return deepmerge
3838
+ }
3839
+ var customMerge = options.customMerge(key);
3840
+ return typeof customMerge === 'function' ? customMerge : deepmerge
3841
+ }
3842
+
3843
+ function getEnumerableOwnPropertySymbols(target) {
3844
+ return Object.getOwnPropertySymbols
3845
+ ? Object.getOwnPropertySymbols(target).filter(function(symbol) {
3846
+ return target.propertyIsEnumerable(symbol)
3847
+ })
3848
+ : []
3849
+ }
3850
+
3851
+ function getKeys(target) {
3852
+ return Object.keys(target).concat(getEnumerableOwnPropertySymbols(target))
3853
+ }
3854
+
3855
+ function propertyIsOnObject(object, property) {
3856
+ try {
3857
+ return property in object
3858
+ } catch(_) {
3859
+ return false
3860
+ }
3861
+ }
3862
+
3863
+ // Protects from prototype poisoning and unexpected merging up the prototype chain.
3864
+ function propertyIsUnsafe(target, key) {
3865
+ return propertyIsOnObject(target, key) // Properties are safe to merge if they don't exist in the target yet,
3866
+ && !(Object.hasOwnProperty.call(target, key) // unsafe if they exist up the prototype chain,
3867
+ && Object.propertyIsEnumerable.call(target, key)) // and also unsafe if they're nonenumerable.
3868
+ }
3869
+
3870
+ function mergeObject(target, source, options) {
3871
+ var destination = {};
3872
+ if (options.isMergeableObject(target)) {
3873
+ getKeys(target).forEach(function(key) {
3874
+ destination[key] = cloneUnlessOtherwiseSpecified(target[key], options);
3875
+ });
3876
+ }
3877
+ getKeys(source).forEach(function(key) {
3878
+ if (propertyIsUnsafe(target, key)) {
3879
+ return
3880
+ }
3881
+
3882
+ if (propertyIsOnObject(target, key) && options.isMergeableObject(source[key])) {
3883
+ destination[key] = getMergeFunction(key, options)(target[key], source[key], options);
3884
+ } else {
3885
+ destination[key] = cloneUnlessOtherwiseSpecified(source[key], options);
3886
+ }
3887
+ });
3888
+ return destination
3889
+ }
3890
+
3891
+ function deepmerge(target, source, options) {
3892
+ options = options || {};
3893
+ options.arrayMerge = options.arrayMerge || defaultArrayMerge;
3894
+ options.isMergeableObject = options.isMergeableObject || isMergeableObject;
3895
+ // cloneUnlessOtherwiseSpecified is added to `options` so that custom arrayMerge()
3896
+ // implementations can use it. The caller may not replace it.
3897
+ options.cloneUnlessOtherwiseSpecified = cloneUnlessOtherwiseSpecified;
3898
+
3899
+ var sourceIsArray = Array.isArray(source);
3900
+ var targetIsArray = Array.isArray(target);
3901
+ var sourceAndTargetTypesMatch = sourceIsArray === targetIsArray;
3902
+
3903
+ if (!sourceAndTargetTypesMatch) {
3904
+ return cloneUnlessOtherwiseSpecified(source, options)
3905
+ } else if (sourceIsArray) {
3906
+ return options.arrayMerge(target, source, options)
3907
+ } else {
3908
+ return mergeObject(target, source, options)
3909
+ }
3910
+ }
3911
+
3912
+ deepmerge.all = function deepmergeAll(array, options) {
3913
+ if (!Array.isArray(array)) {
3914
+ throw new Error('first argument should be an array')
3915
+ }
3916
+
3917
+ return array.reduce(function(prev, next) {
3918
+ return deepmerge(prev, next, options)
3919
+ }, {})
3920
+ };
3921
+
3922
+ var deepmerge_1 = deepmerge;
3923
+
3924
+ var cjs = deepmerge_1;
3925
+
3926
+ // Create a pinia store named skills with a state using the type Skills, with actions:
3927
+ // setupSkillCheck(skillCheck: SkillCheckState, id: string)
3928
+ // passSkillCheck(skillCheckId: string)
3929
+ // failSkillCheck(skillCheckId: string)
3930
+ // generateSaveData(): Function that generates a Skills object from the data in the state
3931
+ // loadSaveData(data: Skills): Function that loads the data into the state
3932
+ // setupSkills(skills: { [key: string]: SkillData})
3933
+ // 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
3934
+ // incrementSkill(skill: string, amount: number): Increments the level of a skill by amount
3935
+ const useSkills = pinia.defineStore('skills', {
3936
+ state: () => ({
3937
+ skillChecks: {},
3938
+ skills: {},
3939
+ }),
3940
+ actions: {
3941
+ setupSkillCheck(skillCheck, id) {
3942
+ this.skillChecks[id] = skillCheck;
3943
+ },
3944
+ passSkillCheck(skillCheckId) {
3945
+ this.skillChecks[skillCheckId].passed = true;
3946
+ this.skillChecks[skillCheckId].available = false;
4010
3947
  },
4011
- removeQuest(id) {
4012
- delete this.quests[id];
3948
+ failSkillCheck(skillCheckId) {
3949
+ this.skillChecks[skillCheckId].passed = false;
3950
+ this.skillChecks[skillCheckId].available = false;
4013
3951
  },
4014
3952
  generateSaveData() {
4015
3953
  return {
4016
- quests: {
4017
- ...this.quests,
4018
- },
3954
+ skillChecks: this.skillChecks,
3955
+ skills: this.skills,
4019
3956
  };
4020
3957
  },
4021
3958
  loadSaveData(data) {
4022
- this.quests = data.quests;
3959
+ this.skillChecks = cjs(this.skillChecks, data.skillChecks);
3960
+ this.skills = cjs(this.skills, data.skills);
3961
+ },
3962
+ setupSkills(skills) {
3963
+ // 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.
3964
+ for (const skill in skills) {
3965
+ this.skills[skill] = {
3966
+ level: skills[skill].startingLevel || 0,
3967
+ xp: 0,
3968
+ };
3969
+ }
3970
+ },
3971
+ addXp(skill, xp) {
3972
+ const skillData = this.skills[skill];
3973
+ if (!skillData) {
3974
+ error(`Skill ${skill} doesn't exist`);
3975
+ }
3976
+ skillData.xp += xp;
3977
+ if (skillData.xp >= getConfig().skillOptions.xpPerLevel) {
3978
+ skillData.xp = 0;
3979
+ skillData.level++;
3980
+ this.levelledUp(skill);
3981
+ }
3982
+ },
3983
+ incrementSkill(skill, amount) {
3984
+ this.skills[skill].level += amount;
3985
+ this.levelledUp(skill);
3986
+ },
3987
+ levelledUp(skill) {
3988
+ const skillName = getConfig().skills[skill].name;
3989
+ const skillLevel = this.skills[skill].level;
3990
+ useNotifications().addNotification(`Your skill in ${skillName} is now level ${skillLevel}`);
4023
3991
  },
4024
3992
  },
4025
3993
  });
4026
3994
 
3995
+ function getFile(url) {
3996
+ return new Promise((resolve, reject) => {
3997
+ // Set up our HTTP request
3998
+ const xhr = new XMLHttpRequest();
3999
+ // Setup our listener to process completed requests
4000
+ xhr.onload = function () {
4001
+ // Process our return data
4002
+ if (xhr.status >= 200 && xhr.status < 300) {
4003
+ // This will run when the request is successful
4004
+ resolve(xhr.responseText);
4005
+ }
4006
+ else {
4007
+ reject(xhr.status);
4008
+ // This will run when it's not
4009
+ }
4010
+ };
4011
+ xhr.open('GET', url);
4012
+ xhr.send();
4013
+ });
4014
+ }
4015
+
4027
4016
  // Create a pinia store named screens with a state using the type ScreenState, with actions:
4028
4017
  // setScreen(screen: string): Sets the current screen to the given screen
4029
4018
  // setButtons(buttons: { [key: string]: ButtonConfig }): Adds buttons to the buttons state by using the values in the buttons config object
@@ -4315,6 +4304,7 @@ const useVM = pinia.defineStore('vm', {
4315
4304
  data: {},
4316
4305
  lastLabel: 'main',
4317
4306
  script: {},
4307
+ labelStack: ['main'],
4318
4308
  }),
4319
4309
  actions: {
4320
4310
  generateSaveData() {
@@ -4391,6 +4381,7 @@ const useVM = pinia.defineStore('vm', {
4391
4381
  newStack.label = this.currentStack.label;
4392
4382
  }
4393
4383
  this.stack.push(newStack);
4384
+ return this.runLine();
4394
4385
  },
4395
4386
  async nextLine() {
4396
4387
  if (this.stack.length === 0) {
@@ -4418,6 +4409,7 @@ const useVM = pinia.defineStore('vm', {
4418
4409
  this.stack.splice(this.stack.length - 1, 1);
4419
4410
  },
4420
4411
  finishGame() {
4412
+ useInventory().onScriptEnd();
4421
4413
  const mainStore = useMain();
4422
4414
  if (mainStore.options.debug) {
4423
4415
  const dialogStore = useDialogStore();
@@ -4429,8 +4421,24 @@ const useVM = pinia.defineStore('vm', {
4429
4421
  },
4430
4422
  async runLine() {
4431
4423
  const cmd = this.currentLine;
4424
+ useInventory().onScriptStart();
4432
4425
  await runCommand(cmd);
4433
4426
  },
4427
+ async runLabelFunction(label, comeBackToSameLine) {
4428
+ if (comeBackToSameLine) {
4429
+ this.currentStack.currentIndex--;
4430
+ }
4431
+ const branch = this.script[label];
4432
+ if (!branch) {
4433
+ console.error(`Label ${branch} doesn't exist`);
4434
+ }
4435
+ const stack = {
4436
+ currentIndex: 0,
4437
+ branch: branch,
4438
+ label,
4439
+ };
4440
+ await this.addStack(stack);
4441
+ },
4434
4442
  runLabel(label) {
4435
4443
  const branch = this.script[label];
4436
4444
  if (!branch) {
@@ -4459,6 +4467,93 @@ const useVM = pinia.defineStore('vm', {
4459
4467
  },
4460
4468
  });
4461
4469
 
4470
+ function processText(text) {
4471
+ const vmStore = useVM();
4472
+ const skillStore = useSkills();
4473
+ return text.replace(/%{[^}]*}/g, (match) => {
4474
+ const key = match.substr(2, match.length - 3);
4475
+ const searchableState = {
4476
+ data: vmStore.data,
4477
+ skills: skillStore.skills,
4478
+ items: useInventory().items,
4479
+ quests: useQuests().quests,
4480
+ };
4481
+ const [obj, newKey] = findDataHelper(searchableState, key);
4482
+ return obj[newKey];
4483
+ });
4484
+ }
4485
+
4486
+ // Create a pinia store named dialog with a state using the type DialogState, with actions addDialog and clearDialog
4487
+ const useDialogStore = pinia.defineStore('dialog', {
4488
+ state: () => ({
4489
+ dialog: [],
4490
+ }),
4491
+ actions: {
4492
+ generateSaveData() {
4493
+ return {
4494
+ dialog: this.dialog,
4495
+ };
4496
+ },
4497
+ loadSaveData(data) {
4498
+ this.dialog = data.dialog;
4499
+ },
4500
+ addDialog(dialog) {
4501
+ this.dialog.push({
4502
+ ...dialog,
4503
+ interactive: dialog.interactive ?? false,
4504
+ id: randomId(),
4505
+ text: processText(dialog.text),
4506
+ });
4507
+ },
4508
+ clearDialog() {
4509
+ this.dialog.splice(0, this.dialog.length);
4510
+ },
4511
+ reset() {
4512
+ this.dialog = [];
4513
+ },
4514
+ },
4515
+ getters: {
4516
+ currentDialog() {
4517
+ return this.dialog[this.dialog.length - 1];
4518
+ },
4519
+ },
4520
+ });
4521
+
4522
+ // Create a pinia store named hud with a state using the type HudState, and save type HudSave, with actions:
4523
+ // setupHudStats(stats: { [key: string]: HudStatConfig }): Iterates the stats argument to add new stats to the state
4524
+ // setStat(stat: string, value: number): Sets the value of a stat
4525
+ // addStat(stat: string, value: number): Adds a value to a stat
4526
+ // generateSaveData(): Function that generates a HudSave object from the data in the state
4527
+ // loadSaveData(data: HudSave): Function that loads the data into the state
4528
+ const useHud = pinia.defineStore('hud', {
4529
+ state: () => ({
4530
+ hudStats: {},
4531
+ }),
4532
+ actions: {
4533
+ setupHudStats(stats) {
4534
+ for (const stat in stats) {
4535
+ this.hudStats[stat] = {
4536
+ value: stats[stat].startingValue,
4537
+ };
4538
+ }
4539
+ },
4540
+ setStat(stat, value) {
4541
+ this.hudStats[stat].value = value;
4542
+ },
4543
+ addStat(stat, value) {
4544
+ this.hudStats[stat].value += value;
4545
+ },
4546
+ generateSaveData() {
4547
+ return {
4548
+ hudStats: this.hudStats,
4549
+ };
4550
+ },
4551
+ loadSaveData(data) {
4552
+ this.hudStats = cjs(this.hudStats, data.hudStats);
4553
+ },
4554
+ },
4555
+ });
4556
+
4462
4557
  function createSkillCheckState() {
4463
4558
  const skillCheck = {
4464
4559
  passed: false,
@@ -4612,6 +4707,7 @@ function conditionFunction(condition) {
4612
4707
  skillChecks: skillStore.skillChecks,
4613
4708
  stats: useHud().hudStats,
4614
4709
  items: inventory.items,
4710
+ quests: useQuests().quests,
4615
4711
  itemAmount: (id) => {
4616
4712
  return useInventory().getItemAmount(id);
4617
4713
  },
@@ -4684,9 +4780,9 @@ async function runCommand(cmd, choices) {
4684
4780
  catch (err) {
4685
4781
  logger.log(`Error at: `, vmStore.currentStack.label);
4686
4782
  console.error(err);
4687
- error(`Narrat script runtime error at <span class="error-filename">${cmd.fileName}:${cmd.line + 1}</span>
4688
- <b>${err}</b>
4689
- Script: ${cmd.code}
4783
+ error(`Narrat script runtime error at <span class="error-filename">${cmd.fileName}:${cmd.line + 1}</span>
4784
+ <b>${err}</b>
4785
+ Script: ${cmd.code}
4690
4786
  Label: ${vmStore.currentStack.label}`);
4691
4787
  }
4692
4788
  }
@@ -4732,8 +4828,7 @@ async function playerAnswered(choiceIndex) {
4732
4828
  branch: newBranch,
4733
4829
  };
4734
4830
  const vmStore = useVM();
4735
- vmStore.addStack(newStack);
4736
- vmStore.runLine();
4831
+ return vmStore.addStack(newStack);
4737
4832
  }
4738
4833
  else {
4739
4834
  vmStore.nextLine();
@@ -4878,7 +4973,12 @@ const useMain = pinia.defineStore('main', {
4878
4973
  this.modal = false;
4879
4974
  },
4880
4975
  toggleMenu() {
4881
- this.flowState = this.flowState === 'menu' ? 'playing' : 'menu';
4976
+ if (this.modal) {
4977
+ this.modal = false;
4978
+ }
4979
+ else {
4980
+ this.modal = 'menu';
4981
+ }
4882
4982
  },
4883
4983
  pause() {
4884
4984
  this.paused = true;
@@ -5191,7 +5291,7 @@ function render(_ctx, _cache, $props, $setup, $data, $options) {
5191
5291
  ], 4))
5192
5292
  }
5193
5293
 
5194
- 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";
5294
+ 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";
5195
5295
  styleInject(css_248z$1);
5196
5296
 
5197
5297
  script.render = render;
@@ -5238,7 +5338,7 @@ function render$1(_ctx, _cache, $props, $setup, $data, $options) {
5238
5338
  ], 4))
5239
5339
  }
5240
5340
 
5241
- 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";
5341
+ 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";
5242
5342
  styleInject(css_248z$2);
5243
5343
 
5244
5344
  script$1.render = render$1;
@@ -5292,7 +5392,7 @@ function render$2(_ctx, _cache, $props, $setup, $data, $options) {
5292
5392
  }))
5293
5393
  }
5294
5394
 
5295
- 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";
5395
+ 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";
5296
5396
  styleInject(css_248z$3);
5297
5397
 
5298
5398
  script$2.render = render$2;
@@ -7200,6 +7300,9 @@ var script$3 = vue.defineComponent({
7200
7300
  this.showDebug = true;
7201
7301
  const vmStore = useVM();
7202
7302
  const mainStore = useMain();
7303
+ const questsStore = useQuests();
7304
+ const inventoryStore = useInventory();
7305
+ const skillsStore = useSkills();
7203
7306
  this.$nextTick(() => {
7204
7307
  // eslint-disable-next-line no-unused-vars
7205
7308
  const _variablesEditor = new xJ({
@@ -7207,10 +7310,20 @@ var script$3 = vue.defineComponent({
7207
7310
  props: {
7208
7311
  content: {
7209
7312
  text: undefined,
7210
- json: this.variables,
7313
+ json: {
7314
+ data: this.variables,
7315
+ quests: questsStore.quests,
7316
+ items: inventoryStore.items,
7317
+ skills: skillsStore.skills,
7318
+ skillChecks: skillsStore.skillChecks,
7319
+ }
7211
7320
  },
7212
7321
  onChange: (updatedContent) => {
7213
- vmStore.overrideData(updatedContent.json);
7322
+ vmStore.overrideData(updatedContent.json.data);
7323
+ questsStore.quests = updatedContent.json.quests;
7324
+ inventoryStore.items = updatedContent.json.items;
7325
+ skillsStore.skills = updatedContent.json.skills;
7326
+ skillsStore.skillChecks = updatedContent.json.skillChecks;
7214
7327
  },
7215
7328
  },
7216
7329
  });
@@ -7536,7 +7649,7 @@ function render$3(_ctx, _cache, $props, $setup, $data, $options) {
7536
7649
  ]))
7537
7650
  }
7538
7651
 
7539
- 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";
7652
+ 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";
7540
7653
  styleInject(css_248z$4);
7541
7654
 
7542
7655
  script$3.render = render$3;
@@ -7593,7 +7706,7 @@ function render$4(_ctx, _cache, $props, $setup, $data, $options) {
7593
7706
  ]))
7594
7707
  }
7595
7708
 
7596
- 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";
7709
+ 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";
7597
7710
  styleInject(css_248z$5);
7598
7711
 
7599
7712
  script$4.render = render$4;
@@ -7651,7 +7764,7 @@ function render$5(_ctx, _cache, $props, $setup, $data, $options) {
7651
7764
  ], 4))
7652
7765
  }
7653
7766
 
7654
- 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";
7767
+ 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";
7655
7768
  styleInject(css_248z$6);
7656
7769
 
7657
7770
  script$5.render = render$5;
@@ -7688,7 +7801,7 @@ function render$6(_ctx, _cache, $props, $setup, $data, $options) {
7688
7801
  ]))
7689
7802
  }
7690
7803
 
7691
- 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";
7804
+ 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";
7692
7805
  styleInject(css_248z$7);
7693
7806
 
7694
7807
  script$6.render = render$6;
@@ -7721,27 +7834,11 @@ function render$7(_ctx, _cache, $props, $setup, $data, $options) {
7721
7834
  }))
7722
7835
  }
7723
7836
 
7724
- 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";
7837
+ 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";
7725
7838
  styleInject(css_248z$8);
7726
7839
 
7727
7840
  script$7.render = render$7;
7728
7841
 
7729
- function processText(text) {
7730
- const vmStore = useVM();
7731
- const skillStore = useSkills();
7732
- return text.replace(/%{[^}]*}/g, (match) => {
7733
- const key = match.substr(2, match.length - 3);
7734
- const searchableState = {
7735
- data: vmStore.data,
7736
- skills: skillStore.skills,
7737
- items: useInventory().items,
7738
- quests: useQuests().quests,
7739
- };
7740
- const [obj, newKey] = findDataHelper(searchableState, key);
7741
- return obj[newKey];
7742
- });
7743
- }
7744
-
7745
7842
  function aspectRatioFit(screenWidth, screenHeight, gameWidth, gameHeight) {
7746
7843
  const widthRatio = screenWidth / gameWidth;
7747
7844
  const heightRatio = screenHeight / gameHeight;
@@ -7946,7 +8043,7 @@ function render$8(_ctx, _cache, $props, $setup, $data, $options) {
7946
8043
  ]))
7947
8044
  }
7948
8045
 
7949
- 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";
8046
+ 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";
7950
8047
  styleInject(css_248z$9);
7951
8048
 
7952
8049
  script$8.render = render$8;
@@ -7956,7 +8053,9 @@ var script$9 = vue.defineComponent({
7956
8053
  Modal: script$2,
7957
8054
  VolumeControls: script$4,
7958
8055
  },
7959
- props: {},
8056
+ props: {
8057
+ close: Function,
8058
+ },
7960
8059
  data() { },
7961
8060
  mounted() { },
7962
8061
  methods: {
@@ -7964,9 +8063,6 @@ var script$9 = vue.defineComponent({
7964
8063
  window.close();
7965
8064
  // quit
7966
8065
  },
7967
- close() {
7968
- this.$emit('close');
7969
- },
7970
8066
  mainMenu() {
7971
8067
  useMain().menuReturn();
7972
8068
  this.close();
@@ -8014,7 +8110,7 @@ function render$9(_ctx, _cache, $props, $setup, $data, $options) {
8014
8110
  }, 8, ["onClose"]))
8015
8111
  }
8016
8112
 
8017
- var css_248z$a = ".quit-button {\n margin: 20px;\n text-align: center;\n}\r\n";
8113
+ var css_248z$a = ".quit-button {\n margin: 20px;\n text-align: center;\n}\n";
8018
8114
  styleInject(css_248z$a);
8019
8115
 
8020
8116
  script$9.render = render$9;
@@ -8030,7 +8126,7 @@ var script$a = vue.defineComponent({
8030
8126
  VolumeControls: script$4,
8031
8127
  },
8032
8128
  props: {
8033
- close: (() => { }),
8129
+ close: Function,
8034
8130
  },
8035
8131
  data() {
8036
8132
  return {
@@ -8081,20 +8177,17 @@ var script$a = vue.defineComponent({
8081
8177
  });
8082
8178
 
8083
8179
  const _hoisted_1$9 = /*#__PURE__*/vue.createElementVNode("h3", { class: "title" }, "Skills", -1);
8084
- const _hoisted_2$7 = { class: "menu-content" };
8085
- const _hoisted_3$4 = {
8180
+ const _hoisted_2$7 = {
8086
8181
  key: 0,
8087
8182
  class: "skills-container"
8088
8183
  };
8089
- const _hoisted_4$3 = ["onClick"];
8090
- const _hoisted_5$3 = { class: "skill-title" };
8091
- const _hoisted_6$3 = { class: "skill-xp-container" };
8092
- const _hoisted_7$2 = { class: "skill-xp-text" };
8093
- const _hoisted_8$1 = { class: "skill-level" };
8094
- const _hoisted_9$1 = {
8095
- key: 1,
8096
- class: "flex flex-row skill-description-container"
8097
- };
8184
+ const _hoisted_3$4 = ["onClick"];
8185
+ const _hoisted_4$3 = { class: "skill-title" };
8186
+ const _hoisted_5$3 = { class: "skill-xp-container" };
8187
+ const _hoisted_6$3 = { class: "skill-xp-text" };
8188
+ const _hoisted_7$2 = { class: "skill-level" };
8189
+ const _hoisted_8$1 = { key: 1 };
8190
+ const _hoisted_9$1 = { class: "flex flex-row skill-description-container" };
8098
8191
  const _hoisted_10$1 = { class: "flex skill-left" };
8099
8192
  const _hoisted_11$1 = { class: "flex skill-right" };
8100
8193
  const _hoisted_12$1 = /*#__PURE__*/vue.createElementVNode("hr", { class: "hr-solid" }, null, -1);
@@ -8111,35 +8204,31 @@ function render$a(_ctx, _cache, $props, $setup, $data, $options) {
8111
8204
  _hoisted_1$9
8112
8205
  ]),
8113
8206
  body: vue.withCtx(() => [
8114
- vue.createElementVNode("div", _hoisted_2$7, [
8115
- (!_ctx.chosenSkill)
8116
- ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_3$4, [
8117
- (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(_ctx.skillsToDisplay, (skill, key) => {
8118
- return (vue.openBlock(), vue.createElementBlock("button", {
8119
- onClick: () => _ctx.clickSkill(key),
8120
- class: "skill-display",
8121
- style: vue.normalizeStyle(_ctx.getSkillStyle(key)),
8122
- key: key
8123
- }, [
8124
- vue.createElementVNode("h3", _hoisted_5$3, vue.toDisplayString(_ctx.getSkillName(key)), 1),
8125
- vue.createElementVNode("div", _hoisted_6$3, [
8126
- vue.createElementVNode("div", {
8127
- class: "skill-xp-bar",
8128
- style: vue.normalizeStyle(_ctx.xpBarWidth(skill.xp))
8129
- }, null, 4),
8130
- vue.createElementVNode("h3", _hoisted_7$2, vue.toDisplayString(skill.xp) + " / " + vue.toDisplayString(_ctx.xpPerLevel) + " XP ", 1)
8131
- ]),
8132
- vue.createElementVNode("h3", _hoisted_8$1, vue.toDisplayString(skill.level), 1)
8133
- ], 12, _hoisted_4$3))
8134
- }), 128))
8135
- ]))
8136
- : (typeof _ctx.chosenSkill === 'string')
8137
- ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_9$1, [
8207
+ (!_ctx.chosenSkill)
8208
+ ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_2$7, [
8209
+ (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(_ctx.skillsToDisplay, (skill, key) => {
8210
+ return (vue.openBlock(), vue.createElementBlock("button", {
8211
+ onClick: () => _ctx.clickSkill(key),
8212
+ class: "skill-display",
8213
+ style: vue.normalizeStyle(_ctx.getSkillStyle(key)),
8214
+ key: key
8215
+ }, [
8216
+ vue.createElementVNode("h3", _hoisted_4$3, vue.toDisplayString(_ctx.getSkillName(key)), 1),
8217
+ vue.createElementVNode("div", _hoisted_5$3, [
8218
+ vue.createElementVNode("div", {
8219
+ class: "skill-xp-bar",
8220
+ style: vue.normalizeStyle(_ctx.xpBarWidth(skill.xp))
8221
+ }, null, 4),
8222
+ vue.createElementVNode("h3", _hoisted_6$3, vue.toDisplayString(skill.xp) + " / " + vue.toDisplayString(_ctx.xpPerLevel) + " XP", 1)
8223
+ ]),
8224
+ vue.createElementVNode("h3", _hoisted_7$2, vue.toDisplayString(skill.level), 1)
8225
+ ], 12, _hoisted_3$4))
8226
+ }), 128))
8227
+ ]))
8228
+ : (typeof _ctx.chosenSkill === 'string')
8229
+ ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_8$1, [
8230
+ vue.createElementVNode("div", _hoisted_9$1, [
8138
8231
  vue.createElementVNode("div", _hoisted_10$1, [
8139
- vue.createElementVNode("button", {
8140
- class: "button",
8141
- onClick: _cache[0] || (_cache[0] = (...args) => (_ctx.closeSkill && _ctx.closeSkill(...args)))
8142
- }, "Back"),
8143
8232
  vue.createElementVNode("div", {
8144
8233
  class: "skill-display",
8145
8234
  style: vue.normalizeStyle(_ctx.getSkillStyle(_ctx.chosenSkill))
@@ -8151,15 +8240,19 @@ function render$a(_ctx, _cache, $props, $setup, $data, $options) {
8151
8240
  vue.createElementVNode("h3", null, "Level: " + vue.toDisplayString(_ctx.skills[_ctx.chosenSkill].level), 1),
8152
8241
  vue.createElementVNode("p", null, vue.toDisplayString(_ctx.skillConf[_ctx.chosenSkill].description), 1)
8153
8242
  ])
8154
- ]))
8155
- : vue.createCommentVNode("", true)
8156
- ])
8243
+ ]),
8244
+ vue.createElementVNode("button", {
8245
+ class: "button",
8246
+ onClick: _cache[0] || (_cache[0] = (...args) => (_ctx.closeSkill && _ctx.closeSkill(...args)))
8247
+ }, vue.toDisplayString('<--'))
8248
+ ]))
8249
+ : vue.createCommentVNode("", true)
8157
8250
  ]),
8158
8251
  _: 1
8159
8252
  }, 8, ["onClose"]))
8160
8253
  }
8161
8254
 
8162
- 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";
8255
+ 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";
8163
8256
  styleInject(css_248z$b);
8164
8257
 
8165
8258
  script$a.render = render$a;
@@ -8167,14 +8260,16 @@ script$a.render = render$a;
8167
8260
  var script$b = vue.defineComponent({
8168
8261
  setup() {
8169
8262
  const store = useInventory();
8263
+ const dialogStore = useDialogStore();
8170
8264
  const items = vue.computed(() => store.items);
8171
- return { items };
8265
+ const currentlyChoosing = vue.computed(() => dialogStore.currentDialog.choices);
8266
+ return { items, currentlyChoosing };
8172
8267
  },
8173
8268
  components: {
8174
8269
  Modal: script$2,
8175
8270
  },
8176
8271
  props: {
8177
- close: (() => { }),
8272
+ close: Function,
8178
8273
  },
8179
8274
  data() {
8180
8275
  return {
@@ -8191,12 +8286,40 @@ var script$b = vue.defineComponent({
8191
8286
  getItemName(item) {
8192
8287
  return this.itemConf[item].name;
8193
8288
  },
8289
+ getItemConf(item) {
8290
+ return this.itemConf[item];
8291
+ },
8194
8292
  clickItem(item) {
8195
8293
  this.chosenId = item;
8196
8294
  },
8197
8295
  closeItem() {
8198
8296
  this.chosenId = false;
8199
8297
  },
8298
+ useItem() {
8299
+ if (this.canUseChosenItem) {
8300
+ const onUse = this.chosenItemConf.onUse;
8301
+ this.close();
8302
+ if (onUse.action === 'jump') {
8303
+ useVM().runLabel(onUse.label);
8304
+ }
8305
+ else if (onUse.action === 'run_label') {
8306
+ useVM().runLabelFunction(onUse.label, true);
8307
+ }
8308
+ else {
8309
+ error(`Unknown action ${onUse.action}`);
8310
+ }
8311
+ }
8312
+ },
8313
+ canUseItem(item) {
8314
+ const conf = this.itemConf[item.id];
8315
+ if (conf &&
8316
+ conf.onUse &&
8317
+ !useInventory().isInteractionTagBlocked(conf.tag) &&
8318
+ !this.currentlyChoosing) {
8319
+ return true;
8320
+ }
8321
+ return false;
8322
+ },
8200
8323
  },
8201
8324
  computed: {
8202
8325
  itemsToDisplay() {
@@ -8214,6 +8337,9 @@ var script$b = vue.defineComponent({
8214
8337
  }
8215
8338
  return null;
8216
8339
  },
8340
+ canUseChosenItem() {
8341
+ return this.canUseItem(this.chosenItem);
8342
+ },
8217
8343
  chosenItemConf() {
8218
8344
  if (this.chosenId) {
8219
8345
  return this.itemConf[this.chosenId];
@@ -8227,18 +8353,15 @@ var script$b = vue.defineComponent({
8227
8353
  });
8228
8354
 
8229
8355
  const _hoisted_1$a = /*#__PURE__*/vue.createElementVNode("h3", { class: "title" }, "Inventory", -1);
8230
- const _hoisted_2$8 = { class: "menu-content" };
8231
- const _hoisted_3$5 = {
8356
+ const _hoisted_2$8 = {
8232
8357
  key: 0,
8233
8358
  class: "inventory-container"
8234
8359
  };
8235
- const _hoisted_4$4 = ["onClick"];
8236
- const _hoisted_5$4 = { class: "item-title" };
8237
- const _hoisted_6$4 = { class: "item-amount" };
8238
- const _hoisted_7$3 = {
8239
- key: 1,
8240
- class: "flex flex-row item-description-container"
8241
- };
8360
+ const _hoisted_3$5 = ["onClick"];
8361
+ const _hoisted_4$4 = { class: "item-title" };
8362
+ const _hoisted_5$4 = { class: "item-amount" };
8363
+ const _hoisted_6$4 = { key: 1 };
8364
+ const _hoisted_7$3 = { class: "flex flex-row item-description-container" };
8242
8365
  const _hoisted_8$2 = { class: "flex item-left" };
8243
8366
  const _hoisted_9$2 = { class: "flex item-right" };
8244
8367
  const _hoisted_10$2 = /*#__PURE__*/vue.createElementVNode("hr", { class: "hr-solid" }, null, -1);
@@ -8260,28 +8383,24 @@ function render$b(_ctx, _cache, $props, $setup, $data, $options) {
8260
8383
  _hoisted_1$a
8261
8384
  ]),
8262
8385
  body: vue.withCtx(() => [
8263
- vue.createElementVNode("div", _hoisted_2$8, [
8264
- (!_ctx.chosenItem && Object.keys(_ctx.itemsToDisplay).length > 0)
8265
- ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_3$5, [
8266
- (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(_ctx.itemsToDisplay, (item) => {
8267
- return (vue.openBlock(), vue.createElementBlock("button", {
8268
- onClick: () => _ctx.clickItem(item.id),
8269
- class: "item-display",
8270
- style: vue.normalizeStyle(_ctx.getItemStyle(item.id)),
8271
- key: item.id
8272
- }, [
8273
- vue.createElementVNode("h3", _hoisted_5$4, vue.toDisplayString(_ctx.getItemName(item.id)), 1),
8274
- vue.createElementVNode("h3", _hoisted_6$4, vue.toDisplayString(item.amount), 1)
8275
- ], 12, _hoisted_4$4))
8276
- }), 128))
8277
- ]))
8278
- : (typeof _ctx.chosenId === 'string')
8279
- ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_7$3, [
8386
+ (!_ctx.chosenItem && Object.keys(_ctx.itemsToDisplay).length > 0)
8387
+ ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_2$8, [
8388
+ (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(_ctx.itemsToDisplay, (item) => {
8389
+ return (vue.openBlock(), vue.createElementBlock("button", {
8390
+ onClick: () => _ctx.clickItem(item.id),
8391
+ class: "item-display",
8392
+ style: vue.normalizeStyle(_ctx.getItemStyle(item.id)),
8393
+ key: item.id
8394
+ }, [
8395
+ vue.createElementVNode("h3", _hoisted_4$4, vue.toDisplayString(_ctx.getItemName(item.id)), 1),
8396
+ vue.createElementVNode("h3", _hoisted_5$4, vue.toDisplayString(item.amount), 1)
8397
+ ], 12, _hoisted_3$5))
8398
+ }), 128))
8399
+ ]))
8400
+ : (typeof _ctx.chosenId === 'string')
8401
+ ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_6$4, [
8402
+ vue.createElementVNode("div", _hoisted_7$3, [
8280
8403
  vue.createElementVNode("div", _hoisted_8$2, [
8281
- vue.createElementVNode("button", {
8282
- class: "button",
8283
- onClick: _cache[0] || (_cache[0] = (...args) => (_ctx.closeItem && _ctx.closeItem(...args)))
8284
- }, "Back"),
8285
8404
  vue.createElementVNode("div", {
8286
8405
  class: "item-display",
8287
8406
  style: vue.normalizeStyle(_ctx.getItemStyle(_ctx.chosenId))
@@ -8291,17 +8410,25 @@ function render$b(_ctx, _cache, $props, $setup, $data, $options) {
8291
8410
  vue.createElementVNode("h2", null, vue.toDisplayString(_ctx.getItemName(_ctx.chosenId)), 1),
8292
8411
  _hoisted_10$2,
8293
8412
  vue.createElementVNode("h3", null, "Amount: " + vue.toDisplayString(_ctx.chosenItem.amount), 1),
8294
- vue.createElementVNode("p", null, vue.toDisplayString(_ctx.chosenItemConf.description), 1)
8413
+ vue.createElementVNode("p", null, vue.toDisplayString(_ctx.chosenItemConf.description), 1),
8414
+ vue.createElementVNode("button", {
8415
+ onClick: _cache[0] || (_cache[0] = (...args) => (_ctx.useItem && _ctx.useItem(...args))),
8416
+ class: vue.normalizeClass(["button", _ctx.canUseChosenItem ? '' : 'disabled'])
8417
+ }, " Use ", 2)
8295
8418
  ])
8296
- ]))
8297
- : (vue.openBlock(), vue.createElementBlock("div", _hoisted_11$2, _hoisted_13$1))
8298
- ])
8419
+ ]),
8420
+ vue.createElementVNode("button", {
8421
+ class: "button",
8422
+ onClick: _cache[1] || (_cache[1] = (...args) => (_ctx.closeItem && _ctx.closeItem(...args)))
8423
+ }, vue.toDisplayString('<--'))
8424
+ ]))
8425
+ : (vue.openBlock(), vue.createElementBlock("div", _hoisted_11$2, _hoisted_13$1))
8299
8426
  ]),
8300
8427
  _: 1
8301
8428
  }, 8, ["onClose"]))
8302
8429
  }
8303
8430
 
8304
- 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";
8431
+ 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";
8305
8432
  styleInject(css_248z$c);
8306
8433
 
8307
8434
  script$b.render = render$b;
@@ -8318,7 +8445,7 @@ var script$c = vue.defineComponent({
8318
8445
  },
8319
8446
  },
8320
8447
  props: {
8321
- close: (() => { }),
8448
+ close: Function,
8322
8449
  },
8323
8450
  methods: {
8324
8451
  getQuestData(questId) {
@@ -8397,10 +8524,10 @@ function render$c(_ctx, _cache, $props, $setup, $data, $options) {
8397
8524
  key: quest.id
8398
8525
  }, [
8399
8526
  vue.createElementVNode("div", {
8400
- class: vue.normalizeClass(["quest-header",
8401
- quest.state === 'completed'
8402
- ? 'quest-completed'
8403
- : 'quest-in-progress'
8527
+ class: vue.normalizeClass(["quest-header",
8528
+ quest.state === 'completed'
8529
+ ? 'quest-completed'
8530
+ : 'quest-in-progress'
8404
8531
  ])
8405
8532
  }, [
8406
8533
  vue.createElementVNode("h3", _hoisted_3$6, vue.toDisplayString(_ctx.getQuestData(quest.id).title) + " " + vue.toDisplayString(_ctx.getDisplayTextForQuestState(quest)), 1)
@@ -8414,10 +8541,10 @@ function render$c(_ctx, _cache, $props, $setup, $data, $options) {
8414
8541
  key: objective.id
8415
8542
  }, [
8416
8543
  vue.createElementVNode("p", {
8417
- class: vue.normalizeClass(["quest-objective-description",
8418
- objective.state === 'completed'
8419
- ? 'quest-objective-completed'
8420
- : 'quest-objctive-in-progress'
8544
+ class: vue.normalizeClass(["quest-objective-description",
8545
+ objective.state === 'completed'
8546
+ ? 'quest-objective-completed'
8547
+ : 'quest-objctive-in-progress'
8421
8548
  ])
8422
8549
  }, vue.toDisplayString(_ctx.getObjectiveData(quest.id, objective.id).description), 3)
8423
8550
  ]))
@@ -8433,7 +8560,7 @@ function render$c(_ctx, _cache, $props, $setup, $data, $options) {
8433
8560
  }, 8, ["onClose"]))
8434
8561
  }
8435
8562
 
8436
- 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";
8563
+ 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";
8437
8564
  styleInject(css_248z$d);
8438
8565
 
8439
8566
  script$c.render = render$c;
@@ -8723,7 +8850,7 @@ var script$d = vue.defineComponent({
8723
8850
  }
8724
8851
  return {
8725
8852
  title,
8726
- text: processText(dialogKey.text),
8853
+ text: dialogKey.text,
8727
8854
  styleId: dialogKey.speaker,
8728
8855
  choices: dialogKey.choices,
8729
8856
  old: index < this.dialog.length - 1,
@@ -8775,26 +8902,26 @@ function render$d(_ctx, _cache, $props, $setup, $data, $options) {
8775
8902
  (_ctx.modal === 'skills')
8776
8903
  ? (vue.openBlock(), vue.createBlock(_component_Skills, {
8777
8904
  key: 0,
8778
- onClose: _ctx.closeModal
8779
- }, null, 8, ["onClose"]))
8905
+ close: _ctx.closeModal
8906
+ }, null, 8, ["close"]))
8780
8907
  : vue.createCommentVNode("", true),
8781
8908
  (_ctx.modal === 'inventory')
8782
8909
  ? (vue.openBlock(), vue.createBlock(_component_Inventory, {
8783
8910
  key: 1,
8784
- onClose: _ctx.closeModal
8785
- }, null, 8, ["onClose"]))
8911
+ close: _ctx.closeModal
8912
+ }, null, 8, ["close"]))
8786
8913
  : vue.createCommentVNode("", true),
8787
8914
  (_ctx.modal === 'quests')
8788
8915
  ? (vue.openBlock(), vue.createBlock(_component_Quests, {
8789
8916
  key: 2,
8790
- onClose: _ctx.closeModal
8791
- }, null, 8, ["onClose"]))
8917
+ close: _ctx.closeModal
8918
+ }, null, 8, ["close"]))
8792
8919
  : vue.createCommentVNode("", true),
8793
8920
  (_ctx.modal === 'menu')
8794
8921
  ? (vue.openBlock(), vue.createBlock(_component_MainMenu, {
8795
8922
  key: 3,
8796
- onClose: _ctx.closeModal
8797
- }, null, 8, ["onClose"]))
8923
+ close: _ctx.closeModal
8924
+ }, null, 8, ["close"]))
8798
8925
  : vue.createCommentVNode("", true),
8799
8926
  vue.createVNode(vue.Transition, { name: "fade" }, {
8800
8927
  default: vue.withCtx(() => [
@@ -8881,7 +9008,7 @@ function render$d(_ctx, _cache, $props, $setup, $data, $options) {
8881
9008
  ], 4))
8882
9009
  }
8883
9010
 
8884
- 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";
9011
+ 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";
8885
9012
  styleInject(css_248z$e);
8886
9013
 
8887
9014
  script$d.render = render$d;
@@ -9168,8 +9295,7 @@ const ifFunction = async (cmd) => {
9168
9295
  branch: newBranch,
9169
9296
  currentIndex: 0,
9170
9297
  };
9171
- vmStore.addStack(newStack);
9172
- return vmStore.runLine();
9298
+ return vmStore.addStack(newStack);
9173
9299
  }
9174
9300
  return vmStore.nextLine();
9175
9301
  };
@@ -9394,8 +9520,7 @@ const addItemPlugin = new CommandPlugin('add_item', async (cmd) => {
9394
9520
  amount,
9395
9521
  });
9396
9522
  return useVM().nextLine();
9397
- }, generateParser('add_item'));
9398
-
9523
+ }, generateParser('add_item'));
9399
9524
  // Write a CommandPlugin for removeing items to the inventory store
9400
9525
  const removeItemPlugin = new CommandPlugin('remove_item', async (cmd) => {
9401
9526
  const id = cmd.args[0];
@@ -9406,7 +9531,21 @@ const removeItemPlugin = new CommandPlugin('remove_item', async (cmd) => {
9406
9531
  amount,
9407
9532
  });
9408
9533
  return useVM().nextLine();
9409
- }, generateParser('remove_item'));
9534
+ }, generateParser('remove_item'));
9535
+ // Write a CommandPlugin for enabling an interactiongTag in the inventory store
9536
+ const enableInteractionPlugin = new CommandPlugin('enable_interaction', async (cmd) => {
9537
+ const tag = cmd.args[0];
9538
+ const inventory = useInventory();
9539
+ inventory.enableInteraction(tag);
9540
+ return useVM().nextLine();
9541
+ }, generateParser('enable_interaction'));
9542
+ // Write a CommandPlugin for disabling an interactiongTag in the inventory store
9543
+ const disableInteractionPlugin = new CommandPlugin('disable_interaction', async (cmd) => {
9544
+ const tag = cmd.args[0];
9545
+ const inventory = useInventory();
9546
+ inventory.disableInteraction(tag);
9547
+ return useVM().nextLine();
9548
+ }, generateParser('disable_interaction'));
9410
9549
 
9411
9550
  // Write a CommandPlugin for starting a quest with the useQuests quests store
9412
9551
  const startQuestPlugin = new CommandPlugin('start_quest', async (cmd) => {
@@ -9443,8 +9582,16 @@ const completeQuestPlugin = new CommandPlugin('complete_quest', async (cmd) => {
9443
9582
  return useVM().nextLine();
9444
9583
  }, generateParser('complete_quest'));
9445
9584
 
9585
+ // Write a CommandPlugin for running a label using the runLabelFunction of the useVM store
9586
+ const runLabelPlugin = new CommandPlugin('run_label', async (cmd) => {
9587
+ const label = cmd.args[0];
9588
+ if (!label) {
9589
+ error(`run_label command needs a label to argument run`);
9590
+ }
9591
+ await useVM().runLabelFunction(label);
9592
+ }, generateParser('run_label'));
9593
+
9446
9594
  function registerBaseCommands(vm) {
9447
- vm.addCommand(addItemPlugin);
9448
9595
  vm.addCommand(addLevelPlugin);
9449
9596
  vm.addCommand(addStatPlugin);
9450
9597
  vm.addCommand(addXpPlugin);
@@ -9456,7 +9603,6 @@ function registerBaseCommands(vm) {
9456
9603
  vm.addCommand(notifyPlugin);
9457
9604
  vm.addCommand(pauseCommand);
9458
9605
  vm.addCommand(playCommand);
9459
- vm.addCommand(removeItemPlugin);
9460
9606
  vm.addCommand(setButtonCommand);
9461
9607
  vm.addCommand(setScreenCommand);
9462
9608
  vm.addCommand(setStatCommand);
@@ -9465,11 +9611,19 @@ function registerBaseCommands(vm) {
9465
9611
  vm.addCommand(talkCommand);
9466
9612
  vm.addCommand(textCommandPlugin);
9467
9613
  vm.addCommand(waitCommand);
9614
+ // functions and labels
9615
+ vm.addCommand(jumpCommand);
9616
+ vm.addCommand(runLabelPlugin);
9468
9617
  // Quests
9469
9618
  vm.addCommand(startQuestPlugin);
9470
9619
  vm.addCommand(startObjectivePlugin);
9471
9620
  vm.addCommand(completeObjectivePlugin);
9472
9621
  vm.addCommand(completeQuestPlugin);
9622
+ // Inventory
9623
+ vm.addCommand(addItemPlugin);
9624
+ vm.addCommand(removeItemPlugin);
9625
+ vm.addCommand(enableInteractionPlugin);
9626
+ vm.addCommand(disableInteractionPlugin);
9473
9627
  }
9474
9628
 
9475
9629
  class NarratPlugin {
@@ -9512,7 +9666,7 @@ async function startApp(config, options) {
9512
9666
  });
9513
9667
  registerBaseCommands(vm);
9514
9668
  logManager.setupDebugger(options.debug);
9515
- console.log('%c Narrat game engine – 1.2.1 - June 25, 2022 14:20:12', 'background: #222; color: #bada55');
9669
+ console.log('%c Narrat game engine – 1.3.2 - June 26, 2022 18:33:37', 'background: #222; color: #bada55');
9516
9670
  vm.callHook('onNarratSetup');
9517
9671
  app.mount('#game-holder');
9518
9672
  if (options.debug) {