HeroPubLogic.lua 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517
  1. -- 英雄酒馆功能
  2. -- 统计SSR和UR英雄中不同ID英雄的最高星级,并根据星级获得加成属性
  3. -- db
  4. --[=[
  5. human.db.heroPubData = nil
  6. -- {
  7. -- activateIdxList = { [idx] = 1, [idx2] = 1,},--当前激活加成属性在配置中的索引列表
  8. -- heroList = {}
  9. -- }
  10. ]=]--
  11. local Msg = require("core.Msg")
  12. local HeroLogic = require("hero.HeroLogic")
  13. local Lang = require("common.Lang")
  14. local Broadcast = require("broadcast.Broadcast")
  15. local RoleAttr = require("role.RoleAttr")
  16. local RoleDefine = require("role.RoleDefine")
  17. local ObjHuman = require("core.ObjHuman")
  18. local Util = require("common.Util")
  19. local HeroPubCfg = require("excel.heroPub").pub
  20. local HeroGrid = require("hero.HeroGrid")
  21. local RoleSystemLogic = require("roleSystem.RoleSystemLogic")
  22. local RoleSystemDefine = require("roleSystem.RoleSystemDefine")
  23. HERO_OP_UPSTAR = 1 -- 升星/合成
  24. HERO_OP_DEL = 2 -- 删除
  25. HERO_OP_RETURN = 3 -- 回退
  26. HERO_OP_ADD = 4 -- 获得
  27. local function initPubData(human)
  28. human.db.heroPubData = {}
  29. human.db.heroPubData.activateIdxList = {}
  30. end
  31. local function getPubData(human)
  32. return human.db.heroPubData
  33. end
  34. local function updatePubData(human, opType, activateIdx)
  35. local heroPubData = getPubData(human)
  36. if not heroPubData then
  37. initPubData(human)
  38. heroPubData = getPubData(human)
  39. end
  40. if opType > 0 then
  41. heroPubData.activateIdxList[activateIdx] = 1
  42. else
  43. heroPubData.activateIdxList[activateIdx] = nil
  44. end
  45. end
  46. -- 数据格式转换
  47. local function transformHeroData(human)
  48. local pubHeroList = human.pubHeroList
  49. if not pubHeroList or not next(pubHeroList) then
  50. return
  51. end
  52. local len = 0
  53. local heroInfoTbl = {}
  54. for _, heroInfo in pairs(pubHeroList) do
  55. len = len + 1
  56. heroInfoTbl[len] = heroInfo
  57. end
  58. return heroInfoTbl
  59. end
  60. local function isCanActivate(idxList, maxIdx)
  61. if maxIdx <= 0 then
  62. return false
  63. end
  64. for i=1, maxIdx do
  65. if not idxList[i] then
  66. return true
  67. end
  68. end
  69. return false
  70. end
  71. -- 计算当前符合条件的所有英雄的总星级
  72. local function calcAllHeroStar(heroList)
  73. local stars = 0
  74. for _, heroInfo in pairs(heroList or {}) do
  75. stars = stars + heroInfo.star
  76. end
  77. return stars
  78. end
  79. -- 根据星级,获得英雄酒馆加成属性在配置中的索引
  80. local function getPubAttrIdx(maxStarHeroList)
  81. local idx = 0
  82. local star = calcAllHeroStar(maxStarHeroList)
  83. if star <= 0 then
  84. return idx
  85. end
  86. for k, v in ipairs(HeroPubCfg) do
  87. if star < v.activateStar then
  88. break
  89. end
  90. idx = k
  91. end
  92. return idx
  93. end
  94. -- 重置缓存的酒馆英雄数据
  95. local function resetPubHeroList(human, newHeroList)
  96. if not human.pubHeroList then
  97. human.pubHeroList = {}
  98. else
  99. Util.initTable(human.pubHeroList)
  100. end
  101. for heroId, heroInfo in pairs(newHeroList) do
  102. human.pubHeroList[heroId] = {
  103. uuid = heroInfo.uuid,
  104. star = heroInfo.star
  105. }
  106. end
  107. end
  108. -- 更新战力
  109. local function updatePower(human)
  110. RoleAttr.cleanHeroAttrCache(human)
  111. ObjHuman.doCalc(human)
  112. ObjHuman.sendAttr(human, RoleDefine.ZHANDOULI)
  113. end
  114. -- 更新加成属性
  115. local function updatePubAttr(human)
  116. local heroPubData = getPubData(human)
  117. if not heroPubData then
  118. return
  119. end
  120. local bl = false
  121. local activateIdxList = heroPubData.activateIdxList
  122. local nowMaxAttrIdx = getPubAttrIdx(human.pubHeroList)
  123. local maxAttrIdx = #HeroPubCfg
  124. for i = nowMaxAttrIdx+1, maxAttrIdx do
  125. if activateIdxList[i] then
  126. updatePubData(human, 0, i)
  127. bl = true
  128. end
  129. end
  130. -- 只有加成属性降低才自动更新, 加成属性提高则需要手动更新...
  131. if bl then
  132. updatePower(human)
  133. end
  134. end
  135. -- 进行红点检测
  136. local function redDotCheck(human)
  137. RoleSystemLogic.onDot(human, RoleSystemDefine.ROLE_SYS_ID_304)
  138. end
  139. -- 英雄升星/合成时的处理函数
  140. local function upgradeStarFunc(human, heroId, herouuid)
  141. local targetHerouuid
  142. local pubHeroList = human.pubHeroList
  143. local heroGrid = HeroLogic.getHeroGridByUuid(human, herouuid)
  144. local oldHeroInfo = pubHeroList[heroId]
  145. if heroGrid.star > oldHeroInfo.star then
  146. oldHeroInfo.uuid = herouuid
  147. oldHeroInfo.star = heroGrid.star
  148. targetHerouuid = herouuid
  149. end
  150. return targetHerouuid
  151. end
  152. -- 英雄回退/删除时的处理函数
  153. local function delHeroFunc(human, heroId, herouuid)
  154. local targetHerouuid, isDel
  155. local pubHeroList = human.pubHeroList
  156. -- 当前星级最高的英雄删除/回退了,
  157. if pubHeroList[heroId] and pubHeroList[heroId].uuid == herouuid then
  158. pubHeroList[heroId] = nil
  159. isDel = true
  160. -- 获取同ID的英雄中星级最高的
  161. local newMaxStar, newHerouuid = HeroLogic.GetMaxStarHero(human, heroId)
  162. if newMaxStar and newHerouuid then
  163. pubHeroList[heroId] = {uuid = newHerouuid, star = newMaxStar}
  164. targetHerouuid = newHerouuid
  165. end
  166. end
  167. return targetHerouuid, isDel
  168. end
  169. -- 获得英雄时的处理函数
  170. local function addHeroFunc(human, heroId, herouuid)
  171. local targetHerouuid
  172. local pubHeroList = human.pubHeroList
  173. local heroGrid = HeroLogic.getHeroGridByUuid(human, herouuid)
  174. if not pubHeroList or not pubHeroList[heroId] then
  175. targetHerouuid = herouuid
  176. else
  177. if pubHeroList[heroId] and pubHeroList[heroId].star < heroGrid.star then
  178. targetHerouuid = herouuid
  179. end
  180. end
  181. if targetHerouuid then
  182. human.pubHeroList = human.pubHeroList or {}
  183. human.pubHeroList[heroId] = human.pubHeroList[heroId] or {}
  184. human.pubHeroList[heroId].uuid = herouuid
  185. human.pubHeroList[heroId].star = heroGrid.star
  186. end
  187. return targetHerouuid
  188. end
  189. local function respondHeroInfo(human)
  190. local msgMax = 20
  191. local msgRet = Msg.gc.GC_HEROPUB_HERO_QUERY
  192. local msgHeroList = msgRet.heroList
  193. local heroInfoTbl = transformHeroData(human)
  194. if not heroInfoTbl then
  195. msgHeroList[0] = 0
  196. msgRet.start = 1
  197. msgRet.isEnd = 1
  198. Msg.send(msgRet, human.fd)
  199. else
  200. local len = 0
  201. local startTag = 1
  202. local maxLen =#heroInfoTbl
  203. for i=1, maxLen do
  204. len = len + 1
  205. msgHeroList[0] = len
  206. local net = { relic = {}, gemData = {}, general = {}}
  207. local heroGrid = HeroLogic.getHeroGridByUuid(human, heroInfoTbl[i].uuid)
  208. HeroGrid.makeHeroSimple(net, heroGrid, nil, human)
  209. msgHeroList[len].heroId = net.id
  210. msgHeroList[len].heroName = net.name
  211. msgHeroList[len].heroStar = net.star
  212. msgHeroList[len].heroCamp = net.camp
  213. msgHeroList[len].heroBody = net.body
  214. msgHeroList[len].heroGrade = net.grade
  215. if len >= msgMax then
  216. msgRet.start = startTag
  217. msgRet.isEnd = 0
  218. if maxLen - len <= 0 then
  219. msgRet.isEnd = 1
  220. return Msg.send(msgRet, human.fd)
  221. end
  222. Msg.send(msgRet, human.fd)
  223. len = 0
  224. startTag = 0
  225. maxLen = maxLen - msgMax
  226. end
  227. end
  228. msgRet.start = startTag
  229. msgRet.isEnd = 1
  230. Msg.send(msgRet, human.fd)
  231. end
  232. end
  233. local function respndAttrInfo(human)
  234. local msgMax = 20
  235. local startTag = 1
  236. local maxLen = #HeroPubCfg
  237. local heroPubData = getPubData(human)
  238. local nowMaxStar = calcAllHeroStar(human.pubHeroList)
  239. local msgRet = Msg.gc.GC_HEROPUB_ATTR_QUERY
  240. msgRet.star = nowMaxStar
  241. local attrList = msgRet.attrList
  242. local len = 0
  243. for i, cfg in ipairs(HeroPubCfg) do
  244. len = len + 1
  245. attrList[0] = len
  246. attrList[len].index = i
  247. attrList[len].isActivate = 0
  248. attrList[len].activateStar = cfg.activateStar
  249. if heroPubData and heroPubData.activateIdxList[i] then
  250. attrList[len].isActivate = 1
  251. end
  252. local attrInfo = attrList[len].attrInfo
  253. for k ,v in ipairs(cfg.attrs) do
  254. attrInfo[k].key = v[1]
  255. attrInfo[k].value = v[2]
  256. attrInfo[0] = k
  257. end
  258. if len >= msgMax then
  259. msgRet.start = startTag
  260. msgRet.isEnd = 0
  261. if maxLen - len <= 0 then
  262. msgRet.isEnd = 1
  263. end
  264. Msg.send(msgRet, human.fd)
  265. len = 0
  266. startTag = 0
  267. maxLen = maxLen - msgMax
  268. end
  269. end
  270. msgRet.start = startTag
  271. msgRet.isEnd = 1
  272. Msg.send(msgRet, human.fd)
  273. end
  274. local function respondUpdateSingleHero(human, updateHerouuid, delHeroId)
  275. local msgRet = Msg.gc.GC_HEROPUB_UPDATE_HERO
  276. local net = { relic = {}, gemData = {}, general = {}}
  277. if updateHerouuid then
  278. local heroGrid = HeroLogic.getHeroGridByUuid(human, updateHerouuid)
  279. HeroGrid.makeHeroSimple(net, heroGrid, nil, human)
  280. end
  281. msgRet.updateHeroInfo.heroId = net.id or delHeroId
  282. msgRet.updateHeroInfo.heroName = net.name or ""
  283. msgRet.updateHeroInfo.heroStar = net.star or 0
  284. msgRet.updateHeroInfo.heroCamp = net.camp or 0
  285. msgRet.updateHeroInfo.heroBody = net.body or 0
  286. msgRet.updateHeroInfo.heroGrade = net.grade or 0
  287. Msg.send(msgRet, human.fd)
  288. end
  289. function onLogin(human)
  290. local maxStarHeroList = HeroLogic.GetHeroMaxStarList(human)
  291. if next(maxStarHeroList) then
  292. -- 缓存组成酒馆的英雄列表
  293. resetPubHeroList(human, maxStarHeroList)
  294. end
  295. end
  296. function doCalcHero(human, attrs)
  297. if not human then
  298. return
  299. end
  300. local heroPubData = getPubData(human)
  301. if not heroPubData then
  302. return
  303. end
  304. local activateIdxList = heroPubData.activateIdxList
  305. for k, v in ipairs(HeroPubCfg) do
  306. if activateIdxList[k] then
  307. for _, attrInfo in ipairs(v.attrs) do
  308. RoleAttr.updateValue(attrInfo[1], attrInfo[2], attrs)
  309. end
  310. end
  311. end
  312. end
  313. -- 英雄总star有更新(升星/合成, 回退, 删除, 增加)
  314. function UpdateHero(human, opType, heroId, herouuid)
  315. local updateHerouuid, isDel
  316. if opType == HERO_OP_UPSTAR then
  317. updateHerouuid = upgradeStarFunc(human, heroId, herouuid)
  318. elseif opType == HERO_OP_DEL then
  319. updateHerouuid, isDel = delHeroFunc(human, heroId, herouuid)
  320. elseif opType == HERO_OP_RETURN then
  321. updateHerouuid = delHeroFunc(human, heroId, herouuid)
  322. elseif opType == HERO_OP_ADD then
  323. updateHerouuid = addHeroFunc(human, heroId, herouuid)
  324. end
  325. local delHeroId = 0
  326. if opType == HERO_OP_DEL and not updateHerouuid and isDel then --英雄被删,且背包中没有同ID的英雄
  327. delHeroId = heroId
  328. end
  329. if updateHerouuid or delHeroId > 0 then
  330. redDotCheck(human)
  331. updatePubAttr(human)
  332. -- respondUpdateSingleHero(human, updateHerouuid, delHeroId)
  333. -- respndAttrInfo(human)
  334. end
  335. end
  336. --红点判断
  337. function isDot(human)
  338. local heroPubData = getPubData(human)
  339. local nowMaxAttrIdx = getPubAttrIdx(human.pubHeroList)
  340. if not heroPubData then
  341. if nowMaxAttrIdx <= 0 then
  342. return false
  343. else
  344. return true
  345. end
  346. end
  347. if isCanActivate(heroPubData.activateIdxList, nowMaxAttrIdx) then
  348. return true
  349. end
  350. return false
  351. end
  352. -- GM 设置激活
  353. function GM_SetAttrIdx(human, idx)
  354. if not idx then
  355. return Broadcast.sendErr(human, Lang.COMMON_ARGUMENT_ERROR)
  356. end
  357. if idx < 0 then
  358. idx = 0
  359. end
  360. local reallyIdx = getPubAttrIdx(human.pubHeroList)
  361. if idx > reallyIdx then
  362. idx = reallyIdx
  363. end
  364. -- if idx > #HeroPubCfg then
  365. -- idx = #HeroPubCfg
  366. -- end
  367. local heroPubData = getPubData(human)
  368. if heroPubData then
  369. Util.initTable(heroPubData.activateIdxList)
  370. end
  371. updatePubData(human, 1, idx)
  372. ObjHuman.GM_SaveDB(human)
  373. end
  374. -- 查询
  375. function PubQuery(human)
  376. respondHeroInfo(human)
  377. respndAttrInfo(human)
  378. end
  379. --激活属性
  380. function ActivatePubAtrr(human, targetIdx)
  381. local nowMaxIdx = getPubAttrIdx(human.pubHeroList)
  382. if targetIdx > nowMaxIdx then
  383. return Broadcast.sendErr(human, Lang.HEROPUB_STAR_NOT_ENOUGH)
  384. end
  385. local heroPubData = getPubData(human)
  386. if heroPubData and heroPubData.activateIdxList and heroPubData.activateIdxList[targetIdx] then
  387. return Broadcast.sendErr(human, Lang.BINGSHU_LEARN_ERR_HAD)
  388. end
  389. updatePubData(human, 1, targetIdx)
  390. local msgRet = Msg.gc.GC_HEROPUB_ACTIVATE
  391. msgRet.index = targetIdx
  392. Msg.send(msgRet, human.fd)
  393. --更新战力
  394. updatePower(human)
  395. --红点检测
  396. redDotCheck(human)
  397. end