diff --git a/packages-user/client-base/src/map/extension/door.ts b/packages-user/client-base/src/map/extension/door.ts index f8d36b3..84359ff 100644 --- a/packages-user/client-base/src/map/extension/door.ts +++ b/packages-user/client-base/src/map/extension/door.ts @@ -20,7 +20,6 @@ export class MapDoorRenderer implements IMapDoorRenderer { readonly layer: IMapLayer ) { this.controller = layer.addHook(new MapDoorHook(this)); - this.controller.load(); } setAnimateInterval(interval: number): void { diff --git a/packages-user/client-base/src/map/extension/hero.ts b/packages-user/client-base/src/map/extension/hero.ts index 5478cfd..091ea23 100644 --- a/packages-user/client-base/src/map/extension/hero.ts +++ b/packages-user/client-base/src/map/extension/hero.ts @@ -84,9 +84,7 @@ export class MapHeroRenderer implements IMapHeroRenderer { ) { this.dir4 = faceManager.get(FaceGroup.Dir4)!; this.locationController = hero.addHook(new MapHeroLocationHook(this)); - this.locationController.load(); this.moverController = hero.mover.addHook(new MapHeroMoverHook(this)); - this.moverController.load(); const moving = this.addHeroMoving(renderer, layer, hero); const heroEntity: IHeroRenderEntity = { block: moving, diff --git a/packages-user/client-base/src/map/renderer.ts b/packages-user/client-base/src/map/renderer.ts index 3ca00fe..e00e95d 100644 --- a/packages-user/client-base/src/map/renderer.ts +++ b/packages-user/client-base/src/map/renderer.ts @@ -432,7 +432,6 @@ export class MapRenderer if (this.layerHooks.has(layer)) continue; // prettier-ignore const controller = layer.addHook(new RendererLayerHook(this, layer)); - controller.load(); this.layerHooks.set(layer, controller); } } @@ -452,7 +451,6 @@ export class MapRenderer this.map = map; this.syncLayerHooks(); this.mapHook = map.addHook(new RendererLayerStateHook(this)); - this.mapHook.load(); this.sortLayer(); this.resizeLayer(); this.layerCount = map.layerList.size; diff --git a/packages-user/data-base/src/hero/attribute.ts b/packages-user/data-base/src/hero/attribute.ts index baa684d..cb189de 100644 --- a/packages-user/data-base/src/hero/attribute.ts +++ b/packages-user/data-base/src/hero/attribute.ts @@ -1,15 +1,27 @@ -import { logger } from '@motajs/common'; +import { + Hookable, + HookController, + IHookController, + logger +} from '@motajs/common'; import { SaveCompression, shouldReplay } from '@user/data-common'; import { IHeroAttribute, IHeroAttributeCloneOption, + IHeroAttributeHooks, IHeroAttributeSave, IHeroModifier, IModifierStateSave } from './types'; import { isNil } from 'lodash-es'; -export class HeroAttribute implements IHeroAttribute { +export class HeroAttribute + extends Hookable> + implements IHeroAttribute +{ + /** 当前的勇士基础属性 */ + private attribute: THero; + /** 当前勇士属性修饰器 */ private readonly modifier: Map = new Map(); /** 当前每个修饰器对应的属性名称 */ @@ -24,15 +36,19 @@ export class HeroAttribute implements IHeroAttribute { /** 当前勇士最终属性 */ private readonly finalAttribute: THero; - /** - * @param attribute 当前勇士的基础属性 - */ - constructor(private attribute: THero) { + constructor(attribute: THero) { + super(); // 克隆入参,避免调用方传入的共享基础属性对象被本实例改写 this.attribute = structuredClone(attribute); this.finalAttribute = structuredClone(attribute); } + protected createController( + hook: Partial> + ): IHookController> { + return new HookController(this, hook); + } + //#region 属性计算 /** @@ -70,6 +86,7 @@ export class HeroAttribute implements IHeroAttribute { } this.finalAttribute[name] = value; + this.forEachHook(hook => hook.onUpdateAttribute?.(name, value)); } *catchCalculateProgress(name: K) { diff --git a/packages-user/data-base/src/hero/types.ts b/packages-user/data-base/src/hero/types.ts index 9e64c84..883e53c 100644 --- a/packages-user/data-base/src/hero/types.ts +++ b/packages-user/data-base/src/hero/types.ts @@ -92,7 +92,18 @@ export interface IHeroAttributeCloneOption { cloneModifier: boolean; } -export interface IReadonlyHeroAttribute { +export interface IHeroAttributeHooks extends IHookBase { + /** + * 当勇士的某个属性发生变化时触发 + * @param name 属性名称 + * @param value 属性值 + */ + onUpdateAttribute?(name: K, value: THero[K]): void; +} + +export interface IReadonlyHeroAttribute extends IHookable< + IHeroAttributeHooks +> { /** * 获取勇士的基础属性,即未经过任何 Buff 或装备等加成的属性 * @param name 属性名称 diff --git a/packages-user/data-base/src/map/gameMap.ts b/packages-user/data-base/src/map/gameMap.ts index 418b151..2e5cc8e 100644 --- a/packages-user/data-base/src/map/gameMap.ts +++ b/packages-user/data-base/src/map/gameMap.ts @@ -66,7 +66,6 @@ export class GameMap extends Hookable implements IGameMap { }); const controller = layer.addHook(new StateMapLayerHook(this, layer)); this.layerHookMap.set(layer, controller); - controller.load(); this.aliasLayerMap.set(alias, layer); return layer; } diff --git a/packages/common/src/hook.ts b/packages/common/src/hook.ts index 195b1a4..9ee98b9 100644 --- a/packages/common/src/hook.ts +++ b/packages/common/src/hook.ts @@ -27,6 +27,8 @@ export abstract class Hookable< this.hookMap.set(hook, obj); this.controllerMap.set(controller, obj); this.hookList.add(obj); + hook.awake?.(obj.controller); + this.loadedList.add(obj); return controller; } @@ -75,10 +77,6 @@ export class HookController implements IHookController { readonly hook: Partial ) {} - load(): void { - this.hookable.loadHook(this.hook); - } - unload(): void { this.hookable.removeHookByController(this); } diff --git a/packages/common/src/types.ts b/packages/common/src/types.ts index aa400be..ad52bc8 100644 --- a/packages/common/src/types.ts +++ b/packages/common/src/types.ts @@ -53,11 +53,6 @@ export interface IHookController { /** 控制器的钩子对象 */ readonly hook: Partial; - /** - * 加载此控制器对应的钩子对象 - */ - load(): void; - /** * 卸载此控制器对应的钩子对象,之后此钩子将不会再被触发 */