@novely/core 0.31.3 → 0.33.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +13 -2
- package/dist/index.global.js +105 -77
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +105 -77
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -483,7 +483,7 @@ type Character<$Lang extends Lang = string> = {
|
|
|
483
483
|
type ValidAction = ['choice', number] | ['clear', Set<keyof DefaultActionProxy>?, Set<string>?, {
|
|
484
484
|
music: Set<string>;
|
|
485
485
|
sounds: Set<string>;
|
|
486
|
-
}?] | ['condition', (state: State) => boolean, Record<string, ValidAction[]>] | ['dialog', string | undefined, TextContent<string, State>, string | undefined] | ['say', string, TextContent<string, State>] | ['end'] | ['showBackground', string | NonEmptyRecord<BackgroundImage>] | ['playMusic', string] | ['stopMusic', string] | ['pauseMusic', string] | ['playSound', audio: string, loop?: boolean] | ['pauseSound', string] | ['stopSound', string] | ['voice', string] | ['stopVoice'] | ['jump', string] | ['showCharacter', string, keyof Character['emotions'], string?, string?] | ['hideCharacter', string, string?, string?, number?] | ['animateCharacter', string, number, ...string[]] | ['wait', (number | ((state: State) => number))] | ['function', FunctionAction<string, State>] | ['input', string, (meta: ActionInputOnInputMeta<string, State>) => void, ActionInputSetup?] | ['custom', CustomHandler<string, State>] | ['vibrate', ...number[]] | ['next'] | ['text', ...TextContent<string, State>[]] | ['exit'] | ['preload', string] | ['block', string] | ValidAction[];
|
|
486
|
+
}?] | ['condition', (state: State) => boolean, Record<string, ValidAction[]>] | ['dialog', string | undefined, TextContent<string, State>, string | undefined] | ['say', string, TextContent<string, State>] | ['end'] | ['showBackground', string | NonEmptyRecord<BackgroundImage>] | ['playMusic', string] | ['stopMusic', string] | ['pauseMusic', string] | ['playSound', audio: string, loop?: boolean] | ['pauseSound', string] | ['stopSound', string] | ['voice', string | Record<string, string>] | ['stopVoice'] | ['jump', string] | ['showCharacter', string, keyof Character['emotions'], string?, string?] | ['hideCharacter', string, string?, string?, number?] | ['animateCharacter', string, number, ...string[]] | ['wait', (number | ((state: State) => number))] | ['function', FunctionAction<string, State>] | ['input', string, (meta: ActionInputOnInputMeta<string, State>) => void, ActionInputSetup?] | ['custom', CustomHandler<string, State>] | ['vibrate', ...number[]] | ['next'] | ['text', ...TextContent<string, State>[]] | ['exit'] | ['preload', string] | ['block', string] | ValidAction[];
|
|
487
487
|
type Story = Record<string, ValidAction[]>;
|
|
488
488
|
type TextContent<L extends string, S extends State> = string | ((state: S) => string) | Record<L, string | ((state: S) => string)>;
|
|
489
489
|
type FunctionableValue<T> = T | (() => T);
|
|
@@ -587,6 +587,7 @@ type ConditionCheckFunction<S extends State, R extends string | true | false> =
|
|
|
587
587
|
type FunctionAction<L extends string, S extends State> = (props: FunctionActionProps<L, S>) => Thenable<void>;
|
|
588
588
|
type ActionInputSetup = (input: HTMLInputElement, cleanup: (cb: () => void) => void) => void;
|
|
589
589
|
type BackgroundImage = Partial<Record<'portrait' | 'landscape' | 'all', string>> & Record<string, string>;
|
|
590
|
+
type VoiceAction<L extends Lang> = (params: string | Partial<Record<L, string>>) => ValidAction;
|
|
590
591
|
type ActionProxy<Characters extends Record<string, Character>, Languages extends Lang, S extends State> = {
|
|
591
592
|
choice: {
|
|
592
593
|
(...choices: [name: TextContent<Languages, S>, actions: ValidAction[], active?: ChoiceCheckFunction<Languages, S>][]): ValidAction;
|
|
@@ -614,8 +615,18 @@ type ActionProxy<Characters extends Record<string, Character>, Languages extends
|
|
|
614
615
|
stopSound: (audio: string) => ValidAction;
|
|
615
616
|
/**
|
|
616
617
|
* Plays voice
|
|
618
|
+
*
|
|
619
|
+
* @example
|
|
620
|
+
* ```
|
|
621
|
+
* engine.script({
|
|
622
|
+
* start: [
|
|
623
|
+
* engine.action.voice('./rick-astley-never-gonna-give-you-up.mp3'),
|
|
624
|
+
* engine.action.say('Rick', 'Never gonna give you up'),
|
|
625
|
+
* ]
|
|
626
|
+
* })
|
|
627
|
+
* ```
|
|
617
628
|
*/
|
|
618
|
-
voice:
|
|
629
|
+
voice: VoiceAction<Languages>;
|
|
619
630
|
/**
|
|
620
631
|
* Stops currently playing voice
|
|
621
632
|
*/
|
package/dist/index.global.js
CHANGED
|
@@ -642,6 +642,90 @@ var Novely = (() => {
|
|
|
642
642
|
return lang;
|
|
643
643
|
}
|
|
644
644
|
};
|
|
645
|
+
var createReferFunction = (story) => {
|
|
646
|
+
const refer = (path) => {
|
|
647
|
+
let current = story;
|
|
648
|
+
let precurrent = story;
|
|
649
|
+
const blocks = [];
|
|
650
|
+
for (const [type, val] of path) {
|
|
651
|
+
if (type === "jump") {
|
|
652
|
+
precurrent = story;
|
|
653
|
+
current = current[val];
|
|
654
|
+
} else if (type === null) {
|
|
655
|
+
precurrent = current;
|
|
656
|
+
current = current[val];
|
|
657
|
+
} else if (type === "choice") {
|
|
658
|
+
blocks.push(precurrent);
|
|
659
|
+
current = current[val + 1][1];
|
|
660
|
+
} else if (type === "condition") {
|
|
661
|
+
blocks.push(precurrent);
|
|
662
|
+
current = current[2][val];
|
|
663
|
+
} else if (type === "block") {
|
|
664
|
+
blocks.push(precurrent);
|
|
665
|
+
current = story[val];
|
|
666
|
+
} else if (type === "block:exit" || type === "choice:exit" || type === "condition:exit") {
|
|
667
|
+
current = blocks.pop();
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
return current;
|
|
671
|
+
};
|
|
672
|
+
return refer;
|
|
673
|
+
};
|
|
674
|
+
var exitPath = ({ path, refer, onExitImpossible }) => {
|
|
675
|
+
const last = path.at(-1);
|
|
676
|
+
const ignore = [];
|
|
677
|
+
let wasExitImpossible = false;
|
|
678
|
+
if (!isAction(refer(path))) {
|
|
679
|
+
if (last && isNull(last[0]) && isNumber(last[1])) {
|
|
680
|
+
last[1]--;
|
|
681
|
+
} else {
|
|
682
|
+
path.pop();
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
if (isExitImpossible(path)) {
|
|
686
|
+
const referred = refer(path);
|
|
687
|
+
if (isAction(referred) && isSkippedDuringRestore(referred[0])) {
|
|
688
|
+
onExitImpossible();
|
|
689
|
+
}
|
|
690
|
+
wasExitImpossible = true;
|
|
691
|
+
return {
|
|
692
|
+
exitImpossible: wasExitImpossible
|
|
693
|
+
};
|
|
694
|
+
}
|
|
695
|
+
for (let i = path.length - 1; i > 0; i--) {
|
|
696
|
+
const [name] = path[i];
|
|
697
|
+
if (isBlockExitStatement(name)) {
|
|
698
|
+
ignore.push(name);
|
|
699
|
+
}
|
|
700
|
+
if (!isBlockStatement(name))
|
|
701
|
+
continue;
|
|
702
|
+
if (ignore.at(-1)?.startsWith(name)) {
|
|
703
|
+
ignore.pop();
|
|
704
|
+
continue;
|
|
705
|
+
}
|
|
706
|
+
path.push([`${name}:exit`]);
|
|
707
|
+
const prev = findLastPathItemBeforeItemOfType(path.slice(0, i + 1), name);
|
|
708
|
+
if (prev)
|
|
709
|
+
path.push([null, prev[1] + 1]);
|
|
710
|
+
if (!isAction(refer(path))) {
|
|
711
|
+
path.pop();
|
|
712
|
+
continue;
|
|
713
|
+
}
|
|
714
|
+
break;
|
|
715
|
+
}
|
|
716
|
+
return {
|
|
717
|
+
exitImpossible: wasExitImpossible
|
|
718
|
+
};
|
|
719
|
+
};
|
|
720
|
+
var nextPath = (path) => {
|
|
721
|
+
const last = path.at(-1);
|
|
722
|
+
if (last && (isNull(last[0]) || last[0] === "jump") && isNumber(last[1])) {
|
|
723
|
+
last[1]++;
|
|
724
|
+
} else {
|
|
725
|
+
path.push([null, 0]);
|
|
726
|
+
}
|
|
727
|
+
return path;
|
|
728
|
+
};
|
|
645
729
|
|
|
646
730
|
// ../../node_modules/.pnpm/dequal@2.0.3/node_modules/dequal/lite/index.mjs
|
|
647
731
|
var has = Object.prototype.hasOwnProperty;
|
|
@@ -1169,10 +1253,12 @@ var Novely = (() => {
|
|
|
1169
1253
|
}
|
|
1170
1254
|
}
|
|
1171
1255
|
}
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1256
|
+
if (context.meta.goingBack) {
|
|
1257
|
+
match("clear", [keep, characters2, audio], {
|
|
1258
|
+
ctx: context,
|
|
1259
|
+
data: latest[1]
|
|
1260
|
+
});
|
|
1261
|
+
}
|
|
1176
1262
|
const lastQueueItem = queue.at(-1) || [];
|
|
1177
1263
|
const lastQueueItemRequiresUserAction = isSkippedDuringRestore(lastQueueItem[0]) || isUserRequiredAction(lastQueueItem);
|
|
1178
1264
|
await run((item) => {
|
|
@@ -1190,32 +1276,7 @@ var Novely = (() => {
|
|
|
1190
1276
|
context.meta.restoring = context.meta.goingBack = false;
|
|
1191
1277
|
render(context);
|
|
1192
1278
|
};
|
|
1193
|
-
const refer = (
|
|
1194
|
-
let current = story;
|
|
1195
|
-
let precurrent = story;
|
|
1196
|
-
const blocks = [];
|
|
1197
|
-
for (const [type, val] of path) {
|
|
1198
|
-
if (type === "jump") {
|
|
1199
|
-
precurrent = story;
|
|
1200
|
-
current = current[val];
|
|
1201
|
-
} else if (type === null) {
|
|
1202
|
-
precurrent = current;
|
|
1203
|
-
current = current[val];
|
|
1204
|
-
} else if (type === "choice") {
|
|
1205
|
-
blocks.push(precurrent);
|
|
1206
|
-
current = current[val + 1][1];
|
|
1207
|
-
} else if (type === "condition") {
|
|
1208
|
-
blocks.push(precurrent);
|
|
1209
|
-
current = current[2][val];
|
|
1210
|
-
} else if (type === "block") {
|
|
1211
|
-
blocks.push(precurrent);
|
|
1212
|
-
current = story[val];
|
|
1213
|
-
} else if (type === "block:exit" || type === "choice:exit" || type === "condition:exit") {
|
|
1214
|
-
current = blocks.pop();
|
|
1215
|
-
}
|
|
1216
|
-
}
|
|
1217
|
-
return current;
|
|
1218
|
-
};
|
|
1279
|
+
const refer = createReferFunction(story);
|
|
1219
1280
|
const exit = (force = false, saving = true) => {
|
|
1220
1281
|
const ctx = renderer.getContext(MAIN_CONTEXT_KEY);
|
|
1221
1282
|
const stack = useStack(ctx);
|
|
@@ -1340,15 +1401,6 @@ var Novely = (() => {
|
|
|
1340
1401
|
stack.push(current);
|
|
1341
1402
|
save("auto");
|
|
1342
1403
|
};
|
|
1343
|
-
const nextPath = (path) => {
|
|
1344
|
-
const last = path.at(-1);
|
|
1345
|
-
if (last && (isNull(last[0]) || last[0] === "jump") && isNumber(last[1])) {
|
|
1346
|
-
last[1]++;
|
|
1347
|
-
} else {
|
|
1348
|
-
path.push([null, 0]);
|
|
1349
|
-
}
|
|
1350
|
-
return path;
|
|
1351
|
-
};
|
|
1352
1404
|
const next = (ctx) => {
|
|
1353
1405
|
const stack = useStack(ctx);
|
|
1354
1406
|
const path = stack.value[0];
|
|
@@ -1405,7 +1457,13 @@ var Novely = (() => {
|
|
|
1405
1457
|
push();
|
|
1406
1458
|
},
|
|
1407
1459
|
voice({ ctx, push }, [source]) {
|
|
1408
|
-
|
|
1460
|
+
const [lang] = storageData.get().meta;
|
|
1461
|
+
const audioSource = isString(source) ? source : source[lang];
|
|
1462
|
+
if (!audioSource) {
|
|
1463
|
+
push();
|
|
1464
|
+
return;
|
|
1465
|
+
}
|
|
1466
|
+
ctx.audio.voice(audioSource);
|
|
1409
1467
|
push();
|
|
1410
1468
|
},
|
|
1411
1469
|
stopVoice({ ctx, push }) {
|
|
@@ -1607,49 +1665,19 @@ var Novely = (() => {
|
|
|
1607
1665
|
exit({ ctx, data: data2 }) {
|
|
1608
1666
|
if (ctx.meta.restoring)
|
|
1609
1667
|
return;
|
|
1610
|
-
const
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
if (!isAction(refer(path))) {
|
|
1615
|
-
if (last && isNull(last[0]) && isNumber(last[1])) {
|
|
1616
|
-
last[1]--;
|
|
1617
|
-
} else {
|
|
1618
|
-
path.pop();
|
|
1619
|
-
}
|
|
1620
|
-
}
|
|
1621
|
-
if (isExitImpossible(path)) {
|
|
1622
|
-
const referred = refer(path);
|
|
1623
|
-
if (isAction(referred) && isSkippedDuringRestore(referred[0])) {
|
|
1668
|
+
const { exitImpossible } = exitPath({
|
|
1669
|
+
path: useStack(ctx).value[0],
|
|
1670
|
+
refer,
|
|
1671
|
+
onExitImpossible: () => {
|
|
1624
1672
|
match("end", [], {
|
|
1625
1673
|
ctx,
|
|
1626
1674
|
data: data2
|
|
1627
1675
|
});
|
|
1628
1676
|
}
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
const [name] = path[i];
|
|
1633
|
-
if (isBlockExitStatement(name)) {
|
|
1634
|
-
ignore.push(name);
|
|
1635
|
-
}
|
|
1636
|
-
if (!isBlockStatement(name))
|
|
1637
|
-
continue;
|
|
1638
|
-
if (ignore.at(-1)?.startsWith(name)) {
|
|
1639
|
-
ignore.pop();
|
|
1640
|
-
continue;
|
|
1641
|
-
}
|
|
1642
|
-
path.push([`${name}:exit`]);
|
|
1643
|
-
const prev = findLastPathItemBeforeItemOfType(path.slice(0, i + 1), name);
|
|
1644
|
-
if (prev)
|
|
1645
|
-
path.push([null, prev[1] + 1]);
|
|
1646
|
-
if (!isAction(refer(path))) {
|
|
1647
|
-
path.pop();
|
|
1648
|
-
continue;
|
|
1649
|
-
}
|
|
1650
|
-
break;
|
|
1677
|
+
});
|
|
1678
|
+
if (!exitImpossible) {
|
|
1679
|
+
render(ctx);
|
|
1651
1680
|
}
|
|
1652
|
-
render(ctx);
|
|
1653
1681
|
},
|
|
1654
1682
|
preload({ ctx, push }, [source]) {
|
|
1655
1683
|
if (!ctx.meta.goingBack && !ctx.meta.restoring && !PRELOADED_ASSETS.has(source)) {
|