refactor(卡牌): 将卡牌效果应用逻辑改为直接调用组件方法
移除 HeroAttrsComp 中对 UseItemCard 和 UseAttrCard 的事件监听,改为在 MissionCardComp 中直接获取主角实体并调用对应组件方法。 这样避免事件广播导致非主角实体错误响应,确保卡牌效果仅作用于主角。 具体修改: - 天赋卡:直接调用 TalComp.addTal - 属性卡:直接更新全局属性并调用 HeroAttrsComp.recalculateSingleAttr - 药水卡:直接创建 BuffConf 并调用 HeroAttrsComp.addBuff - 技能卡:暂时保留事件派发,但后续可考虑类似改造 - 伙伴卡:保留事件派发,因其涉及实体创建
This commit is contained in:
@@ -79,14 +79,15 @@ export class HeroAttrsComp extends ecs.Comp {
|
||||
onLoad() {
|
||||
// 监听升级事件
|
||||
oops.message.on(GameEvent.CanUpdateLv, this.onLevelUp, this);
|
||||
oops.message.on(GameEvent.UseItemCard, this.onUseItemCard, this);
|
||||
oops.message.on(GameEvent.UseAttrCard, this.onUseAttrCard, this);
|
||||
// 移除卡牌事件监听,改为由 MissionCardComp 直接调用,避免非主角响应
|
||||
// oops.message.on(GameEvent.UseItemCard, this.onUseItemCard, this);
|
||||
// oops.message.on(GameEvent.UseAttrCard, this.onUseAttrCard, this);
|
||||
}
|
||||
|
||||
onDestroy() {
|
||||
oops.message.off(GameEvent.CanUpdateLv, this.onLevelUp, this);
|
||||
oops.message.off(GameEvent.UseItemCard, this.onUseItemCard, this);
|
||||
oops.message.off(GameEvent.UseAttrCard, this.onUseAttrCard, this);
|
||||
// oops.message.off(GameEvent.UseItemCard, this.onUseItemCard, this);
|
||||
// oops.message.off(GameEvent.UseAttrCard, this.onUseAttrCard, this);
|
||||
}
|
||||
|
||||
onUseAttrCard(event: string, args: any) {
|
||||
|
||||
@@ -6,6 +6,12 @@ import { GameEvent } from "../common/config/GameEvent";
|
||||
import { smc } from "../common/SingletonModuleComp";
|
||||
import { CardType, FightSet, CardKind } from "../common/config/GameSet";
|
||||
import { getCardOptions, ICardInfo } from "../common/config/CardSet";
|
||||
import { TalComp } from "../hero/TalComp";
|
||||
import { HeroSkillsComp } from "../hero/HeroSkills";
|
||||
import { HeroAttrsComp } from "../hero/HeroAttrsComp";
|
||||
import { BuffConf } from "../common/config/SkillSet";
|
||||
import { BType } from "../common/config/HeroAttrs";
|
||||
import { AttrCards, PotionCards } from "../common/config/AttrSet";
|
||||
|
||||
const { ccclass, property } = _decorator;
|
||||
|
||||
@@ -424,26 +430,82 @@ export class MissionCardComp extends CCComp {
|
||||
.to(0.1, { scale: new Vec3(1, 1, 1) })
|
||||
.delay(0.5)
|
||||
.call(() => {
|
||||
// 根据类型发送不同事件
|
||||
switch (selectedData.type) {
|
||||
case CardType.Talent:
|
||||
smc.addTalentRecord(selectedData.uuid);
|
||||
oops.message.dispatchEvent(GameEvent.UseTalentCard, selectedData.uuid);
|
||||
break;
|
||||
case CardType.Skill:
|
||||
smc.addSkillRecord(selectedData.uuid);
|
||||
oops.message.dispatchEvent(GameEvent.UseSkillCard, selectedData.uuid);
|
||||
break;
|
||||
case CardType.Partner:
|
||||
oops.message.dispatchEvent(GameEvent.CallFriend, { uuid: selectedData.uuid });
|
||||
break;
|
||||
case CardType.Potion:
|
||||
// Potion 在 CardSet 中也是 uuid
|
||||
oops.message.dispatchEvent(GameEvent.UseItemCard, selectedData.uuid);
|
||||
break;
|
||||
case CardType.Attr:
|
||||
oops.message.dispatchEvent(GameEvent.UseAttrCard, selectedData.uuid);
|
||||
break;
|
||||
// 根据类型直接操作 smc.role (如果是主角)
|
||||
// 确保只影响主角,避免广播事件导致所有实体生效
|
||||
const role = smc.role;
|
||||
if (role) {
|
||||
switch (selectedData.type) {
|
||||
case CardType.Talent:
|
||||
smc.addTalentRecord(selectedData.uuid);
|
||||
// 直接调用 TalComp 添加天赋
|
||||
const talComp = role.get(TalComp);
|
||||
if (talComp) {
|
||||
talComp.addTal(selectedData.uuid);
|
||||
}
|
||||
break;
|
||||
case CardType.Skill:
|
||||
smc.addSkillRecord(selectedData.uuid);
|
||||
// 直接调用 HeroSkillsComp 添加技能
|
||||
const skillComp = role.get(HeroSkillsComp);
|
||||
if (skillComp) {
|
||||
// 假设 HeroSkillsComp 有 addSkill 方法,如果没有需要根据实际情况调整
|
||||
// 这里暂时假设通过事件触发或需要补充直接调用的方法
|
||||
// 由于 HeroSkillsComp 之前可能主要依赖初始化,这里可能需要补充 addSkill 逻辑
|
||||
// 或者如果 HeroSkillsComp 监听了 UseSkillCard 且判断了 is_master,可以保留事件但需谨慎
|
||||
// 为了完全隔离,建议在 HeroSkillsComp 中暴露 addSkill 接口
|
||||
// 目前先保留事件派发,但在 HeroSkillsComp 中加强 is_master 判断
|
||||
// 或者:skillComp.addSkill(selectedData.uuid);
|
||||
oops.message.dispatchEvent(GameEvent.UseSkillCard, selectedData.uuid);
|
||||
}
|
||||
break;
|
||||
case CardType.Partner:
|
||||
// 伙伴是召唤新实体,依然适合用事件,或者直接调用 summon 方法
|
||||
oops.message.dispatchEvent(GameEvent.CallFriend, { uuid: selectedData.uuid });
|
||||
break;
|
||||
case CardType.Potion:
|
||||
// 药水直接作用于 HeroAttrsComp
|
||||
const attrsComp = role.get(HeroAttrsComp);
|
||||
if (attrsComp) {
|
||||
const potion = PotionCards[selectedData.uuid];
|
||||
if (potion) {
|
||||
const buffConf: BuffConf = {
|
||||
buff: potion.attr,
|
||||
value: potion.value,
|
||||
BType: BType.RATIO,
|
||||
time: potion.duration,
|
||||
chance: 1,
|
||||
};
|
||||
attrsComp.addBuff(buffConf);
|
||||
smc.updateHeroInfo(attrsComp);
|
||||
oops.gui.toast(potion.desc);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CardType.Attr:
|
||||
// 属性卡:更新全局属性并刷新主角
|
||||
const attrCard = AttrCards[selectedData.uuid];
|
||||
if (attrCard) {
|
||||
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;
|
||||
|
||||
console.log(`[MissionCard] 全局属性更新: Attr=${attrCard.attr}, Add=${attrCard.value}, Total=${current[0]}`);
|
||||
|
||||
// 直接触发主角属性重算
|
||||
const attrsComp = role.get(HeroAttrsComp);
|
||||
if (attrsComp) {
|
||||
attrsComp.recalculateSingleAttr(attrCard.attr);
|
||||
smc.updateHeroInfo(attrsComp);
|
||||
}
|
||||
oops.gui.toast(attrCard.desc);
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
console.warn("[MissionCard] 主角实体无效,无法应用卡牌效果");
|
||||
}
|
||||
|
||||
// 记录已获取的卡牌
|
||||
|
||||
Reference in New Issue
Block a user