From cb2a72da5269db3615fdccab1236c11c7f2942db Mon Sep 17 00:00:00 2001 From: panFD Date: Thu, 13 Aug 2026 14:12:05 +0800 Subject: [PATCH] =?UTF-8?q?refactor(map):=20=E9=87=8D=E6=9E=84rogue?= =?UTF-8?q?=E6=88=98=E6=96=97=E6=95=B0=E5=80=BC=E7=94=9F=E6=88=90=E9=80=BB?= =?UTF-8?q?=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 重构了Rogue模式的怪物数值计算方式,移除了基于英雄实时强度的动态缩放算法,改为统一使用基础属性乘以可调系数的固定缩放方案: 1. 更新了怪物配置基础属性,对齐1级英雄面板作为基准 2. 简化了数值公式,仅保留三个可调节的全局系数用于平衡难度 3. 删除了冗余的ECS查询、强度计算和类型系数逻辑 4. 更新了全部注释文档,明确数值校准目标和调整方式 --- assets/script/game/common/config/heroSet.ts | 70 ++++++------ assets/script/game/map/RogueConfig.ts | 114 ++++---------------- 2 files changed, 56 insertions(+), 128 deletions(-) diff --git a/assets/script/game/common/config/heroSet.ts b/assets/script/game/common/config/heroSet.ts index 508d9259..e053e039 100644 --- a/assets/script/game/common/config/heroSet.ts +++ b/assets/script/game/common/config/heroSet.ts @@ -790,75 +790,75 @@ export const HeroInfo: Record = { }, /* - *=============怪物配置列表================ - * 基础近战型(lv:1) : SPEED:800 |AP:12 | HP:360 | skills[0].cd=0.65 - * 重型坦克型(lv:1) : SPEED:800 |AP:30 | HP:1050 | skills[0].cd=2 - * 远程dps(lv:1) : SPEED:800 |AP:45 | HP:240 | skills[0].cd=1.5 - * 远程辅助(lv:1) : SPEED:800 |AP:20 | HP:240 | skills[0].cd=1 - * 精英 (lv:1) : SPEED:800 |AP:20 | HP:4500 | skills[0].cd=1 + *=============怪物配置列表================ + * 性能基准:1 级怪物与 1 级英雄(card_lv=1)单体性能持平 —— + * 近战怪镜像 5001(hp300/ap22/cd1.8),远程怪镜像 5004(hp160/ap28/cd1.3), + * 重型/Boss 以更高 hp 换取更低 DPS,承担"墙"与"压场"定位。 + * 运行时最终属性 = 本表基础值 × RogueConfig.MON_HP_MUL / MON_AP_MUL + * (Boss 额外 × BOSS_HP_BONUS_MUL),校准目标:整场战斗双方对砍 ≈ 30s。 */ // 基础怪物 (全部固定点位站桩攻击,HType仅决定是前排还是后排) - // 前排怪物 (站在前排,承受更多伤害) — v5: TD节奏CD,多而弱爽感设计 + // 前排怪物 — 近战镜像 1 级英雄基准(hp300/ap22/cd1.8),变体微分定位 6001: { - uuid: 6001, name: "兽人战士", path: "m1", fac: FacSet.MON, lv: 1, type: HType.Melee, monType: MonType.Melee, hp: 286, ap: 10, speed: 70, - skills: { 6005: { uuid: 6005, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.VerySlow1].cd, ccd: 0 } }, info: "基础前排怪" + uuid: 6001, name: "兽人战士", path: "m1", fac: FacSet.MON, lv: 1, type: HType.Melee, monType: MonType.Melee, hp: 300, ap: 22, speed: 70, + skills: { 6005: { uuid: 6005, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow3].cd, ccd: 0 } }, info: "基础前排怪, 与1级近战英雄持平" }, 6002: { - uuid: 6002, name: "兽人精锐战士", path: "m2", fac: FacSet.MON, lv: 1, type: HType.Melee, monType: MonType.Melee, hp: 390, ap: 14, speed: 110, - skills: { 6005: { uuid: 6005, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.VerySlow2].cd, ccd: 0 } }, info: "进阶前排怪, 更快更痛" + uuid: 6002, name: "兽人精锐战士", path: "m2", fac: FacSet.MON, lv: 1, type: HType.Melee, monType: MonType.Melee, hp: 340, ap: 26, speed: 110, + skills: { 6005: { uuid: 6005, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow2].cd, ccd: 0 } }, info: "进阶前排怪, 更快更痛" }, 6003: { - uuid: 6003, name: "兽人重装兵", path: "m3", fac: FacSet.MON, lv: 1, type: HType.Melee, monType: MonType.Heavy, hp: 1105, ap: 20, speed: 50, - skills: { 6005: { uuid: 6005, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.VerySlow3].cd, ccd: 0 } }, info: "重型坦克怪, 高HP慢攻" + uuid: 6003, name: "兽人重装兵", path: "m3", fac: FacSet.MON, lv: 1, type: HType.Melee, monType: MonType.Heavy, hp: 800, ap: 14, speed: 50, + skills: { 6005: { uuid: 6005, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.VerySlow3].cd, ccd: 0 } }, info: "重型坦克怪, 高HP低攻承伤位" }, - // 后排怪物 (站在后排,输出更高) + // 后排怪物 — 远程镜像 1 级法师基准(hp160/ap28/cd1.3),变体微分定位 6004: { - uuid: 6004, name: "兽人射手", path: "m4", fac: FacSet.MON, lv: 1, type: HType.Long, monType: MonType.Long, hp: 247, ap: 35, speed: 70, - skills: { 6008: { uuid: 6008, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.VerySlow1].cd, ccd: 0 } }, info: "后排高DPS怪" + uuid: 6004, name: "兽人射手", path: "m4", fac: FacSet.MON, lv: 1, type: HType.Long, monType: MonType.Long, hp: 160, ap: 28, speed: 70, + skills: { 6008: { uuid: 6008, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Mid3].cd, ccd: 0 } }, info: "后排输出怪, 与1级远程英雄持平" }, 6005: { - uuid: 6005, name: "兽人刺客", path: "m5", fac: FacSet.MON, lv: 1, type: HType.Long, monType: MonType.Assassin, hp: 273, ap: 38, speed: 130, - skills: { 6103: { uuid: 6103, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.VerySlow2].cd, ccd: 0 } }, info: "高AP快速攻击刺客" + uuid: 6005, name: "兽人刺客", path: "m5", fac: FacSet.MON, lv: 1, type: HType.Long, monType: MonType.Assassin, hp: 130, ap: 26, speed: 130, + skills: { 6103: { uuid: 6103, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Normal3].cd, ccd: 0 } }, info: "高攻速低HP刺客" }, // 特殊位怪物 6006: { - uuid: 6006, name: "骷髅领主", path: "m6", fac: FacSet.MON, lv: 1, type: HType.Melee, monType: MonType.MeleeBoss, hp: 6500, ap: 20, speed: 60, + uuid: 6006, name: "骷髅领主", path: "m6", fac: FacSet.MON, lv: 1, type: HType.Melee, monType: MonType.MeleeBoss, hp: 900, ap: 20, speed: 60, skills: { 6005: { uuid: 6005, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.VerySlow3].cd, ccd: 0 } }, info: "前排MiniBoss级坦克" }, 6007: { - uuid: 6007, name: "兽人术士", path: "m7", fac: FacSet.MON, lv: 1, type: HType.Long, monType: MonType.Support, hp: 390, ap: 24, speed: 70, - skills: { 6103: { uuid: 6103, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.VerySlow1].cd, ccd: 0 } }, info: "后排法师怪, 魔法攻击" + uuid: 6007, name: "兽人术士", path: "m7", fac: FacSet.MON, lv: 1, type: HType.Long, monType: MonType.Support, hp: 240, ap: 18, speed: 70, + skills: { 6103: { uuid: 6103, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow3].cd, ccd: 0 } }, info: "后排辅助法师怪" }, 6008: { - uuid: 6008, name: "兽人火法", path: "m8", fac: FacSet.MON, lv: 1, type: HType.Long, monType: MonType.Summoner, hp: 351, ap: 32, speed: 70, - skills: { 6103: { uuid: 6103, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.VerySlow2].cd, ccd: 0 } }, info: "后排高输出法师怪" + uuid: 6008, name: "兽人火法", path: "m8", fac: FacSet.MON, lv: 1, type: HType.Long, monType: MonType.Summoner, hp: 220, ap: 24, speed: 70, + skills: { 6103: { uuid: 6103, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow1].cd, ccd: 0 } }, info: "后排召唤系法师怪" }, - // BOSS怪物 — Boss节奏1.2-1.5s,删除不存在的6206技能 + // BOSS怪物 — 与6006同基准,以高HP压场,血量经 BOSS_HP_BONUS_MUL 单独放大 6101: { - uuid: 6101, name: "兽人首领-双刀战士", path: "mb1", fac: FacSet.MON, lv: 6, type: HType.Melee, monType: MonType.MeleeBoss, hp: 2470, ap: 30, speed: 120, - skills: { 6103: { uuid: 6103, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.VerySlow3].cd, ccd: 0 } }, info: "前排Boss, 高攻速" + uuid: 6101, name: "兽人首领-双刀战士", path: "mb1", fac: FacSet.MON, lv: 6, type: HType.Melee, monType: MonType.MeleeBoss, hp: 1200, ap: 24, speed: 120, + skills: { 6103: { uuid: 6103, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow3].cd, ccd: 0 } }, info: "前排Boss, 攻速型" }, 6102: { - uuid: 6102, name: "兽人首领-斧头战士", path: "mb2", fac: FacSet.MON, lv: 6, type: HType.Melee, monType: MonType.MeleeBoss, hp: 9750, ap: 26, speed: 60, - skills: { 6005: { uuid: 6005, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.VerySlow1].cd, ccd: 0 } }, info: "前排Boss, 超高HP" + uuid: 6102, name: "兽人首领-斧头战士", path: "mb2", fac: FacSet.MON, lv: 6, type: HType.Melee, monType: MonType.MeleeBoss, hp: 1500, ap: 18, speed: 60, + skills: { 6005: { uuid: 6005, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.VerySlow3].cd, ccd: 0 } }, info: "前排Boss, 超高HP" }, 6103: { - uuid: 6103, name: "兽人首领-魔法师", path: "mb3", fac: FacSet.MON, lv: 6, type: HType.Long, monType: MonType.LongBoss, hp: 2925, ap: 38, speed: 110, - skills: { 6103: { uuid: 6103, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.VerySlow2].cd, ccd: 0 } }, info: "后排法系Boss, 高AP" + uuid: 6103, name: "兽人首领-魔法师", path: "mb3", fac: FacSet.MON, lv: 6, type: HType.Long, monType: MonType.LongBoss, hp: 1000, ap: 28, speed: 110, + skills: { 6103: { uuid: 6103, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow1].cd, ccd: 0 } }, info: "后排法系Boss" }, 6104: { - uuid: 6104, name: "兽人首领-射手", path: "mb4", fac: FacSet.MON, lv: 6, type: HType.Long, monType: MonType.LongBoss, hp: 8840, ap: 30, speed: 70, - skills: { 6005: { uuid: 6005, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.VerySlow3].cd, ccd: 0 } }, info: "后排位Boss, 均衡型" + uuid: 6104, name: "兽人首领-射手", path: "mb4", fac: FacSet.MON, lv: 6, type: HType.Long, monType: MonType.LongBoss, hp: 1100, ap: 24, speed: 70, + skills: { 6005: { uuid: 6005, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow2].cd, ccd: 0 } }, info: "后排位Boss, 均衡型" }, 6105: { - uuid: 6105, name: "亡灵首领-法师", path: "mb5", fac: FacSet.MON, lv: 6, type: HType.Long, monType: MonType.LongBoss, hp: 3380, ap: 42, speed: 110, - skills: { 6103: { uuid: 6103, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.VerySlow1].cd, ccd: 0 } }, info: "后排高AP Boss" + uuid: 6105, name: "亡灵首领-法师", path: "mb5", fac: FacSet.MON, lv: 6, type: HType.Long, monType: MonType.LongBoss, hp: 1000, ap: 30, speed: 110, + skills: { 6103: { uuid: 6103, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow3].cd, ccd: 0 } }, info: "后排高AP Boss" }, 6106: { - uuid: 6106, name: "亡灵首领-骑马战士", path: "mb6", fac: FacSet.MON, lv: 6, type: HType.Melee, monType: MonType.MeleeBoss, hp: 11700, ap: 26, speed: 130, + uuid: 6106, name: "亡灵首领-骑马战士", path: "mb6", fac: FacSet.MON, lv: 6, type: HType.Melee, monType: MonType.MeleeBoss, hp: 1800, ap: 20, speed: 130, skills: { 6005: { uuid: 6005, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.VerySlow3].cd, ccd: 0 } }, info: "前排终极Boss, 最高HP+高速" }, diff --git a/assets/script/game/map/RogueConfig.ts b/assets/script/game/map/RogueConfig.ts index 2a16f78a..b2b4f453 100644 --- a/assets/script/game/map/RogueConfig.ts +++ b/assets/script/game/map/RogueConfig.ts @@ -11,23 +11,19 @@ * 设计层次: * 1. BossComboLibrary - Boss 组合库(小怪构成 + Boss/小怪技能池 + 抽取权重) * 2. MonSkillPool/BossSkillPool - 怪物技能池(atking / atked / dead 等全触发类型) - * 3. RogueSpawningEngine - 生成引擎(按英雄强度反推怪物强度) + * 3. RogueSpawningEngine - 生成引擎(基础属性 × 可调系数) * - * 核心公式: - * heroPower = Σ calcHeroPower(HeroInfo[uuid], lv) (场上存活英雄) - * targetPower = heroPower × BOSS_TYPE_RATIO × FINAL_HP_MUL × MON_POWER_MUL - * hpScale = targetPower ÷ Σ 怪物基础强度 - * 怪物 hp = base_hp × hpScale (走总强度框架,自动匹配玩家) - * - * 怪物 ap 独立挂钩玩家输出(不走总强度,避免被 hp 挤占): - * 怪物 ap = 玩家平均攻击 × AP_GROWTH_FINAL × AP_RELATIVE × 类型系数 + * 核心公式(基础属性 × 可调系数): + * 怪物 hp = HeroInfo 基础hp × MON_HP_MUL(Boss 额外 × BOSS_HP_BONUS_MUL) + * 怪物 ap = HeroInfo 基础ap × MON_AP_MUL + * 怪物基础面板与 1 级英雄持平(近战镜像 hp300/ap22/cd1.8),默认系数校准为 + * 整场战斗(3 英雄 vs 4 小怪 + 1 Boss)双方对砍 ≈ WAVE_DURATION(30s)。 + * 手感微调只改 MON_HP_MUL / MON_AP_MUL / BOSS_HP_BONUS_MUL 三个系数即可。 */ -import { HeroInfo, MonType, MonTypeName, calcHeroPower, TriggerGrouped, LvReviveEntry } from "../common/config/heroSet"; +import { HeroInfo, MonType, MonTypeName, TriggerGrouped, LvReviveEntry } from "../common/config/heroSet"; import { SkillOverrides } from "../common/config/SkillSet"; import { FacSet } from "../common/config/GameSet"; -import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS"; -import { HeroAttrsComp } from "../hero/HeroAttrsComp"; // ======================== 1. 战斗常量 ======================== @@ -38,17 +34,13 @@ export const WAVE_DURATION = 30; export const BOSS_COUNT = 1; export const MINION_COUNT = 4; -/** Boss 战强度系数(原压力回合系数) */ -export const BOSS_TYPE_RATIO = 1.2; -/** 最终 Boss 战 HP 乘区(原 wave 20 配置) */ -export const FINAL_HP_MUL = 1.8; -/** 全局怪物强度系数(1 = 怪物强度与英雄能力持平,同时作用于 hp 缩放与 ap 挂钩公式) */ -export const MON_POWER_MUL = 1; -/** 怪物 ap 最终递进系数(原 wave 20 满档 3.0) */ -export const AP_GROWTH_FINAL = 3.0; -/** 怪物 ap 相对玩家平均攻击的基础系数(<1 保证单怪不至于一击致命,由 Boss/精英类型再上浮) */ -export const AP_RELATIVE = 0.6; -/** Boss 血量加成(原 wave 20 bossBonusHpMul = 1.6) */ +/** 怪物血量可调系数:最终 hp = HeroInfo 基础hp × MON_HP_MUL。 + * 2.6 = 校准后怪物总血量 / 3 英雄 30s 输出(≈30 DPS),双方对砍 ≈ 30s 分胜负 */ +export const MON_HP_MUL = 2.6; +/** 怪物攻击可调系数:最终 ap = HeroInfo 基础ap × MON_AP_MUL。 + * 0.9 使 4 小怪+1 Boss 的总 DPS ≈ 20,30s 恰好磨光 3 英雄总血量(≈600) */ +export const MON_AP_MUL = 0.9; +/** Boss 血量额外加成(在 MON_HP_MUL 之上乘算,突出压场定位) */ export const BOSS_HP_BONUS_MUL = 1.6; /** 战斗超时(秒):超过后强制结算整局(残留怪销毁并扣留存分) */ export const BATTLE_TIMEOUT = 90; @@ -371,12 +363,12 @@ export const TestModeConfig = { /** * Boss 组合生成引擎 - * 随机抽一组 Boss 组合,按英雄强度反推怪物强度(最终 Boss 战档位) + * 随机抽一组 Boss 组合,怪物最终属性 = HeroInfo 基础属性 × 可调系数 */ export class RogueSpawningEngine { /** - * 生成一场战斗的怪物列表:随机一组 Boss 组合(1 Boss + 组合小怪)。 + * 生成一场战斗的怪物列表:随机一组 Boss 组合(1 Boss + 4 小怪,属性走基础×系数)。 * Boss 压队尾(登场时由 MissionMonComp 统一布位)。 * @returns 怪物列表(小怪在前、Boss 在尾) */ @@ -406,21 +398,10 @@ export class RogueSpawningEngine { monsters.push(this.makeBoss()); } - // 属性缩放:直接取最终 Boss 战档位系数 - const heroPower = this.getCurrentHeroPower(); - const targetPower = heroPower * BOSS_TYPE_RATIO * MON_POWER_MUL; - const totalBasePower = monsters.reduce((sum, m) => { - const info = HeroInfo[m.uuid]; - return sum + (info ? calcHeroPower(info, 1) : m.hp + m.ap); - }, 0); - if (totalBasePower > 0 && targetPower > 0) { - const hpScale = (targetPower * FINAL_HP_MUL) / totalBasePower; - const heroAvgAp = this.getCurrentHeroAttack(); - for (const m of monsters) { - m.hp = Math.max(1, Math.round(m.hp * hpScale)); - // ap = 玩家平均攻击 × 最终递进 × 基础系数 × 全局强度系数 × 类型系数 - m.ap = Math.max(1, Math.round(heroAvgAp * AP_GROWTH_FINAL * AP_RELATIVE * MON_POWER_MUL * this.getApTypeFactor(m))); - } + // 属性缩放:基础属性 × 可调系数(Boss 血量额外加成),校准目标双方对砍 ≈ 30s + for (const m of monsters) { + m.hp = Math.max(1, Math.round(m.hp * MON_HP_MUL * (m.isBoss ? BOSS_HP_BONUS_MUL : 1))); + m.ap = Math.max(1, Math.round(m.ap * MON_AP_MUL)); } // 挂载组合技能(Boss 专属池 / 小怪普通池) @@ -443,45 +424,6 @@ export class RogueSpawningEngine { reset(): void { } - // ======================== 私有生成子算法 ======================== - - /** - * 计算场上存活英雄的总强度 - * 通过 ECS 查询所有 HeroAttrsComp,累加 calcHeroPower - */ - private getCurrentHeroPower(): number { - let total = 0; - ecs.query(ecs.allOf(HeroAttrsComp)).forEach((entity: ecs.Entity) => { - const attrs = entity.get(HeroAttrsComp); - if (!attrs || attrs.is_dead || attrs.fac !== FacSet.HERO) return; - const info = HeroInfo[attrs.hero_uuid]; - if (!info) return; - // 使用英雄当前等级(升级卡驱动),保证强度评估与实战一致 - const lv = Math.max(1, attrs.lv || 1); - total += calcHeroPower(info, lv); - }); - // 兜底:无英雄时返回基准强度,避免除零 - return Math.max(total, 100); - } - - /** - * 计算场上存活英雄的输出强度(用于怪物 ap 挂钩玩家,独立于总强度框架)。 - * 取玩家英雄的"实时 ap 平均",怪物 ap 以此为锚,保证玩家输出越高、被反击越痛。 - */ - private getCurrentHeroAttack(): number { - let totalAp = 0; - let count = 0; - ecs.query(ecs.allOf(HeroAttrsComp)).forEach((entity: ecs.Entity) => { - const attrs = entity.get(HeroAttrsComp); - if (!attrs || attrs.is_dead || attrs.fac !== FacSet.HERO) return; - totalAp += Math.max(1, attrs.ap || 1); - count++; - }); - // 兜底:无英雄时返回基准攻击,避免除零 - if (count === 0) return 30; - return totalAp / count; // 平均单英雄攻击 - } - /** 测试模式:完全绕过引擎逻辑 */ private generateTestWave(): GeneratedMonster[] { const count = Math.max(1, TestModeConfig.spawnCount || 1); @@ -536,20 +478,6 @@ export class RogueSpawningEngine { }; } - /** - * 怪物 ap 类型系数:Boss 上浮,远程/召唤稍降(避免玻璃大炮互秒),近战/重甲基准。 - */ - private getApTypeFactor(m: GeneratedMonster): number { - if (m.isBoss) return 2.2; // Boss 单发重,符合"压场"定位 - if (m.isBossGuard) return 1.2; // 护卫略高于杂鱼 - switch (m.type) { - case MonType.Long: return 0.9; - case MonType.Summoner: return 0.7; - case MonType.Assassin: return 1.1; - default: return 1.0; // Melee / Heavy - } - } - /** 生成普通怪物 */ private makeMonster(type: MonType, spawnIndex: number): GeneratedMonster { let uuids = MonList[type];