Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
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
4 changes: 3 additions & 1 deletion packages/parser/src/interface/runtimeInterface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,6 @@ export interface sceneEntry {
* 场景栈条目接口 (兼容性别名)
* @interface ISceneEntry
*/
export interface ISceneEntry extends sceneEntry {}
export interface ISceneEntry extends sceneEntry {
sceneParams: Record<string, any>; // 场景参数
}
2 changes: 1 addition & 1 deletion packages/parser/src/interface/sceneInterface.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* 语句类型
*/
import { sceneEntry, ISceneEntry } from './runtimeInterface';
import { ISceneEntry } from './runtimeInterface';
import { fileType } from './assets';

export enum commandType {
Expand Down
2 changes: 1 addition & 1 deletion packages/webgal/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"@emotion/css": "^11.11.2",
"@icon-park/react": "^1.4.2",
"@reduxjs/toolkit": "^1.8.1",
"angular-expressions": "^1.4.3",
"angular-expressions": "^1.5.5",
"axios": "^1.13.5",
"cloudlogjs": "^1.0.9",
"gifuct-js": "^2.1.2",
Expand Down
3 changes: 3 additions & 0 deletions packages/webgal/src/Core/Modules/scene.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export interface ISceneEntry {
sceneName: string; // 场景名称
sceneUrl: string; // 场景url
continueLine: number; // 继续原场景的行号
sceneParams: Record<string, any>; // 场景参数
}

/**
Expand All @@ -29,6 +30,7 @@ export class SceneManager {
public sceneData: ISceneData = cloneDeep(initSceneData);
public lockSceneWrite = false;
public sceneWritePromise: Promise<void> | null = null;
public currentSceneParams: Record<string, any> = {}; // 当前场景参数

public resetScene() {
this.sceneData.currentSentenceId = 0;
Expand All @@ -37,5 +39,6 @@ export class SceneManager {
this.sceneWritePromise = null;
this.settledScenes.clear();
this.settledAssets.clear();
this.currentSceneParams = {};
}
}
29 changes: 11 additions & 18 deletions packages/webgal/src/Core/controller/gamePlay/scriptExecutor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,36 +3,22 @@ import { runScript } from './runScript';
import { logger } from '../../util/logger';
import { restoreScene } from '../scene/restoreScene';
import { webgalStore } from '@/store/store';
import { getValueFromStateElseKey } from '@/Core/gameScripts/setVar';
import { strIf } from '@/Core/controller/gamePlay/strIf';
import cloneDeep from 'lodash/cloneDeep';
import { ISceneEntry } from '@/Core/Modules/scene';
import { WebGAL } from '@/Core/WebGAL';
import { getBooleanArgByKey, getStringArgByKey } from '@/Core/util/getSentenceArg';
import { stageStateManager } from '@/Core/Modules/stage/stageStateManager';
import { jumpToLabel } from '@/Core/gameScripts/label/jumpToLabel';
import { prefetchCurrentSceneByProgress } from '@/Core/util/prefetcher/progressPrefetcher';
import { evaluateStageExpression } from '@/Core/util/evalSentenceFn';

const MAX_FORWARD_SCRIPT_EXECUTION = 1000;

export const whenChecker = (whenValue: string | undefined): boolean => {
if (whenValue === undefined) {
return true;
}
// 先把变量解析出来
const valExpArr = whenValue.split(/([+\-*\/()><!]|>=|<=|==|&&|\|\||!=)/g);
const valExp = valExpArr
.map((_e) => {
const e = _e.trim();
if (e.match(/[a-zA-Z]/)) {
if (e.match(/^(true|false)$/)) {
return e;
}
return getValueFromStateElseKey(e, true, true);
} else return e;
})
.reduce((pre, curr) => pre + curr, '');
return !!strIf(valExp);
return evaluateStageExpression(whenValue, { returnType: 'boolean' });
};

/**
Expand Down Expand Up @@ -69,8 +55,15 @@ export const scriptExecutor = (depth = 0) => {

if (contentExp !== null) {
contentExp.forEach((e) => {
const contentVarValue = getValueFromStateElseKey(e.replace(/(?<!\\)\{(.*)\}/, '$1'));
retContent = retContent.replace(e, contentVarValue);
let likeExpr = e;
// {}可能是对象
if (!/(?<!\\)\{.+\s*:\s*.+\}/.test(e)) {
likeExpr = e.replace(/(?<!\\)\{(.*)\}/, '$1');
}
const contentVarValue = evaluateStageExpression(likeExpr, { returnType: 'origin' });
// 如果是对象,我们需要将其转换为字符串
if (typeof contentVarValue === 'object') retContent = retContent.replace(e, JSON.stringify(contentVarValue));
else retContent = retContent.replace(e, String(contentVarValue));
});
}
retContent = retContent.replace(/\\{/g, '{').replace(/\\}/g, '}');
Expand Down
10 changes: 0 additions & 10 deletions packages/webgal/src/Core/controller/gamePlay/strIf.ts

This file was deleted.

16 changes: 14 additions & 2 deletions packages/webgal/src/Core/controller/scene/callScene.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,17 @@ import { sceneParser } from '../../parser/sceneParser';
import { logger } from '../../util/logger';
import { nextSentence } from '@/Core/controller/gamePlay/nextSentence';
import { clearPrefetchLinks } from '@/Core/util/prefetcher/assetsPrefetcher';

import cloneDeep from 'lodash/cloneDeep';
import { WebGAL } from '@/Core/WebGAL';
import { evaluateStageExpressionWithoutDot } from '@/Core/util/evalSentenceFn';

/**
* 调用场景
* @param sceneUrl 场景路径
* @param sceneName 场景名称
* @param args 参数
*/
export const callScene = (sceneUrl: string, sceneName: string) => {
export const callScene = (sceneUrl: string, sceneName: string, params: Record<string, any> = {}) => {
if (WebGAL.sceneManager.lockSceneWrite) {
return;
}
Expand All @@ -23,6 +25,7 @@ export const callScene = (sceneUrl: string, sceneName: string) => {
sceneName: WebGAL.sceneManager.sceneData.currentScene.sceneName,
sceneUrl: WebGAL.sceneManager.sceneData.currentScene.sceneUrl,
continueLine: WebGAL.sceneManager.sceneData.currentSentenceId,
sceneParams: cloneDeep(WebGAL.sceneManager.currentSceneParams), // 保存当前场景参数
});
// 场景写入到运行时
const sceneWritePromise = sceneFetcher(sceneUrl)
Expand All @@ -33,6 +36,15 @@ export const callScene = (sceneUrl: string, sceneName: string) => {
WebGAL.sceneManager.settledScenes.add(sceneUrl); // 放入已加载场景列表,避免递归加载相同场景
logger.debug('现在调用场景,调用结果:', WebGAL.sceneManager.sceneData);
shouldAutoNext = !isFastPreviewSceneWrite;
WebGAL.sceneManager.currentSceneParams = Object.entries(params)
.map(([key, value]) => ({
key,
value: evaluateStageExpressionWithoutDot(value),
}))
.reduce((res: Record<string, string>, item: Record<string, string>) => {
res[item.key] = item.value;
return res;
}, {} as Record<string, string>); // 设置新场景参数并立即求值
})
.catch((e) => {
logger.error('场景调用错误', e);
Expand Down
13 changes: 12 additions & 1 deletion packages/webgal/src/Core/controller/scene/changeScene.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@ import { nextSentence } from '@/Core/controller/gamePlay/nextSentence';
import { clearPrefetchLinks } from '@/Core/util/prefetcher/assetsPrefetcher';

import { WebGAL } from '@/Core/WebGAL';
import { evaluateStageExpressionWithoutDot } from '@/Core/util/evalSentenceFn';

/**
* 切换场景
* @param sceneUrl 场景路径
* @param sceneName 场景名称
* @param args 场景参数
*/
export const changeScene = (sceneUrl: string, sceneName: string) => {
export const changeScene = (sceneUrl: string, sceneName: string, params: Record<string, any> = {}) => {
if (WebGAL.sceneManager.lockSceneWrite) {
return;
}
Expand All @@ -27,6 +29,15 @@ export const changeScene = (sceneUrl: string, sceneName: string) => {
WebGAL.sceneManager.settledScenes.add(sceneUrl); // 放入已加载场景列表,避免递归加载相同场景
logger.debug('现在切换场景,切换后的结果:', WebGAL.sceneManager.sceneData);
shouldAutoNext = !isFastPreviewSceneWrite;
WebGAL.sceneManager.currentSceneParams = Object.entries(params)
.map(([key, value]) => ({
key,
value: evaluateStageExpressionWithoutDot(value),
}))
.reduce((res: Record<string, string>, item: Record<string, string>) => {
res[item.key] = item.value;
return res;
}, {} as Record<string, string>); // 设置新场景参数并立即求值
})
.catch((e) => {
logger.error('场景调用错误', e);
Expand Down
1 change: 1 addition & 0 deletions packages/webgal/src/Core/controller/scene/restoreScene.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export const restoreScene = (entry: ISceneEntry) => {
WebGAL.sceneManager.sceneData.currentSentenceId = entry.continueLine + 1; // 重设场景
logger.debug('现在恢复场景,恢复后场景:', WebGAL.sceneManager.sceneData.currentScene);
shouldAutoNext = !isFastPreviewSceneWrite;
WebGAL.sceneManager.currentSceneParams = entry.sceneParams ?? {};
})
.catch((e) => {
logger.error('场景调用错误', e);
Expand Down
7 changes: 6 additions & 1 deletion packages/webgal/src/Core/gameScripts/callSceneScript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ import { callScene } from '../controller/scene/callScene';
export const callSceneScript = (sentence: ISentence): IPerform => {
const sceneNameArray: Array<string> = sentence.content.split('/');
const sceneName = sceneNameArray[sceneNameArray.length - 1];
callScene(sentence.content, sceneName);
// 从 args 中提取场景参数
const params: Record<string, any> = {};
sentence.args.forEach((arg) => {
if (arg.key.startsWith('@')) params[arg.key.slice(1)] = arg.value;
});
callScene(sentence.content, sceneName, params);
return createNonePerform({ isHoldOn: true });
};
9 changes: 8 additions & 1 deletion packages/webgal/src/Core/gameScripts/changeSceneScript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,13 @@ import { changeScene } from '../controller/scene/changeScene';
export const changeSceneScript = (sentence: ISentence): IPerform => {
const sceneNameArray: Array<string> = sentence.content.split('/');
const sceneName = sceneNameArray[sceneNameArray.length - 1];
changeScene(sentence.content, sceneName);
// 从 args 中提取场景参数
const params: Record<string, any> = {};
sentence.args.forEach((arg) => {
if (arg.key.startsWith('@')) {
params[arg.key.slice(1)] = arg.value;
}
});
changeScene(sentence.content, sceneName, params);
return createNonePerform({ isHoldOn: true });
};
18 changes: 12 additions & 6 deletions packages/webgal/src/Core/gameScripts/choose/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { createNonePerform, IPerform } from '@/Core/Modules/perform/performInter
import { changeScene } from '@/Core/controller/scene/changeScene';
import { jmp } from '@/Core/gameScripts/label/jmp';
import ReactDOM from 'react-dom';
import React from 'react';
import styles from './choose.module.scss';
import { webgalStore } from '@/store/store';
import { useSEByWebgalStore } from '@/hooks/useSoundEffect';
Expand All @@ -16,6 +15,7 @@ import { useFontFamily } from '@/hooks/useFontFamily';
import { getNumberArgByKey } from '@/Core/util/getSentenceArg';

class ChooseOption {
public params: Record<string, any> = {};
/**
* 格式:
* (showConditionVar>1)[enableConditionVar>2]->text:jump
Expand All @@ -38,6 +38,13 @@ class ChooseOption {
}
return option;
}
public appendArgs(args: { key: string; value: any }[]) {
// 解析后面的 -xxx 参数
args.forEach(({ key, value }) => {
if (key.startsWith('@')) this.params[key.slice(1)] = value;
});
return this;
}
public text: string;
public jump: string;
public jumpToScene: boolean;
Expand All @@ -57,10 +64,9 @@ class ChooseOption {
*/
export const choose = (sentence: ISentence): IPerform => {
const chooseOptionScripts = sentence.content.split(/(?<!\\)\|/);
const chooseOptions = chooseOptionScripts.map((e) => ChooseOption.parse(e.trim()));
const chooseOptions = chooseOptionScripts.map((e) => ChooseOption.parse(e.trim()).appendArgs(sentence.args));
const defaultChoose = getNumberArgByKey(sentence, 'defaultChoose');
const defaultPreviewChoice = getDefaultPreviewChoice(chooseOptions, defaultChoose);

if (defaultPreviewChoice) {
selectChooseOption(defaultPreviewChoice, false);
if (!defaultPreviewChoice.jumpToScene) {
Expand Down Expand Up @@ -112,7 +118,7 @@ function getDefaultPreviewChoice(chooseOptions: ChooseOption[], defaultChoose: n

function selectChooseOption(option: ChooseOption, autoNext = true) {
if (option.jumpToScene) {
changeScene(option.jump, option.text);
changeScene(option.jump, option.text, option.params);
} else {
jmp(option.jump, autoNext);
}
Expand All @@ -125,7 +131,7 @@ function Choose(props: { chooseOptions: ChooseOption[] }) {
// 运行时计算JSX.Element[]
const runtimeBuildList = (chooseListFull: ChooseOption[]) => {
return chooseListFull
.filter((e, i) => whenChecker(e.showCondition))
.filter((e) => whenChecker(e.showCondition))
.map((e, i) => {
const enable = whenChecker(e.enableCondition);
const className = enable
Expand All @@ -135,7 +141,7 @@ function Choose(props: { chooseOptions: ChooseOption[] }) {
? () => {
playSeClick();
WebGAL.gameplay.performController.unmountPerform('choose');
selectChooseOption(e);
selectChooseOption(e, true);
}
: () => {};
return (
Expand Down
Loading
Loading