narraleaf-react 0.40.1 → 0.41.1
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/game/nlcore/elements/character/sentence.d.ts +0 -1
- package/dist/game/nlcore/elements/character/word.d.ts +0 -1
- package/dist/game/player/elements/player/skipKeySignal.d.ts +53 -0
- package/dist/game/player/elements/say/dialogAdvanceIntent.d.ts +75 -0
- package/dist/main.js +40 -40
- package/package.json +115 -115
|
@@ -12,7 +12,6 @@ import type { DialogAvatar } from "../../elements/character/avatar";
|
|
|
12
12
|
*/
|
|
13
13
|
export type SentenceMetadata = Record<string, unknown>;
|
|
14
14
|
export type SentenceConfig = {
|
|
15
|
-
pause?: boolean | number;
|
|
16
15
|
voice: Sound | null;
|
|
17
16
|
character: Character | null;
|
|
18
17
|
voiceId: string | number | null;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The skip key, as a signal rather than a component.
|
|
3
|
+
*
|
|
4
|
+
* Holding the key down is a mode and tapping it is one advance, and the difference has to be made
|
|
5
|
+
* somewhere: the key itself only reports "down" and "up". This turns those two into the stream of
|
|
6
|
+
* advance requests the rest of the player consumes - one unforced request the moment the key goes
|
|
7
|
+
* down, then forced ones for as long as it stays down.
|
|
8
|
+
*
|
|
9
|
+
* It lives apart from `KeyEventAnnouncer` because the announcer is DOM (window listeners, key
|
|
10
|
+
* matching, the suspension guard) and this is not: it is timers and one boolean, which is the part
|
|
11
|
+
* worth pinning and the part a test can reach.
|
|
12
|
+
*
|
|
13
|
+
* Comments in English per project convention.
|
|
14
|
+
*/
|
|
15
|
+
/** Emit one advance request. `forced` marks the skip mode rather than a single advance. */
|
|
16
|
+
export type SkipEmit = (forced: boolean) => void;
|
|
17
|
+
export type SkipKeySignalOptions = {
|
|
18
|
+
/** How long the key must be held before the mode starts. `0` starts it on the next interval. */
|
|
19
|
+
delay: number;
|
|
20
|
+
/** How often the mode repeats while the key is held. */
|
|
21
|
+
interval: number;
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Turn key-down and key-up into advance requests.
|
|
25
|
+
*
|
|
26
|
+
* `press` is idempotent: the OS repeats key-down while a key is held, and every repeat after the
|
|
27
|
+
* first is the same press. `release` ends the mode; so does `dispose`, which the announcer calls
|
|
28
|
+
* when it stops listening - a key released while the player is unmounted, or a window that lost
|
|
29
|
+
* focus mid-press, must not leave an interval running against a game that has gone.
|
|
30
|
+
*/
|
|
31
|
+
export declare class SkipKeySignal {
|
|
32
|
+
private readonly emit;
|
|
33
|
+
private readonly options;
|
|
34
|
+
private held;
|
|
35
|
+
private delayTimer;
|
|
36
|
+
private repeatTimer;
|
|
37
|
+
constructor(emit: SkipEmit, options: SkipKeySignalOptions);
|
|
38
|
+
isHeld(): boolean;
|
|
39
|
+
/**
|
|
40
|
+
* The key went down.
|
|
41
|
+
*
|
|
42
|
+
* The first thing a press produces is an ordinary advance - the same one a click produces - and
|
|
43
|
+
* only what follows it is the mode. A tap therefore reads a line at the speed it was written,
|
|
44
|
+
* pauses included; the player who wants the rest of the scene holds the key and says so.
|
|
45
|
+
*/
|
|
46
|
+
press(): void;
|
|
47
|
+
/** The key came up. */
|
|
48
|
+
release(): void;
|
|
49
|
+
/** Stop everything, whatever state the key is in. */
|
|
50
|
+
dispose(): void;
|
|
51
|
+
private startRepeating;
|
|
52
|
+
private clearTimers;
|
|
53
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What one request to get on with the line actually asks the box to do.
|
|
3
|
+
*
|
|
4
|
+
* Three different things reach a dialog box meaning "carry on", and they do not mean the same thing:
|
|
5
|
+
* a click on the box, a click on the stage, and the skip key. They used to arrive along two paths
|
|
6
|
+
* with different manners - the box's own click asked the sentence to complete, everything else told
|
|
7
|
+
* it to force-skip - and the difference was invisible until a line had a `Pause` in it, because
|
|
8
|
+
* force-skipping is the only one of the two that walks straight past pauses.
|
|
9
|
+
*
|
|
10
|
+
* The rule below is the one worth pinning, and pinning it needs no React: a single advance is a
|
|
11
|
+
* single advance whoever asked for it, and only the skip *mode* is allowed to blow through the
|
|
12
|
+
* pauses an author wrote.
|
|
13
|
+
*
|
|
14
|
+
* Comments in English per project convention.
|
|
15
|
+
*/
|
|
16
|
+
/**
|
|
17
|
+
* The three things an advance request can mean.
|
|
18
|
+
*
|
|
19
|
+
* - `requestComplete` - one advance: reveal to the next pause, or settle a line already revealed.
|
|
20
|
+
* - `forceSkip` - the skip mode: reveal the whole line, pauses included, and settle it.
|
|
21
|
+
* - `ignore` - this box does not hold the line, so the request is not its to answer.
|
|
22
|
+
*/
|
|
23
|
+
export type DialogAdvanceIntent = "ignore" | "requestComplete" | "forceSkip";
|
|
24
|
+
export type DialogAdvanceInput = {
|
|
25
|
+
/** Whether this box holds the line right now. An inactive box ignores advances on purpose. */
|
|
26
|
+
active: boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Whether this is the skip *mode* rather than one advance.
|
|
29
|
+
*
|
|
30
|
+
* True for the skip key's repeats while it is held down, for `LiveGame.skipDialog`, and for the
|
|
31
|
+
* fast-forward pump. False for a click - on the box or on the stage - and for the first press of
|
|
32
|
+
* the skip key, which is a tap and asks for one line like any other advance.
|
|
33
|
+
*/
|
|
34
|
+
forced: boolean;
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* Decide what one advance request means.
|
|
38
|
+
*
|
|
39
|
+
* **A single advance never forces.** Forcing is what the skip mode does, and its whole point is to
|
|
40
|
+
* ignore what the author asked for - including a `Pause`, which exists precisely to hold the line
|
|
41
|
+
* until the player answers it. A click that forced would reveal the rest of the line in one go and
|
|
42
|
+
* silently spend the pause with it, which is the same text loss as advancing past a line nobody
|
|
43
|
+
* read, only harder to notice: the words are all on screen, they were simply never revealed at the
|
|
44
|
+
* speed they were written to be.
|
|
45
|
+
*
|
|
46
|
+
* That a click on the box and a click on the stage should behave identically is not a nicety - the
|
|
47
|
+
* box covers part of the stage and nothing tells a player which half of a dialogue they hit.
|
|
48
|
+
*
|
|
49
|
+
* The first press of the skip key is a tap, and a tap is an advance. Only its repeats - which
|
|
50
|
+
* arrive only while the key is still down - are the mode.
|
|
51
|
+
*/
|
|
52
|
+
export declare function resolveDialogAdvanceIntent({ active, forced, }: DialogAdvanceInput): DialogAdvanceIntent;
|
|
53
|
+
/**
|
|
54
|
+
* The part of a dialog state an advance touches.
|
|
55
|
+
*
|
|
56
|
+
* Structural on purpose: this module is reached from a test that drives a real `DialogState`, and
|
|
57
|
+
* importing the class here to name it would tie a decision with no dependencies to the component
|
|
58
|
+
* file that has all of them.
|
|
59
|
+
*/
|
|
60
|
+
export type DialogAdvanceTarget = {
|
|
61
|
+
setIdle(idle: boolean): void;
|
|
62
|
+
forceSkip(): void;
|
|
63
|
+
requestComplete(): void;
|
|
64
|
+
};
|
|
65
|
+
/**
|
|
66
|
+
* Decide what the request means and carry it out.
|
|
67
|
+
*
|
|
68
|
+
* Kept here with the decision rather than in the component so that the two cannot drift: a test can
|
|
69
|
+
* drive a real dialog state through the real dispatch, which is the only way the rule above is worth
|
|
70
|
+
* anything. Returns what it decided, for callers that want to log or assert it.
|
|
71
|
+
*
|
|
72
|
+
* The forced branch marks the line idle *before* it skips: the skip reveals the whole line, so the
|
|
73
|
+
* line is fully revealed by the time anything can ask, and the same tick settles it.
|
|
74
|
+
*/
|
|
75
|
+
export declare function applyDialogAdvance(target: DialogAdvanceTarget, input: DialogAdvanceInput): DialogAdvanceIntent;
|