diff --git a/docs/api/user-data-base/钩子.md b/docs/api/user-data-base/钩子.md new file mode 100644 index 0000000..4fc989b --- /dev/null +++ b/docs/api/user-data-base/钩子.md @@ -0,0 +1,97 @@ +# 游戏事件钩子 API 文档 + +本文档由 `DeepSeek R1` 模型生成并微调。 + +--- + +## GameLoading 加载进度钩子 + +### 核心事件说明 + +| 事件名 | 触发时机 | 参数 | +| ------------------ | -------------------------- | ---- | +| `coreLoaded` | 核心脚本加载完成时 | 无 | +| `autotileLoaded` | 所有自动元件资源加载完成时 | 无 | +| `coreInit` | 核心类初始化完成时 | 无 | +| `loaded` | 所有启动必要资源加载完成时 | 无 | +| `registered` | 客户端和数据端都完成挂载时 | 无 | +| `dataRegistered` | 数据端服务挂载完成时 | 无 | +| `clientRegistered` | 渲染端挂载完成时 | 无 | + +--- + +### 使用示例 + +```typescript +import { loading } from '@user/data-base'; + +// 监听核心初始化事件 +loading.on('coreInit', () => { + console.log('核心系统已就绪'); + initializeCustomModules(); +}); + +// 监听完整加载事件 +loading.once('loaded', () => { + showMainMenu(); + preloadOptionalAssets(); +}); +``` + +--- + +## GameEvent 游戏运行时钩子 + +### 核心事件说明 + +| 事件名 | 触发时机 | 参数 | +| ------------------ | ------------------------------------ | ------------------------------------------------------------------------------- | +| `reset` | 游戏初始化时,例如读档后、进入游戏后 | 无 | +| `mounted` | 游戏 DOM 挂载完成后 | 无 | +| `statusBarUpdate` | 状态栏更新时 | 无 | +| `renderLoaded` | 渲染端加载完成时 | 无 | +| `afterGetItem` | 拾取道具后 | `[itemId: 道具ID, x: 坐标X, y: 坐标Y, isGentleClick: 是否轻击]` | +| `afterOpenDoor` | 成功开门后 | `[doorId: 门动画ID, x: 坐标X, y: 坐标Y]` | +| `afterChangeFloor` | 楼层切换完成后 | `[floorId: 新楼层ID]` | +| `moveOneStep` | 玩家移动一步后 | `[x: 新坐标X, y: 新坐标Y, floorId: 当前楼层ID]` | +| `afterBattle` | 战斗结算完成后 | `[enemy: 敌人数据对象, x?: 战斗坐标X, y?: 战斗坐标Y]` | +| `changingFloor` | 楼层切换过程中(动画播放时) | `[floorId: 目标楼层ID, heroLoc: 玩家位置对象]` | +| `setBlock` | 地图图块被修改时 | `[x: 坐标X, y: 坐标Y, floorId: 楼层ID, newBlock: 新图块值, oldBlock: 旧图块值]` | +| `enemyExtract` | 解析敌人数据时 | `[col: 敌人集合对象]` | +| `restart` | 从游戏返回标题界面时 | 无 | +| `setBgFgBlock` | 设置背景/前景图块时 | `[name: 图层名称, number: 图块值, x: 坐标X, y: 坐标Y, floorId: 楼层ID]` | +| `replayStatus` | 录像播放状态切换时 | `[replaying: 是否正在回放]` | +| `loadData` | 加载存档时 | 无 | + +--- + +### 使用示例 + +```typescript +// 监听玩家移动事件 +hook.on('moveOneStep', (x, y, floorId) => { + console.log(x, y, floorId); +}); + +// 监听战斗结束事件 +hook.on('afterBattle', (enemy, x, y) => { + console.log(enemy, x, y); +}); + +// 监听存档加载事件 +hook.once('loadData', () => { + console.log('读档成功!'); +}); +``` + +--- + +## 弃用说明 + +```typescript +/** + * @deprecated 自 v2.B 起废弃的 GameListener + * 计划在 v2.C 移除,请使用新的 UI 交互系统代替 + */ +export const gameListener = new GameListener(); +``` diff --git a/docs/api/user-data-state/ObjectMoverBase.md b/docs/api/user-data-state/ObjectMoverBase.md new file mode 100644 index 0000000..09400bd --- /dev/null +++ b/docs/api/user-data-state/ObjectMoverBase.md @@ -0,0 +1,424 @@ +# ObjectMoverBase API 文档 + +本文档由 `DeepSeek R1` 模型生成并微调。 + +--- + +## 类描述 + +游戏中可移动对象的基类控制器,提供面向方向、移动队列管理和动画协调的通用移动能力。继承自 EventEmitter3,用于实现图块、角色等元素的移动控制。 + +```mermaid +graph LR + ObjectMoverBase --> EventEmitter + + click EventEmitter "https://nodejs.org/api/events.html#class-eventemitter" +``` + +--- + +## 核心属性 + +| 属性名 | 类型 | 说明 | +| ------------ | ----------------- | ------------------------ | +| `moveSpeed` | `number` | 当前移动速度(毫秒/格) | +| `moveDir` | `Dir2` | 当前移动方向(八方向) | +| `moving` | `boolean` | 是否处于移动状态 | +| `faceDir` | `Dir2` | 当前面朝方向(八方向) | +| `controller` | `IMoveController` | 当前移动控制实例(只读) | + +--- + +## 事件说明 + +| 事件名 | 参数 | 触发时机 | +| ----------- | ------------- | ------------------ | +| `stepEnd` | `MoveStepDir` | 单步移动完成时 | +| `moveEnd` | - | 整个移动队列完成时 | +| `moveStart` | `MoveStep[]` | 移动队列开始执行时 | + +--- + +## 方法说明 + +### `startMove` + +```typescript +function startMove(): IMoveController | null; +``` + +**功能** +启动移动队列执行 + +**返回值** +`IMoveController`:移动控制器实例(可追加指令) +`null`:队列为空或已在移动中时返回 + +**示例** + +```typescript +const controller = mover.startMove(); +if (controller) { + controller.push({ type: 'dir', value: 'right' }); +} +``` + +--- + +### `insertMove` + +```typescript +function insertMove(...move: MoveStep[]): void; +``` + +| 参数 | 类型 | 说明 | +| ------ | ------------ | ------------ | +| `move` | `MoveStep[]` | 移动指令序列 | + +**功能** +向队列末尾插入移动指令 + +**示例** + +```typescript +// 添加转向+加速指令 +mover.insertMove({ type: 'dir', value: 'left' }, { type: 'speed', value: 200 }); +``` + +--- + +### `clearMoveQueue` + +```typescript +function clearMoveQueue(): void; +``` + +**功能** +清空所有待执行移动指令 + +**注意** +不影响已开始的移动步骤 + +--- + +### `oneStep` + +```typescript +function oneStep(step: Move2): void; +``` + +| 参数 | 类型 | 说明 | +| ------ | ------- | --------------------------------- | +| `step` | `Move2` | 移动方向(支持八向/前后相对方向) | + +**功能** +添加单步方向移动指令 + +**示例** + +```typescript +// 添加面朝方向移动指令 +mover.oneStep('forward'); +``` + +--- + +### `moveAs` + +```typescript +function moveAs(steps: MoveStep[]): void; +``` + +| 参数 | 类型 | 说明 | +| ------- | ------------ | ------------------ | +| `steps` | `MoveStep[]` | 结构化移动指令序列 | + +**功能** +批量加载复杂移动路径 + +**示例** + +```typescript +mover.moveAs([ + { type: 'dir', value: 'up' }, // 向上移动 + { type: 'speed', value: 150 }, // 修改速度为每 150ms 移动一格 + { type: 'dir', value: 'rightup' } // 右上45度移动 +]); +``` + +--- + +### `setFaceDir` + +```typescript +function setFaceDir(dir: Dir2): void; +``` + +| 参数 | 类型 | 说明 | +| ----- | ------ | -------------- | +| `dir` | `Dir2` | 八方向面朝方向 | + +**限制** +仅在非移动状态生效 + +**示例** + +```typescript +// 设置角色面朝左上方 +mover.setFaceDir('leftup'); +``` + +--- + +### `setMoveDir` + +```typescript +function setMoveDir(dir: Dir2): void; +``` + +| 参数 | 类型 | 说明 | +| ----- | ------ | ------------ | +| `dir` | `Dir2` | 基础移动方向 | + +**注意** +影响`forward/backward`指令的实际方向 + +--- + +## 抽象方法 + +### `abstract onMoveStart` + +```typescript +function onMoveStart(controller: IMoveController): Promise; +``` + +**触发时机** +移动队列开始执行时 + +--- + +### `abstract onMoveEnd` + +```typescript +function onMoveEnd(controller: IMoveController): Promise; +``` + +**触发时机** +移动队列完成或被中断时 + +--- + +### `abstract onStepStart` + +```typescript +function onStepStart( + step: MoveStepDir, + controller: IMoveController +): Promise; +``` + +| 参数 | 类型 | 说明 | +| ------------ | ----------------- | ------------ | +| `step` | `MoveStepDir` | 当前移动步骤 | +| `controller` | `IMoveController` | 移动控制器 | + +**返回值** +`Promise`:步骤执行标识码(用于后续传递) + +--- + +### `abstract onStepEnd` + +```typescript +function onStepEnd( + step: MoveStepDir, + code: number, + controller: IMoveController +): Promise; +``` + +| 参数 | 类型 | 说明 | +| ------------ | ----------------- | -------------------------- | +| `code` | `number` | `onStepStart` 返回的标识码 | +| `controller` | `IMoveController` | 移动控制器 | + +--- + +### `abstract onSetMoveSpeed` + +```typescript +function onSetMoveSpeed(speed: number, controller: IMoveController): void; +``` + +| 参数 | 类型 | 说明 | +| ------------ | ----------------- | -------------- | +| `speed` | `number` | 新的移动速度值 | +| `controller` | `IMoveController` | 移动控制器 | + +--- + +## BlockMover + +`BlockMover` 是基于 `ObjectMoverBase` 的内置类,用于实现图块移动。 + +```mermaid +graph LR + BlockMover --> ObjectMoverBase + ObjectMoverBase --> EventEmitter + + click EventEmitter "https://nodejs.org/api/events.html#class-eventemitter" +``` + +### 新增方法 + +```typescript +function bind( + x: number, + y: number, + floorId: FloorIds, + layer: FloorLayer, + dir: Dir = 'down' +): boolean; +``` + +| 参数 | 类型 | 说明 | +| --------- | ------------ | -------------------- | +| `x` | `number` | 图块 X 坐标 | +| `y` | `number` | 图块 Y 坐标 | +| `floorId` | `FloorIds` | 所在楼层 ID | +| `layer` | `FloorLayer` | 图层类型(bg/fg 等) | +| `dir` | `Dir` | 初始方向 | + +**返回值**:绑定成功返回 `true`,若目标正在移动则返回 `false` + +**示例** + +```typescript +if (blockMover.bind(5, 8, 'floor1', 'bg', 'up')) { + blockMover.insertMove({ type: 'dir', value: 'right' }); +} +``` + +--- + +## HeroMover + +`HeroMover` 是基于 `ObjectMoverBase` 的内置类,用于实现勇士移动。 + +```mermaid +graph LR + HeroMover --> ObjectMoverBase + ObjectMoverBase --> EventEmitter + + click EventEmitter "https://nodejs.org/api/events.html#class-eventemitter" +``` + +### 覆盖方法 + +```ts +function startMove( + ignoreTerrain: boolean = false, + noRoute: boolean = false, + inLockControl: boolean = false, + autoSave: boolean = false +): IMoveController | null; +``` + +| 参数 | 说明 | +| --------------- | ---------------------------------------- | +| `ignoreTerrain` | 是否忽略地形,即是否穿墙 | +| `noRoute` | 是否不计入录像 | +| `inLockControl` | 是否是在锁定控制中移动的,例如事件中移动 | +| `autoSave` | 在必要时刻是否自动存档 | + +其余用法与基类相同。 + +--- + +## 使用示例 + +### 勇士移动控制 + +```typescript +import { heroMoverCollection } from '@user/data-state'; + +// 获取勇士移动控制器单例 +const heroMover = heroMoveCollection.mover; + +// 设置面朝方向为右侧 +heroMover.setFaceDir('right'); + +// 添加移动指令:前进三步 +heroMover.insertMove( + { type: 'dir', value: 'forward' }, + { type: 'dir', value: 'forward' }, + { type: 'dir', value: 'forward' } +); + +// 启动移动并获取控制器 +const controller = heroMover.startMove( + false, // 不允许穿墙 + true, // 不计入录像 + false, // 不在录像锁定中触发 + false // 不进行自动存档 +); + +if (controller) { + // 动态追加移动指令 + controller.push({ type: 'dir', value: 'leftup' }); + // 监听移动完成事件 + controller.onEnd.then(() => { + console.log('勇士移动完成'); + }); +} +``` + +### 图块移动控制 + +```typescript +import { BlockMover } from '@user/data-state'; + +// 创建图块移动器实例 +const blockMover = new BlockMover(); + +// 绑定到(5,8)位置的背景图块 +if (blockMover.bind(5, 8, 'floor1', 'bg', 'up')) { + // 添加螺旋移动路径 + blockMover.moveAs([ + { type: 'dir', value: 'right' }, + { type: 'dir', value: 'down' }, + { type: 'dir', value: 'left' }, + { type: 'dir', value: 'up' } + ]); + + // 设置移动速度为200像素/秒 + blockMover.insertMove({ type: 'speed', value: 200 }); + + // 启动移动 + const ctrl = blockMover.startMove(); +} +``` + +--- + +## 移动指令类型 + +```typescript +type MoveStep = + | { type: 'dir'; value: Move2 } // 方向指令 + | { type: 'speed'; value: number }; // 速度指令 +``` + +--- + +## 注意事项 + +1. **方向优先级** + `forward/backward` 基于当前面朝方向计算,修改 faceDir 会影响实际移动方向 + +2. **速度叠加规则** + 多个 speed 指令按队列顺序覆盖,最终生效最后一个速度值 + +3. **移动中断处理** + 调用 controller.stop() 会立即中断移动并触发 moveEnd 事件 diff --git a/docs/api/user-entry-data/Mota.md b/docs/api/user-entry-data/Mota.md new file mode 100644 index 0000000..ad02971 --- /dev/null +++ b/docs/api/user-entry-data/Mota.md @@ -0,0 +1,251 @@ +# Mota API 文档 + +本文档由 `DeepSeek R1` 模型生成并微调。 + +--- + +## 核心功能 + +模块化管理系统,提供跨进程模块注册与获取能力,支持数据端与渲染端分离架构。用于解决服务端录像验证与客户端渲染的模块隔离问题。 + +--- + +## 全局访问 + +```typescript +// 浏览器环境 +Mota.require('@motajs/client'); + +// ESM 环境 +import { Mota } from '@motajs/core'; +``` + +--- + +## 核心方法 + +### `require` + +```typescript +function require(key: K): ModuleInterface[K]; +function require(key: string): T; +``` + +**功能** +获取已注册的模块实例 + +| 参数 | 类型 | 说明 | +| ----- | -------- | -------------------------- | +| `key` | `string` | 模块标识符或自定义命名空间 | + +**返回值** +对应模块的导出对象 + +**预定义模块列表**: + +```typescript +interface ModuleInterface { + // ---------- 样板库 + '@motajs/client': typeof Client; + '@motajs/client-base': typeof ClientBase; + '@motajs/common': typeof Common; + '@motajs/legacy-client': typeof LegacyClient; + '@motajs/legacy-common': typeof LegacyCommon; + '@motajs/legacy-system': typeof LegacySystem; + '@motajs/legacy-ui': typeof LegacyUI; + '@motajs/render': typeof Render; + '@motajs/render-core': typeof RenderCore; + '@motajs/render-elements': typeof RenderElements; + '@motajs/render-style': typeof RenderStyle; + '@motajs/render-vue': typeof RenderVue; + '@motajs/system': typeof System; + '@motajs/system-action': typeof SystemAction; + '@motajs/system-ui': typeof SystemUI; + // ---------- 用户扩展 + '@user/client-modules': typeof ClientModules; + '@user/data-base': typeof DataBase; + '@user/data-fallback': typeof DataFallback; + '@user/data-state': typeof DataState; + '@user/data-utils': typeof DataUtils; + '@user/legacy-plugin-client': typeof LegacyPluginClient; + '@user/legacy-plugin-data': typeof LegacyPluginData; + // ---------- 必要的第三方库 + MutateAnimate: typeof MutateAnimate; + Vue: typeof Vue; + Lodash: typeof Lodash; +} +``` + +**示例**: + +```typescript +// 获取动画引擎 +const Animate = Mota.require('MutateAnimate'); + +// 获取Vue实例 +const Vue = Mota.require('Vue'); + +// 获取旧版UI系统 +const LegacyUI = Mota.require('@motajs/legacy-ui'); +``` + +--- + +### `register` + +```typescript +function register( + key: K, + data: ModuleInterface[K] +): void; +function register(key: string, data: unknown): void; +``` + +**功能** +注册模块到全局系统 + +| 参数 | 类型 | 说明 | +| ------ | -------- | ------------ | +| `key` | `string` | 模块标识符 | +| `data` | `any` | 模块导出对象 | + +**注意事项** + +- 重复注册会触发控制台警告 +- 推荐在游戏初始化阶段注册 + +**示例**: + +```typescript +// 注册自定义模块 +class MyCustomModule { + static version = '1.0.0'; +} +Mota.register('@user/custom-module', MyCustomModule); + +// 使用自定义模块 +const custom = Mota.require('@user/custom-module'); +console.log(custom.version); // 输出 1.0.0 +``` + +--- + +## 渲染进程控制 + +### `r` + +```typescript +function r(fn: (this: T) => void, thisArg?: T): void; +``` + +**功能** +包裹只在渲染进程执行的代码 + +| 参数 | 类型 | 说明 | +| --------- | ---------- | -------------------- | +| `fn` | `Function` | 需要渲染端执行的函数 | +| `thisArg` | `any` | 函数执行上下文 | + +**特性** + +- 在录像验证和服务端环境下不会执行 +- 无返回值设计 + +**示例**: + +```typescript +// 播放仅客户端可见的特效 +Mota.r(() => { + const animate = Mota.require('MutateAnimate'); + animate(heroSprite).shake(5, 1000); +}); +``` + +--- + +### `rf` + +```typescript +function rf any, T>( + fn: F, + thisArg?: T +): (...params: Parameters) => ReturnType | undefined; +``` + +**功能** +生成渲染进程安全函数 + +| 参数 | 类型 | 说明 | +| --------- | ---------- | ---------------- | +| `fn` | `Function` | 需要包装的原函数 | +| `thisArg` | `any` | 函数执行上下文 | + +**返回值** +经过安全包裹的函数,在非渲染环境调用返回 `undefined` + +**示例**: + +```typescript +// 创建安全渲染函数 +const safeAlert = Mota.rf((msg: string) => { + alert(`客户端提示: ${msg}`); +}); + +// 调用时自动判断执行环境 +safeAlert('仅在客户端显示'); // 服务端返回 undefined +``` + +--- + +## 架构示意图 + +```mermaid +graph TD + subgraph 数据端 + Validator[录像验证系统] + CoreLogic[核心逻辑] + end + + subgraph 渲染端 + UI[用户界面] + Effects[特效系统] + Render[渲染引擎] + end + + MotaSystem -->|require/register| Validator + MotaSystem -->|r/rf| Render + CoreLogic -->|跨进程通信| Effects +``` + +--- + +## 注意事项 + +1. **模块隔离** + 数据端模块与渲染端模块物理隔离,数据端不可直接引用渲染端,而渲染端是可以直接引用数据端的 + +2. **版本兼容** + 遗留系统模块(legacy-\*)将在未来版本逐步废弃,这些模块也不再提供 API 文档,如果需要自行阅读源码。 + +3. **性能优化** + 高频调用模块建议缓存引用: + + ```typescript + // 推荐 + const Animate = Mota.require('MutateAnimate'); + + // 不推荐 + function update() { + const Animate = Mota.require('MutateAnimate'); // 每次调用都查找 + } + ``` + +4. **错误处理** + 使用 try-catch 包裹高风险模块获取: + ```typescript + try { + const LegacyUI = Mota.require('@motajs/legacy-ui'); + } catch (e) { + fallbackUI(); + } + ``` diff --git a/packages-user/data-base/src/game.ts b/packages-user/data-base/src/game.ts index 14fa4dc..803a660 100644 --- a/packages-user/data-base/src/game.ts +++ b/packages-user/data-base/src/game.ts @@ -3,12 +3,19 @@ import { IDamageEnemy, IEnemyCollection } from '@motajs/types'; // ----- 加载事件 interface GameLoadEvent { + /** 当核心脚本加载完毕时触发 */ coreLoaded: []; + /** 当自动元件加载完毕后触发 */ autotileLoaded: []; + /** 当核心类初始化完毕后触发 */ coreInit: []; + /** 当所有启动必要资源加载完毕后触发 */ loaded: []; + /** 当客户端(渲染端)和数据端都挂载完毕后触发 */ registered: []; + /** 当数据端挂载完毕后触发 */ dataRegistered: []; + /** 当客户端(渲染端)挂载完毕后触发 */ clientRegistered: []; } @@ -36,8 +43,8 @@ class GameLoading extends EventEmitter { } /** - * 当自动原件加载完毕时 - * @param autotiles 自动原件数组 + * 当自动元件加载完毕时 + * @param autotiles 自动元件数组 */ onAutotileLoaded( autotiles: Partial, HTMLImageElement>> @@ -82,32 +89,32 @@ loading.once('dataRegistered', () => { }); export interface GameEvent { - /** Emitted in libs/events.js resetGame. */ + /** 当游戏初始化时触发,Emitted in libs/events.js resetGame. */ reset: []; - /** Emitted in src/App.vue setup. */ + /** 当游戏挂载完毕后触发,Emitted in src/App.vue setup. */ mounted: []; - /** Emitted in plugin/game/ui.ts updateStatusBar_update */ + /** 当状态栏更新时触发,Emitted in plugin/game/ui.ts updateStatusBar_update */ statusBarUpdate: []; - /** Emitted in core/index.ts */ + /** 当客户端(渲染端)加载完毕后触发,Emitted in core/index.ts */ renderLoaded: []; - /** Emitted in libs/events.js getItem */ + /** 当捡拾道具后触发,Emitted in libs/events.js getItem */ afterGetItem: [ itemId: AllIdsOf<'items'>, x: number, y: number, isGentleClick: boolean ]; - /** Emitted in libs/events.js _openDoor_animate */ + /** 当开门后触发,Emitted in libs/events.js _openDoor_animate */ afterOpenDoor: [doorId: AllIdsOf<'animates'>, x: number, y: number]; - /** Emitted in project/functions.js afterChangeFloor */ + /** 当楼层切换后触发,Emitted in project/functions.js afterChangeFloor */ afterChangeFloor: [floorId: FloorIds]; - /** Emitted in project/functions.js moveOneStep */ + /** 勇士每移动一步时触发,Emitted in project/functions.js moveOneStep */ moveOneStep: [x: number, y: number, floorId: FloorIds]; - /** Emitted in src/game/enemy/battle.ts afterBattle */ + /** 战斗后触发,Emitted in src/game/enemy/battle.ts afterBattle */ afterBattle: [enemy: IDamageEnemy, x?: number, y?: number]; - /** Emitted in libs/events.js changingFloor */ + /** 楼层切换中触发,具体时刻是楼层切换的正中间,刚刚执行完切换,Emitted in libs/events.js changingFloor */ changingFloor: [floorId: FloorIds, heroLoc: Loc]; - /** Emitted in libs/maps.js setBlock */ + /** 当某一个图块被设置时触发,Emitted in libs/maps.js setBlock */ setBlock: [ x: number, y: number, @@ -115,11 +122,11 @@ export interface GameEvent { newBlock: AllNumbers, oldBlock: AllNumbers ]; - /** Emitted in game/enemy/damage.ts */ + /** 当怪物信息被解析时触发,Emitted in game/enemy/damage.ts */ enemyExtract: [col: IEnemyCollection]; - /** Emitted in lib/events.js restart */ + /** 当从游戏中回到游戏标题界面时触发,Emitted in lib/events.js restart */ restart: []; - /** Emitted in lib/maps.js setBgFgBlock */ + /** 当设置背景或前景图块时触发,Emitted in lib/maps.js setBgFgBlock */ setBgFgBlock: [ name: 'bg' | 'fg' | 'bg2' | 'fg2', number: AllNumbers, @@ -127,9 +134,9 @@ export interface GameEvent { y: number, floorId: FloorIds ]; - /** Emitted in lib/control.js */ + /** 当录像播放在暂停和播放状态间切换时触发,Emitted in lib/control.js */ replayStatus: [replaying: boolean]; - /** Emitted in project/functions.js */ + /** 当加载存档时触发,Emitted in project/functions.js */ loadData: []; } @@ -248,6 +255,7 @@ class GameListener extends EventEmitter { } } +/** @deprecated */ export const gameListener = new GameListener(); declare global { diff --git a/packages-user/data-state/src/state/move.ts b/packages-user/data-state/src/state/move.ts index e45e7e1..ff0bbc1 100644 --- a/packages-user/data-state/src/state/move.ts +++ b/packages-user/data-state/src/state/move.ts @@ -15,6 +15,8 @@ import type { HeroKeyMover } from '@user/client-modules'; import { BluePalace, MiscData } from '../mechanism/misc'; import { sleep } from '@motajs/common'; +// todo: 转身功能 + interface MoveStepDir { type: 'dir'; value: Move2; diff --git a/packages-user/entry-client/src/create.ts b/packages-user/entry-client/src/create.ts index 06c6a03..27f63b0 100644 --- a/packages-user/entry-client/src/create.ts +++ b/packages-user/entry-client/src/create.ts @@ -18,6 +18,7 @@ import * as ClientModules from '@user/client-modules'; import * as LegacyPluginClient from '@user/legacy-plugin-client'; import * as MutateAnimate from 'mutate-animate'; import * as Vue from 'vue'; +import * as Lodash from 'lodash-es'; import { hook, loading } from '@user/data-base'; export function create() { @@ -42,6 +43,7 @@ export function create() { Mota.register('@user/legacy-plugin-client', LegacyPluginClient); Mota.register('MutateAnimate', MutateAnimate); Mota.register('Vue', Vue); + Mota.register('Lodash', Lodash); loading.emit('clientRegistered'); } diff --git a/packages-user/entry-data/src/mota.ts b/packages-user/entry-data/src/mota.ts index 72156d6..374faf5 100644 --- a/packages-user/entry-data/src/mota.ts +++ b/packages-user/entry-data/src/mota.ts @@ -23,6 +23,7 @@ import type * as LegacyPluginData from '@user/legacy-plugin-data'; // ---------- 必要的第三方库 import type * as MutateAnimate from 'mutate-animate'; import type * as Vue from 'vue'; +import type * as Lodash from 'lodash-es'; interface ModuleInterface { '@motajs/client': typeof Client; @@ -50,6 +51,7 @@ interface ModuleInterface { // ---------- 必要的第三方库 MutateAnimate: typeof MutateAnimate; Vue: typeof Vue; + Lodash: typeof Lodash; } export interface IMota {