Files
pixelheros/assets/script/game/common/config/CardSet.ts
panFD 8818ec9c3f refactor(card): 升级动态升级卡的英雄绑定逻辑
将动态升级卡从绑定英雄UUID改为绑定实体EID,适配ECS实体管理模式:
1. 更新CardConfig定义,替换target_hero_uuid为target_hero_eid
2. 新增EID反查UUID的工具方法,适配渲染和交互逻辑
3. 修改抽卡、卡牌点击和使用的全流程逻辑
4. 优化升级卡生成和匹配的稳定性
2026-07-21 00:03:44 +08:00

438 lines
24 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import * as exp from "constants"
import { HeroInfo, HeroList, HType } from "./heroSet"
import { FightSet, SKILL_CARD_WAVES } from "./GameSet"
import { oops } from "db://oops-framework/core/Oops"
import { SkillOverrides, TGroup } from "./SkillSet"
class I18nString {
constructor(private key: string, private params?: any[]) { }
private getTranslated(): string {
let str = oops.language.getLangByID(this.key) || this.key;
if (this.params && this.params.length > 0) {
for (let i = 0; i < this.params.length; i++) {
str = str.replace(`{${i}}`, String(this.params[i]));
}
}
return str;
}
toString() { return this.getTranslated(); }
valueOf() { return this.getTranslated(); }
toJSON() { return this.getTranslated(); }
get length() { return this.toString().length; }
}
const t = (key: string, ...params: any[]) => new I18nString(key, params) as unknown as string;
/** 卡牌大类定义 */
export enum CardType {
Hero = 1,
Skill = 2,
SpecialUpgrade = 3,
SpecialRefresh = 4,
}
/** 卡牌大类定义 */
export enum CKind {
Hero = 1, //英雄
Skill = 2, //技能
Card = 3, //卡牌
Potion = 4, //药水
}
/** 技能卡触发类型 */
export enum CardSkillType {
Interval = 1, // 间隔定时触发 (战斗中每隔N秒执行)
Field = 2, // 驻场技能 (被动光环)
BattleStart = 3, // 战斗开始时触发一次
BattleEnd = 4, // 战斗结束时触发一次
HeroDead = 5, // 场上己方英雄死亡时触发
HeroCall = 6, // 场上己方英雄召唤上场时触发
}
/**
* 卡牌技能触发类型
* - 命名对齐英雄侧 SkillTriggerType便于跨模块认知统一
* - 枚举值从 1 开始,避免 0 的 falsy 坑if (trigger_type) 判断出错)
*/
export enum CardTriggerType {
Instant = 1, // 即时触发:使用后立即生效一次
Interval = 2, // 定时循环:战斗中按 t_inv 间隔重复触发
Field = 3, // 驻场光环:被动生效(仅显式分类,仍由 field 字段驱动)
FightStart = 4, // 战斗开始时触发
FightEnd = 5, // 战斗结束时触发(每波结束)
HeroDead = 6, // 场上己方英雄死亡时触发
HeroCall = 7, // 英雄上场时触发(主角召唤 + 技能召唤 + 复活)
}
/**
* 卡池等级占位枚举(已废弃分层语义)。
* 新机制下所有英雄卡均属 LV1不再使用卡池升级。
* 保留枚举仅为兼容历史代码引用。
*/
export enum CardLV {
LV1 = 1,
LV2 = 2,
LV3 = 3,
LV4 = 4,
LV5 = 5,
}
/** 通用卡牌配置 */
export interface CardConfig {
uuid: number
type: CardType
cost: number
weight: number
kind: CKind
pool_lv: CardLV
wave?: number // 针对技能卡:仅在指定波次(wave)才能抽到
hero_lv?: number
card_lv?: number
base_pool_lv?: number
// 技能卡扩展属性
skill?: number // 关联的技能 UUID
icon?: string // 图标ID可选优先使用未设置时按 trigger_type 从 SkillSet/FieldSkillSet 自动取)
name?: string // 卡牌名称
info?: string // 卡牌描述信息
is_inst?: boolean // 是否即时起效
t_times?: number // 触发次数
t_inv?: number // 触发间隔(秒)
keep_waves?: number // 维持的波次数(-1表示持续到战斗结束0或undefined表示仅本波次
overrides?: SkillOverrides // 技能参数覆写如自定义伤害ap、buff值、金币数等
field?: number[] // 驻场技能 UUID 数组,表示该卡牌提供驻场属性加成
/** 触发类型(必填,技能卡专用;功能卡/英雄卡可缺省) */
trigger_type?: CardTriggerType;
/**
* 事件型触发的全局次数上限(仅 FightStart/FightEnd/HeroDead/HeroCall 有效)
* 默认 Infinity达到上限后销毁节点
* 注意:与 t_times 语义不同——t_times 控制每波内 Interval 的次数
*/
trigger_limit?: number;
/**
* 动态升级卡专属:目标英雄实体 eid运行时唯一
* 仅当 type === CardType.SpecialUpgrade 且该卡由 buildDrawCards 动态生成时使用。
* 使用该卡时精确升级场上对应 eid 的英雄实体。
*/
target_hero_eid?: number;
}
/** 升级卡折扣表(已废弃,保留以兼容历史引用) */
export const CardsUpSet: Record<number, number> = {
1: 50,
2: 100,
3: 150,
4: 200,
5: 250,
}
/** 卡池升级每波减免金额(已废弃,保留以兼容历史引用) */
export const CARD_POOL_UPGRADE_DISCOUNT_PER_WAVE = 10
/** 卡池默认初始等级(已废弃,所有卡牌统一 LV1 */
export const CARD_POOL_INIT_LEVEL = CardLV.LV1
/** 卡池等级上限(已废弃,所有卡牌统一 LV1 */
export const CARD_POOL_MAX_LEVEL = CardLV.LV1
/** 英雄最高等级限制(已废弃,统一由 FightSet.HERO_MAX_LV 控制) */
export const CARD_HERO_MAX_LEVEL = 1
/** 基础卡池(英雄、技能、功能) */
export const CardPoolList: CardConfig[] = [];
// 动态生成英雄卡池:所有英雄统一生成 lv1 卡牌
HeroList.forEach(uuid => {
const hero = HeroInfo[uuid];
if (!hero) return;
const baseCost = FightSet.BASE_COST;
const baseWeight = 25;
CardPoolList.push({
uuid: hero.uuid,
type: CardType.Hero,
cost: baseCost,
weight: baseWeight,
pool_lv: CardLV.LV1,
kind: CKind.Hero,
hero_lv: 1,
base_pool_lv: 1,
});
});
// 添加非英雄卡牌 (技能、功能卡)
// 体系wave 由 SKILL_CARD_WAVES 统一配置每档强度递增Field 靠 field uuid 区分数值Interval 靠 overrides 覆写)
// wave→card_lv 映射由 SKILL_CARD_WAVES 索引+1 自动生成wave 1→lv1, wave 5→lv2, wave 8→lv3
const waveToCardLv: Record<number, number> = {};
SKILL_CARD_WAVES.forEach((w, i) => { waveToCardLv[w] = i + 1; });
const SkillCardData: any[] = [
// ==================== wave 1 档(基础强度) ====================
// --- 驻场卡Field ---
{ uuid: 8701, skill: 0, wave: SKILL_CARD_WAVES[0], name: "战后恢复", info: "战斗结束生命回复量+10%", is_inst: false, keep_waves: -1, field: [7001], trigger_type: CardTriggerType.Field },
{ uuid: 8702, skill: 0, wave: SKILL_CARD_WAVES[0], name: "攻击加成", info: "英雄攻击力+10%", is_inst: false, keep_waves: -1, field: [7002], trigger_type: CardTriggerType.Field },
{ uuid: 8703, skill: 0, wave: SKILL_CARD_WAVES[0], name: "击晕加成", info: "英雄击晕概率+10%", is_inst: false, keep_waves: -1, field: [7003], trigger_type: CardTriggerType.Field },
{ uuid: 8704, skill: 0, wave: SKILL_CARD_WAVES[0], name: "暴击加成", info: "英雄暴击率+10%", is_inst: false, keep_waves: -1, field: [7004], trigger_type: CardTriggerType.Field },
{ uuid: 8705, skill: 0, wave: SKILL_CARD_WAVES[0], name: "暴伤加成", info: "英雄暴击伤害+20%", is_inst: false, keep_waves: -1, field: [7005], trigger_type: CardTriggerType.Field },
{ uuid: 8706, skill: 0, wave: SKILL_CARD_WAVES[0], name: "攻速加成", info: "英雄攻击速度+10%", is_inst: false, keep_waves: -1, field: [7006], trigger_type: CardTriggerType.Field },
{ uuid: 8707, skill: 0, wave: SKILL_CARD_WAVES[0], name: "生命加成", info: "英雄最大生命+10%", is_inst: false, keep_waves: -1, field: [7007], trigger_type: CardTriggerType.Field },
{ uuid: 8708, skill: 0, wave: SKILL_CARD_WAVES[0], name: "风怒加成", info: "英雄风怒概率+10%", is_inst: false, keep_waves: -1, field: [7008], trigger_type: CardTriggerType.Field },
{ uuid: 8709, skill: 0, wave: SKILL_CARD_WAVES[0], name: "穿刺加成", info: "英雄穿刺概率+10%", is_inst: false, keep_waves: -1, field: [7009], trigger_type: CardTriggerType.Field },
{ uuid: 8710, skill: 0, wave: SKILL_CARD_WAVES[0], name: "金币收益", info: "每回合金币收益+1", is_inst: false, keep_waves: -1, field: [7010], trigger_type: CardTriggerType.Field },
{ uuid: 8711, skill: 0, wave: SKILL_CARD_WAVES[0], name: "出售强化", info: "卖出英雄金币+1", is_inst: false, keep_waves: -1, field: [7011], trigger_type: CardTriggerType.Field },
// ==================== wave 5 档(强度 ×2 ====================
// --- 驻场卡field uuid +200对应 FieldSkillSet 72xx 段) ---
{ uuid: 8751, skill: 0, wave: SKILL_CARD_WAVES[1], name: "战后恢复+", info: "战斗结束生命回复量+20%", is_inst: false, keep_waves: -1, field: [7201], trigger_type: CardTriggerType.Field },
{ uuid: 8752, skill: 0, wave: SKILL_CARD_WAVES[1], name: "攻击加成+", info: "英雄攻击力+20%", is_inst: false, keep_waves: -1, field: [7202], trigger_type: CardTriggerType.Field },
{ uuid: 8753, skill: 0, wave: SKILL_CARD_WAVES[1], name: "击晕加成+", info: "英雄击晕概率+20%", is_inst: false, keep_waves: -1, field: [7203], trigger_type: CardTriggerType.Field },
{ uuid: 8754, skill: 0, wave: SKILL_CARD_WAVES[1], name: "暴击加成+", info: "英雄暴击率+20%", is_inst: false, keep_waves: -1, field: [7204], trigger_type: CardTriggerType.Field },
{ uuid: 8755, skill: 0, wave: SKILL_CARD_WAVES[1], name: "暴伤加成+", info: "英雄暴击伤害+40%", is_inst: false, keep_waves: -1, field: [7205], trigger_type: CardTriggerType.Field },
{ uuid: 8756, skill: 0, wave: SKILL_CARD_WAVES[1], name: "攻速加成+", info: "英雄攻击速度+20%", is_inst: false, keep_waves: -1, field: [7206], trigger_type: CardTriggerType.Field },
{ uuid: 8757, skill: 0, wave: SKILL_CARD_WAVES[1], name: "生命加成+", info: "英雄最大生命+20%", is_inst: false, keep_waves: -1, field: [7207], trigger_type: CardTriggerType.Field },
{ uuid: 8758, skill: 0, wave: SKILL_CARD_WAVES[1], name: "风怒加成+", info: "英雄风怒概率+20%", is_inst: false, keep_waves: -1, field: [7208], trigger_type: CardTriggerType.Field },
{ uuid: 8759, skill: 0, wave: SKILL_CARD_WAVES[1], name: "穿刺加成+", info: "英雄穿刺概率+20%", is_inst: false, keep_waves: -1, field: [7209], trigger_type: CardTriggerType.Field },
// --- 范围攻击卡ap 递增,间隔缩短) ---
{ uuid: 8261, skill: 6201, wave: SKILL_CARD_WAVES[1], name: "雷墙+", info: "召唤雷墙阻挡敌人,有概率击晕", is_inst: false, t_inv: 5, keep_waves: -1, trigger_type: CardTriggerType.Interval, overrides: { ap: 150 } },
{ uuid: 8262, skill: 6202, wave: SKILL_CARD_WAVES[1], name: "火墙+", info: "召唤火墙阻挡敌人,有概率击晕", is_inst: false, t_inv: 5, keep_waves: -1, trigger_type: CardTriggerType.Interval, overrides: { ap: 150 } },
{ uuid: 8263, skill: 6203, wave: SKILL_CARD_WAVES[1], name: "飓风+", info: "召唤飓风攻击敌人,有概率击晕", is_inst: false, t_inv: 5, keep_waves: -1, trigger_type: CardTriggerType.Interval, overrides: { ap: 150 } },
{ uuid: 8264, skill: 6204, wave: SKILL_CARD_WAVES[1], name: "水墙+", info: "召唤水墙阻挡敌人,有概率击晕", is_inst: false, t_inv: 5, keep_waves: -1, trigger_type: CardTriggerType.Interval, overrides: { ap: 150 } },
{ uuid: 8265, skill: 6205, wave: SKILL_CARD_WAVES[1], name: "风墙+", info: "召唤风墙困住敌人,有概率击晕", is_inst: false, t_inv: 5, keep_waves: -1, trigger_type: CardTriggerType.Interval, overrides: { ap: 150 } },
{ uuid: 8266, skill: 6206, wave: SKILL_CARD_WAVES[1], name: "陨石术+", info: "召唤陨石范围攻击敌人,有概率击晕", is_inst: false, t_inv: 5, keep_waves: -1, trigger_type: CardTriggerType.Interval, overrides: { ap: 150 } },
{ uuid: 8760, skill: 0, wave: SKILL_CARD_WAVES[1], name: "金币收益+", info: "每回合金币收益+2", is_inst: false, keep_waves: -1, field: [7210], trigger_type: CardTriggerType.Field },
{ uuid: 8761, skill: 0, wave: SKILL_CARD_WAVES[1], name: "购买优惠+", info: "购买卡牌费用-2金币", is_inst: false, keep_waves: -1, field: [7212], trigger_type: CardTriggerType.Field },
{ uuid: 8762, skill: 0, wave: SKILL_CARD_WAVES[1], name: "刷新优惠", info: "刷新卡牌费用-1金币", is_inst: false, keep_waves: -1, field: [7213], trigger_type: CardTriggerType.Field },
// ==================== wave 8 档(强度 ×3 ====================
// --- 驻场卡field uuid +400对应 FieldSkillSet 74xx 段) ---
{ uuid: 8801, skill: 0, wave: SKILL_CARD_WAVES[2], name: "战后恢复++", info: "战斗结束生命回复量+30%", is_inst: false, keep_waves: -1, field: [7401], trigger_type: CardTriggerType.Field },
{ uuid: 8802, skill: 0, wave: SKILL_CARD_WAVES[2], name: "攻击加成++", info: "英雄攻击力+30%", is_inst: false, keep_waves: -1, field: [7402], trigger_type: CardTriggerType.Field },
{ uuid: 8803, skill: 0, wave: SKILL_CARD_WAVES[2], name: "击晕加成++", info: "英雄击晕概率+30%", is_inst: false, keep_waves: -1, field: [7403], trigger_type: CardTriggerType.Field },
{ uuid: 8804, skill: 0, wave: SKILL_CARD_WAVES[2], name: "暴击加成++", info: "英雄暴击率+30%", is_inst: false, keep_waves: -1, field: [7404], trigger_type: CardTriggerType.Field },
{ uuid: 8805, skill: 0, wave: SKILL_CARD_WAVES[2], name: "暴伤加成++", info: "英雄暴击伤害+60%", is_inst: false, keep_waves: -1, field: [7405], trigger_type: CardTriggerType.Field },
{ uuid: 8806, skill: 0, wave: SKILL_CARD_WAVES[2], name: "攻速加成++", info: "英雄攻击速度+30%", is_inst: false, keep_waves: -1, field: [7406], trigger_type: CardTriggerType.Field },
{ uuid: 8807, skill: 0, wave: SKILL_CARD_WAVES[2], name: "生命加成++", info: "英雄最大生命+30%", is_inst: false, keep_waves: -1, field: [7407], trigger_type: CardTriggerType.Field },
{ uuid: 8808, skill: 0, wave: SKILL_CARD_WAVES[2], name: "风怒加成++", info: "英雄风怒概率+30%", is_inst: false, keep_waves: -1, field: [7408], trigger_type: CardTriggerType.Field },
{ uuid: 8809, skill: 0, wave: SKILL_CARD_WAVES[2], name: "穿刺加成++", info: "英雄穿刺概率+30%", is_inst: false, keep_waves: -1, field: [7409], trigger_type: CardTriggerType.Field },
{ uuid: 8361, skill: 6201, wave: SKILL_CARD_WAVES[2], name: "雷墙++", info: "召唤雷墙阻挡敌人,有概率击晕", is_inst: false, t_inv: 4, keep_waves: -1, trigger_type: CardTriggerType.Interval, overrides: { ap: 250 } },
{ uuid: 8362, skill: 6202, wave: SKILL_CARD_WAVES[2], name: "火墙++", info: "召唤火墙阻挡敌人,有概率击晕", is_inst: false, t_inv: 4, keep_waves: -1, trigger_type: CardTriggerType.Interval, overrides: { ap: 250 } },
{ uuid: 8363, skill: 6203, wave: SKILL_CARD_WAVES[2], name: "飓风++", info: "召唤飓风攻击敌人,有概率击晕", is_inst: false, t_inv: 4, keep_waves: -1, trigger_type: CardTriggerType.Interval, overrides: { ap: 250 } },
{ uuid: 8364, skill: 6204, wave: SKILL_CARD_WAVES[2], name: "水墙++", info: "召唤水墙阻挡敌人,有概率击晕", is_inst: false, t_inv: 4, keep_waves: -1, trigger_type: CardTriggerType.Interval, overrides: { ap: 250 } },
{ uuid: 8365, skill: 6205, wave: SKILL_CARD_WAVES[2], name: "风墙++", info: "召唤风墙困住敌人,有概率击晕", is_inst: false, t_inv: 4, keep_waves: -1, trigger_type: CardTriggerType.Interval, overrides: { ap: 250 } },
{ uuid: 8366, skill: 6206, wave: SKILL_CARD_WAVES[2], name: "陨石术++", info: "召唤陨石范围攻击敌人,有概率击晕", is_inst: false, t_inv: 4, keep_waves: -1, trigger_type: CardTriggerType.Interval, overrides: { ap: 250 } },
{ uuid: 8810, skill: 0, wave: SKILL_CARD_WAVES[2], name: "金币收益++", info: "每回合金币收益+3", is_inst: false, keep_waves: -1, field: [7410], trigger_type: CardTriggerType.Field },
{ uuid: 8811, skill: 0, wave: SKILL_CARD_WAVES[2], name: "召唤强化++", info: "召唤触发技能次数+1", is_inst: false, keep_waves: -1, field: [7014], trigger_type: CardTriggerType.Field },
{ uuid: 8812, skill: 0, wave: SKILL_CARD_WAVES[2], name: "死亡强化++", info: "死亡触发技能次数+1", is_inst: false, keep_waves: -1, field: [7015], trigger_type: CardTriggerType.Field },
{ uuid: 8813, skill: 0, wave: SKILL_CARD_WAVES[2], name: "开场强化++", info: "战斗开始触发技能次数+1", is_inst: false, keep_waves: -1, field: [7016], trigger_type: CardTriggerType.Field },
{ uuid: 8814, skill: 0, wave: SKILL_CARD_WAVES[2], name: "结束强化++", info: "战斗结束触发技能次数+1", is_inst: false, keep_waves: -1, field: [7017], trigger_type: CardTriggerType.Field },
{ uuid: 8815, skill: 0, wave: SKILL_CARD_WAVES[2], name: "攻击强化++", info: "攻击触发技能次数+1", is_inst: false, keep_waves: -1, field: [7018], trigger_type: CardTriggerType.Field },
{ uuid: 8816, skill: 0, wave: SKILL_CARD_WAVES[2], name: "受击强化++", info: "被攻击触发技能次数+1", is_inst: false, keep_waves: -1, field: [7019], trigger_type: CardTriggerType.Field },
// --- 范围攻击卡ap 最高,间隔最短) ---
];
SkillCardData.forEach(data => {
const cardLv = waveToCardLv[data.wave] ?? 1;
CardPoolList.push({
uuid: data.uuid,
skill: data.skill || undefined,
type: CardType.Skill,
cost: 0,
weight: 10,
pool_lv: CardLV.LV1,
wave: data.wave,
kind: CKind.Skill,
card_lv: cardLv,
name: data.name,
info: data.info,
icon: data.icon,
is_inst: data.is_inst,
t_times: data.t_times || (data.is_inst ? 1 : 999),
t_inv: data.t_inv || 0,
keep_waves: data.keep_waves,
field: data.field,
overrides: data.overrides,
trigger_type: data.trigger_type,
trigger_limit: data.trigger_limit,
});
});
export enum SpecialRefreshHeroType {
Any = 0,
Melee = 1,
Ranged = 2,
}
/** 升级功能卡完整配置(作为动态升级卡的基础模板) */
export interface SpecialUpgradeCardConfig extends CardConfig {
name: string
info: string
/** 模板字段currentLv=0 表示动态卡(实际值由 target_hero_eid 对应的英雄决定) */
currentLv: number
/** 模板字段targetLv=0 表示"+1 级"(实际目标等级 = 当前等级 + 1 */
targetLv: number
}
/** 刷新功能卡完整配置 */
export interface SpecialRefreshCardConfig extends CardConfig {
name: string
info: string
refreshLv: number
refreshHeroType: SpecialRefreshHeroType
}
/**
* 升级卡模板。
* 仅有 7001 一条记录作为动态升级卡的基础配置cost/weight/name/info
* 实际使用时由 MissionCardComp.buildDrawCards 根据场上英雄动态生成 CardConfig
* 通过 target_hero_eid 字段绑定具体英雄实体。
*/
export const SpecialUpgradeCardList: Record<number, SpecialUpgradeCardConfig> = {
7001: {
uuid: 7001, type: CardType.SpecialUpgrade, cost: 10, weight: 18, pool_lv: CardLV.LV1, kind: CKind.Card, name: t("scard_name_7001"), info: t("scard_info_7001"),
currentLv: 0, targetLv: 0,
},
}
export const SpecialRefreshCardList: Record<number, SpecialRefreshCardConfig> = {
7101: {
uuid: 7101, type: CardType.SpecialRefresh, cost: 3, weight: 14, pool_lv: CardLV.LV1, kind: CKind.Card, name: t("scard_name_7101"), info: t("scard_info_7101"),
refreshLv: 0, refreshHeroType: SpecialRefreshHeroType.Melee,
},
7102: {
uuid: 7102, type: CardType.SpecialRefresh, cost: 3, weight: 14, pool_lv: CardLV.LV1, kind: CKind.Card, name: t("scard_name_7102"), info: t("scard_info_7102"),
refreshLv: 0, refreshHeroType: SpecialRefreshHeroType.Ranged,
},
7103: {
uuid: 7103, type: CardType.SpecialRefresh, cost: 4, weight: 12, pool_lv: CardLV.LV1, kind: CKind.Card, name: t("scard_name_7103"), info: t("scard_info_7103"),
refreshLv: 0, refreshHeroType: SpecialRefreshHeroType.Any,
},
}
/** 规范等级到合法区间(保留以兼容历史调用,新机制下统一返回 LV1 */
const clampCardLv = (lv: number): CardLV => {
return CardLV.LV1;
}
/** 单次按权重抽取一张卡 */
const weightedPick = (cards: CardConfig[]): CardConfig | null => {
if (cards.length === 0) return null
const totalWeight = cards.reduce((total, card) => total + card.weight, 0)
let random = Math.random() * totalWeight
for (const card of cards) {
random -= card.weight
if (random <= 0) return card
}
return cards[cards.length - 1]
}
/** 连续抽取 count 张卡,允许重复或通过 unique 剔除重复 */
const pickCards = (cards: CardConfig[], count: number, unique: boolean = false): CardConfig[] => {
if (cards.length === 0 || count <= 0) return []
const selected: CardConfig[] = []
let available = [...cards]
while (selected.length < count) {
if (available.length === 0) break
const pick = weightedPick(available)
if (!pick) break
selected.push(pick)
if (unique) {
available = available.filter(c => c.uuid !== pick.uuid)
}
}
return selected
}
/**
* 获取基础卡池(已废弃 lv 参数,新机制下返回完整卡池)。
* @param lv 历史遗留参数,不再生效
* @param onlyCurrentLv 历史遗留参数,不再生效
*/
export const getCardPoolByLv = (lv: number, onlyCurrentLv: boolean = false): CardConfig[] => {
return CardPoolList;
}
const normalizeTypeFilter = (type: CardType | CardType[]): Set<CardType> => {
const list = Array.isArray(type) ? type : [type]
return new Set<CardType>(list)
}
/**
* 常规发牌:前 3 英雄 + 后 1 其他;支持按类型过滤。
* @param lv 历史遗留参数,不再生效
* @param type 限定卡牌类型
* @param onlyCurrentLv 历史遗留参数,不再生效
*/
export const getCardsByLv = (
lv: number,
type?: CardType | CardType[],
onlyCurrentLv: boolean = false
): CardConfig[] => {
const pool = getCardPoolByLv(lv, onlyCurrentLv)
if (type !== undefined) {
const typeSet = normalizeTypeFilter(type)
const filteredPool = pool.filter(card => typeSet.has(card.type))
return pickCards(filteredPool, 4)
}
const heroPool = pool.filter(card => card.type === CardType.Hero)
const otherPool = pool.filter(card => card.type !== CardType.Hero)
const heroes = pickCards(heroPool, 3)
const others = pickCards(otherPool, 1)
return [...heroes, ...others]
}
/**
* 通用按规则抽卡(已废弃 lv/targetPoolLv/onlyCurrentLv 参数,仅为兼容保留)。
*/
export const drawCardsByRule = (
lv: number,
options: {
count?: number
onlyCurrentLv?: boolean
type?: CardType | CardType[]
heroType?: HType
heroLv?: number
targetPoolLv?: number
wave?: number
unique?: boolean
} = {}
): CardConfig[] => {
const count = Math.max(0, Math.floor(options.count ?? 4))
let pool = getCardPoolByLv(lv, options.onlyCurrentLv ?? false)
if (options.type !== undefined) {
const typeSet = normalizeTypeFilter(options.type)
pool = pool.filter(card => typeSet.has(card.type))
}
if (options.heroType !== undefined || options.heroLv !== undefined) {
pool = pool.filter(card => {
if (card.type !== CardType.Hero) return false
const hero = HeroInfo[card.uuid]
if (!hero) return false
if (options.heroType !== undefined && hero.type !== options.heroType) return false
if (options.heroLv !== undefined && card.hero_lv !== options.heroLv) return false
return true
})
}
// 如果传入了波次并且是技能卡,则根据 wave 过滤
if (options.wave !== undefined) {
pool = pool.filter(card => {
if (card.type === CardType.Skill) {
return card.wave === options.wave;
}
return true;
})
}
const picked = pickCards(pool, count, options.unique)
return picked
}