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/ui/BattleGame/BattleGameBossIntroPresente...

96 lines
3.5 KiB

import {
BATTLE_EVENT_ALL,
BattleEventType,
EntityTag,
TagComp,
UnitMetaComp,
type BattleEvent,
type EntityId,
type UnitDefId,
} from 'db://assets/mx/module/battle';
import { parseLegacyMonsterId, parseMonsterUnitDefId } from '../../battle/config/MonsterHpCalculator';
import type { ProjectBattleHandle } from '../../battle/runtime/BattleRuntime';
import { UIID } from '../../game/ConfigRes';
import { MonsterDataManager, MonsterType } from '../../manager/MonsterDataManager';
import { BattleAudio } from '../../battle/audio/BattleAudio';
import type { BattleBossPanelData } from '../BattleBoss/UIBattleBoss';
/** Boss 出场弹窗:仅敌方波次 Boss;万神幡/营召唤等额外出怪不弹 */
export class BattleGameBossIntroPresenter {
private _battle: ProjectBattleHandle | null = null;
private _onEvent: ((e: BattleEvent) => void) | null = null;
/** 绑定战斗事件 */
bind(battle: ProjectBattleHandle): void {
this.unbind();
this._battle = battle;
this._onEvent = (e) => this._onBattleEvent(e);
battle.on(BATTLE_EVENT_ALL, this._onEvent);
}
/** 注销战斗事件 */
unbind(): void {
if (this._battle && this._onEvent) {
this._battle.off(BATTLE_EVENT_ALL, this._onEvent);
}
this._battle = null;
this._onEvent = null;
}
private _onBattleEvent(event: BattleEvent): void {
if (event.type !== BattleEventType.UnitSpawned) return;
this._tryShowBossIntro(event.spawnPort, event.unitDefId, event.entity);
}
/**
* 敌方出怪口波次 Boss 出场时打开 BattleBoss。
* @param spawnPort 出怪口
* @param unitDefId 单位定义 id
* @param entityId 实体 id
*/
private _tryShowBossIntro(spawnPort: number, unitDefId: UnitDefId, entityId: EntityId): void {
const battle = this._battle;
if (!battle) return;
if (!this._isEnemySpawnPort(spawnPort)) return;
// 万神幡 / 营 / 技能召唤:meta.glowShadow=true,只出怪不出征弹窗
const meta = battle.session.world.getComponent(entityId, UnitMetaComp);
if (meta?.glowShadow) return;
const parsed = parseMonsterUnitDefId(unitDefId);
const monsterId = parsed?.monsterId ?? parseLegacyMonsterId(unitDefId);
if (!(monsterId > 0)) {
console.log('[BattleGameBossIntro] unitDefId 无效', unitDefId);
return;
}
const row = MonsterDataManager.getMonsterDataById(monsterId);
if (!row) {
console.log('[BattleGameBossIntro] Monster 缺失', monsterId);
return;
}
const tags = battle.session.world.getComponent(entityId, TagComp);
const isBoss = row.type === MonsterType.Boss
|| !!tags?.tags.includes(EntityTag.Boss);
if (!isBoss) return;
if (gg.ui.hasPanel(UIID.BattleBoss)) {
console.log('[BattleGameBossIntro] BattleBoss 已打开,跳过', monsterId);
return;
}
BattleAudio.playBossIntro();
const data: BattleBossPanelData = { monsterId };
void gg.ui.openPanel(UIID.BattleBoss, { data });
}
/** 相对本机玩家的敌方出怪口(本机 id0→spawnPoint_1) */
private _isEnemySpawnPort(spawnPort: number): boolean {
const battle = this._battle;
if (!battle) return false;
const localId = battle.localPlayerId;
const enemyPort = localId === 0 ? 1 : 2;
return spawnPort === enemyPort;
}
}