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 皮,行进=走路) */ const NEW_BOSS_ICONS: Readonly> = { 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); } /** * 是否五行新小怪(不设皮肤、不区分阵营;行进/死亡用系小怪轨)。 * @param row Monster 行 */ static isElementSmallMonster(row: ITableMonster | null | undefined): boolean { if (!row || row.type !== MonsterType.SmallMonster) 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]; } /** * 新怪表现:不 setSkin。 * @param row Monster 行 */ static skipsBattleSpineSkin(row: ITableMonster | null | undefined): boolean { return this.isElementSmallMonster(row) || this.isNewElementBoss(row); } /** * 行进动画名。五行小怪=`{系}小怪`;新 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 新五行怪不设皮肤;仅旧多皮资源(猴/哮天犬等)仍用。 * - type1 小怪 / type3 召唤:己方口=`icon`,敌方口=`icon`+`2` * - type2 Boss:己方口=`皮肤字1_1`,敌方口=`皮肤字2_1` * @param row Monster 行 * @param enemyCamp 是否敌方出怪口放出的怪 */ public static resolveBattleSpineSkin(row: ITableMonster, enemyCamp: boolean): string { if (this.skipsBattleSpineSkin(row)) { return ''; } const icon = String(row.icon ?? '').trim(); if (row.type === MonsterType.SmallMonster || row.type === MonsterType.SummonMonster) { if (!icon) { console.error('[MonsterDataManager] 怪物 icon 为空,无法定皮肤', row.id, row.type); return ''; } return enemyCamp ? `${icon}2` : icon; } if (row.type === MonsterType.Boss) { return enemyCamp ? '皮肤字2_1' : '皮肤字1_1'; } if (!icon) { console.error('[MonsterDataManager] 怪物 icon 为空', row.id, row.type); return ''; } return icon; } /** * 可被吞噬的小兵:小怪或召唤物,不含 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); } }