-- 英雄酒馆功能 -- 统计SSR和UR英雄中不同ID英雄的最高星级,并根据星级获得加成属性 -- db --[=[ human.db.heroPubData = nil -- { -- activateIdxList = { [idx] = 1, [idx2] = 1,},--当前激活加成属性在配置中的索引列表 -- heroList = {} -- } ]=]-- local Msg = require("core.Msg") local HeroLogic = require("hero.HeroLogic") local Lang = require("common.Lang") local Broadcast = require("broadcast.Broadcast") local RoleAttr = require("role.RoleAttr") local RoleDefine = require("role.RoleDefine") local ObjHuman = require("core.ObjHuman") local Util = require("common.Util") local HeroPubCfg = require("excel.heroPub").pub local HeroGrid = require("hero.HeroGrid") local RoleSystemLogic = require("roleSystem.RoleSystemLogic") local RoleSystemDefine = require("roleSystem.RoleSystemDefine") HERO_OP_UPSTAR = 1 -- 升星/合成 HERO_OP_DEL = 2 -- 删除 HERO_OP_RETURN = 3 -- 回退 HERO_OP_ADD = 4 -- 获得 local function initPubData(human) human.db.heroPubData = {} human.db.heroPubData.activateIdxList = {} end local function getPubData(human) return human.db.heroPubData end local function updatePubData(human, opType, activateIdx) local heroPubData = getPubData(human) if not heroPubData then initPubData(human) heroPubData = getPubData(human) end if opType > 0 then heroPubData.activateIdxList[activateIdx] = 1 else heroPubData.activateIdxList[activateIdx] = nil end end -- 数据格式转换 local function transformHeroData(human) local pubHeroList = human.pubHeroList if not pubHeroList or not next(pubHeroList) then return end local len = 0 local heroInfoTbl = {} for _, heroInfo in pairs(pubHeroList) do len = len + 1 heroInfoTbl[len] = heroInfo end return heroInfoTbl end local function isCanActivate(idxList, maxIdx) if maxIdx <= 0 then return false end for i=1, maxIdx do if not idxList[i] then return true end end return false end -- 计算当前符合条件的所有英雄的总星级 local function calcAllHeroStar(heroList) local stars = 0 for _, heroInfo in pairs(heroList or {}) do stars = stars + heroInfo.star end return stars end -- 根据星级,获得英雄酒馆加成属性在配置中的索引 local function getPubAttrIdx(maxStarHeroList) local idx = 0 local star = calcAllHeroStar(maxStarHeroList) if star <= 0 then return idx end for k, v in ipairs(HeroPubCfg) do if star < v.activateStar then break end idx = k end return idx end -- 重置缓存的酒馆英雄数据 local function resetPubHeroList(human, newHeroList) if not human.pubHeroList then human.pubHeroList = {} else Util.initTable(human.pubHeroList) end for heroId, heroInfo in pairs(newHeroList) do human.pubHeroList[heroId] = { uuid = heroInfo.uuid, star = heroInfo.star } end end -- 更新战力 local function updatePower(human) RoleAttr.cleanHeroAttrCache(human) ObjHuman.doCalc(human) ObjHuman.sendAttr(human, RoleDefine.ZHANDOULI) end -- 更新加成属性 local function updatePubAttr(human) local heroPubData = getPubData(human) if not heroPubData then return end local bl = false local activateIdxList = heroPubData.activateIdxList local nowMaxAttrIdx = getPubAttrIdx(human.pubHeroList) local maxAttrIdx = #HeroPubCfg for i = nowMaxAttrIdx+1, maxAttrIdx do if activateIdxList[i] then updatePubData(human, 0, i) bl = true end end -- 只有加成属性降低才自动更新, 加成属性提高则需要手动更新... if bl then updatePower(human) end end -- 进行红点检测 local function redDotCheck(human) RoleSystemLogic.onDot(human, RoleSystemDefine.ROLE_SYS_ID_304) end -- 英雄升星/合成时的处理函数 local function upgradeStarFunc(human, heroId, herouuid) local targetHerouuid local pubHeroList = human.pubHeroList local heroGrid = HeroLogic.getHeroGridByUuid(human, herouuid) local oldHeroInfo = pubHeroList[heroId] if heroGrid.star > oldHeroInfo.star then oldHeroInfo.uuid = herouuid oldHeroInfo.star = heroGrid.star targetHerouuid = herouuid end return targetHerouuid end -- 英雄回退/删除时的处理函数 local function delHeroFunc(human, heroId, herouuid) local targetHerouuid, isDel local pubHeroList = human.pubHeroList -- 当前星级最高的英雄删除/回退了, if pubHeroList[heroId] and pubHeroList[heroId].uuid == herouuid then pubHeroList[heroId] = nil isDel = true -- 获取同ID的英雄中星级最高的 local newMaxStar, newHerouuid = HeroLogic.GetMaxStarHero(human, heroId) if newMaxStar and newHerouuid then pubHeroList[heroId] = {uuid = newHerouuid, star = newMaxStar} targetHerouuid = newHerouuid end end return targetHerouuid, isDel end -- 获得英雄时的处理函数 local function addHeroFunc(human, heroId, herouuid) local targetHerouuid local pubHeroList = human.pubHeroList local heroGrid = HeroLogic.getHeroGridByUuid(human, herouuid) if not pubHeroList or not pubHeroList[heroId] then targetHerouuid = herouuid else if pubHeroList[heroId] and pubHeroList[heroId].star < heroGrid.star then targetHerouuid = herouuid end end if targetHerouuid then human.pubHeroList = human.pubHeroList or {} human.pubHeroList[heroId] = human.pubHeroList[heroId] or {} human.pubHeroList[heroId].uuid = herouuid human.pubHeroList[heroId].star = heroGrid.star end return targetHerouuid end local function respondHeroInfo(human) local msgMax = 20 local msgRet = Msg.gc.GC_HEROPUB_HERO_QUERY local msgHeroList = msgRet.heroList local heroInfoTbl = transformHeroData(human) if not heroInfoTbl then msgHeroList[0] = 0 msgRet.start = 1 msgRet.isEnd = 1 Msg.send(msgRet, human.fd) else local len = 0 local startTag = 1 local maxLen =#heroInfoTbl for i=1, maxLen do len = len + 1 msgHeroList[0] = len local net = { relic = {}, gemData = {}, general = {}} local heroGrid = HeroLogic.getHeroGridByUuid(human, heroInfoTbl[i].uuid) HeroGrid.makeHeroSimple(net, heroGrid, nil, human) msgHeroList[len].heroId = net.id msgHeroList[len].heroName = net.name msgHeroList[len].heroStar = net.star msgHeroList[len].heroCamp = net.camp msgHeroList[len].heroBody = net.body msgHeroList[len].heroGrade = net.grade if len >= msgMax then msgRet.start = startTag msgRet.isEnd = 0 if maxLen - len <= 0 then msgRet.isEnd = 1 return Msg.send(msgRet, human.fd) end Msg.send(msgRet, human.fd) len = 0 startTag = 0 maxLen = maxLen - msgMax end end msgRet.start = startTag msgRet.isEnd = 1 Msg.send(msgRet, human.fd) end end local function respndAttrInfo(human) local msgMax = 20 local startTag = 1 local maxLen = #HeroPubCfg local heroPubData = getPubData(human) local nowMaxStar = calcAllHeroStar(human.pubHeroList) local msgRet = Msg.gc.GC_HEROPUB_ATTR_QUERY msgRet.star = nowMaxStar local attrList = msgRet.attrList local len = 0 for i, cfg in ipairs(HeroPubCfg) do len = len + 1 attrList[0] = len attrList[len].index = i attrList[len].isActivate = 0 attrList[len].activateStar = cfg.activateStar if heroPubData and heroPubData.activateIdxList[i] then attrList[len].isActivate = 1 end local attrInfo = attrList[len].attrInfo for k ,v in ipairs(cfg.attrs) do attrInfo[k].key = v[1] attrInfo[k].value = v[2] attrInfo[0] = k end if len >= msgMax then msgRet.start = startTag msgRet.isEnd = 0 if maxLen - len <= 0 then msgRet.isEnd = 1 end Msg.send(msgRet, human.fd) len = 0 startTag = 0 maxLen = maxLen - msgMax end end msgRet.start = startTag msgRet.isEnd = 1 Msg.send(msgRet, human.fd) end local function respondUpdateSingleHero(human, updateHerouuid, delHeroId) local msgRet = Msg.gc.GC_HEROPUB_UPDATE_HERO local net = { relic = {}, gemData = {}, general = {}} if updateHerouuid then local heroGrid = HeroLogic.getHeroGridByUuid(human, updateHerouuid) HeroGrid.makeHeroSimple(net, heroGrid, nil, human) end msgRet.updateHeroInfo.heroId = net.id or delHeroId msgRet.updateHeroInfo.heroName = net.name or "" msgRet.updateHeroInfo.heroStar = net.star or 0 msgRet.updateHeroInfo.heroCamp = net.camp or 0 msgRet.updateHeroInfo.heroBody = net.body or 0 msgRet.updateHeroInfo.heroGrade = net.grade or 0 Msg.send(msgRet, human.fd) end function onLogin(human) local maxStarHeroList = HeroLogic.GetHeroMaxStarList(human) if next(maxStarHeroList) then -- 缓存组成酒馆的英雄列表 resetPubHeroList(human, maxStarHeroList) end end function doCalcHero(human, attrs) if not human then return end local heroPubData = getPubData(human) if not heroPubData then return end local activateIdxList = heroPubData.activateIdxList for k, v in ipairs(HeroPubCfg) do if activateIdxList[k] then for _, attrInfo in ipairs(v.attrs) do RoleAttr.updateValue(attrInfo[1], attrInfo[2], attrs) end end end end -- 英雄总star有更新(升星/合成, 回退, 删除, 增加) function UpdateHero(human, opType, heroId, herouuid) local updateHerouuid, isDel if opType == HERO_OP_UPSTAR then updateHerouuid = upgradeStarFunc(human, heroId, herouuid) elseif opType == HERO_OP_DEL then updateHerouuid, isDel = delHeroFunc(human, heroId, herouuid) elseif opType == HERO_OP_RETURN then updateHerouuid = delHeroFunc(human, heroId, herouuid) elseif opType == HERO_OP_ADD then updateHerouuid = addHeroFunc(human, heroId, herouuid) end local delHeroId = 0 if opType == HERO_OP_DEL and not updateHerouuid and isDel then --英雄被删,且背包中没有同ID的英雄 delHeroId = heroId end if updateHerouuid or delHeroId > 0 then redDotCheck(human) updatePubAttr(human) -- respondUpdateSingleHero(human, updateHerouuid, delHeroId) -- respndAttrInfo(human) end end --红点判断 function isDot(human) local heroPubData = getPubData(human) local nowMaxAttrIdx = getPubAttrIdx(human.pubHeroList) if not heroPubData then if nowMaxAttrIdx <= 0 then return false else return true end end if isCanActivate(heroPubData.activateIdxList, nowMaxAttrIdx) then return true end return false end -- GM 设置激活 function GM_SetAttrIdx(human, idx) if not idx then return Broadcast.sendErr(human, Lang.COMMON_ARGUMENT_ERROR) end if idx < 0 then idx = 0 end local reallyIdx = getPubAttrIdx(human.pubHeroList) if idx > reallyIdx then idx = reallyIdx end -- if idx > #HeroPubCfg then -- idx = #HeroPubCfg -- end local heroPubData = getPubData(human) if heroPubData then Util.initTable(heroPubData.activateIdxList) end updatePubData(human, 1, idx) ObjHuman.GM_SaveDB(human) end -- 查询 function PubQuery(human) respondHeroInfo(human) respndAttrInfo(human) end --激活属性 function ActivatePubAtrr(human, targetIdx) local nowMaxIdx = getPubAttrIdx(human.pubHeroList) if targetIdx > nowMaxIdx then return Broadcast.sendErr(human, Lang.HEROPUB_STAR_NOT_ENOUGH) end local heroPubData = getPubData(human) if heroPubData and heroPubData.activateIdxList and heroPubData.activateIdxList[targetIdx] then return Broadcast.sendErr(human, Lang.BINGSHU_LEARN_ERR_HAD) end updatePubData(human, 1, targetIdx) local msgRet = Msg.gc.GC_HEROPUB_ACTIVATE msgRet.index = targetIdx Msg.send(msgRet, human.fd) --更新战力 updatePower(human) --红点检测 redDotCheck(human) end