1. 为所有卡牌配置添加icon字段,支持自定义指定图集内的图标 2. 重构列表组件与卡片组件的图标获取逻辑,优先使用自定义图标 3. 更新预加载的图集资源从ui3改为ui6,适配新图标图集 4. 调整弹窗预制体尺寸与图集引用,适配新的图标资源系统
124 lines
6.5 KiB
TypeScript
124 lines
6.5 KiB
TypeScript
/**
|
||
* @file SCardSet.ts
|
||
* @description 技能卡池独立配置
|
||
*
|
||
* 职责:
|
||
* 维护所有技能卡(CardType.Skill)的原始数据,并构建为标准 CardConfig[]。
|
||
*
|
||
* 设计:
|
||
* - 技能卡不再按 wave 过滤,所有技能卡均可被抽取。
|
||
* - 所有技能卡均按次数触发(t_times),不再永久存在。
|
||
* - card_lv 直接显式配置,不再依赖 wave 推导。
|
||
*
|
||
* 依赖:
|
||
* - CardSet —— CardConfig / CardType / CKind / CardLV / CardTriggerType
|
||
* - SkillSet —— SkillOverrides
|
||
*/
|
||
import { CardConfig, CardType, CardLV, CKind, CardTriggerType } from "./CardSet";
|
||
import { SkillOverrides } from "./SkillSet";
|
||
|
||
/** 技能卡原始数据(平铺字段,构建后转为 CardConfig) */
|
||
interface SkillCardRaw {
|
||
uuid: number;
|
||
skill: number;
|
||
card_lv: number;
|
||
name: string;
|
||
info: string;
|
||
icon?: string; // 图标ID(对应 ui6 图集 frame 名)
|
||
is_inst: boolean;
|
||
t_times?: number; // 触发次数(未设置时按 is_inst 取默认值:即时=1,定时=3)
|
||
t_inv?: number;
|
||
keep_waves?: number; // 维持波次数(默认 0=仅本波次)
|
||
trigger_type: CardTriggerType;
|
||
overrides?: SkillOverrides;
|
||
}
|
||
|
||
const SkillCardData: SkillCardRaw[] = [
|
||
// ==================== card_lv 2 档(强度 ×2) ====================
|
||
// --- 范围攻击卡(ap 递增,间隔缩短) ---
|
||
{ uuid: 8261, skill: 6201, card_lv: 2, icon: "Stat_LightningDamag", name: "雷墙+", info: "召唤雷墙阻挡敌人,有概率击晕", is_inst: false, t_times: 3, t_inv: 5, trigger_type: CardTriggerType.Interval, overrides: { ap: 150 } },
|
||
{ uuid: 8262, skill: 6202, card_lv: 2, icon: "Stat_FireDamage", name: "火墙+", info: "召唤火墙阻挡敌人,有概率击晕", is_inst: false, t_times: 3, t_inv: 5, trigger_type: CardTriggerType.Interval, overrides: { ap: 150 } },
|
||
{ uuid: 8263, skill: 6203, card_lv: 2, icon: "Stat_Stun_01", name: "飓风+", info: "召唤飓风攻击敌人,有概率击晕", is_inst: false, t_times: 3, t_inv: 5, trigger_type: CardTriggerType.Interval, overrides: { ap: 150 } },
|
||
{ uuid: 8264, skill: 6204, card_lv: 2, icon: "Stat_Mana", name: "水墙+", info: "召唤水墙阻挡敌人,有概率击晕", is_inst: false, t_times: 3, t_inv: 5, trigger_type: CardTriggerType.Interval, overrides: { ap: 150 } },
|
||
{ uuid: 8265, skill: 6205, card_lv: 2, icon: "Stat_Stun_01", name: "风墙+", info: "召唤风墙困住敌人,有概率击晕", is_inst: false, t_times: 3, t_inv: 5, trigger_type: CardTriggerType.Interval, overrides: { ap: 150 } },
|
||
{ uuid: 8266, skill: 6206, card_lv: 2, icon: "Stat_Tripleshot", name: "陨石术+", info: "召唤陨石范围攻击敌人,有概率击晕", is_inst: false, t_times: 3, t_inv: 5, trigger_type: CardTriggerType.Interval, overrides: { ap: 150 } },
|
||
|
||
// ==================== card_lv 3 档(强度 ×3) ====================
|
||
{ uuid: 8361, skill: 6201, card_lv: 3, icon: "Stat_LightningDamag", name: "雷墙++", info: "召唤雷墙阻挡敌人,有概率击晕", is_inst: false, t_times: 4, t_inv: 4, trigger_type: CardTriggerType.Interval, overrides: { ap: 250 } },
|
||
{ uuid: 8362, skill: 6202, card_lv: 3, icon: "Stat_FireDamage", name: "火墙++", info: "召唤火墙阻挡敌人,有概率击晕", is_inst: false, t_times: 4, t_inv: 4, trigger_type: CardTriggerType.Interval, overrides: { ap: 250 } },
|
||
{ uuid: 8363, skill: 6203, card_lv: 3, icon: "Stat_Stun_01", name: "飓风++", info: "召唤飓风攻击敌人,有概率击晕", is_inst: false, t_times: 4, t_inv: 4, trigger_type: CardTriggerType.Interval, overrides: { ap: 250 } },
|
||
{ uuid: 8364, skill: 6204, card_lv: 3, icon: "Stat_Mana", name: "水墙++", info: "召唤水墙阻挡敌人,有概率击晕", is_inst: false, t_times: 4, t_inv: 4, trigger_type: CardTriggerType.Interval, overrides: { ap: 250 } },
|
||
{ uuid: 8365, skill: 6205, card_lv: 3, icon: "Stat_Stun_01", name: "风墙++", info: "召唤风墙困住敌人,有概率击晕", is_inst: false, t_times: 4, t_inv: 4, trigger_type: CardTriggerType.Interval, overrides: { ap: 250 } },
|
||
{ uuid: 8366, skill: 6206, card_lv: 3, icon: "Stat_Tripleshot", name: "陨石术++", info: "召唤陨石范围攻击敌人,有概率击晕", is_inst: false, t_times: 4, t_inv: 4, trigger_type: CardTriggerType.Interval, overrides: { ap: 250 } },
|
||
];
|
||
|
||
/**
|
||
* 技能卡池(已构建为标准 CardConfig[])。
|
||
* 不再按 wave 过滤,所有技能卡均可被抽取。
|
||
*/
|
||
export const SkillCardList: CardConfig[] = SkillCardData.map(data => {
|
||
// 触发次数:显式配置优先;未配置时即时=1,定时=3
|
||
const defaultTimes = data.is_inst ? 1 : 3;
|
||
return {
|
||
uuid: data.uuid,
|
||
skill: data.skill || undefined,
|
||
type: CardType.Skill,
|
||
cost: 0,
|
||
weight: 10,
|
||
pool_lv: CardLV.LV1,
|
||
kind: CKind.Skill,
|
||
card_lv: data.card_lv,
|
||
icon: data.icon,
|
||
name: data.name,
|
||
info: data.info,
|
||
is_inst: data.is_inst,
|
||
t_times: data.t_times ?? defaultTimes,
|
||
t_inv: data.t_inv || 0,
|
||
keep_waves: data.keep_waves ?? 0,
|
||
overrides: data.overrides,
|
||
trigger_type: data.trigger_type,
|
||
} as CardConfig;
|
||
});
|
||
|
||
/**
|
||
* 按权重抽取一张卡(带权重随机)。
|
||
*/
|
||
function weightedPick(cards: CardConfig[]): CardConfig | null {
|
||
if (cards.length === 0) return null;
|
||
const totalWeight = cards.reduce((total, card) => total + (card.weight ?? 0), 0);
|
||
let random = Math.random() * totalWeight;
|
||
for (const card of cards) {
|
||
random -= (card.weight ?? 0);
|
||
if (random <= 0) return card;
|
||
}
|
||
return cards[cards.length - 1];
|
||
}
|
||
|
||
/**
|
||
* 按权重抽取 N 张技能卡(unique 保证一次刷新内不重复,不足时允许重复补齐)。
|
||
* @param count 需要抽取的数量
|
||
*/
|
||
export function drawSkillCards(count: number): CardConfig[] {
|
||
const safeCount = Math.max(0, Math.floor(count));
|
||
if (SkillCardList.length === 0 || safeCount <= 0) return [];
|
||
|
||
const picked: CardConfig[] = [];
|
||
let available = [...SkillCardList];
|
||
while (picked.length < safeCount) {
|
||
if (available.length === 0) break;
|
||
const pick = weightedPick(available);
|
||
if (!pick) break;
|
||
picked.push(pick);
|
||
available = available.filter(c => c.uuid !== pick.uuid);
|
||
}
|
||
|
||
// 不足时允许重复补齐
|
||
const filled = [...picked];
|
||
while (filled.length < safeCount) {
|
||
const fallback = weightedPick(SkillCardList);
|
||
if (!fallback) break;
|
||
filled.push(fallback);
|
||
}
|
||
return filled;
|
||
}
|