diff --git a/assets/script/game/map/MissionCardComp.ts b/assets/script/game/map/MissionCardComp.ts index e1098791..d1228b47 100644 --- a/assets/script/game/map/MissionCardComp.ts +++ b/assets/script/game/map/MissionCardComp.ts @@ -502,37 +502,72 @@ export class MissionCardComp extends CCComp { } break; case CardType.Attr: - // 属性卡:更新全局属性并刷新主角 + // 属性卡:使用 addBuff 添加永久属性加成 const attrCard = AttrCards[selectedData.uuid]; if (attrCard) { - let globalBefore = 0; - if (smc.global_attrs[attrCard.attr]) { - globalBefore = smc.global_attrs[attrCard.attr][0]; - } - const roleAttrs = role.get(HeroAttrsComp); - let roleBefore = 0; - if (roleAttrs) { - roleBefore = roleAttrs.Attrs[attrCard.attr] || 0; - } - mLogger.log(this.debugMode, 'MissionCard', `[MissionCard] Attr Before: Global=${globalBefore}, Hero=${roleBefore}, Attrs=${JSON.stringify(roleAttrs.Attrs)}`); - - if (!smc.global_attrs[attrCard.attr]) { - smc.global_attrs[attrCard.attr] = [0, 0]; - } - const current = smc.global_attrs[attrCard.attr]; - current[0] += attrCard.value; - current[1] += 1; - - // 直接触发主角属性重算 const attrsComp = role.get(HeroAttrsComp); if (attrsComp) { - attrsComp.recalculateSingleAttr(attrCard.attr); - smc.updateHeroInfo(attrsComp); + // 记录变更前状态 + const roleBefore = attrsComp.Attrs[attrCard.attr] || 0; + + // 构造永久 Buff (time: 0) + const buffConf: BuffConf = { + buff: attrCard.attr, + value: attrCard.value, + // 注意:这里需要根据属性类型决定是 VALUE 还是 RATIO + // 通常 AttrCards 里的 value 如果是百分比属性(如暴击率),配置值可能是 2 (代表2%) + // HeroAttrsComp.addBuff 会根据 BType 累加 + // 为了安全,我们可以查一下 AttrsType,或者默认属性卡都是 VALUE (直接加数值) 或 RATIO (百分比) + // 根据 AttrSet.ts,AttrCards 的 value 是直接数值。 + // 而 HeroAttrsComp.recalculateSingleAttr 中,RATIO 类型的属性也是直接加 totalRatio + // 所以这里关键是 buffConf.BType。 + // 如果我们希望属性卡是"基础值加成"(VALUE) 还是 "百分比加成"(RATIO)? + // 查看 AttrSet.ts: 2003 DEF value: 2 desc: "防御力 +2%" -> 看起来是百分比 + // 2001 AP value: 10 desc: "攻击力 +10" -> 看起来是数值 + // 所以需要根据 attrCard.attr 的类型来决定 BType,或者在 AttrCards 配置中增加 BType 字段 + // 目前 AttrInfo 接口没有 BType。 + // 我们可以引入 AttrsType 来判断默认类型,或者全部作为 VALUE (如果是百分比属性,VALUE也是加到数值上的) + // 修正:HeroAttrsComp.recalculateSingleAttr 中: + // isRatioAttr = AttrsType[attrIndex] === BType.RATIO + // 如果是 RATIO 属性,totalValue + totalRatio + // 如果是 VALUE 属性,totalValue * (1 + totalRatio/100) + + // 策略: + // 如果是数值型属性(如HP, AP),属性卡通常是加固定值 -> BType.VALUE + // 如果是百分比型属性(如暴击率),属性卡加的是点数 -> BType.VALUE (因为最终计算是 totalValue + totalRatio,对于百分比属性 totalValue 就是基础点数) + // 等等,recalculateSingleAttr 对 RATIO 属性是 totalValue + totalRatio + // 如果暴击率基础是 0,加 2%暴击率。 + // 如果用 BType.VALUE, totalValue += 2。 结果 = 2 + 0 = 2。正确。 + // 如果用 BType.RATIO, totalRatio += 2。 结果 = 0 + 2 = 2。也正确。 + + // 但是对于数值型属性(如AP): + // 攻击力 +10。 + // 用 BType.VALUE, totalValue += 10。 结果 = (Base+10) * (1+Ratio)。正确。 + // 用 BType.RATIO, totalRatio += 10。 结果 = Base * (1+10/100) = Base * 1.1。这是加10%,不是加10点。 + + // 结论:AttrCards 中的 value 看起来都是"点数"或"绝对值",所以应该统一使用 BType.VALUE。 + // 即使是 "防御力 +2%" (2003),如果 DEF 是 RATIO 类型(AttrSet.ts里定义为RATIO? 不,DEF通常是混合,但这里AttrsType定义DEF是RATIO? 让我们查一下) + // 查 AttrsType: [Attrs.DEF]: BType.RATIO + // 如果 DEF 是 RATIO,那 +2% 就是 +2 数值。 + // 所以统一用 BType.VALUE 是安全的,代表"增加属性面板数值"。 + + BType: BType.VALUE, + time: 0, + chance: 1, + }; + + mLogger.log(this.debugMode, 'MissionCard', `[MissionCard] Adding Buff: Attr=${attrCard.attr}, Val=${attrCard.value}, Type=VALUE`); + + attrsComp.addBuff(buffConf); + // addBuff 内部会自动调用 recalculateSingleAttr 和 updateHeroInfo const roleAfter = attrsComp.Attrs[attrCard.attr] || 0; - mLogger.log(this.debugMode, 'MissionCard', `[MissionCard] Attr After: Global=${current[0]}, Hero=${roleAfter}, Attrs=${JSON.stringify(attrsComp.Attrs)}`); + mLogger.log(this.debugMode, 'MissionCard', `[MissionCard] Attr After: Hero=${roleAfter} (Change: ${roleAfter - roleBefore})`); + + oops.gui.toast(attrCard.desc); } - oops.gui.toast(attrCard.desc); + } else { + console.warn(`[MissionCard] 未找到属性卡配置: UUID=${selectedData.uuid}`); } break; }