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.
 
 
 
 
AdLike2048/assets/script/battle/combat/BattleBuffUnitAttackSpeedHo...

102 lines
3.8 KiB

import type { BattleSession } from 'db://assets/mx/module/battle';
import { AttributeComp, CombatComp } from 'db://assets/mx/module/battle/ecs/Components';
import type { EntityId } from 'db://assets/mx/module/ecs';
import { BattleBuffCarryStore } from '../../manager/battleBuff/BattleBuffCarryStore';
import { resolveCarriedUnitAttackSpeedBonusWan } from '../../manager/battleBuff/BattleBuffPassiveSkillUtil';
import type { ProjectBattleHandle } from '../runtime/BattleRuntime';
import { AI_PLAYER_ID } from '../ai/runtime/AiCampArea';
/** 被动攻击单位攻速 modifier 分组 */
const UNIT_ASPD_MOD_GROUP = 'battle_buff_unit_aspd';
/** 单玩家攻速 */
type PlayerAspd = {
/** playerId */
playerId: number;
/** 万分比 */
bonusWan: number;
};
/**
* 被动 functiontype=27 九天天鼓:携带方「我方单位」(己侧场上塔/神将)攻速 +万分比。
* 不是出征兵;出征兵见补元丹/云麾号角。
*/
export class BattleBuffUnitAttackSpeedHost {
private _battle: ProjectBattleHandle | null = null;
private readonly _bonuses: PlayerAspd[] = [];
/** 绑定本局并对已有攻击单位施加攻速加成 */
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;
for (let i = 0; i < this._bonuses.length; i++) {
const player = battle.getPlayer(this._bonuses[i].playerId);
if (!player) continue;
const deployed = player.deployedUnits;
for (let u = 0; u < deployed.length; u++) {
this.refreshEntity(battle.session, deployed[u], this._bonuses[i].playerId);
}
}
}
/** 解除绑定 */
unbind(): void {
this._battle = null;
this._bonuses.length = 0;
}
/**
* 塔部署/升级后补施加被动攻速。
* @param session 会话
* @param entityId 实体
* @param ownerPlayerId 塔归属;缺省用本机
*/
refreshEntity(session: BattleSession, entityId: EntityId, ownerPlayerId?: number): void {
if (this._bonuses.length <= 0) return;
const pid = ownerPlayerId != null
? Math.max(0, Math.floor(Number(ownerPlayerId) || 0))
: (this._battle?.localPlayerId ?? 0);
for (let i = 0; i < this._bonuses.length; i++) {
if (this._bonuses[i].playerId !== pid) continue;
this._applyModifier(session, entityId, this._bonuses[i].bonusWan, pid);
return;
}
}
private _pushBonus(playerId: number): void {
const adjust = resolveCarriedUnitAttackSpeedBonusWan(BattleBuffCarryStore.getPassives(playerId));
if (!adjust.active || adjust.bonusWan <= 0) return;
this._bonuses.push({ playerId, bonusWan: adjust.bonusWan });
}
private _applyModifier(session: BattleSession, entityId: EntityId, bonusWan: number, playerId: number): void {
const world = session.world;
if (!world.isAlive(entityId)) return;
if (!world.getComponent(entityId, CombatComp)) return;
if (!world.getComponent(entityId, AttributeComp)) {
world.addComponent(entityId, new AttributeComp());
}
session.attributes.addModifier(entityId, {
attr: 'aspd_add',
op: 'Add',
value: bonusWan,
source: `${UNIT_ASPD_MOD_GROUP}_${playerId}`,
group: UNIT_ASPD_MOD_GROUP,
});
}
}
let _host: BattleBuffUnitAttackSpeedHost | null = null;
/** 全局攻击单位攻速被动 Host(单局复用) */
export function getBattleBuffUnitAttackSpeedHost(): BattleBuffUnitAttackSpeedHost {
if (!_host) _host = new BattleBuffUnitAttackSpeedHost();
return _host;
}