feat(map,hero): 实现英雄技能整组合并展示功能
重构英雄技能展示逻辑,支持将同一触发槽位的多个技能/光环词条合并为一个技能展示: 1. 新增触发组整组分档渲染接口,合并同槽位多技能档位数据 2. 新增组名获取函数,统一使用槽位首个自定义名称作为展示名 3. 调整图鉴面板技能列表,每个触发槽位仅展示一个合并后的图标 4. 升级技能弹窗渲染逻辑,支持整组模式下的合并说明展示 5. 优化注释与代码结构,统一技能展示口径
This commit is contained in:
@@ -486,19 +486,21 @@ export class HerosListComp extends CCComp {
|
||||
|
||||
// ======================== 技能图标列表 ========================
|
||||
|
||||
/** 图鉴面板展示的触发技能类型(heroInfo 触发配置:死亡/战斗开始/光环/攻击后/受击) */
|
||||
/** 图鉴面板展示的触发技能槽位(按触发时机排序:召唤→战斗开始→攻击后→受击后→死亡→常驻光环) */
|
||||
private static readonly PANEL_TRIGGER_TYPES: SkillTriggerType[] = [
|
||||
SkillTriggerType.Dead,
|
||||
SkillTriggerType.Call,
|
||||
SkillTriggerType.FStart,
|
||||
SkillTriggerType.Field,
|
||||
SkillTriggerType.Atking,
|
||||
SkillTriggerType.Atked,
|
||||
SkillTriggerType.Dead,
|
||||
SkillTriggerType.Field,
|
||||
]
|
||||
|
||||
/**
|
||||
* 刷新当前英雄的技能图标列表:
|
||||
* 1. 大招:skills[1] 及以后(首个为普攻,跳过)。
|
||||
* 2. 触发技能:Dead/FStart/Field/Atking/Atked(复活已纳入 dead)。
|
||||
* 2. 触发技能:每个触发槽位(Call/FStart/Atking/Atked/Dead/Field)整组视为一个技能,
|
||||
* 只出一个图标,组内多技能/词条合并展示(复活已纳入 dead)。
|
||||
* 以局外等级(getHeroOuterLv)为当前等级,未达解锁档的显示 locked,
|
||||
* 已激活的显示当前等级对应的技能等级。
|
||||
*/
|
||||
@@ -522,63 +524,76 @@ export class HerosListComp extends CCComp {
|
||||
this.addSkillIcon(hSkill.uuid, sLv, false, false)
|
||||
})
|
||||
|
||||
// ---- 触发技能:按 PANEL_TRIGGER_TYPES 顺序追加 ----
|
||||
// ---- 触发技能:每个触发槽位整组一个图标,按 PANEL_TRIGGER_TYPES 顺序追加 ----
|
||||
for (const type of HerosListComp.PANEL_TRIGGER_TYPES) {
|
||||
if (type === SkillTriggerType.Field) {
|
||||
this.addFieldIcons(hero[SkillTriggerType.Field], lv)
|
||||
this.addFieldGroupIcon(hero[SkillTriggerType.Field], lv)
|
||||
} else {
|
||||
this.addTriggerIcons(hero[type] as TriggerGrouped | undefined, lv, type)
|
||||
this.addTriggerGroupIcon(hero[type] as TriggerGrouped | undefined, lv, type)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 实例化技能小图标并初始化
|
||||
* @param s_uuid 技能 UUID(SkillSet 或 FieldSkillSet)
|
||||
* @param s_lv 当前等级对应的技能等级(locked 时为解锁预览档)
|
||||
* @param locked 当前等级未激活 → 显示锁定遮罩
|
||||
* @param isField true 表示驻场光环词条(图标取 FieldSkillSet)
|
||||
* @param slot 技能所属槽位(普攻/大招传 undefined;触发/光环传对应类型,
|
||||
* 同一底座不同槽位视为不同技能,弹窗按槽位精确取档;复活已纳入 dead)
|
||||
* @param s_uuid 技能 UUID(SkillSet 或 FieldSkillSet;整组模式下取组内首个,仅用于图标)
|
||||
* @param s_lv 当前等级对应的技能等级(locked 时为解锁预览档)
|
||||
* @param locked 当前等级未激活 → 显示锁定遮罩
|
||||
* @param isField true 表示驻场光环词条(图标取 FieldSkillSet)
|
||||
* @param slot 技能所属槽位(普攻/大招传 undefined;触发/光环传对应类型,
|
||||
* 同一底座不同槽位视为不同技能,弹窗按槽位取档;复活已纳入 dead)
|
||||
* @param isGroup 整组模式:该图标代表整个触发槽位,组名取组内首个自定义名,
|
||||
* 弹窗按整组合并渲染(组内多技能/词条统一说明)
|
||||
*/
|
||||
private addSkillIcon(s_uuid: number, s_lv: number, locked: boolean, isField: boolean, slot?: SkillTriggerType) {
|
||||
private addSkillIcon(s_uuid: number, s_lv: number, locked: boolean, isField: boolean, slot?: SkillTriggerType, isGroup: boolean = false) {
|
||||
const node = instantiate(this.skill_icon_prefab)
|
||||
node.name = `skill_${s_uuid}`
|
||||
const comp = node.getComponent(SSkillBoxComp) || node.addComponent(SSkillBoxComp)
|
||||
// 携带所属英雄与槽位,点击弹窗按英雄技能分档描述渲染
|
||||
comp.initHeroSkill(s_uuid, s_lv, locked, isField, this.huuid, slot)
|
||||
comp.initHeroSkill(s_uuid, s_lv, locked, isField, this.huuid, slot, isGroup)
|
||||
this.skills_node.addChild(node)
|
||||
}
|
||||
|
||||
/**
|
||||
* 触发技能(dead/fstart/atking/atked):按 s_uuid 分组,取 ≤lv 最大档判定激活;
|
||||
* 未激活时预览最低档(与 resolveTriggerByLv 同语义)
|
||||
* @param type 触发槽位(随图标透传,区分与普攻同底座的触发技能)
|
||||
* 触发技能槽位(call/fstart/atking/atked/dead)整组一个图标:
|
||||
* 组内多 s_uuid 合并展示,图标/等级取组内首个 s_uuid 的生效档(未激活预览最低档);
|
||||
* 整组激活判定:组内任一 s_uuid 存在 ≤lv 生效档即视为已激活(与 resolveTriggerByLv 同语义)
|
||||
* @param type 触发槽位(随图标透传,弹窗按整组取档)
|
||||
*/
|
||||
private addTriggerIcons(grouped: TriggerGrouped | undefined, lv: number, type: SkillTriggerType) {
|
||||
private addTriggerGroupIcon(grouped: TriggerGrouped | undefined, lv: number, type: SkillTriggerType) {
|
||||
if (!grouped) return
|
||||
for (const key in grouped) {
|
||||
const entries = grouped[key]
|
||||
if (!entries?.length) continue
|
||||
const sorted = [...entries].sort((a, b) => a.lv - b.lv)
|
||||
let active: LvTriggerEntry | undefined
|
||||
for (const e of sorted) { if (e.lv <= lv) active = e }
|
||||
const pick = active ?? sorted[0]
|
||||
this.addSkillIcon(Number(key), pick.s_lv ?? 1, !active, false, type)
|
||||
const keys = Object.keys(grouped).map(Number).filter(k => grouped[k]?.length)
|
||||
if (keys.length === 0) return
|
||||
// 图标/等级取组内首个 s_uuid 的生效档
|
||||
const sorted = [...grouped[keys[0]]].sort((a, b) => a.lv - b.lv)
|
||||
let active: LvTriggerEntry | undefined
|
||||
for (const e of sorted) { if (e.lv <= lv) active = e }
|
||||
// 整组激活判定:组内任一 s_uuid 存在生效档即激活
|
||||
let anyActive = !!active
|
||||
for (const key of keys) {
|
||||
if (anyActive) break
|
||||
for (const e of grouped[key] ?? []) {
|
||||
if (e.lv <= lv) { anyActive = true; break }
|
||||
}
|
||||
}
|
||||
const pick = active ?? sorted[0]
|
||||
this.addSkillIcon(keys[0], pick.s_lv ?? 1, !anyActive, false, type, true)
|
||||
}
|
||||
|
||||
/** 驻场光环:未激活取最低档预览,激活取 ≤lv 最大档的词条列表 */
|
||||
private addFieldIcons(field: LvFieldEntry[] | undefined, lv: number) {
|
||||
/**
|
||||
* 驻场光环槽位整组一个图标:组内多词条合并展示,
|
||||
* 图标取生效档(未激活预览最低档)的首个词条
|
||||
*/
|
||||
private addFieldGroupIcon(field: LvFieldEntry[] | undefined, lv: number) {
|
||||
if (!field?.length) return
|
||||
const sorted = [...field].sort((a, b) => a.lv - b.lv)
|
||||
let active: LvFieldEntry | undefined
|
||||
for (const e of sorted) { if (e.lv <= lv) active = e }
|
||||
const pick = active ?? sorted[0]
|
||||
for (const entry of pick.uuids) {
|
||||
// 词条档位无 s_lv 概念,技能等级恒为 1(等级标签展示技能等级而非解锁的英雄等级)
|
||||
this.addSkillIcon(entry.uuid, 1, !active, true, SkillTriggerType.Field)
|
||||
}
|
||||
const firstUuid = pick.uuids[0]?.uuid
|
||||
if (!firstUuid) return
|
||||
// 词条档位无 s_lv 概念,技能等级恒为 1(等级标签展示技能等级而非解锁的英雄等级)
|
||||
this.addSkillIcon(firstUuid, 1, !active, true, SkillTriggerType.Field, true)
|
||||
}
|
||||
|
||||
/** 复活技能已纳入 dead 触发组,通过 dead 配置展示(revive_hp / revive_count),无需单独处理 */
|
||||
|
||||
Reference in New Issue
Block a user