地图修改

This commit is contained in:
2025-07-28 00:14:20 +08:00
parent 4bd2e5566a
commit 48eaa6d1ad
39 changed files with 6805 additions and 2484 deletions

View File

@@ -6,13 +6,14 @@
* - 包含词条系统和怪物强化逻辑
* - 供 MissionMonComp.ts 等组件调用
*
* 波次规则:
* - 固定波次5(商店)、10(Boss)、15(休息)、20(Boss)、25(商店)、30(Boss)
* - 精英波次个位数是4和9的波次(4、9、14、19、24、29...)
* - 普通波次:其他所有波次
* 波次规则固定9波模式
* - 1-3波普通波次
* - 4-6波怪物潮波次大量低级怪物
* - 7-8波精英波次
* - 9波最终Boss波次
*
* @author 游戏开发团队
* @version 1.0
* @version 2.0
* @date 2025-07-12
*/
@@ -26,13 +27,57 @@ import { BuffAttr } from "../common/config/SkillSet";
* 肉鸽模式波次类型枚举
*/
export enum RogueWaveType {
NORMAL = "normal",
ELITE = "elite",
BOSS = "boss",
SHOP = "shop",
REST = "rest"
NORMAL = "normal", // 普通波次1-3波
HORDE = "horde", // 怪物潮波次4-6波
ELITE = "elite", // 精英波次7-8波
FINAL_BOSS = "final_boss" // 最终Boss波次9波
}
/**
* 固定数值配置(根据波次固定血量和攻击力)
*/
export const RogueStatsConfig = {
// 血量配置
hp: {
1: 10, // 波次1小怪血量10
2: 15, // 波次2小怪血量15插值
3: 25, // 波次3小怪血量25
4: 35, // 波次4怪物潮血量35插值
5: 60, // 波次5怪物潮血量60
6: 80, // 波次6怪物潮血量80插值
7: 100, // 波次7精英血量100
8: 150, // 波次8精英血量150插值
9: 500 // 波次9boss血量500
},
// 攻击力配置
attack: {
1: 5, // 1-3波攻击力5
2: 5, // 1-3波攻击力5
3: 5, // 1-3波攻击力5
4: 8, // 4-6波攻击力8
5: 8, // 4-6波攻击力8
6: 8, // 4-6波攻击力8
7: 12, // 7-8波攻击力12
8: 12, // 7-8波攻击力12
9: 30 // 9波boss攻击力30
},
/**
* 获取指定波次的血量
*/
getHp(waveNumber: number): number {
return this.hp[waveNumber] || this.hp[9]; // 默认返回boss血量
},
/**
* 获取指定波次的攻击力
*/
getAttack(waveNumber: number): number {
return this.attack[waveNumber] || this.attack[9]; // 默认返回boss攻击力
}
};
/**
* 怪物词条配置直接使用BuffAttr作为词条类型
* 这样可以直接复用Mon.ts中的Buff处理逻辑
@@ -111,21 +156,23 @@ export const MonsterAffixConfig = {
};
/**
* 词条数量配置
* 词条数量配置9波固定模式
*/
export const AffixCountConfig = {
currentMode: "normal" as "normal" | "enhanced",
modes: {
normal: {
[RogueWaveType.NORMAL]: 0,
[RogueWaveType.ELITE]: 1,
[RogueWaveType.BOSS]: 2,
[RogueWaveType.NORMAL]: 0, // 1-3波无词条
[RogueWaveType.HORDE]: 0, // 4-6波无词条数量取胜
[RogueWaveType.ELITE]: 1, // 7-8波1个词条
[RogueWaveType.FINAL_BOSS]: 2, // 9波2个词条
},
enhanced: {
[RogueWaveType.NORMAL]: 1,
[RogueWaveType.ELITE]: 2,
[RogueWaveType.BOSS]: 3,
[RogueWaveType.NORMAL]: 1, // 1-3波1个词条
[RogueWaveType.HORDE]: 1, // 4-6波1个词条
[RogueWaveType.ELITE]: 2, // 7-8波2个词条
[RogueWaveType.FINAL_BOSS]: 3, // 9波3个词条
}
},
@@ -147,22 +194,27 @@ export const AffixCountConfig = {
};
/**
* 波次配置
* 波次配置固定9波模式
*/
export const RogueWaveConfig = {
fixedWaves: {
5: RogueWaveType.SHOP,
10: RogueWaveType.BOSS,
15: RogueWaveType.REST,
20: RogueWaveType.BOSS,
25: RogueWaveType.SHOP,
30: RogueWaveType.BOSS
// 固定9波模式每波类型固定
getWaveType: (waveNumber: number): RogueWaveType => {
if (waveNumber <= 3) {
return RogueWaveType.NORMAL; // 1-3波普通
} else if (waveNumber <= 6) {
return RogueWaveType.HORDE; // 4-6波怪物潮
} else if (waveNumber <= 8) {
return RogueWaveType.ELITE; // 7-8波精英
} else if (waveNumber === 9) {
return RogueWaveType.FINAL_BOSS; // 9波最终Boss
} else {
// 超过9波的情况如果需要循环
const cycleWave = ((waveNumber - 1) % 9) + 1;
return RogueWaveConfig.getWaveType(cycleWave);
}
},
isEliteWave: (waveNumber: number): boolean => {
const lastDigit = waveNumber % 10;
return lastDigit === 4 || lastDigit === 9;
}
maxWaves: 9 // 固定最大波数
};
// ==================== 肉鸽配置生成器 ====================
@@ -176,44 +228,35 @@ export class RogueConfig {
* 生成波次配置(主入口)
*/
static generateWaveConfig(waveNumber: number) {
let waveType: RogueWaveType;
const waveType = RogueWaveConfig.getWaveType(waveNumber);
const fixedHp = RogueStatsConfig.getHp(waveNumber);
const fixedAttack = RogueStatsConfig.getAttack(waveNumber);
// 判断波次类型
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}`);
console.log(`[RogueConfig]: 第${waveNumber}波 - 类型: ${waveType} - 固定HP: ${fixedHp}, 固定攻击: ${fixedAttack} (固定9波模式)`);
// 根据类型生成配置
switch (waveType) {
case RogueWaveType.NORMAL:
return this.generateNormalWave(waveNumber);
case RogueWaveType.HORDE:
return this.generateHordeWave(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);
case RogueWaveType.FINAL_BOSS:
return this.generateFinalBossWave(waveNumber);
default:
return this.generateNormalWave(waveNumber);
}
}
/**
* 生成普通波次
* 生成普通波次1-3波
*/
static generateNormalWave(waveNumber: number) {
const series = getRandomSeries();
const seriesConfig = MonsterSeriesConfig[series];
// 数量减少为原来的三分之一
const baseCount = Math.min(3 + Math.floor(waveNumber / 5), 8);
// 普通波次固定数量10个怪物
const baseCount = 10;
const monsters = [];
// 选择怪物类型
@@ -245,36 +288,125 @@ export class RogueConfig {
series: series,
affixes: affixes,
enhancedStats: enhanced.stats,
buffData: enhanced.buffData
buffData: enhanced.buffData,
// 肉鸽固定数值
rogueHp: RogueStatsConfig.getHp(waveNumber),
rogueAttack: RogueStatsConfig.getAttack(waveNumber)
});
}
return {
waveType: RogueWaveType.NORMAL,
monsters: monsters,
description: `普通波次 - ${seriesConfig.name}`,
description: `${waveNumber}波 - 普通波次 (10个怪物)`,
waveNumber: waveNumber
};
}
/**
* 生成精英波次
* 生成怪物潮波次4-6波
*/
static generateHordeWave(waveNumber: number) {
const series = getRandomSeries();
const seriesConfig = MonsterSeriesConfig[series];
// 怪物潮固定数量20个怪物
const baseCount = 20;
const monsters = [];
// 怪物潮主要使用绿色品质的小怪
const hordeMonsters = seriesConfig.allMonsters.filter(uuid => {
return HeroInfo[uuid] && HeroInfo[uuid].quality === HQuality.GREEN;
});
if (hordeMonsters.length > 0) {
const hordeMonster = hordeMonsters[Math.floor(Math.random() * hordeMonsters.length)];
const monsterInfo = HeroInfo[hordeMonster];
// 生成词条(怪物潮通常没有词条,靠数量取胜)
const affixes = this.generateMonsterAffixes(
monsterInfo.quality,
waveNumber,
RogueWaveType.HORDE
);
const enhanced = this.applyAffixesToMonster(affixes, monsterInfo);
monsters.push({
uuid: hordeMonster,
count: baseCount,
type: "warrior",
series: series,
isHorde: true,
affixes: affixes,
enhancedStats: enhanced.stats,
buffData: enhanced.buffData,
// 肉鸽固定数值
rogueHp: RogueStatsConfig.getHp(waveNumber),
rogueAttack: RogueStatsConfig.getAttack(waveNumber)
});
} else {
// 如果没有绿色怪物,使用其他怪物
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.HORDE
);
const enhanced = this.applyAffixesToMonster(affixes, monsterInfo);
monsters.push({
uuid: randomMonster,
count: baseCount,
type: randomType,
series: series,
isHorde: true,
affixes: affixes,
enhancedStats: enhanced.stats,
buffData: enhanced.buffData,
// 肉鸽固定数值
rogueHp: RogueStatsConfig.getHp(waveNumber),
rogueAttack: RogueStatsConfig.getAttack(waveNumber)
});
}
}
return {
waveType: RogueWaveType.HORDE,
monsters: monsters,
description: `${waveNumber}波 - 怪物潮 (20个怪物)`,
waveNumber: waveNumber
};
}
/**
* 生成精英波次7-8波
*/
static generateEliteWave(waveNumber: number) {
const series = getRandomSeries();
const seriesConfig = MonsterSeriesConfig[series];
// 查找精英怪物
const monsters = [];
// 1. 生成5个精英怪物
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)];
// 数量减少为原来的三分之一
const count = Math.max(1, Math.floor(2 + waveNumber / 8));
const monsterInfo = HeroInfo[eliteMonster];
// 生成精英词条
@@ -288,27 +420,65 @@ export class RogueConfig {
monsters.push({
uuid: eliteMonster,
count: count,
type: "warrior",
count: 5, // 固定5个精英
type: "elite",
series: series,
affixes: affixes,
enhancedStats: enhanced.stats,
buffData: enhanced.buffData
buffData: enhanced.buffData,
// 肉鸽固定数值
rogueHp: RogueStatsConfig.getHp(waveNumber),
rogueAttack: RogueStatsConfig.getAttack(waveNumber)
});
}
// 2. 生成10个普通小怪
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: 10, // 固定10个小怪
type: "normal",
series: series,
affixes: affixes,
enhancedStats: enhanced.stats,
buffData: enhanced.buffData,
// 肉鸽固定数值
rogueHp: RogueStatsConfig.getHp(waveNumber),
rogueAttack: RogueStatsConfig.getAttack(waveNumber)
});
}
return {
waveType: RogueWaveType.ELITE,
monsters: monsters,
description: `精英波次 - ${seriesConfig.name}精锐`,
description: `${waveNumber}波 - 精英波次 (5个精英+10个小怪)`,
waveNumber: waveNumber
};
}
/**
* 生成Boss波次
* 生成最终Boss波次第9波
*/
static generateBossWave(waveNumber: number) {
static generateFinalBossWave(waveNumber: number) {
const series = getRandomSeries();
const seriesConfig = MonsterSeriesConfig[series];
@@ -323,53 +493,72 @@ export class RogueConfig {
const bossInfo = HeroInfo[bossMonster];
// 生成Boss词条
// 生成最终Boss词条
const bossAffixes = this.generateMonsterAffixes(
bossInfo.quality,
waveNumber,
RogueWaveType.BOSS
RogueWaveType.FINAL_BOSS
);
const enhancedBoss = this.applyAffixesToMonster(bossAffixes, bossInfo);
// Boss数量减少为原来的三分之一一般Boss只刷1只
const monsters = [{
// 1个Boss + 5个小怪
const monsters = [];
// 1. 添加Boss
monsters.push({
uuid: bossMonster,
count: 1,
type: "boss",
type: "final_boss",
series: series,
isBoss: true,
isFinalBoss: true,
affixes: bossAffixes,
enhancedStats: enhancedBoss.stats,
buffData: enhancedBoss.buffData
}];
buffData: enhancedBoss.buffData,
// 肉鸽固定数值
rogueHp: RogueStatsConfig.getHp(waveNumber),
rogueAttack: RogueStatsConfig.getAttack(waveNumber)
});
// 2. 添加5个小怪
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: 5, // 固定5个小怪
type: "normal",
series: series,
affixes: affixes,
enhancedStats: enhanced.stats,
buffData: enhanced.buffData,
// 肉鸽固定数值
rogueHp: RogueStatsConfig.getHp(waveNumber),
rogueAttack: RogueStatsConfig.getAttack(waveNumber)
});
}
return {
waveType: RogueWaveType.BOSS,
waveType: RogueWaveType.FINAL_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: "休息波次",
description: `${waveNumber}波 - 最终Boss战 (1个Boss+5个小怪)`,
waveNumber: waveNumber
};
}