refactor(rogue): 调整Rogue模式怪物配置与战斗逻辑
1. 新增怪物出生站位配置 2. 调整单场战斗怪物数量为3只,支持0~2个Boss组合 3. 更新配置校验与怪物生成逻辑 4. 修复英雄预设体的尺寸与位置偏移
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
*
|
||||
* 游戏机制:
|
||||
* - 整局只有一场战斗:开局英雄三次三选一后自动开战。
|
||||
* - 怪物从 BossComboLibrary 按权重随机抽一组(1 Boss + 4 小怪),
|
||||
* - 怪物从 BossComboLibrary 按权重随机抽一组(固定 3 只怪:0~2 Boss + 剩余小怪),
|
||||
* 战斗开始瞬间一次全量登场(X∈[100,320] 均匀铺开),双方立即互相攻击。
|
||||
* - 怪物全灭 → 胜利结算;英雄全灭 → 失败结算;无回合递进、无分批刷怪。
|
||||
*
|
||||
@@ -18,7 +18,7 @@
|
||||
* Boss 基础面板固定为初始英雄 2 倍强度(BOSS_BASE_HP/BOSS_BASE_AP),与小怪共用同一套系数,
|
||||
* 场上 Boss 恰好为小怪 2 倍强度(如需额外压场可调 BOSS_HP_BONUS_MUL)。
|
||||
* 小怪基础面板与 1 级英雄持平(近战镜像 hp300/ap22/cd1.8),默认系数校准为
|
||||
* 整场战斗(3 英雄 vs 4 小怪 + 1 Boss)双方对砍 ≈ WAVE_DURATION(30s)。
|
||||
* 整场战斗(3 英雄 vs 3 只怪)双方对砍 ≈ WAVE_DURATION(30s)。
|
||||
* 手感微调只改 MON_HP_MUL / MON_AP_MUL / BOSS_HP_BONUS_MUL 三个系数即可。
|
||||
*/
|
||||
|
||||
@@ -31,9 +31,10 @@ import { FacSet } from "../common/config/GameSet";
|
||||
/** 单场战斗时长基准(秒):供清屏速度评价(BattleBannerComp 清屏奖励)等使用 */
|
||||
export const WAVE_DURATION = 30;
|
||||
|
||||
/** 怪物登场固定构成:1 个 Boss + 4 个小怪(一次全量登场,打完即整局结束) */
|
||||
export const BOSS_COUNT = 1;
|
||||
export const MINION_COUNT = 4;
|
||||
/** 怪物登场固定构成:单场战斗固定 3 只怪,Boss 数量由组合配置决定(0~2 个),
|
||||
* 剩余位置由小怪填充。例如:3 小怪、1 Boss + 2 小怪、2 Boss + 1 小怪(最大难度) */
|
||||
export const BOSS_COUNT = 2;
|
||||
export const MINION_COUNT = 3;
|
||||
|
||||
/** 怪物血量可调系数:最终 hp = HeroInfo 基础hp × MON_HP_MUL。
|
||||
* 2.6 = 校准后怪物总血量 / 3 英雄 30s 输出(≈30 DPS),双方对砍 ≈ 30s 分胜负 */
|
||||
@@ -104,11 +105,13 @@ export interface BossComboMinionSlot {
|
||||
count: number;
|
||||
}
|
||||
|
||||
/** Boss 组合配置:一场战斗随机抽一组登场(1 Boss + minions 小怪) */
|
||||
/** Boss 组合配置:一场战斗随机抽一组登场(固定 3 只怪,Boss 数量由 bossCount 决定) */
|
||||
export interface BossComboConfig {
|
||||
id: string;
|
||||
name: string;
|
||||
/** 小怪构成(合计数量建议等于 MINION_COUNT,超出截断、不足自动补近战) */
|
||||
/** 本场 Boss 数量(0~2),剩余位置由小怪填充 */
|
||||
bossCount: number;
|
||||
/** 小怪构成(合计数量建议等于 MINION_COUNT - bossCount,超出截断、不足自动补近战) */
|
||||
minions: BossComboMinionSlot[];
|
||||
/** Boss 技能池 id(引用 BossSkillPool,可选) */
|
||||
boss_skill_pool?: string[];
|
||||
@@ -118,37 +121,46 @@ export interface BossComboConfig {
|
||||
weight: number;
|
||||
}
|
||||
|
||||
/** Boss 组合库(硬编码):每场战斗按权重随机抽一组 */
|
||||
/** Boss 组合库(硬编码):每场战斗按权重随机抽一组,固定 3 只怪。
|
||||
* 组合类型:
|
||||
* - 3 小怪(0 Boss):均衡难度
|
||||
* - 1 Boss + 2 小怪:标准难度
|
||||
* - 2 Boss + 1 小怪:最大难度 */
|
||||
export const BossComboLibrary: Record<string, BossComboConfig> = {
|
||||
/** 3 小怪:均衡组合 */
|
||||
rage_charge: {
|
||||
id: "rage_charge", name: "狂暴冲锋组", weight: 10,
|
||||
minions: [{ type: MonType.Melee, count: 3 }, { type: MonType.Heavy, count: 1 }],
|
||||
boss_skill_pool: ["boss_rage"],
|
||||
id: "rage_charge", name: "狂暴冲锋组", weight: 10, bossCount: 0,
|
||||
minions: [{ type: MonType.Melee, count: 2 }, { type: MonType.Heavy, count: 1 }],
|
||||
},
|
||||
iron_wall: {
|
||||
id: "iron_wall", name: "铁壁推进组", weight: 8,
|
||||
minions: [{ type: MonType.Heavy, count: 2 }, { type: MonType.Support, count: 1 }, { type: MonType.Long, count: 1 }],
|
||||
boss_skill_pool: ["boss_iron"],
|
||||
id: "iron_wall", name: "铁壁推进组", weight: 8, bossCount: 0,
|
||||
minions: [{ type: MonType.Heavy, count: 2 }, { type: MonType.Support, count: 1 }],
|
||||
skill_pool: ["tough"],
|
||||
},
|
||||
doom_ritual: {
|
||||
id: "doom_ritual", name: "毁灭仪式组", weight: 6,
|
||||
minions: [{ type: MonType.Summoner, count: 1 }, { type: MonType.Long, count: 2 }, { type: MonType.Support, count: 1 }],
|
||||
boss_skill_pool: ["boss_doom"],
|
||||
id: "doom_ritual", name: "毁灭仪式组", weight: 6, bossCount: 0,
|
||||
minions: [{ type: MonType.Summoner, count: 1 }, { type: MonType.Long, count: 1 }, { type: MonType.Support, count: 1 }],
|
||||
skill_pool: ["warcry"],
|
||||
},
|
||||
/** 1 Boss + 2 小怪:标准难度 */
|
||||
assassin_raid: {
|
||||
id: "assassin_raid", name: "刺客突袭组", weight: 7,
|
||||
minions: [{ type: MonType.Assassin, count: 2 }, { type: MonType.Melee, count: 2 }],
|
||||
id: "assassin_raid", name: "刺客突袭组", weight: 7, bossCount: 1,
|
||||
minions: [{ type: MonType.Assassin, count: 1 }, { type: MonType.Melee, count: 1 }],
|
||||
boss_skill_pool: ["boss_rage", "boss_doom"],
|
||||
skill_pool: ["berserk"],
|
||||
},
|
||||
blood_legion: {
|
||||
id: "blood_legion", name: "吸血军团组", weight: 5,
|
||||
minions: [{ type: MonType.Melee, count: 2 }, { type: MonType.Long, count: 1 }, { type: MonType.Summoner, count: 1 }],
|
||||
id: "blood_legion", name: "吸血军团组", weight: 5, bossCount: 1,
|
||||
minions: [{ type: MonType.Melee, count: 1 }, { type: MonType.Long, count: 1 }],
|
||||
boss_skill_pool: ["boss_iron", "boss_doom"],
|
||||
skill_pool: ["leech"],
|
||||
},
|
||||
/** 2 Boss + 1 小怪:最大难度 */
|
||||
twin_boss: {
|
||||
id: "twin_boss", name: "双王降临", weight: 3, bossCount: 2,
|
||||
minions: [{ type: MonType.Support, count: 1 }],
|
||||
boss_skill_pool: ["boss_rage", "boss_iron", "boss_doom"],
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -277,7 +289,7 @@ export const BossSkillPool: Record<string, MonSkillSet> = {
|
||||
export function validateRogueConfig(): string[] {
|
||||
const errors: string[] = [];
|
||||
|
||||
// 1. 校验组合引用与数量
|
||||
// 1. 校验组合引用与数量(固定 3 只怪:bossCount + minionTotal 必须等于 MINION_COUNT)
|
||||
for (const id in BossComboLibrary) {
|
||||
const combo = BossComboLibrary[id];
|
||||
let minionTotal = 0;
|
||||
@@ -287,8 +299,12 @@ export function validateRogueConfig(): string[] {
|
||||
errors.push(`组合 ${id} 引用的怪物类型 ${slot.type}(${MonTypeName[slot.type] || "?"}) 在 MonList 中无可用 uuid`);
|
||||
}
|
||||
}
|
||||
if (minionTotal !== MINION_COUNT) {
|
||||
errors.push(`组合 ${id} 小怪数量=${minionTotal} 与 MINION_COUNT=${MINION_COUNT} 不一致`);
|
||||
const totalMon = combo.bossCount + minionTotal;
|
||||
if (totalMon !== MINION_COUNT) {
|
||||
errors.push(`组合 ${id} 总怪数=${totalMon}(bossCount=${combo.bossCount} + minions=${minionTotal})与 MINION_COUNT=${MINION_COUNT} 不一致`);
|
||||
}
|
||||
if (combo.bossCount < 0 || combo.bossCount > BOSS_COUNT) {
|
||||
errors.push(`组合 ${id} bossCount=${combo.bossCount} 超出允许范围 [0, ${BOSS_COUNT}]`);
|
||||
}
|
||||
if (combo.skill_pool) {
|
||||
for (const skillId of combo.skill_pool) {
|
||||
@@ -371,7 +387,7 @@ export const TestModeConfig = {
|
||||
export class RogueSpawningEngine {
|
||||
|
||||
/**
|
||||
* 生成一场战斗的怪物列表:随机一组 Boss 组合(1 Boss + 4 小怪,属性走基础×系数)。
|
||||
* 生成一场战斗的怪物列表:随机一组 Boss 组合(固定 3 只怪,Boss 数量由 combo.bossCount 决定)。
|
||||
* Boss 压队尾(登场时由 MissionMonComp 统一布位)。
|
||||
* @returns 怪物列表(小怪在前、Boss 在尾)
|
||||
*/
|
||||
@@ -383,6 +399,7 @@ export class RogueSpawningEngine {
|
||||
|
||||
const combo = pickBossCombo();
|
||||
const monsters: GeneratedMonster[] = [];
|
||||
const bossCount = combo ? Math.max(0, Math.min(combo.bossCount, BOSS_COUNT)) : 0;
|
||||
|
||||
if (combo) {
|
||||
for (const slot of combo.minions) {
|
||||
@@ -391,13 +408,14 @@ export class RogueSpawningEngine {
|
||||
}
|
||||
}
|
||||
}
|
||||
// 组合库为空或数量不足兜底:补近战小怪至 MINION_COUNT
|
||||
while (monsters.length < MINION_COUNT) {
|
||||
// 组合库为空或数量不足兜底:补近战小怪至 MINION_COUNT - bossCount
|
||||
const minionTarget = MINION_COUNT - bossCount;
|
||||
while (monsters.length < minionTarget) {
|
||||
monsters.push(this.makeMonster(MonType.Melee, monsters.length));
|
||||
}
|
||||
|
||||
// Boss 压队尾
|
||||
for (let i = 0; i < BOSS_COUNT; i++) {
|
||||
for (let i = 0; i < bossCount; i++) {
|
||||
monsters.push(this.makeBoss());
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user