import { calcMonsterHpBaseByBattleTime } from '../battle/config/MonsterHpCalculator'; import { TableNames } from '../game/ConfigTableData'; /** * Monster.type(与 AutoTable / Monster.json 对齐) * 1 小怪 · 2 BOSS · 3 召唤怪物 */ export enum MonsterType { /** 小怪 */ SmallMonster = 1, /** BOSS */ Boss = 2, /** 召唤怪物 */ SummonMonster = 3, /** @deprecated 新表无中期 Boss;数值同 Boss,旧分支兼容 */ MidBoss = 2, /** @deprecated 新表无 */ SilverBoss = 4, /** @deprecated 新表无 */ GoldenBoss = 5, /** @deprecated 新表无 */ OrangeBoss = 6, /** @deprecated 新表无 */ ZombieFactory = 7, /** @deprecated 新表无 */ TreasureBox = 8, } /** icon「小怪金」→ 行进「金小怪」 */ const ELEMENT_MARCH_BY_ICON: Readonly> = { 小怪金: '金小怪', 小怪木: '木小怪', 小怪水: '水小怪', 小怪火: '火小怪', 小怪土: '土小怪', }; /** 新 Boss 预制体 icon(仅 default 皮,行进=走路;兼容表写 BOSS金 / 资源 Boss金) */ const NEW_BOSS_ICONS: Readonly> = { Boss金: true, Boss木: true, Boss水: true, Boss火: true, Boss土: true, BOSS金: true, BOSS木: true, BOSS水: true, BOSS火: true, BOSS土: true, }; /** 怪物表数据管理 */ export class MonsterDataManager { /** 获取怪物配表列表 */ public static getAllMonsterList1() { return gg.data.table.getTableList(TableNames.Monster); } /** * 通过怪物 id 获取配表 * @param id 怪物 id */ public static getMonsterDataById(id: number) { const allList = this.getAllMonsterList1(); return allList.find((x) => x.id === id); } /** * 是否五行新小怪/召唤(icon 为小怪金…土;不设皮肤;行进/死亡用系小怪轨)。 * 含 type=3 召唤(如木 Boss 招出的 10004),勿按旧多皮走「走路/小怪木2」。 * @param row Monster 行 */ static isElementSmallMonster(row: ITableMonster | null | undefined): boolean { if (!row) return false; const t = Math.floor(Number(row.type)); if (t !== MonsterType.SmallMonster && t !== MonsterType.SummonMonster) return false; const icon = String(row.icon ?? '').trim(); return !!ELEMENT_MARCH_BY_ICON[icon]; } /** * 是否新 Boss(不设皮肤、不区分阵营;行进=走路)。 * @param row Monster 行 */ static isNewElementBoss(row: ITableMonster | null | undefined): boolean { if (!row || !this.isBossType(row.type)) return false; const icon = String(row.icon ?? '').trim(); return !!NEW_BOSS_ICONS[icon]; } /** * 本项目全部怪物仅 default 皮,永不 setSkin、不区分阵营。 * @param _row Monster 行(保留签名供调用方) */ static skipsBattleSpineSkin(_row: ITableMonster | null | undefined): boolean { return true; } /** * 行进动画名。五行小怪=`{系}小怪`;新 Boss=`走路`;其它=`走路`。 * @param row Monster 行 */ static resolveMarchAnim(row: ITableMonster | null | undefined): string { if (!row) { console.error('[MonsterDataManager] resolveMarchAnim 无配表'); return ''; } if (this.isElementSmallMonster(row)) { const icon = String(row.icon ?? '').trim(); const anim = ELEMENT_MARCH_BY_ICON[icon]; if (!anim) { console.error('[MonsterDataManager] 五行小怪 icon 无法映射行进动画', row.id, icon); return ''; } return anim; } return '走路'; } /** * 死亡动画名。五行小怪=`{系}小怪2`;无契约轨返回空(走外部死亡特效)。 * @param row Monster 行 */ static resolveDeathAnim(row: ITableMonster | null | undefined): string { if (!row) { console.error('[MonsterDataManager] resolveDeathAnim 无配表'); return ''; } if (!this.isElementSmallMonster(row)) return ''; const march = this.resolveMarchAnim(row); if (!march) return ''; return `${march}2`; } /** * @deprecated 本项目怪物不设皮肤,恒返回空。 * @param _row Monster 行 * @param _enemyCamp 是否敌方出怪口 */ public static resolveBattleSpineSkin(_row: ITableMonster, _enemyCamp: boolean): string { return ''; } /** * 可被吞噬的小兵:小怪或召唤物,不含 Boss。 * @param monsterId Monster.id */ static isDevourMinion(monsterId: number): boolean { const row = this.getMonsterDataById(monsterId); if (!row) return false; return row.type === MonsterType.SmallMonster || row.type === MonsterType.SummonMonster; } /** * 是否为 Boss 类型(含旧表银/金/橙 Boss)。 * @param type Monster.type */ static isBossType(type: number): boolean { return type === MonsterType.Boss || type === MonsterType.SilverBoss || type === MonsterType.GoldenBoss || type === MonsterType.OrangeBoss; } /** * 通过难度和时间和战力获取怪物血量 * @param diff 难度 * @param time 时间 * @param power 战力 * @param powerPara 战力参数(玩家战力 >= 推荐) * @param powerPara2 战力参数(玩家战力 < 推荐) */ public static getMonsterHpByDiffAndTime( diff: number, time: number, power: number, powerPara: number, powerPara2: number = 0, ) { return calcMonsterHpBaseByBattleTime(diff, time, power, powerPara, powerPara2); } }