HeroTianYuan.lua 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406
  1. -- 天元系统
  2. local Lang = require("common.Lang")
  3. local Msg = require("core.Msg")
  4. local BagLogic = require("bag.BagLogic")
  5. local HeroLogic = require("hero.HeroLogic")
  6. local ObjHuman = require("core.ObjHuman")
  7. local Grid = require("bag.Grid")
  8. local RoleAttr = require("role.RoleAttr")
  9. local HeroTianYuanCfg = require("excel.heroTianYuan")
  10. local Broadcast = require("broadcast.Broadcast")
  11. local RoleDefine = require("role.RoleDefine")
  12. local LOGTAG = "HeroTianYuan" --日志标识
  13. local function initData(heroGrid)
  14. heroGrid.tianYuanData = {
  15. pointIdx = 0,
  16. stage = 0,
  17. }
  18. end
  19. local function updateData(heroGrid, newPointIdx, newStage)
  20. if not heroGrid.tianYuanData then
  21. initData(heroGrid)
  22. end
  23. if newPointIdx then
  24. heroGrid.tianYuanData.pointIdx = newPointIdx
  25. end
  26. if newStage then
  27. heroGrid.tianYuanData.stage = newStage
  28. end
  29. end
  30. -- 系统开启条件检查
  31. local function openCheck(human, heroID, heroIndex)
  32. local heroGrid = HeroLogic.getHeroGrid(human, heroID, heroIndex)
  33. if not heroGrid then
  34. return Broadcast.sendErr(human, Lang.FUWEN_HERO_GRID_ERR)
  35. end
  36. local varCfg = HeroTianYuanCfg.var[1]
  37. if heroGrid.star < varCfg.unLockCondStar then
  38. return Broadcast.sendErr(human, Lang.HEROPUB_STAR_NOT_ENOUGH)
  39. end
  40. return true
  41. end
  42. -- 获取正确的消耗道具信息
  43. local function getTargetItemArr(nowStage, nowPointIdx, maxStage)
  44. local varCfg = HeroTianYuanCfg.var[1]
  45. local targetStageCfgIdx = math.min(nowStage + 1, maxStage)
  46. local targetStageCfg = HeroTianYuanCfg.upGrade[targetStageCfgIdx]
  47. local itemCfg
  48. if nowPointIdx < varCfg.pointMaxNum and nowStage < maxStage then
  49. itemCfg = targetStageCfg.pointCost
  50. else
  51. itemCfg = targetStageCfg.stageCost
  52. end
  53. local itemArr = {}
  54. for i, itemInfo in ipairs(itemCfg) do
  55. itemArr[i] = { itemInfo[1], itemInfo[2] }
  56. end
  57. return itemArr
  58. end
  59. local function transformData(targetList, sourceArr, mul)
  60. mul = mul or 1
  61. for _, tb in ipairs(sourceArr) do
  62. local id = tb[1]
  63. local val = tb[2]
  64. targetList[id] = (targetList[id] or 0) + val * mul
  65. end
  66. end
  67. -- 统计数据, dataType: 1-加成属性, 2-消耗道具
  68. local function calcData(nowStage, nowPointIdx, dataType)
  69. if nowStage <= 0 and nowPointIdx <= 0 then
  70. return
  71. end
  72. local dataList = {}
  73. local maxPointNum = HeroTianYuanCfg.var[1].pointMaxNum
  74. for i = 1, nowStage do
  75. -- 天元突破的消耗道具/加成属性
  76. local stageCfg = HeroTianYuanCfg.upGrade[i]
  77. if stageCfg then
  78. local sourceData = stageCfg.stageCost
  79. if dataType == 1 then
  80. sourceData = stageCfg.stageAttrs
  81. end
  82. transformData(dataList, sourceData)
  83. end
  84. -- 天元点的消耗道具/加成属性
  85. stageCfg = HeroTianYuanCfg.upGrade[i+1]
  86. if stageCfg then
  87. local sourceData = stageCfg.pointCost
  88. local pointNum = 0
  89. if i == nowStage and nowPointIdx > 0 then
  90. pointNum = nowPointIdx
  91. elseif i ~= nowStage then
  92. pointNum = maxPointNum
  93. end
  94. if pointNum > 0 then
  95. if dataType == 1 then
  96. sourceData = stageCfg.pointAttrs
  97. end
  98. transformData(dataList, sourceData, pointNum)
  99. end
  100. end
  101. end
  102. -- 0 ~ 1重天元点的消耗道具/加成属性
  103. local pointNum = nowPointIdx
  104. if nowStage >= 1 then
  105. pointNum = maxPointNum
  106. end
  107. local stageOneCfg = HeroTianYuanCfg.upGrade[1]
  108. local sourceData = stageOneCfg.pointCost
  109. if dataType == 1 then
  110. sourceData = stageOneCfg.pointAttrs
  111. end
  112. transformData(dataList, sourceData, pointNum)
  113. return dataList
  114. end
  115. -- 获取下一次提升增加的属性
  116. local function getNextAttrs(nowStage, nowPointIdx, maxPointNum)
  117. nowStage = math.min(nowStage+1, #HeroTianYuanCfg.upGrade)
  118. local stageCfg = HeroTianYuanCfg.upGrade[nowStage]
  119. if nowPointIdx >= maxPointNum then -- 当前天元点已全部点亮, 需要突破天元
  120. return stageCfg.stageAttrs
  121. else
  122. return stageCfg.pointAttrs
  123. end
  124. end
  125. -- 更新战力
  126. local function updatePower(human, heroID, heroIndex)
  127. RoleAttr.cleanHeroAttrCache(human)
  128. RoleAttr.doCalc(human)
  129. HeroLogic.sendHeroBagDynamic(human, heroID, heroIndex)
  130. ObjHuman.sendAttr(human, RoleDefine.ZHANDOULI)
  131. end
  132. -- 英雄天元红点检测
  133. function isTianYuanDot(human, heroGrid)
  134. local varCfg = HeroTianYuanCfg.var[1]
  135. if heroGrid.star < varCfg.unLockCondStar then
  136. return false
  137. end
  138. local tianYuanData = heroGrid.tianYuanData
  139. local nowPointIdx = tianYuanData and tianYuanData.pointIdx or 0
  140. local nowStage = tianYuanData and tianYuanData.stage or 0
  141. local maxStage = #HeroTianYuanCfg.upGrade
  142. if nowStage >= maxStage then
  143. return false
  144. end
  145. local itemArr = getTargetItemArr(nowStage, nowPointIdx, maxStage)
  146. for _, item in ipairs(itemArr) do
  147. if BagLogic.getItemCnt(human, item[1]) < item[2] then
  148. return false
  149. end
  150. end
  151. return true
  152. end
  153. -- 计算返还材料
  154. function CalcReturnItem(human, heroGrid)
  155. if not heroGrid or not heroGrid.tianYuanData then
  156. return
  157. end
  158. local nowStage = heroGrid.tianYuanData.stage or 0
  159. local nowPointIdx = heroGrid.tianYuanData.pointIdx or 0
  160. local itemList = calcData(nowStage, nowPointIdx, 2)
  161. return itemList
  162. end
  163. -- 重置英雄天元数据
  164. function ResetTianYuanData(human, heroGrid)
  165. if not heroGrid or not heroGrid.tianYuanData then
  166. return
  167. end
  168. heroGrid.tianYuanData = nil
  169. end
  170. -- 英雄天元加成
  171. function doCalcHero(human, heroGrid, tatgetAttrs)
  172. if not heroGrid or not heroGrid.tianYuanData then
  173. return
  174. end
  175. local nowStage = heroGrid.tianYuanData.stage or 0
  176. local nowPointIdx = heroGrid.tianYuanData.pointIdx or 0
  177. local sourceAttrs = calcData(nowStage, nowPointIdx, 1)
  178. for attrId, attrVal in pairs(sourceAttrs or {}) do
  179. RoleAttr.updateValue(attrId, attrVal, tatgetAttrs)
  180. end
  181. end
  182. -- 查询英雄天元信息
  183. function HeroTianYuan_Query(human, heroID, heroIndex)
  184. local res = openCheck(human, heroID, heroIndex)
  185. if res ~= true then
  186. return
  187. end
  188. local maxPointNum = HeroTianYuanCfg.var[1].pointMaxNum
  189. local upGradeCfg = HeroTianYuanCfg.upGrade
  190. local heroGrid = HeroLogic.getHeroGrid(human, heroID, heroIndex)
  191. local tianYuanData = heroGrid.tianYuanData
  192. local nowPointIdx = tianYuanData and tianYuanData.pointIdx or 0
  193. local nowStage = tianYuanData and tianYuanData.stage or 0
  194. local msgRet = Msg.gc.GC_HEROTY_QUERY
  195. msgRet.pointIdx = nowPointIdx
  196. msgRet.stageIdx = nowStage
  197. msgRet.stageMax = #upGradeCfg
  198. msgRet.maxPoint = maxPointNum
  199. -- 消耗
  200. local itemArr = getTargetItemArr(nowStage, nowPointIdx, msgRet.stageMax)
  201. local item = itemArr[1]
  202. local itemId, itemCnt = item[1], item[2]
  203. if nowStage >= msgRet.stageMax then
  204. itemCnt = 0
  205. end
  206. Grid.makeItem(msgRet.cost, itemId, itemCnt)
  207. -- msgRet.cost[0] = #itemArr
  208. -- for i, item in ipairs(itemArr) do
  209. -- local itemId, itemCnt = item[1], item[2]
  210. -- if nowStage >= msgRet.stageMax then
  211. -- itemCnt = 0
  212. -- end
  213. -- Grid.makeItem(msgRet.cost[i], itemId, itemCnt)
  214. -- end
  215. -- 总加成属性
  216. msgRet.attrs[0] = 0
  217. local attrs = calcData(nowStage, nowPointIdx, 1)
  218. if attrs then
  219. local len = 0
  220. for attrId, attrVal in pairs(attrs) do
  221. len = len + 1
  222. msgRet.attrs[0] = len
  223. msgRet.attrs[len].key = attrId
  224. msgRet.attrs[len].value = attrVal
  225. end
  226. end
  227. -- 下一次提升增加的属性
  228. msgRet.nextAttrs[0] = 0
  229. if nowStage < msgRet.stageMax then
  230. local nextAttrs = getNextAttrs(nowStage, nowPointIdx, maxPointNum)
  231. if nextAttrs then
  232. msgRet.nextAttrs[0] = #nextAttrs
  233. for i, attrTb in ipairs(nextAttrs) do
  234. msgRet.nextAttrs[i].key = attrTb[1]
  235. msgRet.nextAttrs[i].value = attrTb[2]
  236. end
  237. end
  238. end
  239. Msg.send(msgRet, human.fd)
  240. end
  241. -- 请求点亮天元点
  242. function HeroTianYuan_PointUpGrade(human, heroID, heroIndex)
  243. local res = openCheck(human, heroID, heroIndex)
  244. if res ~= true then
  245. return
  246. end
  247. local heroGrid = HeroLogic.getHeroGrid(human, heroID, heroIndex)
  248. local varCfg = HeroTianYuanCfg.var[1]
  249. local tianYuanData = heroGrid.tianYuanData
  250. local nowPointIdx = tianYuanData and tianYuanData.pointIdx or 0
  251. local nowStage = tianYuanData and tianYuanData.stage or 0
  252. if nowPointIdx >= varCfg.pointMaxNum then
  253. return Broadcast.sendErr(human, Lang.HERO_TY_POINT_MAX)
  254. end
  255. if nowStage >= #HeroTianYuanCfg.upGrade then
  256. return Broadcast.sendErr(human, Lang.HERO_TY_STAGE_MAX)
  257. end
  258. local targetCfgIdx = nowStage + 1
  259. local targetStageCfg = HeroTianYuanCfg.upGrade[targetCfgIdx]
  260. if not targetStageCfg then
  261. return Broadcast.sendErr(human, Lang.COMMON_COMFIG_ERROR)
  262. end
  263. -- 消耗检查
  264. for _, itemInfo in ipairs(targetStageCfg.pointCost) do
  265. if BagLogic.getItemCnt(human, itemInfo[1]) < itemInfo[2] then
  266. return Broadcast.sendErr(human, Lang.COMMON_ITEM_NOT_ENOUGH)
  267. end
  268. end
  269. -- 扣除消耗
  270. for _, itemInfo in ipairs(targetStageCfg.pointCost) do
  271. BagLogic.delItem(human, itemInfo[1], itemInfo[2], LOGTAG)
  272. end
  273. -- 更新点亮天元点索引
  274. nowPointIdx = nowPointIdx + 1
  275. updateData(heroGrid, nowPointIdx)
  276. -- 推送最新数据给客户端
  277. HeroTianYuan_Query(human, heroID, heroIndex)
  278. -- 更新战力
  279. updatePower(human, heroID, heroIndex)
  280. -- 刷新红点
  281. HeroLogic.refreshDot(human, heroGrid.uuid)
  282. end
  283. -- 请求天元突破
  284. function HeroTianYuan_StageUpGrade(human, heroID, heroIndex)
  285. local res = openCheck(human, heroID, heroIndex)
  286. if res ~= true then
  287. return
  288. end
  289. local heroGrid = HeroLogic.getHeroGrid(human, heroID, heroIndex)
  290. local varCfg = HeroTianYuanCfg.var[1]
  291. local tianYuanData = heroGrid.tianYuanData
  292. local nowPointIdx = tianYuanData and tianYuanData.pointIdx or 0
  293. local nowStage = tianYuanData and tianYuanData.stage or 0
  294. if nowPointIdx < varCfg.pointMaxNum then
  295. return Broadcast.sendErr(human, Lang.HERO_TY_POINT_NOT_ENOUGH)
  296. end
  297. if nowStage >= #HeroTianYuanCfg.upGrade then
  298. return Broadcast.sendErr(human, Lang.HERO_TY_STAGE_MAX)
  299. end
  300. local nextStage = nowStage + 1
  301. local nextStageCfg = HeroTianYuanCfg.upGrade[nextStage]
  302. if not nextStageCfg then
  303. return Broadcast.sendErr(human, Lang.COMMON_COMFIG_ERROR)
  304. end
  305. -- 消耗检查
  306. for _, itemInfo in ipairs(nextStageCfg.stageCost) do
  307. if BagLogic.getItemCnt(human, itemInfo[1]) < itemInfo[2] then
  308. return Broadcast.sendErr(human, Lang.COMMON_ITEM_NOT_ENOUGH)
  309. end
  310. end
  311. -- 扣除消耗
  312. for _, itemInfo in ipairs(nextStageCfg.stageCost) do
  313. BagLogic.delItem(human, itemInfo[1], itemInfo[2], LOGTAG)
  314. end
  315. -- 更新天元点索引, 天元重数
  316. updateData(heroGrid, 0, nextStage)
  317. -- 推送最新数据给客户端
  318. HeroTianYuan_Query(human, heroID, heroIndex)
  319. -- 更新战力
  320. updatePower(human, heroID, heroIndex)
  321. -- 刷新红点
  322. HeroLogic.refreshDot(human, heroGrid.uuid)
  323. end