RoleBreakUI.ts 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383
  1. /** @format */
  2. import {BaseUI} from './BaseUI'
  3. import {Data, Mgr} from '../GameControl'
  4. import {ccUtils} from '../utils/ccUtils'
  5. import {list, observer, render} from '../mobx/observer'
  6. import {msgCmd} from '../proto/msg_cmd'
  7. import {IRoleQualityConfig, RoleQualityConfig} from '../config/RoleQualityConfig'
  8. import {ATTR_NAME, GOODS, LANGUAGE_TYPE, PROFESSION, QUALITY_COLOR, QUALITY_TYPE, ROLE_TYPE} from '../enums/Enum'
  9. import {idNum} from '../proto/typedef'
  10. import List, {SelectedType} from '../uiutils/List'
  11. import UserButton from '../uiutils/UserButton'
  12. import {heroOnekeyUpgradeStarRsp, heroUpgrade, heroUpgradeStar, heroUpgradeStarRsp} from '../proto/game'
  13. import {i18nLabel} from '../uiutils/i18nLabel'
  14. import {UI} from '../enums/UI'
  15. import {GoodsConfig} from '../config/GoodsConfig'
  16. import {RoleLevelConfig} from '../config/RoleLevelConfig'
  17. import {IRewardNty} from '../interface/UIInterface'
  18. import {IRole} from '../interface/GlobalInterface'
  19. const {ccclass, property} = cc._decorator
  20. export interface qualityGoods {
  21. id: number
  22. num: number
  23. quality: number
  24. }
  25. type roleGoods = IRole | qualityGoods
  26. @ccclass
  27. @observer
  28. export class RoleBreakUI extends BaseUI {
  29. chooseRole: IRole = null
  30. roleAndGoodArr: roleGoods[]
  31. needArr: roleGoods[]
  32. @list('roleList')
  33. roleList: List
  34. lastPower: number
  35. onShow(args, fromUI: number) {
  36. Mgr.net.add(msgCmd.cmd_hero_upgrade_star_rsp, this, this.onHeroStarRsp)
  37. Mgr.net.add(msgCmd.cmd_hero_onekey_upgrade_star_rsp, this, this.onHeroOneKeyStarRsp)
  38. Mgr.ui.showTop(this, [GOODS.coin, GOODS.diamond])
  39. this.clearRole()
  40. }
  41. onHide(): any {
  42. Mgr.event.removeAll(this)
  43. }
  44. clearRole() {
  45. this.chooseRole = null
  46. this.resetData()
  47. this.initNeedSlot()
  48. this.initUI()
  49. this.initOneKey()
  50. }
  51. resetData() {
  52. this.chooseRole = null
  53. this.roleList.selectedMode = SelectedType.SINGLE
  54. this.roleList.selectedId = -1
  55. this.roleAndGoodArr = [...Data.user.roles.filter(value => value.cfg.quality < Data.main.maxRoleQuality)]
  56. let goodsIDArr: number[] = []
  57. let cfgArr: IRoleQualityConfig[] = []
  58. for (let ID in RoleQualityConfig) {
  59. let goodsID = RoleQualityConfig[ID].resetGoods
  60. if (!goodsIDArr.includes(goodsID)) {
  61. goodsIDArr.push(goodsID)
  62. cfgArr.push(RoleQualityConfig[ID])
  63. }
  64. }
  65. for (let i = 0; i < goodsIDArr.length; i++) {
  66. let goodsID = goodsIDArr[i]
  67. if (goodsID > 0 && Mgr.goods.getGoodsNum(goodsID) > 0) {
  68. for (let j = 0; j < Mgr.goods.getGoodsNum(goodsID); j++) {
  69. this.roleAndGoodArr.push({
  70. id: goodsID,
  71. num: 1,
  72. quality: cfgArr[i].ID - 1,
  73. })
  74. }
  75. }
  76. }
  77. this.needArr = []
  78. }
  79. initUI() {
  80. cc.find('btn_auto', this.node).active = this.chooseRole == null
  81. cc.find('btn_break', this.node).active = this.chooseRole != null
  82. cc.find('joinTip', this.node).active = this.chooseRole == null
  83. let breakTip = cc.find('breakTip', this.node)
  84. let curSlotRoleNode = cc.find('cur_slot/role', this.node)
  85. curSlotRoleNode.active = false
  86. let nextSlotRoleNode = cc.find('next_slot/role', this.node)
  87. nextSlotRoleNode.active = false
  88. let hasChoose = this.chooseRole != null
  89. breakTip.active = hasChoose
  90. cc.find('add_need', this.node).active = hasChoose
  91. cc.find('need', this.node).active = hasChoose
  92. let rtTip = cc.find('tip_rt', this.node)
  93. ccUtils.setLabel(LANGUAGE_TYPE.autoBreakTip, rtTip)
  94. if (this.chooseRole) {
  95. let iRole = this.chooseRole
  96. this.lastPower = iRole.power
  97. curSlotRoleNode.active = true
  98. let hero = ccUtils.deepCopy(iRole.hero)
  99. hero.id += 1
  100. Mgr.global.initRoleItem(iRole, curSlotRoleNode, this)
  101. let nextQualityIRole = Mgr.global.buildIRole(hero)
  102. nextSlotRoleNode.active = true
  103. Mgr.global.initRoleItem(nextQualityIRole, nextSlotRoleNode, this)
  104. this.loadTexImg(`Public/role/streamer_${iRole.cfg.qualityType + 1}`, breakTip, 'streamer')
  105. ccUtils.setLabel(iRole.cfg.name, breakTip, 'roleName')
  106. let attrOrigin = cc.find('scrollView/view/content/attrs/attr', breakTip)
  107. let attrs = [ATTR_NAME.HP, ATTR_NAME.defense, ATTR_NAME.spellDefense]
  108. attrs.unshift(iRole.cfg.profession == PROFESSION.mage ? ATTR_NAME.spellAttack : ATTR_NAME.attack)
  109. let allAttrs = ccUtils.instantChildren(attrOrigin, attrs.length + 1)
  110. //显示等级
  111. let lvNode = allAttrs[0]
  112. ccUtils.setLabel(LANGUAGE_TYPE.lvMax, lvNode, 'attrName')
  113. ccUtils.setLabel(RoleQualityConfig[iRole.cfg.quality].maxLv.toString(), lvNode, 'attrNum')
  114. ccUtils.setLabel(RoleQualityConfig[nextQualityIRole.cfg.quality].maxLv.toString(), lvNode, 'nextNum')
  115. for (let i = 0; i < attrs.length; i++) {
  116. let attr = attrs[i]
  117. let attrNode = allAttrs[i + 1]
  118. ccUtils.setLabel(LANGUAGE_TYPE[attr.toString()], attrNode, 'attrName')
  119. ccUtils.setLabel(iRole[attr.toString()], attrNode, 'attrNum')
  120. ccUtils.setLabel(nextQualityIRole[attr.toString()], attrNode, 'nextNum')
  121. }
  122. ccUtils.setLabel(nextQualityIRole.cfg.tips, breakTip, 'scrollView/view/content/rtL/rt')
  123. ccUtils.setLabel(LANGUAGE_TYPE.needBreakTip, rtTip)
  124. let rtTipI18n = rtTip.getComponent(i18nLabel)
  125. let qCfg = RoleQualityConfig[iRole.cfg.quality + 1]
  126. if (qCfg.anyQualityNum > 0) {
  127. this.roleList.maxMutSelected = qCfg.anyQualityNum
  128. rtTipI18n.setParamByIndex(qCfg.anyQualityNum.toString(), 0)
  129. rtTipI18n.setParamByIndex(QUALITY_COLOR[Data.user.qualityTypeArr[qCfg.anyQuality]], 1)
  130. rtTipI18n.setParamByIndex(LANGUAGE_TYPE[QUALITY_TYPE[Data.user.qualityTypeArr[qCfg.anyQuality]]], 2)
  131. } else {
  132. this.roleList.maxMutSelected = qCfg.sameQualityNum
  133. rtTipI18n.setParamByIndex(qCfg.sameQualityNum.toString(), 0)
  134. rtTipI18n.setParamByIndex(QUALITY_COLOR[Data.user.qualityTypeArr[qCfg.sameQuality]], 1)
  135. rtTipI18n.setParamByIndex(
  136. Mgr.i18n.getLabel(iRole.cfg.name) +
  137. (iRole.grade > 0 ? `(${iRole.grade}${Mgr.i18n.getLabel(LANGUAGE_TYPE.star)})` : ''),
  138. 2,
  139. )
  140. }
  141. cc.find('need', this.node).children.forEach((value, index) => {
  142. value.active = index < this.roleList.maxMutSelected
  143. })
  144. }
  145. this.roleAndGoodArr.sort((a, b) => {
  146. if (this.chooseRole) {
  147. let aNeed = 'cfg' in a ? this.roleCanBeNeed(a) : this.goodsCanBeNeed(a)
  148. let bNeed = 'cfg' in b ? this.roleCanBeNeed(b) : this.goodsCanBeNeed(b)
  149. return Number(bNeed) - Number(aNeed)
  150. }
  151. let aAlter
  152. let bAlter
  153. if ('isAlter' in a) {
  154. aAlter = a.isAlter
  155. }
  156. if ('isAlter' in b) {
  157. bAlter = b.isAlter
  158. }
  159. if (aAlter != bAlter) {
  160. return aAlter - bAlter
  161. }
  162. let aIndex = 'cfg' in a ? Data.user.teamRole.indexOf(a) : -1
  163. let bIndex = 'cfg' in b ? Data.user.teamRole.indexOf(b) : -1
  164. if (aIndex != bIndex) {
  165. if (aIndex >= 0 && bIndex >= 0) {
  166. return aIndex - bIndex
  167. } else {
  168. return bIndex - aIndex
  169. }
  170. }
  171. let aQuality
  172. let aNum = 0
  173. let bNum = 0
  174. let bQuality
  175. if ('quality' in a) {
  176. aQuality = a.quality
  177. aNum = a.num
  178. } else {
  179. aQuality = a.cfg.quality
  180. }
  181. if ('quality' in b) {
  182. bQuality = b.quality
  183. bNum = b.num
  184. } else {
  185. bQuality = b.cfg.quality
  186. }
  187. let curQuality = this.chooseRole ? this.chooseRole.cfg.quality : -1
  188. // 先按照aQuality bQuality是否等于 iRole.cfg.quality 进行排序
  189. if (aQuality == curQuality && bQuality != curQuality) {
  190. return -1
  191. } else if (aQuality != curQuality && bQuality == curQuality) {
  192. return 1
  193. } else {
  194. if (aQuality != bQuality) {
  195. return bQuality - aQuality
  196. }
  197. if (aNum != bNum) {
  198. return aNum - bNum
  199. }
  200. if ('cfg' in a && 'cfg' in b) {
  201. return b.power - a.power
  202. }
  203. }
  204. })
  205. this.roleList.numItems = this.roleAndGoodArr.length
  206. }
  207. roleCanBeNeed(iRole: IRole) {
  208. if (!this.chooseRole) return false
  209. //选择了某个目标,可以吃的材料卡可以点击
  210. let qCfg = RoleQualityConfig[this.chooseRole.cfg.quality + 1]
  211. //同名卡可以点击
  212. let can1 = qCfg.sameQualityNum > 0 && this.chooseRole.hero.id == iRole.hero.id
  213. //同品质卡可以点击
  214. let can2 = qCfg.anyQualityNum > 0 && this.chooseRole.cfg.quality - this.chooseRole.grade == iRole.cfg.quality
  215. return (can1 || can2) && !Mgr.goods.roleIsUp(iRole) && iRole != this.chooseRole
  216. }
  217. goodsCanBeNeed(goods: qualityGoods) {
  218. if (!this.chooseRole) return false
  219. let qCfg = RoleQualityConfig[this.chooseRole.cfg.quality + 1]
  220. return qCfg.anyQualityNum > 0 && qCfg.resetGoods == goods.id
  221. }
  222. initNeedSlot() {
  223. let children = cc.find('need', this.node).children
  224. for (let i = 0; i < children.length; i++) {
  225. let node = children[i]
  226. let itemParent = cc.find('itemParent', node)
  227. if (this.needArr[i]) {
  228. itemParent.active = true
  229. this.initByRoleAndGoods(node, this.needArr[i])
  230. } else {
  231. itemParent.active = false
  232. }
  233. }
  234. }
  235. initRoleItem(node: cc.Node, index: number) {
  236. let roleAndGoods = this.roleAndGoodArr[index]
  237. let iRole: IRole = 'cfg' in roleAndGoods ? roleAndGoods : null
  238. let goods: qualityGoods = 'quality' in roleAndGoods ? roleAndGoods : null
  239. this.initByRoleAndGoods(node, roleAndGoods)
  240. let isIRole = iRole != null
  241. let icon_battle = cc.find('icon_battle', node)
  242. icon_battle.active = isIRole && Mgr.goods.roleIsUp(iRole)
  243. //升级需要资源
  244. cc.find('red_dot', node).active = isIRole && Mgr.goods.checkRoleBreakNeed(iRole).canUp
  245. let canClick = false
  246. if (this.chooseRole) {
  247. if (iRole) canClick = this.roleCanBeNeed(iRole) && !iRole.isAlter
  248. if (goods) canClick = this.goodsCanBeNeed(goods)
  249. } else if (iRole) {
  250. //没有选择,可以突破的角色可以点击
  251. canClick = RoleQualityConfig[iRole.cfg.quality + 1] != undefined && !iRole.isAlter
  252. }
  253. node.getComponent(UserButton).interactable = canClick
  254. cc.find('gray', node).active = !canClick
  255. }
  256. initByRoleAndGoods(node: cc.Node, roleAndGoods: roleGoods) {
  257. let iRole: IRole = 'cfg' in roleAndGoods ? roleAndGoods : null
  258. let goods: qualityGoods = 'quality' in roleAndGoods ? roleAndGoods : null
  259. let itemParent = cc.find('itemParent', node)
  260. if (!iRole) {
  261. Mgr.goods.initOneGoods({id: goods.id, num: goods.num}, itemParent, this, {showDetails: false})
  262. } else {
  263. Mgr.global.initRoleItem(iRole, itemParent, this)
  264. }
  265. }
  266. initOneKey() {
  267. let canUp = false
  268. for (let iRole of Data.user.roles) {
  269. if (iRole.cfg.qualityType < QUALITY_TYPE.elite && !Mgr.goods.roleIsUp(iRole) && iRole.hero.lv == 1) {
  270. canUp ||= Mgr.goods.checkRoleBreakNeed(iRole, true).canUp
  271. if (canUp) break
  272. }
  273. }
  274. cc.find('btn_auto/red_dot', this.node).active = canUp
  275. }
  276. //网络事件=======================================
  277. onHeroStarRsp(data: heroUpgradeStarRsp, rewardNty: IRewardNty) {
  278. Mgr.ui.show(UI.PowerUpUI, `+${this.chooseRole.power - this.lastPower}`)
  279. this.clearRole()
  280. Mgr.ui.showUIs([
  281. Mgr.ui.getGroupUIInfo(UI.RoleBreakSuccessUI, Mgr.global.buildIRole(data.data)),
  282. Mgr.ui.getRewardGroupUIInfo(rewardNty),
  283. ])
  284. }
  285. onHeroOneKeyStarRsp(data: heroOnekeyUpgradeStarRsp, rewardNty: IRewardNty) {
  286. this.clearRole()
  287. let changeIRole: IRole[] = []
  288. for (let i = Data.user.roles.length - 1; i >= 0; i--) {
  289. let findHero = data.changeList.find(value => value.sid == Data.user.roles[i].hero.sid)
  290. if (findHero) {
  291. changeIRole.push(Data.user.roles[i])
  292. }
  293. }
  294. }
  295. //触发事件=======================================
  296. // 点击事件=======================================
  297. onRoleClick(node, index, lastSelected, isSelected, isMax) {
  298. if (this.roleList.scrollView.isScrolling()) return
  299. if (!node) return
  300. if (cc.find('gray', node).active) return
  301. if (isMax) Mgr.ui.tip(LANGUAGE_TYPE.materialsLimit)
  302. if (this.chooseRole) {
  303. this.needArr = []
  304. this.roleList.getMultSelected().forEach(i => {
  305. this.needArr.push(this.roleAndGoodArr[i])
  306. })
  307. this.initNeedSlot()
  308. } else {
  309. this.chooseRole = this.roleAndGoodArr[index] as IRole
  310. this.roleList.selectedMode = SelectedType.MULT
  311. this.roleList.setMultSelected([], null)
  312. this.initUI()
  313. this.roleList.scrollTo(0)
  314. }
  315. }
  316. onChooseRoleClick() {
  317. this.clearRole()
  318. }
  319. onBreakClick() {
  320. if (!this.chooseRole) return
  321. if (this.needArr?.length < this.roleList.maxMutSelected) {
  322. Mgr.ui.tip(LANGUAGE_TYPE.materialsNeed)
  323. return
  324. }
  325. let currency: idNum = {id: 0, num: 0}
  326. let sidArr: string[] = []
  327. let hasLvUp = false
  328. this.needArr.forEach(value => {
  329. if ('hero' in value) {
  330. sidArr.push(value.hero.sid)
  331. if (!hasLvUp && value.hero.lv > 1) hasLvUp = true
  332. }
  333. if ('quality' in value) {
  334. currency.id = value.id
  335. currency.num += 1
  336. }
  337. })
  338. let isSame = RoleQualityConfig[this.chooseRole.cfg.quality + 1].sameQualityNum > 0
  339. let data: heroUpgradeStar = {
  340. currency,
  341. other: isSame ? [] : sidArr,
  342. same: isSame ? sidArr : [],
  343. sid: this.chooseRole.hero.sid,
  344. }
  345. if (hasLvUp) {
  346. Mgr.ui.message(LANGUAGE_TYPE.materialsLvUp, () => {
  347. Mgr.net.send(msgCmd.cmd_hero_upgrade_star, data)
  348. })
  349. } else {
  350. Mgr.net.send(msgCmd.cmd_hero_upgrade_star, data)
  351. }
  352. }
  353. onOneKeyBreakClick() {
  354. Mgr.net.send(msgCmd.cmd_hero_onekey_upgrade_star)
  355. }
  356. }