refactor(game): 拆分装备卡配置与逻辑,独立管理装备系统

1. 将装备卡从原技能卡池拆分至独立的EquipSet.ts配置
2. 新增专用的装备盒实体与事件流程,替换原有技能卡复用逻辑
3. 调整FieldSkillHelper以支持装备卡的属性加成统计
4. 优化装备商店与抽卡逻辑,移除装备卡的抽卡参与
This commit is contained in:
pan
2026-07-22 12:55:57 +08:00
parent e17ffeb2fd
commit fd056b4433
8 changed files with 124 additions and 115 deletions

View File

@@ -3,7 +3,6 @@ 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"
import { EquipCardData, isEquipmentCard, getEquipmentFieldCount } from "./EquipSet"
class I18nString {
constructor(private key: string, private params?: any[]) { }
@@ -166,7 +165,11 @@ const waveToCardLv: Record<number, number> = {};
SKILL_CARD_WAVES.forEach((w, i) => { waveToCardLv[w] = i + 1; });
const SkillCardData: any[] = [
// ==================== wave 5 档(范围攻击卡ap 递增,间隔缩短 ====================
// ==================== wave 1 档(基础强度 ====================
// 装备卡Field 类型)已迁移至 EquipSet.ts此处仅保留技能卡
// ==================== wave 5 档(强度 ×2 ====================
// --- 范围攻击卡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 } },
@@ -174,13 +177,16 @@ const SkillCardData: any[] = [
{ 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 } },
// ==================== wave 8 档范围攻击卡ap 最高,间隔最短) ====================
// ==================== wave 8 档(强度 ×3 ====================
{ 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 } },
// --- 范围攻击卡ap 最高,间隔最短) ---
];
SkillCardData.forEach(data => {
@@ -209,29 +215,6 @@ SkillCardData.forEach(data => {
});
});
// 装备卡统一从 EquipSet 注册到 CardPoolListtrigger_type=Fieldkeep_waves=-1
EquipCardData.forEach(data => {
const cardLv = waveToCardLv[data.wave] ?? 1;
CardPoolList.push({
uuid: data.uuid,
type: CardType.Skill,
cost: data.cost ?? 0,
weight: 10,
pool_lv: CardLV.LV1,
wave: data.wave,
kind: CKind.Skill,
card_lv: cardLv,
name: data.name,
info: data.info,
is_inst: false,
t_times: 999,
t_inv: 0,
keep_waves: -1,
field: data.field,
trigger_type: CardTriggerType.Field,
});
});
export enum SpecialRefreshHeroType {
Any = 0,
@@ -291,9 +274,8 @@ const clampCardLv = (lv: number): CardLV => {
return CardLV.LV1;
}
// ============ 装备(光环类技能卡)语义化封装 ============
// 装备判定逻辑已迁移至 EquipSet.ts此处 re-export 保持外部引用兼容。
export { isEquipmentCard, getEquipmentFieldCount };
// ============ 装备相关语义已迁移至 EquipSet.ts ============
// 装备卡池EquipPoolList独立管理不再混入 CardPoolList
/** 单次按权重抽取一张卡 */
const weightedPick = (cards: CardConfig[]): CardConfig | null => {
@@ -376,7 +358,6 @@ export const drawCardsByRule = (
targetPoolLv?: number
wave?: number
unique?: boolean
excludeEquipment?: boolean
} = {}
): CardConfig[] => {
const count = Math.max(0, Math.floor(options.count ?? 4))
@@ -406,11 +387,6 @@ export const drawCardsByRule = (
})
}
// 装备卡已改为商店直购,不再参与抽卡
if (options.excludeEquipment) {
pool = pool.filter(card => !isEquipmentCard(card));
}
const picked = pickCards(pool, count, options.unique)
return picked
}

View File

@@ -3,45 +3,38 @@
* @description 装备卡池独立配置
*
* 职责:
* 1. 定义所有装备卡的原始数据EquipCardData
* 2. 提供 isEquipmentCard / getEquipmentFieldCount 工具函数
* 定义所有装备卡的静态数据与技能卡池CardSet.CardPoolList彻底分离
* 装备卡不再参与抽卡,改为商店直购,任务开始时一次性全部展示
*
* 设计说明
* - 装备卡在运行时仍以 CardConfig 形式注册到 CardPoolList由 CardSet.ts 统一映射),
* 保证 SkillBoxComp.init() 和 EquipListComp.applyCardData() 能通过 CardPoolList 查询配置。
* - 装备卡统一 trigger_type = Fieldkeep_waves = -1持续到战斗结束
* - wave 档位区分强度wave 1 (×1) / wave 5 (×2) / wave 8 (×3)
* field uuid 分别对应 FieldSkillSet 的 70xx / 72xx / 74xx 段。
* 装备生效机制
* 购买 → 派发 GameEvent.UseEquipCard → MissEquipComp 接收 → EBox ECS 实体
* → EquipBoxComptrigger_type=Field被动驻场→ FieldSkillHelper 全局聚合属性加成
*
* 依赖:
* - GameSet.SKILL_CARD_WAVES —— wave 档位定义
* - CardConfig / CardTriggerType / CardType / CKind / CardLVCardSet
* - SKILL_CARD_WAVESGameSet—— wave 档位定义
* - FieldSkillSetSkillSet—— 属性词条配置
*/
import { CardConfig, CardType, CardLV, CKind, CardTriggerType } from "./CardSet";
import { SKILL_CARD_WAVES } from "./GameSet";
/**
* 装备卡原始数据(不含 CardType/CKind 等框架字段,由 CardSet.ts 统一映射为 CardConfig
* trigger_type 固定为 Fieldkeep_waves 固定为 -1。
*/
export interface EquipCardRaw {
/** 装备唯一标识 */
/** wave → card_lv 映射wave 1→lv1, wave 5→lv2, wave 8→lv3 */
const waveToCardLv: Record<number, number> = {};
SKILL_CARD_WAVES.forEach((w, i) => { waveToCardLv[w] = i + 1; });
/** 装备卡原始数据(仅装备相关字段,由 EquipSet 内部转换为 CardConfig */
interface EquipRawData {
uuid: number;
/** 所属波次档位 */
wave: number;
/** 装备名称 */
name: string;
/** 装备描述 */
info: string;
/** 属性词条数组(指向 FieldSkillSet uuid支持单卡多词条 */
field: number[];
/** 购买费用(默认 0 */
cost?: number;
}
// ==================== 装备卡数据 ====================
export const EquipCardData: EquipCardRaw[] = [
/** 装备卡原始数据表 */
const EquipRawList: EquipRawData[] = [
// ==================== wave 1 档(基础强度) ====================
{ uuid: 8701, wave: SKILL_CARD_WAVES[0], name: "战后恢复", info: "战斗结束生命回复量+10%", field: [7001] },
{ uuid: 8702, wave: SKILL_CARD_WAVES[0], name: "攻击加成", info: "英雄攻击力+10%", field: [7002] },
{ uuid: 8703, wave: SKILL_CARD_WAVES[0], name: "击晕加成", info: "英雄击晕概率+10%", field: [7003] },
@@ -51,14 +44,12 @@ export const EquipCardData: EquipCardRaw[] = [
{ uuid: 8707, wave: SKILL_CARD_WAVES[0], name: "生命加成", info: "英雄最大生命+10%", field: [7007] },
{ uuid: 8708, wave: SKILL_CARD_WAVES[0], name: "风怒加成", info: "英雄风怒概率+10%", field: [7008] },
{ uuid: 8709, wave: SKILL_CARD_WAVES[0], name: "穿刺加成", info: "英雄穿刺概率+10%", field: [7009] },
{ uuid: 8710, wave: SKILL_CARD_WAVES[0], name: "金币收益", info: "每回合金币收益+1", field: [7010] },
{ uuid: 8711, wave: SKILL_CARD_WAVES[0], name: "出售强化", info: "卖出英雄金币+1", field: [7011] },
// --- 多词条装备 ---
// 多词条装备
{ uuid: 8720, wave: SKILL_CARD_WAVES[0], name: "勇者护符", info: "英雄攻击力+10%, 暴击率+10%, 暴击伤害+20%", field: [7002, 7004, 7005] },
// ==================== wave 5 档(强度 ×2field uuid 72xx 段 ====================
// ==================== wave 5 档(强度 ×2 ====================
{ uuid: 8751, wave: SKILL_CARD_WAVES[1], name: "战后恢复+", info: "战斗结束生命回复量+20%", field: [7201] },
{ uuid: 8752, wave: SKILL_CARD_WAVES[1], name: "攻击加成+", info: "英雄攻击力+20%", field: [7202] },
{ uuid: 8753, wave: SKILL_CARD_WAVES[1], name: "击晕加成+", info: "英雄击晕概率+20%", field: [7203] },
@@ -68,15 +59,13 @@ export const EquipCardData: EquipCardRaw[] = [
{ uuid: 8757, wave: SKILL_CARD_WAVES[1], name: "生命加成+", info: "英雄最大生命+20%", field: [7207] },
{ uuid: 8758, wave: SKILL_CARD_WAVES[1], name: "风怒加成+", info: "英雄风怒概率+20%", field: [7208] },
{ uuid: 8759, wave: SKILL_CARD_WAVES[1], name: "穿刺加成+", info: "英雄穿刺概率+20%", field: [7209] },
{ uuid: 8760, wave: SKILL_CARD_WAVES[1], name: "金币收益+", info: "每回合金币收益+2", field: [7210] },
{ uuid: 8761, wave: SKILL_CARD_WAVES[1], name: "购买优惠+", info: "购买卡牌费用-2金币", field: [7212] },
{ uuid: 8762, wave: SKILL_CARD_WAVES[1], name: "刷新优惠", info: "刷新卡牌费用-1金币", field: [7213] },
// --- 多词条装备 ---
// 多词条装备
{ uuid: 8770, wave: SKILL_CARD_WAVES[1], name: "守卫护甲", info: "英雄最大生命+20%, 战后生命回复+20%, 攻速+20%", field: [7207, 7201, 7206] },
// ==================== wave 8 档(强度 ×3field uuid 74xx 段 ====================
// ==================== wave 8 档(强度 ×3 ====================
{ uuid: 8801, wave: SKILL_CARD_WAVES[2], name: "战后恢复++", info: "战斗结束生命回复量+30%", field: [7401] },
{ uuid: 8802, wave: SKILL_CARD_WAVES[2], name: "攻击加成++", info: "英雄攻击力+30%", field: [7402] },
{ uuid: 8803, wave: SKILL_CARD_WAVES[2], name: "击晕加成++", info: "英雄击晕概率+30%", field: [7403] },
@@ -86,38 +75,51 @@ export const EquipCardData: EquipCardRaw[] = [
{ uuid: 8807, wave: SKILL_CARD_WAVES[2], name: "生命加成++", info: "英雄最大生命+30%", field: [7407] },
{ uuid: 8808, wave: SKILL_CARD_WAVES[2], name: "风怒加成++", info: "英雄风怒概率+30%", field: [7408] },
{ uuid: 8809, wave: SKILL_CARD_WAVES[2], name: "穿刺加成++", info: "英雄穿刺概率+30%", field: [7409] },
{ uuid: 8810, wave: SKILL_CARD_WAVES[2], name: "金币收益++", info: "每回合金币收益+3", field: [7410] },
// 触发次数强化
{ uuid: 8811, wave: SKILL_CARD_WAVES[2], name: "召唤强化++", info: "召唤触发技能次数+1", field: [7014] },
{ uuid: 8812, wave: SKILL_CARD_WAVES[2], name: "死亡强化++", info: "死亡触发技能次数+1", field: [7015] },
{ uuid: 8813, wave: SKILL_CARD_WAVES[2], name: "开场强化++", info: "战斗开始触发技能次数+1", field: [7016] },
{ uuid: 8814, wave: SKILL_CARD_WAVES[2], name: "结束强化++", info: "战斗结束触发技能次数+1", field: [7017] },
{ uuid: 8815, wave: SKILL_CARD_WAVES[2], name: "攻击强化++", info: "攻击触发技能次数+1", field: [7018] },
{ uuid: 8816, wave: SKILL_CARD_WAVES[2], name: "受击强化++", info: "被攻击触发技能次数+1", field: [7019] },
// --- 多词条装备 ---
// 多词条装备
{ uuid: 8820, wave: SKILL_CARD_WAVES[2], name: "神圣之刃", info: "英雄攻击力+30%, 暴击率+30%, 暴击伤害+60%, 攻速+30%", field: [7402, 7404, 7405, 7406] },
];
// ==================== 工具函数 ====================
/**
* 判断卡牌是否为「装备」(光环类技能卡)。
* 判定条件trigger_type 为 Field3且 field 数组非空。
* 装备卡池列表(转换为 CardConfig 格式)
*
* 使用数字字面量 3 避免对 CardSet.CardTriggerType 的运行时依赖,
* 由 CardSet.ts 注册时统一填充 trigger_type = CardTriggerType.Field。
* 所有装备卡统一配置:
* - type: Skill复用卡牌体系
* - trigger_type: Field被动驻场
* - keep_waves: -1持续到战斗结束
* - is_inst: false不主动施法
* - cost: 由原始数据指定,默认 0
*/
export const isEquipmentCard = (card: { trigger_type?: number; field?: number[] }): boolean => {
return card.trigger_type === 3
&& !!card.field
&& card.field.length > 0;
}
export const EquipPoolList: CardConfig[] = EquipRawList.map(data => ({
uuid: data.uuid,
type: CardType.Skill,
cost: data.cost ?? 0,
weight: 10,
pool_lv: CardLV.LV1,
wave: data.wave,
kind: CKind.Skill,
card_lv: waveToCardLv[data.wave] ?? 1,
name: data.name,
info: data.info,
is_inst: false,
t_times: 999,
t_inv: 0,
keep_waves: -1,
field: data.field,
trigger_type: CardTriggerType.Field,
}));
/**
* 获取装备卡的属性词条数量。
* 非装备卡返回 0装备卡返回 field 数组长度。
* 按 UUID 查找装备卡配置
* @param uuid 装备卡 UUID
*/
export const getEquipmentFieldCount = (card: { trigger_type?: number; field?: number[] }): number => {
return isEquipmentCard(card) ? (card.field?.length ?? 0) : 0;
export function findEquipByUuid(uuid: number): CardConfig | undefined {
return EquipPoolList.find(e => e.uuid === uuid);
}

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "efed3c93-e996-4e93-9801-e948cf268e3c",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -82,5 +82,7 @@ export enum GameEvent {
CardPoolUpgrade = "CardPoolUpgrade",
TriggerSkill = "TriggerSkill", // 瞬间触发施法事件
RemoveSkillBox = "RemoveSkillBox", // 技能盒销毁事件
UseEquipCard = "UseEquipCard", // 装备卡购买使用事件
RemoveEquipBox = "RemoveEquipBox", // 装备盒销毁事件
}

View File

@@ -4,6 +4,7 @@ import { HeroInfo } from "../common/config/heroSet";
import { FieldSkillSet, FieldSkillType } from "../common/config/SkillSet";
import { HeroAttrsComp } from "./HeroAttrsComp";
import { SkillBoxComp } from "../map/SkillBoxComp";
import { EquipBoxComp } from "../map/EquipBoxComp";
/**
* 驻场技能(光环属性)计算辅助类
@@ -45,6 +46,19 @@ export class FieldSkillHelper {
}
});
// 3. 统计装备盒(装备卡)带来的驻场技能加成
ecs.query(ecs.allOf(EquipBoxComp)).forEach((entity: ecs.Entity) => {
const equipBox = entity.get(EquipBoxComp);
if (!equipBox || !equipBox.field || equipBox.field.length === 0) return;
for (const skillUuid of equipBox.field) {
const skillConfig = FieldSkillSet[skillUuid];
if (skillConfig && skillConfig.type === type) {
total += skillConfig.value;
}
}
});
return total;
}
}

View File

@@ -24,7 +24,8 @@
* - 销毁时通过 GameEvent.RemoveSkillBox 通知 MissSkillsComp 回收槽位
*
* 依赖:
* - CardPoolList / CardTriggerTypeCardSet—— 查询技能卡的触发配置
* - CardPoolList / CardTriggerTypeCardSet—— 通用卡牌类型定义
* - EquipPoolListEquipSet—— 装备卡池配置(查询触发配置)
* - SkillSet —— 技能静态配置icon 字段)
* - GameEvent —— 各类游戏事件
* - smc.mission —— 游戏运行状态
@@ -34,6 +35,7 @@ import { _decorator, Node, Prefab, Sprite, Label, Vec3, resources, SpriteAtlas,
import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
import { CCComp } from "../../../../extensions/oops-plugin-framework/assets/module/common/CCComp";
import { CardPoolList, CardTriggerType } from "../common/config/CardSet";
import { EquipPoolList } from "../common/config/EquipSet";
import { SkillSet, SkillOverrides, FieldSkillSet } from "../common/config/SkillSet";
import { oops } from "db://oops-framework/core/Oops";
import { GameEvent } from "../common/config/GameEvent";
@@ -149,7 +151,9 @@ export class EquipBoxComp extends CCComp {
if (!this.initialized) return;
oops.audio.playEffect("music/button");
// 点击时弹出 HInfoComp传入卡牌 UUID 和等级以启用预览模式
const config = CardPoolList.find(c => c.uuid === this.s_uuid || c.skill === this.s_uuid);
// 优先从装备卡池查找,找不到再从技能卡池查找
const config = EquipPoolList.find(c => c.uuid === this.s_uuid || c.skill === this.s_uuid)
?? CardPoolList.find(c => c.uuid === this.s_uuid || c.skill === this.s_uuid);
const cardUuid = config ? config.uuid : this.s_uuid;
oops.gui.remove(UIID.HInfo);
@@ -158,7 +162,7 @@ export class EquipBoxComp extends CCComp {
/**
* 初始化技能卡效果:
* 1. 从 CardPoolList 查询技能卡的触发配置(含 trigger_type
* 1. 从 EquipPoolList 查询装备卡的触发配置(含 trigger_type
* 2. 更新 UI 显示(图标 + 次数)。
* 3. 按 trigger_type 注册对应事件监听并执行首次触发。
*
@@ -168,8 +172,8 @@ export class EquipBoxComp extends CCComp {
init(uuid: number, card_lv: number) {
this.card_lv = card_lv;
// 查询触发配置
const config = CardPoolList.find(c => c.uuid === uuid);
// 装备卡配置已迁移至 EquipPoolList
const config = EquipPoolList.find(c => c.uuid === uuid);
if (config) {
this.s_uuid = config.skill ?? uuid; // 获取实际的技能 UUID
this.is_instant = config.is_inst ?? true;

View File

@@ -4,18 +4,19 @@
*
* 职责:
* 1. 渲染单个装备卡的显示信息(名称、等级、属性词条、图标)。
* 2. 处理购买点击 → 扣费 → 派发 UseSkillCard 事件触发装备生效。
* 2. 处理购买点击 → 扣费 → 派发 UseEquipCard 事件触发装备生效。
*
* 装备使用机制:
* 与技能卡使用流程一致——购买后派发 GameEvent.UseSkillCard
* 由 MissSkillsComp 接收并创建 SkillBoxComp 实体,
* SkillBoxComp 按 Field 类型被动驻场,属性加成由 FieldSkillHelper 全局聚合。
* 与技能卡使用流程一致——购买后派发 GameEvent.UseEquipCard
* 由 MissEquipComp 接收并创建 EquipBoxComp 实体,
* EquipBoxComp 按 Field 类型被动驻场,属性加成由 FieldSkillHelper 全局聚合。
*/
import { mLogger } from "../common/Logger";
import { _decorator, Node, Sprite, Label, NodeEventType } from "cc";
import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
import { CCComp } from "../../../../extensions/oops-plugin-framework/assets/module/common/CCComp";
import { CardConfig, CardPoolList } from "../common/config/CardSet";
import { CardConfig } from "../common/config/CardSet";
import { EquipPoolList } from "../common/config/EquipSet";
import { FieldSkillSet } from "../common/config/SkillSet";
import { oops } from "db://oops-framework/core/Oops";
import { GameEvent } from "../common/config/GameEvent";
@@ -106,7 +107,7 @@ export class EquipListComp extends CCComp {
updateUI() {
if (!this.cardData) return;
const cardConfig = CardPoolList.find(c => c.uuid === this.cardData!.uuid);
const cardConfig = EquipPoolList.find(c => c.uuid === this.cardData!.uuid);
// 名称
if (this.name_label) {
@@ -191,8 +192,8 @@ export class EquipListComp extends CCComp {
return;
}
// 派发 UseSkillCard装备生效流程与技能卡一致
oops.message.dispatchEvent(GameEvent.UseSkillCard, this.cardData);
// 派发 UseEquipCard装备生效流程由 MissEquipComp 接收处理
oops.message.dispatchEvent(GameEvent.UseEquipCard, this.cardData);
// 标记已购买
this.isPurchased = true;

View File

@@ -39,7 +39,8 @@ import { _decorator, instantiate, Label, Node, NodeEventType, Prefab, Tween, twe
import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
import { CCComp } from "../../../../extensions/oops-plugin-framework/assets/module/common/CCComp";
import { GameEvent } from "../common/config/GameEvent";
import { CardConfig, CardPoolList, CardType, drawCardsByRule, isEquipmentCard, SpecialRefreshCardList, SpecialRefreshHeroType, SpecialUpgradeCardList } from "../common/config/CardSet";
import { CardConfig, CardPoolList, CardType, drawCardsByRule, SpecialRefreshCardList, SpecialRefreshHeroType, SpecialUpgradeCardList } from "../common/config/CardSet";
import { EquipPoolList } from "../common/config/EquipSet";
import { CardComp } from "./CardComp";
import { SCardComp } from "./SCardComp";
import { EquipListComp } from "./EquipListComp";
@@ -319,6 +320,8 @@ export class MissionCardComp extends CCComp {
oops.message.on(GameEvent.HeroSell, this.onHeroSell, this);
oops.message.on(GameEvent.UseHeroCard, this.onUseHeroCard, this);
oops.message.on(GameEvent.UseSkillCard, this.onUseSkillCard, this);
// 监听装备购买事件,追踪已购记录
oops.message.on(GameEvent.UseEquipCard, this.onUseEquipCard, this);
oops.message.on(GameEvent.UseSpecialCard, this.onUseSpecialCard, this);
oops.message.on(GameEvent.ShowSmallTip, this.onShowSmallTip, this);
oops.message.on(GameEvent.CardUsed, this.onCardUsed, this);
@@ -475,12 +478,6 @@ export class MissionCardComp extends CCComp {
// 由 onCardUsed 立即向被使用的槽位补充一张新技能卡。
// 弹窗由外部(按钮/阶段切换)控制显隐。
// 追踪装备购买记录EquipListComp 购买后也会派发此事件)
const usedCard = args as CardConfig;
if (usedCard && isEquipmentCard(usedCard)) {
this.purchasedEquipUuids.add(usedCard.uuid);
}
// 修复:独立判断 guide2 的关闭 和 guide3 的开启
if (!smc.finish_guides.includes(2)) {
smc.finish_guides.push(2);
@@ -495,6 +492,14 @@ export class MissionCardComp extends CCComp {
this.scheduleOnce(() => this.updateCoinAndCostUI(), 0);
}
/** 装备购买事件回调:记录已购 UUID防止重复购买 */
private onUseEquipCard(event: string, args: any) {
const usedCard = args as CardConfig;
if (usedCard) {
this.purchasedEquipUuids.add(usedCard.uuid);
}
}
/** 解除按钮监听,避免节点销毁后回调泄漏 */
private unbindEvents() {
oops.message.off(GameEvent.CoinAdd, this.onCoinAdd, this);
@@ -503,6 +508,7 @@ export class MissionCardComp extends CCComp {
oops.message.off(GameEvent.HeroSell, this.onHeroSell, this);
oops.message.off(GameEvent.UseHeroCard, this.onUseHeroCard, this);
oops.message.off(GameEvent.UseSkillCard, this.onUseSkillCard, this);
oops.message.off(GameEvent.UseEquipCard, this.onUseEquipCard, this);
oops.message.off(GameEvent.UseSpecialCard, this.onUseSpecialCard, this);
oops.message.off(GameEvent.ShowSmallTip, this.onShowSmallTip, this);
oops.message.off(GameEvent.CardUsed, this.onCardUsed, this);
@@ -744,10 +750,8 @@ export class MissionCardComp extends CCComp {
// 清空旧列表
this.equipsBoxNode.removeAllChildren();
// 获取所有装备
const equipments = CardPoolList.filter(c => isEquipmentCard(c));
for (const equip of equipments) {
// 从独立装备卡池获取所有装备
for (const equip of EquipPoolList) {
const node = instantiate(this.equipPrefab);
this.equipsBoxNode.addChild(node);
const comp = node.getComponent(EquipListComp) || node.addComponent(EquipListComp);
@@ -765,7 +769,7 @@ export class MissionCardComp extends CCComp {
}
mLogger.log(this.debugMode, "MissionCardComp", "populate equipments", {
count: equipments.length
count: EquipPoolList.length
});
}
@@ -1082,13 +1086,11 @@ export class MissionCardComp extends CCComp {
private buildSkillDrawCards(): CardConfig[] {
const currentWave = this.getCurrentWave();
// 使用明确规则的 drawCardsByRule指定只要 3 张技能卡,并且过滤对应 wave
// 装备卡已改为商店直购,不再参与抽卡
const cards = drawCardsByRule(1, {
count: 3,
type: CardType.Skill,
wave: currentWave,
unique: true, // 保证技能牌不重复
excludeEquipment: true, // 排除装备卡
});
if (cards.length >= 3) return cards.slice(0, 3);
@@ -1099,7 +1101,6 @@ export class MissionCardComp extends CCComp {
type: CardType.Skill,
wave: currentWave,
unique: true,
excludeEquipment: true,
});
if (fallback.length === 0) break;