HeroTianYuan.lua 12 KB

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