diff --git a/packages-user/data-state/src/core.ts b/packages-user/data-state/src/core.ts index 66e9b70..9f605fd 100644 --- a/packages-user/data-state/src/core.ts +++ b/packages-user/data-state/src/core.ts @@ -20,7 +20,8 @@ import { IItemStore, ItemStore, IMapStore, - MapStore + MapStore, + IReplaySystem } from '@user/data-common'; import { EnemyManager, @@ -42,8 +43,11 @@ import { GameEventSystem, IEnemyContext, IGameEventSystem, - MapDamage + MapDamage, + IPathfindingSystem, + PathfindingSystem } from '@user/data-system'; +import { ReplaySystem } from '../../data-common/src/replay/system'; import { CommonAuraConverter, GuardAuraConverter, @@ -73,6 +77,7 @@ import { isNil } from 'lodash-es'; import { DirectionMapper, IDirectionMapper, logger } from '@motajs/common'; import { DefaultHeroMoveTopImpl } from './hero'; import { createEventBuiltinRegistrations } from './event'; +import { createReplayCommandItems, registerReplayCommandItems } from './replay'; export class CoreState implements ICoreState { // Layer 0 公共层,最底层的接口,不会依赖任何其他内容,一般是工具性接口及不需要存档的数据 @@ -94,6 +99,10 @@ export class CoreState implements ICoreState { // Layer 2 执行层,游戏逻辑对象都在这,包括一些需要操作数据层的逻辑系统等 readonly enemyContext: IEnemyContext; readonly eventSystem: IGameEventSystem; + /** 已绑定勇士移动器的寻路系统 */ + readonly pathfinding: IPathfindingSystem; + /** 当前 CoreState 独立拥有的录像系统 */ + readonly replaySystem: IReplaySystem; // Layer 3 用户层,也就是最顶层的内容,一般仅用于初始化以及仅供渲染端调用的顶层模块 readonly loadProgress: ILoadProgressTotal; @@ -232,6 +241,17 @@ export class CoreState implements ICoreState { const heroMoveTopImpl = new DefaultHeroMoveTopImpl(this); this.hero.location.mover.useTopImplementation(heroMoveTopImpl); + const pathfinding = new PathfindingSystem(this); + pathfinding.useMover(this.hero.location.mover); + this.pathfinding = pathfinding; + + const replaySystem = new ReplaySystem(); + registerReplayCommandItems( + replaySystem, + createReplayCommandItems(this) + ); + this.replaySystem = replaySystem; + //#endregion } diff --git a/packages-user/data-state/src/index.ts b/packages-user/data-state/src/index.ts index 54b0d76..eb2c5f6 100644 --- a/packages-user/data-state/src/index.ts +++ b/packages-user/data-state/src/index.ts @@ -1,6 +1,7 @@ export * from './enemy'; export * from './event'; export * from './hero'; +export * from './replay'; export * from './core'; export * from './ins'; diff --git a/packages-user/data-state/src/replay/commands.test.ts b/packages-user/data-state/src/replay/commands.test.ts index 9239796..88864a7 100644 --- a/packages-user/data-state/src/replay/commands.test.ts +++ b/packages-user/data-state/src/replay/commands.test.ts @@ -67,6 +67,35 @@ describe('replay commands', () => { ).toThrow('Duplicate replay command code'); }); + // 验证每个 CoreState 都独立装配八个稳定 command 与寻路访问边界 + it('assembles an independent top-level registry for every CoreState', () => { + const first = createCoreState(); + const second = createCoreState(); + expect(first.replaySystem).not.toBe(second.replaySystem); + expect(first.pathfinding).not.toBe(second.pathfinding); + expect( + REPLAY_COMMAND_ORDER.map(code => + first.replaySystem.getCommand(code) + ).length + ).toBe(8); + expect( + REPLAY_COMMAND_ORDER.map(code => + second.replaySystem.getCommand(code) + ).length + ).toBe(8); + expect( + REPLAY_COMMAND_ORDER.every( + code => first.replaySystem.getCommand(code) !== null + ) + ).toBe(true); + expect( + REPLAY_COMMAND_ORDER.every( + code => second.replaySystem.getCommand(code) !== null + ) + ).toBe(true); + expect(first.replaySystem.route).not.toBe(second.replaySystem.route); + }); + // 验证四向移动在 controller.onEnd 兑现前不会完成 command it('awaits a directional movement controller', async () => { const state = createCoreState();