消消方块阵换皮表情
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.
 
 
 

512 lines
23 KiB

//*********************
// create by 流云
// time: Wed Mar 25 2026
// desc:
//*********************
import { _decorator, Component, Node, find, instantiate, RichText, Tween, Vec3 } from 'cc';
import { Auto_SkillSelect } from './Auto_SkillSelect';
import { MonsterType } from '../../manager/MonsterDataManager';
import { SkillSelectItem } from './SkillSelectItem';
import { BattleType, ChapterDifficulty } from '../../manager/ChapterDataManager';
import BeginnerGuideManager, { BeginnerGuideType } from '../BattleGame/BeginnerGuideManager';
import { GEvent } from 'db://assets/mx/module/event/GEvent';
import { ConstNumType } from '../../game/ConfigProjectData';
import { StatisticsType } from '../../game/GameData';
import { UIID } from '../../game/ConfigRes';
import { WeaponType } from '../../manager/WeaponDataManager';
import MTools from 'db://assets/mx/tools/MTools';
import { OpenParam } from '../../../mx/module/ui/UIBase';
import { BattleResLoader } from '../../game/BattleResLoader';
const { ccclass, property } = _decorator;
@ccclass('UISkillSelect')
export class UISkillSelect extends Auto_SkillSelect {
guideBtnNode: Node = null;
onLoad(): void {
super.onLoad();
}
onEnable(): void {
super.onEnable();
if (!gg.game?.isBattleContextActive?.()) {
return;
}
gg.game.CurentBattle.pause('SkillSelect');
}
onAdded(args?: OpenParam): void {
try {
super.onAdded(args);
} catch (e) {
console.error('[UISkillSelect] onAdded/onInit error', e);
try {
gg.ui.reportSkillSelectInitFailed(args, e, this.getOpenFailContext());
} catch (reportErr) {
console.error('[UISkillSelect] reportSkillSelectInitFailed error', reportErr);
}
void this.close(1);
}
}
onDisable(): void {
super.onDisable();
const battle = gg.game?.CurentBattle;
if (!battle) {
return;
}
if (battle.BattleType == BattleType.SpeedMode) {
this.getAll();
}
if (battle.BattleType == BattleType.OrangeWeaponMode_Ya) {
battle.luosiReplicaBoxForceType = 0;
battle.flushPendingJiujiuwoyaSkillUpgradeEffect();
}
battle.onBlockingPanelClosed();
}
onInit(): void {
if (!gg.game?.isBattleContextActive?.()) {
void this.close(1);
return;
}
let isFirstSelectWeapon = this.prema || false
console.log('isFirstSelectWeapon', isFirstSelectWeapon)
this.showOpenCenterEff();
this.showOpenMaskEff(2);
gg.game.CurentBattle.IsOpenSkillSelectTimes++;
// 开启宝箱会推进“已开启次数”,需要立即刷新主界面宝箱免费/价格文案
GEvent.Ins.emit(GEvent.UpdateGameCoinNum);
this.initData(false, isFirstSelectWeapon);
if (this._skillSelectTreasureTrace) {
console.log('[SkillSelectTrace]', JSON.stringify({
step: 'onInit_done',
wave: gg.game.CurentBattle?.CurentWaveNum,
openTimes: gg.game.CurentBattle?.IsOpenSkillSelectTimes,
isSkillSelect: this._isSkillSelect,
skillCount: this.skills?.length ?? 0,
weaponCount: this.weapons?.length ?? 0,
}));
}
}
skills: ITableSkill[] = []
weapons: ITableWeapon2[] = []
tetriTypes: number[] = []
/** 救救我鸭:每个武器选项对应要替换的角色下标(优先 weaponid=1) */
private _yaCarrierIndices: number[] = [];
private _isSkillSelect: boolean = true;
private _itemBaseScale: Vec3 | null = null;
isFirstSelectWeapon = false
/** 打开失败时采集:三选一 skill/weapon id + 本局已拥有武器/技能 id(0 表示该项数据异常) */
getOpenFailContext(): Record<string, unknown> {
const battle = gg.game?.CurentBattle;
const curWeaponIds = battle?.CurUseWeaponArr?.map(w => w?.weaponid).filter(id => id != null) ?? [];
const curSkillIds = battle?.CurUseSkillArr?.map(s => s?.id).filter(id => id != null) ?? [];
const panelType = this._resolvePanelTypeForFailContext();
const isSkillPanel = panelType === 'skill';
return {
panelType,
pickSkillIds: isSkillPanel
? (this.skills?.map(s => (s && s.id != null) ? s.id : 0) ?? [])
: [],
pickWeaponIds: !isSkillPanel
? (this.weapons?.map(w => (w && w.weaponid != null) ? w.weaponid : 0) ?? [])
: [],
curWeaponIds,
curSkillIds,
};
}
/** initData 未完成时,按开箱次数推断当前应是技能箱还是武器箱 */
private _resolvePanelTypeForFailContext(): 'skill' | 'weapon' {
try {
if (this.isFirstSelectWeapon) {
return 'weapon';
}
const battle = gg.game?.CurentBattle;
if (!battle) {
return this._isSkillSelect ? 'skill' : 'weapon';
}
let arr = gg.data?.table?.getConstArray(ConstNumType.IsOpenSkillSelect) ?? [];
if (battle.BattleType == BattleType.OrangeWeaponMode_Dan) {
arr = [];
}
const isSkill = !arr.includes(battle.IsOpenSkillSelectTimes)
&& battle.BattleType != BattleType.SpeedMode
&& !this.isFirstSelectWeapon;
return isSkill ? 'skill' : 'weapon';
} catch {
return this._isSkillSelect ? 'skill' : 'weapon';
}
}
initData(isAd: boolean = false, isFirstSelectWeapon: boolean = false) {
if (!gg.game?.isBattleContextActive?.()) {
return;
}
let arr = gg.data.table.getConstArray(ConstNumType.IsOpenSkillSelect);
if(gg.game.CurentBattle.BattleType == BattleType.OrangeWeaponMode_Dan){
arr = []
//没有武器宝箱选择
}
this.isFirstSelectWeapon = isFirstSelectWeapon
const yaForce = gg.game.CurentBattle.BattleType == BattleType.OrangeWeaponMode_Ya
? gg.game.CurentBattle.luosiReplicaBoxForceType
: 0;
if (yaForce === 1) {
//this.isFirstSelectWeapon = true;
}
this._isSkillSelect = !arr.includes(gg.game.CurentBattle.IsOpenSkillSelectTimes)
&& gg.game.CurentBattle.BattleType != BattleType.SpeedMode && !this.isFirstSelectWeapon;
if (yaForce === 2) {
this._isSkillSelect = true;
}
if (yaForce === 1) {
this._isSkillSelect = false;
}
if (yaForce) {
gg.game.CurentBattle.luosiReplicaBoxForceType = 0;
}
if (this._isSkillSelect && !isFirstSelectWeapon) {
if (gg.data.doc.chapter == 1 && gg.game.CurentBattle.IsOpenSkillSelectTimes == 2 && gg.game.CurentBattle.curRogueSkillTimes == 0) {
if (!isAd) {
this.skills = gg.game.CurentBattle.SkillCore.getFirstRandomSkills()
} else {
this.skills = gg.game.CurentBattle.SkillCore.getSecondRandomSkills()
}
} else {
this.skills = gg.game.CurentBattle.SkillCore.randomSkills(3, isAd).map(x => x.skill);
}
} else {
if (gg.game.CurentBattle.BattleType == BattleType.OrangeWeaponMode_Ya) {
this.weapons = gg.game.CurentBattle.getJiujiuwoyaWeapons(isAd);
this._yaCarrierIndices = gg.game.CurentBattle.getJiujiuwoyaWeaponCarrierIndices(this.weapons.length);
} else {
this.weapons = gg.game.CurentBattle.getWeapons(isAd);
this._yaCarrierIndices = [];
}
this.tetriTypes = [];
// console.log('this.weapons', this.weapons)
if (gg.game.CurentBattle.BattleType != BattleType.SpeedMode
&& gg.game.CurentBattle.BattleType != BattleType.OrangeWeaponMode_Dan
&& gg.game.CurentBattle.BattleType != BattleType.OrangeWeaponMode_Ya) {
for (let i = 0; i < this.weapons.length; i++) {
this.tetriTypes.push(gg.game.CurentBattle.getTetrTypeRandom());
}
} else {
const n = Math.max(this.weapons.length, 3);
if (gg.game.CurentBattle.BattleType != BattleType.OrangeWeaponMode_Ya) {
this.tetriTypes = MTools.getRandomElements([1, 2, 3, 4, 5, 6], n);
}
if(gg.game.CurentBattle.BattleType == BattleType.OrangeWeaponMode_Dan){
this.tetriTypes = gg.game.CurentBattle.ModechooseTetriType
console.log('this.tetriTypes', this.tetriTypes)
}
}
}
this.updateUI()
}
updateUI() {
const content = this.ui_content;
if (!content) return;
// 连续开宝箱/快速刷新时,item 可能正在做缩放 tween(scale.x=0→1)
// 若此时用 children[0] 作为模板 instantiate,会把“中途缩放”的 scale 克隆过去,导致新 item 偶现变小/变大
// 仅重置 children[0] 不够:当本次只展示 2 个时,第 3 个子节点被隐藏且不会进下方循环,其 tween 仍会继续并污染下次 instantiate
const kids = content.children.slice();
for (const node of kids) {
if (!node?.isValid) continue;
Tween.stopAllByTarget(node);
const si = node.getComponent(SkillSelectItem);
if (si) si.resetScale();
}
const tplNode = (this.ui_singleItem?.isValid ? this.ui_singleItem : content.children[0]) ?? null;
const tplItem = tplNode?.getComponent(SkillSelectItem) ?? null;
if (tplItem) {
if (!this._itemBaseScale) {
this._itemBaseScale = tplItem.getBaseScale();
}
if (this._itemBaseScale && tplNode?.isValid) {
tplNode.setScale(this._itemBaseScale.x, this._itemBaseScale.y, this._itemBaseScale.z);
}
}
for (let i = 0; i < this.ui_content.children.length; i++) {
let item = this.ui_content.children[i];
item.active = false;
}
if (this._isSkillSelect) {
for (let i = 0; i < this.skills.length; i++) {
let data = this.skills[i];
let n: Node = null;
if (i < this.ui_content.children.length) {
n = this.ui_content.children[i];
} else {
const proto = (this.ui_singleItem?.isValid ? this.ui_singleItem : this.ui_content.children[0]);
n = instantiate(proto);
n.parent = this.ui_content;
}
n.active = true;
const item = n.getComponent(SkillSelectItem);
if (item) {
item.resetScale();
item.setSkill(data);
} else if (this._itemBaseScale) {
n.setScale(this._itemBaseScale.x, this._itemBaseScale.y, this._itemBaseScale.z);
}
}
} else {
for (let i = 0; i < this.weapons.length; i++) {
let data = this.weapons[i];
let n: Node = null;
if (i < this.ui_content.children.length) {
n = this.ui_content.children[i];
} else {
const proto = (this.ui_singleItem?.isValid ? this.ui_singleItem : this.ui_content.children[0]);
n = instantiate(proto);
n.parent = this.ui_content;
}
n.active = true;
const item = n.getComponent(SkillSelectItem);
if (item) {
item.resetScale();
const ya = gg.game.CurentBattle.BattleType == BattleType.OrangeWeaponMode_Ya;
const carrierIdx = ya ? (this._yaCarrierIndices[i] ?? i) : this.tetriTypes[i];
item.setWeapon(data, carrierIdx);
if (gg.data.doc.chapter == 1 && gg.game.CurentBattle.curRogueWeaponTimes == 1) {
if (data.weaponid == WeaponType.FuWenTa) {
this.guideBtnNode = n
this.scheduleOnce(() => {
this.showNewGuide()
}, 0.1)
}
}
} else if (this._itemBaseScale) {
n.setScale(this._itemBaseScale.x, this._itemBaseScale.y, this._itemBaseScale.z);
}
}
}
if (this._isSkillSelect) {
this.lb_tittle.string = gg.lang.get('技能升级')//'技能升级'
this.lb_subTittle.string = gg.lang.get('请选择升级一个技能')//'请选择升级一个技能'
} else {
this.lb_tittle.string = gg.lang.get('武器升级')//'武器升级'
this.lb_subTittle.string = gg.lang.get('请选择升级一个武器')//'请选择升级一个武器'
if(gg.game.CurentBattle.BattleType == BattleType.SpeedMode || this.isFirstSelectWeapon) {
this.lb_tittle.string = gg.lang.get('武器选择')//'武器升级'
this.lb_subTittle.string = gg.lang.get('本局使用武器')//'请选择升级一个武器'
}
}
//设置按钮状态
let rogueFreeRefreshTimes = gg.game.CurentBattle.getRogueFreeRefreshTimes()
let rogueADRefreshTimes = gg.game.CurentBattle.getRogueADRefreshTimes()
let rogueFreeAllGetTimes = gg.game.CurentBattle.getRogueFreeAllGetTimes()
let rogueADAllGetTimes = gg.game.CurentBattle.getRogueADAllGetTimes()
this.btnRefresh.active = rogueFreeRefreshTimes > 0
this.btnRefreshAD.active = !this.btnRefresh.active && rogueADRefreshTimes > 0
this.btnAll.active = rogueFreeAllGetTimes > 0 && this._isSkillSelect && !this.btnRefresh.active;
this.btnADAll.active = !this.btnAll.active && rogueADAllGetTimes > 0 && this._isSkillSelect;
this.btnRefresh.getChildByName('leftTimes').getComponent(RichText).string = gg.lang.get('剩余{1}次', [rogueFreeRefreshTimes]) //`${rogueFreeRefreshTimes}`
this.btnRefreshAD.getChildByName('leftTimes').getComponent(RichText).string = gg.lang.get('剩余{1}次', [rogueADRefreshTimes]) //`${rogueADRefreshTimes}`
this.btnAll.getChildByName('leftTimes').getComponent(RichText).string = gg.lang.get('剩余{1}次', [rogueFreeAllGetTimes]) //`${rogueFreeAllGetTimes}`
this.btnADAll.getChildByName('leftTimes').getComponent(RichText).string = gg.lang.get('剩余{1}次', [rogueADAllGetTimes]) //`${rogueADAllGetTimes}`
if (this._isSkillSelect && gg.game.CurentBattle.ChapterId == 1) {
this.ui_dianji.active = this.btnRefresh.active
}
if (this._isSkillSelect && gg.game.CurentBattle.ChapterId == 1) {
this.ui_dianjiAll.active = this.btnAll.active
}
//curRogueWeaponTimes == 0隐藏按钮
if (this._isSkillSelect) {
if (gg.game.CurentBattle.curRogueSkillTimes == 0 && gg.game.CurentBattle.ChapterId == 1 && gg.game.CurentBattle.Difficulty == ChapterDifficulty.Normal) {
// this.btnRefreshAD.active = false
// this.btnAll.active = false
// this.btnADAll.active = false
//console.log('gg.game.CurentBattle.curRogueSkillTimes111', gg.game.CurentBattle.curRogueSkillTimes)
}
} else {
if (gg.game.CurentBattle.curRogueWeaponTimes == 1 && gg.game.CurentBattle.ChapterId == 1 && gg.game.CurentBattle.Difficulty == ChapterDifficulty.Normal) {
this.btnRefreshAD.active = false
this.btnAll.active = false
this.btnADAll.active = false
this.btnRefresh.active = false
this.btnSure.active = false;
//console.log('gg.game.CurentBattle.curRogueWeaponTimes222', gg.game.CurentBattle.curRogueWeaponTimes)
}
if (gg.game.CurentBattle.BattleType == BattleType.SpeedMode || this.isFirstSelectWeapon) {
this.btnRefreshAD.active = false
this.btnAll.active = false
this.btnADAll.active = false
this.btnRefresh.active = false
this.btnSure.active = true;
}
}
}
click_btnADAll(): void {
gg.sdk.showVideoAd((res) => {
if (res) {
let curWaveNum = gg.game.CurentBattle.CurentWaveNum
gg.sdk.reportDY("inLevel", `章节${gg.game.CurentBattle.getReportDYChapterId()}_${curWaveNum}-AD-技能全都要`)
gg.game.CurentBattle.subRogueADAllGetTimes()
this.getAll();
gg.game.CurentBattle.IsWatchAd = true
gg.PRR.AdClickNum.push(2)
} else {
gg.ui.showToast("观看视频失败");
}
});
}
click_btnAll(): void {
//白银宝箱
gg.game.CurentBattle.subRogueFreeAllGetTimes()
this.getAll();
gg.sdk.reportDY("inLevel", `章节${gg.game.CurentBattle.getReportDYChapterId()}_${gg.game.CurentBattle.CurentWaveNum}-免费技能全都要`)
}
click_btnRefresh(): void {
gg.game.CurentBattle.subRogueFreeRefreshTimes()
gg.sdk.reportDY("inLevel", `章节${gg.game.CurentBattle.getReportDYChapterId()}_${gg.game.CurentBattle.CurentWaveNum}-免费技能刷新`)
this.initData(true);
}
click_btnRefreshAD(): void {
gg.sdk.showVideoAd((res) => {
if (res) {
let curWaveNum = gg.game.CurentBattle.CurentWaveNum
gg.sdk.reportDY("inLevel", `章节${gg.game.CurentBattle.getReportDYChapterId()}_${curWaveNum}-AD-技能刷新`)
gg.game.CurentBattle.subRogueADRefreshTimes()
gg.game.CurentBattle.IsWatchAd = true
gg.PRR.AdClickNum.push(1)
this.initData(true);
} else {
gg.ui.showToast("观看视频失败");
}
});
}
click_btnSure(): void {
if (this.isFirstSelectWeapon && gg.game.CurentBattle.BattleType == BattleType.OrangeWeaponMode_Dan) {
this.getAll();
}
this.close();
}
getAll() {
if (this._isSkillSelect) {
gg.game.CurentBattle.addCurRogueSkillTimes();
gg.game.CurentBattle.addCurHaveSkillArr(this.skills);
//判断是抽卡副本
if (gg.game.CurentBattle.BattleType == BattleType.GachaMode) {
GEvent.Ins.emit(GEvent.AddSkillIcon, this.skills);
}
} else {
gg.game.CurentBattle.addCurRogueWeaponTimes();
const ya = gg.game.CurentBattle.BattleType == BattleType.OrangeWeaponMode_Ya;
for (let i = 0; i < this.weapons.length; i++) {
if (ya) {
const idx = this._yaCarrierIndices[i] ?? i;
gg.game.CurentBattle.changeJiujiuwoyaWeapon(idx, this.weapons[i].weaponid);
} else {
gg.game.CurentBattle.changeTetriWeaponConfig(this.tetriTypes[i], this.weapons[i].weaponid);
}
}
//判断是抽卡副本
if (gg.game.CurentBattle.BattleType == BattleType.GachaMode) {
GEvent.Ins.emit(GEvent.AddWeaponIcon, this.weapons.map(x => x.weaponid));
}
// 全选武器:预热各武器子弹 + hitEffect 爆炸
BattleResLoader.preloadWeaponCombatAssetsBatch(this.weapons);
}
this.close();
}
showNewGuide(idx: number = 0) {
if (gg.data.doc.chapter == 1 && gg.game.CurentBattle.curRogueWeaponTimes == 1) {
//引导
gg.ui.openPanel(UIID.NewGuideMask, {
data: [
[this.guideBtnNode],
[''],
() => {
//gg.data.setStatistics(StatisticsType.firstChapterGuideIndex, 2)
},
true,
255
]
});
}
// if (gg.game.CurentBattle.Difficulty != ChapterDifficulty.Normal) {
// return
// }
// let curRogueSkillTimes = gg.game.CurentBattle.curRogueSkillTimes
// if (idx == 1 && gg.game.CurentBattle.ChapterId == 1 && this.rogueType == MonsterType.SilverBoss && curRogueSkillTimes == 0) {//&& gg.data.getLocalGuideValue('引导刷新技能') == '0'
// // gg.data.setLocalGuideValue('引导刷新技能', '1')
// // BeginnerGuideManager 会吞掉触摸,底层 btnRefresh 收不到点击,需在回调里补发一次刷新
// // 引导镂空/层级下,同一触摸可能先命中按钮再进回调,会触发两次 click_btnRefresh:引导期间先卸掉按钮监听
// this.btnRefresh.off(Node.EventType.TOUCH_END, this.click_btnRefresh, this)
// this.ui_guideMask.active = true
// let firstNode = this.btnRefresh//this.ui_guideMask.getChildByName('freeRefreshPos')
// let guideActionApplied = false
// let finishCallBack = () => {
// if (guideActionApplied) return
// guideActionApplied = true
// this.ui_guideMask.active = false
// this.click_btnRefresh()
// //this.btnRefresh.on(Node.EventType.TOUCH_END, this.click_btnRefresh, this)
// }
// this.ui_guideMask.getComponent(BeginnerGuideManager).setIsGuideClick(BeginnerGuideType.DIANJI)
// this.ui_guideMask.getComponent(BeginnerGuideManager).setBindNode(firstNode, finishCallBack,
// gg.lang.get('刷新更高概率获得技能'), 1, 1200)
// } else if (idx == 3 && gg.game.CurentBattle.ChapterId == 1 && this.rogueType == MonsterType.SilverBoss && curRogueSkillTimes == 0) {//&& gg.data.getLocalGuideValue('引导选择第一个技能') == '0'
// // BeginnerGuideManager 会吞掉触摸,底层 SkillSelectItem 收不到点击,需在回调里补发 onClick
// // 同一触摸若先穿透到首张卡片会触发 onClick,再进回调会双选:仅对引导绑定的那张卡卸监听
// this.ui_guideMask.active = true
// let firstNode = this.ui_content.children[0]
// let firstItem = firstNode?.getComponent(SkillSelectItem)
// if (firstItem) {
// firstNode.off(Node.EventType.TOUCH_END, firstItem.onClick, firstItem)
// }
// let guideActionApplied = false
// let finishCallBack = () => {
// if (guideActionApplied) return
// guideActionApplied = true
// this.ui_guideMask.active = false
// let item = firstNode?.getComponent(SkillSelectItem)
// if (item?.node?.isValid && item.Skill) {
// item.onClick()
// }
// }
// this.ui_guideMask.getComponent(BeginnerGuideManager).setIsGuideClick(BeginnerGuideType.DIANJI)
// this.ui_guideMask.getComponent(BeginnerGuideManager).setBindNode(firstNode, finishCallBack,
// gg.lang.get('品质更好更强'), 1, 1200)
// }
}
}