refactor: 统一将游戏内的「波次」术语替换为「回合」

本次提交将全项目中所有与「波次」相关的术语、注释、配置描述、UI文本全部替换为「回合」,包括:
1.  技能卡牌、怪物刷新、经济系统的相关注释与变量名
2.  配置表中的波次相关常量与描述文本
3.  UI预制体中的波次显示文本
4.  所有相关的文档注释与接口说明

统一术语后,游戏的关卡流程描述将更符合常规肉鸽游戏的表达习惯,避免与「波次」字面含义混淆,提升代码可读性与团队协作一致性。
This commit is contained in:
panFD
2026-08-09 14:51:48 +08:00
parent 2907c214f1
commit c59ba45b5b
14 changed files with 622 additions and 618 deletions

View File

@@ -3,24 +3,24 @@
* @description 肉鸽刷怪系统(基于英雄强度的动态难度 + 心流循环)
*
* 设计层次:
* 1. WaveType - 型(普通 / 压力 / 放松5 一个心流循环
* 2. WaveConfig - 每硬编码(数量 + 小队池 + HP/AP 倍率 + 强度微调)
* 1. WaveType - 回合类型(普通 / 压力 / 放松5 回合一个心流循环
* 2. WaveConfig - 每回合硬编码(数量 + 小队池 + HP/AP 倍率 + 强度微调)
* 3. DynamicTuner - 动态难度调节器(系统根据战况放水 / 加压)
* 4. MonSkillSet - 怪物技能池atking / atked / dead 等全触发类型)
* 5. RogueSpawningEngine - 生成引擎(按英雄强度反推怪物强度)
*
* 核心公式:
* heroPower = Σ calcHeroPower(HeroInfo[uuid], lv) (场上存活英雄)
* targetPower = heroPower × 型系数 × wave.power_adjust × DynamicTuner.factor
* targetPower = heroPower × 回合类型系数 × wave.power_adjust × DynamicTuner.factor
* scale = targetPower ÷ Σ 怪物基础强度
* 每只怪: hp ×= scale, ap ×= scale
*
* 波次节奏:
* - 最大 20 ,第 20 通关
* - 每 30 秒,固定分 3 批,每 10 秒释放一批
* - 普通 18~36 只,放松 × 1.5 = 27~54 只
* - wave % 5 === 0 → 压力(必带 Boss强度高、数量少
* - wave % 5 === 1 → 放松(数量 × 1.5,强度低,爽快清屏)
* 回合节奏:
* - 最大 20 回合,第 20 回合通关
* - 每回合 30 秒,固定分 3 批,每 10 秒释放一批
* - 普通回合 18~36 只,放松回合 × 1.5 = 27~54 只
* - wave % 5 === 0 → 压力回合(必带 Boss强度高、数量少
* - wave % 5 === 1 → 放松回合(数量 × 1.5,强度低,爽快清屏)
*/
import { HeroInfo, MonType, MonTypeName, calcHeroPower, TriggerGrouped, LvReviveEntry, heroInfo } from "../common/config/heroSet";
@@ -29,50 +29,50 @@ import { FacSet } from "../common/config/GameSet";
import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
import { HeroAttrsComp } from "../hero/HeroAttrsComp";
// ======================== 1. 型与节奏常量 ========================
// ======================== 1. 回合类型与节奏常量 ========================
/** 型枚举 */
/** 回合类型枚举 */
export enum WaveType {
Normal = 0, // 普通
Pressure = 1, // 压力wave % 5 === 0必带 Boss
Relax = 2, // 放松wave % 5 === 1量大强度低
Normal = 0, // 普通回合
Pressure = 1, // 压力回合wave % 5 === 0必带 Boss
Relax = 2, // 放松回合wave % 5 === 1量大强度低
}
/** 型名称 */
/** 回合类型名称 */
export const WaveTypeName: Record<WaveType, string> = {
[WaveType.Normal]: "普通",
[WaveType.Pressure]: "压力",
[WaveType.Relax]: "放松",
};
/** 型强度系数(硬编码) */
/** 回合类型强度系数(硬编码) */
export const WAVE_TYPE_POWER_RATIO: Record<WaveType, number> = {
[WaveType.Normal]: 0.9, // 普通:标准强度
[WaveType.Pressure]: 1.2, // 压力:强度高、数量少
[WaveType.Relax]: 0.6, // 放松:量大、强度低
[WaveType.Normal]: 0.9, // 普通回合:标准强度
[WaveType.Pressure]: 1.2, // 压力回合:强度高、数量少
[WaveType.Relax]: 0.6, // 放松回合:量大、强度低
};
/** 放松数量倍率(相对普通 */
/** 放松回合数量倍率(相对普通回合 */
export const RELAX_COUNT_MUL = 1.5;
/** 最大波次(第 20 通关) */
/** 最大回合数(第 20 回合通关) */
export const MAX_WAVE = 20;
/** 每时长(秒) */
/** 每回合时长(秒) */
export const WAVE_DURATION = 30;
/** 每分批次数 */
/** 每回合分批次数 */
export const BATCH_COUNT = 3;
/** 每批间隔30 秒 / 3 批 = 10 秒 */
export const BATCH_INTERVAL = WAVE_DURATION / BATCH_COUNT;
/** 每怪物硬上限(放松 36 × 1.5 = 54 */
/** 每回合怪物硬上限(放松回合 36 × 1.5 = 54 */
export const MAX_MONSTERS = 54;
/**
* 获取指定波次的波
* @param wave 波次1 起)
* 获取指定回合的回合类
* @param wave 回合1 起)
* @returns WaveType
*/
export function getWaveType(wave: number): WaveType {
@@ -87,7 +87,7 @@ export function getWaveType(wave: number): WaveType {
* 动态难度调节器(系统控制放水 / 加压)
* 与硬编码系数并存,用于根据战况实时微调难度。
*
* 用法示例MissionComp 每结束时调用):
* 用法示例MissionComp 每回合结束时调用):
* DynamicTuner.adjust(clearTime, heroDeathCount);
*
* 调节规则(内部硬编码):
@@ -107,7 +107,7 @@ export const DynamicTuner = {
STEP: 0.05,
/**
* 根据上一战况自动调节难度
* 根据上一回合战况自动调节难度
* @param clearTime 清场耗时(秒)
* @param heroDeathCount 英雄死亡数
*/
@@ -228,7 +228,7 @@ export interface MonSkillSet {
/**
* 怪物技能池(硬编码)
* 压力 / Boss 可配置专属技能,普通随机挂载增加变数。
* 压力回合 / Boss 可配置专属技能,普通回合随机挂载增加变数。
*
* 技能 uuid 引用 SkillSet 中的 6000~6500 段触发技能。
*/
@@ -270,7 +270,7 @@ export const MonSkillPool: Record<string, MonSkillSet> = {
},
};
/** Boss 专属技能池(压力 Boss 随机挂载) */
/** Boss 专属技能池(压力回合 Boss 随机挂载) */
export const BossSkillPool: Record<string, MonSkillSet> = {
/** 狂暴领主:攻击触发全队攻击提升 */
boss_rage: {
@@ -301,37 +301,37 @@ export const BossSkillPool: Record<string, MonSkillSet> = {
},
};
// ======================== 6. 波次配置表 ========================
// ======================== 6. 回合配置表 ========================
/** 单波次完整配置 */
/** 单回合完整配置 */
export interface WaveConfig {
/** 基础怪物总数(普通 36 为上限,放松自动 × 1.5 = 54 */
/** 基础怪物总数(普通回合 36 为上限,放松回合自动 × 1.5 = 54 */
base_count: number;
/** 可选小队 id 池,引擎按权重抽取拼装到 base_count */
squad_pool: string[];
/** HP 强化倍率(硬编码,逐递进) */
/** HP 强化倍率(硬编码,逐回合递进) */
hp_mul: number;
/** AP 强化倍率(硬编码,逐递进) */
/** AP 强化倍率(硬编码,逐回合递进) */
ap_mul: number;
/** 强度微调(放水 / 加压,默认 1.0 */
power_adjust?: number;
/** 是否 Boss (压力必为 true */
/** 是否 Boss 回合(压力回合必为 true */
boss_wave?: boolean;
/** 普通怪技能池 id可选随机挂载 */
skill_pool?: string[];
/** Boss 技能池 idBoss 专用,随机挂载) */
/** Boss 技能池 idBoss 回合专用,随机挂载) */
boss_skill_pool?: string[];
}
/**
* 波次配置表(硬编码 wave 1~20
* 回合配置表(硬编码 wave 1~20
*
* 心流循环5 一循环):
* wave % 5 === 0 → 压力(必带 Boss强度高、数量少
* wave % 5 === 1 → 放松(数量 × 1.5,强度低)
* 其余 → 普通(标准强度)
* 心流循环5 回合一循环):
* wave % 5 === 0 → 压力回合(必带 Boss强度高、数量少
* wave % 5 === 1 → 放松回合(数量 × 1.5,强度低)
* 其余 → 普通回合(标准强度)
*
* 强度递进hp_mul / ap_mul 每 5 一档,压力额外提升。
* 强度递进hp_mul / ap_mul 每 5 回合一档,压力回合额外提升。
*/
export const WaveConfigs: Record<number, WaveConfig> = {
// ===== 第一循环:教学期 =====
@@ -339,34 +339,34 @@ export const WaveConfigs: Record<number, WaveConfig> = {
2: { base_count: 21, squad_pool: ["melee_grunt", "mixed_balanced"], hp_mul: 1.00, ap_mul: 1.00 },
3: { base_count: 24, squad_pool: ["melee_grunt", "mixed_balanced", "long_line"], hp_mul: 1.05, ap_mul: 1.00 },
4: { base_count: 27, squad_pool: ["mixed_balanced", "long_line", "heavy_shield"], hp_mul: 1.10, ap_mul: 1.05 },
// 压力:第一 Boss
// 压力回合:第一 Boss
5: { base_count: 21, squad_pool: ["melee_grunt", "mixed_balanced", "heavy_shield"], hp_mul: 1.15, ap_mul: 1.10, boss_wave: true, boss_skill_pool: ["boss_rage"] },
// ===== 第二循环:引入技能怪 =====
// 放松:量大好清
// 放松回合:量大好清
6: { base_count: 30, squad_pool: ["melee_grunt", "mixed_balanced", "long_line"], hp_mul: 1.10, ap_mul: 1.05 },
7: { base_count: 30, squad_pool: ["melee_grunt", "heavy_shield", "long_line"], hp_mul: 1.15, ap_mul: 1.10, skill_pool: ["tough"] },
8: { base_count: 33, squad_pool: ["assassin_squad", "mixed_balanced", "summoner_cult"], hp_mul: 1.20, ap_mul: 1.15, skill_pool: ["berserk"] },
9: { base_count: 33, squad_pool: ["heavy_shield", "long_line", "mixed_balanced"], hp_mul: 1.25, ap_mul: 1.20, skill_pool: ["berserk", "tough"] },
// 压力:第二 Boss
// 压力回合:第二 Boss
10: { base_count: 24, squad_pool: ["melee_grunt", "assassin_squad", "mixed_balanced"], hp_mul: 1.30, ap_mul: 1.25, boss_wave: true, boss_skill_pool: ["boss_rage", "boss_iron"] },
// ===== 第三循环:组合多样化 =====
// 放松
// 放松回合
11: { base_count: 33, squad_pool: ["assassin_squad", "long_line", "summoner_cult", "mixed_balanced"], hp_mul: 1.25, ap_mul: 1.20, skill_pool: ["leech"] },
12: { base_count: 33, squad_pool: ["heavy_shield", "melee_grunt", "mixed_balanced", "long_line"], hp_mul: 1.30, ap_mul: 1.25, skill_pool: ["tough", "warcry"] },
13: { base_count: 36, squad_pool: ["assassin_squad", "summoner_cult", "mixed_balanced"], hp_mul: 1.35, ap_mul: 1.30, skill_pool: ["berserk", "leech"] },
14: { base_count: 36, squad_pool: ["heavy_shield", "long_line", "melee_grunt"], hp_mul: 1.40, ap_mul: 1.35, skill_pool: ["berserk", "tough", "legacy"] },
// 压力:第三 Boss中期高潮
// 压力回合:第三 Boss中期高潮
15: { base_count: 27, squad_pool: ["assassin_squad", "mixed_balanced", "summoner_cult"], hp_mul: 1.50, ap_mul: 1.40, boss_wave: true, boss_skill_pool: ["boss_rage", "boss_iron", "boss_doom"] },
// ===== 第四循环:终极阶段 =====
// 放松
// 放松回合
16: { base_count: 36, squad_pool: ["assassin_squad", "heavy_shield", "long_line"], hp_mul: 1.45, ap_mul: 1.40, skill_pool: ["leech", "warcry"] },
17: { base_count: 36, squad_pool: ["melee_grunt", "summoner_cult", "mixed_balanced"], hp_mul: 1.50, ap_mul: 1.45, skill_pool: ["berserk", "legacy"] },
18: { base_count: 36, squad_pool: ["assassin_squad", "long_line", "heavy_shield"], hp_mul: 1.55, ap_mul: 1.50, skill_pool: ["berserk", "tough", "leech"] },
19: { base_count: 36, squad_pool: ["mixed_balanced", "summoner_cult", "melee_grunt"], hp_mul: 1.60, ap_mul: 1.55, skill_pool: ["berserk", "tough", "legacy", "warcry"] },
// 压力:最终 Boss
// 压力回合:最终 Boss
20: { base_count: 30, squad_pool: ["assassin_squad", "heavy_shield", "summoner_cult", "mixed_balanced"], hp_mul: 1.80, ap_mul: 1.70, boss_wave: true, boss_skill_pool: ["boss_doom", "boss_rage"] },
};
@@ -472,13 +472,13 @@ export const TestModeConfig = {
/**
* 肉鸽刷怪生成引擎
* 按英雄强度反推怪物强度,结合型系数与动态调节器生成怪物列表
* 按英雄强度反推怪物强度,结合回合类型系数与动态调节器生成怪物列表
*/
export class RogueSpawningEngine {
/**
* 生成指定波次的怪物列表
* @param waveNumber 波次1 起,>MAX_WAVE 时复用 wave MAX_WAVE 配置)
* 生成指定回合的怪物列表
* @param waveNumber 回合1 起,>MAX_WAVE 时复用 wave MAX_WAVE 配置)
* @returns 怪物列表,长度 ≤ MAX_MONSTERS
*/
generateWave(waveNumber: number): GeneratedMonster[] {
@@ -499,14 +499,14 @@ export class RogueSpawningEngine {
const powerAdjust = cfg.power_adjust ?? 1.0;
const targetPower = heroPower * typeRatio * powerAdjust * DynamicTuner.factor;
// 2. 确定怪物总数(放松 × 1.5
// 2. 确定怪物总数(放松回合 × 1.5
let totalCount = cfg.base_count;
if (waveType === WaveType.Relax) {
totalCount = Math.round(totalCount * RELAX_COUNT_MUL);
}
totalCount = Math.min(totalCount, MAX_MONSTERS);
// 3. Boss 位(压力必带 Boss占 1 个名额)
// 3. Boss 位(压力回合必带 Boss占 1 个名额)
const monsters: GeneratedMonster[] = [];
let remaining = totalCount;
if (cfg.boss_wave) {
@@ -563,8 +563,8 @@ export class RogueSpawningEngine {
}
/**
* 获取指定波次的怪物总数
* @param waveNumber 目标
* 获取指定回合的怪物总数
* @param waveNumber 目标回合
* @returns 预计生成的怪物总数
*/
getWaveMonsterCount(waveNumber: number): number {
@@ -672,7 +672,7 @@ export class RogueSpawningEngine {
const baseHp = baseInfo ? baseInfo.hp : 500;
const baseAp = baseInfo ? baseInfo.ap : 30;
// Boss 自带额外血量加成:每 5 递增 20%wave 5=1.0, 10=1.2, 15=1.4...
// Boss 自带额外血量加成:每 5 回合递增 20%wave 5=1.0, 10=1.2, 15=1.4...
const bossBonusHpMul = 1 + 0.20 * Math.floor(Math.max(0, wave - 5) / 5);
return {
@@ -753,21 +753,21 @@ export class RogueSpawningEngine {
export const spawningEngine = new RogueSpawningEngine();
/** 历史接口:波次槽位(保留兼容) */
/** 历史接口:回合槽位(保留兼容) */
export interface IWaveSlot {
type: number;
count: number;
}
/**
* 获取指定波次预计的怪物总数量
* @param waveNumber 目标
* 获取指定回合预计的怪物总数量
* @param waveNumber 目标回合
*/
export function getWaveMonsterCount(waveNumber: number): number {
return spawningEngine.getWaveMonsterCount(waveNumber);
}
/** 获取波次槽位配置(向后兼容,从 generateWave 反推) */
/** 获取回合槽位配置(向后兼容,从 generateWave 反推) */
export function getWaveSlotConfig(waveNumber: number): IWaveSlot[] {
const generated = spawningEngine.generateWave(waveNumber);
const slotMap = new Map<number, number>();
@@ -785,7 +785,7 @@ export const DefaultWaveSlot: IWaveSlot[] = [
{ type: MonType.Support, count: 5 },
];
/** 波次槽位配置代理(按需生成) */
/** 回合槽位配置代理(按需生成) */
export const WaveSlotConfig: { [wave: number]: IWaveSlot[] } = new Proxy(
{} as { [wave: number]: IWaveSlot[] },
{