/** @format */ import {BaseUI} from './BaseUI' import {ccUtils} from '../utils/ccUtils' import {Data, Mgr} from '../GameControl' import List from '../uiutils/List' import {RanksLevelConfig} from '../config/RanksLevelConfig' import {list, node, observer} from '../mobx/observer' import {ITalentConfig, TalentConfig} from '../config/TalentConfig' import {DIS_ID, GOODS, LANGUAGE_TYPE} from '../enums/Enum' import {talentActivate, talentActivateRsp} from '../proto/game' import {msgCmd} from '../proto/msg_cmd' import {GoodsConfig} from '../config/GoodsConfig' import {UI} from '../enums/UI' import {DataConfig} from '../config/DataConfig' import {IOperateNeed, IRole} from '../interface/GlobalInterface' import {IRoleLevelConfig, RoleLevelConfig} from '../config/RoleLevelConfig' import {idNum} from '../proto/typedef' import {RoleQualityConfig} from '../config/RoleQualityConfig' const {ccclass, property} = cc._decorator interface ITalentData { talents: ITalentConfig[] bigTalent: ITalentConfig } enum TALENT_TYPE { normal = 1, big, } @ccclass @observer export default class TalentUI extends BaseUI { // 用于显示对应天赋的说明 @node('tp/tip') talTip: cc.Node @node('tp') tpAll: cc.Node // 天赋界面天赋和技能列表 - ScrollView @list('tal_sv') talentViewList: List levelData: ITalentData[] = [] chooseTalent: number chooseTalentNode: cc.Node lastBigActiveLv: number = 0 lastActiveLv: number = 0 nextCanActiveSmallID: number = -1 nextCanActiveBigID: number = -1 lastPower: number /********************** 周期事件 **********************/ // LIFE-CYCLE CALLBACKS: onLoad() { // 天赋说明 this.tpAll.active = false this.levelData.length = 0 let keys = Object.keys(TalentConfig) let maxLv = 0 for (let i = keys.length - 1; i >= 0; i++) { if (TalentConfig[keys[i]].talentType == TALENT_TYPE.normal) { maxLv = TalentConfig[keys[i]].lv break } } maxLv = DataConfig[DIS_ID.maxLv].data3 this.levelData = new Array(maxLv).fill(null) for (let key in TalentConfig) { let cfg = TalentConfig[key] if (cfg.lv <= maxLv) { if (!this.levelData[cfg.lv - 1]) this.levelData[cfg.lv - 1] = {talents: [], bigTalent: null} if (cfg.talentType == TALENT_TYPE.normal) { this.levelData[cfg.lv - 1].talents.push(cfg) } else if (cfg.talentType == TALENT_TYPE.big) { this.levelData[cfg.lv - 1].bigTalent = cfg } } } this.initMaxBigLv() } onEnable() { Mgr.global.initPower() this.initNextActiveID() Mgr.net.add(msgCmd.cmd_talent_activate_rsp, this, this.onTalentActivateRsp) ccUtils.setLabel('lv.' + Data.user.level, this.node, 'lv_lb') // 设置玩家当前等级的经验条(0-1之间) ccUtils.setProgress(Data.user.exp / RanksLevelConfig[Data.user.level].exp, this.node, 'lv_pb') //前面有一个空节点占位 this.talentViewList.numItems = this.levelData.length + 1 this.talentViewList.scrollTo(this.lastActiveLv - 1 >= 0 ? this.lastActiveLv - 1 : 0) Mgr.ui.showTop(this, [GOODS.coin, GOODS.diamond, GOODS.talentCoin]) //天赋引导,升级第一个大天赋 Mgr.global.tryShowUserGuide(['12_3'], () => { this.chooseTalent = Object.values(TalentConfig).find(value => value.talentType == TALENT_TYPE.big).ID let targetNode = this.talentViewList.content.children.find(v => cc.find('sk', v).active) this.chooseTalentNode = cc.find('sk', targetNode) this.onBuyClick() }) } onHide() { this.tpAll.active = false Mgr.event.removeAll(this) } initMaxBigLv() { this.lastBigActiveLv = 0 this.lastActiveLv = 0 Data.user.talents.forEach(v => { let cfg = TalentConfig[v] if (cfg.talentType == TALENT_TYPE.big && cfg.lv > this.lastBigActiveLv) this.lastBigActiveLv = cfg.lv if (cfg.talentType == TALENT_TYPE.normal && cfg.lv > this.lastActiveLv) this.lastActiveLv = cfg.lv }) } initNextActiveID() { let cfgArr = Mgr.goods.getNextCanActiveTalents() this.nextCanActiveSmallID = cfgArr[0] ? cfgArr[0].ID : -1 this.nextCanActiveBigID = cfgArr[1] ? cfgArr[1].ID : -1 } initTalentViewList(node: cc.Node, index: number) { cc.find('pb', node).active = index < this.lastBigActiveLv index -= 1 node.children.forEach(v => { if (v.name != 'pb') { v.active = index >= 0 } }) if (index < 0) return let isMaxLv = index == this.levelData.length - 1 let levelViewData = this.levelData[index] ccUtils.setLabel((index + 1).toString(), node, 'lv_lb') let talents = cc.find('s_tal', node).children // 遍历当前级别所有天赋,判断哪些天赋需要激活 let smallAllActive = true for (let i = 0; i < talents.length; i++) { let hasActiveTalent = Data.user.talents.includes(levelViewData.talents[i].ID) smallAllActive &&= hasActiveTalent let talent = talents[i] let isLastTal = i == talents.length - 1 ccUtils.setSpriteGray(!hasActiveTalent, talent, 'icon') cc.find('bg', talent).active = !(isLastTal && isMaxLv) cc.find('pb', talent).active = hasActiveTalent && !(isLastTal && isMaxLv) cc.find('red_dots', talent).active = levelViewData.talents[i].ID == this.nextCanActiveSmallID && Mgr.goods.getOperateNeed(Mgr.goods.getLongIdNumByCfgArr(levelViewData.talents[i].goods)).canUp && levelViewData.talents[i].lv <= Data.user.level this.loadTexImg(`TalentUI/icon/${levelViewData.talents[i].icon}`, talent, 'icon') talent['cfgID'] = levelViewData.talents[i].ID } cc.find('bright_bottom', node).active = smallAllActive let bigTalent = cc.find('sk', node) bigTalent.active = !!levelViewData.bigTalent let hasActiveBigTalent = levelViewData.bigTalent && Data.user.talents.includes(levelViewData.bigTalent.ID) if (bigTalent.active) { bigTalent['cfgID'] = levelViewData.bigTalent.ID cc.find('red_dots', bigTalent).active = levelViewData.bigTalent.ID == this.nextCanActiveBigID && Mgr.goods.getOperateNeed(Mgr.goods.getLongIdNumByCfgArr(levelViewData.bigTalent.goods)).canUp && levelViewData.bigTalent.lv <= Data.user.level this.loadTexImg(`TalentUI/icon/${levelViewData.bigTalent.icon}`, bigTalent, 'icon') ccUtils.setSpriteGray(!hasActiveBigTalent, bigTalent, 'icon') } } initTalentTip() { let cfg: ITalentConfig = TalentConfig[this.chooseTalent] let lvCan = Data.user.level >= cfg.lv let lastActive = !cfg.condition || Data.user.talents.includes(cfg.condition) let isActive = Data.user.talents.includes(this.chooseTalent) cc.find('has', this.talTip).active = isActive ccUtils.setLabel(Mgr.i18n.getEntryLabel(cfg.entryID), this.talTip, 'scrollView/view/content/label') let canBuy = cc.find('canBuy', this.talTip) canBuy.active = !isActive && lvCan && lastActive if (canBuy.active) { this.loadTexImg(`Public/goods/${GoodsConfig[cfg.goods[0]].icon}`, canBuy, 'goods_icon') ccUtils.setLabel(`${Math.toKMBNum(cfg.goods[1])}`, canBuy, 'goods_num') } let lock = cc.find('lock', this.talTip) lock.active = !isActive && (!lvCan || !lastActive) if (lock.active) { ccUtils.setLabel( `${Mgr.i18n.getLabel(lvCan ? LANGUAGE_TYPE.unlockLastTalent : LANGUAGE_TYPE.lvUnlock, [ cfg.lv.toString(), ])}`, lock, 'label', ) } } /********************** 网络事件 **********************/ onTalentActivateRsp(data: talentActivateRsp) { ccUtils.playAni( TalentConfig[data.id].talentType == TALENT_TYPE.normal ? 'activeSmall' : 'activeBig', 0, this.chooseTalentNode, 'activeAni', ) Data.user.talents.push(data.id) Mgr.global.initTalentAdd() this.initNextActiveID() Data.user.roles.forEach(iRole => { Mgr.global.buildIRole(iRole.hero, iRole) }) Data.user.cards.forEach(iCard => { Mgr.global.buildICard(iCard.card, iCard) }) Mgr.global.updatePower() this.initMaxBigLv() this.initTalentTip() this.tpAll.active = false this.talentViewList.numItems = this.levelData.length + 1 } /********************** 触发事件 **********************/ /********************** 点击事件 **********************/ onTalentClick(e) { // 点击天赋时,弹出天赋说明 this.tpAll.active = true let node = e.currentTarget this.chooseTalent = node['cfgID'] this.chooseTalentNode = node this.initTalentTip() let cfg: ITalentConfig = TalentConfig[this.chooseTalent] let pos = ccUtils.convertNode2NodePosAR(node, this.talTip.parent) let isLeft = pos.x < 500 let bg = cc.find('bg', this.talTip) bg.scaleX = isLeft ? 1 : -1 bg.x = isLeft ? -12 : 0 this.talTip.setPosition(pos.add(cc.v2(250 * bg.scaleX, cfg.talentType == TALENT_TYPE.normal ? 0 : 20))) } onBuyClick() { if (this.chooseTalent) { let cfg: ITalentConfig = TalentConfig[this.chooseTalent] let hasNum = Data.user.goods.get(cfg.goods[0]) if (hasNum >= cfg.goods[1]) { let data: talentActivate = {id: this.chooseTalent} Mgr.net.send(msgCmd.cmd_talent_activate, data) } else { let idNum = Mgr.goods.getLongIdNumByCfgArr(cfg.goods) let operate = Mgr.goods.getOperateNeed(idNum) Mgr.ui.showObtain(operate) } } } onTipClick() { // 天赋说明弹框被点击时响应 this.tpAll.active = false } }