HeroTianYuan.lua 12 KB

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