refactor: 拆分技能卡配置到独立文件,优化抽卡逻辑
1. 新建SCardSet.ts单独管理技能卡池配置,将原CardSet.ts中的技能卡数据迁移 2. 重构多处业务代码,从SkillCardList而非CardPoolList获取技能卡配置 3. 简化技能卡抽卡逻辑,新增drawSkillCards工具函数统一处理抽卡 4. 修复TalentsComp中计算contentHeight的小语法问题 5. 新增技能卡商店显隐控制功能
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
|||||||
import * as exp from "constants"
|
import * as exp from "constants"
|
||||||
import { HeroInfo, HeroList, HType } from "./heroSet"
|
import { HeroInfo, HeroList, HType } from "./heroSet"
|
||||||
import { FightSet, SKILL_CARD_WAVES } from "./GameSet"
|
import { FightSet } from "./GameSet"
|
||||||
import { oops } from "db://oops-framework/core/Oops"
|
import { oops } from "db://oops-framework/core/Oops"
|
||||||
import { SkillOverrides, TGroup } from "./SkillSet"
|
import { SkillOverrides, TGroup } from "./SkillSet"
|
||||||
|
|
||||||
@@ -158,63 +158,6 @@ HeroList.forEach(uuid => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// 添加非英雄卡牌 (技能、功能卡)
|
|
||||||
// 体系: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 类型)已迁移至 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 } },
|
|
||||||
{ 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 } },
|
|
||||||
|
|
||||||
|
|
||||||
// ==================== 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 => {
|
|
||||||
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 {
|
export enum SpecialRefreshHeroType {
|
||||||
Any = 0,
|
Any = 0,
|
||||||
|
|||||||
125
assets/script/game/common/config/SCardSet.ts
Normal file
125
assets/script/game/common/config/SCardSet.ts
Normal file
@@ -0,0 +1,125 @@
|
|||||||
|
/**
|
||||||
|
* @file SCardSet.ts
|
||||||
|
* @description 技能卡池独立配置
|
||||||
|
*
|
||||||
|
* 职责:
|
||||||
|
* 维护所有技能卡(CardType.Skill)的原始数据,并构建为标准 CardConfig[]。
|
||||||
|
*
|
||||||
|
* 设计:
|
||||||
|
* - 技能卡不再按 wave 过滤,所有技能卡均可被抽取(长期存在)。
|
||||||
|
* - 保留 wave / card_lv 字段仅用于 UI 排序与档位展示,不参与抽卡过滤。
|
||||||
|
*
|
||||||
|
* 依赖:
|
||||||
|
* - CardSet —— CardConfig / CardType / CKind / CardLV / CardTriggerType
|
||||||
|
* - GameSet —— SKILL_CARD_WAVES(档位定义)
|
||||||
|
* - SkillSet —— SkillOverrides
|
||||||
|
*/
|
||||||
|
import { CardConfig, CardType, CardLV, CKind, CardTriggerType } from "./CardSet";
|
||||||
|
import { SKILL_CARD_WAVES } from "./GameSet";
|
||||||
|
import { SkillOverrides } from "./SkillSet";
|
||||||
|
|
||||||
|
// 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; });
|
||||||
|
|
||||||
|
/** 技能卡原始数据(平铺字段,构建后转为 CardConfig) */
|
||||||
|
interface SkillCardRaw {
|
||||||
|
uuid: number;
|
||||||
|
skill: number;
|
||||||
|
wave: number;
|
||||||
|
name: string;
|
||||||
|
info: string;
|
||||||
|
is_inst: boolean;
|
||||||
|
t_inv?: number;
|
||||||
|
keep_waves?: number;
|
||||||
|
trigger_type: CardTriggerType;
|
||||||
|
overrides?: SkillOverrides;
|
||||||
|
}
|
||||||
|
|
||||||
|
const SkillCardData: SkillCardRaw[] = [
|
||||||
|
// ==================== 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 } },
|
||||||
|
{ 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 } },
|
||||||
|
|
||||||
|
// ==================== 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 } },
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 技能卡池(已构建为标准 CardConfig[])。
|
||||||
|
* 不再按 wave 过滤,所有技能卡均可被抽取。
|
||||||
|
*/
|
||||||
|
export const SkillCardList: CardConfig[] = SkillCardData.map(data => {
|
||||||
|
const cardLv = waveToCardLv[data.wave] ?? 1;
|
||||||
|
return {
|
||||||
|
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,
|
||||||
|
is_inst: data.is_inst,
|
||||||
|
t_times: data.is_inst ? 1 : 999,
|
||||||
|
t_inv: data.t_inv || 0,
|
||||||
|
keep_waves: data.keep_waves,
|
||||||
|
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;
|
||||||
|
}
|
||||||
9
assets/script/game/common/config/SCardSet.ts.meta
Normal file
9
assets/script/game/common/config/SCardSet.ts.meta
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"ver": "4.0.24",
|
||||||
|
"importer": "typescript",
|
||||||
|
"imported": true,
|
||||||
|
"uuid": "33e40432-3cdc-48fe-a33d-19d6f6fac7f3",
|
||||||
|
"files": [],
|
||||||
|
"subMetas": {},
|
||||||
|
"userData": {}
|
||||||
|
}
|
||||||
@@ -23,6 +23,7 @@ import { _decorator, Animation, AnimationClip, EventTouch, Label, Node, NodeEven
|
|||||||
import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
|
import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
|
||||||
import { CCComp } from "../../../../extensions/oops-plugin-framework/assets/module/common/CCComp";
|
import { CCComp } from "../../../../extensions/oops-plugin-framework/assets/module/common/CCComp";
|
||||||
import { CardConfig, CardType, SpecialRefreshCardList, SpecialUpgradeCardList, CKind, CardPoolList } from "../common/config/CardSet";
|
import { CardConfig, CardType, SpecialRefreshCardList, SpecialUpgradeCardList, CKind, CardPoolList } from "../common/config/CardSet";
|
||||||
|
import { SkillCardList } from "../common/config/SCardSet";
|
||||||
import { CardBgComp } from "./CardBgComp";
|
import { CardBgComp } from "./CardBgComp";
|
||||||
import { HeroInfo } from "../common/config/heroSet";
|
import { HeroInfo } from "../common/config/heroSet";
|
||||||
import { SkillSet } from "../common/config/SkillSet";
|
import { SkillSet } from "../common/config/SkillSet";
|
||||||
@@ -240,7 +241,7 @@ export class CardLiteComp extends CCComp {
|
|||||||
} else if (this.card_type === CardType.Skill) {
|
} else if (this.card_type === CardType.Skill) {
|
||||||
if (this.lvl_node) this.lvl_node.node.active = false;
|
if (this.lvl_node) this.lvl_node.node.active = false;
|
||||||
const skill = SkillSet[this.card_uuid];
|
const skill = SkillSet[this.card_uuid];
|
||||||
const skillCard = CardPoolList.find(c => c.uuid === this.card_uuid);
|
const skillCard = SkillCardList.find(c => c.uuid === this.card_uuid) ?? CardPoolList.find(c => c.uuid === this.card_uuid);
|
||||||
const card_lv = Math.max(1, Math.floor(this.cardData.card_lv ?? 1));
|
const card_lv = Math.max(1, Math.floor(this.cardData.card_lv ?? 1));
|
||||||
const spSuffix = card_lv >= 2 ? "★".repeat(card_lv - 1) : "";
|
const spSuffix = card_lv >= 2 ? "★".repeat(card_lv - 1) : "";
|
||||||
this.setLabel(this.name_node, `${spSuffix}${skillCard?.name || skill?.name || ""}${spSuffix}`);
|
this.setLabel(this.name_node, `${spSuffix}${skillCard?.name || skill?.name || ""}${spSuffix}`);
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ import { MissionHeroComp } from "./MissionHeroComp";
|
|||||||
import { MoveComp } from "../hero/MoveComp";
|
import { MoveComp } from "../hero/MoveComp";
|
||||||
import { FacSet, getLvColor } from "../common/config/GameSet";
|
import { FacSet, getLvColor } from "../common/config/GameSet";
|
||||||
import { CKind, CardPoolList, CardConfig, CardTriggerType } from "../common/config/CardSet";
|
import { CKind, CardPoolList, CardConfig, CardTriggerType } from "../common/config/CardSet";
|
||||||
|
import { SkillCardList } from "../common/config/SCardSet";
|
||||||
import { EquipPoolList } from "../common/config/EquipSet";
|
import { EquipPoolList } from "../common/config/EquipSet";
|
||||||
import { SkillSet } from "../common/config/SkillSet";
|
import { SkillSet } from "../common/config/SkillSet";
|
||||||
import { CardBgComp } from "./CardBgComp";
|
import { CardBgComp } from "./CardBgComp";
|
||||||
@@ -188,7 +189,7 @@ export class HInfoComp extends CCComp {
|
|||||||
// 根据来源从对应卡池查询配置
|
// 根据来源从对应卡池查询配置
|
||||||
const config = this.isEquipCard
|
const config = this.isEquipCard
|
||||||
? EquipPoolList.find(c => c.uuid === heroUuid)
|
? EquipPoolList.find(c => c.uuid === heroUuid)
|
||||||
: CardPoolList.find(c => c.uuid === heroUuid);
|
: (SkillCardList.find(c => c.uuid === heroUuid) ?? CardPoolList.find(c => c.uuid === heroUuid));
|
||||||
if (!config) return;
|
if (!config) return;
|
||||||
|
|
||||||
if (this.nameLabel) this.nameLabel.string = config.name ?? "";
|
if (this.nameLabel) this.nameLabel.string = config.name ?? "";
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ec
|
|||||||
import { CCComp } from "../../../../extensions/oops-plugin-framework/assets/module/common/CCComp";
|
import { CCComp } from "../../../../extensions/oops-plugin-framework/assets/module/common/CCComp";
|
||||||
import { GameEvent } from "../common/config/GameEvent";
|
import { GameEvent } from "../common/config/GameEvent";
|
||||||
import { CardConfig, CardPoolList, CardType, drawCardsByRule, SpecialRefreshCardList, SpecialRefreshHeroType, SpecialUpgradeCardList } from "../common/config/CardSet";
|
import { CardConfig, CardPoolList, CardType, drawCardsByRule, SpecialRefreshCardList, SpecialRefreshHeroType, SpecialUpgradeCardList } from "../common/config/CardSet";
|
||||||
|
import { drawSkillCards } from "../common/config/SCardSet";
|
||||||
import { EquipPoolList } from "../common/config/EquipSet";
|
import { EquipPoolList } from "../common/config/EquipSet";
|
||||||
import { CardComp } from "./CardComp";
|
import { CardComp } from "./CardComp";
|
||||||
import { SCardComp } from "./SCardComp";
|
import { SCardComp } from "./SCardComp";
|
||||||
@@ -229,6 +230,12 @@ export class MissionCardComp extends CCComp {
|
|||||||
if (this.closeEquips && this.closeEquips.isValid) {
|
if (this.closeEquips && this.closeEquips.isValid) {
|
||||||
this.closeEquips.off(NodeEventType.TOUCH_END, this.onCloseEquipsClick, this);
|
this.closeEquips.off(NodeEventType.TOUCH_END, this.onCloseEquipsClick, this);
|
||||||
}
|
}
|
||||||
|
if (this.showSkills && this.showSkills.isValid) {
|
||||||
|
this.showSkills.off(NodeEventType.TOUCH_END, this.onShowSkillsClick, this);
|
||||||
|
}
|
||||||
|
if (this.closeSkills && this.closeSkills.isValid) {
|
||||||
|
this.closeSkills.off(NodeEventType.TOUCH_END, this.onCloseSkillsClick, this);
|
||||||
|
}
|
||||||
this.unbindEvents();
|
this.unbindEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -275,6 +282,9 @@ export class MissionCardComp extends CCComp {
|
|||||||
this.purchasedEquipUuids.clear();
|
this.purchasedEquipUuids.clear();
|
||||||
this.populateEquipments();
|
this.populateEquipments();
|
||||||
|
|
||||||
|
// 首次进入准备阶段自动抽取一次技能卡,后续刷新只能通过技能刷新按钮触发
|
||||||
|
this.initSkillCardsOnce();
|
||||||
|
|
||||||
mLogger.log(this.debugMode, "MissionCardComp", "mission start");
|
mLogger.log(this.debugMode, "MissionCardComp", "mission start");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -346,6 +356,11 @@ export class MissionCardComp extends CCComp {
|
|||||||
/** 关闭装备商店按钮 */
|
/** 关闭装备商店按钮 */
|
||||||
this.closeEquips?.on(NodeEventType.TOUCH_END, this.onCloseEquipsClick, this);
|
this.closeEquips?.on(NodeEventType.TOUCH_END, this.onCloseEquipsClick, this);
|
||||||
|
|
||||||
|
/** 技能卡池显示按钮 */
|
||||||
|
this.showSkills?.on(NodeEventType.TOUCH_END, this.onShowSkillsClick, this);
|
||||||
|
/** 关闭技能卡池按钮 */
|
||||||
|
this.closeSkills?.on(NodeEventType.TOUCH_END, this.onCloseSkillsClick, this);
|
||||||
|
|
||||||
/** 技能卡刷新按钮 */
|
/** 技能卡刷新按钮 */
|
||||||
this.skill_refresh?.on(NodeEventType.TOUCH_START, this.onSkillDrawTouchStart, this);
|
this.skill_refresh?.on(NodeEventType.TOUCH_START, this.onSkillDrawTouchStart, this);
|
||||||
this.skill_refresh?.on(NodeEventType.TOUCH_END, this.onSkillDrawTouchEnd, this);
|
this.skill_refresh?.on(NodeEventType.TOUCH_END, this.onSkillDrawTouchEnd, this);
|
||||||
@@ -455,10 +470,19 @@ export class MissionCardComp extends CCComp {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private showSkillCardPopup() {
|
/**
|
||||||
if (!this.skill_card_node) return;
|
* 首次进入准备阶段时自动抽取一次技能卡:
|
||||||
this.skill_card_node.active = true;
|
* - 仅在任务开始时调用一次。
|
||||||
// 先分发卡牌数据(让卡面内容就绪),再做入场动画
|
* - 后续抽卡只能通过技能刷新按钮触发。
|
||||||
|
*/
|
||||||
|
private initSkillCardsOnce() {
|
||||||
|
if (this.skillCardComps.length === 0) {
|
||||||
|
this.cacheCardComps();
|
||||||
|
}
|
||||||
|
// 显示技能卡牌面板
|
||||||
|
if (this.skill_card_node) {
|
||||||
|
this.skill_card_node.active = true;
|
||||||
|
}
|
||||||
const cards = this.buildSkillDrawCards();
|
const cards = this.buildSkillDrawCards();
|
||||||
this.dispatchCardsToSkillSlots(cards);
|
this.dispatchCardsToSkillSlots(cards);
|
||||||
this.playSkillCardEnterAnim();
|
this.playSkillCardEnterAnim();
|
||||||
@@ -469,6 +493,25 @@ export class MissionCardComp extends CCComp {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 技能卡池显隐切换按钮回调:
|
||||||
|
* - 仅切换 skill_card_node 的 active 状态,不执行抽卡。
|
||||||
|
* - 后续刷新需通过技能刷新按钮(skill_refresh)触发。
|
||||||
|
*/
|
||||||
|
private onShowSkillsClick() {
|
||||||
|
if (!this.skill_card_node || !this.skill_card_node.isValid) return;
|
||||||
|
oops.audio.playEffect("music/button");
|
||||||
|
const visible = !this.skill_card_node.active;
|
||||||
|
this.skill_card_node.active = visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 关闭技能卡池按钮回调 */
|
||||||
|
private onCloseSkillsClick() {
|
||||||
|
if (!this.skill_card_node || !this.skill_card_node.isValid) return;
|
||||||
|
oops.audio.playEffect("music/button");
|
||||||
|
this.skill_card_node.active = false;
|
||||||
|
}
|
||||||
|
|
||||||
private dispatchCardsToSkillSlots(cards: CardConfig[]) {
|
private dispatchCardsToSkillSlots(cards: CardConfig[]) {
|
||||||
if (!this.skillCardComps) return;
|
if (!this.skillCardComps) return;
|
||||||
for (let i = 0; i < this.skillCardComps.length; i++) {
|
for (let i = 0; i < this.skillCardComps.length; i++) {
|
||||||
@@ -1088,36 +1131,14 @@ export class MissionCardComp extends CCComp {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构建技能卡抽卡结果,返回 3 张。
|
||||||
|
*
|
||||||
|
* 技能卡池长期存在,不再按波次过滤,
|
||||||
|
* 直接从 SCardSet 的 drawSkillCards 按权重抽取。
|
||||||
|
*/
|
||||||
private buildSkillDrawCards(): CardConfig[] {
|
private buildSkillDrawCards(): CardConfig[] {
|
||||||
const currentWave = this.getCurrentWave();
|
return drawSkillCards(3);
|
||||||
// 使用明确规则的 drawCardsByRule,指定只要 3 张技能卡,并且过滤对应 wave
|
|
||||||
const cards = drawCardsByRule(1, {
|
|
||||||
count: 3,
|
|
||||||
type: CardType.Skill,
|
|
||||||
wave: currentWave,
|
|
||||||
unique: true, // 保证技能牌不重复
|
|
||||||
});
|
|
||||||
|
|
||||||
if (cards.length >= 3) return cards.slice(0, 3);
|
|
||||||
const filled = [...cards];
|
|
||||||
while (filled.length < 3) {
|
|
||||||
const fallback = drawCardsByRule(1, {
|
|
||||||
count: 3,
|
|
||||||
type: CardType.Skill,
|
|
||||||
wave: currentWave,
|
|
||||||
unique: true,
|
|
||||||
});
|
|
||||||
if (fallback.length === 0) break;
|
|
||||||
|
|
||||||
// 如果池子数量不足,只能被迫允许重复,但尽量拿没被抽到的
|
|
||||||
const fPick = fallback.find(c => !filled.some(fc => fc.uuid === c.uuid));
|
|
||||||
if (fPick) {
|
|
||||||
filled.push(fPick);
|
|
||||||
} else {
|
|
||||||
filled.push(fallback[filled.length % fallback.length]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return filled;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private tryRefreshHeroCards(heroType?: HType): boolean {
|
private tryRefreshHeroCards(heroType?: HType): boolean {
|
||||||
@@ -1427,11 +1448,6 @@ export class MissionCardComp extends CCComp {
|
|||||||
return Math.max(0, Math.floor(missionData?.hero_num ?? 0));
|
return Math.max(0, Math.floor(missionData?.hero_num ?? 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
private getCurrentWave(): number {
|
|
||||||
const missionData = this.getMissionData();
|
|
||||||
return Math.max(1, Math.floor(missionData?.level ?? 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
private getMissionHeroMaxNum(): number {
|
private getMissionHeroMaxNum(): number {
|
||||||
return FightSet.HERO_MAX_NUM
|
return FightSet.HERO_MAX_NUM
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,8 @@ import { mLogger } from "../common/Logger";
|
|||||||
import { _decorator, Animation, AnimationClip, EventTouch, Label, Node, NodeEventType, Sprite, SpriteAtlas, Tween, tween, UIOpacity, Vec3, UITransform, Widget } from "cc";
|
import { _decorator, Animation, AnimationClip, EventTouch, Label, Node, NodeEventType, Sprite, SpriteAtlas, Tween, tween, UIOpacity, Vec3, UITransform, Widget } from "cc";
|
||||||
import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
|
import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
|
||||||
import { CCComp } from "../../../../extensions/oops-plugin-framework/assets/module/common/CCComp";
|
import { CCComp } from "../../../../extensions/oops-plugin-framework/assets/module/common/CCComp";
|
||||||
import { CardConfig, CardType, CKind, CardPoolList } from "../common/config/CardSet";
|
import { CardConfig, CardType, CKind } from "../common/config/CardSet";
|
||||||
|
import { SkillCardList } from "../common/config/SCardSet";
|
||||||
import { CardBgComp } from "./CardBgComp";
|
import { CardBgComp } from "./CardBgComp";
|
||||||
import { FieldSkillSet, SkillSet } from "../common/config/SkillSet";
|
import { FieldSkillSet, SkillSet } from "../common/config/SkillSet";
|
||||||
import { GameEvent } from "../common/config/GameEvent";
|
import { GameEvent } from "../common/config/GameEvent";
|
||||||
@@ -255,7 +256,7 @@ export class SCardComp extends CCComp {
|
|||||||
|
|
||||||
const s_uuid = this.cardData.skill ?? this.card_uuid;
|
const s_uuid = this.cardData.skill ?? this.card_uuid;
|
||||||
const skill = SkillSet[s_uuid];
|
const skill = SkillSet[s_uuid];
|
||||||
const skillCard = CardPoolList.find(c => c.uuid === this.card_uuid);
|
const skillCard = SkillCardList.find(c => c.uuid === this.card_uuid);
|
||||||
const card_lv = Math.max(1, Math.floor(this.cardData.card_lv ?? 1));
|
const card_lv = Math.max(1, Math.floor(this.cardData.card_lv ?? 1));
|
||||||
const spSuffix = card_lv >= 2 ? "★".repeat(card_lv - 1) : "";
|
const spSuffix = card_lv >= 2 ? "★".repeat(card_lv - 1) : "";
|
||||||
this.setLabel(this.name_node, `${spSuffix}${skillCard?.name || skill?.name || ""}${spSuffix}`);
|
this.setLabel(this.name_node, `${spSuffix}${skillCard?.name || skill?.name || ""}${spSuffix}`);
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
* - 销毁时通过 GameEvent.RemoveSkillBox 通知 MissSkillsComp 回收槽位
|
* - 销毁时通过 GameEvent.RemoveSkillBox 通知 MissSkillsComp 回收槽位
|
||||||
*
|
*
|
||||||
* 依赖:
|
* 依赖:
|
||||||
* - CardPoolList / CardTriggerType(CardSet)—— 查询技能卡的触发配置
|
* - SkillCardList(SCardSet)/ CardTriggerType(CardSet)—— 查询技能卡的触发配置
|
||||||
* - SkillSet —— 技能静态配置(icon 字段)
|
* - SkillSet —— 技能静态配置(icon 字段)
|
||||||
* - GameEvent —— 各类游戏事件
|
* - GameEvent —— 各类游戏事件
|
||||||
* - smc.mission —— 游戏运行状态
|
* - smc.mission —— 游戏运行状态
|
||||||
@@ -33,7 +33,8 @@ import { mLogger } from "../common/Logger";
|
|||||||
import { _decorator, Node, Prefab, Sprite, Label, Vec3, resources, SpriteAtlas, tween, v3, Tween, NodeEventType } from "cc";
|
import { _decorator, Node, Prefab, Sprite, Label, Vec3, resources, SpriteAtlas, tween, v3, Tween, NodeEventType } from "cc";
|
||||||
import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
|
import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
|
||||||
import { CCComp } from "../../../../extensions/oops-plugin-framework/assets/module/common/CCComp";
|
import { CCComp } from "../../../../extensions/oops-plugin-framework/assets/module/common/CCComp";
|
||||||
import { CardPoolList, CardTriggerType } from "../common/config/CardSet";
|
import { CardTriggerType } from "../common/config/CardSet";
|
||||||
|
import { SkillCardList } from "../common/config/SCardSet";
|
||||||
import { SkillSet, SkillOverrides, FieldSkillSet } from "../common/config/SkillSet";
|
import { SkillSet, SkillOverrides, FieldSkillSet } from "../common/config/SkillSet";
|
||||||
import { oops } from "db://oops-framework/core/Oops";
|
import { oops } from "db://oops-framework/core/Oops";
|
||||||
import { GameEvent } from "../common/config/GameEvent";
|
import { GameEvent } from "../common/config/GameEvent";
|
||||||
@@ -149,7 +150,7 @@ export class SkillBoxComp extends CCComp {
|
|||||||
if (!this.initialized) return;
|
if (!this.initialized) return;
|
||||||
oops.audio.playEffect("music/button");
|
oops.audio.playEffect("music/button");
|
||||||
// 点击时弹出 HInfoComp,传入卡牌 UUID 和等级以启用预览模式
|
// 点击时弹出 HInfoComp,传入卡牌 UUID 和等级以启用预览模式
|
||||||
const config = CardPoolList.find(c => c.uuid === this.s_uuid || c.skill === this.s_uuid);
|
const config = SkillCardList.find(c => c.uuid === this.s_uuid || c.skill === this.s_uuid);
|
||||||
const cardUuid = config ? config.uuid : this.s_uuid;
|
const cardUuid = config ? config.uuid : this.s_uuid;
|
||||||
|
|
||||||
oops.gui.remove(UIID.HInfo);
|
oops.gui.remove(UIID.HInfo);
|
||||||
@@ -158,7 +159,7 @@ export class SkillBoxComp extends CCComp {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 初始化技能卡效果:
|
* 初始化技能卡效果:
|
||||||
* 1. 从 CardPoolList 查询技能卡的触发配置(含 trigger_type)。
|
* 1. 从 SkillCardList 查询技能卡的触发配置(含 trigger_type)。
|
||||||
* 2. 更新 UI 显示(图标 + 次数)。
|
* 2. 更新 UI 显示(图标 + 次数)。
|
||||||
* 3. 按 trigger_type 注册对应事件监听并执行首次触发。
|
* 3. 按 trigger_type 注册对应事件监听并执行首次触发。
|
||||||
*
|
*
|
||||||
@@ -169,7 +170,7 @@ export class SkillBoxComp extends CCComp {
|
|||||||
this.card_lv = card_lv;
|
this.card_lv = card_lv;
|
||||||
|
|
||||||
// 查询触发配置
|
// 查询触发配置
|
||||||
const config = CardPoolList.find(c => c.uuid === uuid);
|
const config = SkillCardList.find(c => c.uuid === uuid);
|
||||||
if (config) {
|
if (config) {
|
||||||
this.s_uuid = config.skill ?? uuid; // 获取实际的技能 UUID
|
this.s_uuid = config.skill ?? uuid; // 获取实际的技能 UUID
|
||||||
this.is_instant = config.is_inst ?? true;
|
this.is_instant = config.is_inst ?? true;
|
||||||
|
|||||||
@@ -15,7 +15,8 @@ import { _decorator, instantiate, Node, Prefab, UITransform } from "cc";
|
|||||||
import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
|
import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
|
||||||
import { CCComp } from "../../../../extensions/oops-plugin-framework/assets/module/common/CCComp";
|
import { CCComp } from "../../../../extensions/oops-plugin-framework/assets/module/common/CCComp";
|
||||||
import { mLogger } from "../common/Logger";
|
import { mLogger } from "../common/Logger";
|
||||||
import { CardPoolList, CardType, CardConfig } from "../common/config/CardSet";
|
import { CardConfig } from "../common/config/CardSet";
|
||||||
|
import { SkillCardList } from "../common/config/SCardSet";
|
||||||
import { TalentItemComp } from "./TalentItemComp";
|
import { TalentItemComp } from "./TalentItemComp";
|
||||||
|
|
||||||
const { ccclass, property } = _decorator;
|
const { ccclass, property } = _decorator;
|
||||||
@@ -51,7 +52,7 @@ export class TalentsComp extends CCComp {
|
|||||||
// 第一次:实例化所有子节点
|
// 第一次:实例化所有子节点
|
||||||
if (!this.rendered) {
|
if (!this.rendered) {
|
||||||
// 获取所有天赋(技能卡)并按 wave 和 uuid 排序
|
// 获取所有天赋(技能卡)并按 wave 和 uuid 排序
|
||||||
this.cachedConfigs = CardPoolList.filter(card => card.type === CardType.Skill)
|
this.cachedConfigs = [...SkillCardList]
|
||||||
.sort((a, b) => {
|
.sort((a, b) => {
|
||||||
const waveA = a.wave || 1;
|
const waveA = a.wave || 1;
|
||||||
const waveB = b.wave || 1;
|
const waveB = b.wave || 1;
|
||||||
@@ -73,7 +74,7 @@ export class TalentsComp extends CCComp {
|
|||||||
// 默认底高 1000,每行 3 个天赋信息卡,每张卡高 270,行间距 15
|
// 默认底高 1000,每行 3 个天赋信息卡,每张卡高 270,行间距 15
|
||||||
const totalCount = this.cachedConfigs.length;
|
const totalCount = this.cachedConfigs.length;
|
||||||
const rows = Math.ceil(totalCount / 3);
|
const rows = Math.ceil(totalCount / 3);
|
||||||
const contentHeight = Math.max(1000, rows * 270 + (rows > 0 ? (rows - 1) * 15 : 0+50));
|
const contentHeight = Math.max(1000, rows * 270 + (rows > 0 ? (rows - 1) * 15 : 0 + 50));
|
||||||
|
|
||||||
const uiTransform = this.talents_content.getComponent(UITransform);
|
const uiTransform = this.talents_content.getComponent(UITransform);
|
||||||
if (uiTransform) {
|
if (uiTransform) {
|
||||||
|
|||||||
Reference in New Issue
Block a user