Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/webgal/src/Core/Modules/stage/stageInterface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,7 @@ export interface IStageState {
showText: string; // 文字
showTextSize: number; // 文字
showName: string; // 人物名
textboxTheme: string; // 对话框主题
command: string; // 语句指令
choose: Array<IChooseItem>; // 选项列表
vocal: string; // 语音 文件地址(相对或绝对)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ export const initState: IStageState = {
showText: '',
showTextSize: -1,
showName: '',
textboxTheme: '',
command: '',
choose: [],
vocal: '',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import { describe, expect, it } from 'vitest';
import { resolveDialogDisplayState } from './resolveDialogDisplayState';

describe('resolveDialogDisplayState', () => {
it('uses speaker as the default show name and textbox theme', () => {
expect(
resolveDialogDisplayState({
previousShowName: '',
previousTextboxTheme: '',
speaker: 'anon',
textboxThemeOverride: null,
clear: false,
}),
).toEqual({
showName: 'anon',
textboxTheme: 'anon',
});
});

it('keeps the speaker name and lets textboxTheme override the default theme', () => {
expect(
resolveDialogDisplayState({
previousShowName: '',
previousTextboxTheme: '',
speaker: 'anon',
textboxThemeOverride: 'system',
clear: false,
}),
).toEqual({
showName: 'anon',
textboxTheme: 'system',
});
});

it('inherits the previous state when the sentence does not provide a new speaker or theme', () => {
expect(
resolveDialogDisplayState({
previousShowName: 'anon',
previousTextboxTheme: 'system',
speaker: null,
textboxThemeOverride: null,
clear: false,
}),
).toEqual({
showName: 'anon',
textboxTheme: 'system',
});
});

it('resets the textbox theme to the new speaker when the previous sentence used an override', () => {
expect(
resolveDialogDisplayState({
previousShowName: 'anon',
previousTextboxTheme: 'system',
speaker: 'heroine',
textboxThemeOverride: null,
clear: false,
}),
).toEqual({
showName: 'heroine',
textboxTheme: 'heroine',
});
});

it('clears both show name and textbox theme by default', () => {
expect(
resolveDialogDisplayState({
previousShowName: 'anon',
previousTextboxTheme: 'system',
speaker: null,
textboxThemeOverride: null,
clear: true,
}),
).toEqual({
showName: '',
textboxTheme: '',
});
});

it('allows textboxTheme to override the cleared default', () => {
expect(
resolveDialogDisplayState({
previousShowName: 'anon',
previousTextboxTheme: 'anon',
speaker: null,
textboxThemeOverride: 'system',
clear: true,
}),
).toEqual({
showName: '',
textboxTheme: 'system',
});
});
});
40 changes: 40 additions & 0 deletions packages/webgal/src/Core/gameScripts/resolveDialogDisplayState.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
interface ResolveDialogDisplayStateOptions {
previousShowName: string;
previousTextboxTheme: string;
speaker: string | null;
textboxThemeOverride: string | null;
clear: boolean;
}

interface DialogDisplayState {
showName: string;
textboxTheme: string;
}

export function resolveDialogDisplayState(options: ResolveDialogDisplayStateOptions): DialogDisplayState {
const { previousShowName, previousTextboxTheme, speaker, textboxThemeOverride, clear } = options;

let showName = previousShowName;
if (speaker !== null) {
showName = speaker;
}
if (clear) {
showName = '';
}

let textboxTheme = previousTextboxTheme;
if (speaker !== null) {
textboxTheme = speaker;
}
if (clear) {
textboxTheme = '';
}
if (textboxThemeOverride !== null) {
textboxTheme = textboxThemeOverride;
}
Comment thread
A-kirami marked this conversation as resolved.
Outdated

return {
showName,
textboxTheme,
};
}
20 changes: 11 additions & 9 deletions packages/webgal/src/Core/gameScripts/say.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { compileSentence } from '@/Stage/TextBox/TextBox';
import { performMouthAnimation } from '@/Core/gameScripts/vocal/vocalAnimation';
import { match } from '@/Core/util/match';
import { stageStateManager } from '@/Core/Modules/stage/stageStateManager';
import { resolveDialogDisplayState } from './resolveDialogDisplayState';

/**
* 进行普通对话的显示
Expand All @@ -29,6 +30,7 @@ export const say = (sentence: ISentence): IPerform => {
const isNotend = getBooleanArgByKey(sentence, 'notend') ?? false; // 是否有 notend 参数
const speaker = getStringArgByKey(sentence, 'speaker'); // 获取说话者
const clear = getBooleanArgByKey(sentence, 'clear') ?? false; // 是否清除说话者
const textboxThemeOverride = getStringArgByKey(sentence, 'theme'); // 覆盖本句对话框主题
const vocal = getStringArgByKey(sentence, 'vocal'); // 是否播放语音

// 如果是concat,那么就继承上一句的key,并且继承上一句对话。
Expand Down Expand Up @@ -75,15 +77,15 @@ export const say = (sentence: ISentence): IPerform => {
break;
}

// 设置显示的角色名称
let showName = stageState.showName; // 先默认继承
if (speaker !== null) {
showName = speaker;
}
if (clear) {
showName = '';
}
stageStateManager.setStage('showName', showName);
const dialogDisplayState = resolveDialogDisplayState({
previousShowName: stageState.showName,
previousTextboxTheme: stageState.textboxTheme,
speaker,
textboxThemeOverride,
clear,
});
stageStateManager.setStage('showName', dialogDisplayState.showName);
stageStateManager.setStage('textboxTheme', dialogDisplayState.textboxTheme);

// 模拟说话
let performSimulateVocalTimeout: ReturnType<typeof setTimeout> | null = null;
Expand Down
3 changes: 2 additions & 1 deletion packages/webgal/src/Stage/TextBox/IMSSTextbox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export default function IMSSTextbox(props: ITextboxProps) {
miniAvatar,
isHasName,
showName,
textboxTheme,
font,
textDuration,
isUseStroke,
Expand Down Expand Up @@ -214,7 +215,7 @@ export default function IMSSTextbox(props: ITextboxProps) {
return (
<>
{isText && (
<div className={styles.TextBox_Container}>
<div className={styles.TextBox_Container} data-textbox-theme={textboxTheme || undefined}>
<div
className={
applyStyle('TextBox_main', styles.TextBox_main) +
Expand Down
2 changes: 2 additions & 0 deletions packages/webgal/src/Stage/TextBox/TextBox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ export const TextBox = () => {
const textArray = compileSentence(stageState.showText, lineLimit);
const isHasName = stageState.showName !== '';
const showName = compileSentence(stageState.showName, lineLimit);
const textboxTheme = stageState.textboxTheme;
const currentConcatDialogPrev = stageState.currentConcatDialogPrev;
const currentDialogKey = stageState.currentDialogKey;
const miniAvatar = stageState.miniAvatar;
Expand Down Expand Up @@ -95,6 +96,7 @@ export const TextBox = () => {
textDelay={textDelay}
showName={showName}
isHasName={isHasName}
textboxTheme={textboxTheme}
currentConcatDialogPrev={currentConcatDialogPrev}
fontSize={size}
currentDialogKey={currentDialogKey}
Expand Down
1 change: 1 addition & 0 deletions packages/webgal/src/Stage/TextBox/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export interface ITextboxProps {
miniAvatar: string;
showName: EnhancedNode[][];
isHasName: boolean;
textboxTheme: string;
font: string;
textDuration: number;
textSizeState: number;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ export const TextPreview = (props: any) => {
textDelay: textDelay,
isHasName: isHasName,
showName: showNameArray,
textboxTheme: '',
currentConcatDialogPrev: '',
fontSize: size,
currentDialogKey: String(previewKey),
Expand Down
Loading