@luna-editor/engine 0.2.0 → 0.3.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/Player.d.ts +1 -1
- package/dist/Player.js +676 -95
- package/dist/api/conversationBranch.d.ts +4 -0
- package/dist/api/conversationBranch.js +83 -0
- package/dist/components/BackgroundLayer.d.ts +19 -0
- package/dist/components/BackgroundLayer.js +220 -0
- package/dist/components/ClickWaitIndicator.d.ts +10 -0
- package/dist/components/ClickWaitIndicator.js +31 -0
- package/dist/components/ConversationBranchBox.d.ts +2 -0
- package/dist/components/ConversationBranchBox.js +29 -0
- package/dist/components/DialogueBox.js +16 -1
- package/dist/components/FontSettingsPanel.d.ts +10 -0
- package/dist/components/FontSettingsPanel.js +30 -0
- package/dist/components/FullscreenTextBox.d.ts +6 -0
- package/dist/components/FullscreenTextBox.js +70 -0
- package/dist/components/GameScreen.d.ts +9 -2
- package/dist/components/GameScreen.js +396 -80
- package/dist/components/OverlayUI.d.ts +2 -3
- package/dist/components/OverlayUI.js +3 -14
- package/dist/components/PluginComponentProvider.d.ts +3 -3
- package/dist/components/PluginComponentProvider.js +22 -4
- package/dist/components/TimeWaitIndicator.d.ts +15 -0
- package/dist/components/TimeWaitIndicator.js +17 -0
- package/dist/contexts/AudioContext.d.ts +1 -0
- package/dist/contexts/AudioContext.js +1 -0
- package/dist/contexts/DataContext.d.ts +3 -1
- package/dist/contexts/DataContext.js +104 -17
- package/dist/contexts/PlaybackTextContext.d.ts +32 -0
- package/dist/contexts/PlaybackTextContext.js +29 -0
- package/dist/data-api-types.d.ts +251 -0
- package/dist/data-api-types.js +6 -0
- package/dist/emotion-effect-types.d.ts +86 -0
- package/dist/emotion-effect-types.js +6 -0
- package/dist/hooks/useBacklog.js +3 -1
- package/dist/hooks/useConversationBranch.d.ts +16 -0
- package/dist/hooks/useConversationBranch.js +125 -0
- package/dist/hooks/useFontLoader.d.ts +30 -0
- package/dist/hooks/useFontLoader.js +192 -0
- package/dist/hooks/useFullscreenText.d.ts +17 -0
- package/dist/hooks/useFullscreenText.js +120 -0
- package/dist/hooks/useImagePreloader.d.ts +5 -0
- package/dist/hooks/useImagePreloader.js +53 -0
- package/dist/hooks/usePlayerLogic.d.ts +10 -3
- package/dist/hooks/usePlayerLogic.js +115 -18
- package/dist/hooks/usePluginAPI.js +1 -1
- package/dist/hooks/usePluginEvents.d.ts +4 -1
- package/dist/hooks/usePluginEvents.js +16 -11
- package/dist/hooks/usePreloadImages.js +27 -7
- package/dist/hooks/useSoundPlayer.d.ts +15 -0
- package/dist/hooks/useSoundPlayer.js +209 -0
- package/dist/hooks/useTypewriter.d.ts +6 -2
- package/dist/hooks/useTypewriter.js +42 -6
- package/dist/hooks/useVoice.js +4 -1
- package/dist/index.d.ts +5 -3
- package/dist/index.js +3 -1
- package/dist/plugin/PluginManager.d.ts +86 -5
- package/dist/plugin/PluginManager.js +427 -94
- package/dist/sdk.d.ts +133 -162
- package/dist/sdk.js +39 -4
- package/dist/types.d.ts +300 -4
- package/dist/utils/branchBlockConverter.d.ts +2 -0
- package/dist/utils/branchBlockConverter.js +21 -0
- package/dist/utils/branchNavigator.d.ts +14 -0
- package/dist/utils/branchNavigator.js +55 -0
- package/dist/utils/facePositionCalculator.js +0 -1
- package/dist/utils/variableManager.d.ts +18 -0
- package/dist/utils/variableManager.js +159 -0
- package/package.json +6 -6
- package/dist/components/ConversationLogUI.d.ts +0 -2
- package/dist/components/ConversationLogUI.js +0 -115
- package/dist/hooks/useConversationLog.d.ts +0 -14
- package/dist/hooks/useConversationLog.js +0 -82
- package/dist/hooks/useUIVisibility.d.ts +0 -9
- package/dist/hooks/useUIVisibility.js +0 -19
package/dist/types.d.ts
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
export type
|
|
1
|
+
export type SoundCategory = "bgm" | "se" | "voice";
|
|
2
|
+
/** Block options stored as key-value pairs */
|
|
3
|
+
export type BlockOptions = Record<string, string | number | boolean>;
|
|
4
|
+
export type ScenarioBlockType = "dialogue" | "narration" | "action_node" | "character_entrance" | "character_state_change" | "bgm_play" | "se_play" | "bgm_stop" | "conversation_branch" | "background_change" | "background_group" | "variable_operation" | "fullscreen_text" | "click_wait" | "time_wait";
|
|
2
5
|
export interface ScenarioBlock {
|
|
3
6
|
id: string;
|
|
4
7
|
scenarioId: string;
|
|
@@ -9,9 +12,11 @@ export interface ScenarioBlock {
|
|
|
9
12
|
speakerStateId: string | null;
|
|
10
13
|
partVoiceId: string | null;
|
|
11
14
|
actionNodeId: string | null;
|
|
12
|
-
linkedExitBlockId: string | null;
|
|
13
15
|
createdAt: Date;
|
|
14
16
|
updatedAt: Date;
|
|
17
|
+
/** Plugin-defined block options (key-value pairs) */
|
|
18
|
+
options?: BlockOptions | null;
|
|
19
|
+
characterLayoutMode?: "detailed" | "simple";
|
|
15
20
|
speaker?: {
|
|
16
21
|
id: string;
|
|
17
22
|
name: string;
|
|
@@ -28,15 +33,64 @@ export interface ScenarioBlock {
|
|
|
28
33
|
scale?: number;
|
|
29
34
|
translateY?: number;
|
|
30
35
|
translateX?: number;
|
|
36
|
+
isDefault?: boolean;
|
|
37
|
+
layers?: EntityStateLayer[];
|
|
31
38
|
} | null;
|
|
32
39
|
actionNode?: ActionNode | null;
|
|
33
40
|
attributeValues: ScenarioBlockAttributeValue[];
|
|
34
41
|
entityAttributeValues: ScenarioBlockEntityAttributeValue[];
|
|
35
42
|
characters?: ScenarioBlockCharacter[];
|
|
36
|
-
|
|
43
|
+
soundId?: string | null;
|
|
44
|
+
sound?: {
|
|
37
45
|
id: string;
|
|
38
|
-
|
|
46
|
+
name: string;
|
|
47
|
+
url: string;
|
|
48
|
+
duration: number | null;
|
|
49
|
+
loop: boolean;
|
|
50
|
+
soundType: {
|
|
51
|
+
id: string;
|
|
52
|
+
name: string;
|
|
53
|
+
category: SoundCategory;
|
|
54
|
+
};
|
|
55
|
+
} | null;
|
|
56
|
+
backgroundObjectId?: string | null;
|
|
57
|
+
backgroundStateId?: string | null;
|
|
58
|
+
backgroundObjectFit?: "contain" | "cover" | null;
|
|
59
|
+
backgroundLoop?: boolean | null;
|
|
60
|
+
backgroundObject?: {
|
|
61
|
+
id: string;
|
|
62
|
+
name: string;
|
|
39
63
|
} | null;
|
|
64
|
+
backgroundState?: {
|
|
65
|
+
id: string;
|
|
66
|
+
name: string;
|
|
67
|
+
imageUrl: string | null;
|
|
68
|
+
webmUrl?: string | null;
|
|
69
|
+
} | null;
|
|
70
|
+
backgroundGroupItems?: BackgroundGroupItem[];
|
|
71
|
+
}
|
|
72
|
+
/** 背景の表示レイヤー(BackgroundGroupItem用) */
|
|
73
|
+
type BackgroundGroupLayerType = "background" | "above_character" | "above_dialogue" | "above_all_ui";
|
|
74
|
+
export interface BackgroundGroupItem {
|
|
75
|
+
id: string;
|
|
76
|
+
scenarioBlockId: string;
|
|
77
|
+
objectId: string;
|
|
78
|
+
stateId: string;
|
|
79
|
+
objectFit: "contain" | "cover";
|
|
80
|
+
loop: boolean;
|
|
81
|
+
opacity: number;
|
|
82
|
+
order: number;
|
|
83
|
+
layer: BackgroundGroupLayerType;
|
|
84
|
+
object: {
|
|
85
|
+
id: string;
|
|
86
|
+
name: string;
|
|
87
|
+
};
|
|
88
|
+
state: {
|
|
89
|
+
id: string;
|
|
90
|
+
name: string;
|
|
91
|
+
imageUrl: string | null;
|
|
92
|
+
webmUrl?: string | null;
|
|
93
|
+
};
|
|
40
94
|
}
|
|
41
95
|
export interface ScenarioBlockCharacter {
|
|
42
96
|
id: string;
|
|
@@ -50,6 +104,7 @@ export interface ScenarioBlockCharacter {
|
|
|
50
104
|
object: {
|
|
51
105
|
id: string;
|
|
52
106
|
name: string;
|
|
107
|
+
isLayerEnabled?: boolean;
|
|
53
108
|
};
|
|
54
109
|
entityState: {
|
|
55
110
|
id: string;
|
|
@@ -59,7 +114,18 @@ export interface ScenarioBlockCharacter {
|
|
|
59
114
|
scale?: number;
|
|
60
115
|
translateY?: number;
|
|
61
116
|
translateX?: number;
|
|
117
|
+
isDefault?: boolean;
|
|
118
|
+
layers?: EntityStateLayer[];
|
|
62
119
|
};
|
|
120
|
+
baseBodyState?: {
|
|
121
|
+
id: string;
|
|
122
|
+
objectId: string;
|
|
123
|
+
name: string;
|
|
124
|
+
imageUrl: string | null;
|
|
125
|
+
scale?: number;
|
|
126
|
+
translateY?: number;
|
|
127
|
+
translateX?: number;
|
|
128
|
+
} | null;
|
|
63
129
|
}
|
|
64
130
|
export interface ActionNode {
|
|
65
131
|
id: string;
|
|
@@ -115,10 +181,18 @@ export interface Character {
|
|
|
115
181
|
state?: EntityState;
|
|
116
182
|
element?: HTMLElement;
|
|
117
183
|
}
|
|
184
|
+
export interface EntityStateLayer {
|
|
185
|
+
id: string;
|
|
186
|
+
entityStateId: string;
|
|
187
|
+
imageUrl: string;
|
|
188
|
+
sortOrder: number;
|
|
189
|
+
}
|
|
118
190
|
export interface EntityState {
|
|
119
191
|
id: string;
|
|
120
192
|
name: string;
|
|
121
193
|
imageUrl?: string | null;
|
|
194
|
+
isDefault?: boolean;
|
|
195
|
+
layers?: EntityStateLayer[];
|
|
122
196
|
}
|
|
123
197
|
export interface DisplayedCharacter {
|
|
124
198
|
objectId: string;
|
|
@@ -130,6 +204,7 @@ export interface DisplayedCharacter {
|
|
|
130
204
|
object: {
|
|
131
205
|
id: string;
|
|
132
206
|
name: string;
|
|
207
|
+
isLayerEnabled?: boolean;
|
|
133
208
|
};
|
|
134
209
|
entityState: {
|
|
135
210
|
id: string;
|
|
@@ -139,7 +214,69 @@ export interface DisplayedCharacter {
|
|
|
139
214
|
scale?: number;
|
|
140
215
|
translateY?: number;
|
|
141
216
|
translateX?: number;
|
|
217
|
+
isDefault?: boolean;
|
|
218
|
+
layers?: EntityStateLayer[];
|
|
142
219
|
};
|
|
220
|
+
baseBodyState?: {
|
|
221
|
+
id: string;
|
|
222
|
+
name: string;
|
|
223
|
+
imageUrl: string | null;
|
|
224
|
+
scale?: number;
|
|
225
|
+
translateY?: number;
|
|
226
|
+
translateX?: number;
|
|
227
|
+
} | null;
|
|
228
|
+
}
|
|
229
|
+
export type VariableType = "string" | "number" | "choice" | "boolean";
|
|
230
|
+
export type VariableOperationType = "set" | "add" | "subtract" | "toggle";
|
|
231
|
+
export type VariableConditionType = "equals" | "less_than" | "greater_than";
|
|
232
|
+
export type BranchType = "choice" | "variable";
|
|
233
|
+
export interface Variable {
|
|
234
|
+
id: string;
|
|
235
|
+
workId: string;
|
|
236
|
+
name: string;
|
|
237
|
+
type: VariableType;
|
|
238
|
+
defaultValueString: string | null;
|
|
239
|
+
defaultValueNumber: number | null;
|
|
240
|
+
defaultValueChoice: string | null;
|
|
241
|
+
defaultValueBoolean: boolean | null;
|
|
242
|
+
choices?: VariableChoice[];
|
|
243
|
+
}
|
|
244
|
+
export interface VariableChoice {
|
|
245
|
+
id: string;
|
|
246
|
+
variableId: string;
|
|
247
|
+
label: string;
|
|
248
|
+
order: number;
|
|
249
|
+
}
|
|
250
|
+
export interface VariableOperation {
|
|
251
|
+
id: string;
|
|
252
|
+
blockId: string;
|
|
253
|
+
variableId: string;
|
|
254
|
+
operationType: VariableOperationType;
|
|
255
|
+
valueString: string | null;
|
|
256
|
+
valueNumber: number | null;
|
|
257
|
+
valueChoice: string | null;
|
|
258
|
+
valueBoolean: boolean | null;
|
|
259
|
+
variable?: Variable;
|
|
260
|
+
}
|
|
261
|
+
export interface VariableBranchCondition {
|
|
262
|
+
id: string;
|
|
263
|
+
branchId: string;
|
|
264
|
+
choiceId: string;
|
|
265
|
+
variableId: string;
|
|
266
|
+
conditionType: VariableConditionType;
|
|
267
|
+
valueString: string | null;
|
|
268
|
+
valueNumber: number | null;
|
|
269
|
+
valueChoice: string | null;
|
|
270
|
+
valueBoolean: boolean | null;
|
|
271
|
+
order: number;
|
|
272
|
+
}
|
|
273
|
+
export type FontType = "google" | "custom";
|
|
274
|
+
export interface WorkFont {
|
|
275
|
+
id: string;
|
|
276
|
+
name: string;
|
|
277
|
+
fontFamily: string;
|
|
278
|
+
type: FontType;
|
|
279
|
+
url: string | null;
|
|
143
280
|
}
|
|
144
281
|
export interface PublishedScenario {
|
|
145
282
|
id: string;
|
|
@@ -149,6 +286,10 @@ export interface PublishedScenario {
|
|
|
149
286
|
description: string | null;
|
|
150
287
|
blocks: ScenarioBlock[];
|
|
151
288
|
publishedAt: Date;
|
|
289
|
+
variables?: Variable[];
|
|
290
|
+
variableOperations?: VariableOperation[];
|
|
291
|
+
variableBranchConditions?: VariableBranchCondition[];
|
|
292
|
+
fonts?: WorkFont[];
|
|
152
293
|
}
|
|
153
294
|
export interface PlayerSettings {
|
|
154
295
|
aspectRatio: string;
|
|
@@ -167,16 +308,41 @@ export interface PlayerSettings {
|
|
|
167
308
|
effectVolume?: number;
|
|
168
309
|
/** テキスト音音量 (0-1, デフォルト: 1) */
|
|
169
310
|
textSoundVolume?: number;
|
|
311
|
+
/** デフォルト背景フェード時間 (ミリ秒, デフォルト: 0) */
|
|
312
|
+
defaultBackgroundFadeDuration?: number;
|
|
313
|
+
/** 全ての音声をミュートする (デフォルト: false) */
|
|
314
|
+
muteAudio?: boolean;
|
|
315
|
+
/** 選択されたフォントファミリー(テキスト用) */
|
|
316
|
+
selectedFontFamily?: string;
|
|
317
|
+
/** 選択されたUIフォントファミリー(メニュー・ラベル等) */
|
|
318
|
+
selectedUIFontFamily?: string;
|
|
319
|
+
/** 非アクティブキャラクターの明るさ (0-1, デフォルト: 0.8) */
|
|
320
|
+
inactiveCharacterBrightness?: number;
|
|
321
|
+
/** キャラクター間隔(簡易モード用、デフォルト: 0.1) */
|
|
322
|
+
characterSpacing?: number;
|
|
170
323
|
}
|
|
171
324
|
export interface PluginConfig {
|
|
172
325
|
packageName: string;
|
|
173
326
|
bundleUrl: string;
|
|
174
327
|
config?: unknown;
|
|
328
|
+
/** アセットのファイル名→絶対URLマッピング(外部アプリから利用時に必要) */
|
|
329
|
+
assets?: {
|
|
330
|
+
filename: string;
|
|
331
|
+
url: string;
|
|
332
|
+
}[];
|
|
333
|
+
}
|
|
334
|
+
/** 作品のサウンドデータ(プラグインからアクセス可能) */
|
|
335
|
+
export interface WorkSound {
|
|
336
|
+
id: string;
|
|
337
|
+
name: string;
|
|
338
|
+
url: string;
|
|
175
339
|
}
|
|
176
340
|
export interface PlayerProps {
|
|
177
341
|
scenario: PublishedScenario;
|
|
178
342
|
settings?: PlayerSettings;
|
|
179
343
|
plugins?: PluginConfig[];
|
|
344
|
+
/** 作品のサウンドデータ(プラグインからplayWorkSoundで使用可能) */
|
|
345
|
+
sounds?: WorkSound[];
|
|
180
346
|
onEnd?: () => void;
|
|
181
347
|
onScenarioEnd?: () => void;
|
|
182
348
|
onScenarioStart?: () => void;
|
|
@@ -184,11 +350,22 @@ export interface PlayerProps {
|
|
|
184
350
|
onSettingsChange?: (settings: PlayerSettings) => void;
|
|
185
351
|
className?: string;
|
|
186
352
|
autoplay?: boolean;
|
|
353
|
+
/** ホイールスクロールを無効化するかどうか(デフォルト: true) */
|
|
354
|
+
preventDefaultScroll?: boolean;
|
|
355
|
+
/** 画面サイズを明示的に指定(プレビュー用)。指定しない場合はwindowサイズを使用 */
|
|
356
|
+
screenSize?: {
|
|
357
|
+
width: number;
|
|
358
|
+
height: number;
|
|
359
|
+
};
|
|
360
|
+
/** キーボードナビゲーションを無効化するかどうか(デフォルト: false) */
|
|
361
|
+
disableKeyboardNavigation?: boolean;
|
|
187
362
|
}
|
|
363
|
+
export type VariableValue = string | number | boolean;
|
|
188
364
|
export interface PlayerState {
|
|
189
365
|
currentBlockIndex: number;
|
|
190
366
|
isPlaying: boolean;
|
|
191
367
|
isEnded: boolean;
|
|
368
|
+
variables?: Map<string, VariableValue>;
|
|
192
369
|
}
|
|
193
370
|
export interface BacklogEntry {
|
|
194
371
|
id: string;
|
|
@@ -198,4 +375,123 @@ export interface BacklogEntry {
|
|
|
198
375
|
content: string | null;
|
|
199
376
|
speakerName?: string;
|
|
200
377
|
speakerState?: string;
|
|
378
|
+
/** Block options (for plugin-defined options like bubble style) */
|
|
379
|
+
options?: BlockOptions | null;
|
|
380
|
+
}
|
|
381
|
+
export interface ConversationBranch {
|
|
382
|
+
id: string;
|
|
383
|
+
blockId: string;
|
|
384
|
+
workId: string;
|
|
385
|
+
branchType?: BranchType;
|
|
386
|
+
createdAt: Date;
|
|
387
|
+
updatedAt: Date;
|
|
388
|
+
branchChoices: ConversationChoice[];
|
|
389
|
+
}
|
|
390
|
+
export interface ConversationChoice {
|
|
391
|
+
id: string;
|
|
392
|
+
branchId: string;
|
|
393
|
+
choiceText: string;
|
|
394
|
+
order: number;
|
|
395
|
+
createdAt: Date;
|
|
396
|
+
updatedAt: Date;
|
|
397
|
+
branchBlocks: ConversationBranchBlock[];
|
|
398
|
+
}
|
|
399
|
+
export interface ConversationBranchBlock {
|
|
400
|
+
id: string;
|
|
401
|
+
choiceId: string;
|
|
402
|
+
blockType: ScenarioBlockType;
|
|
403
|
+
content: string | null;
|
|
404
|
+
speakerId: string | null;
|
|
405
|
+
speakerStateId: string | null;
|
|
406
|
+
actionNodeId: string | null;
|
|
407
|
+
partVoiceId: string | null;
|
|
408
|
+
order: number;
|
|
409
|
+
createdAt: Date;
|
|
410
|
+
updatedAt: Date;
|
|
411
|
+
speaker?: {
|
|
412
|
+
id: string;
|
|
413
|
+
name: string;
|
|
414
|
+
typeId: string;
|
|
415
|
+
workId: string;
|
|
416
|
+
description: string | null;
|
|
417
|
+
order: number;
|
|
418
|
+
} | null;
|
|
419
|
+
speakerState?: {
|
|
420
|
+
id: string;
|
|
421
|
+
name: string;
|
|
422
|
+
imageUrl: string | null;
|
|
423
|
+
cropArea: string | null;
|
|
424
|
+
scale?: number;
|
|
425
|
+
translateY?: number;
|
|
426
|
+
translateX?: number;
|
|
427
|
+
} | null;
|
|
428
|
+
actionNode?: ActionNode | null;
|
|
429
|
+
backgroundObjectId?: string | null;
|
|
430
|
+
backgroundStateId?: string | null;
|
|
431
|
+
backgroundObjectFit?: "contain" | "cover" | null;
|
|
432
|
+
backgroundLoop?: boolean | null;
|
|
433
|
+
backgroundObject?: {
|
|
434
|
+
id: string;
|
|
435
|
+
name: string;
|
|
436
|
+
} | null;
|
|
437
|
+
backgroundState?: {
|
|
438
|
+
id: string;
|
|
439
|
+
name: string;
|
|
440
|
+
imageUrl: string | null;
|
|
441
|
+
webmUrl?: string | null;
|
|
442
|
+
} | null;
|
|
443
|
+
}
|
|
444
|
+
export interface ChoiceData {
|
|
445
|
+
id: string;
|
|
446
|
+
text: string;
|
|
447
|
+
order: number;
|
|
448
|
+
isDisabled?: boolean;
|
|
449
|
+
}
|
|
450
|
+
export type ConversationBranchError = "DATA_MISSING" | "NETWORK_ERROR" | "INVALID_STRUCTURE" | "NO_MATCHING_CONDITION";
|
|
451
|
+
export interface ConversationBranchState {
|
|
452
|
+
isActive: boolean;
|
|
453
|
+
branchType?: BranchType;
|
|
454
|
+
currentChoices: ChoiceData[];
|
|
455
|
+
selectedChoiceId: string | null;
|
|
456
|
+
errorState: ConversationBranchError | null;
|
|
457
|
+
}
|
|
458
|
+
export interface BranchChoiceHistory {
|
|
459
|
+
branchBlockId: string;
|
|
460
|
+
selectedChoiceId: string;
|
|
461
|
+
branchBlockIndex?: number;
|
|
462
|
+
}
|
|
463
|
+
export type ConversationBranchEvent = "START" | "CHOICE_AVAILABLE" | "CHOICE_SELECTED" | "END" | "ERROR";
|
|
464
|
+
export interface BranchEventCallback {
|
|
465
|
+
onChoiceSelected?: (choiceId: string) => void;
|
|
466
|
+
onBranchStarted?: (choices: ChoiceData[]) => void;
|
|
467
|
+
onBranchEnded?: () => void;
|
|
468
|
+
onError?: (error: ConversationBranchError) => void;
|
|
469
|
+
}
|
|
470
|
+
export interface EnhancedPlayerState extends PlayerState {
|
|
471
|
+
branchHistory: BranchChoiceHistory[];
|
|
472
|
+
isInBranch: boolean;
|
|
473
|
+
currentBranchState?: ConversationBranchState;
|
|
474
|
+
}
|
|
475
|
+
export type BackgroundMediaType = "image" | "gif" | "video";
|
|
476
|
+
/** 背景の表示レイヤー */
|
|
477
|
+
export type BackgroundLayerType = "background" | "above_character" | "above_dialogue" | "above_all_ui";
|
|
478
|
+
export interface BackgroundData {
|
|
479
|
+
objectId: string;
|
|
480
|
+
stateId: string;
|
|
481
|
+
objectName: string;
|
|
482
|
+
stateName: string;
|
|
483
|
+
imageUrl: string;
|
|
484
|
+
/** WebM形式のURL(iOS/macOS以外で使用) */
|
|
485
|
+
webmUrl?: string | null;
|
|
486
|
+
objectFit: "contain" | "cover";
|
|
487
|
+
loop: boolean;
|
|
488
|
+
mediaType: BackgroundMediaType;
|
|
489
|
+
/** フェード時間(ミリ秒) */
|
|
490
|
+
fadeDuration?: number;
|
|
491
|
+
/** 不透明度 (0.0-1.0, default 1.0) */
|
|
492
|
+
opacity?: number;
|
|
493
|
+
/** 表示レイヤー (default: "background") */
|
|
494
|
+
layer?: BackgroundLayerType;
|
|
201
495
|
}
|
|
496
|
+
export type BackgroundGroupData = BackgroundData[];
|
|
497
|
+
export {};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export function convertBranchBlockToScenarioBlock(branchBlock) {
|
|
2
|
+
return {
|
|
3
|
+
id: branchBlock.id,
|
|
4
|
+
scenarioId: "",
|
|
5
|
+
order: branchBlock.order,
|
|
6
|
+
blockType: branchBlock.blockType,
|
|
7
|
+
content: branchBlock.content,
|
|
8
|
+
speakerId: branchBlock.speakerId,
|
|
9
|
+
speakerStateId: branchBlock.speakerStateId,
|
|
10
|
+
partVoiceId: branchBlock.partVoiceId,
|
|
11
|
+
actionNodeId: branchBlock.actionNodeId,
|
|
12
|
+
createdAt: branchBlock.createdAt,
|
|
13
|
+
updatedAt: branchBlock.updatedAt,
|
|
14
|
+
speaker: branchBlock.speaker,
|
|
15
|
+
speakerState: branchBlock.speakerState,
|
|
16
|
+
actionNode: branchBlock.actionNode,
|
|
17
|
+
attributeValues: [],
|
|
18
|
+
entityAttributeValues: [],
|
|
19
|
+
characters: [],
|
|
20
|
+
};
|
|
21
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { ConversationBranchBlock, ConversationChoice } from "../types";
|
|
2
|
+
export declare class BranchNavigator {
|
|
3
|
+
private branchBlocks;
|
|
4
|
+
private currentIndex;
|
|
5
|
+
private isActive;
|
|
6
|
+
startBranchNavigation(choice: ConversationChoice, startIndex?: number): void;
|
|
7
|
+
nextBranchBlock(): ConversationBranchBlock | null;
|
|
8
|
+
getCurrentBranchBlock(): ConversationBranchBlock | null;
|
|
9
|
+
getCurrentBranchBlockIndex(): number;
|
|
10
|
+
previousBranchBlock(): ConversationBranchBlock | null;
|
|
11
|
+
hasMoreBranchBlocks(): boolean;
|
|
12
|
+
reset(): void;
|
|
13
|
+
getIsActive(): boolean;
|
|
14
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
export class BranchNavigator {
|
|
2
|
+
constructor() {
|
|
3
|
+
this.branchBlocks = [];
|
|
4
|
+
this.currentIndex = 0;
|
|
5
|
+
this.isActive = false;
|
|
6
|
+
}
|
|
7
|
+
startBranchNavigation(choice, startIndex = 0) {
|
|
8
|
+
this.branchBlocks = [...choice.branchBlocks].sort((a, b) => a.order - b.order);
|
|
9
|
+
this.currentIndex = startIndex;
|
|
10
|
+
this.isActive = this.branchBlocks.length > 0;
|
|
11
|
+
if (this.currentIndex >= this.branchBlocks.length) {
|
|
12
|
+
this.currentIndex = 0;
|
|
13
|
+
this.isActive = false;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
nextBranchBlock() {
|
|
17
|
+
if (!this.isActive || this.currentIndex >= this.branchBlocks.length) {
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
const block = this.branchBlocks[this.currentIndex];
|
|
21
|
+
this.currentIndex++;
|
|
22
|
+
if (this.currentIndex >= this.branchBlocks.length) {
|
|
23
|
+
this.isActive = false;
|
|
24
|
+
}
|
|
25
|
+
return block;
|
|
26
|
+
}
|
|
27
|
+
getCurrentBranchBlock() {
|
|
28
|
+
if (!this.isActive || this.currentIndex >= this.branchBlocks.length) {
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
return this.branchBlocks[this.currentIndex];
|
|
32
|
+
}
|
|
33
|
+
getCurrentBranchBlockIndex() {
|
|
34
|
+
return this.currentIndex;
|
|
35
|
+
}
|
|
36
|
+
previousBranchBlock() {
|
|
37
|
+
if (this.currentIndex > 0) {
|
|
38
|
+
this.currentIndex--;
|
|
39
|
+
this.isActive = true;
|
|
40
|
+
return this.branchBlocks[this.currentIndex];
|
|
41
|
+
}
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
hasMoreBranchBlocks() {
|
|
45
|
+
return this.isActive && this.currentIndex < this.branchBlocks.length;
|
|
46
|
+
}
|
|
47
|
+
reset() {
|
|
48
|
+
this.branchBlocks = [];
|
|
49
|
+
this.currentIndex = 0;
|
|
50
|
+
this.isActive = false;
|
|
51
|
+
}
|
|
52
|
+
getIsActive() {
|
|
53
|
+
return this.isActive;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { Variable, VariableBranchCondition, VariableOperation, VariableValue } from "../types";
|
|
2
|
+
export declare class VariableManager {
|
|
3
|
+
private variables;
|
|
4
|
+
private variableDefinitions;
|
|
5
|
+
private variableNameToId;
|
|
6
|
+
constructor(variables: Variable[]);
|
|
7
|
+
private getDefaultValue;
|
|
8
|
+
getValue(variableId: string): VariableValue | undefined;
|
|
9
|
+
getValueByName(variableName: string): VariableValue | undefined;
|
|
10
|
+
getVariableDefinition(variableId: string): Variable | undefined;
|
|
11
|
+
executeOperation(operation: VariableOperation): void;
|
|
12
|
+
private setValue;
|
|
13
|
+
evaluateCondition(condition: VariableBranchCondition): boolean;
|
|
14
|
+
private evaluateEquals;
|
|
15
|
+
interpolateText(text: string): string;
|
|
16
|
+
getVariablesMap(): Map<string, VariableValue>;
|
|
17
|
+
reset(): void;
|
|
18
|
+
}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
export class VariableManager {
|
|
2
|
+
constructor(variables) {
|
|
3
|
+
this.variables = new Map();
|
|
4
|
+
this.variableDefinitions = new Map();
|
|
5
|
+
this.variableNameToId = new Map();
|
|
6
|
+
for (const variable of variables) {
|
|
7
|
+
this.variableDefinitions.set(variable.id, variable);
|
|
8
|
+
this.variableNameToId.set(variable.name, variable.id);
|
|
9
|
+
this.variables.set(variable.id, this.getDefaultValue(variable));
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
getDefaultValue(variable) {
|
|
13
|
+
switch (variable.type) {
|
|
14
|
+
case "string":
|
|
15
|
+
return variable.defaultValueString || "";
|
|
16
|
+
case "number":
|
|
17
|
+
return variable.defaultValueNumber || 0;
|
|
18
|
+
case "boolean":
|
|
19
|
+
return variable.defaultValueBoolean || false;
|
|
20
|
+
case "choice":
|
|
21
|
+
return variable.defaultValueChoice || "";
|
|
22
|
+
default:
|
|
23
|
+
return "";
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
getValue(variableId) {
|
|
27
|
+
return this.variables.get(variableId);
|
|
28
|
+
}
|
|
29
|
+
getValueByName(variableName) {
|
|
30
|
+
const variableId = this.variableNameToId.get(variableName);
|
|
31
|
+
if (!variableId)
|
|
32
|
+
return undefined;
|
|
33
|
+
return this.variables.get(variableId);
|
|
34
|
+
}
|
|
35
|
+
getVariableDefinition(variableId) {
|
|
36
|
+
return this.variableDefinitions.get(variableId);
|
|
37
|
+
}
|
|
38
|
+
executeOperation(operation) {
|
|
39
|
+
const variable = this.variableDefinitions.get(operation.variableId);
|
|
40
|
+
if (!variable) {
|
|
41
|
+
console.warn(`Variable not found: ${operation.variableId}`);
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
const currentValue = this.variables.get(operation.variableId);
|
|
45
|
+
switch (operation.operationType) {
|
|
46
|
+
case "set":
|
|
47
|
+
this.setValue(operation.variableId, variable, operation);
|
|
48
|
+
break;
|
|
49
|
+
case "add":
|
|
50
|
+
if (variable.type === "number" && typeof currentValue === "number") {
|
|
51
|
+
const addValue = operation.valueNumber || 0;
|
|
52
|
+
const newValue = Math.max(-1000000, Math.min(1000000, currentValue + addValue));
|
|
53
|
+
this.variables.set(operation.variableId, newValue);
|
|
54
|
+
}
|
|
55
|
+
break;
|
|
56
|
+
case "subtract":
|
|
57
|
+
if (variable.type === "number" && typeof currentValue === "number") {
|
|
58
|
+
const subtractValue = operation.valueNumber || 0;
|
|
59
|
+
const newValue = Math.max(-1000000, Math.min(1000000, currentValue - subtractValue));
|
|
60
|
+
this.variables.set(operation.variableId, newValue);
|
|
61
|
+
}
|
|
62
|
+
break;
|
|
63
|
+
case "toggle":
|
|
64
|
+
if (variable.type === "boolean" && typeof currentValue === "boolean") {
|
|
65
|
+
this.variables.set(operation.variableId, !currentValue);
|
|
66
|
+
}
|
|
67
|
+
break;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
setValue(variableId, variable, operation) {
|
|
71
|
+
switch (variable.type) {
|
|
72
|
+
case "string":
|
|
73
|
+
this.variables.set(variableId, operation.valueString || "");
|
|
74
|
+
break;
|
|
75
|
+
case "number":
|
|
76
|
+
this.variables.set(variableId, operation.valueNumber || 0);
|
|
77
|
+
break;
|
|
78
|
+
case "boolean":
|
|
79
|
+
this.variables.set(variableId, operation.valueBoolean || false);
|
|
80
|
+
break;
|
|
81
|
+
case "choice":
|
|
82
|
+
this.variables.set(variableId, operation.valueChoice || "");
|
|
83
|
+
break;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
evaluateCondition(condition) {
|
|
87
|
+
const variable = this.variableDefinitions.get(condition.variableId);
|
|
88
|
+
if (!variable) {
|
|
89
|
+
console.warn(`Variable not found: ${condition.variableId}`);
|
|
90
|
+
return false;
|
|
91
|
+
}
|
|
92
|
+
const currentValue = this.variables.get(condition.variableId);
|
|
93
|
+
switch (condition.conditionType) {
|
|
94
|
+
case "equals":
|
|
95
|
+
return this.evaluateEquals(variable, currentValue, condition);
|
|
96
|
+
case "less_than":
|
|
97
|
+
if (variable.type === "number" &&
|
|
98
|
+
typeof currentValue === "number" &&
|
|
99
|
+
condition.valueNumber !== null) {
|
|
100
|
+
return currentValue < condition.valueNumber;
|
|
101
|
+
}
|
|
102
|
+
return false;
|
|
103
|
+
case "greater_than":
|
|
104
|
+
if (variable.type === "number" &&
|
|
105
|
+
typeof currentValue === "number" &&
|
|
106
|
+
condition.valueNumber !== null) {
|
|
107
|
+
return currentValue > condition.valueNumber;
|
|
108
|
+
}
|
|
109
|
+
return false;
|
|
110
|
+
default:
|
|
111
|
+
return false;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
evaluateEquals(variable, currentValue, condition) {
|
|
115
|
+
switch (variable.type) {
|
|
116
|
+
case "string":
|
|
117
|
+
return currentValue === (condition.valueString || "");
|
|
118
|
+
case "number":
|
|
119
|
+
return currentValue === (condition.valueNumber || 0);
|
|
120
|
+
case "boolean":
|
|
121
|
+
return currentValue === (condition.valueBoolean || false);
|
|
122
|
+
case "choice":
|
|
123
|
+
return currentValue === (condition.valueChoice || "");
|
|
124
|
+
default:
|
|
125
|
+
return false;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
interpolateText(text) {
|
|
129
|
+
return text.replace(/\{([^}]+)\}/g, (match, variableName) => {
|
|
130
|
+
var _a;
|
|
131
|
+
const trimmedName = variableName.trim();
|
|
132
|
+
const variableId = this.variableNameToId.get(trimmedName);
|
|
133
|
+
if (!variableId) {
|
|
134
|
+
return match;
|
|
135
|
+
}
|
|
136
|
+
const value = this.variables.get(variableId);
|
|
137
|
+
if (value === undefined) {
|
|
138
|
+
return match;
|
|
139
|
+
}
|
|
140
|
+
const variable = this.variableDefinitions.get(variableId);
|
|
141
|
+
if (!variable) {
|
|
142
|
+
return match;
|
|
143
|
+
}
|
|
144
|
+
if (variable.type === "choice" && typeof value === "string") {
|
|
145
|
+
const choice = (_a = variable.choices) === null || _a === void 0 ? void 0 : _a.find((c) => c.id === value);
|
|
146
|
+
return choice ? choice.label : match;
|
|
147
|
+
}
|
|
148
|
+
return String(value);
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
getVariablesMap() {
|
|
152
|
+
return new Map(this.variables);
|
|
153
|
+
}
|
|
154
|
+
reset() {
|
|
155
|
+
for (const [id, variable] of this.variableDefinitions) {
|
|
156
|
+
this.variables.set(id, this.getDefaultValue(variable));
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|