/** @format */ import {UI} from '../enums/UI' import {BaseUI} from './BaseUI' import {Data, Mgr} from '../GameControl' import {ccUtils} from '../utils/ccUtils' import {observer, render, node, label, editBox, list} from '../mobx/observer' import {msgCmd} from '../proto/msg_cmd' import {DIS_ID, EVENT, GOODS, RECRUIT_TYPE, LANGUAGE_TYPE, PREFAB_TYPE, MOD, AD_ID} from '../enums/Enum' import List from '../uiutils/List' import {hero, manual, drawInfo, idNum, drawAwardInfo} from '../proto/typedef' import {drawGetDataRsp, drawRsp} from '../proto/game' import {HeroescallConfig, IHeroescallConfig} from '../config/HeroescallConfig' import {CallawardConfig} from '../config/CallawardConfig' import {RoleConfig} from '../config/RoleConfig' import {CardConsumeConfig} from '../config/CardConsumeConfig' import {DataConfig} from '../config/DataConfig' import {i18nLabel} from '../uiutils/i18nLabel' import {IReward, IRewardNty, ItemUICfg} from '../interface/UIInterface' import {SOUND} from '../enums/Sound' import FrameAnimation from '../uiutils/FrameAnimation' const {ccclass, property} = cc._decorator enum DRAW_TYPE { //抽卡类型 rare = 1, //高级英雄 normal = 2, //普通英雄 forging = 3, //装备 } enum PAY_TYPE { //抽奖付费方式 free = 1, scroll = 2, currency = 3, } enum IRecruitAnim_TYPE { //动画id forgingIdle = 'forgingIdle', //锻造待机动画 forge = 'forging', //锻造动画 magicBookIdle = 'magicBookIdle', //高级召唤待机动画 rareSummoning = 'rareSummoning', //高级召唤动画 normalIdle = 'normalIdle', //普通召唤待机动画 normalSummoning = 'normalSummoning', //普通召唤动画 } interface HEROIC_RANK { //英雄等级 index: number color: string heroI18n: string equipI18n: string } /** 抽卡类型数据 */ interface RecruitType { id: number i18n: string } interface HeroesCallConfig { ID: number //奖池 points: number //库ID type: number //召唤类型 priority: number //显示顺序 quality: number //品质 } @ccclass @observer export class RecruitUI extends BaseUI { @node('summoning') summoningNode: cc.Node @node('summoning/normal') normalNode: cc.Node @node('summoning/rare') rareNode: cc.Node @node('forging') forgingNode: cc.Node @node('summon_list') summonNode: cc.Node @node('chain_list') chainList: cc.Node @node('forging/ani') forgingAni: cc.Node @node('summoning/rare/ani') rareAni: cc.Node @node('summoning/normal/ani') normalAni: cc.Node @node('quick_ani') //点击快速关闭动画 quickCloseAni: cc.Node recruitTypeList: RecruitType[] = [ //抽卡功能-抽卡类型 {id: RECRUIT_TYPE.summoning, i18n: LANGUAGE_TYPE.summoning}, //英雄召唤 {id: RECRUIT_TYPE.forging, i18n: LANGUAGE_TYPE.forging}, //装备锻造 ] RecruitAwardList: drawAwardInfo[] curSelectType: number = this.recruitTypeList[0].id // 当前选择显示的界面 curShowPublicity: HeroesCallConfig[] = [] normaScrollNum: number //普通卷轴数量 rareScrollNum: number //高级卷轴数量 equipScrollNum: number //锻造卷轴数量 drawNum: number = 10 //一次性连抽数量 hero: drawInfo hero2: drawInfo equip: drawInfo normaDrawGoods: number = DataConfig[DIS_ID.normalSummon].data1 //英雄普通召唤消耗道具 rareDrawGoods: number = DataConfig[DIS_ID.rareSummon].data1 //英雄高级召唤消耗道具 equipFreeNum: number = DataConfig[DIS_ID.equipSummon].data1 //每日免费装备锻造次数 normaDrawNum: number = DataConfig[DIS_ID.normalSummon].data2 //普通召唤-单抽消耗道具数量 rareDrawNum: number = DataConfig[DIS_ID.rareSummon].data2 //高级召唤-单抽消耗道具数量 equipDrawNum: number = DataConfig[DIS_ID.equipSummon].data2 //装备锻造-单抽消耗道具数量 normaFreeNum: number = DataConfig[DIS_ID.normalSummon].data3 //每日免费普通召唤次数 rareDrawLimit: number = DataConfig[DIS_ID.rareSummon].data3 //每日高级召唤次数限制 equipDrawLimit: number = DataConfig[DIS_ID.equipSummon].data3 //每日装备锻造次数限制 normaDrawLimit: number = DataConfig[DIS_ID.normalSummon].data4 //普通召唤每日次数上限 rareTenDraw: number = DataConfig[DIS_ID.rareSummon].data4 //十连高级召唤钻石消耗 equipDrawGoods: number = DataConfig[DIS_ID.equipSummon].data4 //锻造召唤消耗道具 curNormaDraw: number = DataConfig[DIS_ID.normalSummon].data2 //默认单抽数量-会随自己物品数量变动 curRareDraw: number = DataConfig[DIS_ID.rareSummon].data2 //高级召唤-单抽消耗道具数量 curEquipDraw: number = DataConfig[DIS_ID.equipSummon].data2 //默认单抽数量-会随自己物品数量变动 animForging: cc.Animation animRareSummoning: cc.Animation animNormalSummoning: cc.Animation curSummonType: DRAW_TYPE onShow(args: number = this.recruitTypeList[0].id, fromUI: number) { //招募引导,招募按钮 cc.find('guide', this.node).active = Mgr.global.tryShowUserGuide(['20_3']) //抽奖数据 Mgr.net.add(msgCmd.cmd_draw_get_data_rsp, this, this.onDrawGetRsp) //抽奖数据 Mgr.net.add(msgCmd.cmd_draw_rsp, this, this.onDrawRsp) Mgr.net.send(msgCmd.cmd_draw_get_data) //从右到左显示货币 Mgr.ui.showTop(this, [GOODS.diamond, GOODS.coin, GOODS.normalDrawScroll, GOODS.rarelDrawScroll]) this.curSelectType = this.recruitTypeList[0].id // 默认打开第一个界面 不记录玩家上次的留存的记录 this.initShowData() if (!ccUtils.isEmpty(args)) this.curSelectType = args //默认打开那个界面 this.initAni() } initAni() { this.animForging = this.forgingAni.getComponent(cc.Animation) this.animRareSummoning = this.rareAni.getComponent(cc.Animation) this.animNormalSummoning = this.normalAni.getComponent(cc.Animation) //播放已经暂停的动画 ccUtils.playAni(IRecruitAnim_TYPE.forgingIdle, 0, this.forgingAni) ccUtils.playAni(IRecruitAnim_TYPE.magicBookIdle, 0, this.rareAni) ccUtils.playAni(IRecruitAnim_TYPE.normalIdle, 0, this.normalAni) let initIdle = (tmpAni: cc.Animation, type: IRecruitAnim_TYPE, node: cc.Node) => { // 为动画添加结束回调 tmpAni.on( 'finished', function () { ccUtils.playAni(type, 0, node) this.showRewardUI() }, this, ) } initIdle(this.animForging, IRecruitAnim_TYPE.forgingIdle, this.forgingAni) //播放锻造待机动画 initIdle(this.animRareSummoning, IRecruitAnim_TYPE.magicBookIdle, this.rareAni) //播放高级抽卡待机动画 initIdle(this.animNormalSummoning, IRecruitAnim_TYPE.normalIdle, this.normalAni) //播放普通抽卡待机动画 } onHide(): any { // 为动画添加结束回调 this.animForging.off('finished') this.animRareSummoning.off('finished') this.animNormalSummoning.off('finished') ccUtils.stopAni(this.forgingAni, IRecruitAnim_TYPE.forge) ccUtils.stopAni(this.rareAni, IRecruitAnim_TYPE.rareSummoning) ccUtils.stopAni(this.normalAni, IRecruitAnim_TYPE.normalSummoning) ccUtils.setTogglesChecked(RECRUIT_TYPE.summoning, this.summonNode) Mgr.event.removeAll(this) } //UI或者其他函数======================================= //显示界面对应数据 initShowData() { let diamond = cc.find('btn_diamond/num', this.rareNode) let normaI18n = cc.find('btn_summoning/lb', this.normalNode) let rareI18n = cc.find('btn_summoning/lb', this.rareNode) let equipI18n = cc.find('btn_summoning/lb', this.forgingNode) this.normaScrollNum = Data.user.goods.get(this.normaDrawGoods) this.rareScrollNum = Data.user.goods.get(this.rareDrawGoods) this.equipScrollNum = Data.user.goods.get(this.equipDrawGoods) let normaStr = this.normaScrollNum >= this.drawNum ? this.drawNum.toString() : this.normaDrawNum.toString() let rareStr = this.rareScrollNum >= this.drawNum ? this.drawNum.toString() : this.rareDrawNum.toString() let equipStr = this.equipScrollNum >= this.drawNum ? this.drawNum.toString() : this.equipDrawNum.toString() normaI18n.getComponent(i18nLabel).setParamByIndex(normaStr, 0) rareI18n.getComponent(i18nLabel).setParamByIndex(rareStr, 0) equipI18n.getComponent(i18nLabel).setParamByIndex(equipStr, 0) this.curNormaDraw = this.normaScrollNum >= this.drawNum ? this.drawNum : this.normaDrawNum this.curRareDraw = this.rareScrollNum >= this.drawNum ? this.drawNum : this.rareDrawNum this.curEquipDraw = this.equipScrollNum >= this.drawNum ? this.drawNum : this.equipDrawNum ccUtils.setColor(Data.user.goods.get(GOODS.diamond) >= this.rareTenDraw ? '#00FF00' : '#FF2525', diamond) ccUtils.setLabel(this.rareTenDraw.toString(), diamond) //高级召唤十连抽的钻石数量 this.updShowInterface() } //刷新界面显示 updShowInterface() { //显示抽卡界面还是锻造界面 this.summoningNode.active = this.curSelectType == RECRUIT_TYPE.summoning this.forgingNode.active = this.curSelectType == RECRUIT_TYPE.forging cc.find('toggle2', this.summonNode).active = Mgr.global.checkModOpen(MOD.equipGet) this.chainList.children[0].active = Mgr.global.checkModOpen(MOD.equipGet) ccUtils.setTogglesChecked(this.curSelectType, this.summonNode) } //更新当前界面的红点提示 updShowRedDots() { for (let i = 0; i < this.summonNode.childrenCount; i++) { let item = this.summonNode.children[i] if (this.recruitTypeList[i].id == RECRUIT_TYPE.summoning && this.hero2) { let normalFree = this.normaFreeNum - this.hero2.free //免费次数 //普通英雄抽卡或高级英雄抽卡满足10连抽就提示问题 cc.find('red_dots', item).active = this.normaScrollNum >= this.drawNum || this.rareScrollNum >= this.drawNum || normalFree > 0 } else if (this.recruitTypeList[i].id == RECRUIT_TYPE.forging && this.equip) { //装备满足10连抽或者有免费的就提示红点 cc.find('red_dots', item).active = this.equipFreeNum - this.equip.free > 0 || this.equipScrollNum >= this.drawNum } } cc.find('btn_free/red_dots', this.normalNode).active = this.normaFreeNum - this.hero2.free > 0 //如果普通召唤有免费的就提示十连 cc.find('btn_summoning/red_dots', this.normalNode).active = this.normaScrollNum >= this.drawNum //如果普通召唤的卷轴有十连就提示红点 cc.find('btn_summoning/red_dots', this.rareNode).active = this.rareScrollNum >= this.drawNum //如果高级召唤的卷轴大于10就显示红点 cc.find('btn_free/red_dots', this.forgingNode).active = this.equipFreeNum - this.equip.free > 0 //如果有免费次数就显示红点 cc.find('btn_summoning/red_dots', this.forgingNode).active = this.equipScrollNum >= this.drawNum //如果装备的十连够了就提示红点 //cc.find('btn_free/red_dots', this.forgingNode).active = this.equipFreeNum - this.equip. > 0 } //更新装备抽奖的保底数量 updEquipNum(list: number[]) { if (list[0]) cc.find('rarelb', this.forgingNode).getComponent(i18nLabel).setParamByIndex(list[0].toString(), 0) if (list[1]) cc.find('elitelb', this.forgingNode).getComponent(i18nLabel).setParamByIndex(list[1].toString(), 0) } showRewardUI() { this.quickCloseAni.active = false let idNumArr: idNum[] = [] let itemUICfgArr: ItemUICfg[] = [] for (let award of this.RecruitAwardList) { idNumArr.push({id: award.id, num: award.num}) itemUICfgArr.push({changeQuality: award.quality, showDetails: true}) } let rewardArgs: IReward = {idNumArr, itemUICfgArr} Mgr.ui.show(UI.RewardUI, rewardArgs) } //网络事件======================================= onDrawGetRsp(data: drawGetDataRsp) { this.hero2 = data.hero2 ? data.hero2 : drawGetDataRsp.create().hero2 this.hero = data.hero ? data.hero : drawGetDataRsp.create().hero this.equip = data.equip ? data.equip : drawGetDataRsp.create().equip let setColor = (num: number, node: cc.Node) => { ccUtils.setColor(num > 0 ? '#BAFF27' : '#FF2525', node, 'residue_lb') ccUtils.setLabel(num.toString(), node, 'residue_lb') //剩余次数 } let setLabel = (str: number, str2: number, node: cc.Node) => { ccUtils.setLabel((str2 - str).toString(), node, 'summ_residue_lb') //当前抽奖次数 ccUtils.setLabel('/' + str2, node, 'summ_max_lb') //最大抽奖数据 } setColor(this.normaFreeNum - this.hero2.free, this.normalNode) //免费次数 setColor(this.equipFreeNum - this.equip.free, this.forgingNode) //免费次数 setLabel(this.hero2.daily, this.normaDrawLimit, this.normalNode) setLabel(this.hero.daily, this.rareDrawLimit, cc.find('lbs', this.rareNode)) setLabel(this.equip.daily, this.equipDrawLimit, this.forgingNode) if (this.equip.list.length > 0) { this.updEquipNum(this.equip.list) } this.updShowRedDots() //刷新当前界面红点提示 this.updShowInterface() //刷新选中颜色 } //抽卡结果 onDrawRsp(data: drawRsp, rewardNty: IRewardNty) { //如果是普通抽奖 if (data.drawType == DRAW_TYPE.normal) { ccUtils.playAni(IRecruitAnim_TYPE.normalSummoning, 0, this.normalAni) this.hero2 = data let normalFree = this.normaFreeNum - this.hero2.free //免费次数 ccUtils.setLabel((this.normaDrawLimit - this.hero2.daily).toString(), this.normalNode, 'summ_residue_lb') //当前抽奖次数 ccUtils.setColor(normalFree > 0 ? '#BAFF27' : '#FF2525', this.normalNode, 'residue_lb') ccUtils.setLabel(normalFree.toString(), this.normalNode, 'residue_lb') //剩余次数 } else if (data.drawType == DRAW_TYPE.rare) { ccUtils.playAni(IRecruitAnim_TYPE.rareSummoning, 0, this.rareAni) this.hero = data ccUtils.setLabel((this.rareDrawLimit - this.hero.daily).toString(), this.rareNode, 'lbs/summ_residue_lb') //当前抽奖次数 } else if (data.drawType == DRAW_TYPE.forging) { ccUtils.playAni(IRecruitAnim_TYPE.forge, 0, this.forgingAni) this.equip = data let equipFree = this.equipFreeNum - this.equip.free //免费次数 ccUtils.setLabel((this.equipDrawLimit - this.equip.daily).toString(), this.forgingNode, 'summ_residue_lb') //当前抽奖次数 ccUtils.setColor(equipFree > 0 ? '#BAFF27' : '#FF2525', this.forgingNode, 'residue_lb') ccUtils.setLabel(equipFree.toString(), this.forgingNode, 'residue_lb') //剩余次数 if (this.equip.list.length > 0) { this.updEquipNum(this.equip.list) } } this.quickCloseAni.active = true this.initShowData() this.updShowRedDots() //刷新红点提示 this.RecruitAwardList = data.awardList } //触发事件======================================= // @render // showRender() {} // 点击事件======================================= //英雄抽奖 onClickSummon(event) { Mgr.audio.playSFX(SOUND.toggleClick) this.curSelectType = RECRUIT_TYPE.summoning Mgr.ui.showTop(this, [GOODS.diamond, GOODS.coin, GOODS.normalDrawScroll, GOODS.rarelDrawScroll]) this.updShowInterface() } //装备锻造 onClickForging(event) { Mgr.audio.playSFX(SOUND.toggleClick) this.curSelectType = RECRUIT_TYPE.forging Mgr.ui.showTop(this, [GOODS.diamond, GOODS.coin, this.equipDrawGoods]) this.updShowInterface() } //公示英雄抽卡库 onClickPublicity(event: cc.Button, data: number) { this.curShowPublicity = [] for (let key in HeroescallConfig) { let heroCfg = HeroescallConfig[key] let CallCfg = CallawardConfig[heroCfg.points] if (heroCfg.type == data && CallCfg && CallCfg.odds > 0) { this.curShowPublicity.push({ ID: heroCfg.ID, points: heroCfg.points, type: heroCfg.type, priority: CallCfg.priority, quality: CallCfg.quality, }) } } this.curShowPublicity.sort((a, b) => b.priority - a.priority) Mgr.ui.show(UI.RecruitPublicityUI, this.curShowPublicity) } //免费召唤 onClickFreeNormal(event: cc.Button, data: number) { this.curSummonType = DRAW_TYPE.normal Mgr.platform.playVideoAD(AD_ID.summoning, () => { Mgr.net.send(msgCmd.cmd_draw, {drawType: DRAW_TYPE.normal, payType: PAY_TYPE.free, num: 1}) }) } //普通卷轴召唤 onClickScrollNormal(event: cc.Button, data: number) { this.curSummonType = DRAW_TYPE.normal Mgr.net.send(msgCmd.cmd_draw, {drawType: DRAW_TYPE.normal, payType: PAY_TYPE.scroll, num: this.curNormaDraw}) } //高级卷轴召唤 onClickScrollRare(event: cc.Button, data: number) { this.curSummonType = DRAW_TYPE.rare Mgr.net.send(msgCmd.cmd_draw, {drawType: DRAW_TYPE.rare, payType: PAY_TYPE.scroll, num: this.curRareDraw}) } //高级钻石召唤 onClickDiamondRare(event: cc.Button, data: number) { this.curSummonType = DRAW_TYPE.rare Mgr.net.send(msgCmd.cmd_draw, {drawType: DRAW_TYPE.rare, payType: PAY_TYPE.currency, num: 10}) } //装备免费召唤 onClickFreeEquip(event: cc.Button, data: number) { //TODO 免费抽奖需要接入广告sdk this.curSummonType = DRAW_TYPE.forging Mgr.audio.playSFX(SOUND.drawEquip) Mgr.platform.playVideoAD(AD_ID.forging, () => { Mgr.net.send(msgCmd.cmd_draw, {drawType: DRAW_TYPE.forging, payType: PAY_TYPE.free, num: 1}) }) } //装备钻石召唤 onClickDiamondEquip(event: cc.Button, data: number) { this.curSummonType = DRAW_TYPE.forging Mgr.audio.playSFX(SOUND.drawEquip) Mgr.net.send(msgCmd.cmd_draw, {drawType: DRAW_TYPE.forging, payType: PAY_TYPE.scroll, num: this.curEquipDraw}) } //关闭当前正在播放的抽奖动画 切换为待机状态 onClickQuickCloseAni() { if (this.curSummonType == DRAW_TYPE.forging) { ccUtils.stopAni(this.forgingAni, IRecruitAnim_TYPE.forge) ccUtils.playAni(IRecruitAnim_TYPE.forgingIdle, 0, this.forgingAni) } else if (this.curSummonType == DRAW_TYPE.rare) { ccUtils.stopAni(this.rareAni, IRecruitAnim_TYPE.rareSummoning) ccUtils.playAni(IRecruitAnim_TYPE.magicBookIdle, 0, this.rareAni) } else if (this.curSummonType == DRAW_TYPE.normal) { ccUtils.stopAni(this.normalAni, IRecruitAnim_TYPE.normalSummoning) ccUtils.playAni(IRecruitAnim_TYPE.normalIdle, 0, this.normalAni) } this.showRewardUI() //提前显示奖励 } }