HeroPubLogic.lua 17 KB

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