-- 天元系统 local Lang = require("common.Lang") local Msg = require("core.Msg") local BagLogic = require("bag.BagLogic") local HeroLogic = require("hero.HeroLogic") local ObjHuman = require("core.ObjHuman") local Grid = require("bag.Grid") local RoleAttr = require("role.RoleAttr") local HeroTianYuanCfg = require("excel.heroTianYuan") local Broadcast = require("broadcast.Broadcast") local RoleDefine = require("role.RoleDefine") local TalismanLogic = require("talisman.TalismanLogic") local GiftLogic local LOGTAG = "HeroTianYuan" --日志标识 -- 获取来自秘宝的属性倍数加成 local function getAttrMulFromTalisman(human) local attrMul = TalismanLogic.getTalismanAdd(human, TalismanLogic.OTHER_EFFECT_TBL.HeroTianYuan_Attr_Mul) attrMul = attrMul / 100 return attrMul end local function initData(heroGrid) heroGrid.tianYuanData = { pointIdx = 0, stage = 0, } end local function updateData(heroGrid, newPointIdx, newStage) if not heroGrid.tianYuanData then initData(heroGrid) end if newPointIdx then heroGrid.tianYuanData.pointIdx = newPointIdx end if newStage then heroGrid.tianYuanData.stage = newStage end end -- 系统开启条件检查 local function openCheck(human, heroID, heroIndex) local heroGrid = HeroLogic.getHeroGrid(human, heroID, heroIndex) if not heroGrid then return Broadcast.sendErr(human, Lang.FUWEN_HERO_GRID_ERR) end local varCfg = HeroTianYuanCfg.var[1] if heroGrid.star < varCfg.unLockCondStar then return Broadcast.sendErr(human, Lang.HEROPUB_STAR_NOT_ENOUGH) end return true end -- 获取正确的消耗道具信息 local function getTargetItemArr(nowStage, nowPointIdx, maxStage) local varCfg = HeroTianYuanCfg.var[1] local targetStageCfgIdx = math.min(nowStage + 1, maxStage) local targetStageCfg = HeroTianYuanCfg.upGrade[targetStageCfgIdx] local itemCfg if nowPointIdx < varCfg.pointMaxNum and nowStage < maxStage then itemCfg = targetStageCfg.pointCost else itemCfg = targetStageCfg.stageCost end local itemArr = {} for i, itemInfo in ipairs(itemCfg) do itemArr[i] = { itemInfo[1], itemInfo[2] } end return itemArr end local function transformData(targetList, sourceArr, mul) mul = mul or 1 for _, tb in ipairs(sourceArr) do local id = tb[1] local val = tb[2] targetList[id] = (targetList[id] or 0) + val * mul end end -- 统计数据, dataType: 1-加成属性, 2-消耗道具 local function calcData(nowStage, nowPointIdx, dataType) if nowStage <= 0 and nowPointIdx <= 0 then return end local dataList = {} local maxPointNum = HeroTianYuanCfg.var[1].pointMaxNum for i = 1, nowStage do -- 天元突破的消耗道具/加成属性 local stageCfg = HeroTianYuanCfg.upGrade[i] if stageCfg then local sourceData = stageCfg.stageCost if dataType == 1 then sourceData = stageCfg.stageAttrs end transformData(dataList, sourceData) end -- 天元点的消耗道具/加成属性 stageCfg = HeroTianYuanCfg.upGrade[i+1] if stageCfg then local sourceData = stageCfg.pointCost local pointNum = 0 if i == nowStage and nowPointIdx > 0 then pointNum = nowPointIdx elseif i ~= nowStage then pointNum = maxPointNum end if pointNum > 0 then if dataType == 1 then sourceData = stageCfg.pointAttrs end transformData(dataList, sourceData, pointNum) end end end -- 0 ~ 1重天元点的消耗道具/加成属性 local pointNum = nowPointIdx if nowStage >= 1 then pointNum = maxPointNum end local stageOneCfg = HeroTianYuanCfg.upGrade[1] local sourceData = stageOneCfg.pointCost if dataType == 1 then sourceData = stageOneCfg.pointAttrs end transformData(dataList, sourceData, pointNum) return dataList end -- 获取下一次提升增加的属性 local function getNextAttrs(nowStage, nowPointIdx, maxPointNum) nowStage = math.min(nowStage+1, #HeroTianYuanCfg.upGrade) local stageCfg = HeroTianYuanCfg.upGrade[nowStage] if nowPointIdx >= maxPointNum then -- 当前天元点已全部点亮, 需要突破天元 return stageCfg.stageAttrs else return stageCfg.pointAttrs end end -- 更新战力 local function updatePower(human, heroID, heroIndex) RoleAttr.cleanHeroAttrCache(human) RoleAttr.doCalc(human) HeroLogic.sendHeroBagDynamic(human, heroID, heroIndex) ObjHuman.sendAttr(human, RoleDefine.ZHANDOULI) end -- 英雄天元红点检测 function isTianYuanDot(human, heroGrid) local varCfg = HeroTianYuanCfg.var[1] if heroGrid.star < varCfg.unLockCondStar then return false end local tianYuanData = heroGrid.tianYuanData local nowPointIdx = tianYuanData and tianYuanData.pointIdx or 0 local nowStage = tianYuanData and tianYuanData.stage or 0 local maxStage = #HeroTianYuanCfg.upGrade if nowStage >= maxStage then return false end local itemArr = getTargetItemArr(nowStage, nowPointIdx, maxStage) for _, item in ipairs(itemArr) do if BagLogic.getItemCnt(human, item[1]) < item[2] then return false end end return true end -- 计算返还材料 function CalcReturnItem(human, heroGrid) if not heroGrid or not heroGrid.tianYuanData then return end local nowStage = heroGrid.tianYuanData.stage or 0 local nowPointIdx = heroGrid.tianYuanData.pointIdx or 0 local itemList = calcData(nowStage, nowPointIdx, 2) return itemList end -- 重置英雄天元数据 function ResetTianYuanData(human, heroGrid) if not heroGrid or not heroGrid.tianYuanData then return end heroGrid.tianYuanData = nil end -- 英雄天元加成 function doCalcHero(human, heroGrid, tatgetAttrs) if not heroGrid or not heroGrid.tianYuanData then return end local nowStage = heroGrid.tianYuanData.stage or 0 local nowPointIdx = heroGrid.tianYuanData.pointIdx or 0 local sourceAttrs = calcData(nowStage, nowPointIdx, 1) local attrMul = getAttrMulFromTalisman(human) attrMul = 1 + attrMul for attrId, attrVal in pairs(sourceAttrs or {}) do RoleAttr.updateValue(attrId, attrVal * attrMul, tatgetAttrs) end end -- 查询英雄天元信息 function HeroTianYuan_Query(human, heroID, heroIndex) local res = openCheck(human, heroID, heroIndex) if res ~= true then return end local maxPointNum = HeroTianYuanCfg.var[1].pointMaxNum local upGradeCfg = HeroTianYuanCfg.upGrade local heroGrid = HeroLogic.getHeroGrid(human, heroID, heroIndex) local tianYuanData = heroGrid.tianYuanData local nowPointIdx = tianYuanData and tianYuanData.pointIdx or 0 local nowStage = tianYuanData and tianYuanData.stage or 0 local msgRet = Msg.gc.GC_HEROTY_QUERY msgRet.pointIdx = nowPointIdx msgRet.stageIdx = nowStage msgRet.stageMax = #upGradeCfg msgRet.maxPoint = maxPointNum -- 消耗 local itemArr = getTargetItemArr(nowStage, nowPointIdx, msgRet.stageMax) local item = itemArr[1] local itemId, itemCnt = item[1], item[2] if nowStage >= msgRet.stageMax then itemCnt = 0 end Grid.makeItem(msgRet.cost, itemId, itemCnt) -- msgRet.cost[0] = #itemArr -- for i, item in ipairs(itemArr) do -- local itemId, itemCnt = item[1], item[2] -- if nowStage >= msgRet.stageMax then -- itemCnt = 0 -- end -- Grid.makeItem(msgRet.cost[i], itemId, itemCnt) -- end local attrMul = getAttrMulFromTalisman(human) attrMul = 1 + attrMul -- 总加成属性 msgRet.attrs[0] = 0 local attrs = calcData(nowStage, nowPointIdx, 1) if attrs then local len = 0 for attrId, attrVal in pairs(attrs) do len = len + 1 msgRet.attrs[0] = len msgRet.attrs[len].key = attrId msgRet.attrs[len].value = attrVal * attrMul end end -- 下一次提升增加的属性 msgRet.nextAttrs[0] = 0 if nowStage < msgRet.stageMax then local nextAttrs = getNextAttrs(nowStage, nowPointIdx, maxPointNum) if nextAttrs then msgRet.nextAttrs[0] = #nextAttrs for i, attrTb in ipairs(nextAttrs) do msgRet.nextAttrs[i].key = attrTb[1] msgRet.nextAttrs[i].value = attrTb[2] * attrMul end end end Msg.send(msgRet, human.fd) end -- 请求点亮天元点 function HeroTianYuan_PointUpGrade(human, heroID, heroIndex) local res = openCheck(human, heroID, heroIndex) if res ~= true then return end local heroGrid = HeroLogic.getHeroGrid(human, heroID, heroIndex) local varCfg = HeroTianYuanCfg.var[1] local tianYuanData = heroGrid.tianYuanData local nowPointIdx = tianYuanData and tianYuanData.pointIdx or 0 local nowStage = tianYuanData and tianYuanData.stage or 0 if nowPointIdx >= varCfg.pointMaxNum then return Broadcast.sendErr(human, Lang.HERO_TY_POINT_MAX) end if nowStage >= #HeroTianYuanCfg.upGrade then return Broadcast.sendErr(human, Lang.HERO_TY_STAGE_MAX) end local targetCfgIdx = nowStage + 1 local targetStageCfg = HeroTianYuanCfg.upGrade[targetCfgIdx] if not targetStageCfg then return Broadcast.sendErr(human, Lang.COMMON_COMFIG_ERROR) end -- 消耗检查 for _, itemInfo in ipairs(targetStageCfg.pointCost) do if BagLogic.getItemCnt(human, itemInfo[1]) < itemInfo[2] then return Broadcast.sendErr(human, Lang.COMMON_ITEM_NOT_ENOUGH) end end -- 扣除消耗 for _, itemInfo in ipairs(targetStageCfg.pointCost) do BagLogic.delItem(human, itemInfo[1], itemInfo[2], LOGTAG) end -- 更新点亮天元点索引 nowPointIdx = nowPointIdx + 1 updateData(heroGrid, nowPointIdx) -- 推送最新数据给客户端 HeroTianYuan_Query(human, heroID, heroIndex) -- 更新战力 updatePower(human, heroID, heroIndex) -- 刷新红点 HeroLogic.refreshDot(human, heroGrid.uuid) end -- 请求天元突破 function HeroTianYuan_StageUpGrade(human, heroID, heroIndex) local res = openCheck(human, heroID, heroIndex) if res ~= true then return end local heroGrid = HeroLogic.getHeroGrid(human, heroID, heroIndex) local varCfg = HeroTianYuanCfg.var[1] local tianYuanData = heroGrid.tianYuanData local nowPointIdx = tianYuanData and tianYuanData.pointIdx or 0 local nowStage = tianYuanData and tianYuanData.stage or 0 if nowPointIdx < varCfg.pointMaxNum then return Broadcast.sendErr(human, Lang.HERO_TY_POINT_NOT_ENOUGH) end if nowStage >= #HeroTianYuanCfg.upGrade then return Broadcast.sendErr(human, Lang.HERO_TY_STAGE_MAX) end local nextStage = nowStage + 1 local nextStageCfg = HeroTianYuanCfg.upGrade[nextStage] if not nextStageCfg then return Broadcast.sendErr(human, Lang.COMMON_COMFIG_ERROR) end -- 消耗检查 for _, itemInfo in ipairs(nextStageCfg.stageCost) do if BagLogic.getItemCnt(human, itemInfo[1]) < itemInfo[2] then return Broadcast.sendErr(human, Lang.COMMON_ITEM_NOT_ENOUGH) end end -- 扣除消耗 for _, itemInfo in ipairs(nextStageCfg.stageCost) do BagLogic.delItem(human, itemInfo[1], itemInfo[2], LOGTAG) end -- 更新天元点索引, 天元重数 updateData(heroGrid, 0, nextStage) -- 推送最新数据给客户端 HeroTianYuan_Query(human, heroID, heroIndex) -- 更新战力 updatePower(human, heroID, heroIndex) -- 刷新红点 HeroLogic.refreshDot(human, heroGrid.uuid) -- 弹窗礼包 GiftLogic = GiftLogic or require("topup.GiftLogic") GiftLogic.trigger(human, GiftLogic.GIFT_HEROTIANYUAN_UPGRADE_STAR, {currentVal = nextStage}, GiftLogic.GIFT_SEC_TYPE3) end