You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
AdLike2048/assets/script/ui/PopSelect/UIPopSelect.ts

200 lines
7.1 KiB

4 days ago
//*********************
// create by 流云
// time: Tue Oct 13 2026
4 days ago
// desc: 局内 Battlebuff 三选一
4 days ago
//*********************
4 days ago
import { _decorator, find, instantiate, Label, Node, RichText, sp } from 'cc';
import { SpriteLoad } from 'db://assets/mx/components/SpriteLoad';
4 days ago
import { Auto_PopSelect } from './Auto_PopSelect';
4 days ago
import { GBundle, GPath, UIID } from '../../game/ConfigRes';
import {
BattleBuffSelectService,
type BattleBuffSelectOption,
} from '../../manager/battleBuff/BattleBuffSelectService';
import { BattleBuffInGameRefresh } from '../../battle/combat/BattleBuffInGameRefresh';
import type { ProjectBattleHandle } from '../../battle/runtime/BattleRuntime';
const { ccclass } = _decorator;
/** 五行 target → 图标名 */
const TARGET_ICON: string[] = ['', '金', '木', '水', '火', '土'];
/** Spine 皮肤 */
const SKIN_PURPLE = '紫色';
const SKIN_ORANGE = '橙色';
4 days ago
@ccclass('UIPopSelect')
export class UIPopSelect extends Auto_PopSelect {
4 days ago
/** 本机 playerId */
private _playerId = 0;
/** itemTemplate 原型 */
private _itemTemplate: Node | null = null;
/** 已实例化选项节点 */
private readonly _itemNodes: Node[] = [];
4 days ago
4 days ago
onInit(): void {
3 days ago
const battle = gg.game.CurentBattle as ProjectBattleHandle | null;
this._playerId = battle?.localPlayerId ?? 0;
4 days ago
if (!this.lb_haveCount) {
this.lb_haveCount = find('ui_center/btnRefresh/lb_haveCount', this.node)?.getComponent(Label) ?? null;
}
this._cacheTemplate();
BattleBuffSelectService.ensurePlayer(this._playerId);
const options = BattleBuffSelectService.beginPopup(this._playerId);
this._renderOptions(options);
this._refreshCountUi();
4 days ago
}
4 days ago
click_btnRefresh(): void {
if (!BattleBuffSelectService.canRefresh(this._playerId)) {
gg.ui.showToast('刷新次数已用完');
return;
}
if (BattleBuffSelectService.shouldUseFreeRefresh(this._playerId)) {
const next = BattleBuffSelectService.refreshOptions(this._playerId, false);
if (next) {
this._renderOptions(next);
this._refreshCountUi();
}
return;
}
gg.sdk.showVideoAd((res) => {
if (!res) {
gg.ui.showToast('观看视频失败');
return;
}
if (!this.node?.isValid) return;
const next = BattleBuffSelectService.refreshOptions(this._playerId, true);
if (next) {
this._renderOptions(next);
this._refreshCountUi();
}
});
4 days ago
}
4 days ago
private _cacheTemplate(): void {
if (this._itemTemplate) return;
const list = this.ui_itemList;
if (!list) {
console.warn('[UIPopSelect] 缺少 ui_itemList');
return;
}
const tpl = list.getChildByName('itemTemplate') ?? list.getChildByName('ui_itemTemplate');
if (!tpl) {
console.warn('[UIPopSelect] 缺少 itemTemplate/ui_itemTemplate');
return;
}
this._itemTemplate = tpl;
tpl.active = false;
4 days ago
}
4 days ago
private _refreshCountUi(): void {
const remain = BattleBuffSelectService.remainRefreshTotal(this._playerId);
if (this.lb_haveCount) {
3 days ago
this.lb_haveCount.string = `${remain}`;
4 days ago
}
if (this.btnRefresh) {
this.btnRefresh.active = BattleBuffSelectService.canRefresh(this._playerId);
}
}
private _renderOptions(options: BattleBuffSelectOption[]): void {
this._clearItems();
const list = this.ui_itemList;
const tpl = this._itemTemplate;
if (!list || !tpl) return;
for (let i = 0; i < options.length; i++) {
const node = instantiate(tpl);
node.active = true;
node.name = `item_${i}`;
list.addChild(node);
this._itemNodes.push(node);
this._bindItem(node, options[i]);
}
}
private _clearItems(): void {
for (let i = 0; i < this._itemNodes.length; i++) {
const n = this._itemNodes[i];
if (n?.isValid) n.destroy();
}
this._itemNodes.length = 0;
}
private _bindItem(node: Node, opt: BattleBuffSelectOption): void {
const row = opt.row;
const q = Math.floor(Number(opt.quality) || 0);
this._setSprite(node.getChildByName('bg'), GPath.PingjiKuang(`b${q}`));
this._setSprite(node.getChildByName('quality'), GPath.PingjiKuang(`q${q}`));
const iconName = String(row.icon || row.name || '').trim();
if (iconName) {
this._setSprite(node.getChildByName('icon'), GPath.ShopSkill(iconName));
} else {
console.warn('[UIPopSelect] buff icon 为空', row.id);
}
const five = node.getChildByName('fiveIcon');
const target = Math.floor(Number(row.target) || 0);
if (five) {
if (target >= 1 && target <= 5) {
five.active = true;
this._setSprite(five, GPath.ElementAttr(TARGET_ICON[target]));
} else {
five.active = false;
}
}
const lbName = node.getChildByName('lbName')?.getComponent(Label);
if (lbName) lbName.string = String(row.name ?? '');
const rtDesc = node.getChildByName('rtDesc')?.getComponent(RichText);
if (rtDesc) rtDesc.string = String(row.desc ?? '');
this._syncLight(node.getChildByName('light'), q);
node.off(Node.EventType.TOUCH_END);
node.on(Node.EventType.TOUCH_END, () => this._onPick(opt.id), this);
}
private _syncLight(light: Node | null, quality: number): void {
if (!light) return;
if (quality !== 3 && quality !== 4) {
light.active = false;
return;
}
light.active = true;
const skel = light.getComponent(sp.Skeleton);
if (!skel) {
console.warn('[UIPopSelect] light 缺少 Skeleton');
return;
}
const skin = quality === 4 ? SKIN_ORANGE : SKIN_PURPLE;
try {
skel.setSkin(skin);
skel.setAnimation(0, skel.animation || 'animation', true);
} catch (e) {
console.warn('[UIPopSelect] setSkin 失败', skin, e);
}
}
private _setSprite(node: Node | null, path: string): void {
if (!node) return;
let sl = node.getComponent(SpriteLoad);
if (!sl) {
sl = node.addComponent(SpriteLoad);
}
sl.setSprite(path, GBundle.Items);
}
private _onPick(buffId: number): void {
const parsed = BattleBuffSelectService.confirmPick(this._playerId, buffId);
if (!parsed) return;
const battle = gg.game.CurentBattle as ProjectBattleHandle | null;
if (battle) {
BattleBuffInGameRefresh.afterPick(battle, this._playerId);
}
const battleUi = gg.ui.getPanelBase(UIID.BattleGame) as { refreshBattleBuffSkills?: () => void } | null;
battleUi?.refreshBattleBuffSkills?.();
this.close(2);
}
onDisable(): void {
this._clearItems();
super.onDisable();
4 days ago
}
}