diff --git a/assets/script/game/map/MissionCardComp.ts b/assets/script/game/map/MissionCardComp.ts index a923a0cd..db142773 100644 --- a/assets/script/game/map/MissionCardComp.ts +++ b/assets/script/game/map/MissionCardComp.ts @@ -5,7 +5,7 @@ * 职责: * 1. **卡牌分发管理** —— 从卡池抽取 3 张英雄卡,分发到 3 个 CHeroComp 槽位。 * 抽卡规则:从基础英雄卡池按权重抽取,同一次抽卡内英雄不重复; - * 不过滤已召唤英雄,抽到同 uuid 可触发二合一合成升级。 + * 过滤已上场英雄(卡池不足时自动回退,保证能抽满)。 * 2. **金币费用管理** —— 抽卡费用(refreshCost)的扣除。 * 3. **英雄数量上限校验** —— 在 UseHeroCard 事件的 guard 阶段判断是否允许再召唤英雄。 * 4. **场上英雄信息面板(HInfoComp 列表)同步** —— @@ -1879,15 +1879,19 @@ export class MissionCardComp extends CCComp { * * 规则: * 1. 从基础英雄卡池按权重抽取,同一次抽卡内英雄不重复。 - * 2. 不过滤已召唤英雄:抽到同 uuid 可触发二合一合成升级。 + * 2. 过滤已上场英雄(卡池不足 3 张时自动回退到未过滤池,保证能抽满)。 * 3. 不足 3 张时循环补齐(允许重复)。 * * 注:升级卡机制已移除,英雄卡池只出普通英雄卡。 */ private buildDrawCards(): CardConfig[] { - const availableHeroCards = CardPoolList.filter(c => c.type === CardType.Hero); + const allHeroCards = CardPoolList.filter(c => c.type === CardType.Hero); + if (allHeroCards.length === 0) return []; - if (availableHeroCards.length === 0) return []; + // 优先从“未上场英雄”子池抽取;子池不足 3 张时回退到全量池,避免凑不齐 3 张 + const onFieldUuids = this.getAliveHeroUuidSet(); + const filtered = allHeroCards.filter(c => !onFieldUuids.has(c.uuid)); + const availableHeroCards = filtered.length >= 3 ? filtered : allHeroCards; const result: CardConfig[] = []; const usedUuids = new Set(); @@ -1922,13 +1926,16 @@ export class MissionCardComp extends CCComp { } private tryRefreshHeroCards(heroType?: HType): boolean { - const cards = drawCardsByRule({ + let cards = drawCardsByRule({ count: 3, type: CardType.Hero, heroType, unique: true, // 保证一次刷新内的英雄卡不重复 }); - // 不过滤已召唤英雄:抽到同 uuid 可触发二合一合成升级 + // 过滤已上场英雄;若过滤后为空则回退到未过滤池,避免无可抽卡 + const onFieldUuids = this.getAliveHeroUuidSet(); + const filtered = cards.filter(c => !onFieldUuids.has(c.uuid)); + if (filtered.length > 0) cards = filtered; if (cards.length <= 0) return false; this.layoutCardSlots(); this.dispatchCardsToSlots(cards.slice(0, 3)); @@ -2173,6 +2180,19 @@ export class MissionCardComp extends CCComp { return count; } + /** 收集当前场上存活英雄的 uuid 集合(用于抽卡时过滤重复上场英雄) */ + private getAliveHeroUuidSet(): Set { + const uuids = new Set(); + ecs.query(ecs.allOf(HeroAttrsComp)).forEach((entity: ecs.Entity) => { + const model = entity.get(HeroAttrsComp); + if (!model) return; + if (model.fac !== FacSet.HERO) return; + if (model.is_dead) return; + uuids.add(model.hero_uuid); + }); + return uuids; + } + private queryAliveHeroActors(): Array<{ eid: number, model: HeroAttrsComp, view: HeroViewComp | null }> { const actors: Array<{ eid: number, model: HeroAttrsComp, view: HeroViewComp | null }> = []; ecs.query(ecs.allOf(HeroAttrsComp)).forEach((entity: ecs.Entity) => {