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.
96 lines
3.5 KiB
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;
|
|
}
|
|
}
|
|
|