feat(hero skill): add slot support for hero skill detail panel
1. 新增技能槽位参数,解决同底座技能(如普攻+触发技能)的分档定位问题 2. 新增2级/3级面板节点配置,自动隐藏无对应档位的面板 3. 重构英雄技能档位生成逻辑,支持按槽位精确查找技能配置 4. 优化技能弹窗渲染逻辑,传递槽位参数避免匹配错误分组
This commit is contained in:
@@ -2293,12 +2293,18 @@
|
|||||||
"main_status": {
|
"main_status": {
|
||||||
"__id__": 67
|
"__id__": 67
|
||||||
},
|
},
|
||||||
|
"lv2_node": {
|
||||||
|
"__id__": 85
|
||||||
|
},
|
||||||
"lv2_status": {
|
"lv2_status": {
|
||||||
"__id__": 175
|
"__id__": 175
|
||||||
},
|
},
|
||||||
"lv2_desc": {
|
"lv2_desc": {
|
||||||
"__id__": 191
|
"__id__": 191
|
||||||
},
|
},
|
||||||
|
"lv3_node": {
|
||||||
|
"__id__": 110
|
||||||
|
},
|
||||||
"lv3_status": {
|
"lv3_status": {
|
||||||
"__id__": 203
|
"__id__": 203
|
||||||
},
|
},
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
Before Width: | Height: | Size: 994 KiB After Width: | Height: | Size: 1009 KiB |
@@ -433,71 +433,34 @@ export interface HeroSkillTierLine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 输出二(结构化):指定技能各等级档位说明,按技能等级升序。
|
* 收集指定触发槽位的触发技能档位与触发语境词;未命中(组不存在/无该 s_uuid/无底座)返回 null。
|
||||||
*
|
|
||||||
* slv1 给完整能力 + 数值;slv2+ 给相对上一级的提升。每档附带解锁英雄等级,
|
|
||||||
* 调用方可自行对比英雄当前等级(smc.getHeroOuterLv)判定激活状态。
|
|
||||||
*
|
|
||||||
* 技能定位顺序(覆盖英雄图鉴全部 5 类技能形态):
|
|
||||||
* 1. hero.skills[skillUuid] —— 普攻/大招
|
|
||||||
* 2. 5 类触发技能组 —— call/dead/fstart/atking/atked
|
|
||||||
* 3. hero.field —— 驻场光环词条(FieldSkillSet uuid)
|
|
||||||
* 4. hero.revive —— 复活技能(SkillSet uuid)
|
|
||||||
* 均未命中返回 []。
|
|
||||||
*
|
|
||||||
* Why: 同一底座技能可能被多个英雄以不同 overrides 引用,必须以英雄语境取档。
|
|
||||||
*
|
|
||||||
* @param heroUuid 英雄 uuid(HeroInfo key)
|
|
||||||
* @param skillUuid 技能 uuid(skills key / 触发组 s_uuid / FieldSkillSet uuid / 复活 SkillSet uuid)
|
|
||||||
* @returns 档位行数组;技能不属于该英雄时返回 []
|
|
||||||
*/
|
*/
|
||||||
export function buildHeroSkillTierLines(heroUuid: number, skillUuid: number): HeroSkillTierLine[] {
|
function collectTriggerTiers(hero: heroInfo, type: SkillTriggerType, skillUuid: number): { tiers: ISkillTierInfo[]; label: string } | null {
|
||||||
const hero = HeroInfo[heroUuid];
|
const grouped = hero[type] as TriggerGrouped | undefined;
|
||||||
if (!hero) return [];
|
const entries = grouped?.[skillUuid];
|
||||||
|
if (!grouped || !entries?.length) return null;
|
||||||
let tiers: ISkillTierInfo[] = [];
|
const base = SkillSet[skillUuid];
|
||||||
let triggerLabel = "";
|
if (!base) return null;
|
||||||
|
const sorted = [...entries].sort((a, b) => (a.s_lv ?? 0) - (b.s_lv ?? 0));
|
||||||
const hSkill = hero.skills?.[skillUuid];
|
let inherit: string | undefined;
|
||||||
if (hSkill) {
|
const tiers = sorted.map((e: LvTriggerEntry, i: number) => {
|
||||||
// 普攻/大招路径
|
if (e.desc) inherit = e.desc;
|
||||||
tiers = collectSkillTiers(hSkill);
|
return {
|
||||||
} else {
|
sLv: e.s_lv ?? (i + 1),
|
||||||
// 触发技能路径:在 5 类触发组中定位 s_uuid
|
heroLv: e.lv,
|
||||||
for (const type of TRIGGER_KEYS) {
|
skill: mergeSkillParams(base, e.overrides),
|
||||||
const grouped = hero[type] as TriggerGrouped | undefined;
|
desc: e.desc ?? inherit,
|
||||||
const entries = grouped?.[skillUuid];
|
tNum: e.t_num,
|
||||||
if (!grouped || !entries?.length) continue;
|
};
|
||||||
const base = SkillSet[skillUuid];
|
});
|
||||||
if (!base) return [];
|
const label = (type === SkillTriggerType.Atking || type === SkillTriggerType.Atked)
|
||||||
const sorted = [...entries].sort((a, b) => (a.s_lv ?? 0) - (b.s_lv ?? 0));
|
? `${SkillTriggerName[type]}${valueRich(sorted[0].t_num)}次`
|
||||||
let inherit: string | undefined;
|
: SkillTriggerName[type];
|
||||||
tiers = sorted.map((e: LvTriggerEntry, i: number) => {
|
return { tiers, label };
|
||||||
if (e.desc) inherit = e.desc;
|
}
|
||||||
return {
|
|
||||||
sLv: e.s_lv ?? (i + 1),
|
|
||||||
heroLv: e.lv,
|
|
||||||
skill: mergeSkillParams(base, e.overrides),
|
|
||||||
desc: e.desc ?? inherit,
|
|
||||||
tNum: e.t_num,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
triggerLabel = (type === SkillTriggerType.Atking || type === SkillTriggerType.Atked)
|
|
||||||
? `${SkillTriggerName[type]}${valueRich(sorted[0].t_num)}次`
|
|
||||||
: SkillTriggerName[type];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 光环/复活路径(无 ISkillTierInfo 中间结构,直接生成 HeroSkillTierLine)
|
|
||||||
if (tiers.length === 0) {
|
|
||||||
const fieldLines = collectFieldTierLines(hero, skillUuid);
|
|
||||||
if (fieldLines.length > 0) return fieldLines;
|
|
||||||
const reviveLines = collectReviveTierLines(hero, skillUuid);
|
|
||||||
if (reviveLines.length > 0) return reviveLines;
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/** 档位 → 展示行:slv1 完整能力 + 数值;slv2+ 相对上一级的提升 */
|
||||||
|
function buildTierLines(tiers: ISkillTierInfo[], triggerLabel: string): HeroSkillTierLine[] {
|
||||||
const lines: HeroSkillTierLine[] = [];
|
const lines: HeroSkillTierLine[] = [];
|
||||||
for (let i = 0; i < tiers.length; i++) {
|
for (let i = 0; i < tiers.length; i++) {
|
||||||
const t = tiers[i];
|
const t = tiers[i];
|
||||||
@@ -514,6 +477,71 @@ export function buildHeroSkillTierLines(heroUuid: number, skillUuid: number): He
|
|||||||
return lines;
|
return lines;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 输出二(结构化):指定技能各等级档位说明,按技能等级升序。
|
||||||
|
*
|
||||||
|
* slv1 给完整能力 + 数值;slv2+ 给相对上一级的提升。每档附带解锁英雄等级,
|
||||||
|
* 调用方可自行对比英雄当前等级(smc.getHeroOuterLv)判定激活状态。
|
||||||
|
*
|
||||||
|
* 技能定位顺序(覆盖英雄图鉴全部 5 类技能形态):
|
||||||
|
* 1. hero.skills[skillUuid] —— 普攻/大招
|
||||||
|
* 2. 5 类触发技能组 —— call/dead/fstart/atking/atked
|
||||||
|
* 3. hero.field —— 驻场光环词条(FieldSkillSet uuid)
|
||||||
|
* 4. hero.revive —— 复活技能(SkillSet uuid)
|
||||||
|
* 均未命中返回 []。
|
||||||
|
*
|
||||||
|
* Why: 同一底座技能可能被多个英雄以不同 overrides 引用,必须以英雄语境取档;
|
||||||
|
* 同一底座还可能同时是普攻与触发技能(如 5002 的 6004),传 slot 指定槽位
|
||||||
|
* 可避免自动定位命中错误分组(激活等级/档位随之错位)。
|
||||||
|
*
|
||||||
|
* @param heroUuid 英雄 uuid(HeroInfo key)
|
||||||
|
* @param skillUuid 技能 uuid(skills key / 触发组 s_uuid / FieldSkillSet uuid / 复活 SkillSet uuid)
|
||||||
|
* @param slot 技能所属槽位(可空):指定时仅在该槽位查找;缺省按上述顺序自动定位
|
||||||
|
* @returns 档位行数组;技能不属于该英雄时返回 []
|
||||||
|
*/
|
||||||
|
export function buildHeroSkillTierLines(heroUuid: number, skillUuid: number, slot?: SkillTriggerType): HeroSkillTierLine[] {
|
||||||
|
const hero = HeroInfo[heroUuid];
|
||||||
|
if (!hero) return [];
|
||||||
|
|
||||||
|
// 槽位指定:光环/复活结构特殊直接生成行;触发组走统一档位结构
|
||||||
|
if (slot === SkillTriggerType.Field) return collectFieldTierLines(hero, skillUuid);
|
||||||
|
if (slot === SkillTriggerType.Revive) return collectReviveTierLines(hero, skillUuid);
|
||||||
|
if (slot !== undefined) {
|
||||||
|
const hit = collectTriggerTiers(hero, slot, skillUuid);
|
||||||
|
return hit ? buildTierLines(hit.tiers, hit.label) : [];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 自动定位:普攻/大招优先,其次 5 类触发组,最后光环/复活
|
||||||
|
let tiers: ISkillTierInfo[] = [];
|
||||||
|
let triggerLabel = "";
|
||||||
|
const hSkill = hero.skills?.[skillUuid];
|
||||||
|
if (hSkill) {
|
||||||
|
// 普攻/大招路径
|
||||||
|
tiers = collectSkillTiers(hSkill);
|
||||||
|
} else {
|
||||||
|
// 触发技能路径:在 5 类触发组中定位 s_uuid
|
||||||
|
for (const type of TRIGGER_KEYS) {
|
||||||
|
const hit = collectTriggerTiers(hero, type, skillUuid);
|
||||||
|
if (hit) {
|
||||||
|
tiers = hit.tiers;
|
||||||
|
triggerLabel = hit.label;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 光环/复活路径(无 ISkillTierInfo 中间结构,直接生成 HeroSkillTierLine)
|
||||||
|
if (tiers.length === 0) {
|
||||||
|
const fieldLines = collectFieldTierLines(hero, skillUuid);
|
||||||
|
if (fieldLines.length > 0) return fieldLines;
|
||||||
|
const reviveLines = collectReviveTierLines(hero, skillUuid);
|
||||||
|
if (reviveLines.length > 0) return reviveLines;
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
return buildTierLines(tiers, triggerLabel);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 输出二:指定技能的各阶段说明(富文本整段)。
|
* 输出二:指定技能的各阶段说明(富文本整段)。
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { v3 } from "cc"
|
import { v3 } from "cc"
|
||||||
import { BoxSet, FacSet, FightSet } from "./GameSet"
|
import { BoxSet, FacSet, FightSet } from "./GameSet"
|
||||||
import { SkillOverrides, TGroup, SkillSet, FieldSkillSet, SkillConfig, SkillKind, FieldSkillConfig, FieldSkillType, mergeSkillParams } from "./SkillSet"
|
import { SkillOverrides, TGroup, SkillSet, FieldSkillSet, SkillConfig, SkillKind, FieldSkillConfig, FieldSkillType, mergeSkillParams } from "./SkillSet"
|
||||||
import { BuffList, BuffConfig, ModOp } from "./BuffSet"
|
import { BuffList, BuffConfig, ModOp } from "./BuffSet"
|
||||||
|
|||||||
@@ -533,7 +533,7 @@ export class HerosListComp extends CCComp {
|
|||||||
} else if (type === SkillTriggerType.Revive) {
|
} else if (type === SkillTriggerType.Revive) {
|
||||||
this.addReviveIcon(hero[SkillTriggerType.Revive], lv)
|
this.addReviveIcon(hero[SkillTriggerType.Revive], lv)
|
||||||
} else {
|
} else {
|
||||||
this.addTriggerIcons(hero[type] as TriggerGrouped | undefined, lv)
|
this.addTriggerIcons(hero[type] as TriggerGrouped | undefined, lv, type)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -544,21 +544,24 @@ export class HerosListComp extends CCComp {
|
|||||||
* @param s_lv 当前等级对应的技能等级(locked 时为解锁预览档)
|
* @param s_lv 当前等级对应的技能等级(locked 时为解锁预览档)
|
||||||
* @param locked 当前等级未激活 → 显示锁定遮罩
|
* @param locked 当前等级未激活 → 显示锁定遮罩
|
||||||
* @param isField true 表示驻场光环词条(图标取 FieldSkillSet)
|
* @param isField true 表示驻场光环词条(图标取 FieldSkillSet)
|
||||||
|
* @param slot 技能所属槽位(普攻/大招传 undefined;触发/光环/复活传对应类型,
|
||||||
|
* 同一底座不同槽位视为不同技能,弹窗按槽位精确取档)
|
||||||
*/
|
*/
|
||||||
private addSkillIcon(s_uuid: number, s_lv: number, locked: boolean, isField: boolean) {
|
private addSkillIcon(s_uuid: number, s_lv: number, locked: boolean, isField: boolean, slot?: SkillTriggerType) {
|
||||||
const node = instantiate(this.skill_icon_prefab)
|
const node = instantiate(this.skill_icon_prefab)
|
||||||
node.name = `skill_${s_uuid}`
|
node.name = `skill_${s_uuid}`
|
||||||
const comp = node.getComponent(SSkillBoxComp) || node.addComponent(SSkillBoxComp)
|
const comp = node.getComponent(SSkillBoxComp) || node.addComponent(SSkillBoxComp)
|
||||||
// 携带所属英雄,点击弹窗按英雄技能分档描述渲染
|
// 携带所属英雄与槽位,点击弹窗按英雄技能分档描述渲染
|
||||||
comp.initHeroSkill(s_uuid, s_lv, locked, isField, this.huuid)
|
comp.initHeroSkill(s_uuid, s_lv, locked, isField, this.huuid, slot)
|
||||||
this.skills_node.addChild(node)
|
this.skills_node.addChild(node)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 触发技能(dead/fstart/atking/atked):按 s_uuid 分组,取 ≤lv 最大档判定激活;
|
* 触发技能(dead/fstart/atking/atked):按 s_uuid 分组,取 ≤lv 最大档判定激活;
|
||||||
* 未激活时预览最低档(与 resolveTriggerByLv 同语义)
|
* 未激活时预览最低档(与 resolveTriggerByLv 同语义)
|
||||||
|
* @param type 触发槽位(随图标透传,区分与普攻同底座的触发技能)
|
||||||
*/
|
*/
|
||||||
private addTriggerIcons(grouped: TriggerGrouped | undefined, lv: number) {
|
private addTriggerIcons(grouped: TriggerGrouped | undefined, lv: number, type: SkillTriggerType) {
|
||||||
if (!grouped) return
|
if (!grouped) return
|
||||||
for (const key in grouped) {
|
for (const key in grouped) {
|
||||||
const entries = grouped[key]
|
const entries = grouped[key]
|
||||||
@@ -567,7 +570,7 @@ export class HerosListComp extends CCComp {
|
|||||||
let active: LvTriggerEntry | undefined
|
let active: LvTriggerEntry | undefined
|
||||||
for (const e of sorted) { if (e.lv <= lv) active = e }
|
for (const e of sorted) { if (e.lv <= lv) active = e }
|
||||||
const pick = active ?? sorted[0]
|
const pick = active ?? sorted[0]
|
||||||
this.addSkillIcon(Number(key), pick.s_lv ?? 1, !active, false)
|
this.addSkillIcon(Number(key), pick.s_lv ?? 1, !active, false, type)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -580,7 +583,7 @@ export class HerosListComp extends CCComp {
|
|||||||
const pick = active ?? sorted[0]
|
const pick = active ?? sorted[0]
|
||||||
for (const entry of pick.uuids) {
|
for (const entry of pick.uuids) {
|
||||||
// 词条档位无 s_lv 概念,技能等级恒为 1(等级标签展示技能等级而非解锁的英雄等级)
|
// 词条档位无 s_lv 概念,技能等级恒为 1(等级标签展示技能等级而非解锁的英雄等级)
|
||||||
this.addSkillIcon(entry.uuid, 1, !active, true)
|
this.addSkillIcon(entry.uuid, 1, !active, true, SkillTriggerType.Field)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -592,7 +595,7 @@ export class HerosListComp extends CCComp {
|
|||||||
for (const e of sorted) { if (e.lv <= lv) active = e }
|
for (const e of sorted) { if (e.lv <= lv) active = e }
|
||||||
const pick = active ?? sorted[0]
|
const pick = active ?? sorted[0]
|
||||||
// 复活档位无 s_lv 概念,技能等级恒为 1(等级标签展示技能等级而非解锁的英雄等级)
|
// 复活档位无 s_lv 概念,技能等级恒为 1(等级标签展示技能等级而非解锁的英雄等级)
|
||||||
this.addSkillIcon(pick.s_uuid, 1, !active, false)
|
this.addSkillIcon(pick.s_uuid, 1, !active, false, SkillTriggerType.Revive)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ======================== 英雄动画 ========================
|
// ======================== 英雄动画 ========================
|
||||||
|
|||||||
@@ -46,6 +46,9 @@ export class SSkillBoxComp extends CCComp {
|
|||||||
private s_uuid: number = 0;
|
private s_uuid: number = 0;
|
||||||
/** 所属英雄 UUID(英雄图鉴模式,>0 时点击弹窗走英雄技能分档描述) */
|
/** 所属英雄 UUID(英雄图鉴模式,>0 时点击弹窗走英雄技能分档描述) */
|
||||||
private hero_uuid: number = 0;
|
private hero_uuid: number = 0;
|
||||||
|
/** 技能所属槽位(英雄图鉴模式):同一底座可同时为普攻与触发技能(如 5002 的 6004),
|
||||||
|
* 弹窗按槽位精确取档,避免自动定位命中错误分组 */
|
||||||
|
private hero_slot?: SkillTriggerType;
|
||||||
/** 卡牌等级 */
|
/** 卡牌等级 */
|
||||||
private card_lv: number = 1;
|
private card_lv: number = 1;
|
||||||
/** 卡牌自定义图标ID(优先级最高,未定义则按 trigger_type 自动取) */
|
/** 卡牌自定义图标ID(优先级最高,未定义则按 trigger_type 自动取) */
|
||||||
@@ -83,6 +86,8 @@ export class SSkillBoxComp extends CCComp {
|
|||||||
trigger_type: this.trigger_type,
|
trigger_type: this.trigger_type,
|
||||||
// 英雄图鉴模式:携带所属英雄,弹窗按英雄技能分档描述渲染
|
// 英雄图鉴模式:携带所属英雄,弹窗按英雄技能分档描述渲染
|
||||||
hero_uuid: this.hero_uuid || undefined,
|
hero_uuid: this.hero_uuid || undefined,
|
||||||
|
// 槽位:同一底座不同槽位视为不同技能(激活等级/档位各自独立)
|
||||||
|
hero_slot: this.hero_uuid ? this.hero_slot : undefined,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,10 +110,12 @@ export class SSkillBoxComp extends CCComp {
|
|||||||
* @param locked 当前等级未激活时显示锁定遮罩
|
* @param locked 当前等级未激活时显示锁定遮罩
|
||||||
* @param isField true 时图标取 FieldSkillSet(驻场光环词条)
|
* @param isField true 时图标取 FieldSkillSet(驻场光环词条)
|
||||||
* @param heroUuid 所属英雄 UUID(点击弹窗按英雄技能分档描述渲染)
|
* @param heroUuid 所属英雄 UUID(点击弹窗按英雄技能分档描述渲染)
|
||||||
|
* @param slot 技能所属槽位(普攻/大招传 undefined;触发/光环/复活传对应类型)
|
||||||
*/
|
*/
|
||||||
initHeroSkill(s_uuid: number, s_lv: number, locked: boolean, isField: boolean = false, heroUuid: number = 0) {
|
initHeroSkill(s_uuid: number, s_lv: number, locked: boolean, isField: boolean = false, heroUuid: number = 0, slot?: SkillTriggerType) {
|
||||||
this.s_uuid = s_uuid;
|
this.s_uuid = s_uuid;
|
||||||
this.hero_uuid = heroUuid;
|
this.hero_uuid = heroUuid;
|
||||||
|
this.hero_slot = slot;
|
||||||
this.card_lv = s_lv;
|
this.card_lv = s_lv;
|
||||||
this.hero_icon_source = isField ? "field" : "skill";
|
this.hero_icon_source = isField ? "field" : "skill";
|
||||||
this.updateUI();
|
this.updateUI();
|
||||||
@@ -182,11 +189,24 @@ export class SSkillBoxComp extends CCComp {
|
|||||||
/**
|
/**
|
||||||
* 英雄图鉴模式:按技能 uuid 在英雄配置中定位,取英雄语境展示名。
|
* 英雄图鉴模式:按技能 uuid 在英雄配置中定位,取英雄语境展示名。
|
||||||
* 覆盖普攻/大招(skills)、5 类触发技能、驻场光环(field)、复活(revive)。
|
* 覆盖普攻/大招(skills)、5 类触发技能、驻场光环(field)、复活(revive)。
|
||||||
|
* 指定槽位时仅在对应槽位查找(同一底座可同时是普攻与触发技能,需精确区分);
|
||||||
* 未命中返回空串,由调用方回退底座名。
|
* 未命中返回空串,由调用方回退底座名。
|
||||||
*/
|
*/
|
||||||
private resolveHeroSkillName(): string {
|
private resolveHeroSkillName(): string {
|
||||||
const hero = HeroInfo[this.hero_uuid];
|
const hero = HeroInfo[this.hero_uuid];
|
||||||
if (!hero) return "";
|
if (!hero) return "";
|
||||||
|
// 槽位指定:光环/复活/触发组各自取值,未命中直接回退
|
||||||
|
if (this.hero_slot !== undefined) {
|
||||||
|
if (this.hero_slot === SkillTriggerType.Field) {
|
||||||
|
return getFieldSkillName(hero, this.s_uuid);
|
||||||
|
}
|
||||||
|
if (this.hero_slot === SkillTriggerType.Revive) {
|
||||||
|
return getReviveSkillName(hero, this.s_uuid);
|
||||||
|
}
|
||||||
|
const grouped = hero[this.hero_slot] as TriggerGrouped | undefined;
|
||||||
|
if (grouped?.[this.s_uuid]?.length) return getGroupedTriggerName(grouped, this.s_uuid);
|
||||||
|
return "";
|
||||||
|
}
|
||||||
// 普攻/大招
|
// 普攻/大招
|
||||||
const hSkill = hero.skills?.[this.s_uuid];
|
const hSkill = hero.skills?.[this.s_uuid];
|
||||||
if (hSkill?.name) return hSkill.name;
|
if (hSkill?.name) return hSkill.name;
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ import { oops } from "db://oops-framework/core/Oops";
|
|||||||
import { CardTriggerType, CardConfig } from "../common/config/CardSet";
|
import { CardTriggerType, CardConfig } from "../common/config/CardSet";
|
||||||
import { SkillSet, FieldSkillSet } from "../common/config/SkillSet";
|
import { SkillSet, FieldSkillSet } from "../common/config/SkillSet";
|
||||||
import { SkillCardList } from "../common/config/SCardSet";
|
import { SkillCardList } from "../common/config/SCardSet";
|
||||||
import { FieldEntry } from "../common/config/heroSet";
|
import { FieldEntry, SkillTriggerType } from "../common/config/heroSet";
|
||||||
import { buildCardDescRich } from "../common/config/CardSkillText";
|
import { buildCardDescRich } from "../common/config/CardSkillText";
|
||||||
import { buildHeroSkillTierLines, HeroSkillTierLine } from "../common/HeroSkillText";
|
import { buildHeroSkillTierLines, HeroSkillTierLine } from "../common/HeroSkillText";
|
||||||
import { smc } from "../common/SingletonModuleComp";
|
import { smc } from "../common/SingletonModuleComp";
|
||||||
@@ -57,6 +57,9 @@ export interface SInfoParams {
|
|||||||
trigger_type?: CardTriggerType;
|
trigger_type?: CardTriggerType;
|
||||||
/** 所属英雄 UUID(英雄图鉴模式:按英雄技能分档描述渲染,优先级高于卡牌逻辑) */
|
/** 所属英雄 UUID(英雄图鉴模式:按英雄技能分档描述渲染,优先级高于卡牌逻辑) */
|
||||||
hero_uuid?: number;
|
hero_uuid?: number;
|
||||||
|
/** 技能所属槽位(英雄图鉴模式):同一底座可同时为普攻与触发技能(如 5002 的 6004),
|
||||||
|
* 指定后仅在该槽位取档,激活等级/档位按槽位独立判定 */
|
||||||
|
hero_slot?: SkillTriggerType;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 等级提升信息(用于 2 级 / 3 级面板) */
|
/** 等级提升信息(用于 2 级 / 3 级面板) */
|
||||||
@@ -94,6 +97,10 @@ export class SinfoComp extends CCComp {
|
|||||||
@property({ type: Label, displayName: "1级激活状态" })
|
@property({ type: Label, displayName: "1级激活状态" })
|
||||||
private main_status: Label = null;
|
private main_status: Label = null;
|
||||||
|
|
||||||
|
/** 2级面板节点(无 2 级档位的技能隐藏) */
|
||||||
|
@property({ type: Node, displayName: "2级面板" })
|
||||||
|
private lv2_node: Node = null;
|
||||||
|
|
||||||
/** 2级激活状态标签 */
|
/** 2级激活状态标签 */
|
||||||
@property({ type: Label, displayName: "2级激活状态" })
|
@property({ type: Label, displayName: "2级激活状态" })
|
||||||
private lv2_status: Label = null;
|
private lv2_status: Label = null;
|
||||||
@@ -102,6 +109,10 @@ export class SinfoComp extends CCComp {
|
|||||||
@property({ type: RichText, displayName: "2级提升说明" })
|
@property({ type: RichText, displayName: "2级提升说明" })
|
||||||
private lv2_desc: RichText = null;
|
private lv2_desc: RichText = null;
|
||||||
|
|
||||||
|
/** 3级面板节点(无 3 级及以上档位的技能隐藏) */
|
||||||
|
@property({ type: Node, displayName: "3级面板" })
|
||||||
|
private lv3_node: Node = null;
|
||||||
|
|
||||||
/** 3级激活状态标签 */
|
/** 3级激活状态标签 */
|
||||||
@property({ type: Label, displayName: "3级激活状态" })
|
@property({ type: Label, displayName: "3级激活状态" })
|
||||||
private lv3_status: Label = null;
|
private lv3_status: Label = null;
|
||||||
@@ -215,7 +226,7 @@ export class SinfoComp extends CCComp {
|
|||||||
* @returns true 已渲染(拦截通用卡牌逻辑);false 技能无分档数据,回退通用卡牌逻辑
|
* @returns true 已渲染(拦截通用卡牌逻辑);false 技能无分档数据,回退通用卡牌逻辑
|
||||||
*/
|
*/
|
||||||
private renderHeroSkill(p: SInfoParams): boolean {
|
private renderHeroSkill(p: SInfoParams): boolean {
|
||||||
const tiers = buildHeroSkillTierLines(p.hero_uuid!, p.uuid);
|
const tiers = buildHeroSkillTierLines(p.hero_uuid!, p.uuid, p.hero_slot);
|
||||||
if (tiers.length === 0) return false;
|
if (tiers.length === 0) return false;
|
||||||
|
|
||||||
// 图标 / 名称 / 当前技能等级与通用逻辑一致(skill_lv 传的就是当前生效 s_lv)
|
// 图标 / 名称 / 当前技能等级与通用逻辑一致(skill_lv 传的就是当前生效 s_lv)
|
||||||
@@ -237,6 +248,9 @@ export class SinfoComp extends CCComp {
|
|||||||
// 技能 2 级 / 3 级(3 级以后档位合并进 3 级栏,多行展示)
|
// 技能 2 级 / 3 级(3 级以后档位合并进 3 级栏,多行展示)
|
||||||
const lv2 = tiers.find(t => t.sLv === 2);
|
const lv2 = tiers.find(t => t.sLv === 2);
|
||||||
const lv3Plus = tiers.filter(t => t.sLv >= 3);
|
const lv3Plus = tiers.filter(t => t.sLv >= 3);
|
||||||
|
// 无对应档位的技能隐藏 2 级 / 3 级面板节点
|
||||||
|
this.setPanelActive(this.lv2_node, !!lv2);
|
||||||
|
this.setPanelActive(this.lv3_node, lv3Plus.length > 0);
|
||||||
this.renderLvPanelFromTier(lv2, heroLv, this.lv2_status, this.lv2_desc);
|
this.renderLvPanelFromTier(lv2, heroLv, this.lv2_status, this.lv2_desc);
|
||||||
const lv3Merged = lv3Plus.length
|
const lv3Merged = lv3Plus.length
|
||||||
? { sLv: lv3Plus[0].sLv, heroLv: lv3Plus[0].heroLv, text: lv3Plus.map(t => t.text).join("\n") }
|
? { sLv: lv3Plus[0].sLv, heroLv: lv3Plus[0].heroLv, text: lv3Plus.map(t => t.text).join("\n") }
|
||||||
@@ -245,6 +259,13 @@ export class SinfoComp extends CCComp {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 设置等级面板节点显隐(无对应档位时隐藏) */
|
||||||
|
private setPanelActive(node: Node | null, active: boolean) {
|
||||||
|
if (node && node.isValid) {
|
||||||
|
node.active = active;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** 按档位渲染单等级面板:激活状态按英雄等级对比档位解锁等级 */
|
/** 按档位渲染单等级面板:激活状态按英雄等级对比档位解锁等级 */
|
||||||
private renderLvPanelFromTier(tier: HeroSkillTierLine | undefined, heroLv: number, statusLabel: Label | null, descRich: RichText | null) {
|
private renderLvPanelFromTier(tier: HeroSkillTierLine | undefined, heroLv: number, statusLabel: Label | null, descRich: RichText | null) {
|
||||||
if (statusLabel && statusLabel.isValid) {
|
if (statusLabel && statusLabel.isValid) {
|
||||||
|
|||||||
Reference in New Issue
Block a user