import { Node, sp, Sprite } from 'cc'; import { SpriteLoad } from 'db://assets/mx/components/SpriteLoad'; import { ensureSpineSkeletonDataRuntime } from 'db://assets/mx/module/lang/spineRuntimePatch'; import { applyWeaponSpineSkin } from '../../battle/view/GlyphSpineSkin'; import { GBundle } from '../../game/ConfigRes'; const LOG = '[PopNewWeaponItemView]'; const WEAPON_SPINE_ANIM = '待机'; /** 武器名不少于 5 字时 name 缩放(与 itemNode1 openNode 一致) */ const WEAPON_NAME_LONG_LEN = 5; const NAME_SCALE_NORMAL = 1; const NAME_SCALE_LONG = 0.8; /** * PopNewWeapon 武器格子:quality / name / type1~4 */ export class PopNewWeaponItemView { /** 绑定成品武器展示 */ static bind(item: Node, equipId: number): void { const weapon = gg.equip.getEquip(equipId); if (!weapon) { console.warn(LOG, '武器表缺失', equipId); item.active = false; return; } item.active = true; const weaponType = Number(weapon.type) | 0; const skin = String(weapon.skin ?? '').trim(); const weaponName = String(weapon.name ?? '').trim(); if (weaponType < 1 || weaponType > 4) console.warn(LOG, 'type 无效', equipId, weaponType); if (!skin) console.warn(LOG, 'skin 缺失', equipId); if (!weaponName) console.warn(LOG, 'name 缺失', equipId); const bgIndex = PopNewWeaponItemView._qualityBgIndex(Number(weapon.quality), equipId); PopNewWeaponItemView._setSprite(item.getChildByName('quality'), `weapon/武器底${bgIndex}`); PopNewWeaponItemView._setWeaponName(item.getChildByName('name'), weaponName); PopNewWeaponItemView._applyWeaponSpineGroup(item, weaponType, skin); } /** 设置武器名图与缩放 */ private static _setWeaponName(nameNode: Node | null, weaponName: string): void { if (!nameNode?.isValid) { console.warn(LOG, 'name 节点缺失'); return; } const scale = weaponName.length >= WEAPON_NAME_LONG_LEN ? NAME_SCALE_LONG : NAME_SCALE_NORMAL; const applyScale = (): void => { nameNode.setScale(scale, scale, 1); }; const path = weaponName ? `weapon/${weaponName}` : ''; if (!path) { nameNode.active = false; applyScale(); return; } nameNode.active = true; if (!nameNode.getComponent(Sprite)) nameNode.addComponent(Sprite); nameNode.getOrAddComponent(SpriteLoad).setSprite(path, GBundle.Items, () => { applyScale(); }); applyScale(); } /** 按武器类型显隐 type1~4 并换肤 */ private static _applyWeaponSpineGroup(parent: Node, weaponType: number, skin: string): void { let matched = false; for (let t = 1; t <= 4; t++) { const typeNode = parent.getChildByName(`type${t}`); if (!typeNode) continue; const show = t === weaponType; typeNode.active = show; if (!show) continue; matched = true; PopNewWeaponItemView._applyWeaponSpine(typeNode, skin); } if (!matched && weaponType >= 1 && weaponType <= 4) { console.warn(LOG, 'type 节点缺失', parent.name, weaponType); } } /** 设置单个武器 Spine 皮肤与待机 */ private static _applyWeaponSpine(typeNode: Node, skin: string): void { const skel = typeNode.getComponent(sp.Skeleton) ?? typeNode.getComponentInChildren(sp.Skeleton); if (!skel) { console.warn(LOG, 'Spine 缺失', typeNode.name); return; } if (skel.skeletonData) ensureSpineSkeletonDataRuntime(skel.skeletonData); if (skin) applyWeaponSpineSkin(skel, skin, LOG); try { skel.setAnimation(0, WEAPON_SPINE_ANIM, true); } catch (e) { console.warn(LOG, 'setAnimation 失败', WEAPON_SPINE_ANIM, String(e)); } } /** 成品品质 → 武器底 0~4 */ private static _qualityBgIndex(quality: number, equipId: number): number { const q = Number(quality) | 0; if (q < 0 || q > 4) console.warn(LOG, '品质无效', equipId, q); return q; } /** icons/weapon 下图 */ private static _setSprite(node: Node | null, path: string): void { if (!node?.isValid) return; if (!path) { node.active = false; return; } node.active = true; if (!node.getComponent(Sprite)) node.addComponent(Sprite); node.getOrAddComponent(SpriteLoad).setSprite(path, GBundle.Items); } }