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, } /** 怪物表数据管理 */ 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); } /** * 战斗 Spine 皮肤名(按出怪阵营) * - type1 小怪 / type3 召唤:己方口=`icon`,敌方口=`icon`+`2`(如 哮天犬 / 哮天犬2) * - type2 Boss:己方口=`皮肤字1_1`,敌方口=`皮肤字2_1`(资源无「皮肤字_」中间下划线) * @param row Monster 行 * @param enemyCamp 是否敌方出怪口放出的怪 */ public static resolveBattleSpineSkin(row: ITableMonster, enemyCamp: boolean): string { const icon = String(row.icon ?? '').trim(); if (row.type === MonsterType.SmallMonster || row.type === MonsterType.SummonMonster) { if (!icon) { console.log('[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.log('[MonsterDataManager] 怪物 icon 为空', row.id, row.type); return ''; } return icon; } /** * 营召唤怪物展示名:`res[营等级-1]`(1 级读第一项,2 级读第二项)。 * @param row Monster 行 * @param yingLevel 营字合成等级(1-based) */ public static resolveYingSummonDisplayName(row: ITableMonster, yingLevel: number): string { const entry = this._resolveYingSummonResEntry(row, yingLevel); return entry ? gg.lang.get(entry) : ''; } /** * 营召唤怪物 Spine 皮肤:`res[营等级-1]`,敌方阵营加后缀「2」。 * @param row Monster 行 * @param yingLevel 营字合成等级(1-based) * @param enemyCamp 是否敌方阵营出怪 */ public static resolveYingSummonSpineSkin(row: ITableMonster, yingLevel: number, enemyCamp: boolean): string { const base = this._resolveYingSummonResEntry(row, yingLevel); if (!base) return ''; return enemyCamp ? `${base}2` : base; } /** * 营等级对应 Monster.res 项(1 级→res[0])。 * @param row Monster 行 * @param yingLevel 营字合成等级(1-based) */ private static _resolveYingSummonResEntry(row: ITableMonster, yingLevel: number): string { const res = row.res; if (!res?.length) { console.log('[MonsterDataManager] 营召唤 res 为空', row.id); return ''; } const idx = Math.max(0, Math.floor(yingLevel) - 1); if (idx >= res.length) { console.log('[MonsterDataManager] 营等级超出 res 长度', row.id, yingLevel, res.length); return ''; } const base = String(res[idx] ?? '').trim(); if (!base) { console.log('[MonsterDataManager] 营召唤 res 项为空', row.id, idx); return ''; } return base; } /** * 可被吞噬的小兵:小怪或召唤物,不含 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); } }