refactor(skill-text): 重构技能文案系统,拆分英雄/卡牌语境

1.  将原HeroSkillDesc拆分为CardSkillText(卡牌/道具通用)和HeroSkillText(英雄专属)
2.  移除废弃的HeroSkillDesc文件与相关引用
3.  统一技能文案生成逻辑,修复数值漂移问题
4.  调整英雄配置中技能解锁等级与分档规则
5.  优化技能弹窗UI与参数传递逻辑
This commit is contained in:
panFD
2026-08-28 08:36:39 +08:00
parent 423653c4c8
commit 10a6d18836
17 changed files with 1698 additions and 1782 deletions

View File

@@ -5,14 +5,13 @@
* 职责:
* 1. 展示技能小图标(SSkillBoxComp)点击后的详细信息弹窗。
* 2. 展示技能名称、当前等级、图标、主功能说明。
* 3. 展示 2 级 / 3 级 激活状态(已激活显示"已激活",未激活显示"x级激活")
* 及相对上一档的能力提升说明。
* 3. 展示 1 级 / 2 级 / 3 级 激活状态(已激活显示"已激活",未激活显示"x级激活")。
* 4. 点击弹窗外部区域关闭。
*
* 使用(oops.gui 模块):
* oops.gui.open(UIID.SInfo, {
* uuid: 8701, // 卡牌/技能 UUID
* card_lv: 1, // 当前等级
* skill_lv: 1, // 当前等级
* card_icon: "xxx", // 图标ID(可选,缺省自动解析)
* skill_name: "战后恢复", // 名称(可选)
* field: [...], // 驻场词条(装备卡)
@@ -23,9 +22,10 @@
* 依赖:
* - oops.gui(UI 生命周期)—— open / removeByNode
* - SkillSet / FieldSkillSet(技能/光环静态配置)
* - SkillCardList / EquipPoolList(卡牌静态配置)
* - HeroSkillDesc(buildCardDescRich 富文本描述生成,卡牌模式)
* - HeroSkillText(buildHeroSkillTierLines 技能分档描述,英雄技能模式)
* - SkillCardList(卡牌静态配置)
* - CardSkillText(buildCardDescRich 富文本描述生成,卡牌模式)
* - HeroSkillText(buildHeroSkillTierLines 技能分档描述,英雄技能模式,
* 覆盖普攻/大招、触发技能、驻场光环词条与复活)
*/
import { _decorator, Node, Label, RichText, NodeEventType, Sprite, Color, input, Input, EventTouch, UITransform, Vec3 } from "cc";
import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
@@ -34,9 +34,8 @@ import { oops } from "db://oops-framework/core/Oops";
import { CardTriggerType, CardConfig } from "../common/config/CardSet";
import { SkillSet, FieldSkillSet } from "../common/config/SkillSet";
import { SkillCardList } from "../common/config/SCardSet";
import { EquipPoolList } from "../common/config/EquipSet";
import { FieldEntry } from "../common/config/heroSet";
import { buildCardDescRich } from "../common/config/HeroSkillDesc";
import { buildCardDescRich } from "../common/config/CardSkillText";
import { buildHeroSkillTierLines, HeroSkillTierLine } from "../common/HeroSkillText";
import { smc } from "../common/SingletonModuleComp";
@@ -47,7 +46,7 @@ export interface SInfoParams {
/** 卡牌/技能 UUID */
uuid: number;
/** 当前等级 */
card_lv: number;
skill_lv: number;
/** 图标ID(可选,优先级最高) */
card_icon?: string;
/** 技能名称(可选) */
@@ -68,8 +67,6 @@ interface LvUpgradeInfo {
lvText: string;
/** 激活状态文本("已激活" 或 "2级激活") */
statusText: string;
/** 能力提升富文本描述 */
desc: string;
}
@ccclass('SinfoComp')
@@ -93,6 +90,10 @@ export class SinfoComp extends CCComp {
@property({ type: RichText, displayName: "主功能说明" })
private main_info: RichText = null;
/** 1级激活状态标签 */
@property({ type: Label, displayName: "1级激活状态" })
private main_status: Label = null;
/** 2级激活状态标签 */
@property({ type: Label, displayName: "2级激活状态" })
private lv2_status: Label = null;
@@ -198,16 +199,16 @@ export class SinfoComp extends CCComp {
* - main_info:技能 slv1 完整描述
* - lv2_desc:slv2 相对 slv1 的提升;lv3_desc:slv3 及以后档(合并展示)
* - lv2/lv3_status:按英雄局外等级(smc.getHeroOuterLv)对比档位解锁等级判定激活
* @returns true 已渲染(拦截通用卡牌逻辑);false 技能无分档数据(光环/复活词条),回退通用逻辑
* @returns true 已渲染(拦截通用卡牌逻辑);false 技能无分档数据,回退通用卡牌逻辑
*/
private renderHeroSkill(p: SInfoParams): boolean {
const tiers = buildHeroSkillTierLines(p.hero_uuid!, p.uuid);
if (tiers.length === 0) return false;
// 图标 / 名称 / 当前技能等级与通用逻辑一致(card_lv 传的就是当前生效 s_lv)
// 图标 / 名称 / 当前技能等级与通用逻辑一致(skill_lv 传的就是当前生效 s_lv)
this.renderIcon(p);
this.setLabel(this.name_label, this.resolveName(p));
this.setLabel(this.lv_label, `Lv.${p.card_lv}`);
this.setLabel(this.lv_label, `Lv.${p.skill_lv}`);
// 技能 1 级:完整能力描述
if (this.main_info && this.main_info.isValid) {
@@ -217,6 +218,9 @@ export class SinfoComp extends CCComp {
// 英雄当前局外等级:激活判定基准
const heroLv = Math.max(1, smc.getHeroOuterLv(p.hero_uuid!));
// 技能 1 级:激活状态与 2/3 级面板同一表示方式(描述已在 main_info 展示,此处仅渲染状态)
this.renderLvPanelFromTier(tiers[0], heroLv, this.main_status, null);
// 技能 2 级 / 3 级(3 级以后档位合并进 3 级栏,多行展示)
const lv2 = tiers.find(t => t.sLv === 2);
const lv3Plus = tiers.filter(t => t.sLv >= 3);
@@ -259,14 +263,16 @@ export class SinfoComp extends CCComp {
this.setLabel(this.name_label, name);
// ---- 当前等级 ----
this.setLabel(this.lv_label, `Lv.${p.card_lv}`);
this.setLabel(this.lv_label, `Lv.${p.skill_lv}`);
// ---- 主功能说明 ----
this.renderMainInfo(p);
// ---- 2 级 / 3 级 激活信息 ----
// ---- 1 级 / 2 级 / 3 级 激活信息 ----
const lv1Info = this.buildLvUpgradeInfo(p, 1);
const lv2Info = this.buildLvUpgradeInfo(p, 2);
const lv3Info = this.buildLvUpgradeInfo(p, 3);
this.renderLvPanel(lv1Info, this.main_status, null);
this.renderLvPanel(lv2Info, this.lv2_status, this.lv2_desc);
this.renderLvPanel(lv3Info, this.lv3_status, this.lv3_desc);
}
@@ -287,9 +293,6 @@ export class SinfoComp extends CCComp {
/** 解析图标ID */
private resolveIconId(p: SInfoParams): string | undefined {
if (p.card_icon) return p.card_icon;
// 装备卡:从 EquipPoolList 查 icon
const equip = EquipPoolList.find(c => c.uuid === p.uuid);
if (equip?.icon) return equip.icon;
// 技能卡:从 SkillCardList 查 icon
const skillCard = SkillCardList.find(c => c.uuid === p.uuid || c.skill === p.uuid);
if (skillCard?.icon) return skillCard.icon;
@@ -300,14 +303,14 @@ export class SinfoComp extends CCComp {
}
// 技能底座:从 SkillSet 取
const skillUuid = skillCard?.skill ?? p.uuid;
return SkillSet[skillUuid]?.icon;
if (SkillSet[skillUuid]?.icon) return SkillSet[skillUuid]!.icon;
// 驻场光环词条:uuid 为 FieldSkillSet 词条(英雄图鉴光环弹窗)
return FieldSkillSet[p.uuid]?.icon;
}
/** 解析技能名称 */
private resolveName(p: SInfoParams): string {
if (p.skill_name) return p.skill_name;
const equip = EquipPoolList.find(c => c.uuid === p.uuid);
if (equip?.name) return equip.name;
const skillCard = SkillCardList.find(c => c.uuid === p.uuid || c.skill === p.uuid);
if (skillCard?.name) return skillCard.name;
if (p.trigger_type === CardTriggerType.Field && p.field?.length) {
@@ -315,7 +318,9 @@ export class SinfoComp extends CCComp {
return FieldSkillSet[fieldUuid]?.name ?? "";
}
const skillUuid = skillCard?.skill ?? p.uuid;
return SkillSet[skillUuid]?.name ?? "";
if (SkillSet[skillUuid]?.name) return SkillSet[skillUuid]!.name;
// 驻场光环词条:名称取 FieldSkillSet(英雄图鉴光环弹窗)
return FieldSkillSet[p.uuid]?.name ?? "";
}
/** 渲染主功能说明 */
@@ -334,10 +339,7 @@ export class SinfoComp extends CCComp {
/** 构建 CardConfig 供描述生成器使用 */
private buildCardConfig(p: SInfoParams): CardConfig | null {
// 优先从装备卡池查
const equip = EquipPoolList.find(c => c.uuid === p.uuid);
if (equip) return equip;
// 其次从技能卡池查
// 优先从技能卡池查
const skillCard = SkillCardList.find(c => c.uuid === p.uuid || c.skill === p.uuid);
if (skillCard) return skillCard;
// 手动构建
@@ -347,7 +349,6 @@ export class SinfoComp extends CCComp {
cost: 0,
weight: 0,
kind: 2, // CKind.Skill
card_lv: p.card_lv,
icon: p.card_icon,
name: p.skill_name,
field: p.field,
@@ -357,8 +358,6 @@ export class SinfoComp extends CCComp {
/** 解析主功能说明纯文本(兜底) */
private resolveInfoText(p: SInfoParams): string {
const equip = EquipPoolList.find(c => c.uuid === p.uuid);
if (equip?.info) return equip.info;
const skillCard = SkillCardList.find(c => c.uuid === p.uuid || c.skill === p.uuid);
if (skillCard?.info) return skillCard.info;
const skillUuid = skillCard?.skill ?? p.uuid;
@@ -367,40 +366,10 @@ export class SinfoComp extends CCComp {
/** 构建指定等级的提升信息 */
private buildLvUpgradeInfo(p: SInfoParams, targetLv: number): LvUpgradeInfo {
const unlocked = p.card_lv >= targetLv;
const unlocked = p.skill_lv >= targetLv;
const lvText = `Lv.${targetLv}`;
const statusText = unlocked ? "已激活" : `${targetLv}级激活`;
// 能力提升描述:从对应等级的装备卡配置中提取
const desc = this.buildLvDesc(p, targetLv);
return { unlocked, lvText, statusText, desc };
}
/** 构建指定等级的提升描述 */
private buildLvDesc(p: SInfoParams, targetLv: number): string {
// 从装备卡池中查找同名更高档位配置
const currentEquip = EquipPoolList.find(c => c.uuid === p.uuid);
if (currentEquip) {
const higher = EquipPoolList.find(c =>
c.name === currentEquip.name && c.card_lv === targetLv
);
if (higher) {
return buildCardDescRich(higher);
}
return "";
}
// 技能卡:从技能卡池查找同技能更高档位
const currentCard = SkillCardList.find(c => c.uuid === p.uuid || c.skill === p.uuid);
if (currentCard) {
const skillUuid = currentCard.skill ?? currentCard.uuid;
const higher = SkillCardList.find(c =>
(c.skill ?? c.uuid) === skillUuid && c.card_lv === targetLv
);
if (higher) {
return buildCardDescRich(higher);
}
}
return "";
return { unlocked, lvText, statusText };
}
/** 渲染单个等级面板 */
@@ -413,7 +382,7 @@ export class SinfoComp extends CCComp {
: new Color(150, 150, 150, 255);
}
if (descRich && descRich.isValid) {
descRich.string = info.desc || (info.unlocked ? "" : "未解锁");
descRich.string = info.unlocked ? "" : "未解锁";
}
}