Files
heros/assets/script/game/map/RogueConfig.ts

460 lines
14 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* 肉鸽模式配置脚本
*
* 功能说明:
* - 提供肉鸽模式的波次生成配置
* - 包含词条系统和怪物强化逻辑
* - 供 MissionMonComp.ts 等组件调用
*
* 波次规则:
* - 固定波次5(商店)、10(Boss)、15(休息)、20(Boss)、25(商店)、30(Boss)
* - 精英波次个位数是4和9的波次(4、9、14、19、24、29...)
* - 普通波次:其他所有波次
*
* @author 游戏开发团队
* @version 1.0
* @date 2025-07-12
*/
// 导入配置
import { HQuality, HeroInfo, MonsterSeriesConfig, getRandomSeries } from "../common/config/heroSet";
import { BuffAttr } from "../common/config/SkillSet";
// ==================== 核心配置 ====================
/**
* 肉鸽模式波次类型枚举
*/
export enum RogueWaveType {
NORMAL = "normal",
ELITE = "elite",
BOSS = "boss",
SHOP = "shop",
REST = "rest"
}
/**
* 怪物词条配置直接使用BuffAttr作为词条类型
* 这样可以直接复用Mon.ts中的Buff处理逻辑
*/
export const MonsterAffixConfig = {
[BuffAttr.ATK]: {
name: "狂暴",
description: "攻击力提升50%",
value: 50,
rarity: "common",
applicableQualities: [HQuality.GREEN, HQuality.BLUE, HQuality.PURPLE]
},
[BuffAttr.ATK_CD]: {
name: "迅捷",
description: "攻击速度提升30%",
value: 30, // 正值表示提升Mon.ts中会转换为负值
rarity: "common",
applicableQualities: [HQuality.GREEN, HQuality.BLUE]
},
[BuffAttr.CRITICAL]: {
name: "致命",
description: "暴击率提升25%",
value: 25,
rarity: "uncommon",
applicableQualities: [HQuality.BLUE, HQuality.PURPLE]
},
[BuffAttr.DEF]: {
name: "装甲",
description: "减少受到的伤害30%",
value: 30,
rarity: "common",
applicableQualities: [HQuality.GREEN, HQuality.BLUE, HQuality.PURPLE]
},
[BuffAttr.HP]: {
name: "坚韧",
description: "生命值提升50%",
value: 50,
rarity: "common",
applicableQualities: [HQuality.GREEN, HQuality.BLUE, HQuality.PURPLE]
},
[BuffAttr.CRITICAL_DMG]: {
name: "嗜血",
description: "暴击伤害提升40%",
value: 40,
rarity: "uncommon",
applicableQualities: [HQuality.BLUE, HQuality.PURPLE]
},
[BuffAttr.DODGE]: {
name: "敏捷",
description: "闪避率提升25%",
value: 25,
rarity: "uncommon",
applicableQualities: [HQuality.GREEN, HQuality.BLUE]
},
[BuffAttr.BURN_COUNT]: {
name: "燃烧",
description: "攻击附带易伤效果额外持续3次",
value: 3,
rarity: "uncommon",
applicableQualities: [HQuality.GREEN, HQuality.BLUE, HQuality.PURPLE]
},
[BuffAttr.PUNCTURE]: {
name: "穿刺",
description: "攻击穿透1个敌人",
value: 1,
rarity: "uncommon",
applicableQualities: [HQuality.BLUE, HQuality.PURPLE]
},
[BuffAttr.FROST_RATIO]: {
name: "冰冻",
description: "攻击有20%概率冰冻敌人",
value: 20,
rarity: "rare",
applicableQualities: [HQuality.BLUE, HQuality.PURPLE]
}
};
/**
* 词条数量配置
*/
export const AffixCountConfig = {
currentMode: "normal" as "normal" | "enhanced",
modes: {
normal: {
[RogueWaveType.NORMAL]: 0,
[RogueWaveType.ELITE]: 1,
[RogueWaveType.BOSS]: 2,
},
enhanced: {
[RogueWaveType.NORMAL]: 1,
[RogueWaveType.ELITE]: 2,
[RogueWaveType.BOSS]: 3,
}
},
setMode(mode: "normal" | "enhanced") {
this.currentMode = mode;
},
getAffixCount(waveType: RogueWaveType): number {
return this.modes[this.currentMode][waveType] || 0;
},
enableNormalMode() {
this.setMode("normal");
},
enableEnhancedMode() {
this.setMode("enhanced");
}
};
/**
* 波次配置
*/
export const RogueWaveConfig = {
fixedWaves: {
5: RogueWaveType.SHOP,
10: RogueWaveType.BOSS,
15: RogueWaveType.REST,
20: RogueWaveType.BOSS,
25: RogueWaveType.SHOP,
30: RogueWaveType.BOSS
},
isEliteWave: (waveNumber: number): boolean => {
const lastDigit = waveNumber % 10;
return lastDigit === 4 || lastDigit === 9;
}
};
// ==================== 肉鸽配置生成器 ====================
/**
* 肉鸽配置生成器
*/
export class RogueConfig {
/**
* 生成波次配置(主入口)
*/
static generateWaveConfig(waveNumber: number) {
let waveType: RogueWaveType;
// 判断波次类型
if (RogueWaveConfig.fixedWaves[waveNumber]) {
waveType = RogueWaveConfig.fixedWaves[waveNumber];
} else if (RogueWaveConfig.isEliteWave(waveNumber)) {
waveType = RogueWaveType.ELITE;
} else {
waveType = RogueWaveType.NORMAL;
}
console.log(`[RogueConfig]: 第${waveNumber}波 - 类型: ${waveType}`);
// 根据类型生成配置
switch (waveType) {
case RogueWaveType.NORMAL:
return this.generateNormalWave(waveNumber);
case RogueWaveType.ELITE:
return this.generateEliteWave(waveNumber);
case RogueWaveType.BOSS:
return this.generateBossWave(waveNumber);
case RogueWaveType.SHOP:
return this.generateShopWave(waveNumber);
case RogueWaveType.REST:
return this.generateRestWave(waveNumber);
default:
return this.generateNormalWave(waveNumber);
}
}
/**
* 生成普通波次
*/
static generateNormalWave(waveNumber: number) {
const series = getRandomSeries();
const seriesConfig = MonsterSeriesConfig[series];
// 数量提升为原来的3倍最大数量也提升
const baseCount = Math.min((3 + Math.floor(waveNumber / 5)) * 3, 24);
const monsters = [];
// 选择怪物类型
const availableTypes = [];
if (seriesConfig.monsters.warrior.length > 0) availableTypes.push("warrior");
if (seriesConfig.monsters.remote.length > 0) availableTypes.push("remote");
if (seriesConfig.monsters.mage.length > 0) availableTypes.push("mage");
if (availableTypes.length > 0) {
const randomType = availableTypes[Math.floor(Math.random() * availableTypes.length)];
const typeMonsters = seriesConfig.monsters[randomType];
const randomMonster = typeMonsters[Math.floor(Math.random() * typeMonsters.length)];
const monsterInfo = HeroInfo[randomMonster];
// 生成词条
const affixes = this.generateMonsterAffixes(
monsterInfo.quality,
waveNumber,
RogueWaveType.NORMAL
);
// 应用强化
const enhanced = this.applyAffixesToMonster(affixes, monsterInfo);
monsters.push({
uuid: randomMonster,
count: baseCount,
type: randomType,
series: series,
affixes: affixes,
enhancedStats: enhanced.stats,
buffData: enhanced.buffData
});
}
return {
waveType: RogueWaveType.NORMAL,
monsters: monsters,
description: `普通波次 - ${seriesConfig.name}`,
waveNumber: waveNumber
};
}
/**
* 生成精英波次
*/
static generateEliteWave(waveNumber: number) {
const series = getRandomSeries();
const seriesConfig = MonsterSeriesConfig[series];
// 查找精英怪物
const eliteMonsters = seriesConfig.allMonsters.filter(uuid => {
return HeroInfo[uuid] && HeroInfo[uuid].quality === HQuality.BLUE;
});
const monsters = [];
if (eliteMonsters.length > 0) {
const eliteMonster = eliteMonsters[Math.floor(Math.random() * eliteMonsters.length)];
// 数量提升为原来的3倍
const count = Math.max(1, Math.floor((2 + waveNumber / 8) * 3));
const monsterInfo = HeroInfo[eliteMonster];
// 生成精英词条
const affixes = this.generateMonsterAffixes(
monsterInfo.quality,
waveNumber,
RogueWaveType.ELITE
);
const enhanced = this.applyAffixesToMonster(affixes, monsterInfo);
monsters.push({
uuid: eliteMonster,
count: count,
type: "warrior",
series: series,
affixes: affixes,
enhancedStats: enhanced.stats,
buffData: enhanced.buffData
});
}
return {
waveType: RogueWaveType.ELITE,
monsters: monsters,
description: `精英波次 - ${seriesConfig.name}精锐`,
waveNumber: waveNumber
};
}
/**
* 生成Boss波次
*/
static generateBossWave(waveNumber: number) {
const series = getRandomSeries();
const seriesConfig = MonsterSeriesConfig[series];
// 查找Boss怪物
const bossMonsters = seriesConfig.allMonsters.filter(uuid => {
return HeroInfo[uuid] && HeroInfo[uuid].quality === HQuality.PURPLE;
});
const bossMonster = bossMonsters.length > 0 ?
bossMonsters[Math.floor(Math.random() * bossMonsters.length)] :
seriesConfig.allMonsters[Math.floor(Math.random() * seriesConfig.allMonsters.length)];
const bossInfo = HeroInfo[bossMonster];
// 生成Boss词条
const bossAffixes = this.generateMonsterAffixes(
bossInfo.quality,
waveNumber,
RogueWaveType.BOSS
);
const enhancedBoss = this.applyAffixesToMonster(bossAffixes, bossInfo);
// Boss数量提升为3倍一般Boss只刷1只这里最多刷3只
const monsters = [{
uuid: bossMonster,
count: 3,
type: "boss",
series: series,
isBoss: true,
affixes: bossAffixes,
enhancedStats: enhancedBoss.stats,
buffData: enhancedBoss.buffData
}];
return {
waveType: RogueWaveType.BOSS,
monsters: monsters,
description: `Boss战 - ${seriesConfig.name}首领`,
waveNumber: waveNumber
};
}
/**
* 生成商店波次
*/
static generateShopWave(waveNumber: number) {
return {
waveType: RogueWaveType.SHOP,
description: "商店波次",
waveNumber: waveNumber
};
}
/**
* 生成休息波次
*/
static generateRestWave(waveNumber: number) {
return {
waveType: RogueWaveType.REST,
description: "休息波次",
waveNumber: waveNumber
};
}
/**
* 生成怪物词条现在直接返回BuffAttr数组
*/
static generateMonsterAffixes(
monsterQuality: number,
waveNumber: number,
waveType: RogueWaveType
): BuffAttr[] {
const affixCount = AffixCountConfig.getAffixCount(waveType);
if (affixCount === 0) return [];
const availableAffixes = Object.keys(MonsterAffixConfig).filter(affixType => {
const buffAttr = parseInt(affixType) as BuffAttr;
const config = MonsterAffixConfig[buffAttr];
return config.applicableQualities.includes(monsterQuality);
}).map(key => parseInt(key) as BuffAttr);
const selectedAffixes: BuffAttr[] = [];
for (let i = 0; i < affixCount && availableAffixes.length > 0; i++) {
const randomIndex = Math.floor(Math.random() * availableAffixes.length);
const selectedAffix = availableAffixes[randomIndex];
selectedAffixes.push(selectedAffix);
availableAffixes.splice(randomIndex, 1);
}
return selectedAffixes;
}
/**
* 应用词条到怪物(简化版本,主要用于日志显示)
*/
static applyAffixesToMonster(affixes: BuffAttr[], baseStats: any) {
const modifiedStats = { ...baseStats };
const buffData = [];
for (const affix of affixes) {
const config = MonsterAffixConfig[affix];
if (config) {
buffData.push({
buff_type: affix,
value: config.value
});
// 预览属性变化实际应用在Mon.ts中
switch (affix) {
case BuffAttr.ATK:
// 攻击力提升幅度加大每波提升额外增加10%
modifiedStats.ap = Math.floor(modifiedStats.ap * (1 + config.value / 100 + baseStats.lv * 0.1));
break;
case BuffAttr.HP:
// 生命值提升幅度加大每波提升额外增加15%
modifiedStats.hp = Math.floor(modifiedStats.hp * (1 + config.value / 100 + baseStats.lv * 0.15));
break;
case BuffAttr.ATK_CD:
modifiedStats.cd = Math.max(0.1, modifiedStats.cd * (1 - config.value / 100));
break;
}
}
}
return {
stats: modifiedStats,
buffData: buffData, // 返回Buff数据格式与Mon.ts兼容
affixes: affixes
};
}
/**
* 获取怪物等级
*/
static getMonsterLevel(waveNumber: number): number {
return Math.max(1, Math.floor(waveNumber / 5) + 1);
}
}
// ==================== 导出接口 ====================
/**
* 外部调用接口 - 获取波次配置
*/
export const getRogueWaveConfig = (waveNumber: number) => {
return RogueConfig.generateWaveConfig(waveNumber);
};