HeroPubLogic.lua 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510
  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 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. end
  221. Msg.send(msgRet, human.fd)
  222. len = 0
  223. startTag = 0
  224. maxLen = maxLen - msgMax
  225. end
  226. end
  227. msgRet.start = startTag
  228. msgRet.isEnd = 1
  229. Msg.send(msgRet, human.fd)
  230. end
  231. end
  232. local function respndAttrInfo(human)
  233. local msgMax = 20
  234. local startTag = 1
  235. local maxLen = #HeroPubCfg
  236. local heroPubData = getPubData(human)
  237. local nowMaxStar = calcAllHeroStar(human.pubHeroList)
  238. local msgRet = Msg.gc.GC_HEROPUB_ATTR_QUERY
  239. msgRet.star = nowMaxStar
  240. local attrList = msgRet.attrList
  241. local len = 0
  242. for i, cfg in ipairs(HeroPubCfg) do
  243. len = len + 1
  244. attrList[0] = len
  245. attrList[len].index = i
  246. attrList[len].isActivate = 0
  247. attrList[len].activateStar = cfg.activateStar
  248. if heroPubData and heroPubData.activateIdxList[i] then
  249. attrList[len].isActivate = 1
  250. end
  251. local attrInfo = attrList[len].attrInfo
  252. for k ,v in ipairs(cfg.attrs) do
  253. attrInfo[k].key = v[1]
  254. attrInfo[k].value = v[2]
  255. attrInfo[0] = k
  256. end
  257. if len >= msgMax then
  258. msgRet.start = startTag
  259. msgRet.isEnd = 0
  260. if maxLen - len <= 0 then
  261. msgRet.isEnd = 1
  262. end
  263. Msg.send(msgRet, human.fd)
  264. len = 0
  265. startTag = 0
  266. maxLen = maxLen - msgMax
  267. end
  268. end
  269. msgRet.start = startTag
  270. msgRet.isEnd = 1
  271. Msg.send(msgRet, human.fd)
  272. end
  273. local function respondUpdateSingleHero(human, updateHerouuid, delHeroId)
  274. local msgRet = Msg.gc.GC_HEROPUB_UPDATE_HERO
  275. local net = { relic = {}, gemData = {}, general = {}}
  276. if updateHerouuid then
  277. local heroGrid = HeroLogic.getHeroGridByUuid(human, updateHerouuid)
  278. HeroGrid.makeHeroSimple(net, heroGrid, nil, human)
  279. end
  280. msgRet.updateHeroInfo.heroId = net.id or delHeroId
  281. msgRet.updateHeroInfo.heroName = net.name or ""
  282. msgRet.updateHeroInfo.heroStar = net.star or 0
  283. msgRet.updateHeroInfo.heroCamp = net.camp or 0
  284. msgRet.updateHeroInfo.heroBody = net.body or 0
  285. msgRet.updateHeroInfo.heroGrade = net.grade or 0
  286. Msg.send(msgRet, human.fd)
  287. end
  288. function onLogin(human)
  289. local maxStarHeroList = HeroLogic.GetHeroMaxStarList(human)
  290. if next(maxStarHeroList) then
  291. -- 缓存组成酒馆的英雄列表
  292. resetPubHeroList(human, maxStarHeroList)
  293. end
  294. end
  295. function doCalcHero(human, attrs)
  296. if not human then
  297. return
  298. end
  299. local heroPubData = getPubData(human)
  300. if not heroPubData then
  301. return
  302. end
  303. local activateIdxList = heroPubData.activateIdxList
  304. for k, v in ipairs(HeroPubCfg) do
  305. if activateIdxList[k] then
  306. for _, attrInfo in ipairs(v.attrs) do
  307. RoleAttr.updateValue(attrInfo[1], attrInfo[2], attrs)
  308. end
  309. end
  310. end
  311. end
  312. -- 英雄总star有更新(升星/合成, 回退, 删除, 增加)
  313. function UpdateHero(human, opType, heroId, herouuid)
  314. local updateHerouuid, isDel
  315. if opType == HERO_OP_UPSTAR then
  316. updateHerouuid = upgradeStarFunc(human, heroId, herouuid)
  317. elseif opType == HERO_OP_DEL then
  318. updateHerouuid, isDel = delHeroFunc(human, heroId, herouuid)
  319. elseif opType == HERO_OP_RETURN then
  320. updateHerouuid = delHeroFunc(human, heroId, herouuid)
  321. elseif opType == HERO_OP_ADD then
  322. updateHerouuid = addHeroFunc(human, heroId, herouuid)
  323. end
  324. local delHeroId = 0
  325. if opType == HERO_OP_DEL and not updateHerouuid and isDel then --英雄被删,且背包中没有同ID的英雄
  326. delHeroId = heroId
  327. end
  328. if updateHerouuid or delHeroId > 0 then
  329. redDotCheck(human)
  330. updatePubAttr(human)
  331. -- respondUpdateSingleHero(human, updateHerouuid, delHeroId)
  332. -- respndAttrInfo(human)
  333. end
  334. end
  335. --红点判断
  336. function isDot(human)
  337. local heroPubData = getPubData(human)
  338. local nowMaxAttrIdx = getPubAttrIdx(human.pubHeroList)
  339. if not heroPubData then
  340. if nowMaxAttrIdx <= 0 then
  341. return false
  342. else
  343. return true
  344. end
  345. end
  346. if isCanActivate(heroPubData.activateIdxList, nowMaxAttrIdx) then
  347. return true
  348. end
  349. return false
  350. end
  351. -- GM 设置激活
  352. function GM_SetAttrIdx(human, idx)
  353. if not idx then
  354. return Broadcast.sendErr(human, Lang.COMMON_ARGUMENT_ERROR)
  355. end
  356. if idx < 0 then
  357. idx = 0
  358. end
  359. local reallyIdx = getPubAttrIdx(human.pubHeroList)
  360. if idx > reallyIdx then
  361. idx = reallyIdx
  362. end
  363. -- if idx > #HeroPubCfg then
  364. -- idx = #HeroPubCfg
  365. -- end
  366. updatePubData(human, 1, idx)
  367. ObjHuman.GM_SaveDB(human)
  368. end
  369. -- 查询
  370. function PubQuery(human)
  371. respondHeroInfo(human)
  372. respndAttrInfo(human)
  373. end
  374. --激活属性
  375. function ActivatePubAtrr(human, targetIdx)
  376. local nowMaxIdx = getPubAttrIdx(human.pubHeroList)
  377. if targetIdx > nowMaxIdx then
  378. return Broadcast.sendErr(human, Lang.HEROPUB_STAR_NOT_ENOUGH)
  379. end
  380. local heroPubData = getPubData(human)
  381. if heroPubData and heroPubData.activateIdxList and heroPubData.activateIdxList[targetIdx] then
  382. return Broadcast.sendErr(human, Lang.BINGSHU_LEARN_ERR_HAD)
  383. end
  384. updatePubData(human, 1, targetIdx)
  385. local msgRet = Msg.gc.GC_HEROPUB_ACTIVATE
  386. msgRet.index = targetIdx
  387. Msg.send(msgRet, human.fd)
  388. --更新战力
  389. updatePower(human)
  390. --红点检测
  391. redDotCheck(human)
  392. end