feat(hero-ui): 新增普攻lv2强化档独立展示功能
实现英雄图鉴中普攻lv2强化档的单独展示逻辑: 1. 为技能档位渲染添加minLv参数,支持裁剪低档位 2. 新增普攻lv2专属模式,图标/名称取lv1,弹窗仅展示lv2+档位 3. 自动为符合条件的普攻强化档生成独立技能图标 4. 适配等级显示偏移,配置Lv2显示为Lv1
This commit is contained in:
@@ -542,9 +542,11 @@ function buildTierLines(tiers: ISkillTierInfo[], triggerLabel: string): HeroSkil
|
|||||||
* @param heroUuid 英雄 uuid(HeroInfo key)
|
* @param heroUuid 英雄 uuid(HeroInfo key)
|
||||||
* @param skillUuid 技能 uuid(skills key / 触发组 s_uuid / FieldSkillSet uuid / 复活 SkillSet uuid)
|
* @param skillUuid 技能 uuid(skills key / 触发组 s_uuid / FieldSkillSet uuid / 复活 SkillSet uuid)
|
||||||
* @param slot 技能所属槽位(可空):指定时仅在该槽位查找;缺省按上述顺序自动定位
|
* @param slot 技能所属槽位(可空):指定时仅在该槽位查找;缺省按上述顺序自动定位
|
||||||
|
* @param minLv 最低展示档(默认 1):传 2 时裁剪掉 sLv<2 的档,仅保留 lv2+ 档位
|
||||||
|
* (普攻强化档作为独立技能展示的场景,如 heroSet 普攻 lv2 档单独出图标)
|
||||||
* @returns 档位行数组;技能不属于该英雄时返回 []
|
* @returns 档位行数组;技能不属于该英雄时返回 []
|
||||||
*/
|
*/
|
||||||
export function buildHeroSkillTierLines(heroUuid: number, skillUuid: number, slot?: SkillTriggerType): HeroSkillTierLine[] {
|
export function buildHeroSkillTierLines(heroUuid: number, skillUuid: number, slot?: SkillTriggerType, minLv: number = 1): HeroSkillTierLine[] {
|
||||||
const hero = HeroInfo[heroUuid];
|
const hero = HeroInfo[heroUuid];
|
||||||
if (!hero) return [];
|
if (!hero) return [];
|
||||||
|
|
||||||
@@ -577,12 +579,13 @@ export function buildHeroSkillTierLines(heroUuid: number, skillUuid: number, slo
|
|||||||
// 光环路径(无 ISkillTierInfo 中间结构,直接生成 HeroSkillTierLine)
|
// 光环路径(无 ISkillTierInfo 中间结构,直接生成 HeroSkillTierLine)
|
||||||
if (tiers.length === 0) {
|
if (tiers.length === 0) {
|
||||||
const fieldLines = collectFieldTierLines(hero, skillUuid);
|
const fieldLines = collectFieldTierLines(hero, skillUuid);
|
||||||
if (fieldLines.length > 0) return fieldLines;
|
if (fieldLines.length > 0) return minLv > 1 ? fieldLines.filter(l => l.sLv >= minLv) : fieldLines;
|
||||||
// 复活已纳入 dead 触发组,通过 dead 路径处理
|
// 复活已纳入 dead 触发组,通过 dead 路径处理
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
return buildTierLines(tiers, triggerLabel);
|
const lines = buildTierLines(tiers, triggerLabel);
|
||||||
|
return minLv > 1 ? lines.filter(l => l.sLv >= minLv) : lines;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -22,7 +22,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 { oops } from "db://oops-framework/core/Oops";
|
import { oops } from "db://oops-framework/core/Oops";
|
||||||
import { mLogger } from "../common/Logger";
|
import { mLogger } from "../common/Logger";
|
||||||
import { HeroInfo, HeroList, SkillTriggerType, LvFieldEntry, LvTriggerEntry, TriggerGrouped, getHeroDisplayStats } from "../common/config/heroSet";
|
import { HeroInfo, HeroList, SkillTriggerType, LvFieldEntry, LvTriggerEntry, TriggerGrouped, HSkillInfo, getHeroDisplayStats } from "../common/config/heroSet";
|
||||||
import { buildHeroSkillDesc } from "../common/HeroSkillText";
|
import { buildHeroSkillDesc } from "../common/HeroSkillText";
|
||||||
import { GameEvent } from "../common/config/GameEvent";
|
import { GameEvent } from "../common/config/GameEvent";
|
||||||
import { HERO_UPGRADE_NEED_FRAGMENTS, RARITY_BG_COLORS } from "../common/config/GameSet";
|
import { HERO_UPGRADE_NEED_FRAGMENTS, RARITY_BG_COLORS } from "../common/config/GameSet";
|
||||||
@@ -524,6 +524,9 @@ export class HerosListComp extends CCComp {
|
|||||||
this.addSkillIcon(hSkill.uuid, sLv, false, false)
|
this.addSkillIcon(hSkill.uuid, sLv, false, false)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// ---- 普攻 lv2 强化档:作为独立技能图标(名称/图标取 lv1,弹窗只展示 lv2 说明) ----
|
||||||
|
this.addNormalLv2Icon(Object.values(hero.skills)[0], lv)
|
||||||
|
|
||||||
// ---- 触发技能:每个触发槽位整组一个图标,按 PANEL_TRIGGER_TYPES 顺序追加 ----
|
// ---- 触发技能:每个触发槽位整组一个图标,按 PANEL_TRIGGER_TYPES 顺序追加 ----
|
||||||
for (const type of HerosListComp.PANEL_TRIGGER_TYPES) {
|
for (const type of HerosListComp.PANEL_TRIGGER_TYPES) {
|
||||||
if (type === SkillTriggerType.Field) {
|
if (type === SkillTriggerType.Field) {
|
||||||
@@ -544,13 +547,15 @@ export class HerosListComp extends CCComp {
|
|||||||
* 同一底座不同槽位视为不同技能,弹窗按槽位取档;复活已纳入 dead)
|
* 同一底座不同槽位视为不同技能,弹窗按槽位取档;复活已纳入 dead)
|
||||||
* @param isGroup 整组模式:该图标代表整个触发槽位,组名取组内首个自定义名,
|
* @param isGroup 整组模式:该图标代表整个触发槽位,组名取组内首个自定义名,
|
||||||
* 弹窗按整组合并渲染(组内多技能/词条统一说明)
|
* 弹窗按整组合并渲染(组内多技能/词条统一说明)
|
||||||
|
* @param normalLv2 普攻 lv2 专属模式:该图标代表普攻 lv2 强化档,名称/图标取 lv1,
|
||||||
|
* 弹窗只展示 lv2 档位说明
|
||||||
*/
|
*/
|
||||||
private addSkillIcon(s_uuid: number, s_lv: number, locked: boolean, isField: boolean, slot?: SkillTriggerType, isGroup: boolean = false) {
|
private addSkillIcon(s_uuid: number, s_lv: number, locked: boolean, isField: boolean, slot?: SkillTriggerType, isGroup: boolean = false, normalLv2: boolean = false) {
|
||||||
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, slot, isGroup)
|
comp.initHeroSkill(s_uuid, s_lv, locked, isField, this.huuid, slot, isGroup, normalLv2)
|
||||||
this.skills_node.addChild(node)
|
this.skills_node.addChild(node)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -598,6 +603,22 @@ export class HerosListComp extends CCComp {
|
|||||||
|
|
||||||
/** 复活技能已纳入 dead 触发组,通过 dead 配置展示(revive_hp / revive_count),无需单独处理 */
|
/** 复活技能已纳入 dead 触发组,通过 dead 配置展示(revive_hp / revive_count),无需单独处理 */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 普攻 lv2+ 强化档作为独立技能图标:
|
||||||
|
* 普攻(skills[0])lv_entries 存在档时单独出图标,名称/图标取 lv1(s_uuid 相同),
|
||||||
|
* 等级显示偏移一档(配置 Lv2 → Lv1,SSkillBoxComp 统一处理),弹窗按 hero_normal_lv2
|
||||||
|
* 模式只展示 lv2+ 档位说明;激活判定按档位的英雄等级(lv 阈值)。
|
||||||
|
* Why: 普攻 lv2 档是独立成长机制(如附加暴击/冰冻),需让玩家明确感知其存在与解锁条件。
|
||||||
|
*/
|
||||||
|
private addNormalLv2Icon(normal: HSkillInfo | undefined, lv: number) {
|
||||||
|
const entry = normal?.lv_entries?.[0]
|
||||||
|
if (!normal || !entry) return
|
||||||
|
// 节点命名区分 lv2 档(普攻与触发槽位可能同底座,uuid 重名会互相干扰)
|
||||||
|
this.addSkillIcon(normal.uuid, entry.s_lv ?? 2, lv < entry.lv, false, undefined, false, true)
|
||||||
|
const icon = this.skills_node.children[this.skills_node.children.length - 1]
|
||||||
|
if (icon) icon.name = `skill_${normal.uuid}_lv2`
|
||||||
|
}
|
||||||
|
|
||||||
// ======================== 英雄动画 ========================
|
// ======================== 英雄动画 ========================
|
||||||
|
|
||||||
private updateHeroAnimation(uuid: number) {
|
private updateHeroAnimation(uuid: number) {
|
||||||
|
|||||||
@@ -48,6 +48,9 @@ export class SSkillBoxComp extends CCComp {
|
|||||||
/** 整组模式(英雄图鉴):true 时该图标代表整个触发槽位(atking/dead/fstart/atked/call/field),
|
/** 整组模式(英雄图鉴):true 时该图标代表整个触发槽位(atking/dead/fstart/atked/call/field),
|
||||||
* 组内多技能/词条合并为一个名称与一套说明展示,弹窗按整组取档 */
|
* 组内多技能/词条合并为一个名称与一套说明展示,弹窗按整组取档 */
|
||||||
private hero_group: boolean = false;
|
private hero_group: boolean = false;
|
||||||
|
/** 普攻 lv2 专属模式(英雄图鉴):true 时该图标代表普攻 lv2 强化档,
|
||||||
|
* 名称/图标取 lv1,弹窗只展示 lv2 档位说明(裁剪 lv1 档) */
|
||||||
|
private hero_normal_lv2: boolean = false;
|
||||||
/** 卡牌等级 */
|
/** 卡牌等级 */
|
||||||
private rarity: number = 1;
|
private rarity: number = 1;
|
||||||
/** 卡牌自定义图标ID(优先级最高,未定义则按 trigger_type 自动取) */
|
/** 卡牌自定义图标ID(优先级最高,未定义则按 trigger_type 自动取) */
|
||||||
@@ -89,6 +92,8 @@ export class SSkillBoxComp extends CCComp {
|
|||||||
hero_slot: this.hero_uuid ? this.hero_slot : undefined,
|
hero_slot: this.hero_uuid ? this.hero_slot : undefined,
|
||||||
// 整组模式:弹窗按整个触发槽位合并渲染(组内多技能/词条统一说明)
|
// 整组模式:弹窗按整个触发槽位合并渲染(组内多技能/词条统一说明)
|
||||||
hero_group: this.hero_uuid ? this.hero_group : undefined,
|
hero_group: this.hero_uuid ? this.hero_group : undefined,
|
||||||
|
// 普攻 lv2 专属模式:弹窗只展示 lv2 档位说明(名称/图标取 lv1)
|
||||||
|
hero_normal_lv2: this.hero_uuid ? this.hero_normal_lv2 : undefined,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -115,13 +120,18 @@ export class SSkillBoxComp extends CCComp {
|
|||||||
* @param slot 技能所属槽位(普攻/大招传 undefined;触发/光环传对应类型,复活已纳入 dead)
|
* @param slot 技能所属槽位(普攻/大招传 undefined;触发/光环传对应类型,复活已纳入 dead)
|
||||||
* @param isGroup 整组模式:该图标代表整个触发槽位,组名取组内首个自定义名,
|
* @param isGroup 整组模式:该图标代表整个触发槽位,组名取组内首个自定义名,
|
||||||
* 弹窗按整组合并渲染(组内多技能/词条统一说明)
|
* 弹窗按整组合并渲染(组内多技能/词条统一说明)
|
||||||
|
* @param normalLv2 普攻 lv2+ 强化档专属模式:名称/图标取 lv1,弹窗只展示 lv2+ 档位说明;
|
||||||
|
* 等级显示偏移一档(配置 Lv2 → 显示 Lv1,Lv3 → 显示 Lv2),强化档从 1 起计
|
||||||
*/
|
*/
|
||||||
initHeroSkill(s_uuid: number, s_lv: number, locked: boolean, isField: boolean = false, heroUuid: number = 0, slot?: SkillTriggerType, isGroup: boolean = false) {
|
initHeroSkill(s_uuid: number, s_lv: number, locked: boolean, isField: boolean = false, heroUuid: number = 0, slot?: SkillTriggerType, isGroup: boolean = false, normalLv2: boolean = false) {
|
||||||
this.s_uuid = s_uuid;
|
this.s_uuid = s_uuid;
|
||||||
this.hero_uuid = heroUuid;
|
this.hero_uuid = heroUuid;
|
||||||
this.hero_slot = slot;
|
this.hero_slot = slot;
|
||||||
this.hero_group = isGroup;
|
this.hero_group = isGroup;
|
||||||
this.rarity = s_lv;
|
this.hero_normal_lv2 = normalLv2;
|
||||||
|
// 普攻 lv2+ 强化档:等级显示偏移一档(配置 Lv2 显示 Lv1,Lv3 显示 Lv2),
|
||||||
|
// 强化档作为独立于普攻的技能存在,等级从 1 起计
|
||||||
|
this.rarity = normalLv2 ? Math.max(1, s_lv - 1) : s_lv;
|
||||||
this.hero_icon_source = isField ? "field" : "skill";
|
this.hero_icon_source = isField ? "field" : "skill";
|
||||||
this.updateUI();
|
this.updateUI();
|
||||||
this.setLocked(locked);
|
this.setLocked(locked);
|
||||||
|
|||||||
@@ -64,6 +64,9 @@ export interface SInfoParams {
|
|||||||
/** 触发组整体模式(英雄图鉴):true 时按 hero_slot 整组渲染,
|
/** 触发组整体模式(英雄图鉴):true 时按 hero_slot 整组渲染,
|
||||||
* 组内多技能/词条合并为一套分档说明统一展示(每个触发槽位视为一个技能) */
|
* 组内多技能/词条合并为一套分档说明统一展示(每个触发槽位视为一个技能) */
|
||||||
hero_group?: boolean;
|
hero_group?: boolean;
|
||||||
|
/** 普攻 lv2+ 强化档专属模式(英雄图鉴):名称/图标取 lv1,只展示 lv2+ 档位说明
|
||||||
|
* (裁剪 lv1 档,隐藏 2/3 级面板);等级显示偏移一档(配置 Lv2 → 显示 Lv1,Lv3 → Lv2) */
|
||||||
|
hero_normal_lv2?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 等级提升信息(用于 2 级 / 3 级面板) */
|
/** 等级提升信息(用于 2 级 / 3 级面板) */
|
||||||
@@ -256,15 +259,16 @@ export class SinfoComp extends CCComp {
|
|||||||
private renderHeroSkill(p: SInfoParams): boolean {
|
private renderHeroSkill(p: SInfoParams): boolean {
|
||||||
const tiers = (p.hero_group && p.hero_slot !== undefined)
|
const tiers = (p.hero_group && p.hero_slot !== undefined)
|
||||||
? buildHeroGroupTierLines(p.hero_uuid!, p.hero_slot)
|
? buildHeroGroupTierLines(p.hero_uuid!, p.hero_slot)
|
||||||
: buildHeroSkillTierLines(p.hero_uuid!, p.uuid, p.hero_slot);
|
: buildHeroSkillTierLines(p.hero_uuid!, p.uuid, p.hero_slot, p.hero_normal_lv2 ? 2 : 1);
|
||||||
if (tiers.length === 0) return false;
|
if (tiers.length === 0) return false;
|
||||||
|
|
||||||
// 图标 / 名称 / 当前技能等级与通用逻辑一致(skill_lv 传的就是当前生效 s_lv)
|
// 图标 / 名称 / 当前技能等级与通用逻辑一致(skill_lv 传的就是当前生效 s_lv;
|
||||||
|
// 普攻 lv2+ 强化档等级偏移一档显示:配置 Lv2 → Lv1,Lv3 → Lv2)
|
||||||
this.renderIcon(p);
|
this.renderIcon(p);
|
||||||
this.setLabel(this.name_label, this.resolveName(p));
|
this.setLabel(this.name_label, this.resolveName(p));
|
||||||
this.setLabel(this.lv_label, `Lv.${p.skill_lv}`);
|
this.setLabel(this.lv_label, `Lv.${p.hero_normal_lv2 ? Math.max(1, p.skill_lv - 1) : p.skill_lv}`);
|
||||||
|
|
||||||
// 技能 1 级:完整能力描述
|
// 主说明:普攻 lv2 专属模式只展示 lv2 档位文本(裁剪后首档即 lv2),否则 slv1 完整能力
|
||||||
if (this.main_info && this.main_info.isValid) {
|
if (this.main_info && this.main_info.isValid) {
|
||||||
this.main_info.string = tiers[0].text || "暂无描述";
|
this.main_info.string = tiers[0].text || "暂无描述";
|
||||||
}
|
}
|
||||||
@@ -272,9 +276,17 @@ export class SinfoComp extends CCComp {
|
|||||||
// 英雄当前局外等级:激活判定基准
|
// 英雄当前局外等级:激活判定基准
|
||||||
const heroLv = Math.max(1, smc.getHeroOuterLv(p.hero_uuid!));
|
const heroLv = Math.max(1, smc.getHeroOuterLv(p.hero_uuid!));
|
||||||
|
|
||||||
// 未激活图标背景:1 级档位未解锁时显示
|
// 未激活图标背景:首档未解锁时显示
|
||||||
this.updateInactiveBg(heroLv >= tiers[0].heroLv);
|
this.updateInactiveBg(heroLv >= tiers[0].heroLv);
|
||||||
|
|
||||||
|
// 普攻 lv2 专属模式:等级/档位面板均由该档接管,隐藏 2/3 级面板(只展示 lv2 描述)
|
||||||
|
if (p.hero_normal_lv2) {
|
||||||
|
this.setPanelActive(this.lv2_node, false);
|
||||||
|
this.setPanelActive(this.lv3_node, false);
|
||||||
|
this.renderLvPanelFromTier(tiers[0], heroLv, this.main_status, null);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// 技能 1 级:激活状态与 2/3 级面板同一表示方式(描述已在 main_info 展示,此处仅渲染状态)
|
// 技能 1 级:激活状态与 2/3 级面板同一表示方式(描述已在 main_info 展示,此处仅渲染状态)
|
||||||
this.renderLvPanelFromTier(tiers[0], heroLv, this.main_status, null);
|
this.renderLvPanelFromTier(tiers[0], heroLv, this.main_status, null);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user