import { Prefab } from 'cc'; import { ResPakage } from 'db://assets/mx/module/res/ResourcesManager'; import { ResPkgName } from 'db://assets/mx/module/res/ResPkgName'; import { ChapterLevelBuilder } from '../battle/config/ChapterLevelBuilder'; import { appendBattleHeroDirLoads, appendBattleMonsterDirLoad, } from '../battle/res/BattleHeroResCollector'; /** 战斗分包名(与 GBundle 一致,避免 ConfigRes 循环依赖) */ const B = { BattleMap: 'battleMap', BattleGameMonster: 'battleGameMonster', BattleGame: 'battleGame', } as const; const PrefabPath = 'prefab/'; /** * 进局后静默补载项:有 name 则 load 单预制,否则 loadDir。 */ export interface BattleAfterEnterItem { /** 分包 */ bundle: string; /** 目录路径 */ path: string; /** 单预制名;缺省则整目录 */ name?: string; } /** * 按 Level 组装进战最小包;局内弹窗与长尾走静默补载。 */ export class ResPkgBuilder { /** * 进战阻塞包:地图/模板/首波怪物与英雄体技,不含弹窗与受击长尾。 * @param levelId 战场 Level id * @param _mapID 已废弃;地图预制体名由 Level.map 决定 */ static buildBattlePackage(levelId: number, _mapID: number = 0, _id2: number = 0): ResPakage { const mapPrefabName = ChapterLevelBuilder.resolveLevelMapPrefabName(levelId); const ress: ResPakage['ress'] = [ { name: mapPrefabName, bundle: B.BattleMap, path: 'prefab/地图/', type: Prefab }, { name: '出怪口', bundle: B.BattleMap, path: 'prefab/障碍物/', type: Prefab }, { name: 'levelUpText', bundle: B.BattleMap, path: 'prefab/障碍物/', type: Prefab }, { name: 'monsterTemplate', bundle: B.BattleGameMonster, path: PrefabPath, type: Prefab }, { name: 'textGrid', bundle: B.BattleGame, path: PrefabPath, type: Prefab }, /** 铲子(独立预制体,运行时池化挂 TextGrid) */ { name: '铲', bundle: B.BattleGame, path: PrefabPath, type: Prefab }, /** 开挖揭示宝箱(原格子锁) */ { name: '宝箱', bundle: B.BattleGame, path: PrefabPath, type: Prefab }, /** buff 表现由下方 appendBattleHeroDirLoads 整目录覆盖,此处不再逐条 */ /** 通用飘仙桃(coinFly) */ { name: 'coinFly', bundle: B.BattleGame, path: PrefabPath, type: Prefab }, { name: '营地血条', bundle: B.BattleGame, path: PrefabPath, type: Prefab }, { name: '怪跳出拖尾', bundle: B.BattleGame, path: PrefabPath, type: Prefab }, { name: 'battleText', bundle: B.BattleGame, path: PrefabPath, type: Prefab }, { name: 'canUpEff', bundle: B.BattleGame, path: PrefabPath, type: Prefab }, { name: 'trail1', bundle: B.BattleGame, path: PrefabPath, type: Prefab }, { name: 'trail2', bundle: B.BattleGame, path: PrefabPath, type: Prefab }, { name: 'trail3', bundle: B.BattleGame, path: PrefabPath, type: Prefab }, ]; ResPkgBuilder.pushBattlePrefab(ress, B.BattleGame, 'prefab/数字/', 'atkMonsterScore'); ResPkgBuilder.pushBattlePrefab(ress, B.BattleGame, 'prefab/数字/', 'critHurtScore'); ResPkgBuilder.pushBattlePrefab(ress, B.BattleGame, 'prefab/数字/', 'critHurtScoreZi'); ResPkgBuilder.pushBattlePrefab(ress, B.BattleGame, 'prefab/数字/', 'beatBackScore'); ResPkgBuilder.pushBattlePrefab(ress, B.BattleGame, 'prefab/数字/', 'rateDamageScore'); ResPkgBuilder.pushBattlePrefab(ress, B.BattleGame, PrefabPath, 'killEff'); for (const fx of ChapterLevelBuilder.collectLevelStatusFxPrefabs(levelId)) { ResPkgBuilder.pushBattlePrefab(ress, B.BattleGameMonster, PrefabPath, fx); } ResPkgBuilder.pushBattlePrefab(ress, B.BattleGameMonster, 'prefab/blood/', '小怪血条底'); ResPkgBuilder.pushBattlePrefab(ress, B.BattleGameMonster, 'prefab/blood/', 'BOSS血条底框'); ResPkgBuilder.pushBattlePrefab(ress, B.BattleGameMonster, 'prefab/blood/', 'MidBOSS血条框'); for (const blood of ChapterLevelBuilder.collectLevelBloodBarPrefabs(levelId)) { ResPkgBuilder.pushBattlePrefab(ress, B.BattleGameMonster, 'prefab/blood/', blood); } const resPkg: ResPakage = { name: ResPkgName.BattleRes, isReleaseable: true, ress, }; appendBattleMonsterDirLoad(resPkg); appendBattleHeroDirLoads(resPkg); return resPkg; } /** * 进 BattleGame 后静默 load 的长尾(不 addRef)。 * @param _levelId 关卡(预留按关扩展) */ static getBattleAfterEnterItems(_levelId: number): BattleAfterEnterItem[] { return [ { bundle: B.BattleGame, path: PrefabPath, name: '受击特效' }, { bundle: B.BattleGame, path: PrefabPath, name: '受击刀痕' }, { bundle: B.BattleGame, path: PrefabPath, name: '死亡' }, ]; } private static pushBattlePrefab(ress: ResPakage['ress'], bundle: string, path: string, name: unknown): void { if (typeof name !== 'string') return; const trimmed = name.trim(); if (!trimmed) return; for (let i = 0; i < ress.length; i++) { const row = ress[i]; if (row.name === trimmed && row.bundle === bundle && row.path === path) return; } ress.push({ name: trimmed, bundle, path, type: Prefab }); } }