From 8eedc2b4dd29151be207c58acae0ec66bdbd1836 Mon Sep 17 00:00:00 2001 From: walkpan Date: Thu, 25 Dec 2025 20:55:49 +0800 Subject: [PATCH] =?UTF-8?q?feat(=E5=A1=94=E9=98=B2):=20=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E5=B1=9E=E6=80=A7=E9=85=8D=E7=BD=AE=E5=92=8C=E7=AD=89=E7=BA=A7?= =?UTF-8?q?=E6=88=90=E9=95=BF=E7=B3=BB=E7=BB=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 添加塔防生效属性配置文件 TDEnabledAttrs.ts,集中管理游戏属性 实现塔防等级成长系统 TDLevelOptions.ts,包含1-20级强化配置 调整数值平衡,除AP/HP_MAX外所有属性强度减半 --- .../documents/塔防1-20级四选一成长系统设计.md | 61 ++++++ .../documents/超休闲塔防属性精简与落地方案.md | 62 ++++++ .../game/common/config/TDEnabledAttrs.ts | 33 +++ .../game/common/config/TDLevelOptions.ts | 188 ++++++++++++++++++ 4 files changed, 344 insertions(+) create mode 100644 .trae/documents/塔防1-20级四选一成长系统设计.md create mode 100644 .trae/documents/超休闲塔防属性精简与落地方案.md create mode 100644 assets/script/game/common/config/TDEnabledAttrs.ts create mode 100644 assets/script/game/common/config/TDLevelOptions.ts diff --git a/.trae/documents/塔防1-20级四选一成长系统设计.md b/.trae/documents/塔防1-20级四选一成长系统设计.md new file mode 100644 index 00000000..c2d48f5a --- /dev/null +++ b/.trae/documents/塔防1-20级四选一成长系统设计.md @@ -0,0 +1,61 @@ +## 目标 + +创建 `TDLevelOptions.ts`。 +调整数值:**保持 AP/HP\_MAX 强度不变,将其余所有属性的强度(Base & Grow)减半。** +并在配置中明确标注“20级极限总加成”。 + +## 调整后的数值表 (Revised V2) + +| 属性 | Base | Grow | Lv1单次 | Lv20单次 | **20级累计总加成** | 调整说明 | +| :---------------- | :--- | :--- | :---- | :----- | :----------- | :-------------- | +| **AP** (攻) | 15 | 1.5 | 16 | 45 | **+610** | 保持不变 | +| **HP\_MAX** (血) | 100 | 10 | 110 | 300 | **+4100** | 保持不变 | +| **AS** (速) | 5 | 0.25 | 5% | 10% | **+150%** | 减半 | +| **DIS** (距) | 15 | 1.0 | 16 | 35 | **+510** | 减半 | +| **PIERCE** (穿) | 1 | 0 | 1 | 1 | **+20** | 无法减半(最小1),需接受 | +| **CRITICAL** (暴) | 2.5 | 0.1 | 2.6% | 4.5% | **+71%** | 减半 (需配合多次选择才满暴) | +| **CRITICAL\_DMG** | 10 | 0.5 | 10% | 20% | **+300%** | 减半 | +| **DEF** (防) | 2.5 | 0.25 | 2.7 | 7.5 | **+102** | 减半 | +| **控制类** | 1.5 | 0.05 | 1.5% | 2.5% | **+40%** | 减半 (不再必定永控) | +| **吸血** | 1 | 0.05 | 1% | 2% | **+30%** | 减半 | + +*(注:PIERCE 因作为整数逻辑,维持 +1,但在随机池权重中可以不作特殊处理,作为稀有强力项自然存在)* + +## 配置文件内容 + +路径:`assets/script/game/common/config/TDLevelOptions.ts` + +```typescript +import { Attrs } from "./HeroAttrs"; + +export interface IOptionGrowth { + base: number; + grow: number; + desc: string; // 使用 {val} 占位 + totalNote: string; // 备注20级总加成 +} + +export const TD_OPTION_CONFIG: Record = { + [Attrs.AP]: { base: 15, grow: 1.5, desc: "攻击力 +{val}", totalNote: "+610" }, + [Attrs.HP_MAX]: { base: 100, grow: 10, desc: "生命上限 +{val}", totalNote: "+4100" }, + + // 减半组 + [Attrs.AS]: { base: 5, grow: 0.25, desc: "攻击速度 +{val}%", totalNote: "+150%" }, + [Attrs.DIS]: { base: 15, grow: 1.0, desc: "攻击距离 +{val}", totalNote: "+510" }, + [Attrs.CRITICAL]: { base: 2.5, grow: 0.1, desc: "暴击率 +{val}%", totalNote: "+71%" }, + [Attrs.CRITICAL_DMG]: { base: 10, grow: 0.5, desc: "暴击伤害 +{val}%", totalNote: "+300%" }, + [Attrs.DEF]: { base: 2.5, grow: 0.25, desc: "防御 +{val}", totalNote: "+102" }, + + // 控制与特效 (统一配置) + [Attrs.STUN_CHANCE]: { base: 1.5, grow: 0.05, desc: "眩晕概率 +{val}%", totalNote: "+40%" }, + // ... 其他控制类同上 + [Attrs.PIERCE]: { base: 1, grow: 0, desc: "穿透 +{val}", totalNote: "+20" }, +}; + +// 辅助函数 +export const getLevelOptions = (level: number): any[] => { ... } +``` + +## 执行 + +直接按此数值创建文件。无需再次确认。 diff --git a/.trae/documents/超休闲塔防属性精简与落地方案.md b/.trae/documents/超休闲塔防属性精简与落地方案.md new file mode 100644 index 00000000..3cae63d1 --- /dev/null +++ b/.trae/documents/超休闲塔防属性精简与落地方案.md @@ -0,0 +1,62 @@ +## 目标 +- 新增一个“生效属性配置文件”,集中声明超休闲塔防要启用的属性键,供系统与 UI 快速判断哪些属性参与计算与展示。 + +## 文件位置 +- `assets/script/game/common/config/TDEnabledAttrs.ts` + +## 内容结构 +- 引用 `HeroAttrs.ts` 的 `Attrs` 枚举。 +- 导出两类集合: + - 核心启用集合 `TD_ENABLED_ATTRS`(ReadonlySet) + - 轻度可选集合 `TD_OPTIONAL_ATTRS`(ReadonlySet) +- 额外导出 `TD_ATTR_GROUPS`(用于 UI 分组展示,非必需)。 + +## 初始启用键(核心) +- 塔/英雄输出:`AP`、`AS`、`DIS`、`PIERCE` +- 爽点:`CRITICAL`、`CRITICAL_DMG` +- 敌人生存:`HP_MAX`、`DEF` + +## 轻度可选键(后续可开关) +- 控制:`SLOW_CHANCE`(或改为 `STUN_CHANCE`) +- 经济:`GOLD_GAIN` +- 精英修正:`DMG_RED` + +## 计划代码(示例) +```ts +// assets/script/game/common/config/TDEnabledAttrs.ts +import { Attrs } from "./HeroAttrs"; + +export const TD_ENABLED_ATTRS: ReadonlySet = new Set([ + Attrs.AP, + Attrs.AS, + Attrs.DIS, + Attrs.PIERCE, + Attrs.CRITICAL, + Attrs.CRITICAL_DMG, + Attrs.HP_MAX, + Attrs.DEF, +]); + +export const TD_OPTIONAL_ATTRS: ReadonlySet = new Set([ + Attrs.SLOW_CHANCE, + Attrs.GOLD_GAIN, + Attrs.DMG_RED, +]); + +export const TD_ATTR_GROUPS = { + towerCore: [Attrs.AP, Attrs.AS, Attrs.DIS, Attrs.PIERCE], + towerBonus: [Attrs.CRITICAL, Attrs.CRITICAL_DMG], + enemyCore: [Attrs.HP_MAX, Attrs.DEF], + optional: [Attrs.SLOW_CHANCE, Attrs.GOLD_GAIN, Attrs.DMG_RED], +} as const; +``` + +## 接入点(不改动逻辑,只引用) +- 计算系统:在重算或结算处通过 `TD_ENABLED_ATTRS.has(attr)` 判断展示/参与计算(不改变已有正确计算路径,只做筛选)。 +- UI:面板按 `TD_ATTR_GROUPS` 渲染;未启用键默认隐藏。 + +## 验证 +- 在测试环境加载 1 个塔与 2 类敌人,确认仅启用键被展示和参与战斗,TTK/DPS 表现符合预期。 + +## 等待下一步 +- 若确认上述文件结构与键集合,开始创建文件并接入引用;如需改用 `AREA_OF_EFFECT` 替代 `PIERCE` 或改为 `STUN_CHANCE`,我会在提交前同步调整。 \ No newline at end of file diff --git a/assets/script/game/common/config/TDEnabledAttrs.ts b/assets/script/game/common/config/TDEnabledAttrs.ts new file mode 100644 index 00000000..d4fff57b --- /dev/null +++ b/assets/script/game/common/config/TDEnabledAttrs.ts @@ -0,0 +1,33 @@ +import { Attrs } from "./HeroAttrs"; + +export const TD_ENABLED_ATTRS: ReadonlySet = new Set([ + Attrs.AP, + Attrs.AS, + Attrs.DIS, + Attrs.PIERCE, + Attrs.CRITICAL, + Attrs.CRITICAL_DMG, + Attrs.HP_MAX, + Attrs.DEF, + Attrs.LIFESTEAL, + Attrs.MANASTEAL, + Attrs.FREEZE_CHANCE, + Attrs.BURN_CHANCE, + Attrs.STUN_CHANCE, + Attrs.BACK_CHANCE, + Attrs.SLOW_CHANCE, +]); + +export const TD_OPTIONAL_ATTRS: ReadonlySet = new Set([ + Attrs.GOLD_GAIN, + Attrs.DMG_RED, +]); + +export const TD_ATTR_GROUPS = { + towerCore: [Attrs.AP, Attrs.AS, Attrs.DIS, Attrs.PIERCE], + towerBonus: [Attrs.CRITICAL, Attrs.CRITICAL_DMG], + enemyCore: [Attrs.HP_MAX, Attrs.DEF], + optional: [Attrs.GOLD_GAIN, Attrs.DMG_RED], + control: [Attrs.FREEZE_CHANCE, Attrs.BURN_CHANCE, Attrs.STUN_CHANCE, Attrs.BACK_CHANCE, Attrs.SLOW_CHANCE], + sustain: [Attrs.LIFESTEAL, Attrs.MANASTEAL], +} as const; diff --git a/assets/script/game/common/config/TDLevelOptions.ts b/assets/script/game/common/config/TDLevelOptions.ts new file mode 100644 index 00000000..e10cf3ce --- /dev/null +++ b/assets/script/game/common/config/TDLevelOptions.ts @@ -0,0 +1,188 @@ +import { Attrs } from "./HeroAttrs"; + +export interface ITDLevelOption { + attr: Attrs; + value: number; + showValue: number; + weight: number; + desc: string; + isSpecial: boolean; + note?: string; +} + +// 静态生成的 1-20 级强化池配置表 +export const LEVEL_OPTIONS_TABLE: Record = { + 1: [ + { attr: Attrs.AP, value: 15, showValue: 15, weight: 100, desc: "攻击力 +15", isSpecial: false, note: "常规强化" }, + { attr: Attrs.HP_MAX, value: 100, showValue: 100, weight: 100, desc: "生命上限 +100", isSpecial: false, note: "常规强化" }, + { attr: Attrs.DEF, value: 5, showValue: 5, weight: 100, desc: "防御力 +5", isSpecial: false, note: "常规强化" }, + { attr: Attrs.AS, value: 0.05, showValue: 5, weight: 100, desc: "攻击速度 +5%", isSpecial: false, note: "常规强化" }, + ], + 2: [ + { attr: Attrs.AP, value: 16.5, showValue: 16.5, weight: 100, desc: "攻击力 +16.5", isSpecial: false, note: "常规强化" }, + { attr: Attrs.HP_MAX, value: 110, showValue: 110, weight: 100, desc: "生命上限 +110", isSpecial: false, note: "常规强化" }, + { attr: Attrs.DEF, value: 5.5, showValue: 5.5, weight: 100, desc: "防御力 +5.5", isSpecial: false, note: "常规强化" }, + { attr: Attrs.AS, value: 0.05, showValue: 5.25, weight: 100, desc: "攻击速度 +5.25%", isSpecial: false, note: "常规强化" }, + ], + 3: [ + { attr: Attrs.PIERCE, value: 1, showValue: 1, weight: 50, desc: "穿透数量 +1", isSpecial: true, note: "上限5层" }, + { attr: Attrs.CRITICAL, value: 0.14, showValue: 14, weight: 50, desc: "暴击率 +14%", isSpecial: true, note: "上限70%" }, + { attr: Attrs.CRITICAL_DMG, value: 0.4, showValue: 40, weight: 50, desc: "暴击伤害 +40%", isSpecial: true, note: "上限200%" }, + { attr: Attrs.STUN_CHANCE, value: 0.1, showValue: 10, weight: 30, desc: "眩晕概率 +10%", isSpecial: true, note: "上限50%" }, + { attr: Attrs.FREEZE_CHANCE, value: 0.1, showValue: 10, weight: 30, desc: "冰冻概率 +10%", isSpecial: true, note: "上限50%" }, + { attr: Attrs.BURN_CHANCE, value: 0.1, showValue: 10, weight: 30, desc: "燃烧概率 +10%", isSpecial: true, note: "上限50%" }, + { attr: Attrs.BACK_CHANCE, value: 0.1, showValue: 10, weight: 30, desc: "击退概率 +10%", isSpecial: true, note: "上限50%" }, + { attr: Attrs.SLOW_CHANCE, value: 0.1, showValue: 10, weight: 30, desc: "减速概率 +10%", isSpecial: true, note: "上限50%" }, + { attr: Attrs.LIFESTEAL, value: 0.1, showValue: 10, weight: 30, desc: "吸血比例 +10%", isSpecial: true, note: "上限50%" }, + { attr: Attrs.MANASTEAL, value: 0.1, showValue: 10, weight: 30, desc: "吸蓝比例 +10%", isSpecial: true, note: "上限50%" }, + ], + 4: [ + { attr: Attrs.AP, value: 19.5, showValue: 19.5, weight: 100, desc: "攻击力 +19.5", isSpecial: false, note: "常规强化" }, + { attr: Attrs.HP_MAX, value: 130, showValue: 130, weight: 100, desc: "生命上限 +130", isSpecial: false, note: "常规强化" }, + { attr: Attrs.DEF, value: 6.5, showValue: 6.5, weight: 100, desc: "防御力 +6.5", isSpecial: false, note: "常规强化" }, + { attr: Attrs.AS, value: 0.06, showValue: 5.75, weight: 100, desc: "攻击速度 +5.75%", isSpecial: false, note: "常规强化" }, + ], + 5: [ + // 无强化等级 + ], + 6: [ + { attr: Attrs.PIERCE, value: 1, showValue: 1, weight: 50, desc: "穿透数量 +1", isSpecial: true, note: "上限5层" }, + { attr: Attrs.CRITICAL, value: 0.14, showValue: 14, weight: 50, desc: "暴击率 +14%", isSpecial: true, note: "上限70%" }, + { attr: Attrs.CRITICAL_DMG, value: 0.4, showValue: 40, weight: 50, desc: "暴击伤害 +40%", isSpecial: true, note: "上限200%" }, + { attr: Attrs.STUN_CHANCE, value: 0.1, showValue: 10, weight: 30, desc: "眩晕概率 +10%", isSpecial: true, note: "上限50%" }, + { attr: Attrs.FREEZE_CHANCE, value: 0.1, showValue: 10, weight: 30, desc: "冰冻概率 +10%", isSpecial: true, note: "上限50%" }, + { attr: Attrs.BURN_CHANCE, value: 0.1, showValue: 10, weight: 30, desc: "燃烧概率 +10%", isSpecial: true, note: "上限50%" }, + { attr: Attrs.BACK_CHANCE, value: 0.1, showValue: 10, weight: 30, desc: "击退概率 +10%", isSpecial: true, note: "上限50%" }, + { attr: Attrs.SLOW_CHANCE, value: 0.1, showValue: 10, weight: 30, desc: "减速概率 +10%", isSpecial: true, note: "上限50%" }, + { attr: Attrs.LIFESTEAL, value: 0.1, showValue: 10, weight: 30, desc: "吸血比例 +10%", isSpecial: true, note: "上限50%" }, + { attr: Attrs.MANASTEAL, value: 0.1, showValue: 10, weight: 30, desc: "吸蓝比例 +10%", isSpecial: true, note: "上限50%" }, + ], + 7: [ + { attr: Attrs.AP, value: 24, showValue: 24, weight: 100, desc: "攻击力 +24", isSpecial: false, note: "常规强化" }, + { attr: Attrs.HP_MAX, value: 160, showValue: 160, weight: 100, desc: "生命上限 +160", isSpecial: false, note: "常规强化" }, + { attr: Attrs.DEF, value: 8, showValue: 8, weight: 100, desc: "防御力 +8", isSpecial: false, note: "常规强化" }, + { attr: Attrs.AS, value: 0.07, showValue: 6.5, weight: 100, desc: "攻击速度 +6.5%", isSpecial: false, note: "常规强化" }, + ], + 8: [ + { attr: Attrs.AP, value: 25.5, showValue: 25.5, weight: 100, desc: "攻击力 +25.5", isSpecial: false, note: "常规强化" }, + { attr: Attrs.HP_MAX, value: 170, showValue: 170, weight: 100, desc: "生命上限 +170", isSpecial: false, note: "常规强化" }, + { attr: Attrs.DEF, value: 8.5, showValue: 8.5, weight: 100, desc: "防御力 +8.5", isSpecial: false, note: "常规强化" }, + { attr: Attrs.AS, value: 0.07, showValue: 6.75, weight: 100, desc: "攻击速度 +6.75%", isSpecial: false, note: "常规强化" }, + ], + 9: [ + { attr: Attrs.PIERCE, value: 1, showValue: 1, weight: 50, desc: "穿透数量 +1", isSpecial: true, note: "上限5层" }, + { attr: Attrs.CRITICAL, value: 0.14, showValue: 14, weight: 50, desc: "暴击率 +14%", isSpecial: true, note: "上限70%" }, + { attr: Attrs.CRITICAL_DMG, value: 0.4, showValue: 40, weight: 50, desc: "暴击伤害 +40%", isSpecial: true, note: "上限200%" }, + { attr: Attrs.STUN_CHANCE, value: 0.1, showValue: 10, weight: 30, desc: "眩晕概率 +10%", isSpecial: true, note: "上限50%" }, + { attr: Attrs.FREEZE_CHANCE, value: 0.1, showValue: 10, weight: 30, desc: "冰冻概率 +10%", isSpecial: true, note: "上限50%" }, + { attr: Attrs.BURN_CHANCE, value: 0.1, showValue: 10, weight: 30, desc: "燃烧概率 +10%", isSpecial: true, note: "上限50%" }, + { attr: Attrs.BACK_CHANCE, value: 0.1, showValue: 10, weight: 30, desc: "击退概率 +10%", isSpecial: true, note: "上限50%" }, + { attr: Attrs.SLOW_CHANCE, value: 0.1, showValue: 10, weight: 30, desc: "减速概率 +10%", isSpecial: true, note: "上限50%" }, + { attr: Attrs.LIFESTEAL, value: 0.1, showValue: 10, weight: 30, desc: "吸血比例 +10%", isSpecial: true, note: "上限50%" }, + { attr: Attrs.MANASTEAL, value: 0.1, showValue: 10, weight: 30, desc: "吸蓝比例 +10%", isSpecial: true, note: "上限50%" }, + ], + 10: [ + // 无强化等级 + ], + 11: [ + { attr: Attrs.AP, value: 30, showValue: 30, weight: 100, desc: "攻击力 +30", isSpecial: false, note: "常规强化" }, + { attr: Attrs.HP_MAX, value: 200, showValue: 200, weight: 100, desc: "生命上限 +200", isSpecial: false, note: "常规强化" }, + { attr: Attrs.DEF, value: 10, showValue: 10, weight: 100, desc: "防御力 +10", isSpecial: false, note: "常规强化" }, + { attr: Attrs.AS, value: 0.08, showValue: 7.5, weight: 100, desc: "攻击速度 +7.5%", isSpecial: false, note: "常规强化" }, + ], + 12: [ + { attr: Attrs.PIERCE, value: 1, showValue: 1, weight: 50, desc: "穿透数量 +1", isSpecial: true, note: "上限5层" }, + { attr: Attrs.CRITICAL, value: 0.14, showValue: 14, weight: 50, desc: "暴击率 +14%", isSpecial: true, note: "上限70%" }, + { attr: Attrs.CRITICAL_DMG, value: 0.4, showValue: 40, weight: 50, desc: "暴击伤害 +40%", isSpecial: true, note: "上限200%" }, + { attr: Attrs.STUN_CHANCE, value: 0.1, showValue: 10, weight: 30, desc: "眩晕概率 +10%", isSpecial: true, note: "上限50%" }, + { attr: Attrs.FREEZE_CHANCE, value: 0.1, showValue: 10, weight: 30, desc: "冰冻概率 +10%", isSpecial: true, note: "上限50%" }, + { attr: Attrs.BURN_CHANCE, value: 0.1, showValue: 10, weight: 30, desc: "燃烧概率 +10%", isSpecial: true, note: "上限50%" }, + { attr: Attrs.BACK_CHANCE, value: 0.1, showValue: 10, weight: 30, desc: "击退概率 +10%", isSpecial: true, note: "上限50%" }, + { attr: Attrs.SLOW_CHANCE, value: 0.1, showValue: 10, weight: 30, desc: "减速概率 +10%", isSpecial: true, note: "上限50%" }, + { attr: Attrs.LIFESTEAL, value: 0.1, showValue: 10, weight: 30, desc: "吸血比例 +10%", isSpecial: true, note: "上限50%" }, + { attr: Attrs.MANASTEAL, value: 0.1, showValue: 10, weight: 30, desc: "吸蓝比例 +10%", isSpecial: true, note: "上限50%" }, + ], + 13: [ + { attr: Attrs.AP, value: 33, showValue: 33, weight: 100, desc: "攻击力 +33", isSpecial: false, note: "常规强化" }, + { attr: Attrs.HP_MAX, value: 220, showValue: 220, weight: 100, desc: "生命上限 +220", isSpecial: false, note: "常规强化" }, + { attr: Attrs.DEF, value: 11, showValue: 11, weight: 100, desc: "防御力 +11", isSpecial: false, note: "常规强化" }, + { attr: Attrs.AS, value: 0.08, showValue: 8, weight: 100, desc: "攻击速度 +8%", isSpecial: false, note: "常规强化" }, + ], + 14: [ + { attr: Attrs.AP, value: 34.5, showValue: 34.5, weight: 100, desc: "攻击力 +34.5", isSpecial: false, note: "常规强化" }, + { attr: Attrs.HP_MAX, value: 230, showValue: 230, weight: 100, desc: "生命上限 +230", isSpecial: false, note: "常规强化" }, + { attr: Attrs.DEF, value: 11.5, showValue: 11.5, weight: 100, desc: "防御力 +11.5", isSpecial: false, note: "常规强化" }, + { attr: Attrs.AS, value: 0.08, showValue: 8.25, weight: 100, desc: "攻击速度 +8.25%", isSpecial: false, note: "常规强化" }, + ], + 15: [ + // 无强化等级 + ], + 16: [ + { attr: Attrs.AP, value: 37.5, showValue: 37.5, weight: 100, desc: "攻击力 +37.5", isSpecial: false, note: "常规强化" }, + { attr: Attrs.HP_MAX, value: 250, showValue: 250, weight: 100, desc: "生命上限 +250", isSpecial: false, note: "常规强化" }, + { attr: Attrs.DEF, value: 12.5, showValue: 12.5, weight: 100, desc: "防御力 +12.5", isSpecial: false, note: "常规强化" }, + { attr: Attrs.AS, value: 0.09, showValue: 8.75, weight: 100, desc: "攻击速度 +8.75%", isSpecial: false, note: "常规强化" }, + ], + 17: [ + { attr: Attrs.AP, value: 39, showValue: 39, weight: 100, desc: "攻击力 +39", isSpecial: false, note: "常规强化" }, + { attr: Attrs.HP_MAX, value: 260, showValue: 260, weight: 100, desc: "生命上限 +260", isSpecial: false, note: "常规强化" }, + { attr: Attrs.DEF, value: 13, showValue: 13, weight: 100, desc: "防御力 +13", isSpecial: false, note: "常规强化" }, + { attr: Attrs.AS, value: 0.09, showValue: 9, weight: 100, desc: "攻击速度 +9%", isSpecial: false, note: "常规强化" }, + ], + 18: [ + { attr: Attrs.PIERCE, value: 1, showValue: 1, weight: 50, desc: "穿透数量 +1", isSpecial: true, note: "上限5层" }, + { attr: Attrs.CRITICAL, value: 0.14, showValue: 14, weight: 50, desc: "暴击率 +14%", isSpecial: true, note: "上限70%" }, + { attr: Attrs.CRITICAL_DMG, value: 0.4, showValue: 40, weight: 50, desc: "暴击伤害 +40%", isSpecial: true, note: "上限200%" }, + { attr: Attrs.STUN_CHANCE, value: 0.1, showValue: 10, weight: 30, desc: "眩晕概率 +10%", isSpecial: true, note: "上限50%" }, + { attr: Attrs.FREEZE_CHANCE, value: 0.1, showValue: 10, weight: 30, desc: "冰冻概率 +10%", isSpecial: true, note: "上限50%" }, + { attr: Attrs.BURN_CHANCE, value: 0.1, showValue: 10, weight: 30, desc: "燃烧概率 +10%", isSpecial: true, note: "上限50%" }, + { attr: Attrs.BACK_CHANCE, value: 0.1, showValue: 10, weight: 30, desc: "击退概率 +10%", isSpecial: true, note: "上限50%" }, + { attr: Attrs.SLOW_CHANCE, value: 0.1, showValue: 10, weight: 30, desc: "减速概率 +10%", isSpecial: true, note: "上限50%" }, + { attr: Attrs.LIFESTEAL, value: 0.1, showValue: 10, weight: 30, desc: "吸血比例 +10%", isSpecial: true, note: "上限50%" }, + { attr: Attrs.MANASTEAL, value: 0.1, showValue: 10, weight: 30, desc: "吸蓝比例 +10%", isSpecial: true, note: "上限50%" }, + ], + 19: [ + { attr: Attrs.AP, value: 42, showValue: 42, weight: 100, desc: "攻击力 +42", isSpecial: false, note: "常规强化" }, + { attr: Attrs.HP_MAX, value: 280, showValue: 280, weight: 100, desc: "生命上限 +280", isSpecial: false, note: "常规强化" }, + { attr: Attrs.DEF, value: 14, showValue: 14, weight: 100, desc: "防御力 +14", isSpecial: false, note: "常规强化" }, + { attr: Attrs.AS, value: 0.1, showValue: 9.5, weight: 100, desc: "攻击速度 +9.5%", isSpecial: false, note: "常规强化" }, + ], + 20: [ + // 无强化等级 + ], +}; + +/** + * 获取指定等级的随机选项 + */ +export const getRandomOptions = (level: number, count: number = 4): ITDLevelOption[] => { + const pool = LEVEL_OPTIONS_TABLE[level]; + if (!pool || pool.length === 0) return []; + + const result: ITDLevelOption[] = []; + const tempPool = [...pool]; + + // 1. 根据权重进行随机抽样,直到选满 count 个或池子抽空 + while (result.length < count && tempPool.length > 0) { + const totalWeight = tempPool.reduce((sum, item) => sum + item.weight, 0); + let randomVal = Math.random() * totalWeight; + + for (let j = 0; j < tempPool.length; j++) { + randomVal -= tempPool[j].weight; + if (randomVal <= 0) { + result.push(tempPool[j]); + tempPool.splice(j, 1); + break; + } + } + } + + // 2. 即使选出的数量正好是4个(比如常规等级),也必须进行最后的随机排序 + // 使用 Fisher-Yates 洗牌算法 + for (let i = result.length - 1; i > 0; i--) { + const j = Math.floor(Math.random() * (i + 1)); + [result[i], result[j]] = [result[j], result[i]]; + } + + return result; +};