refactor(missionCard): 调整抽卡过滤逻辑,过滤已上场英雄

修改了MissionCardComp的抽卡规则,新增场上存活英雄uuid集合的获取方法,优先从未上场英雄池抽卡,卡池不足时回退全量池以保证抽满3张卡牌,同时更新了相关注释说明。
This commit is contained in:
pan
2026-08-17 14:15:49 +08:00
parent a59bfd3e40
commit b154fb306c

View File

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