@novely/core 0.34.0 → 0.36.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 +60 -23
- package/dist/index.global.js +268 -61
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +268 -61
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -75,6 +75,20 @@ interface CharacterHandle {
|
|
|
75
75
|
animate: (timeout: number, classes: string[]) => void;
|
|
76
76
|
emotions: Record<string, HTMLImageElement[]>;
|
|
77
77
|
}
|
|
78
|
+
type CustomActionHandle = {
|
|
79
|
+
/**
|
|
80
|
+
* Function to remove custom action from screen (and from your state if any completely)
|
|
81
|
+
*/
|
|
82
|
+
remove: () => void;
|
|
83
|
+
/**
|
|
84
|
+
* Function that will give action root (element which you should add to the screen because custom actions rendered into that element)
|
|
85
|
+
*/
|
|
86
|
+
setMountElement: (mountElement: null | HTMLDivElement) => void;
|
|
87
|
+
/**
|
|
88
|
+
* Function that will give you clean function provided by custom action.
|
|
89
|
+
*/
|
|
90
|
+
setClear: (clear: () => void) => void;
|
|
91
|
+
};
|
|
78
92
|
type AudioHandle = {
|
|
79
93
|
stop: () => void;
|
|
80
94
|
pause: () => void;
|
|
@@ -93,8 +107,7 @@ type Context = {
|
|
|
93
107
|
music: Set<string>;
|
|
94
108
|
sounds: Set<string>;
|
|
95
109
|
}, resolve: () => void) => void;
|
|
96
|
-
custom: (fn: CustomHandler<Lang, State
|
|
97
|
-
clearCustom: (fn: CustomHandler<Lang, State>) => void;
|
|
110
|
+
custom: (fn: CustomHandler<Lang, State>) => CustomActionHandle;
|
|
98
111
|
/**
|
|
99
112
|
* Clears all mentioned actions except for preserved one
|
|
100
113
|
* @param preserve Action that should not be cleared
|
|
@@ -213,6 +226,7 @@ type RendererInit<$Language extends Lang, $Characters extends Record<string, Cha
|
|
|
213
226
|
preview: (save: Save<State>, name: string) => Promise<void>;
|
|
214
227
|
removeContext: (name: string) => void;
|
|
215
228
|
getStateFunction: (context: string) => StateFunction<State>;
|
|
229
|
+
clearCustomAction: (ctx: Context, customAction: CustomHandler) => void;
|
|
216
230
|
getLanguageDisplayName: (lang: Lang) => string;
|
|
217
231
|
};
|
|
218
232
|
|
|
@@ -438,7 +452,7 @@ interface NovelyInit<$Language extends Lang, $Characters extends Record<string,
|
|
|
438
452
|
/**
|
|
439
453
|
* @default "lazy"
|
|
440
454
|
*/
|
|
441
|
-
preloadAssets?: 'lazy' | 'blocking';
|
|
455
|
+
preloadAssets?: 'lazy' | 'blocking' | 'automatic';
|
|
442
456
|
/**
|
|
443
457
|
* Fetching function
|
|
444
458
|
*/
|
|
@@ -499,36 +513,59 @@ type FunctionableValue<T> = T | (() => T);
|
|
|
499
513
|
type CustomHandlerGetResultDataFunction = (data?: Record<string, unknown>) => Record<string, unknown>;
|
|
500
514
|
type CustomHandlerGetResult<I extends boolean> = {
|
|
501
515
|
/**
|
|
502
|
-
*
|
|
516
|
+
* Element for the custom action to be rendered into
|
|
503
517
|
*/
|
|
504
|
-
|
|
518
|
+
element: I extends true ? HTMLDivElement : null;
|
|
505
519
|
/**
|
|
506
|
-
*
|
|
520
|
+
* Root node
|
|
507
521
|
*/
|
|
508
|
-
|
|
522
|
+
root: HTMLElement;
|
|
523
|
+
};
|
|
524
|
+
type CustomHandlerFunctionGetFn = <I extends boolean = true>(insert?: I) => CustomHandlerGetResult<I>;
|
|
525
|
+
type CustomHandlerFunctionParameters<L extends string, S extends State> = {
|
|
509
526
|
/**
|
|
510
|
-
*
|
|
527
|
+
* Returns:
|
|
528
|
+
* - Root where entire novely is mounted
|
|
529
|
+
* - Element in which custom action could be mounted
|
|
530
|
+
*
|
|
531
|
+
* @example
|
|
532
|
+
* ```ts
|
|
533
|
+
* // pass `true` to insert element to the DOM
|
|
534
|
+
* const { root, element } = getDomNodes(true);
|
|
535
|
+
* ```
|
|
511
536
|
*/
|
|
512
|
-
|
|
537
|
+
getDomNodes: CustomHandlerFunctionGetFn;
|
|
513
538
|
/**
|
|
514
|
-
*
|
|
539
|
+
* Renderer Context
|
|
515
540
|
*/
|
|
516
|
-
|
|
541
|
+
rendererContext: Context;
|
|
517
542
|
/**
|
|
518
|
-
*
|
|
543
|
+
* Function to work with custom action's state
|
|
544
|
+
*/
|
|
545
|
+
data: CustomHandlerGetResultDataFunction;
|
|
546
|
+
/**
|
|
547
|
+
* Function to set cleanup handler
|
|
519
548
|
*/
|
|
520
549
|
clear: (fn: () => void) => void;
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
550
|
+
/**
|
|
551
|
+
* Remove's custom handler instance
|
|
552
|
+
*/
|
|
553
|
+
remove: () => void;
|
|
554
|
+
/**
|
|
555
|
+
* Context's state function
|
|
556
|
+
*/
|
|
528
557
|
state: StateFunction<S>;
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
558
|
+
/**
|
|
559
|
+
* Game flags (aka game states)
|
|
560
|
+
*/
|
|
561
|
+
flags: {
|
|
562
|
+
restoring: boolean;
|
|
563
|
+
goingBack: boolean;
|
|
564
|
+
preview: boolean;
|
|
565
|
+
};
|
|
566
|
+
/**
|
|
567
|
+
* Game language
|
|
568
|
+
*/
|
|
532
569
|
lang: L;
|
|
533
570
|
};
|
|
534
571
|
type CustomHandlerFunction<L extends string, S extends State> = (parameters: CustomHandlerFunctionParameters<L, S>) => Thenable<void>;
|
|
@@ -799,4 +836,4 @@ declare const novely: <$Language extends string, $Characters extends Record<stri
|
|
|
799
836
|
*/
|
|
800
837
|
declare const extendAction: <Part0 extends Record<string, (...args: any[]) => ValidAction>, Part1 extends Record<string, (...args: any[]) => ValidAction>>(base: Part0, extension: Part1) => Readonly<Assign<Part0, Part1>>;
|
|
801
838
|
|
|
802
|
-
export { type ActionInputOnInputMeta, type ActionInputSetup, type ActionInputSetupCleanup, type ActionProxy, type AllowedContent, type AudioHandle, type BackgroundImage, type BaseTranslationStrings, type Character, type CharacterHandle, type ConditionParams, type Context, type CoreData, type CustomHandler, type CustomHandlerFunctionGetFn, type CustomHandlerFunctionParameters, type CustomHandlerGetResult, type CustomHandlerGetResultDataFunction, type Data, type DeepPartial, type DefaultActionProxy, EN, type Emotions, type FunctionableValue, type GetActionParameters, type InputHandler, JP, KK, type Lang, type NovelyInit, type NovelyScreen, type Path, type PluralType, type Pluralization, RU, type Renderer, type RendererInit, type Save, type Stack, type StackHolder, type State, type StateFunction, type Storage, type StorageData, type StorageMeta, type Stored, type Story, type TextContent, type Thenable, type TranslationActions, type TypeEssentials, type TypewriterSpeed, type ValidAction, extendAction, localStorageStorage, novely };
|
|
839
|
+
export { type ActionInputOnInputMeta, type ActionInputSetup, type ActionInputSetupCleanup, type ActionProxy, type AllowedContent, type AudioHandle, type BackgroundImage, type BaseTranslationStrings, type Character, type CharacterHandle, type ConditionParams, type Context, type CoreData, type CustomActionHandle, type CustomHandler, type CustomHandlerFunctionGetFn, type CustomHandlerFunctionParameters, type CustomHandlerGetResult, type CustomHandlerGetResultDataFunction, type Data, type DeepPartial, type DefaultActionProxy, EN, type Emotions, type FunctionableValue, type GetActionParameters, type InputHandler, JP, KK, type Lang, type NovelyInit, type NovelyScreen, type Path, type PluralType, type Pluralization, RU, type Renderer, type RendererInit, type Save, type Stack, type StackHolder, type State, type StateFunction, type Storage, type StorageData, type StorageMeta, type Stored, type Story, type TextContent, type Thenable, type TranslationActions, type TypeEssentials, type TypewriterSpeed, type ValidAction, extendAction, localStorageStorage, novely };
|
package/dist/index.global.js
CHANGED
|
@@ -210,6 +210,7 @@ var Novely = (() => {
|
|
|
210
210
|
|
|
211
211
|
// src/shared.ts
|
|
212
212
|
var STACK_MAP = /* @__PURE__ */ new Map();
|
|
213
|
+
var CUSTOM_ACTION_MAP = /* @__PURE__ */ new Map();
|
|
213
214
|
var PRELOADED_ASSETS = /* @__PURE__ */ new Set();
|
|
214
215
|
|
|
215
216
|
// ../../node_modules/.pnpm/esm-env@1.0.0/node_modules/esm-env/prod-ssr.js
|
|
@@ -244,9 +245,16 @@ var Novely = (() => {
|
|
|
244
245
|
}
|
|
245
246
|
|
|
246
247
|
// src/utils.ts
|
|
247
|
-
var matchAction = ({ getContext, push, forward }, values) => {
|
|
248
|
+
var matchAction = ({ getContext, onBeforeActionCall, push, forward }, values) => {
|
|
248
249
|
return (action, props, { ctx, data }) => {
|
|
249
250
|
const context = typeof ctx === "string" ? getContext(ctx) : ctx;
|
|
251
|
+
if (action !== "say") {
|
|
252
|
+
onBeforeActionCall({
|
|
253
|
+
action,
|
|
254
|
+
props,
|
|
255
|
+
ctx: context
|
|
256
|
+
});
|
|
257
|
+
}
|
|
250
258
|
return values[action]({
|
|
251
259
|
ctx: context,
|
|
252
260
|
data,
|
|
@@ -411,7 +419,7 @@ var Novely = (() => {
|
|
|
411
419
|
var getActionsFromPath = (story, path, filter) => {
|
|
412
420
|
let current = story;
|
|
413
421
|
let precurrent;
|
|
414
|
-
let
|
|
422
|
+
let ignoreNestedBefore = null;
|
|
415
423
|
let index = 0;
|
|
416
424
|
let skipPreserve = void 0;
|
|
417
425
|
const skip = /* @__PURE__ */ new Set();
|
|
@@ -432,11 +440,11 @@ var Novely = (() => {
|
|
|
432
440
|
if (isNumber(val)) {
|
|
433
441
|
index++;
|
|
434
442
|
let startIndex = 0;
|
|
435
|
-
if (
|
|
436
|
-
const prev = findLastPathItemBeforeItemOfType(path.slice(0, index),
|
|
443
|
+
if (ignoreNestedBefore) {
|
|
444
|
+
const prev = findLastPathItemBeforeItemOfType(path.slice(0, index), ignoreNestedBefore);
|
|
437
445
|
if (prev) {
|
|
438
446
|
startIndex = prev[1];
|
|
439
|
-
|
|
447
|
+
ignoreNestedBefore = null;
|
|
440
448
|
}
|
|
441
449
|
}
|
|
442
450
|
for (let i = startIndex; i <= val; i++) {
|
|
@@ -471,7 +479,7 @@ var Novely = (() => {
|
|
|
471
479
|
current = story[val];
|
|
472
480
|
} else if (type === "block:exit" || type === "choice:exit" || type === "condition:exit") {
|
|
473
481
|
current = blocks.pop();
|
|
474
|
-
|
|
482
|
+
ignoreNestedBefore = type.slice(0, -5);
|
|
475
483
|
}
|
|
476
484
|
}
|
|
477
485
|
return {
|
|
@@ -655,6 +663,9 @@ var Novely = (() => {
|
|
|
655
663
|
}
|
|
656
664
|
};
|
|
657
665
|
var getResourseType = async (request, url) => {
|
|
666
|
+
if (!isCSSImage(url)) {
|
|
667
|
+
return "other";
|
|
668
|
+
}
|
|
658
669
|
const extension = getUrlFileExtension(url);
|
|
659
670
|
if (HOWLER_SUPPORTED_FILE_FORMATS.has(extension)) {
|
|
660
671
|
return "audio";
|
|
@@ -768,6 +779,68 @@ var Novely = (() => {
|
|
|
768
779
|
}
|
|
769
780
|
return path;
|
|
770
781
|
};
|
|
782
|
+
var isBlockingAction = (action) => {
|
|
783
|
+
return isUserRequiredAction(action) || isSkippedDuringRestore(action[0]) && action[0] !== "vibrate";
|
|
784
|
+
};
|
|
785
|
+
var collectActionsBeforeBlockingAction = ({ path, refer }) => {
|
|
786
|
+
const collection = [];
|
|
787
|
+
let action = refer(path);
|
|
788
|
+
while (true) {
|
|
789
|
+
if (action == void 0) {
|
|
790
|
+
const { exitImpossible } = exitPath({
|
|
791
|
+
path,
|
|
792
|
+
refer
|
|
793
|
+
});
|
|
794
|
+
if (exitImpossible) {
|
|
795
|
+
break;
|
|
796
|
+
}
|
|
797
|
+
}
|
|
798
|
+
if (!action) {
|
|
799
|
+
break;
|
|
800
|
+
}
|
|
801
|
+
if (isBlockingAction(action)) {
|
|
802
|
+
const [name, ...props] = action;
|
|
803
|
+
if (name === "choice") {
|
|
804
|
+
const choiceProps = props;
|
|
805
|
+
for (let i = 0; i < choiceProps.length; i++) {
|
|
806
|
+
const branchContent = choiceProps[i];
|
|
807
|
+
if (!Array.isArray(branchContent))
|
|
808
|
+
continue;
|
|
809
|
+
const virtualPath = klona(path);
|
|
810
|
+
virtualPath.push(["choice", i], [null, 0]);
|
|
811
|
+
const innerActions = collectActionsBeforeBlockingAction({
|
|
812
|
+
path: virtualPath,
|
|
813
|
+
refer
|
|
814
|
+
});
|
|
815
|
+
collection.push(...innerActions);
|
|
816
|
+
}
|
|
817
|
+
} else if (name === "condition") {
|
|
818
|
+
const conditionProps = props;
|
|
819
|
+
const conditions = Object.keys(conditionProps[1]);
|
|
820
|
+
for (const condition of conditions) {
|
|
821
|
+
const virtualPath = klona(path);
|
|
822
|
+
virtualPath.push(["condition", condition], [null, 0]);
|
|
823
|
+
const innerActions = collectActionsBeforeBlockingAction({
|
|
824
|
+
path: virtualPath,
|
|
825
|
+
refer
|
|
826
|
+
});
|
|
827
|
+
collection.push(...innerActions);
|
|
828
|
+
}
|
|
829
|
+
}
|
|
830
|
+
break;
|
|
831
|
+
}
|
|
832
|
+
collection.push(action);
|
|
833
|
+
if (action[0] === "jump") {
|
|
834
|
+
path = [["jump", action[1]], [null, 0]];
|
|
835
|
+
} else if (action[0] == "block") {
|
|
836
|
+
path.push(["block", action[1]], [null, 0]);
|
|
837
|
+
} else {
|
|
838
|
+
nextPath(path);
|
|
839
|
+
}
|
|
840
|
+
action = refer(path);
|
|
841
|
+
}
|
|
842
|
+
return collection;
|
|
843
|
+
};
|
|
771
844
|
|
|
772
845
|
// ../../node_modules/.pnpm/dequal@2.0.3/node_modules/dequal/lite/index.mjs
|
|
773
846
|
var has = Object.prototype.hasOwnProperty;
|
|
@@ -943,6 +1016,76 @@ var Novely = (() => {
|
|
|
943
1016
|
});
|
|
944
1017
|
};
|
|
945
1018
|
|
|
1019
|
+
// src/custom-action.ts
|
|
1020
|
+
var createCustomActionNode = (id) => {
|
|
1021
|
+
const div = document.createElement("div");
|
|
1022
|
+
div.setAttribute("data-id", id);
|
|
1023
|
+
return div;
|
|
1024
|
+
};
|
|
1025
|
+
var getCustomActionHolder = (ctx, fn) => {
|
|
1026
|
+
const cached = CUSTOM_ACTION_MAP.get(ctx.id + fn.key);
|
|
1027
|
+
if (cached) {
|
|
1028
|
+
return cached;
|
|
1029
|
+
}
|
|
1030
|
+
const holder = {
|
|
1031
|
+
cleanup: noop,
|
|
1032
|
+
node: null,
|
|
1033
|
+
fn,
|
|
1034
|
+
localData: {}
|
|
1035
|
+
};
|
|
1036
|
+
CUSTOM_ACTION_MAP.set(ctx.id + fn.key, holder);
|
|
1037
|
+
return holder;
|
|
1038
|
+
};
|
|
1039
|
+
var handleCustomAction = (ctx, fn, { lang, state, setMountElement, setClear, remove: renderersRemove }) => {
|
|
1040
|
+
const holder = getCustomActionHolder(ctx, fn);
|
|
1041
|
+
const flags = {
|
|
1042
|
+
...ctx.meta
|
|
1043
|
+
};
|
|
1044
|
+
const getDomNodes = (insert = true) => {
|
|
1045
|
+
if (holder.node || !insert) {
|
|
1046
|
+
return {
|
|
1047
|
+
element: holder.node,
|
|
1048
|
+
root: ctx.root
|
|
1049
|
+
};
|
|
1050
|
+
}
|
|
1051
|
+
holder.node = insert ? createCustomActionNode(fn.key) : null;
|
|
1052
|
+
setMountElement(holder.node);
|
|
1053
|
+
return {
|
|
1054
|
+
element: holder.node,
|
|
1055
|
+
root: ctx.root
|
|
1056
|
+
};
|
|
1057
|
+
};
|
|
1058
|
+
const clear = (func) => {
|
|
1059
|
+
setClear(holder.cleanup = () => {
|
|
1060
|
+
func();
|
|
1061
|
+
holder.node = null;
|
|
1062
|
+
holder.cleanup = noop;
|
|
1063
|
+
setMountElement(null);
|
|
1064
|
+
setClear(noop);
|
|
1065
|
+
});
|
|
1066
|
+
};
|
|
1067
|
+
const data = (updatedData) => {
|
|
1068
|
+
if (updatedData) {
|
|
1069
|
+
return holder.localData = updatedData;
|
|
1070
|
+
}
|
|
1071
|
+
return holder.localData;
|
|
1072
|
+
};
|
|
1073
|
+
const remove = () => {
|
|
1074
|
+
holder.cleanup();
|
|
1075
|
+
renderersRemove();
|
|
1076
|
+
};
|
|
1077
|
+
return fn({
|
|
1078
|
+
flags,
|
|
1079
|
+
lang,
|
|
1080
|
+
state,
|
|
1081
|
+
data,
|
|
1082
|
+
clear,
|
|
1083
|
+
remove,
|
|
1084
|
+
rendererContext: ctx,
|
|
1085
|
+
getDomNodes
|
|
1086
|
+
});
|
|
1087
|
+
};
|
|
1088
|
+
|
|
946
1089
|
// src/storage.ts
|
|
947
1090
|
var localStorageStorage = (options) => {
|
|
948
1091
|
return {
|
|
@@ -1016,6 +1159,26 @@ var Novely = (() => {
|
|
|
1016
1159
|
const intime = (value) => {
|
|
1017
1160
|
return times.add(value), value;
|
|
1018
1161
|
};
|
|
1162
|
+
const handleAssetsPreloading = async () => {
|
|
1163
|
+
const { preloadAudioBlocking, preloadImageBlocking } = renderer.misc;
|
|
1164
|
+
const list = mapSet(ASSETS_TO_PRELOAD, (asset) => {
|
|
1165
|
+
return limitAssetsDownload(async () => {
|
|
1166
|
+
const type = await getResourseType(request, asset);
|
|
1167
|
+
switch (type) {
|
|
1168
|
+
case "audio": {
|
|
1169
|
+
await preloadAudioBlocking(asset);
|
|
1170
|
+
break;
|
|
1171
|
+
}
|
|
1172
|
+
case "image": {
|
|
1173
|
+
await preloadImageBlocking(asset);
|
|
1174
|
+
break;
|
|
1175
|
+
}
|
|
1176
|
+
}
|
|
1177
|
+
});
|
|
1178
|
+
});
|
|
1179
|
+
await Promise.allSettled(list);
|
|
1180
|
+
ASSETS_TO_PRELOAD.clear();
|
|
1181
|
+
};
|
|
1019
1182
|
const scriptBase = async (part) => {
|
|
1020
1183
|
Object.assign(story, flattenStory(part));
|
|
1021
1184
|
let loadingIsShown = false;
|
|
@@ -1027,31 +1190,14 @@ var Novely = (() => {
|
|
|
1027
1190
|
if (!loadingIsShown) {
|
|
1028
1191
|
renderer.ui.showLoading();
|
|
1029
1192
|
}
|
|
1030
|
-
|
|
1031
|
-
const list = mapSet(ASSETS_TO_PRELOAD, (asset) => {
|
|
1032
|
-
return limitAssetsDownload(async () => {
|
|
1033
|
-
const type = await getResourseType(request, asset);
|
|
1034
|
-
switch (type) {
|
|
1035
|
-
case "audio": {
|
|
1036
|
-
await preloadAudioBlocking(asset);
|
|
1037
|
-
break;
|
|
1038
|
-
}
|
|
1039
|
-
case "image": {
|
|
1040
|
-
await preloadImageBlocking(asset);
|
|
1041
|
-
break;
|
|
1042
|
-
}
|
|
1043
|
-
}
|
|
1044
|
-
});
|
|
1045
|
-
});
|
|
1046
|
-
await Promise.allSettled(list);
|
|
1193
|
+
await handleAssetsPreloading();
|
|
1047
1194
|
}
|
|
1048
|
-
ASSETS_TO_PRELOAD.clear();
|
|
1049
1195
|
await dataLoaded.promise;
|
|
1050
1196
|
renderer.ui.hideLoading();
|
|
1051
1197
|
if (!initialScreenWasShown) {
|
|
1052
1198
|
initialScreenWasShown = true;
|
|
1053
1199
|
if (initialScreen === "game") {
|
|
1054
|
-
restore();
|
|
1200
|
+
restore(void 0);
|
|
1055
1201
|
} else {
|
|
1056
1202
|
renderer.ui.showScreen(initialScreen);
|
|
1057
1203
|
}
|
|
@@ -1060,6 +1206,33 @@ var Novely = (() => {
|
|
|
1060
1206
|
const script = (part) => {
|
|
1061
1207
|
return limitScript(() => scriptBase(part));
|
|
1062
1208
|
};
|
|
1209
|
+
const checkAndAddToPreloadingList = (action2, props) => {
|
|
1210
|
+
if (action2 === "showBackground") {
|
|
1211
|
+
if (isImageAsset(props[0])) {
|
|
1212
|
+
ASSETS_TO_PRELOAD.add(props[0]);
|
|
1213
|
+
}
|
|
1214
|
+
if (props[0] && typeof props[0] === "object") {
|
|
1215
|
+
for (const value of Object.values(props[0])) {
|
|
1216
|
+
if (!isImageAsset(value))
|
|
1217
|
+
continue;
|
|
1218
|
+
ASSETS_TO_PRELOAD.add(value);
|
|
1219
|
+
}
|
|
1220
|
+
}
|
|
1221
|
+
}
|
|
1222
|
+
if (isAudioAction(action2) && isString(props[0])) {
|
|
1223
|
+
ASSETS_TO_PRELOAD.add(props[0]);
|
|
1224
|
+
}
|
|
1225
|
+
if (action2 === "showCharacter" && isString(props[0]) && isString(props[1])) {
|
|
1226
|
+
const images = characters[props[0]].emotions[props[1]];
|
|
1227
|
+
if (Array.isArray(images)) {
|
|
1228
|
+
for (const asset of images) {
|
|
1229
|
+
ASSETS_TO_PRELOAD.add(asset);
|
|
1230
|
+
}
|
|
1231
|
+
} else {
|
|
1232
|
+
ASSETS_TO_PRELOAD.add(images);
|
|
1233
|
+
}
|
|
1234
|
+
}
|
|
1235
|
+
};
|
|
1063
1236
|
const action = new Proxy({}, {
|
|
1064
1237
|
get(_, action2) {
|
|
1065
1238
|
if (action2 in renderer.actions) {
|
|
@@ -1067,31 +1240,7 @@ var Novely = (() => {
|
|
|
1067
1240
|
}
|
|
1068
1241
|
return (...props) => {
|
|
1069
1242
|
if (preloadAssets === "blocking") {
|
|
1070
|
-
|
|
1071
|
-
if (isImageAsset(props[0])) {
|
|
1072
|
-
ASSETS_TO_PRELOAD.add(props[0]);
|
|
1073
|
-
}
|
|
1074
|
-
if (props[0] && typeof props[0] === "object") {
|
|
1075
|
-
for (const value of Object.values(props[0])) {
|
|
1076
|
-
if (!isImageAsset(value))
|
|
1077
|
-
continue;
|
|
1078
|
-
ASSETS_TO_PRELOAD.add(value);
|
|
1079
|
-
}
|
|
1080
|
-
}
|
|
1081
|
-
}
|
|
1082
|
-
if (isAudioAction(action2) && isString(props[0])) {
|
|
1083
|
-
ASSETS_TO_PRELOAD.add(props[0]);
|
|
1084
|
-
}
|
|
1085
|
-
if (action2 === "showCharacter" && isString(props[0]) && isString(props[1])) {
|
|
1086
|
-
const images = characters[props[0]].emotions[props[1]];
|
|
1087
|
-
if (Array.isArray(images)) {
|
|
1088
|
-
for (const asset of images) {
|
|
1089
|
-
ASSETS_TO_PRELOAD.add(asset);
|
|
1090
|
-
}
|
|
1091
|
-
} else {
|
|
1092
|
-
ASSETS_TO_PRELOAD.add(images);
|
|
1093
|
-
}
|
|
1094
|
-
}
|
|
1243
|
+
checkAndAddToPreloadingList(action2, props);
|
|
1095
1244
|
}
|
|
1096
1245
|
return [action2, ...props];
|
|
1097
1246
|
};
|
|
@@ -1218,7 +1367,12 @@ var Novely = (() => {
|
|
|
1218
1367
|
return prev.saves.push(save2), prev;
|
|
1219
1368
|
});
|
|
1220
1369
|
}
|
|
1221
|
-
|
|
1370
|
+
const context = renderer.getContext(MAIN_CONTEXT_KEY);
|
|
1371
|
+
const stack = useStack(context);
|
|
1372
|
+
stack.value = save2;
|
|
1373
|
+
context.meta.restoring = context.meta.goingBack = false;
|
|
1374
|
+
renderer.ui.showScreen("game");
|
|
1375
|
+
render(context);
|
|
1222
1376
|
};
|
|
1223
1377
|
const set = (save2, ctx) => {
|
|
1224
1378
|
const stack = useStack(ctx || MAIN_CONTEXT_KEY);
|
|
@@ -1263,7 +1417,7 @@ var Novely = (() => {
|
|
|
1263
1417
|
}
|
|
1264
1418
|
const [action2, fn] = element;
|
|
1265
1419
|
if (action2 === "custom") {
|
|
1266
|
-
context.
|
|
1420
|
+
getCustomActionHolder(context, fn).cleanup();
|
|
1267
1421
|
}
|
|
1268
1422
|
}
|
|
1269
1423
|
}
|
|
@@ -1273,8 +1427,8 @@ var Novely = (() => {
|
|
|
1273
1427
|
data: latest[1]
|
|
1274
1428
|
});
|
|
1275
1429
|
}
|
|
1276
|
-
const lastQueueItem = queue.at(-1)
|
|
1277
|
-
const lastQueueItemRequiresUserAction =
|
|
1430
|
+
const lastQueueItem = queue.at(-1);
|
|
1431
|
+
const lastQueueItemRequiresUserAction = lastQueueItem && isBlockingAction(lastQueueItem);
|
|
1278
1432
|
await run((item) => {
|
|
1279
1433
|
if (!latest)
|
|
1280
1434
|
return;
|
|
@@ -1388,6 +1542,9 @@ var Novely = (() => {
|
|
|
1388
1542
|
}
|
|
1389
1543
|
return capitalize(language.nameOverride || getIntlLanguageDisplayName(lang));
|
|
1390
1544
|
};
|
|
1545
|
+
const clearCustomAction = (ctx, fn) => {
|
|
1546
|
+
getCustomActionHolder(ctx, fn).cleanup();
|
|
1547
|
+
};
|
|
1391
1548
|
const renderer = createRenderer({
|
|
1392
1549
|
mainContextKey: MAIN_CONTEXT_KEY,
|
|
1393
1550
|
characters,
|
|
@@ -1401,6 +1558,7 @@ var Novely = (() => {
|
|
|
1401
1558
|
preview,
|
|
1402
1559
|
removeContext,
|
|
1403
1560
|
getStateFunction,
|
|
1561
|
+
clearCustomAction,
|
|
1404
1562
|
languages,
|
|
1405
1563
|
storageData,
|
|
1406
1564
|
coreData,
|
|
@@ -1437,6 +1595,40 @@ var Novely = (() => {
|
|
|
1437
1595
|
matchActionOptions.push(ctx);
|
|
1438
1596
|
if (!ctx.meta.preview)
|
|
1439
1597
|
interactivity(true);
|
|
1598
|
+
},
|
|
1599
|
+
onBeforeActionCall({ action: action2, props, ctx }) {
|
|
1600
|
+
if (preloadAssets !== "automatic")
|
|
1601
|
+
return;
|
|
1602
|
+
if (ctx.meta.preview || ctx.meta.restoring)
|
|
1603
|
+
return;
|
|
1604
|
+
if (!isBlockingAction([action2, ...props]))
|
|
1605
|
+
return;
|
|
1606
|
+
try {
|
|
1607
|
+
const collection = collectActionsBeforeBlockingAction({
|
|
1608
|
+
path: nextPath(klona(useStack(ctx).value[0])),
|
|
1609
|
+
refer
|
|
1610
|
+
});
|
|
1611
|
+
for (const [action3, ...props2] of collection) {
|
|
1612
|
+
checkAndAddToPreloadingList(action3, props2);
|
|
1613
|
+
}
|
|
1614
|
+
const { preloadAudioBlocking, preloadImage } = renderer.misc;
|
|
1615
|
+
ASSETS_TO_PRELOAD.forEach(async (asset) => {
|
|
1616
|
+
ASSETS_TO_PRELOAD.delete(asset);
|
|
1617
|
+
const type = await getResourseType(request, asset);
|
|
1618
|
+
switch (type) {
|
|
1619
|
+
case "audio": {
|
|
1620
|
+
preloadAudioBlocking(asset);
|
|
1621
|
+
break;
|
|
1622
|
+
}
|
|
1623
|
+
case "image": {
|
|
1624
|
+
preloadImage(asset);
|
|
1625
|
+
break;
|
|
1626
|
+
}
|
|
1627
|
+
}
|
|
1628
|
+
});
|
|
1629
|
+
} catch (cause) {
|
|
1630
|
+
console.error(cause);
|
|
1631
|
+
}
|
|
1440
1632
|
}
|
|
1441
1633
|
};
|
|
1442
1634
|
const match = matchAction(matchActionOptions, {
|
|
@@ -1644,19 +1836,31 @@ var Novely = (() => {
|
|
|
1644
1836
|
forward
|
|
1645
1837
|
);
|
|
1646
1838
|
},
|
|
1647
|
-
custom({ ctx, push }, [
|
|
1648
|
-
if (
|
|
1839
|
+
custom({ ctx, push }, [fn]) {
|
|
1840
|
+
if (fn.requireUserAction) {
|
|
1649
1841
|
ctx.clearBlockingActions(void 0);
|
|
1650
1842
|
}
|
|
1651
|
-
const
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1843
|
+
const state = getStateFunction(ctx);
|
|
1844
|
+
const lang = storageData.get().meta[0];
|
|
1845
|
+
const result = handleCustomAction(ctx, fn, {
|
|
1846
|
+
...ctx.custom(fn),
|
|
1847
|
+
state,
|
|
1848
|
+
lang
|
|
1849
|
+
});
|
|
1850
|
+
const next2 = () => {
|
|
1851
|
+
if (fn.requireUserAction && !ctx.meta.preview) {
|
|
1655
1852
|
enmemory(ctx);
|
|
1656
1853
|
interactivity(true);
|
|
1657
1854
|
}
|
|
1658
1855
|
push();
|
|
1659
|
-
}
|
|
1856
|
+
};
|
|
1857
|
+
if (!ctx.meta.restoring) {
|
|
1858
|
+
if (isPromise(result)) {
|
|
1859
|
+
result.then(next2);
|
|
1860
|
+
} else {
|
|
1861
|
+
next2();
|
|
1862
|
+
}
|
|
1863
|
+
}
|
|
1660
1864
|
return result;
|
|
1661
1865
|
},
|
|
1662
1866
|
vibrate({ ctx, push }, pattern) {
|
|
@@ -1706,6 +1910,9 @@ var Novely = (() => {
|
|
|
1706
1910
|
render(ctx);
|
|
1707
1911
|
},
|
|
1708
1912
|
preload({ ctx, push }, [source]) {
|
|
1913
|
+
if (DEV && preloadAssets !== "lazy") {
|
|
1914
|
+
console.error(`You do not need a preload action becase "preloadAssets" strategy was set to "${preloadAssets}"`);
|
|
1915
|
+
}
|
|
1709
1916
|
if (!ctx.meta.goingBack && !ctx.meta.restoring && !PRELOADED_ASSETS.has(source)) {
|
|
1710
1917
|
PRELOADED_ASSETS.add(renderer.misc.preloadImage(source));
|
|
1711
1918
|
}
|