refactor(missionCard): 调整抽卡过滤逻辑,过滤已上场英雄
修改了MissionCardComp的抽卡规则,新增场上存活英雄uuid集合的获取方法,优先从未上场英雄池抽卡,卡池不足时回退全量池以保证抽满3张卡牌,同时更新了相关注释说明。
This commit is contained in:
@@ -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<number>();
|
||||
@@ -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<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 }> {
|
||||
const actors: Array<{ eid: number, model: HeroAttrsComp, view: HeroViewComp | null }> = [];
|
||||
ecs.query(ecs.allOf(HeroAttrsComp)).forEach((entity: ecs.Entity) => {
|
||||
|
||||
Reference in New Issue
Block a user