refactor: hook & feat: 勇士属性更新接口

This commit is contained in:
unanmed 2026-09-30 15:44:29 +08:00
parent e48995a293
commit 7180649a64
8 changed files with 37 additions and 22 deletions

View File

@ -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 {

View File

@ -84,9 +84,7 @@ export class MapHeroRenderer implements IMapHeroRenderer {
) {
this.dir4 = faceManager.get<FaceDirection>(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,

View File

@ -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;

View File

@ -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<THero> implements IHeroAttribute<THero> {
export class HeroAttribute<THero>
extends Hookable<IHeroAttributeHooks<THero>>
implements IHeroAttribute<THero>
{
/** 当前的勇士基础属性 */
private attribute: THero;
/** 当前勇士属性修饰器 */
private readonly modifier: Map<keyof THero, IHeroModifier[]> = new Map();
/** 当前每个修饰器对应的属性名称 */
@ -24,15 +36,19 @@ export class HeroAttribute<THero> implements IHeroAttribute<THero> {
/** 当前勇士最终属性 */
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<IHeroAttributeHooks<THero>>
): IHookController<IHeroAttributeHooks<THero>> {
return new HookController(this, hook);
}
//#region 属性计算
/**
@ -70,6 +86,7 @@ export class HeroAttribute<THero> implements IHeroAttribute<THero> {
}
this.finalAttribute[name] = value;
this.forEachHook(hook => hook.onUpdateAttribute?.(name, value));
}
*catchCalculateProgress<K extends keyof THero>(name: K) {

View File

@ -92,7 +92,18 @@ export interface IHeroAttributeCloneOption {
cloneModifier: boolean;
}
export interface IReadonlyHeroAttribute<THero> {
export interface IHeroAttributeHooks<THero> extends IHookBase {
/**
* 当勇士的某个属性发生变化时触发
* @param name 属性名称
* @param value 属性值
*/
onUpdateAttribute?<K extends keyof THero>(name: K, value: THero[K]): void;
}
export interface IReadonlyHeroAttribute<THero> extends IHookable<
IHeroAttributeHooks<THero>
> {
/**
* 获取勇士的基础属性,即未经过任何 Buff 或装备等加成的属性
* @param name 属性名称

View File

@ -66,7 +66,6 @@ export class GameMap extends Hookable<IGameMapHooks> implements IGameMap {
});
const controller = layer.addHook(new StateMapLayerHook(this, layer));
this.layerHookMap.set(layer, controller);
controller.load();
this.aliasLayerMap.set(alias, layer);
return layer;
}

View File

@ -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<H extends IHookBase> implements IHookController<H> {
readonly hook: Partial<H>
) {}
load(): void {
this.hookable.loadHook(this.hook);
}
unload(): void {
this.hookable.removeHookByController(this);
}

View File

@ -53,11 +53,6 @@ export interface IHookController<H extends IHookBase = IHookBase> {
/** 控制器的钩子对象 */
readonly hook: Partial<H>;
/**
* 加载此控制器对应的钩子对象
*/
load(): void;
/**
* 卸载此控制器对应的钩子对象,之后此钩子将不会再被触发
*/