narrat 0.8.2 → 0.8.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/index.esm.js +59 -31
- package/lib/index.js +59 -31
- package/lib/store.d.ts +2 -1
- package/lib/utils/images-loader.d.ts +1 -1
- package/lib/utils/logger.d.ts +8 -0
- package/lib/utils/randomId.d.ts +1 -0
- package/lib/vm/renpy-vm.d.ts +3 -2
- package/package.json +1 -1
package/lib/index.esm.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Version: 0.8.
|
|
1
|
+
// Version: 0.8.5 - June 4, 2022 20:05:21
|
|
2
2
|
import 'es6-promise/auto';
|
|
3
3
|
import { ref, reactive, readonly, defineComponent, openBlock, createElementBlock, normalizeStyle, createElementVNode, createCommentVNode, Fragment, renderList, createBlock, Transition, withCtx, renderSlot, createTextVNode, resolveComponent, toDisplayString, TransitionGroup, createVNode, createApp } from 'vue';
|
|
4
4
|
import { createLogger, createStore } from 'vuex';
|
|
@@ -308,6 +308,22 @@ styleInject(css_248z$2);
|
|
|
308
308
|
|
|
309
309
|
script$1.render = render$1;
|
|
310
310
|
|
|
311
|
+
class Logger {
|
|
312
|
+
debug;
|
|
313
|
+
constructor(debug) {
|
|
314
|
+
this.debug = debug;
|
|
315
|
+
}
|
|
316
|
+
setDebug(debug) {
|
|
317
|
+
this.debug = debug;
|
|
318
|
+
}
|
|
319
|
+
log(...args) {
|
|
320
|
+
if (this.debug) {
|
|
321
|
+
console.log(...args);
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
const logger = new Logger(false);
|
|
326
|
+
|
|
311
327
|
function getPlayTime(startedAt, previousTime) {
|
|
312
328
|
return Date.now() - startedAt + previousTime;
|
|
313
329
|
}
|
|
@@ -408,7 +424,7 @@ var script$3 = defineComponent({
|
|
|
408
424
|
wordCount() {
|
|
409
425
|
const scripts = Object.values(this.$store.state.machine.script);
|
|
410
426
|
const count = scripts.reduce((count, script) => {
|
|
411
|
-
|
|
427
|
+
logger.log(count);
|
|
412
428
|
return count + this.countWordsInScriptBranch(script);
|
|
413
429
|
}, 0);
|
|
414
430
|
alert(`You have ${count} words`);
|
|
@@ -3863,10 +3879,8 @@ var script$4 = defineComponent({
|
|
|
3863
3879
|
},
|
|
3864
3880
|
methods: {
|
|
3865
3881
|
changeVolume(event) {
|
|
3866
|
-
console.log(event);
|
|
3867
3882
|
const target = event.target;
|
|
3868
3883
|
howler.Howler.volume(target.value);
|
|
3869
|
-
console.log(target.value);
|
|
3870
3884
|
},
|
|
3871
3885
|
toggleMute() {
|
|
3872
3886
|
if (this.muted) {
|
|
@@ -4132,7 +4146,7 @@ const images = {};
|
|
|
4132
4146
|
let imagesToLoad = 0;
|
|
4133
4147
|
let imagesLoaded = 0;
|
|
4134
4148
|
function loadImages(config) {
|
|
4135
|
-
|
|
4149
|
+
logger.log(`Loading images`);
|
|
4136
4150
|
return new Promise((resolve, reject) => {
|
|
4137
4151
|
for (const key in config.images) {
|
|
4138
4152
|
const path = config.images[key];
|
|
@@ -4142,19 +4156,19 @@ function loadImages(config) {
|
|
|
4142
4156
|
}
|
|
4143
4157
|
function loadImage(key, path, resolver, rejecter) {
|
|
4144
4158
|
imagesToLoad++;
|
|
4145
|
-
|
|
4159
|
+
logger.log(`Loading image ${key} at ${path}`);
|
|
4146
4160
|
const image = new Image();
|
|
4147
4161
|
image.onload = () => {
|
|
4148
4162
|
imagesLoaded += 1;
|
|
4149
4163
|
images[key] = image;
|
|
4150
|
-
|
|
4164
|
+
logger.log(`Loaded image ${key} successfully`);
|
|
4151
4165
|
if (imagesLoaded >= imagesToLoad) {
|
|
4152
|
-
|
|
4166
|
+
logger.log(`All images loaded`);
|
|
4153
4167
|
resolver();
|
|
4154
4168
|
}
|
|
4155
4169
|
};
|
|
4156
4170
|
image.onerror = (e) => {
|
|
4157
|
-
console.
|
|
4171
|
+
console.error(`Error loading image ${key}`);
|
|
4158
4172
|
rejecter(e);
|
|
4159
4173
|
};
|
|
4160
4174
|
image.src = path;
|
|
@@ -4163,7 +4177,7 @@ function loadImage(key, path, resolver, rejecter) {
|
|
|
4163
4177
|
const audio = {};
|
|
4164
4178
|
howler.Howler.volume(0.5);
|
|
4165
4179
|
async function loadAudioAssets(config) {
|
|
4166
|
-
|
|
4180
|
+
logger.log(`Loading audio`);
|
|
4167
4181
|
const loadingPromises = [];
|
|
4168
4182
|
for (const key in config.music) {
|
|
4169
4183
|
// Backward compatibility with old music list
|
|
@@ -4193,7 +4207,7 @@ async function loadAudioAssets(config) {
|
|
|
4193
4207
|
}
|
|
4194
4208
|
async function loadAudio(key, config) {
|
|
4195
4209
|
return new Promise((resolve, reject) => {
|
|
4196
|
-
|
|
4210
|
+
logger.log(`Loading audio ${config.src}`);
|
|
4197
4211
|
const sound = new howler.Howl({
|
|
4198
4212
|
...config,
|
|
4199
4213
|
});
|
|
@@ -4384,7 +4398,6 @@ styleInject(css_248z$9);
|
|
|
4384
4398
|
|
|
4385
4399
|
script$8.render = render$8;
|
|
4386
4400
|
|
|
4387
|
-
console.log('hello app');
|
|
4388
4401
|
var script$9 = defineComponent({
|
|
4389
4402
|
$refs: {
|
|
4390
4403
|
dialogContainer: HTMLInputElement,
|
|
@@ -4444,7 +4457,6 @@ var script$9 = defineComponent({
|
|
|
4444
4457
|
dialogLength(newCount, oldCount) {
|
|
4445
4458
|
if (this.$refs.dialog) {
|
|
4446
4459
|
const dialog = this.$refs.dialog;
|
|
4447
|
-
console.log('hello dialog');
|
|
4448
4460
|
dialog.scrollTop = dialog.scrollHeight + 100000;
|
|
4449
4461
|
}
|
|
4450
4462
|
},
|
|
@@ -4677,8 +4689,8 @@ const _hoisted_4$3 = { key: 2 };
|
|
|
4677
4689
|
|
|
4678
4690
|
function render$9(_ctx, _cache, $props, $setup, $data, $options) {
|
|
4679
4691
|
const _component_Hud = resolveComponent("Hud");
|
|
4680
|
-
const _component_DialogPicture = resolveComponent("DialogPicture");
|
|
4681
4692
|
const _component_Menu = resolveComponent("Menu");
|
|
4693
|
+
const _component_DialogPicture = resolveComponent("DialogPicture");
|
|
4682
4694
|
const _component_DialogBox = resolveComponent("DialogBox");
|
|
4683
4695
|
const _component_LoadingBar = resolveComponent("LoadingBar");
|
|
4684
4696
|
const _component_DebugMenu = resolveComponent("DebugMenu");
|
|
@@ -4695,6 +4707,7 @@ function render$9(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
4695
4707
|
class: "game",
|
|
4696
4708
|
style: normalizeStyle(_ctx.gameStyle)
|
|
4697
4709
|
}, [
|
|
4710
|
+
createVNode(_component_Menu, { class: "menu-toggle" }),
|
|
4698
4711
|
createVNode(Transition, { name: "fade" }, {
|
|
4699
4712
|
default: withCtx(() => [
|
|
4700
4713
|
(_ctx.picture)
|
|
@@ -4726,7 +4739,6 @@ function render$9(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
4726
4739
|
ref: "dialog",
|
|
4727
4740
|
style: normalizeStyle(_ctx.dialogStyle)
|
|
4728
4741
|
}, [
|
|
4729
|
-
createVNode(_component_Menu, { class: "menu-toggle" }),
|
|
4730
4742
|
createVNode(TransitionGroup, {
|
|
4731
4743
|
name: "list",
|
|
4732
4744
|
tag: "div",
|
|
@@ -4736,7 +4748,7 @@ function render$9(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
4736
4748
|
default: withCtx(() => [
|
|
4737
4749
|
(openBlock(true), createElementBlock(Fragment, null, renderList(_ctx.dialog, (dialog, i) => {
|
|
4738
4750
|
return (openBlock(), createBlock(_component_DialogBox, {
|
|
4739
|
-
key:
|
|
4751
|
+
key: dialog.id,
|
|
4740
4752
|
options: _ctx.getDialogBoxOptions(dialog, i),
|
|
4741
4753
|
active: _ctx.isDialogActive(i)
|
|
4742
4754
|
}, null, 8, ["options", "active"]))
|
|
@@ -4775,7 +4787,7 @@ function render$9(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
4775
4787
|
], 4))
|
|
4776
4788
|
}
|
|
4777
4789
|
|
|
4778
|
-
var css_248z$a = "#app {\n background-color: black;\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: white;\n box-sizing: border-box;\n overflow: hidden;\n transform-origin: center center;\n}\n\n.game {\n background-color: black;\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 background-color: #72080f;\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: #171717;\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:
|
|
4790
|
+
var css_248z$a = "#app {\n background-color: black;\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: white;\n box-sizing: border-box;\n overflow: hidden;\n transform-origin: center center;\n}\n\n.game {\n background-color: black;\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 background-color: #72080f;\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: #171717;\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: 108398;\n}\r\n";
|
|
4779
4791
|
styleInject(css_248z$a);
|
|
4780
4792
|
|
|
4781
4793
|
script$9.render = render$9;
|
|
@@ -4824,7 +4836,7 @@ function runSkillCheck(ctx, params) {
|
|
|
4824
4836
|
}
|
|
4825
4837
|
roll += state.skills[params.skill].level * skillChecks.skillMultiplier;
|
|
4826
4838
|
const skill = skills[params.skill];
|
|
4827
|
-
|
|
4839
|
+
logger.log(`roll `, roll, params.value);
|
|
4828
4840
|
if (roll < params.value) {
|
|
4829
4841
|
success = false;
|
|
4830
4842
|
}
|
|
@@ -4840,7 +4852,7 @@ function runSkillCheck(ctx, params) {
|
|
|
4840
4852
|
function runConditionCommand(ctx, command) {
|
|
4841
4853
|
const options = command.options;
|
|
4842
4854
|
const result = runCondition(ctx, options.condition);
|
|
4843
|
-
|
|
4855
|
+
logger.log(result);
|
|
4844
4856
|
if (result) {
|
|
4845
4857
|
return options.success;
|
|
4846
4858
|
}
|
|
@@ -4911,6 +4923,7 @@ async function runCommand(context, cmd, choices) {
|
|
|
4911
4923
|
currentIndex: 0,
|
|
4912
4924
|
};
|
|
4913
4925
|
commit('setStack', newStack);
|
|
4926
|
+
await dispatch('saveGame');
|
|
4914
4927
|
await dispatch('runLine');
|
|
4915
4928
|
break;
|
|
4916
4929
|
case 'text':
|
|
@@ -4961,7 +4974,6 @@ async function runCommand(context, cmd, choices) {
|
|
|
4961
4974
|
commit('clearDialog');
|
|
4962
4975
|
return dispatch('nextLine');
|
|
4963
4976
|
case 'set_button':
|
|
4964
|
-
console.log(cmd.args);
|
|
4965
4977
|
commit('changeButton', {
|
|
4966
4978
|
button: cmd.args[0],
|
|
4967
4979
|
enabled: cmd.args[1],
|
|
@@ -5048,7 +5060,7 @@ async function runCommand(context, cmd, choices) {
|
|
|
5048
5060
|
}
|
|
5049
5061
|
}
|
|
5050
5062
|
catch (err) {
|
|
5051
|
-
|
|
5063
|
+
logger.log(`Error at: `, state.machine.stack[state.machine.stack.length - 1].label);
|
|
5052
5064
|
console.error(err);
|
|
5053
5065
|
error(commit, `Narrat script runtime error at <span class="error-filename">${cmd.fileName}:${cmd.line + 1}</span>
|
|
5054
5066
|
<b>${err}</b>
|
|
@@ -5127,7 +5139,6 @@ async function runChoice(context, cmd) {
|
|
|
5127
5139
|
const skill = config.skills[check.skill];
|
|
5128
5140
|
const level = context.state.skills[check.skill].level;
|
|
5129
5141
|
const difficultyScore = check.value - level * config.skillChecks.skillMultiplier;
|
|
5130
|
-
console.log(`Check `, check, `score `, difficultyScore);
|
|
5131
5142
|
const skillCheckState = getSkillCheckState(context, choice.skillCheck.id);
|
|
5132
5143
|
let found = false;
|
|
5133
5144
|
let i = 0;
|
|
@@ -5414,7 +5425,7 @@ function parseRenpyScript(errorHandler, code, fileName) {
|
|
|
5414
5425
|
};
|
|
5415
5426
|
ctx.indentSize = detectIndentation(ctx, code);
|
|
5416
5427
|
const lines = findRenpyLines(ctx, code);
|
|
5417
|
-
|
|
5428
|
+
logger.log(lines);
|
|
5418
5429
|
const script = {};
|
|
5419
5430
|
for (const line of lines) {
|
|
5420
5431
|
if (line.code.search(':') === -1) {
|
|
@@ -5596,10 +5607,14 @@ function detectIndentation(ctx, script) {
|
|
|
5596
5607
|
if (result.length < 2) {
|
|
5597
5608
|
ctx.error(0, `Can't detect indentation level. Make sure you indent with at least 2 spaces and consistently`);
|
|
5598
5609
|
}
|
|
5599
|
-
|
|
5610
|
+
logger.log(result);
|
|
5600
5611
|
return result[1].length;
|
|
5601
5612
|
}
|
|
5602
5613
|
|
|
5614
|
+
function randomId() {
|
|
5615
|
+
return `${Date.now() - Math.floor(Math.random() * 99999999)}`;
|
|
5616
|
+
}
|
|
5617
|
+
|
|
5603
5618
|
let key = Symbol('Store Injection Key');
|
|
5604
5619
|
let store;
|
|
5605
5620
|
function setupStore(options) {
|
|
@@ -5610,7 +5625,8 @@ function setupStore(options) {
|
|
|
5610
5625
|
}
|
|
5611
5626
|
// define injection key
|
|
5612
5627
|
key = Symbol('Store Injection Key');
|
|
5613
|
-
|
|
5628
|
+
logger.setDebug(options.debug);
|
|
5629
|
+
logger.log('setup store');
|
|
5614
5630
|
store = createStore({
|
|
5615
5631
|
state: {
|
|
5616
5632
|
machine: {
|
|
@@ -5680,7 +5696,7 @@ function setupStore(options) {
|
|
|
5680
5696
|
};
|
|
5681
5697
|
}
|
|
5682
5698
|
const end = Date.now();
|
|
5683
|
-
|
|
5699
|
+
logger.log(`script parsed in ${end - start} ms`);
|
|
5684
5700
|
commit('setButtons', payload.config.buttons);
|
|
5685
5701
|
commit('setScript', scripts);
|
|
5686
5702
|
commit('setupSkills', payload.config.skills);
|
|
@@ -5702,7 +5718,6 @@ function setupStore(options) {
|
|
|
5702
5718
|
this.dispatch('runLine');
|
|
5703
5719
|
},
|
|
5704
5720
|
async runLine(context) {
|
|
5705
|
-
await this.dispatch('saveGame');
|
|
5706
5721
|
await runLine(context);
|
|
5707
5722
|
},
|
|
5708
5723
|
nextLine(context) {
|
|
@@ -5720,13 +5735,22 @@ function setupStore(options) {
|
|
|
5720
5735
|
lastLabel: state.lastLabel,
|
|
5721
5736
|
skillChecks: state.skillChecks,
|
|
5722
5737
|
playTime: getPlayTime(state.playTime.start, state.playTime.previousPlaytime),
|
|
5738
|
+
hudStats: state.hudStats,
|
|
5739
|
+
currentScreen: state.currentScreen,
|
|
5740
|
+
audio: {
|
|
5741
|
+
currentMusic: state.audio.currentMusic,
|
|
5742
|
+
},
|
|
5723
5743
|
};
|
|
5724
5744
|
localStorage.setItem(SAVE_FILE, JSON.stringify(save));
|
|
5725
5745
|
},
|
|
5726
|
-
loadGame(
|
|
5746
|
+
loadGame(ctx, saveFile) {
|
|
5747
|
+
const { commit, dispatch } = ctx;
|
|
5727
5748
|
if (saveFile) {
|
|
5728
5749
|
const save = JSON.parse(saveFile);
|
|
5729
5750
|
commit('setLoadedData', save);
|
|
5751
|
+
if (save.audio.currentMusic) {
|
|
5752
|
+
changeMusic(ctx, save.audio.currentMusic);
|
|
5753
|
+
}
|
|
5730
5754
|
dispatch('runLabel', save.lastLabel);
|
|
5731
5755
|
}
|
|
5732
5756
|
},
|
|
@@ -5749,6 +5773,9 @@ function setupStore(options) {
|
|
|
5749
5773
|
state.lastLabel = save.lastLabel;
|
|
5750
5774
|
state.skillChecks = save.skillChecks;
|
|
5751
5775
|
state.playTime.previousPlaytime = save.playTime;
|
|
5776
|
+
state.hudStats = save.hudStats;
|
|
5777
|
+
state.currentScreen = save.currentScreen;
|
|
5778
|
+
state.audio = save.audio;
|
|
5752
5779
|
},
|
|
5753
5780
|
reset(state) {
|
|
5754
5781
|
state.ready = false;
|
|
@@ -5801,7 +5828,7 @@ function setupStore(options) {
|
|
|
5801
5828
|
state.hudStats[stat] += amount;
|
|
5802
5829
|
},
|
|
5803
5830
|
addDialog(state, payload) {
|
|
5804
|
-
state.dialog.push(payload.dialog);
|
|
5831
|
+
state.dialog.push({ ...payload.dialog, id: randomId() });
|
|
5805
5832
|
},
|
|
5806
5833
|
nextLine(state) {
|
|
5807
5834
|
state.machine.stack[state.machine.stack.length - 1].currentIndex += 1;
|
|
@@ -5818,6 +5845,7 @@ function setupStore(options) {
|
|
|
5818
5845
|
},
|
|
5819
5846
|
setStack(state, newStack) {
|
|
5820
5847
|
state.machine.stack = [];
|
|
5848
|
+
state.lastLabel = newStack.label;
|
|
5821
5849
|
state.machine.stack.push(newStack);
|
|
5822
5850
|
},
|
|
5823
5851
|
setData(state, { path, value }) {
|
|
@@ -5877,7 +5905,7 @@ function setupStore(options) {
|
|
|
5877
5905
|
return id;
|
|
5878
5906
|
},
|
|
5879
5907
|
deleteNotification(state, id) {
|
|
5880
|
-
|
|
5908
|
+
logger.log('delete notif', id);
|
|
5881
5909
|
delete state.notifications[id];
|
|
5882
5910
|
},
|
|
5883
5911
|
},
|
|
@@ -5902,7 +5930,7 @@ async function startApp(config, options) {
|
|
|
5902
5930
|
mousePos.x = e.clientX;
|
|
5903
5931
|
mousePos.y = e.clientY;
|
|
5904
5932
|
});
|
|
5905
|
-
console.log('%c Narrat game engine – 0.8.
|
|
5933
|
+
console.log('%c Narrat game engine – 0.8.5 - June 4, 2022 20:05:21', 'background: #222; color: #bada55');
|
|
5906
5934
|
const storeSetup = setupStore(options);
|
|
5907
5935
|
store$1 = storeSetup.store;
|
|
5908
5936
|
app = createApp(script$9, {
|
package/lib/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Version: 0.8.
|
|
1
|
+
// Version: 0.8.5 - June 4, 2022 20:05:21
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
4
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
@@ -312,6 +312,22 @@ styleInject(css_248z$2);
|
|
|
312
312
|
|
|
313
313
|
script$1.render = render$1;
|
|
314
314
|
|
|
315
|
+
class Logger {
|
|
316
|
+
debug;
|
|
317
|
+
constructor(debug) {
|
|
318
|
+
this.debug = debug;
|
|
319
|
+
}
|
|
320
|
+
setDebug(debug) {
|
|
321
|
+
this.debug = debug;
|
|
322
|
+
}
|
|
323
|
+
log(...args) {
|
|
324
|
+
if (this.debug) {
|
|
325
|
+
console.log(...args);
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
const logger = new Logger(false);
|
|
330
|
+
|
|
315
331
|
function getPlayTime(startedAt, previousTime) {
|
|
316
332
|
return Date.now() - startedAt + previousTime;
|
|
317
333
|
}
|
|
@@ -412,7 +428,7 @@ var script$3 = vue.defineComponent({
|
|
|
412
428
|
wordCount() {
|
|
413
429
|
const scripts = Object.values(this.$store.state.machine.script);
|
|
414
430
|
const count = scripts.reduce((count, script) => {
|
|
415
|
-
|
|
431
|
+
logger.log(count);
|
|
416
432
|
return count + this.countWordsInScriptBranch(script);
|
|
417
433
|
}, 0);
|
|
418
434
|
alert(`You have ${count} words`);
|
|
@@ -3867,10 +3883,8 @@ var script$4 = vue.defineComponent({
|
|
|
3867
3883
|
},
|
|
3868
3884
|
methods: {
|
|
3869
3885
|
changeVolume(event) {
|
|
3870
|
-
console.log(event);
|
|
3871
3886
|
const target = event.target;
|
|
3872
3887
|
howler.Howler.volume(target.value);
|
|
3873
|
-
console.log(target.value);
|
|
3874
3888
|
},
|
|
3875
3889
|
toggleMute() {
|
|
3876
3890
|
if (this.muted) {
|
|
@@ -4136,7 +4150,7 @@ const images = {};
|
|
|
4136
4150
|
let imagesToLoad = 0;
|
|
4137
4151
|
let imagesLoaded = 0;
|
|
4138
4152
|
function loadImages(config) {
|
|
4139
|
-
|
|
4153
|
+
logger.log(`Loading images`);
|
|
4140
4154
|
return new Promise((resolve, reject) => {
|
|
4141
4155
|
for (const key in config.images) {
|
|
4142
4156
|
const path = config.images[key];
|
|
@@ -4146,19 +4160,19 @@ function loadImages(config) {
|
|
|
4146
4160
|
}
|
|
4147
4161
|
function loadImage(key, path, resolver, rejecter) {
|
|
4148
4162
|
imagesToLoad++;
|
|
4149
|
-
|
|
4163
|
+
logger.log(`Loading image ${key} at ${path}`);
|
|
4150
4164
|
const image = new Image();
|
|
4151
4165
|
image.onload = () => {
|
|
4152
4166
|
imagesLoaded += 1;
|
|
4153
4167
|
images[key] = image;
|
|
4154
|
-
|
|
4168
|
+
logger.log(`Loaded image ${key} successfully`);
|
|
4155
4169
|
if (imagesLoaded >= imagesToLoad) {
|
|
4156
|
-
|
|
4170
|
+
logger.log(`All images loaded`);
|
|
4157
4171
|
resolver();
|
|
4158
4172
|
}
|
|
4159
4173
|
};
|
|
4160
4174
|
image.onerror = (e) => {
|
|
4161
|
-
console.
|
|
4175
|
+
console.error(`Error loading image ${key}`);
|
|
4162
4176
|
rejecter(e);
|
|
4163
4177
|
};
|
|
4164
4178
|
image.src = path;
|
|
@@ -4167,7 +4181,7 @@ function loadImage(key, path, resolver, rejecter) {
|
|
|
4167
4181
|
const audio = {};
|
|
4168
4182
|
howler.Howler.volume(0.5);
|
|
4169
4183
|
async function loadAudioAssets(config) {
|
|
4170
|
-
|
|
4184
|
+
logger.log(`Loading audio`);
|
|
4171
4185
|
const loadingPromises = [];
|
|
4172
4186
|
for (const key in config.music) {
|
|
4173
4187
|
// Backward compatibility with old music list
|
|
@@ -4197,7 +4211,7 @@ async function loadAudioAssets(config) {
|
|
|
4197
4211
|
}
|
|
4198
4212
|
async function loadAudio(key, config) {
|
|
4199
4213
|
return new Promise((resolve, reject) => {
|
|
4200
|
-
|
|
4214
|
+
logger.log(`Loading audio ${config.src}`);
|
|
4201
4215
|
const sound = new howler.Howl({
|
|
4202
4216
|
...config,
|
|
4203
4217
|
});
|
|
@@ -4388,7 +4402,6 @@ styleInject(css_248z$9);
|
|
|
4388
4402
|
|
|
4389
4403
|
script$8.render = render$8;
|
|
4390
4404
|
|
|
4391
|
-
console.log('hello app');
|
|
4392
4405
|
var script$9 = vue.defineComponent({
|
|
4393
4406
|
$refs: {
|
|
4394
4407
|
dialogContainer: HTMLInputElement,
|
|
@@ -4448,7 +4461,6 @@ var script$9 = vue.defineComponent({
|
|
|
4448
4461
|
dialogLength(newCount, oldCount) {
|
|
4449
4462
|
if (this.$refs.dialog) {
|
|
4450
4463
|
const dialog = this.$refs.dialog;
|
|
4451
|
-
console.log('hello dialog');
|
|
4452
4464
|
dialog.scrollTop = dialog.scrollHeight + 100000;
|
|
4453
4465
|
}
|
|
4454
4466
|
},
|
|
@@ -4681,8 +4693,8 @@ const _hoisted_4$3 = { key: 2 };
|
|
|
4681
4693
|
|
|
4682
4694
|
function render$9(_ctx, _cache, $props, $setup, $data, $options) {
|
|
4683
4695
|
const _component_Hud = vue.resolveComponent("Hud");
|
|
4684
|
-
const _component_DialogPicture = vue.resolveComponent("DialogPicture");
|
|
4685
4696
|
const _component_Menu = vue.resolveComponent("Menu");
|
|
4697
|
+
const _component_DialogPicture = vue.resolveComponent("DialogPicture");
|
|
4686
4698
|
const _component_DialogBox = vue.resolveComponent("DialogBox");
|
|
4687
4699
|
const _component_LoadingBar = vue.resolveComponent("LoadingBar");
|
|
4688
4700
|
const _component_DebugMenu = vue.resolveComponent("DebugMenu");
|
|
@@ -4699,6 +4711,7 @@ function render$9(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
4699
4711
|
class: "game",
|
|
4700
4712
|
style: vue.normalizeStyle(_ctx.gameStyle)
|
|
4701
4713
|
}, [
|
|
4714
|
+
vue.createVNode(_component_Menu, { class: "menu-toggle" }),
|
|
4702
4715
|
vue.createVNode(vue.Transition, { name: "fade" }, {
|
|
4703
4716
|
default: vue.withCtx(() => [
|
|
4704
4717
|
(_ctx.picture)
|
|
@@ -4730,7 +4743,6 @@ function render$9(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
4730
4743
|
ref: "dialog",
|
|
4731
4744
|
style: vue.normalizeStyle(_ctx.dialogStyle)
|
|
4732
4745
|
}, [
|
|
4733
|
-
vue.createVNode(_component_Menu, { class: "menu-toggle" }),
|
|
4734
4746
|
vue.createVNode(vue.TransitionGroup, {
|
|
4735
4747
|
name: "list",
|
|
4736
4748
|
tag: "div",
|
|
@@ -4740,7 +4752,7 @@ function render$9(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
4740
4752
|
default: vue.withCtx(() => [
|
|
4741
4753
|
(vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(_ctx.dialog, (dialog, i) => {
|
|
4742
4754
|
return (vue.openBlock(), vue.createBlock(_component_DialogBox, {
|
|
4743
|
-
key:
|
|
4755
|
+
key: dialog.id,
|
|
4744
4756
|
options: _ctx.getDialogBoxOptions(dialog, i),
|
|
4745
4757
|
active: _ctx.isDialogActive(i)
|
|
4746
4758
|
}, null, 8, ["options", "active"]))
|
|
@@ -4779,7 +4791,7 @@ function render$9(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
4779
4791
|
], 4))
|
|
4780
4792
|
}
|
|
4781
4793
|
|
|
4782
|
-
var css_248z$a = "#app {\n background-color: black;\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: white;\n box-sizing: border-box;\n overflow: hidden;\n transform-origin: center center;\n}\n\n.game {\n background-color: black;\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 background-color: #72080f;\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: #171717;\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:
|
|
4794
|
+
var css_248z$a = "#app {\n background-color: black;\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: white;\n box-sizing: border-box;\n overflow: hidden;\n transform-origin: center center;\n}\n\n.game {\n background-color: black;\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 background-color: #72080f;\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: #171717;\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: 108398;\n}\r\n";
|
|
4783
4795
|
styleInject(css_248z$a);
|
|
4784
4796
|
|
|
4785
4797
|
script$9.render = render$9;
|
|
@@ -4828,7 +4840,7 @@ function runSkillCheck(ctx, params) {
|
|
|
4828
4840
|
}
|
|
4829
4841
|
roll += state.skills[params.skill].level * skillChecks.skillMultiplier;
|
|
4830
4842
|
const skill = skills[params.skill];
|
|
4831
|
-
|
|
4843
|
+
logger.log(`roll `, roll, params.value);
|
|
4832
4844
|
if (roll < params.value) {
|
|
4833
4845
|
success = false;
|
|
4834
4846
|
}
|
|
@@ -4844,7 +4856,7 @@ function runSkillCheck(ctx, params) {
|
|
|
4844
4856
|
function runConditionCommand(ctx, command) {
|
|
4845
4857
|
const options = command.options;
|
|
4846
4858
|
const result = runCondition(ctx, options.condition);
|
|
4847
|
-
|
|
4859
|
+
logger.log(result);
|
|
4848
4860
|
if (result) {
|
|
4849
4861
|
return options.success;
|
|
4850
4862
|
}
|
|
@@ -4915,6 +4927,7 @@ async function runCommand(context, cmd, choices) {
|
|
|
4915
4927
|
currentIndex: 0,
|
|
4916
4928
|
};
|
|
4917
4929
|
commit('setStack', newStack);
|
|
4930
|
+
await dispatch('saveGame');
|
|
4918
4931
|
await dispatch('runLine');
|
|
4919
4932
|
break;
|
|
4920
4933
|
case 'text':
|
|
@@ -4965,7 +4978,6 @@ async function runCommand(context, cmd, choices) {
|
|
|
4965
4978
|
commit('clearDialog');
|
|
4966
4979
|
return dispatch('nextLine');
|
|
4967
4980
|
case 'set_button':
|
|
4968
|
-
console.log(cmd.args);
|
|
4969
4981
|
commit('changeButton', {
|
|
4970
4982
|
button: cmd.args[0],
|
|
4971
4983
|
enabled: cmd.args[1],
|
|
@@ -5052,7 +5064,7 @@ async function runCommand(context, cmd, choices) {
|
|
|
5052
5064
|
}
|
|
5053
5065
|
}
|
|
5054
5066
|
catch (err) {
|
|
5055
|
-
|
|
5067
|
+
logger.log(`Error at: `, state.machine.stack[state.machine.stack.length - 1].label);
|
|
5056
5068
|
console.error(err);
|
|
5057
5069
|
error(commit, `Narrat script runtime error at <span class="error-filename">${cmd.fileName}:${cmd.line + 1}</span>
|
|
5058
5070
|
<b>${err}</b>
|
|
@@ -5131,7 +5143,6 @@ async function runChoice(context, cmd) {
|
|
|
5131
5143
|
const skill = config.skills[check.skill];
|
|
5132
5144
|
const level = context.state.skills[check.skill].level;
|
|
5133
5145
|
const difficultyScore = check.value - level * config.skillChecks.skillMultiplier;
|
|
5134
|
-
console.log(`Check `, check, `score `, difficultyScore);
|
|
5135
5146
|
const skillCheckState = getSkillCheckState(context, choice.skillCheck.id);
|
|
5136
5147
|
let found = false;
|
|
5137
5148
|
let i = 0;
|
|
@@ -5418,7 +5429,7 @@ function parseRenpyScript(errorHandler, code, fileName) {
|
|
|
5418
5429
|
};
|
|
5419
5430
|
ctx.indentSize = detectIndentation(ctx, code);
|
|
5420
5431
|
const lines = findRenpyLines(ctx, code);
|
|
5421
|
-
|
|
5432
|
+
logger.log(lines);
|
|
5422
5433
|
const script = {};
|
|
5423
5434
|
for (const line of lines) {
|
|
5424
5435
|
if (line.code.search(':') === -1) {
|
|
@@ -5600,10 +5611,14 @@ function detectIndentation(ctx, script) {
|
|
|
5600
5611
|
if (result.length < 2) {
|
|
5601
5612
|
ctx.error(0, `Can't detect indentation level. Make sure you indent with at least 2 spaces and consistently`);
|
|
5602
5613
|
}
|
|
5603
|
-
|
|
5614
|
+
logger.log(result);
|
|
5604
5615
|
return result[1].length;
|
|
5605
5616
|
}
|
|
5606
5617
|
|
|
5618
|
+
function randomId() {
|
|
5619
|
+
return `${Date.now() - Math.floor(Math.random() * 99999999)}`;
|
|
5620
|
+
}
|
|
5621
|
+
|
|
5607
5622
|
let key = Symbol('Store Injection Key');
|
|
5608
5623
|
let store;
|
|
5609
5624
|
function setupStore(options) {
|
|
@@ -5614,7 +5629,8 @@ function setupStore(options) {
|
|
|
5614
5629
|
}
|
|
5615
5630
|
// define injection key
|
|
5616
5631
|
key = Symbol('Store Injection Key');
|
|
5617
|
-
|
|
5632
|
+
logger.setDebug(options.debug);
|
|
5633
|
+
logger.log('setup store');
|
|
5618
5634
|
store = vuex.createStore({
|
|
5619
5635
|
state: {
|
|
5620
5636
|
machine: {
|
|
@@ -5684,7 +5700,7 @@ function setupStore(options) {
|
|
|
5684
5700
|
};
|
|
5685
5701
|
}
|
|
5686
5702
|
const end = Date.now();
|
|
5687
|
-
|
|
5703
|
+
logger.log(`script parsed in ${end - start} ms`);
|
|
5688
5704
|
commit('setButtons', payload.config.buttons);
|
|
5689
5705
|
commit('setScript', scripts);
|
|
5690
5706
|
commit('setupSkills', payload.config.skills);
|
|
@@ -5706,7 +5722,6 @@ function setupStore(options) {
|
|
|
5706
5722
|
this.dispatch('runLine');
|
|
5707
5723
|
},
|
|
5708
5724
|
async runLine(context) {
|
|
5709
|
-
await this.dispatch('saveGame');
|
|
5710
5725
|
await runLine(context);
|
|
5711
5726
|
},
|
|
5712
5727
|
nextLine(context) {
|
|
@@ -5724,13 +5739,22 @@ function setupStore(options) {
|
|
|
5724
5739
|
lastLabel: state.lastLabel,
|
|
5725
5740
|
skillChecks: state.skillChecks,
|
|
5726
5741
|
playTime: getPlayTime(state.playTime.start, state.playTime.previousPlaytime),
|
|
5742
|
+
hudStats: state.hudStats,
|
|
5743
|
+
currentScreen: state.currentScreen,
|
|
5744
|
+
audio: {
|
|
5745
|
+
currentMusic: state.audio.currentMusic,
|
|
5746
|
+
},
|
|
5727
5747
|
};
|
|
5728
5748
|
localStorage.setItem(SAVE_FILE, JSON.stringify(save));
|
|
5729
5749
|
},
|
|
5730
|
-
loadGame(
|
|
5750
|
+
loadGame(ctx, saveFile) {
|
|
5751
|
+
const { commit, dispatch } = ctx;
|
|
5731
5752
|
if (saveFile) {
|
|
5732
5753
|
const save = JSON.parse(saveFile);
|
|
5733
5754
|
commit('setLoadedData', save);
|
|
5755
|
+
if (save.audio.currentMusic) {
|
|
5756
|
+
changeMusic(ctx, save.audio.currentMusic);
|
|
5757
|
+
}
|
|
5734
5758
|
dispatch('runLabel', save.lastLabel);
|
|
5735
5759
|
}
|
|
5736
5760
|
},
|
|
@@ -5753,6 +5777,9 @@ function setupStore(options) {
|
|
|
5753
5777
|
state.lastLabel = save.lastLabel;
|
|
5754
5778
|
state.skillChecks = save.skillChecks;
|
|
5755
5779
|
state.playTime.previousPlaytime = save.playTime;
|
|
5780
|
+
state.hudStats = save.hudStats;
|
|
5781
|
+
state.currentScreen = save.currentScreen;
|
|
5782
|
+
state.audio = save.audio;
|
|
5756
5783
|
},
|
|
5757
5784
|
reset(state) {
|
|
5758
5785
|
state.ready = false;
|
|
@@ -5805,7 +5832,7 @@ function setupStore(options) {
|
|
|
5805
5832
|
state.hudStats[stat] += amount;
|
|
5806
5833
|
},
|
|
5807
5834
|
addDialog(state, payload) {
|
|
5808
|
-
state.dialog.push(payload.dialog);
|
|
5835
|
+
state.dialog.push({ ...payload.dialog, id: randomId() });
|
|
5809
5836
|
},
|
|
5810
5837
|
nextLine(state) {
|
|
5811
5838
|
state.machine.stack[state.machine.stack.length - 1].currentIndex += 1;
|
|
@@ -5822,6 +5849,7 @@ function setupStore(options) {
|
|
|
5822
5849
|
},
|
|
5823
5850
|
setStack(state, newStack) {
|
|
5824
5851
|
state.machine.stack = [];
|
|
5852
|
+
state.lastLabel = newStack.label;
|
|
5825
5853
|
state.machine.stack.push(newStack);
|
|
5826
5854
|
},
|
|
5827
5855
|
setData(state, { path, value }) {
|
|
@@ -5881,7 +5909,7 @@ function setupStore(options) {
|
|
|
5881
5909
|
return id;
|
|
5882
5910
|
},
|
|
5883
5911
|
deleteNotification(state, id) {
|
|
5884
|
-
|
|
5912
|
+
logger.log('delete notif', id);
|
|
5885
5913
|
delete state.notifications[id];
|
|
5886
5914
|
},
|
|
5887
5915
|
},
|
|
@@ -5906,7 +5934,7 @@ async function startApp(config, options) {
|
|
|
5906
5934
|
mousePos.x = e.clientX;
|
|
5907
5935
|
mousePos.y = e.clientY;
|
|
5908
5936
|
});
|
|
5909
|
-
console.log('%c Narrat game engine – 0.8.
|
|
5937
|
+
console.log('%c Narrat game engine – 0.8.5 - June 4, 2022 20:05:21', 'background: #222; color: #bada55');
|
|
5910
5938
|
const storeSetup = setupStore(options);
|
|
5911
5939
|
store$1 = storeSetup.store;
|
|
5912
5940
|
app = vue.createApp(script$9, {
|
package/lib/store.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { InjectionKey, State } from 'vue';
|
|
2
2
|
import { Store } from 'vuex';
|
|
3
|
-
import { MachineStack } from './types/vuex';
|
|
3
|
+
import { DialogKey, MachineStack } from './types/vuex';
|
|
4
4
|
import { AppOptions } from '.';
|
|
5
|
+
export declare type AddDialogParams = Omit<DialogKey, 'id'>;
|
|
5
6
|
export interface SetupStoreResult {
|
|
6
7
|
store: Store<State>;
|
|
7
8
|
key: InjectionKey<Store<State>>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function randomId(): string;
|
package/lib/vm/renpy-vm.d.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { ActionContext, Commit } from 'vuex';
|
|
2
2
|
import { State } from 'vue';
|
|
3
|
-
import {
|
|
3
|
+
import { DialogChoice } from '@/types/vuex';
|
|
4
|
+
import { AddDialogParams } from '@/store';
|
|
4
5
|
export declare function runLine(context: ActionContext<State, State>): Promise<void>;
|
|
5
6
|
export declare function runCommand(context: ActionContext<State, State>, cmd: Parser.Command, choices?: DialogChoice[]): Promise<any>;
|
|
6
7
|
export declare function playerAnswered(context: ActionContext<State, State>, choiceIndex: number): Promise<void>;
|
|
7
8
|
export declare function runChoice(context: ActionContext<State, State>, cmd: Parser.Command): Promise<void>;
|
|
8
|
-
export declare function textCommand(commit: Commit, dialog:
|
|
9
|
+
export declare function textCommand(commit: Commit, dialog: AddDialogParams): Promise<void>;
|
|
9
10
|
export declare function nextLine(ctx: ActionContext<State, State>): Promise<any>;
|
|
10
11
|
export declare function finishGame({ commit, state }: ActionContext<State, State>): void;
|