HeroPubLogic.lua 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667
  1. -- 英雄酒馆功能
  2. -- 统计SSR和UR英雄中不同ID英雄的最高星级,并根据星级获得加成属性
  3. -- db
  4. --[=[
  5. human.db.heroPubData = nil
  6. -- {
  7. -- activateIdxList = { [idx] = 1, [idx2] = 1,},--当前激活加成属性在配置中的索引列表
  8. -- heroList = {},
  9. -- rewardGetList = {} -- 酒馆奖励领取列表
  10. -- }
  11. ]=]--
  12. local Msg = require("core.Msg")
  13. local HeroLogic = require("hero.HeroLogic")
  14. local Lang = require("common.Lang")
  15. local Broadcast = require("broadcast.Broadcast")
  16. local RoleAttr = require("role.RoleAttr")
  17. local RoleDefine = require("role.RoleDefine")
  18. local ObjHuman = require("core.ObjHuman")
  19. local Util = require("common.Util")
  20. local HeroPubCfg = require("excel.heroPub").pub
  21. local HeroGrid = require("hero.HeroGrid")
  22. local RoleSystemLogic = require("roleSystem.RoleSystemLogic")
  23. local RoleSystemDefine = require("roleSystem.RoleSystemDefine")
  24. local Grid = require("bag.Grid")
  25. local BagLogic = require("bag.BagLogic")
  26. local TalismanLogic = require("talisman.TalismanLogic")
  27. HERO_OP_UPSTAR = 1 -- 升星/合成
  28. HERO_OP_DEL = 2 -- 删除
  29. HERO_OP_RETURN = 3 -- 回退
  30. HERO_OP_ADD = 4 -- 获得
  31. local LOGTAG = "HeroPub"
  32. -- 获取来自秘宝的属性倍数加成
  33. local function getAttrMulFromTalisman(human)
  34. local attrMul = TalismanLogic.getTalismanAdd(human, TalismanLogic.OTHER_EFFECT_TBL.HeroPubLogic_Attr_Mul)
  35. attrMul = attrMul / 100
  36. return attrMul
  37. end
  38. local function initPubData(human)
  39. human.db.heroPubData = human.db.heroPubData or {}
  40. human.db.heroPubData.activateIdxList = human.db.heroPubData.activateIdxList or {}
  41. human.db.heroPubData.rewardGetList = human.db.heroPubData.rewardGetList or {}
  42. -- 新增
  43. -- if not human.db.heroPubData.rewardGetList then
  44. -- human.db.heroPubData.rewardGetList = {}
  45. -- end
  46. end
  47. local function getPubData(human)
  48. return human.db.heroPubData
  49. end
  50. local function updatePubData(human, opType, activateIdx)
  51. local heroPubData = getPubData(human)
  52. if not heroPubData then
  53. initPubData(human)
  54. heroPubData = getPubData(human)
  55. end
  56. if opType > 0 then
  57. heroPubData.activateIdxList[activateIdx] = 1
  58. else
  59. heroPubData.activateIdxList[activateIdx] = nil
  60. end
  61. end
  62. local function updateRewardGetList(human, rewardIdx)
  63. local heroPubData = getPubData(human)
  64. heroPubData.rewardGetList[rewardIdx] = '1'
  65. end
  66. -- 数据格式转换
  67. local function transformHeroData(human)
  68. local pubHeroList = human.pubHeroList
  69. if not pubHeroList or not next(pubHeroList) then
  70. return
  71. end
  72. local len = 0
  73. local heroInfoTbl = {}
  74. for _, heroInfo in pairs(pubHeroList) do
  75. len = len + 1
  76. heroInfoTbl[len] = heroInfo
  77. end
  78. return heroInfoTbl
  79. end
  80. local function isCanActivate(idxList, maxIdx)
  81. if maxIdx <= 0 then
  82. return false
  83. end
  84. for i=1, maxIdx do
  85. if not idxList[i] then
  86. return true
  87. end
  88. end
  89. return false
  90. end
  91. -- 计算当前符合条件的所有英雄的总星级
  92. local function calcAllHeroStar(heroList)
  93. local stars = 0
  94. for _, heroInfo in pairs(heroList or {}) do
  95. stars = stars + heroInfo.star
  96. end
  97. return stars
  98. end
  99. -- 根据星级,获得英雄酒馆加成属性在配置中的索引
  100. local function getPubAttrIdx(maxStarHeroList)
  101. local idx = 0
  102. local star = calcAllHeroStar(maxStarHeroList)
  103. if star <= 0 then
  104. return idx
  105. end
  106. for k, v in ipairs(HeroPubCfg) do
  107. if star < v.activateStar then
  108. break
  109. end
  110. idx = k
  111. end
  112. return idx
  113. end
  114. -- 重置缓存的酒馆英雄数据
  115. local function resetPubHeroList(human, newHeroList)
  116. if not human.pubHeroList then
  117. human.pubHeroList = {}
  118. else
  119. Util.initTable(human.pubHeroList)
  120. end
  121. for heroId, heroInfo in pairs(newHeroList) do
  122. human.pubHeroList[heroId] = {
  123. uuid = heroInfo.uuid,
  124. star = heroInfo.star
  125. }
  126. end
  127. end
  128. -- 更新战力
  129. local function updatePower(human)
  130. RoleAttr.cleanHeroAttrCache(human)
  131. ObjHuman.doCalc(human)
  132. ObjHuman.sendAttr(human, RoleDefine.ZHANDOULI)
  133. end
  134. -- 更新加成属性
  135. local function updatePubAttr(human)
  136. local heroPubData = getPubData(human)
  137. if not heroPubData then
  138. return
  139. end
  140. local bl = false
  141. local activateIdxList = heroPubData.activateIdxList
  142. local nowMaxAttrIdx = getPubAttrIdx(human.pubHeroList)
  143. local maxAttrIdx = #HeroPubCfg
  144. for i = nowMaxAttrIdx+1, maxAttrIdx do
  145. if activateIdxList[i] then
  146. updatePubData(human, 0, i)
  147. bl = true
  148. end
  149. end
  150. -- 只有加成属性降低才自动更新, 加成属性提高则需要手动更新...
  151. if bl then
  152. updatePower(human)
  153. end
  154. end
  155. -- 进行红点检测
  156. local function redDotCheck(human)
  157. RoleSystemLogic.onDot(human, RoleSystemDefine.ROLE_SYS_ID_304)
  158. end
  159. -- 获取宝箱红点状态
  160. local function getBoxRedDot(human)
  161. local heroPubData = getPubData(human)
  162. local nowMaxStar = calcAllHeroStar(human.pubHeroList)
  163. local rewardGetList = heroPubData and heroPubData.rewardGetList or {}
  164. for idx, starCfg in ipairs(HeroPubCfg) do
  165. if nowMaxStar >= starCfg.activateStar and not rewardGetList[idx] then
  166. return true
  167. end
  168. end
  169. return false
  170. end
  171. -- 更新酒馆的宝箱红点
  172. local function updateBoxRedDot(human)
  173. local msgRet = Msg.gc.GC_HEROPUB_BOX_REDDOT
  174. msgRet.redDotState = 0
  175. if getBoxRedDot(human) then
  176. msgRet.redDotState = 1
  177. end
  178. Msg.send(msgRet, human.fd)
  179. end
  180. -- 英雄升星/合成时的处理函数
  181. local function upgradeStarFunc(human, heroId, herouuid)
  182. local targetHerouuid
  183. local pubHeroList = human.pubHeroList
  184. local heroGrid = HeroLogic.getHeroGridByUuid(human, herouuid)
  185. local oldHeroInfo = pubHeroList[heroId]
  186. if heroGrid.star > oldHeroInfo.star then
  187. oldHeroInfo.uuid = herouuid
  188. oldHeroInfo.star = heroGrid.star
  189. targetHerouuid = herouuid
  190. end
  191. return targetHerouuid
  192. end
  193. -- 英雄回退/删除时的处理函数
  194. local function delHeroFunc(human, heroId, herouuid)
  195. local targetHerouuid, isDel
  196. local pubHeroList = human.pubHeroList
  197. if not pubHeroList or not next(pubHeroList) then
  198. return
  199. end
  200. -- 当前星级最高的英雄删除/回退了,
  201. if pubHeroList[heroId] and pubHeroList[heroId].uuid == herouuid then
  202. pubHeroList[heroId] = nil
  203. isDel = true
  204. -- 获取同ID的英雄中星级最高的
  205. local newMaxStar, newHerouuid = HeroLogic.GetMaxStarHero(human, heroId)
  206. if newMaxStar and newHerouuid then
  207. pubHeroList[heroId] = {uuid = newHerouuid, star = newMaxStar}
  208. targetHerouuid = newHerouuid
  209. end
  210. end
  211. return targetHerouuid, isDel
  212. end
  213. -- 获得英雄时的处理函数
  214. local function addHeroFunc(human, heroId, herouuid)
  215. local targetHerouuid
  216. local pubHeroList = human.pubHeroList
  217. local heroGrid = HeroLogic.getHeroGridByUuid(human, herouuid)
  218. if not pubHeroList or not pubHeroList[heroId] then
  219. targetHerouuid = herouuid
  220. else
  221. if pubHeroList[heroId] and pubHeroList[heroId].star < heroGrid.star then
  222. targetHerouuid = herouuid
  223. end
  224. end
  225. if targetHerouuid then
  226. human.pubHeroList = human.pubHeroList or {}
  227. human.pubHeroList[heroId] = human.pubHeroList[heroId] or {}
  228. human.pubHeroList[heroId].uuid = herouuid
  229. human.pubHeroList[heroId].star = heroGrid.star
  230. end
  231. return targetHerouuid
  232. end
  233. local function respondHeroInfo(human)
  234. local msgMax = 20
  235. local msgRet = Msg.gc.GC_HEROPUB_HERO_QUERY
  236. local msgHeroList = msgRet.heroList
  237. local heroInfoTbl = transformHeroData(human)
  238. if not heroInfoTbl then
  239. msgHeroList[0] = 0
  240. msgRet.start = 1
  241. msgRet.isEnd = 1
  242. Msg.send(msgRet, human.fd)
  243. else
  244. local len = 0
  245. local startTag = 1
  246. local maxLen =#heroInfoTbl
  247. for i=1, maxLen do
  248. len = len + 1
  249. msgHeroList[0] = len
  250. local net = { relic = {}, gemData = {}, general = {}}
  251. local heroGrid = HeroLogic.getHeroGridByUuid(human, heroInfoTbl[i].uuid)
  252. HeroGrid.makeHeroSimple(net, heroGrid, nil, human)
  253. msgHeroList[len].heroId = net.id
  254. msgHeroList[len].heroName = net.name
  255. msgHeroList[len].heroStar = net.star
  256. msgHeroList[len].heroCamp = net.camp
  257. msgHeroList[len].heroBody = net.body
  258. msgHeroList[len].heroGrade = net.grade
  259. if len >= msgMax then
  260. msgRet.start = startTag
  261. msgRet.isEnd = 0
  262. if maxLen - len <= 0 then
  263. msgRet.isEnd = 1
  264. return Msg.send(msgRet, human.fd)
  265. end
  266. Msg.send(msgRet, human.fd)
  267. len = 0
  268. startTag = 0
  269. maxLen = maxLen - msgMax
  270. end
  271. end
  272. if len > 0 then
  273. msgRet.start = startTag
  274. msgRet.isEnd = 1
  275. Msg.send(msgRet, human.fd)
  276. end
  277. end
  278. end
  279. local function respndAttrInfo(human)
  280. local msgMax = 20
  281. local startTag = 1
  282. local maxLen = #HeroPubCfg
  283. local heroPubData = getPubData(human)
  284. local nowMaxStar = calcAllHeroStar(human.pubHeroList)
  285. local attrMul = getAttrMulFromTalisman(human)
  286. attrMul = 1 + attrMul
  287. local msgRet = Msg.gc.GC_HEROPUB_ATTR_QUERY
  288. msgRet.star = nowMaxStar
  289. local attrList = msgRet.attrList
  290. local len = 0
  291. for i, cfg in ipairs(HeroPubCfg) do
  292. len = len + 1
  293. attrList[0] = len
  294. attrList[len].index = i
  295. attrList[len].isActivate = 0
  296. attrList[len].activateStar = cfg.activateStar
  297. if heroPubData and heroPubData.activateIdxList[i] then
  298. attrList[len].isActivate = 1
  299. end
  300. local attrInfo = attrList[len].attrInfo
  301. for k ,v in ipairs(cfg.attrs) do
  302. attrInfo[k].key = v[1]
  303. attrInfo[k].value = v[2] * attrMul
  304. attrInfo[0] = k
  305. end
  306. if len >= msgMax then
  307. msgRet.start = startTag
  308. msgRet.isEnd = 0
  309. if maxLen - len <= 0 then
  310. msgRet.isEnd = 1
  311. end
  312. Msg.send(msgRet, human.fd)
  313. len = 0
  314. startTag = 0
  315. maxLen = maxLen - msgMax
  316. end
  317. end
  318. if len > 0 then
  319. msgRet.start = startTag
  320. msgRet.isEnd = 1
  321. Msg.send(msgRet, human.fd)
  322. end
  323. end
  324. -- local function respondUpdateSingleHero(human, updateHerouuid, delHeroId)
  325. -- local msgRet = Msg.gc.GC_HEROPUB_UPDATE_HERO
  326. -- local net = { relic = {}, gemData = {}, general = {}}
  327. -- if updateHerouuid then
  328. -- local heroGrid = HeroLogic.getHeroGridByUuid(human, updateHerouuid)
  329. -- HeroGrid.makeHeroSimple(net, heroGrid, nil, human)
  330. -- end
  331. -- msgRet.updateHeroInfo.heroId = net.id or delHeroId
  332. -- msgRet.updateHeroInfo.heroName = net.name or ""
  333. -- msgRet.updateHeroInfo.heroStar = net.star or 0
  334. -- msgRet.updateHeroInfo.heroCamp = net.camp or 0
  335. -- msgRet.updateHeroInfo.heroBody = net.body or 0
  336. -- msgRet.updateHeroInfo.heroGrade = net.grade or 0
  337. -- Msg.send(msgRet, human.fd)
  338. -- end
  339. function onLogin(human)
  340. local maxStarHeroList = HeroLogic.GetHeroMaxStarList(human)
  341. if next(maxStarHeroList) then
  342. -- 缓存组成酒馆的英雄列表
  343. resetPubHeroList(human, maxStarHeroList)
  344. end
  345. end
  346. function doCalcHero(human, attrs)
  347. if not human then
  348. return
  349. end
  350. local heroPubData = getPubData(human)
  351. if not heroPubData then
  352. return
  353. end
  354. local attrMul = getAttrMulFromTalisman(human)
  355. attrMul = 1 + attrMul
  356. local activateIdxList = heroPubData.activateIdxList
  357. for k, v in ipairs(HeroPubCfg) do
  358. if activateIdxList[k] then
  359. for _, attrInfo in ipairs(v.attrs) do
  360. RoleAttr.updateValue(attrInfo[1], attrInfo[2] * attrMul, attrs)
  361. end
  362. end
  363. end
  364. end
  365. -- 英雄总star有更新(升星/合成, 回退, 删除, 增加)
  366. function UpdateHero(human, opType, heroId, herouuid)
  367. local updateHerouuid, isDel
  368. if opType == HERO_OP_UPSTAR then
  369. updateHerouuid = upgradeStarFunc(human, heroId, herouuid)
  370. elseif opType == HERO_OP_DEL then
  371. updateHerouuid, isDel = delHeroFunc(human, heroId, herouuid)
  372. elseif opType == HERO_OP_RETURN then
  373. updateHerouuid = delHeroFunc(human, heroId, herouuid)
  374. elseif opType == HERO_OP_ADD then
  375. updateHerouuid = addHeroFunc(human, heroId, herouuid)
  376. end
  377. local delHeroId = 0
  378. if opType == HERO_OP_DEL and not updateHerouuid and isDel then --英雄被删,且背包中没有同ID的英雄
  379. delHeroId = heroId
  380. end
  381. if updateHerouuid or delHeroId > 0 then
  382. redDotCheck(human)
  383. updatePubAttr(human)
  384. updateBoxRedDot(human)
  385. -- respondUpdateSingleHero(human, updateHerouuid, delHeroId)
  386. -- respndAttrInfo(human)
  387. end
  388. end
  389. --红点判断
  390. function isDot(human)
  391. local heroPubData = getPubData(human)
  392. local nowMaxAttrIdx = getPubAttrIdx(human.pubHeroList)
  393. if not heroPubData then
  394. if nowMaxAttrIdx <= 0 then
  395. return false
  396. else
  397. return true
  398. end
  399. end
  400. if isCanActivate(heroPubData.activateIdxList, nowMaxAttrIdx) then
  401. return true
  402. end
  403. if getBoxRedDot(human) then
  404. return true
  405. end
  406. return false
  407. end
  408. -- GM 设置激活
  409. function GM_SetAttrIdx(human, idx)
  410. if not idx then
  411. return Broadcast.sendErr(human, Lang.COMMON_ARGUMENT_ERROR)
  412. end
  413. if idx < 0 then
  414. idx = 0
  415. end
  416. local reallyIdx = getPubAttrIdx(human.pubHeroList)
  417. if idx > reallyIdx then
  418. idx = reallyIdx
  419. end
  420. -- if idx > #HeroPubCfg then
  421. -- idx = #HeroPubCfg
  422. -- end
  423. local heroPubData = getPubData(human)
  424. if heroPubData then
  425. Util.initTable(heroPubData.activateIdxList)
  426. end
  427. updatePubData(human, 1, idx)
  428. ObjHuman.GM_SaveDB(human)
  429. end
  430. -- 查询
  431. function PubQuery(human)
  432. respondHeroInfo(human)
  433. respndAttrInfo(human)
  434. updateBoxRedDot(human)
  435. end
  436. --激活属性
  437. function ActivatePubAtrr(human, targetIdx)
  438. local nowMaxIdx = getPubAttrIdx(human.pubHeroList)
  439. if targetIdx > nowMaxIdx then
  440. return Broadcast.sendErr(human, Lang.HEROPUB_STAR_NOT_ENOUGH)
  441. end
  442. local heroPubData = getPubData(human)
  443. if heroPubData and heroPubData.activateIdxList and heroPubData.activateIdxList[targetIdx] then
  444. return Broadcast.sendErr(human, Lang.BINGSHU_LEARN_ERR_HAD)
  445. end
  446. updatePubData(human, 1, targetIdx)
  447. local msgRet = Msg.gc.GC_HEROPUB_ACTIVATE
  448. msgRet.index = targetIdx
  449. Msg.send(msgRet, human.fd)
  450. --更新战力
  451. updatePower(human)
  452. --红点检测
  453. redDotCheck(human)
  454. end
  455. -- 奖励查询
  456. function RewardQuery(human)
  457. local msgMax = 10
  458. local startTag, len = 1, 0
  459. local maxLen = #HeroPubCfg
  460. local heroPubData = getPubData(human)
  461. local rewardGetList = heroPubData and heroPubData.rewardGetList
  462. local nowMaxStar = calcAllHeroStar(human.pubHeroList)
  463. local msgRet = Msg.gc.GC_HEROPUB_REWARD_QUERY
  464. msgRet.nowStar = nowMaxStar
  465. msgRet.isEnd = 0
  466. local rewardList = msgRet.rewardList
  467. for idx, starCfg in ipairs(HeroPubCfg) do
  468. len = len + 1
  469. rewardList[len].reallyIdx = idx
  470. rewardList[len].condStar = starCfg.activateStar
  471. rewardList[len].state = 0
  472. if nowMaxStar >= starCfg.activateStar then
  473. rewardList[len].state = 1
  474. end
  475. if rewardGetList and rewardGetList[idx] then
  476. rewardList[len].state = 2
  477. end
  478. local itemArray = rewardList[len].itemArray
  479. for k, itemCfg in ipairs(starCfg.reward) do
  480. itemArray[0] = k
  481. Grid.makeItem(itemArray[k], itemCfg[1], itemCfg[2])
  482. end
  483. if len >= msgMax then
  484. rewardList[0] = len
  485. msgRet.start = startTag
  486. maxLen = maxLen - len
  487. if maxLen <= 0 then
  488. msgRet.isEnd = 1
  489. end
  490. Msg.send(msgRet, human.fd)
  491. len = 0
  492. startTag = 0
  493. end
  494. end
  495. if len > 0 then
  496. rewardList[0] = len
  497. msgRet.start = startTag
  498. msgRet.isEnd = 1
  499. Msg.send(msgRet, human.fd)
  500. end
  501. end
  502. -- 奖励领取
  503. function RewardGet(human)
  504. local heroPubData = getPubData(human)
  505. if not heroPubData or not heroPubData.rewardGetList then
  506. initPubData(human)
  507. heroPubData = getPubData(human)
  508. end
  509. local rewardGetList = heroPubData.rewardGetList
  510. local nowMaxStar = calcAllHeroStar(human.pubHeroList)
  511. local itemList = {}
  512. for idx, starCfg in ipairs(HeroPubCfg) do
  513. if nowMaxStar >= starCfg.activateStar and not rewardGetList[idx] then
  514. for _, itemCfg in ipairs(starCfg.reward) do
  515. local itemId = itemCfg[1]
  516. itemList[itemId] = (itemList[itemId] or 0) + itemCfg[2]
  517. end
  518. updateRewardGetList(human, idx)
  519. end
  520. end
  521. BagLogic.addItemList(human, itemList, LOGTAG)
  522. RewardQuery(human)
  523. redDotCheck(human)
  524. updateBoxRedDot(human)
  525. end