import { _decorator, instantiate, Label, Node, Prefab, UITransform, v3, Vec3 } from 'cc'; import { CCComp } from 'db://oops-framework/module/common/CCComp'; import { ecs } from 'db://oops-framework/libs/ecs/ECS'; import { SkillSet } from '../common/config/SkillSet'; import { BoxSet, FacSet } from '../common/config/GameSet'; import { smc } from '../common/SingletonModuleComp'; import { Skill } from '../skill/Skill'; import { mLogger } from '../common/Logger'; const { ccclass, property } = _decorator; @ccclass('HSkillComp') @ecs.register('HSkillComp', false) export class HSkillComp extends CCComp { debugMode: boolean = false; private readonly panelName: string = 'skill_debug_panel'; private readonly panelWidth: number = 680; private readonly panelHeight: number = 1180; private readonly colCount: number = 4; private readonly cellWidth: number = 160; private readonly cellHeight: number = 68; private readonly startX: number = -240; private readonly startY: number = 560; @property(Prefab) btnPrefab: Prefab | null = null; private panelNode: Node | null = null; private buttonNodes: Node[] = []; private mockCasterNode: Node | null = null; private mockCasterView: any = null; private currentSkill: Skill | null = null; protected onLoad(): void { this.ensurePanel(); } start() { this.renderSkillButtons(); } start_test() { this.node.active = true; const home = this.node.parent?.getChildByName('mission_home'); if (home) { home.active = false; } this.renderSkillButtons(); } end_test() { const home = this.node.parent?.getChildByName('mission_home'); if (home) { home.active = true; } this.node.active = false; } update_data(uuid: number) { this.renderSkillButtons(); } private ensurePanel() { let panel = this.node.getChildByName(this.panelName); if (!panel) { panel = new Node(this.panelName); panel.parent = this.node; const transform = panel.addComponent(UITransform); transform.setContentSize(this.panelWidth, this.panelHeight); panel.setPosition(0, 640, 0); } this.panelNode = panel; } private renderSkillButtons() { this.ensurePanel(); const prefab = this.getBtnPrefab(); if (!prefab || !this.panelNode || !this.panelNode.isValid) { return; } this.clearButtons(); const skillIds = Object.keys(SkillSet).map(Number).sort((a, b) => a - b); skillIds.forEach((skillId, index) => { const btnNode = instantiate(prefab); btnNode.parent = this.panelNode; const row = Math.floor(index / this.colCount); const col = index % this.colCount; btnNode.setPosition( this.startX + col * this.cellWidth, this.startY - row * this.cellHeight, 0 ); const label = btnNode.getChildByName('Label')?.getComponent(Label); if (label) { const conf = SkillSet[skillId]; label.string = `${skillId} ${conf?.name ?? ''}`; } btnNode.on(Node.EventType.TOUCH_END, () => this.playDebugSkill(skillId), this); this.buttonNodes.push(btnNode); }); } private clearButtons() { this.buttonNodes.forEach(node => { if (!node || !node.isValid) { return; } node.off(Node.EventType.TOUCH_END); node.destroy(); }); this.buttonNodes.length = 0; } private getBtnPrefab(): Prefab | null { if (this.btnPrefab) { return this.btnPrefab; } mLogger.error(this.debugMode, 'HSkillComp', '[HSkillComp] 未绑定 Btn 预制体,请在编辑器中设置 btnPrefab'); return null; } private getSkillParent(): Node { const layer = smc.map?.MapView?.scene?.entityLayer?.node?.getChildByName('SKILL'); if (layer && layer.isValid) { return layer; } return this.node; } private ensureMockCaster(parent: Node, startPos: Vec3): any { if (!this.mockCasterNode || !this.mockCasterNode.isValid) { this.mockCasterNode = new Node('debug_caster'); this.mockCasterNode.parent = parent; this.mockCasterNode.setScale(v3(1, 1, 1)); this.mockCasterNode.active = false; } else if (this.mockCasterNode.parent !== parent) { this.mockCasterNode.parent = parent; } this.mockCasterNode.setPosition(startPos); const mockAttrs = { hero_name: '技能调试器', ap: 100, critical: 0, critical_dmg: 50, freeze_chance: 0, stun_chance: 0, back_chance: 0, slow_chance: 0, puncture: 0, puncture_dmg: 0, wfuny: 0, fac: FacSet.HERO }; const mockEntity = { eid: -10086, get: () => mockAttrs }; this.mockCasterView = { node: this.mockCasterNode, box_group: BoxSet.HERO, ent: mockEntity }; return this.mockCasterView; } private playDebugSkill(skillId: number) { const conf = SkillSet[skillId]; if (!conf) { return; } this.destroyCurrentSkill(); const parent = this.getSkillParent(); const startPos = v3(-260, -40, 0); const targetPos = v3(260, -40, 0); const caster = this.ensureMockCaster(parent, startPos); const skill = ecs.getEntity(Skill); skill.load(startPos.clone(), parent, skillId, targetPos, caster, 0); this.currentSkill = skill; } private destroyCurrentSkill() { if (!this.currentSkill) { return; } this.currentSkill.destroy(); this.currentSkill = null; } reset() { this.destroyCurrentSkill(); this.clearButtons(); if (this.mockCasterNode && this.mockCasterNode.isValid) { this.mockCasterNode.destroy(); this.mockCasterNode = null; } this.node.destroy(); } }