//********************* // create by 流云 // time: Thu Oct 23 2025 // desc: 战斗暂停:继续 / 退出 / 重玩 //********************* import { _decorator, EventTouch, Layout, Node } from 'cc'; import { Auto_BattlePause } from './Auto_BattlePause'; import { UIID, GAudioPath } from '../../game/ConfigRes'; import { StatisticsType, StatusType } from '../../game/GameData'; import type { ProjectBattleHandle } from '../../battle/runtime/BattleRuntime'; import { WeaponDropView } from '../BattleGame/BattleWeaponDropPresenter'; const { ccclass } = _decorator; @ccclass('UIBattlePause') export class UIBattlePause extends Auto_BattlePause { /** 暂停列表当前展示的武器节点 */ private readonly _lootNodes: Node[] = []; /** 继续/退出已受理,防止连点重入 close + gameOver */ private _busy = false; onLoad(): void { super.onLoad(); } onEnable(): void { super.onEnable(); } onDisable(): void { this._recycleLoot(); super.onDisable(); } onInit(): void { if (this.ui_Self?.isValid) this.ui_Self.active = false; this._fillLoot(); } private _battle(): ProjectBattleHandle | null { return (gg.game.CurentBattle as ProjectBattleHandle | null) ?? null; } /** 点击空白:继续游戏(按钮需 stopPropagation,避免误触) */ click_ui_center(e?: EventTouch): void { const t = e?.target as { isChildOf?: (n: unknown) => boolean } | null; if (this._touchOnNode(t, this.btnExit)) return; if (this._touchOnNode(t, this.btnClose)) return; this._resumeBattle(); } /** 关闭暂停面板,继续游戏 */ click_btnClose(e?: EventTouch): void { (e as EventTouch & { stopPropagation?: () => void })?.stopPropagation?.(); this._resumeBattle(); } private _touchOnNode( target: { isChildOf?: (n: unknown) => boolean } | null | undefined, node: Node | null | undefined, ): boolean { return !!(target && node?.isValid && (target === node || target.isChildOf?.(node))); } private _resumeBattle(): void { if (this._busy) return; this._busy = true; const battle = this._battle(); if (battle) { gg.sdk.reportDY( 'inLevel', `${gg.game.getReportDYBattleCountLabel(battle.CurentWaveNum)}-继续游戏`, ); } this.close(2); } /** 退出战斗 → 回大厅/副本。vivo 先展示退出浮层 */ click_btnExit(e?: EventTouch): void { (e as EventTouch & { stopPropagation?: () => void })?.stopPropagation?.(); if (this._busy) return; this._busy = true; gg.sdk.showVivoExitAd(this._leaveBattle); } /** 退出浮层结束后结算失败并回大厅 */ private _leaveBattle = (): void => { const battle = this._battle(); if (!battle) { gg.game.enterMain(UIID.Home); return; } const levelId = battle.LevelConfigId; const waveNum = battle.CurentWaveNum; gg.sdk.reportDY('inLevel', `${gg.game.getReportDYBattleCountLabel(waveNum)}-退出游戏`); const reportLevelId = gg.sdk.get30rLevelId(); gg.sdk.report30r('LEVEL_EXIT', { level_id: reportLevelId, stage_type: gg.sdk.get30rStageType(), ad_cnt: gg.sdk.get30rAdCount(), action_param: reportLevelId, }); if ( waveNum >= 3 && levelId === gg.data.doc.rankId ) { gg.data.setStatistics(StatisticsType.SuccessContinuousCount, 0); } gg.data.project.addFailCount(levelId); void this.close(2).then(() => { battle.gameOver(false); if (!gg.ui.hasPopPanelActiveOrQueued(UIID.BattleFail)) { gg.ui.popPanel(UIID.BattleFail); } }); } click_btnContinue(): void { this._resumeBattle(); } /** 刷新 ui_list 统一战利品列表(敌方奖励显示角标) */ private _fillLoot(): void { this._recycleLoot(); const battle = this._battle(); const drops = battle?.weaponDrop.allDrops ?? []; const list = this.ui_OtherList; const emptyLb = this.lb_notHaveOther; if (emptyLb?.node?.isValid) emptyLb.node.active = drops.length <= 0; if (this.ui_list?.isValid) this.ui_list.active = true; if (!list?.isValid) return; list.active = drops.length > 0; const layout = list.getComponent(Layout); if (layout) layout.resizeMode = Layout.ResizeMode.CONTAINER; for (let i = 0; i < drops.length; i++) { const rec = drops[i]; const node = WeaponDropView.takePauseListPrefab(); if (!node) continue; list.addChild(node); node.setScale(1, 1, 1); node.angle = 0; WeaponDropView.applyPauseListVisual(node, rec); const view = node.getComponent(WeaponDropView) ?? node.addComponent(WeaponDropView); view.playDisplay(); WeaponDropView.applySideMark(node, rec.isSelf); this._lootNodes.push(node); } layout?.updateLayout(); } /** 回收暂停列表武器节点 */ private _recycleLoot(): void { for (let i = 0; i < this._lootNodes.length; i++) { const node = this._lootNodes[i]; if (!node?.isValid) continue; node.getComponent(WeaponDropView)?.resetMotion(); gg.res.putNode(node); } this._lootNodes.length = 0; } }