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.
88 lines
3.2 KiB
88 lines
3.2 KiB
|
3 weeks ago
|
import type { EntityId } from 'db://assets/mx/module/ecs';
|
||
|
|
import {
|
||
|
|
BattleEventType,
|
||
|
|
type BattleEvent,
|
||
|
|
} from 'db://assets/mx/module/battle';
|
||
|
|
import { BattleBuffCarryStore } from '../../manager/battleBuff/BattleBuffCarryStore';
|
||
|
|
import { resolveMarchOwnerPlayerId } from '../../manager/battleBuff/BattleBuffSideResolve';
|
||
|
|
import { resolveCarriedUnitHpBonusWan } from '../../manager/battleBuff/BattleBuffPassiveSkillUtil';
|
||
|
|
import type { ProjectBattleHandle } from '../runtime/BattleRuntime';
|
||
|
|
import { SkillAtkBuffExecutor } from './SkillAtkBuffExecutor';
|
||
|
|
import { AI_PLAYER_ID } from '../ai/runtime/AiCampArea';
|
||
|
|
|
||
|
|
/** 单玩家血量加成 */
|
||
|
|
type PlayerHpBonus = {
|
||
|
|
/** playerId(出征方) */
|
||
|
|
playerId: number;
|
||
|
|
/** 万分比 */
|
||
|
|
bonusWan: number;
|
||
|
|
};
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 被动 functiontype=15 补元丹:携带方「出征兵」maxHp/hp ×(1+万分比/10000)。
|
||
|
|
* 出征兵 = 进攻对面基地的行军怪(本机视角常在对面半场),不是己侧场上单位。
|
||
|
|
*/
|
||
|
|
export class BattleBuffUnitHpHost {
|
||
|
|
private _battle: ProjectBattleHandle | null = null;
|
||
|
|
private readonly _bonuses: PlayerHpBonus[] = [];
|
||
|
|
private _onUnitSpawnedBound = false;
|
||
|
|
|
||
|
|
/** 绑定本局并监听出怪 */
|
||
|
|
bind(battle: ProjectBattleHandle): void {
|
||
|
|
this.unbind();
|
||
|
|
this._battle = battle;
|
||
|
|
this._bonuses.length = 0;
|
||
|
|
this._pushBonus(battle.localPlayerId);
|
||
|
|
this._pushBonus(AI_PLAYER_ID);
|
||
|
|
if (this._bonuses.length <= 0) return;
|
||
|
|
|
||
|
|
battle.session.events.on(BattleEventType.UnitSpawned, this._onUnitSpawned);
|
||
|
|
this._onUnitSpawnedBound = true;
|
||
|
|
battle.session.world.forEachAlive((entityId) => {
|
||
|
|
this._tryApply(entityId);
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
/** 解除绑定 */
|
||
|
|
unbind(): void {
|
||
|
|
const battle = this._battle;
|
||
|
|
if (battle && this._onUnitSpawnedBound) {
|
||
|
|
battle.session.events.off(BattleEventType.UnitSpawned, this._onUnitSpawned);
|
||
|
|
}
|
||
|
|
this._onUnitSpawnedBound = false;
|
||
|
|
this._battle = null;
|
||
|
|
this._bonuses.length = 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
private _pushBonus(playerId: number): void {
|
||
|
|
const adjust = resolveCarriedUnitHpBonusWan(BattleBuffCarryStore.getPassives(playerId));
|
||
|
|
if (!adjust.active || adjust.bonusWan <= 0) return;
|
||
|
|
this._bonuses.push({ playerId, bonusWan: adjust.bonusWan });
|
||
|
|
}
|
||
|
|
|
||
|
|
private _onUnitSpawned = (event: BattleEvent): void => {
|
||
|
|
if (event.type !== BattleEventType.UnitSpawned) return;
|
||
|
|
this._tryApply(event.entity);
|
||
|
|
};
|
||
|
|
|
||
|
|
private _tryApply(entityId: EntityId): void {
|
||
|
|
const battle = this._battle;
|
||
|
|
if (!battle || this._bonuses.length <= 0) return;
|
||
|
|
const ownerId = resolveMarchOwnerPlayerId(battle.session, entityId);
|
||
|
|
if (ownerId < 0) return;
|
||
|
|
for (let i = 0; i < this._bonuses.length; i++) {
|
||
|
|
if (this._bonuses[i].playerId !== ownerId) continue;
|
||
|
|
SkillAtkBuffExecutor.applyMaxHpCoeff(battle.session.world, entityId, this._bonuses[i].bonusWan, battle);
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
let _host: BattleBuffUnitHpHost | null = null;
|
||
|
|
|
||
|
|
/** 全局出征兵血量被动 Host(单局复用) */
|
||
|
|
export function getBattleBuffUnitHpHost(): BattleBuffUnitHpHost {
|
||
|
|
if (!_host) _host = new BattleBuffUnitHpHost();
|
||
|
|
return _host;
|
||
|
|
}
|