/** @format */ import {ccUtils} from '../utils/ccUtils' import {Data, Mgr} from '../GameControl' import {BaseUI} from '../ui/BaseUI' import {card, equip, hero, idNum} from '../proto/typedef' import {RoleConfig} from '../config/RoleConfig' import {CardSkillConfig} from '../config/CardSkillConfig' import {CardConsumeConfig} from '../config/CardConsumeConfig' import {RoleQualityConfig} from '../config/RoleQualityConfig' import {ArmorConfig} from '../config/ArmorConfig' import {EquipmentQualityConfig} from '../config/EquipmentQualityConfig' import {TalentConfig} from '../config/TalentConfig' import {EntryConfig} from '../config/EntryConfig' import { ATTR_NAME, BUILDING, CONDITION_FUNC, ENTRY, GAME_TYPE, GOODS, GOODS_TYPE, LANGUAGE_TYPE, LOCAL, MOD, PREFAB_TYPE, PROFESSION, RECRUIT_TYPE, ROLE_TYPE, } from '../enums/Enum' import {IAdStatus, IBaseAttr, ICard, ICardDebris, ICastleSkill, IEquip, IRole} from '../interface/GlobalInterface' import {FunctionsConfig} from '../config/FunctionsConfig' import {StageInfoConfig} from '../config/StageInfoConfig' import {UI} from '../enums/UI' import {ConstValue} from '../data/ConstValue' import {GoodsConfig} from '../config/GoodsConfig' import {boxGetAward} from '../proto/game' import {msgCmd} from '../proto/msg_cmd' import {ItemUICfg} from '../interface/UIInterface' import UserGuide from '../userguide/UserGuide' import value = cc.js.value import {CastleSkillConfig} from '../config/CastleSkillConfig' import {MonsterManualConfig} from '../config/MonsterManualConfig' export class GlobalManager { userGuideCom: UserGuide curGuideStep: number = 0 lastPower: number adInfoStorage: any startPoint: cc.Vec2 //开始触摸的位置 curPoint: cc.Vec2 //触摸的当前位置 moveOverstepPx: number = 30 //触摸物品后移动超过多少像素就不弹出详细信息 reset() { this.adInfoStorage = null this.curGuideStep = 0 } getItemNode(parent, type: PREFAB_TYPE, url: string, baseUI: BaseUI) { let pool = Data.main.itemsPoolMap.get(`${type}_${url}`) if (!pool) { pool = new cc.NodePool() Data.main.itemsPoolMap.set(`${type}_${url}`, pool) } parent.children.forEach(child => { if (PREFAB_TYPE[type] && child.name != `${type}_${url}`) { Data.main.itemsPoolMap.get(child.name)?.put(child) } }) let node = cc.find(`${type}_${url}`, parent) if (!node) { node = pool.size() ? pool.get() : cc.instantiate(Data.main.itemsPrefabMap.get(type)) baseUI.itemsNodes.push(node) } node.parent = parent node.name = `${type}_${url}` node['uiID'] = baseUI.uiID return node } initRoleItem(iRole: IRole, parent: cc.Node, baseUI: BaseUI, cfg?: ItemUICfg) { let node = this.initCfgRoleItem(iRole.cfg, parent, baseUI, cfg) ccUtils.setLabel(cfg && cfg.hideLv ? '' : `lv.${iRole.hero.lv}`, node, 'lv') } initCfgRoleItem( {quality, qualityType, profession, url, type, ID, cost}, parent: cc.Node, baseUI: BaseUI, cfg?: ItemUICfg, ): cc.Node { let node = this.getItemNode(parent, PREFAB_TYPE.role, `${ID}_${qualityType}`, baseUI) baseUI.loadNotRefTexImg(`Public/goodsQuality/item_frame${qualityType}`, node, 'item_frame') baseUI.loadNotRefTexImg(`Public/role/icon/${url}`, node, 'icon') let professionNode = cc.find('role_type', node) professionNode.active = !cfg || !cfg.hideProfession baseUI.loadNotRefTexImg(`Public/role/role_type_${profession}`, professionNode) let maxGrade = Data.user.maxGradeArr[qualityType - 1] // let grade = cc.find('grade', node) let gradeNum = Data.user.gradeArr[quality - 1] let stars = cc.find('stars', node) if (stars) { stars.active = maxGrade > 0 && gradeNum > 0 ccUtils.instantChildren(stars.children[0], gradeNum) // if (gradeNum > 0) { // baseUI.loadNotRefTexImg(`Public/role/grade_${qualityType}`, grade) // ccUtils.setLabel(gradeNum.toString(), grade, 'lv') // } } let isOnly = type == ROLE_TYPE.only let special = cc.find('item_special', node) if (special) { special.active = isOnly if (special.active) baseUI.loadNotRefTexImg(`Public/role/item_special_frame${qualityType}`, special) } ccUtils.setLabel('', node, 'lv') let costNode = cc.find('cost', node) if (costNode) { costNode.active = cost > 0 && !cfg?.hideCost if (cost > 0) ccUtils.setLabel(cost.toString(), costNode, 'lb') } return node } initRoleSpine(iRole: IRole, node: cc.Node, childUrl?: string) { if (childUrl) { node = cc.find(childUrl, node) } if (!node['_originScale']) { node['_originScale'] = node.scale } node.scale = (node['_originScale'] * iRole.cfg.uiScale) / 100 let skeleton: sp.Skeleton = node.getComponent(sp.Skeleton) skeleton.skeletonData = Data.main.roleSpineMap.get(iRole.cfg.url) skeleton.setAnimation(0, 'stand', true) } initRoleSpineByName(name: string, node: cc.Node, childUrl?: string) { if (childUrl) { node = cc.find(childUrl, node) } let skeleton: sp.Skeleton = node.getComponent(sp.Skeleton) skeleton.skeletonData = Data.main.roleSpineMap.get(name) skeleton.setAnimation(0, 'stand', true) } initCardItem(iCard: ICard, parent: cc.Node, baseUI: BaseUI, cfg?: ItemUICfg) { let node = this.getItemNode(parent, PREFAB_TYPE.card, `${iCard.card.id}_${iCard.cfg.qualityType}`, baseUI) ccUtils.setLabel( `lv.${iCard.card.lv}${cfg && cfg.lvMax ? '/' + RoleQualityConfig[iCard.cfg.quality].maxLv : ''}`, node, 'lv', ) baseUI.loadNotRefTexImg(`Public/goodsQuality/item_frame${iCard.cfg.qualityType}`, node, 'item_frame') baseUI.loadNotRefTexImg(`Public/card/icon/${iCard.cfg.url}`, node, 'icon') let maxGrade = Data.user.maxGradeArr[iCard.cfg.qualityType - 1] let grade = cc.find('grade', node) if (grade) { grade.active = maxGrade > 0 && iCard.grade > 0 if (iCard.grade > 0) { baseUI.loadNotRefTexImg(`Public/role/grade_${iCard.cfg.qualityType}`, grade) ccUtils.setLabel(iCard.grade.toString(), grade, 'lv') } } } initCardDebrisItem(card: ICardDebris, parent: cc.Node, baseUI: BaseUI): cc.Node { let node = this.getItemNode(parent, PREFAB_TYPE.cardDebris, `${card.id}_${card.cfg.qualityType}`, baseUI) baseUI.loadNotRefTexImg(`Public/goodsQuality/item_frame${card.cfg.qualityType}`, node, 'item_frame') baseUI.loadNotRefTexImg(`Public/card/icon/${card.cfg.url}`, node, 'icon') ccUtils.setSpriteGray(true, node, 'icon') cc.find('debris', node).active = true return node } detailsTouchStart(flag, event) { this.startPoint = event.getLocation() this.curPoint = event.getLocation() //如果不移动的话当前位置会是空、所以默认给开始位置 } detailsTouchMove(flag, event) { this.curPoint = event.getLocation() } showGoodsDetails(goodID: number) { let isXOverstep = Math.abs(this.curPoint.x - this.startPoint.x) <= this.moveOverstepPx let isYOverstep = Math.abs(this.curPoint.y - this.startPoint.y) <= this.moveOverstepPx if (isXOverstep && isYOverstep) { Mgr.ui.show(UI.ItemDetailsUI, Mgr.goods.getGoodShowInfo(goodID)) } } initEquipItem(equip: IEquip, parent: cc.Node, baseUI: BaseUI, cfg: ItemUICfg = {showDetails: false}) { let node = Mgr.global.getItemNode( parent, PREFAB_TYPE.equip, `${equip.equip.id}_${equip.cfg.qualityType}`, baseUI, ) node.targetOff(this) if (cfg && cfg.showDetails) { node.on(cc.Node.EventType.TOUCH_START, this.detailsTouchStart.bind(this, true), this) node.on(cc.Node.EventType.TOUCH_END, this.showGoodsDetails.bind(this, equip.equip.id), this) node.on(cc.Node.EventType.TOUCH_MOVE, this.detailsTouchMove.bind(this, false), this) } ccUtils.setLabel( `lv.${equip.equip.lv}${cfg && cfg.lvMax ? '/' + EquipmentQualityConfig[equip.cfg.quality]?.maxLv : ''}`, node, 'lv', ) baseUI.loadNotRefTexImg(`Public/goodsQuality/item_frame${equip.cfg.qualityType}`, node, 'item_frame') baseUI.loadNotRefTexImg(`Public/equip/type_base${equip.cfg.qualityType}`, node, 'type_base') baseUI.loadNotRefTexImg(`Public/equip/type_icon${equip.cfg.type}`, node, 'type_base/type_icon') baseUI.loadNotRefTexImg(`Public/equip/icon/${equip.cfg.icon}`, node, 'icon') let maxGrade = Data.user.maxGradeArr[equip.cfg.qualityType - 1] let grade = cc.find('grade', node) if (grade) { grade.active = maxGrade > 0 && equip.grade > 0 if (equip.grade > 0) { baseUI.loadNotRefTexImg(`Public/role/grade_${equip.cfg.qualityType}`, grade) ccUtils.setLabel(equip.grade.toString(), grade, 'lv') } } } getPowerByAttr(baseAttr: IBaseAttr): number { //比例值(万分比) let rate = Data.game.rateNum // 物理防御系数 1 - 物理防御/(物理防御+防御常数) let defenseCoe = +( 1 / +(1 - baseAttr.defense / (baseAttr.defense + Data.game.defenseConst)).toFixed(2) ).toFixed(2) defenseCoe = defenseCoe || 0 // 法术防御系数 1 - 法术防御/(法术防御+防御常数) let spellDefenseCoe = +( 1 / +(1 - baseAttr.spellDefense / (baseAttr.spellDefense + Data.game.defenseConst)).toFixed(2) ).toFixed(2) spellDefenseCoe = spellDefenseCoe || 0 //攻速系数 攻速/比例值 let attackSpeedCoe = +(baseAttr.attackSpeed / rate).toFixed(2) attackSpeedCoe = attackSpeedCoe || 0 //暴击系数 暴击伤害倍数/比例值 * 暴击率/比例值 * 2 let critCoe = +(baseAttr.critNum / rate).toFixed(2) * +(baseAttr.attackCrit / rate).toFixed(2) * 2 critCoe = critCoe || 0 //命中系数 1/攻击CD/比例值 * 命中率/比例值 let hitCoe = +(1 / +(baseAttr.attackSpeed / rate).toFixed(2)).toFixed(2) * +(baseAttr.hit / rate).toFixed(2) hitCoe = hitCoe || 0 //闪避系数 1/(1-闪避率/比例值) let dodgeCoe = +(1 / +(1 - baseAttr.dodge / rate).toFixed(2)).toFixed(2) dodgeCoe = dodgeCoe || 0 let power = baseAttr.attack * (1 + attackSpeedCoe + critCoe + hitCoe) * 2 + baseAttr.spellAttack * (1 + attackSpeedCoe + critCoe + hitCoe) * 2 + baseAttr.HP * (1 + defenseCoe + spellDefenseCoe + dodgeCoe) * 0.8 return Math.floor(power) } buildIRole(hero: hero, role?: IRole): IRole { let iRole: IRole if (hero.id > 0 && !RoleConfig[hero.id]) { console.error('没有这个英雄') return } if (role) { iRole = role iRole.cfg = RoleConfig[hero.id] iRole.hero = hero iRole.grade = Data.user.gradeArr[iRole.cfg.quality - 1] } else { let baseAttr = this.buildIBaseAttr(RoleConfig[hero.id]) iRole = { ...baseAttr, cfg: RoleConfig[hero.id], grade: Data.user.gradeArr[RoleConfig[hero.id].quality - 1], hero: hero, power: 0, isAlter: false, equips: new Array(Data.main.equipMaxNum).fill(null), } hero.equip.forEach(equip => { let iEquip = Data.user.equips.find(value => value.equip.sid == equip) if (iEquip) iRole.equips[iEquip.cfg.type - 1] = iEquip }) } iRole.isAlter = Data.user.altarInfoList.findIndex(item => item.sid === iRole.hero.sid) != -1 //等级加成 1 + 等级/100 let lvAdd = 1 + +((iRole.hero.lv - 1) / 100).toFixed(2) this.setIBaseAttr(iRole, iRole.cfg, lvAdd, iRole.equips) iRole.power = this.getPowerByAttr(iRole) return iRole } buildHeroByCfg(id: number): IRole { if (id > 0 && !RoleConfig[id]) { console.error('没有这个英雄') return } let iHero: hero = { sid: '', id: id, lv: 0, equip: new Array(Data.main.equipMaxNum).fill(null), } return this.buildIRole(iHero) } buildICard(card: card, iCardObj?: ICard): ICard { let iCard: ICard if (card.id > 0 && !CardSkillConfig[card.id]) { console.error('没有这个卡牌') return } if (iCardObj) { iCard = iCardObj iCard.cfg = CardSkillConfig[card.id] iCard.card = card iCard.debrisCfg = Object.values(CardConsumeConfig).find( item => item.card == Math.floor(iCard.cfg.ID / 100) * 100 + 1, ) iCard.grade = Data.user.gradeArr[iCard.cfg.quality - 1] } else { let baseAttr = this.buildIBaseAttr(CardSkillConfig[card.id]) iCard = { ...baseAttr, cfg: CardSkillConfig[card.id], grade: Data.user.gradeArr[CardSkillConfig[card.id].quality - 1], card: card, power: 0, debrisCfg: Object.values(CardConsumeConfig).find( item => item.card == Math.floor(CardSkillConfig[card.id].ID / 100) * 100 + 1, ), } } // -----卡牌战斗力不受装备,天赋加成---- //等级加成 1 + 等级/比例值 let lvAdd = 1 + +((iCard.card.lv - 1) / 100).toFixed(2) this.setIBaseAttr(iCard, iCard.cfg, lvAdd, []) iCard.power = this.getPowerByAttr(iCard) return iCard } buildCardByCfg(id: number): ICard { if (id > 0 && !CardSkillConfig[id]) { console.error('没有这个卡牌') return } let iCard: card = { sid: '', id: id, lv: 0, } return this.buildICard(iCard) } buildICardDebris(idNum: idNum, iCardDebrisObj?: ICardDebris): ICardDebris { let iCardDebris: ICardDebris if (idNum.id > 0 && !CardConsumeConfig[idNum.id]) { console.error('没有这个卡牌碎片') return } if (iCardDebrisObj) { iCardDebris = iCardDebrisObj iCardDebris.cfg = CardConsumeConfig[idNum.id] iCardDebris.num = idNum.num iCardDebris.id = idNum.id } else { iCardDebris = {cfg: CardConsumeConfig[idNum.id], id: idNum.id, num: idNum.num} } return iCardDebris } buildIEquip(equip: equip, iEquipObj?: IEquip): IEquip { let iEquip: IEquip let curCfg = ArmorConfig[equip.id] if (equip.id > 0 && !curCfg) { console.error('没有这个装备') return } let baseAttr = this.buildIBaseAttr(curCfg) //等级加成 1 + 等级/比例值 废弃 /*let rate = Data.game.rateNum let lvAdd = 1 + +((equip.lv - 1) / 200).toFixed(2) this.scaleBaseAttr(baseAttr, lvAdd) //舍弃小数 for (let key in baseAttr) { baseAttr[key] = Math.floor(baseAttr[key]) }*/ //等级加成为固定值 let lvAddAttr = [ATTR_NAME.HP, ATTR_NAME.attack, ATTR_NAME.spellAttack] for (let attr of lvAddAttr) { if (baseAttr[attr] > 0) { baseAttr[attr] += (equip.lv - 1) * curCfg.increaseLv } } if (iEquipObj) { iEquip = iEquipObj iEquip.cfg = curCfg iEquip.equip = equip this.changeBaseAttr(iEquip, baseAttr) iEquip.grade = Data.user.gradeArr[iEquip.cfg.quality - 1] } else { iEquip = { ...baseAttr, cfg: curCfg, equip: equip, grade: Data.user.gradeArr[curCfg.quality - 1], power: 0, } } iEquip.power = this.getPowerByAttr(iEquip) return iEquip } buildEquipByCfg(id: number): IEquip { if (id > 0 && !ArmorConfig[id]) { console.error('没有这个装备') return } let iEquip: equip = { sid: '', id: id, lv: 0, hero: '', } return this.buildIEquip(iEquip) } buildICastleSkill(id: number): ICastleSkill { let cfg = CastleSkillConfig[id] let baseAttr = this.buildIBaseAttr(cfg) return { ...baseAttr, cfg, lv: cfg.ID % 100, isUse: id == Data.user.useCastleSkillID, } } buildIBaseAttr(cfg: IBaseAttr, isZero: boolean = false) { let baseAttr = { HP: isZero ? 0 : cfg.HP, attack: isZero ? 0 : cfg.attack, spellAttack: isZero ? 0 : cfg.spellAttack, realAttack: isZero ? 0 : cfg.realAttack, defense: isZero ? 0 : cfg.defense, spellDefense: isZero ? 0 : cfg.spellDefense, attackSpeed: isZero ? 0 : cfg.attackSpeed, attackCrit: isZero ? 0 : cfg.attackCrit, critNum: isZero ? 0 : cfg.critNum, hit: isZero ? 0 : cfg.hit, dodge: isZero ? 0 : cfg.dodge, moveSpeed: isZero ? 0 : cfg.moveSpeed, } return baseAttr } changeBaseAttr(baseAttr: IBaseAttr, changeAttr: IBaseAttr, isAdd: boolean = false) { baseAttr.HP = isAdd ? baseAttr.HP + changeAttr.HP : changeAttr.HP baseAttr.attack = isAdd ? baseAttr.attack + changeAttr.attack : changeAttr.attack baseAttr.attackSpeed = isAdd ? baseAttr.attackSpeed + changeAttr.attackSpeed : changeAttr.attackSpeed baseAttr.attackCrit = isAdd ? baseAttr.attackCrit + changeAttr.attackCrit : changeAttr.attackCrit baseAttr.critNum = isAdd ? baseAttr.critNum + changeAttr.critNum : changeAttr.critNum baseAttr.defense = isAdd ? baseAttr.defense + changeAttr.defense : changeAttr.defense baseAttr.dodge = isAdd ? baseAttr.dodge + changeAttr.dodge : changeAttr.dodge baseAttr.hit = isAdd ? baseAttr.hit + changeAttr.hit : changeAttr.hit baseAttr.spellAttack = isAdd ? baseAttr.spellAttack + changeAttr.spellAttack : changeAttr.spellAttack baseAttr.spellDefense = isAdd ? baseAttr.spellDefense + changeAttr.spellDefense : changeAttr.spellDefense baseAttr.realAttack = isAdd ? baseAttr.realAttack + changeAttr.realAttack : changeAttr.realAttack baseAttr.moveSpeed = isAdd ? baseAttr.moveSpeed + changeAttr.moveSpeed : changeAttr.moveSpeed return baseAttr } scaleBaseAttr(baseAttr: IBaseAttr, scale: number) { baseAttr.HP *= scale baseAttr.attack *= scale baseAttr.attackSpeed *= scale baseAttr.attackCrit *= scale baseAttr.critNum *= scale baseAttr.defense *= scale baseAttr.dodge *= scale baseAttr.hit *= scale baseAttr.spellAttack *= scale baseAttr.spellDefense *= scale baseAttr.realAttack *= scale baseAttr.moveSpeed = baseAttr.moveSpeed return baseAttr } setIBaseAttr(obj: ICard | IRole, cfg: IBaseAttr, lvAdd: number, equips: IEquip[]) { //装备加成 let attr = this.buildIBaseAttr(null, true) let allEntryArr: number[] = [] for (let i = 0; i < equips.length; i++) { if (equips[i]) { this.changeBaseAttr(attr, equips[i], true) if (equips[i].cfg.entry) allEntryArr.push(equips[i].cfg.entry) } } obj.HP = cfg.HP * lvAdd + attr.HP obj.attack = cfg.attack * lvAdd + attr.attack obj.attackSpeed = cfg.attackSpeed * lvAdd + attr.attackSpeed obj.attackCrit = cfg.attackCrit * lvAdd + attr.attackCrit obj.critNum = cfg.critNum * lvAdd + attr.critNum obj.defense = cfg.defense * lvAdd + attr.defense obj.dodge = cfg.dodge * lvAdd + attr.dodge obj.hit = cfg.hit * lvAdd + attr.hit obj.spellAttack = cfg.spellAttack * lvAdd + attr.spellAttack obj.spellDefense = cfg.spellDefense * lvAdd + attr.spellDefense obj.realAttack = cfg.realAttack * lvAdd + attr.realAttack obj.moveSpeed = cfg.moveSpeed + attr.moveSpeed //天赋词条加成 if ('hero' in obj) { let profession = obj.cfg.profession if (Data.main.talentAdd && Data.main.talentAdd[profession]) { this.changeBaseAttr(obj, Data.main.talentAdd[profession], true) } } // 所有角色卡牌基础属性万分比词条加成 for (let entry of allEntryArr) { switch (EntryConfig[entry].type) { case ENTRY.addRoleHP: obj.HP *= 1 + EntryConfig[entry].rateArr[0] / Data.game.rateNum case ENTRY.equipAddAttack: obj.attack *= 1 + EntryConfig[entry].rateArr[0] / Data.game.rateNum break } } obj.HP = Math.floor(obj.HP) obj.attack = Math.floor(obj.attack) obj.attackSpeed = Math.floor(obj.attackSpeed) obj.attackCrit = Math.floor(obj.attackCrit) obj.critNum = Math.floor(obj.critNum) obj.defense = Math.floor(obj.defense) obj.dodge = Math.floor(obj.dodge) obj.hit = Math.floor(obj.hit) obj.spellAttack = Math.floor(obj.spellAttack) obj.spellDefense = Math.floor(obj.spellDefense) obj.realAttack = Math.floor(obj.realAttack) obj.moveSpeed = Math.floor(obj.moveSpeed) } getPower() { let power = 0 Data.user.teamRole.forEach(iRole => { if (iRole) { this.buildIRole(iRole.hero, iRole) power += iRole.power } }) Data.user.teamCard.forEach(iCard => { if (iCard) { this.buildICard(iCard.card, iCard) power += iCard.power } }) return power } getPowerString() { return Math.toKMBNum(this.getPower()) } initPower() { this.lastPower = this.getPower() } updatePower() { let newPower = this.getPower() if (newPower > this.lastPower) { Mgr.ui.show(UI.PowerUpUI, `+${newPower - this.lastPower}`) this.lastPower = newPower } } entryBaseAttrAdd(baseAttr: IBaseAttr, entryID: number[]) { for (let id of entryID) { let entryCfg = EntryConfig[id] if (entryCfg.type >= ENTRY.HP && entryCfg.type <= ENTRY.realAttack) { baseAttr[ENTRY[entryCfg.type]] += entryCfg.parmArr[0] } if (entryCfg.type >= ENTRY.HPRate && entryCfg.type <= ENTRY.realAttackRate) { baseAttr[ENTRY[entryCfg.type].replace(/Rate/, '')] += entryCfg.rateArr[0] } if (entryCfg.type == ENTRY.talAddAllDefense) { baseAttr.defense += entryCfg.parmArr[0] baseAttr.spellDefense += entryCfg.parmArr[0] } } } //天赋加成是基础值 initTalentAdd() { Data.user.talents.sort((a, b) => a - b) let talentAdds = [] for (let i = PROFESSION.warrior; i <= PROFESSION.archer; i++) { let talentAdd = this.buildIBaseAttr(null, true) let entryIDs: number[] = [] Data.user.talents.forEach(value => { if (EntryConfig[TalentConfig[value].entryID].profession.includes(i)) { entryIDs.push(TalentConfig[value].entryID) } }) this.entryBaseAttrAdd(talentAdd, entryIDs) let addAllAttrRateArr: ENTRY[] = [ ENTRY.talAddHP, ENTRY.talAddattack, ENTRY.talAddspellAttack, ENTRY.talAdddefense, ENTRY.talAddspellDefense, ] for (let id of Data.user.talents) { let cfg = TalentConfig[id] let entryCfg = EntryConfig[cfg.entryID] if (addAllAttrRateArr.includes(entryCfg.type)) { talentAdd[ENTRY[entryCfg.type].replace('talAdd', '')] *= 1 + entryCfg.rateArr[0] / Data.game.rateNum } } talentAdds[i] = talentAdd } Data.main.talentAdd = talentAdds } checkModOpen(modID: number) { // if (CC_DEV) return true return this.checkModOpenBeyond(modID) } checkModOpenBeyond(modID: number, checkCurrent: boolean = false) { let cfg = FunctionsConfig[modID] let check = true //mod为0时,不跳转页面 if (!checkCurrent && cfg == undefined) return check if (!cfg && checkCurrent) return false switch (cfg.condition) { case CONDITION_FUNC.teamLevel: check = checkCurrent ? Data.user.level == cfg.parameter : Data.user.level >= cfg.parameter break case CONDITION_FUNC.normalBarrier: check = checkCurrent ? Data.user.adventureId == cfg.parameter + 1 : Data.user.adventureId >= cfg.parameter + 1 break case CONDITION_FUNC.createRoleDay: let day = Date.getDayDHMS(Data.main.serverTime - Data.user.createTime).day check = checkCurrent ? day == cfg.parameter : day >= cfg.parameter break case CONDITION_FUNC.eliteBarrier: check = checkCurrent ? Data.user.eliteId == cfg.parameter + 1 : Data.user.eliteId >= cfg.parameter + 1 break } return check } getModLockTip(modID: number) { let cfg = FunctionsConfig[modID] let text = '' if (cfg) { let target = Mgr.i18n.getLabel(FunctionsConfig[modID].name) switch (cfg.condition) { case CONDITION_FUNC.teamLevel: text = Mgr.i18n.getLabel(LANGUAGE_TYPE.teamLevel, [cfg.parameter.toString(), target]) break case CONDITION_FUNC.normalBarrier: let stageInfoCfg = StageInfoConfig[cfg.parameter], barrierName = `${Mgr.i18n.getLabel(stageInfoCfg.name)}-${stageInfoCfg.des}` text = Mgr.i18n.getLabel(LANGUAGE_TYPE.normalBarrier, [barrierName, target]) break case CONDITION_FUNC.createRoleDay: text = Mgr.i18n.getLabel(LANGUAGE_TYPE.createRoleDay, [cfg.parameter.toString(), target]) break } } return text } showModLockTip(modID: number) { Mgr.ui.tip(this.getModLockTip(modID)) } //检查是否功能开启,并显示跳转页面 tryJumpMod(modID: number) { //modID为0时,不跳转 if (modID == 0) return let isOpen = Mgr.global.checkModOpen(modID) if (isOpen) { //对金币&体力购买界面做特殊处理 if (modID == MOD.fatigueBuy || modID == MOD.moneyBuy) { return } let uiID = null let uiArgs = null let preOpenUIs = [] let preOpenUIArgs = [] if (!UI[modID]) { switch (modID) { case MOD.giftStore: case MOD.dailyGift: case MOD.weekGift: case MOD.noviceGift: case MOD.dailyStore: case MOD.resourceStore: case MOD.relicStore: uiID = UI.ShopUI uiArgs = modID break case MOD.advancedCharge: case MOD.elite: uiID = UI.StageChooseUI uiArgs = GAME_TYPE.elite break case MOD.equipGet: uiID = UI.RecruitUI uiArgs = RECRUIT_TYPE.forging //装备锻造 break case MOD.explore: preOpenUIs.push(UI.CurrencyUI) preOpenUIArgs[preOpenUIs.length - 1] = [GOODS.coin, GOODS.diamond, GOODS.fatigue] uiArgs = modID break } } else { uiID = modID switch (modID) { case UI.StageChooseUI: uiArgs = GAME_TYPE.normal break case UI.RecruitUI: //默认抽奖-人物 uiArgs = RECRUIT_TYPE.summoning //英雄召唤 } } if (Mgr.ui.isTopUI(uiID)) { Mgr.ui.callOnShow(uiID, uiArgs) return } Mgr.ui.closeAll([UI.MainUI]) preOpenUIs.forEach((v, i) => Mgr.ui.show(v, preOpenUIArgs[i])) if (uiID) Mgr.ui.show(uiID, uiArgs) } else { this.showModLockTip(modID) } } tryOpenNextReadyBox() { let open = false if (Data.user.readyOpenBox.length > 0) { let idNum = Data.user.readyOpenBox.shift() switch (GoodsConfig[idNum.id].type) { case GOODS_TYPE.randomBox: let req = boxGetAward.create() req.type = GOODS_TYPE.randomBox Data.user.readyOpenBox = Data.user.readyOpenBox.filter( value => GoodsConfig[value.id].type != GOODS_TYPE.randomBox, ) Mgr.net.send(msgCmd.cmd_box_get_award, req) break case GOODS_TYPE.selectBox: open = true Data.user.readyOpenBox.unshift(idNum) break } } return open } //存入&修改localStorage中adFree相关信息(id: adFree_id, time: 结束时间戳) storageAdInfo(id: number, timeStamp: number, leftDailyTimes: number) { if (!id) return let obj = {timeStamp, leftDailyTimes} if (this.adInfoStorage) { this.adInfoStorage[id] = obj } else { let item = Mgr.storage.getObject(LOCAL.adFreeInfo, {}) item[id] = obj this.adInfoStorage = item } Mgr.storage.set(LOCAL.adFreeInfo, this.adInfoStorage) } //获得对应adfree_id对应时间戳 getAdInfo(id: number) { let adFreeInfos = this.adInfoStorage if (!adFreeInfos) { adFreeInfos = Mgr.storage.getObject(LOCAL.adFreeInfo, {}) } let time = adFreeInfos[id] ? adFreeInfos[id].timeStamp - Data.main.serverTime : -0.1 let min = Math.floor(time / 60) let sec = time % 60 let dailyTimes = adFreeInfos[id] ? adFreeInfos[id].leftDailyTimes : 0 let status: IAdStatus = { time, min: min.toString().zeroPrefix(min, 2), sec: sec.toString().zeroPrefix(sec, 2), isZero: time == 0, inTime: time > 0 && dailyTimes > 0, dailyTimes, } return status } tryShowUserGuide(keys: string[], callback: Function = null) { //没有账号不进入引导 if (!Data.user.uid) return false if (!keys || keys.length == 0) return false let bigStep = +keys[0].split('_')[0] if (this.curGuideStep > 2 && this.curGuideStep != bigStep) return false //1级0经验引导 if (bigStep == 1 && (Data.user.exp > 0 || Data.user.level > 1)) { return false } //打完第一关引导 if (bigStep == 2 && Data.user.adventureId != 2) { return false } //功能引导 if (bigStep > 2 && bigStep < 10000 && !this.checkModOpenBeyond(bigStep, true)) { return false } //密林5第十关Boss说明引导 if (bigStep == 10001 && Data.game.stageID != 10) { return false } //特殊怪物引导 if ( bigStep == 10002 && !Object.values(MonsterManualConfig) .map(v => v.trigger) .includes(Data.game.stageID) ) { return false } let curStep = Mgr.storage.getNumber(`userGuide_${bigStep}`) if (curStep) { keys = keys.filter(value => +value.split('_')[1] > curStep) //当前引导小于等于存储的不引导 if (keys.length == 0) return false } Mgr.storage.set(`userGuide_${bigStep}`, +keys[keys.length - 1].split('_')[1]) this.userGuideCom.showGuideByGroup(keys, callback) this.curGuideStep = bigStep return true } initAvatar(node, baseUI: BaseUI) { let sprite = node.getComponent(cc.Sprite) if (Data.user.avatarTex) { sprite.spriteFrame = new cc.SpriteFrame(Data.user.avatarTex) } else { baseUI.loadTexImg(`Public/avatar/${Data.user.avatar}`, node) } } }