feat(equip-system): 新增装备系统核心支持

1.  重构卡牌配置定义,明确Field类型为装备卡并支持单卡多词条
2.  添加装备卡判断和词条计数工具函数
3.  新增EquipListComp装备列表组件
4.  更新aui.plist和预制体UI资源适配新装备系统
5.  补充多词条装备示例配置
This commit is contained in:
panFD
2026-07-22 00:22:08 +08:00
parent db3b5f3649
commit 3e9b65e99d
12 changed files with 33183 additions and 10245 deletions

View File

@@ -55,7 +55,7 @@ export enum CardSkillType {
export enum CardTriggerType {
Instant = 1, // 即时触发:使用后立即生效一次
Interval = 2, // 定时循环:战斗中按 t_inv 间隔重复触发
Field = 3, // 驻场光环:被动生效(仅显式分类,仍由 field 字段驱动)
Field = 3, // 驻场光环(俗称「装备」):被动生效,由 field 数组驱动,支持单卡多词条
FightStart = 4, // 战斗开始时触发
FightEnd = 5, // 战斗结束时触发(每波结束)
HeroDead = 6, // 场上己方英雄死亡时触发
@@ -98,7 +98,7 @@ export interface CardConfig {
t_inv?: number // 触发间隔(秒)
keep_waves?: number // 维持的波次数(-1表示持续到战斗结束0或undefined表示仅本波次
overrides?: SkillOverrides // 技能参数覆写如自定义伤害ap、buff值、金币数等
field?: number[] // 驻场技能 UUID 数组,表示该卡牌提供驻场属性加成
field?: number[] // 装备词条数组驻场光环卡trigger_type=Field的属性词条支持单卡多词条如 [7002, 7004, 7005] 同时提供攻击/暴击/暴伤)
/** 触发类型(必填,技能卡专用;功能卡/英雄卡可缺省) */
trigger_type?: CardTriggerType;
@@ -180,6 +180,8 @@ const SkillCardData: any[] = [
{ 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 },
// --- 多词条装备示例(一张卡自带多条属性词条) ---
{ uuid: 8720, skill: 0, wave: SKILL_CARD_WAVES[0], name: "勇者护符", info: "英雄攻击力+10%, 暴击率+10%, 暴击伤害+20%", is_inst: false, keep_waves: -1, field: [7002, 7004, 7005], trigger_type: CardTriggerType.Field },
// ==================== wave 5 档(强度 ×2 ====================
// --- 驻场卡field uuid +200对应 FieldSkillSet 72xx 段) ---
@@ -204,6 +206,8 @@ const SkillCardData: any[] = [
{ 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 },
// --- 多词条装备示例(一张卡自带多条属性词条) ---
{ uuid: 8770, skill: 0, wave: SKILL_CARD_WAVES[1], name: "守卫护甲", info: "英雄最大生命+20%, 战后生命回复+20%, 攻速+20%", is_inst: false, keep_waves: -1, field: [7207, 7201, 7206], trigger_type: CardTriggerType.Field },
// ==================== wave 8 档(强度 ×3 ====================
@@ -234,6 +238,8 @@ const SkillCardData: any[] = [
{ 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 },
// --- 多词条装备示例(一张卡自带多条属性词条) ---
{ uuid: 8820, skill: 0, wave: SKILL_CARD_WAVES[2], name: "神圣之刃", info: "英雄攻击力+30%, 暴击率+30%, 暴击伤害+60%, 攻速+30%", is_inst: false, keep_waves: -1, field: [7402, 7404, 7405, 7406], trigger_type: CardTriggerType.Field },
// --- 范围攻击卡ap 最高,间隔最短) ---
];
@@ -322,6 +328,28 @@ const clampCardLv = (lv: number): CardLV => {
return CardLV.LV1;
}
// ============ 装备(光环类技能卡)语义化封装 ============
// 说明:不新增 CardType / CKind以 trigger_type=Field 且 field 非空作为装备识别标志,
// 复用现有 CardConfig.field: number[] 天然支持单卡多词条(一张装备自带多条属性加成)。
/**
* 判断卡牌是否为「装备」(光环类技能卡)。
* 判定条件trigger_type 为 Field且 field 数组非空。
*/
export const isEquipmentCard = (card: CardConfig): boolean => {
return card.trigger_type === CardTriggerType.Field
&& !!card.field
&& card.field.length > 0;
}
/**
* 获取装备卡的属性词条数量。
* 非装备卡返回 0装备卡返回 field 数组长度。
*/
export const getEquipmentFieldCount = (card: CardConfig): number => {
return isEquipmentCard(card) ? (card.field?.length ?? 0) : 0;
}
/** 单次按权重抽取一张卡 */
const weightedPick = (cards: CardConfig[]): CardConfig | null => {
if (cards.length === 0) return null