-- 精灵系统 --db --[=[ human.db.elfData = { [elfId1] = { level = 0, star = 0, }, [elfId2] = { level = 0, star = 0, }, } ]=]-- local Msg = require("core.Msg") local Lang = require("common.Lang") local Broadcast = require("broadcast.Broadcast") local ElfConfig = require("excel.elf") local ItemConfig = require("excel.item").item local Grid = require("bag.Grid") local BagLogic = require("bag.BagLogic") local Skill = require("combat.Skill") local RoleAttr = require("role.RoleAttr") local RoleDefine = require("role.RoleDefine") local ObjHuman = require("core.ObjHuman") local RoleSystemLogic = require("roleSystem.RoleSystemLogic") local RoleSystemDefine = require("roleSystem.RoleSystemDefine") local HuanJingTowerLogic = require("huanjingTower.HuanjingTowerLogic") local TalismanLogic = require("talisman.TalismanLogic") local TriggerLogic = require("trigger.TriggerLogic") local TriggerDefine = require("trigger.TriggerDefine") local ChengjiuLogic = require("chengjiu.ChengjiuLogic") local GiftLogic local ELF_UPGRADELV_LOG_TAG = "elfUpGradeLv" local ELF_UPGRADESTAR_LOG_TAG = "elfUpGradeStar" local ELF_COND_TOWER_LEVEL = 600 local ELF_2_CHENGJIU_TASKID = 406 -- 精灵系统对应的成就任务Id local function initElfData(human) human.db.elfData = {} end local function getElfData(human) return human.db.elfData end local function updateElfData(human, elfId, newLevel, newStar) local elfData = getElfData(human) if not elfData then initElfData(human) elfData = getElfData(human) end elfData[elfId] = elfData[elfId] or {level = 0, star = 0} if newLevel then elfData[elfId].level = newLevel end if newStar then elfData[elfId].star = newStar end end -- 获取来自秘宝的属性倍数加成 local function getAttrMulFromTalisman(human) local attrMul = TalismanLogic.getTalismanAdd(human, TalismanLogic.OTHER_EFFECT_TBL.Elf_Attr_Mul) attrMul = attrMul / 100 return attrMul end local function getNextStarCostCnt(nextStar) for _, starCfg in ipairs(ElfConfig.UpGradeStar) do if nextStar == starCfg.star then return starCfg.itemCnt end end return 0 end local function generateCfgByQuality(targetQuality) local tbl = {} for id, cfg in ipairs(ElfConfig.Elf) do if cfg.elfQuality == targetQuality then tbl[id] = cfg end end if not next(tbl) then return nil end return tbl end local function getElfCfgById(targetElfId) for _, elfCfg in ipairs(ElfConfig.Elf) do if elfCfg.elfId == targetElfId then return elfCfg end end end -- 计算一共可以升多少级, 消耗多少道具 local function calcUpGrade(nowLv, itemAllCnt, maxLv) local addLv, oldItemAllCnt, itemCostCnt = 0, itemAllCnt, 0 while true do nowLv = nowLv + 1 if nowLv > maxLv then break end itemCostCnt = nowLv * 3 + 2 if itemAllCnt < itemCostCnt then break end addLv = addLv + 1 itemAllCnt = itemAllCnt - itemCostCnt end local useItemCnt = oldItemAllCnt - itemAllCnt return addLv, useItemCnt end -- 计算当前所有精灵的总星级 local function calcAllElfStar(elfDataList) local stars = 0 for _, elfData in pairs(elfDataList) do stars = stars + elfData.star end return stars end -- 计算精灵当前等级加成属性之和 local function calcLvAttr(elfLv, attrCfg) local nowAttrVal = 0 for i=1, elfLv do nowAttrVal = nowAttrVal + attrCfg[1] * i + attrCfg[2] end return nowAttrVal end local function populateMsgSimpleData(net, elfCfg, itemCfg, elfData) if not net or not elfCfg or not itemCfg then return end local elfNowLv = elfData and elfData.level or 0 local elfNowStar = elfData and elfData.star or 0 net.elfId = elfCfg.elfId net.elfName = itemCfg.name net.elfIcon = itemCfg.icon net.elfLv = elfNowLv net.elfStar = elfNowStar net.elfQuality = elfCfg.elfQuality net.maxLv = elfCfg.elfMaxLv net.maxStar = elfCfg.elfMaxStar local upGradeLvItemId = elfCfg.upGradeLvItemId local upGradeLvItemCnt = elfNowLv >= elfCfg.elfMaxLv and 0 or (elfNowLv + 1) * 3 + 2 Grid.makeItem(net.elfUpGradeLvCost, upGradeLvItemId, upGradeLvItemCnt) local upGradeStarItemId = elfCfg.upGradeStarItemId local upGradeStarItemCnt = elfNowStar >= elfCfg.elfMaxStar and 0 or getNextStarCostCnt(elfNowStar+1) Grid.makeItem(net.elfUpGradeStarCost, upGradeStarItemId, upGradeStarItemCnt) end local function populateMsgAttr(attrNet, attrCfg, attrId, elfLv, isMax, attrMul) local sumAttrVal = calcLvAttr(elfLv, attrCfg) attrNet.nowAttr.key = attrId attrNet.nowAttr.value = sumAttrVal * (1 + attrMul) attrNet.addAtrr.key = attrId attrNet.addAtrr.value = (attrCfg[1] * (elfLv + 1) + attrCfg[2]) * (1 + attrMul) if isMax then attrNet.addAtrr.value = 0 end end local function populateMsgAttr2(attrNet, attrId, attrVal, elfStar, isMax, attrMul) attrMul = 1 + attrMul attrNet.nowAttr.key = attrId attrNet.nowAttr.value = attrVal * elfStar * attrMul attrNet.addAtrr.key = attrId attrNet.addAtrr.value = attrVal if isMax then attrNet.addAtrr.value = 0 end end --是否开启本系统, 内部使用, 需要领取任务奖励后才解锁 local function isOpen(human) -- local towerLevel = HuanJingTowerLogic.getTowerLevel(human) -- if towerLevel >= ELF_COND_TOWER_LEVEL then -- return true -- end -- return false local state = ChengjiuLogic.GetTaskState(human, ELF_2_CHENGJIU_TASKID) if state == 2 then return true end return false end -- 重算战力 local function updatePower(human) RoleAttr.cleanHeroAttrCache(human) RoleAttr.doCalc(human) ObjHuman.sendAttr(human, RoleDefine.ZHANDOULI) end --红点判断 local function dotJudgment(human, cfgHtbl) local elfData = getElfData(human) for _, cfg in pairs(cfgHtbl) do local nowLevel, nowStar = 0, 0 if elfData and elfData[cfg.elfId] then nowLevel = elfData[cfg.elfId].level nowStar = elfData[cfg.elfId].star end if nowStar < cfg.elfMaxStar then local upGradeStarCostCnt = getNextStarCostCnt(nowStar+1) if BagLogic.getItemCnt(human, cfg.upGradeStarItemId) >= upGradeStarCostCnt then return true end end -- 需要精灵可激活或已激活 if nowStar >= 1 and nowLevel < cfg.elfMaxLv then nowLevel = nowLevel + 1 local costItemCnt = nowLevel * 3 + 2 if BagLogic.getItemCnt(human, cfg.upGradeLvItemId) >= costItemCnt then return true end end end return false end -- 红点更新 local function updateDot(human, targetQuality) local cfgHtbl = generateCfgByQuality(targetQuality) -- 该品质的所有精灵不能升星和升级了 if not dotJudgment(human, cfgHtbl) then local dotID = 0 if targetQuality == 1 then dotID = RoleSystemDefine.ROLE_SYS_ID_2032 elseif targetQuality == 2 then dotID = RoleSystemDefine.ROLE_SYS_ID_2033 elseif targetQuality == 3 then dotID = RoleSystemDefine.ROLE_SYS_ID_2034 else dotID = RoleSystemDefine.ROLE_SYS_ID_2035 end --刷新单页 RoleSystemLogic.onDot(human, dotID) --刷新入口处 RoleSystemLogic.onDot(human, RoleSystemDefine.ROLE_SYS_ID_2031) end end -- 外部调用,精灵加成 function doCalcHero(human, addAttrs) if not human or not human.db then return end local elfData = getElfData(human) if not elfData then return end local attrMul = getAttrMulFromTalisman(human) attrMul = 1 + attrMul for elfId, singleElfData in pairs(elfData) do local elfCfg = getElfCfgById(elfId) if elfCfg then -- 等级加成 if singleElfData.level > 0 then local atkVal = calcLvAttr(singleElfData.level, elfCfg.nAttack1) local hpVal = calcLvAttr(singleElfData.level, elfCfg.nLife1) RoleAttr.updateValue(RoleDefine.ATK, atkVal * attrMul, addAttrs) RoleAttr.updateValue(RoleDefine.HP, hpVal * attrMul, addAttrs) end -- 星级加成 RoleAttr.updateValue(RoleDefine.ATK, elfCfg.nAttack2 * singleElfData.star * attrMul, addAttrs) RoleAttr.updateValue(RoleDefine.HP, elfCfg.nLife2 * singleElfData.star * attrMul, addAttrs) RoleAttr.updateValue(RoleDefine.DEF, elfCfg.nDefense2 * singleElfData.star * attrMul, addAttrs) RoleAttr.updateValue(RoleDefine.SPEED, elfCfg.nSpeed2 * singleElfData.star * attrMul, addAttrs) end end end -- 外部调用, 本系统是否开启 function ModuleisOpen(human) -- return isOpen(human) local towerLevel = HuanJingTowerLogic.getTowerLevel(human) if towerLevel >= ELF_COND_TOWER_LEVEL then return true end return false end -- 外部调用, 是否有红点 function isDot(human, dotConfig) if not isOpen(human) then return false end --入口处的红点判断 if dotConfig.id == RoleSystemDefine.ROLE_SYS_ID_2031 then return dotJudgment(human, ElfConfig.Elf) else --单个分页的红点 local elfQuality = 0 if dotConfig.id == RoleSystemDefine.ROLE_SYS_ID_2032 then elfQuality = 1 elseif dotConfig.id == RoleSystemDefine.ROLE_SYS_ID_2033 then elfQuality = 2 elseif dotConfig.id == RoleSystemDefine.ROLE_SYS_ID_2034 then elfQuality = 3 else elfQuality = 4 end local cfgHtbl = generateCfgByQuality(elfQuality) if not cfgHtbl then return false end return dotJudgment(human, cfgHtbl) end end -- 外部调用,是否激活了精灵 function IsActivateElf(human, elfId) if not isOpen(human) then return false end local elfData = getElfData(human) if not elfData or not elfData[elfId] then return false end return true end -- 外部调用,获取精灵当前技能 function GetElfSkill(human, elfId) -- if not isOpen(human) then -- return -- end local elfData = getElfData(human) if not elfData or not elfData[elfId] then return end local elfNowStar = elfData[elfId].star local elfCfg = getElfCfgById(elfId) if not elfCfg then return end return elfCfg.skillArr[elfNowStar] end -- 请求某个品质的所有精灵的简单数据 function Elf_SimpleData_Query(human, targetElfQuality) if not isOpen(human) then return Broadcast.sendErr(human, Lang.COMMOM_NOT_ENABLED) end local elfData = getElfData(human) or {} local msgRet = Msg.gc.GC_ELF_SIMPLEDATA_QUERY local elfArr = msgRet.elfArr elfArr[0] = 0 local len = 0 msgRet.allStars = calcAllElfStar(elfData) for _, elfCfg in ipairs(ElfConfig.Elf) do if elfCfg.elfQuality == targetElfQuality then local elfId = elfCfg.elfId local itemCfg = ItemConfig[elfId] if itemCfg then len = len + 1 populateMsgSimpleData(elfArr[len], elfCfg, itemCfg, elfData[elfId]) end end end elfArr[0] = len Msg.send(msgRet, human.fd) end -- 请求某个精灵的详细数据 function Elf_SingleElf_Query(human, elfId) if not isOpen(human) then return Broadcast.sendErr(human, Lang.COMMOM_NOT_ENABLED) end local itemCfg = ItemConfig[elfId] local elfCfg = getElfCfgById(elfId) if not itemCfg or not elfCfg then return Broadcast.sendErr(human, Lang.COMMON_COMFIG_ERROR) end local elfData = getElfData(human) or {} local targetElfData = elfData[elfId] local msgRet = Msg.gc.GC_ELF_SINGLE_QUERY populateMsgSimpleData(msgRet.elfSimpleData, elfCfg, itemCfg, targetElfData) local elfNowLv = targetElfData and targetElfData.level or 0 local elfNowStar = targetElfData and targetElfData.star or 0 local isMaxLv, isMaxStar = false, false if elfNowLv >= elfCfg.elfMaxLv then isMaxLv = true end if elfNowStar >= elfCfg.elfMaxStar then isMaxStar = true end local elfSkillDataMsg = msgRet.elfSkillData elfSkillDataMsg.nowSkillDesc = "" local elfNowSkillId = elfCfg.skillArr[elfNowStar] local nowSkillCfg = Skill.GetSkillConfig(elfNowSkillId) if nowSkillCfg then elfSkillDataMsg.nowSkillDesc = nowSkillCfg.desc end elfSkillDataMsg.nextSkillDesc = "" local elfNextSkillId = isMaxStar and elfCfg.skillArr[#elfCfg.skillArr] or elfCfg.skillArr[elfNowStar+1] local nextSkillCfg = Skill.GetSkillConfig(elfNextSkillId) if nextSkillCfg then elfSkillDataMsg.nextSkillDesc = nextSkillCfg.desc end elfSkillDataMsg.maxSkillDesc = "" local elfMaxSkillId = elfCfg.skillArr[#elfCfg.skillArr] local maxSkillCfg = Skill.GetSkillConfig(elfMaxSkillId) if maxSkillCfg then elfSkillDataMsg.maxSkillDesc = maxSkillCfg.desc end local attrMul = getAttrMulFromTalisman(human) msgRet.elfLvAttrInfo[0] = 2 populateMsgAttr(msgRet.elfLvAttrInfo[1], elfCfg.nAttack1, RoleDefine.ATK, elfNowLv, isMaxLv, attrMul) populateMsgAttr(msgRet.elfLvAttrInfo[2], elfCfg.nLife1, RoleDefine.HP, elfNowLv, isMaxLv, attrMul) msgRet.elfStarAttrInfo[0] = 4 populateMsgAttr2(msgRet.elfStarAttrInfo[1], RoleDefine.HP, elfCfg.nLife2, elfNowStar, isMaxStar, attrMul) populateMsgAttr2(msgRet.elfStarAttrInfo[2], RoleDefine.ATK, elfCfg.nAttack2, elfNowStar, isMaxStar, attrMul) populateMsgAttr2(msgRet.elfStarAttrInfo[3], RoleDefine.DEF, elfCfg.nDefense2, elfNowStar, isMaxStar, attrMul) populateMsgAttr2(msgRet.elfStarAttrInfo[4], RoleDefine.SPEED, elfCfg.nSpeed2, elfNowStar, isMaxStar, attrMul) Msg.send(msgRet, human.fd) end -- 精灵升级 function Elf_UpGradeLv(human, elfId, opType) if not isOpen(human) then return Broadcast.sendErr(human, Lang.COMMOM_NOT_ENABLED) end local elfCfg = getElfCfgById(elfId) if not elfCfg then return Broadcast.sendErr(human, Lang.COMMON_COMFIG_ERROR) end local elfData = getElfData(human) or {} if not elfData[elfId] then return Broadcast.sendErr(human, Lang.ELF_NOT_ACTIVATE) end local elfNowLv = elfData[elfId].level or 0 if elfNowLv >= elfCfg.elfMaxLv then return Broadcast.sendErr(human, Lang.COMMON_MAXLEVEL) end local upGradeLvItemId = elfCfg.upGradeLvItemId local upGradeLvItemCnt = 0 local itemAllCnt = BagLogic.getItemCnt(human, upGradeLvItemId) if itemAllCnt <= 0 then return Broadcast.sendErr(human, Lang.COMMON_ITEM_NOT_ENOUGH) end -- if BagLogic.getItemCnt(human, upGradeLvItemId) < upGradeLvItemCnt then -- return Broadcast.sendErr(human, Lang.COMMON_ITEM_NOT_ENOUGH) -- end local addLv = 0 if opType == 1 then addLv = 1 upGradeLvItemCnt = (elfNowLv + 1) * 3 + 2 elseif opType == 2 then addLv, upGradeLvItemCnt = calcUpGrade(elfNowLv, itemAllCnt, elfCfg.elfMaxLv) else return Broadcast.sendErr(human, Lang.COMMON_ARGUMENT_ERROR) end if addLv == 0 or BagLogic.getItemCnt(human, upGradeLvItemId) < upGradeLvItemCnt then return Broadcast.sendErr(human, Lang.COMMON_ITEM_NOT_ENOUGH) end BagLogic.delItem(human, upGradeLvItemId, upGradeLvItemCnt, ELF_UPGRADELV_LOG_TAG) updateElfData(human, elfId, elfNowLv+addLv) Elf_SingleElf_Query(human, elfId) updatePower(human) -- 红点刷新 updateDot(human, elfCfg.elfQuality) end -- 精灵升星 function Elf_UpGradeStar(human, elfId) if not isOpen(human) then return Broadcast.sendErr(human, Lang.COMMOM_NOT_ENABLED) end local elfCfg = getElfCfgById(elfId) if not elfCfg then return Broadcast.sendErr(human, Lang.COMMON_COMFIG_ERROR) end local elfData = getElfData(human) or {} local elfNowStar = elfData[elfId] and elfData[elfId].star or 0 if elfNowStar >= elfCfg.elfMaxStar then return Broadcast.sendErr(human, Lang.COMMON_MAXLEVEL) end local nextStar = elfNowStar+1 local upGradeStarItemId = elfCfg.upGradeStarItemId local upGradeStarItemCnt = getNextStarCostCnt(nextStar) if upGradeStarItemCnt == 0 then return Broadcast.sendErr(human, Lang.ELF_MAX_STAR) end if BagLogic.getItemCnt(human, upGradeStarItemId) < upGradeStarItemCnt then return Broadcast.sendErr(human, Lang.COMMON_ITEM_NOT_ENOUGH) end BagLogic.delItem(human, upGradeStarItemId, upGradeStarItemCnt, ELF_UPGRADESTAR_LOG_TAG) updateElfData(human, elfId, nil, nextStar) Elf_SingleElf_Query(human, elfId) updatePower(human) -- 红点刷新 updateDot(human, elfCfg.elfQuality) local nAllStar = calcAllElfStar(elfData) TriggerLogic.PublishEvent(TriggerDefine.EVENT_TYPE_JINGLING_STAR, human.db._id, 1) GiftLogic = GiftLogic or require("topup.GiftLogic") GiftLogic.trigger(human, GiftLogic.GIFT_ELF_UPGRADE_STAR, {currentVal = nAllStar}, GiftLogic.GIFT_SEC_TYPE3) end -- 布阵界面, 请求精灵数据 function Elf_GetElfData_FromPosPage(human, targetElfQuality) local msgRet = Msg.gc.GC_ELF_POS_QUERY local elfArr = msgRet.elfArr elfArr[0] = 0 local len = 0 local elfData = getElfData(human) or {} for _, elfCfg in ipairs(ElfConfig.Elf) do if elfCfg.elfQuality == targetElfQuality then local elfId = elfCfg.elfId local itemCfg = ItemConfig[elfId] if itemCfg then len = len + 1 local elfNowLv = elfData and elfData.level or 0 local elfNowStar = elfData[elfId] and elfData[elfId].star or 0 elfArr[len].elfId = elfId elfArr[len].elfName = itemCfg.name elfArr[len].elfIcon = itemCfg.icon elfArr[len].elfLv = elfNowLv elfArr[len].elfStar = elfNowStar elfArr[len].elfQuality = targetElfQuality elfArr[len].nowSkillDesc = "" elfArr[len].nowSkillIcon = "" local elfNowSkillId = elfCfg.skillArr[elfNowStar] local nowSkillCfg = Skill.GetSkillConfig(elfNowSkillId) if nowSkillCfg then elfArr[len].nowSkillDesc = nowSkillCfg.desc elfArr[len].nowSkillIcon = nowSkillCfg.icon end end end end elfArr[0] = len Msg.send(msgRet, human.fd) end