From b577350003524fdadfaa835ba1bb6f6796ab8561 Mon Sep 17 00:00:00 2001 From: walkpan Date: Fri, 16 Jan 2026 20:11:02 +0800 Subject: [PATCH] =?UTF-8?q?refactor(CardSet):=20=E9=87=8D=E6=9E=84?= =?UTF-8?q?=E9=BB=98=E8=AE=A4=E5=8D=A1=E6=B1=A0=E8=8E=B7=E5=8F=96=E9=80=BB?= =?UTF-8?q?=E8=BE=91=EF=BC=8C=E6=94=AF=E6=8C=81=E5=8A=A8=E6=80=81=E6=9D=83?= =?UTF-8?q?=E9=87=8D=E8=AE=A1=E7=AE=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 重构 getDefaultPool 函数,将重复逻辑统一处理并支持基于解锁等级的动态权重计算。新实现: 1. 统一处理所有卡牌类型的配置映射 2. 自动累加所有小于等于当前等级的配置项 3. 根据解锁等级动态计算权重,高等级卡牌出现概率更高 4. 保留原有兜底逻辑作为最后防线 --- assets/script/game/common/config/CardSet.ts | 139 ++++++++++++-------- 1 file changed, 86 insertions(+), 53 deletions(-) diff --git a/assets/script/game/common/config/CardSet.ts b/assets/script/game/common/config/CardSet.ts index 4b5827e2..8f80f719 100644 --- a/assets/script/game/common/config/CardSet.ts +++ b/assets/script/game/common/config/CardSet.ts @@ -138,77 +138,110 @@ function getCardBaseInfo(type: CardType, uuid: number): ICardInfo | null { } /** - * 获取默认的全量池 (当配置未指定items时使用) + * 获取指定类型的全量池 + * 自动累加所有 <= level 的配置项 * @param type 卡牌类型 - * @param level 当前等级(可选,用于从各模块的CanSelect配置中获取) + * @param level 当前等级 */ function getDefaultPool(type: CardType, level: number = 1): IPoolItem[] { const items: IPoolItem[] = []; + let configMap: Record | null = null; + let defaultWeight = 100; + switch (type) { case CardType.Attr: - // 优先使用 CanSelectAttrs 中的配置 - if (CanSelectAttrs[level]) { - CanSelectAttrs[level].forEach(id => items.push({ id, weight: 100 })); - } else if (CanSelectAttrs[99]) { - // 默认池 - CanSelectAttrs[99].forEach(id => items.push({ id, weight: 100 })); - } else { - // 全量兜底 - Object.keys(AttrCards).forEach(key => items.push({ id: Number(key), weight: 100 })); - } + configMap = CanSelectAttrs; + defaultWeight = 100; break; case CardType.Talent: - // 优先使用 CanSelectTalents 中的配置 - if (CanSelectTalents[level]) { - CanSelectTalents[level].forEach(id => items.push({ id, weight: 50 })); - } else if (CanSelectTalents[99]) { - // 默认池 - CanSelectTalents[99].forEach(id => items.push({ id, weight: 50 })); - } else { - // 全量兜底 - Object.keys(talConf).forEach(key => items.push({ id: Number(key), weight: 50 })); - } + configMap = CanSelectTalents; + defaultWeight = 50; break; case CardType.Skill: - // 优先使用 CanSelectSkills 中的配置 - if (CanSelectSkills[level]) { - CanSelectSkills[level].forEach(id => items.push({ id, weight: 80 })); - } else if (CanSelectSkills[99]) { - // 默认池 - CanSelectSkills[99].forEach(id => items.push({ id, weight: 80 })); - } else { - // 全量兜底 - Object.keys(SkillSet).forEach(key => items.push({ id: Number(key), weight: 80 })); - } + configMap = CanSelectSkills; + defaultWeight = 80; break; case CardType.Partner: - // 优先使用 CanSelectHeros 中的配置 - if (CanSelectHeros[level]) { - CanSelectHeros[level].forEach(id => items.push({ id, weight: 100 })); - } else if (CanSelectHeros[99]) { - // 默认池 - CanSelectHeros[99].forEach(id => items.push({ id, weight: 100 })); - } else { - // 全量兜底 (排除怪物) + configMap = CanSelectHeros; + defaultWeight = 100; + break; + case CardType.Potion: + configMap = CanSelectPotions; + defaultWeight = 100; + break; + } + + if (configMap) { + // 收集所有已解锁的ID (去重) + const unlockedIds = new Set(); + + // 1. 遍历所有等级配置,收集 <= level 的项 + Object.keys(configMap).forEach(lvlStr => { + const lv = parseInt(lvlStr); + // 忽略 99 (默认全开) 这种特殊标记,只处理正常等级逻辑 + if (lv <= level && lv !== 99) { + const ids = configMap![lv]; + if (ids) { + // 计算权重:等级越高,权重越高 + // 基础权重 defaultWeight + // 额外权重:(解锁等级 / 当前等级) * 基础权重 * 2 + // 例如:当前10级 + // 1级卡权重: 100 + (1/10)*200 = 120 + // 9级卡权重: 100 + (9/10)*200 = 280 + // 这样新解锁的卡牌出现概率显著高于旧卡牌 + const extraWeight = Math.floor((lv / Math.max(1, level)) * defaultWeight * 2); + const finalWeight = defaultWeight + extraWeight; + + ids.forEach(id => { + // 如果已经存在(可能在低等级也配置了),取最大权重 + const existing = items.find(i => i.id === id); + if (existing) { + existing.weight = Math.max(existing.weight, finalWeight); + } else { + items.push({ id, weight: finalWeight }); + } + unlockedIds.add(id); + }); + } + } + }); + + // 2. 如果当前等级没有任何解锁项,且存在 99 号默认配置,则回退使用 99 号配置 + // 这种行为保持了原有逻辑的"兜底"特性,但更智能 + if (unlockedIds.size === 0 && configMap[99]) { + configMap[99].forEach(id => { + items.push({ id, weight: defaultWeight }); + unlockedIds.add(id); + }); + } + + // 3. 构建结果 (items 已经在循环中构建好了,这里不需要再从 unlockedIds 重新构建) + // unlockedIds.forEach(id => items.push({ id, weight: defaultWeight })); + } else { + // 兜底逻辑:如果该类型没有配置表 (理论上不应发生,除非新增类型未配置) + // 这里保留原有的全量兜底逻辑作为最后的防线 + switch (type) { + case CardType.Attr: + Object.keys(AttrCards).forEach(key => items.push({ id: Number(key), weight: 100 })); + break; + case CardType.Talent: + Object.keys(talConf).forEach(key => items.push({ id: Number(key), weight: 50 })); + break; + case CardType.Skill: + Object.keys(SkillSet).forEach(key => items.push({ id: Number(key), weight: 80 })); + break; + case CardType.Partner: Object.keys(HeroInfo).forEach(key => { const id = Number(key); if (id < 5200) items.push({ id, weight: 100 }); }); - } - break; - case CardType.Potion: - // 优先使用 CanSelectPotions 中的配置 - if (CanSelectPotions[level]) { - CanSelectPotions[level].forEach(id => items.push({ id, weight: 100 })); - } else if (CanSelectPotions[99]) { - // 默认池 - CanSelectPotions[99].forEach(id => items.push({ id, weight: 100 })); - } else { - // 全量兜底 + break; + case CardType.Potion: Object.keys(PotionCards).forEach(key => items.push({ id: Number(key), weight: 100 })); - } - break; + break; + } } + return items; }