You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
60 lines
2.5 KiB
60 lines
2.5 KiB
import type { World, EntityId } from 'db://assets/mx/module/ecs';
|
|
import { BattleEventFactory } from '../events/BattleEvents';
|
|
import type { BattleEventBus } from '../events/BattleEventBus';
|
|
import type { GridMap } from '../battlefield/GridMap';
|
|
import type { SpatialGrid } from '../battlefield/SpatialGrid';
|
|
import type { AbilitySystem } from './AbilitySystem';
|
|
|
|
/** 暂缓 kill 判定(还魂丹等:死亡特效播完再复活或真死) */
|
|
export type TryDeferEntityKillFn = (victim: EntityId, killer: EntityId, hpBeforeKill: number) => boolean;
|
|
|
|
/** 实体生命周期 */
|
|
export class LifecycleSystem {
|
|
private _tryDeferKill: TryDeferEntityKillFn | null = null;
|
|
|
|
constructor(
|
|
private readonly _world: World,
|
|
private readonly _grid: GridMap,
|
|
private readonly _spatial: SpatialGrid,
|
|
private readonly _events: BattleEventBus,
|
|
private readonly _abilities: AbilitySystem,
|
|
) {}
|
|
|
|
/** 注册暂缓 kill 回调(BattleSession.tryDeferEntityKill 桥接) */
|
|
setTryDeferKillPredicate(fn: TryDeferEntityKillFn | null): void {
|
|
this._tryDeferKill = fn;
|
|
}
|
|
|
|
/**
|
|
* @param victim 被击杀实体 ID
|
|
* @param killer 击杀者实体 ID
|
|
* @param hpBeforeKill 致死前血量(还魂丹等复活继承用)
|
|
* @param damageType 致死伤害类型
|
|
* @param fromPassiveResult 是否来自被动 result
|
|
*/
|
|
kill(victim: EntityId, killer: EntityId, hpBeforeKill = 0, damageType?: string, fromPassiveResult = false): void {
|
|
if (!this._world.isAlive(victim)) return;
|
|
if (this._tryDeferKill?.(victim, killer, hpBeforeKill)) return;
|
|
|
|
// 先解绑触发器,避免后续 fireEvent('OnKill') 仍把 victim 当作施法者
|
|
this._abilities.unbindEntity(victim);
|
|
|
|
this._grid.clearOccupant(victim);
|
|
this._spatial.removeEntity(victim);
|
|
|
|
// 立即派发:金币/飞桃需在 destroy 前读到 UnitMeta / 怪物节点
|
|
this._events.emit(BattleEventFactory.entityKilled(killer, victim, damageType, fromPassiveResult), true);
|
|
this._world.destroy(victim);
|
|
this._abilities.fireEvent('OnKill', { killer, victim });
|
|
}
|
|
|
|
/** 无击杀结算移除(复活回收上场怪等) */
|
|
despawn(entity: EntityId): void {
|
|
if (!this._world.isAlive(entity)) return;
|
|
this._abilities.unbindEntity(entity);
|
|
this._grid.clearOccupant(entity);
|
|
this._spatial.removeEntity(entity);
|
|
this._events.emit(BattleEventFactory.unitDespawned(entity), true);
|
|
this._world.destroy(entity);
|
|
}
|
|
}
|
|
|