HeroPubLogic.lua 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649
  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. -- 当前星级最高的英雄删除/回退了,
  191. if pubHeroList[heroId] and pubHeroList[heroId].uuid == herouuid then
  192. pubHeroList[heroId] = nil
  193. isDel = true
  194. -- 获取同ID的英雄中星级最高的
  195. local newMaxStar, newHerouuid = HeroLogic.GetMaxStarHero(human, heroId)
  196. if newMaxStar and newHerouuid then
  197. pubHeroList[heroId] = {uuid = newHerouuid, star = newMaxStar}
  198. targetHerouuid = newHerouuid
  199. end
  200. end
  201. return targetHerouuid, isDel
  202. end
  203. -- 获得英雄时的处理函数
  204. local function addHeroFunc(human, heroId, herouuid)
  205. local targetHerouuid
  206. local pubHeroList = human.pubHeroList
  207. local heroGrid = HeroLogic.getHeroGridByUuid(human, herouuid)
  208. if not pubHeroList or not pubHeroList[heroId] then
  209. targetHerouuid = herouuid
  210. else
  211. if pubHeroList[heroId] and pubHeroList[heroId].star < heroGrid.star then
  212. targetHerouuid = herouuid
  213. end
  214. end
  215. if targetHerouuid then
  216. human.pubHeroList = human.pubHeroList or {}
  217. human.pubHeroList[heroId] = human.pubHeroList[heroId] or {}
  218. human.pubHeroList[heroId].uuid = herouuid
  219. human.pubHeroList[heroId].star = heroGrid.star
  220. end
  221. return targetHerouuid
  222. end
  223. local function respondHeroInfo(human)
  224. local msgMax = 20
  225. local msgRet = Msg.gc.GC_HEROPUB_HERO_QUERY
  226. local msgHeroList = msgRet.heroList
  227. local heroInfoTbl = transformHeroData(human)
  228. if not heroInfoTbl then
  229. msgHeroList[0] = 0
  230. msgRet.start = 1
  231. msgRet.isEnd = 1
  232. Msg.send(msgRet, human.fd)
  233. else
  234. local len = 0
  235. local startTag = 1
  236. local maxLen =#heroInfoTbl
  237. for i=1, maxLen do
  238. len = len + 1
  239. msgHeroList[0] = len
  240. local net = { relic = {}, gemData = {}, general = {}}
  241. local heroGrid = HeroLogic.getHeroGridByUuid(human, heroInfoTbl[i].uuid)
  242. HeroGrid.makeHeroSimple(net, heroGrid, nil, human)
  243. msgHeroList[len].heroId = net.id
  244. msgHeroList[len].heroName = net.name
  245. msgHeroList[len].heroStar = net.star
  246. msgHeroList[len].heroCamp = net.camp
  247. msgHeroList[len].heroBody = net.body
  248. msgHeroList[len].heroGrade = net.grade
  249. if len >= msgMax then
  250. msgRet.start = startTag
  251. msgRet.isEnd = 0
  252. if maxLen - len <= 0 then
  253. msgRet.isEnd = 1
  254. return Msg.send(msgRet, human.fd)
  255. end
  256. Msg.send(msgRet, human.fd)
  257. len = 0
  258. startTag = 0
  259. maxLen = maxLen - msgMax
  260. end
  261. end
  262. if len > 0 then
  263. msgRet.start = startTag
  264. msgRet.isEnd = 1
  265. Msg.send(msgRet, human.fd)
  266. end
  267. end
  268. end
  269. local function respndAttrInfo(human)
  270. local msgMax = 20
  271. local startTag = 1
  272. local maxLen = #HeroPubCfg
  273. local heroPubData = getPubData(human)
  274. local nowMaxStar = calcAllHeroStar(human.pubHeroList)
  275. local msgRet = Msg.gc.GC_HEROPUB_ATTR_QUERY
  276. msgRet.star = nowMaxStar
  277. local attrList = msgRet.attrList
  278. local len = 0
  279. for i, cfg in ipairs(HeroPubCfg) do
  280. len = len + 1
  281. attrList[0] = len
  282. attrList[len].index = i
  283. attrList[len].isActivate = 0
  284. attrList[len].activateStar = cfg.activateStar
  285. if heroPubData and heroPubData.activateIdxList[i] then
  286. attrList[len].isActivate = 1
  287. end
  288. local attrInfo = attrList[len].attrInfo
  289. for k ,v in ipairs(cfg.attrs) do
  290. attrInfo[k].key = v[1]
  291. attrInfo[k].value = v[2]
  292. attrInfo[0] = k
  293. end
  294. if len >= msgMax then
  295. msgRet.start = startTag
  296. msgRet.isEnd = 0
  297. if maxLen - len <= 0 then
  298. msgRet.isEnd = 1
  299. end
  300. Msg.send(msgRet, human.fd)
  301. len = 0
  302. startTag = 0
  303. maxLen = maxLen - msgMax
  304. end
  305. end
  306. if len > 0 then
  307. msgRet.start = startTag
  308. msgRet.isEnd = 1
  309. Msg.send(msgRet, human.fd)
  310. end
  311. end
  312. -- local function respondUpdateSingleHero(human, updateHerouuid, delHeroId)
  313. -- local msgRet = Msg.gc.GC_HEROPUB_UPDATE_HERO
  314. -- local net = { relic = {}, gemData = {}, general = {}}
  315. -- if updateHerouuid then
  316. -- local heroGrid = HeroLogic.getHeroGridByUuid(human, updateHerouuid)
  317. -- HeroGrid.makeHeroSimple(net, heroGrid, nil, human)
  318. -- end
  319. -- msgRet.updateHeroInfo.heroId = net.id or delHeroId
  320. -- msgRet.updateHeroInfo.heroName = net.name or ""
  321. -- msgRet.updateHeroInfo.heroStar = net.star or 0
  322. -- msgRet.updateHeroInfo.heroCamp = net.camp or 0
  323. -- msgRet.updateHeroInfo.heroBody = net.body or 0
  324. -- msgRet.updateHeroInfo.heroGrade = net.grade or 0
  325. -- Msg.send(msgRet, human.fd)
  326. -- end
  327. function onLogin(human)
  328. local maxStarHeroList = HeroLogic.GetHeroMaxStarList(human)
  329. if next(maxStarHeroList) then
  330. -- 缓存组成酒馆的英雄列表
  331. resetPubHeroList(human, maxStarHeroList)
  332. end
  333. end
  334. function doCalcHero(human, attrs)
  335. if not human then
  336. return
  337. end
  338. local heroPubData = getPubData(human)
  339. if not heroPubData then
  340. return
  341. end
  342. local activateIdxList = heroPubData.activateIdxList
  343. for k, v in ipairs(HeroPubCfg) do
  344. if activateIdxList[k] then
  345. for _, attrInfo in ipairs(v.attrs) do
  346. RoleAttr.updateValue(attrInfo[1], attrInfo[2], attrs)
  347. end
  348. end
  349. end
  350. end
  351. -- 英雄总star有更新(升星/合成, 回退, 删除, 增加)
  352. function UpdateHero(human, opType, heroId, herouuid)
  353. local updateHerouuid, isDel
  354. if opType == HERO_OP_UPSTAR then
  355. updateHerouuid = upgradeStarFunc(human, heroId, herouuid)
  356. elseif opType == HERO_OP_DEL then
  357. updateHerouuid, isDel = delHeroFunc(human, heroId, herouuid)
  358. elseif opType == HERO_OP_RETURN then
  359. updateHerouuid = delHeroFunc(human, heroId, herouuid)
  360. elseif opType == HERO_OP_ADD then
  361. updateHerouuid = addHeroFunc(human, heroId, herouuid)
  362. end
  363. local delHeroId = 0
  364. if opType == HERO_OP_DEL and not updateHerouuid and isDel then --英雄被删,且背包中没有同ID的英雄
  365. delHeroId = heroId
  366. end
  367. if updateHerouuid or delHeroId > 0 then
  368. redDotCheck(human)
  369. updatePubAttr(human)
  370. updateBoxRedDot(human)
  371. -- respondUpdateSingleHero(human, updateHerouuid, delHeroId)
  372. -- respndAttrInfo(human)
  373. end
  374. end
  375. --红点判断
  376. function isDot(human)
  377. local heroPubData = getPubData(human)
  378. local nowMaxAttrIdx = getPubAttrIdx(human.pubHeroList)
  379. if not heroPubData then
  380. if nowMaxAttrIdx <= 0 then
  381. return false
  382. else
  383. return true
  384. end
  385. end
  386. if isCanActivate(heroPubData.activateIdxList, nowMaxAttrIdx) then
  387. return true
  388. end
  389. if getBoxRedDot(human) then
  390. return true
  391. end
  392. return false
  393. end
  394. -- GM 设置激活
  395. function GM_SetAttrIdx(human, idx)
  396. if not idx then
  397. return Broadcast.sendErr(human, Lang.COMMON_ARGUMENT_ERROR)
  398. end
  399. if idx < 0 then
  400. idx = 0
  401. end
  402. local reallyIdx = getPubAttrIdx(human.pubHeroList)
  403. if idx > reallyIdx then
  404. idx = reallyIdx
  405. end
  406. -- if idx > #HeroPubCfg then
  407. -- idx = #HeroPubCfg
  408. -- end
  409. local heroPubData = getPubData(human)
  410. if heroPubData then
  411. Util.initTable(heroPubData.activateIdxList)
  412. end
  413. updatePubData(human, 1, idx)
  414. ObjHuman.GM_SaveDB(human)
  415. end
  416. -- 查询
  417. function PubQuery(human)
  418. respondHeroInfo(human)
  419. respndAttrInfo(human)
  420. updateBoxRedDot(human)
  421. end
  422. --激活属性
  423. function ActivatePubAtrr(human, targetIdx)
  424. local nowMaxIdx = getPubAttrIdx(human.pubHeroList)
  425. if targetIdx > nowMaxIdx then
  426. return Broadcast.sendErr(human, Lang.HEROPUB_STAR_NOT_ENOUGH)
  427. end
  428. local heroPubData = getPubData(human)
  429. if heroPubData and heroPubData.activateIdxList and heroPubData.activateIdxList[targetIdx] then
  430. return Broadcast.sendErr(human, Lang.BINGSHU_LEARN_ERR_HAD)
  431. end
  432. updatePubData(human, 1, targetIdx)
  433. local msgRet = Msg.gc.GC_HEROPUB_ACTIVATE
  434. msgRet.index = targetIdx
  435. Msg.send(msgRet, human.fd)
  436. --更新战力
  437. updatePower(human)
  438. --红点检测
  439. redDotCheck(human)
  440. end
  441. -- 奖励查询
  442. function RewardQuery(human)
  443. local msgMax = 10
  444. local startTag, len = 1, 0
  445. local maxLen = #HeroPubCfg
  446. local heroPubData = getPubData(human)
  447. local rewardGetList = heroPubData and heroPubData.rewardGetList
  448. local nowMaxStar = calcAllHeroStar(human.pubHeroList)
  449. local msgRet = Msg.gc.GC_HEROPUB_REWARD_QUERY
  450. msgRet.nowStar = nowMaxStar
  451. msgRet.isEnd = 0
  452. local rewardList = msgRet.rewardList
  453. for idx, starCfg in ipairs(HeroPubCfg) do
  454. len = len + 1
  455. rewardList[len].reallyIdx = idx
  456. rewardList[len].condStar = starCfg.activateStar
  457. rewardList[len].state = 0
  458. if nowMaxStar >= starCfg.activateStar then
  459. rewardList[len].state = 1
  460. end
  461. if rewardGetList and rewardGetList[idx] then
  462. rewardList[len].state = 2
  463. end
  464. local itemArray = rewardList[len].itemArray
  465. for k, itemCfg in ipairs(starCfg.reward) do
  466. itemArray[0] = k
  467. Grid.makeItem(itemArray[k], itemCfg[1], itemCfg[2])
  468. end
  469. if len >= msgMax then
  470. rewardList[0] = len
  471. msgRet.start = startTag
  472. maxLen = maxLen - len
  473. if maxLen <= 0 then
  474. msgRet.isEnd = 1
  475. end
  476. Msg.send(msgRet, human.fd)
  477. len = 0
  478. startTag = 0
  479. end
  480. end
  481. if len > 0 then
  482. rewardList[0] = len
  483. msgRet.start = startTag
  484. msgRet.isEnd = 1
  485. Msg.send(msgRet, human.fd)
  486. end
  487. end
  488. -- 奖励领取
  489. function RewardGet(human)
  490. local heroPubData = getPubData(human)
  491. if not heroPubData or not heroPubData.rewardGetList then
  492. initPubData(human)
  493. heroPubData = getPubData(human)
  494. end
  495. local rewardGetList = heroPubData.rewardGetList
  496. local nowMaxStar = calcAllHeroStar(human.pubHeroList)
  497. local itemList = {}
  498. for idx, starCfg in ipairs(HeroPubCfg) do
  499. if nowMaxStar >= starCfg.activateStar and not rewardGetList[idx] then
  500. for _, itemCfg in ipairs(starCfg.reward) do
  501. local itemId = itemCfg[1]
  502. itemList[itemId] = (itemList[itemId] or 0) + itemCfg[2]
  503. end
  504. updateRewardGetList(human, idx)
  505. end
  506. end
  507. BagLogic.addItemList(human, itemList, LOGTAG)
  508. RewardQuery(human)
  509. redDotCheck(human)
  510. updateBoxRedDot(human)
  511. end