| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496 |
- -- 收纳箱(回收道具)
- --
- -- doCalcHero 统计收纳箱英雄属性加成
- -- RecycleItem_Query 查询收纳箱等级/经验/属性
- -- RecycleItem_RecycleItemListQuery 查询可回收道具列表
- -- RecycleItem_Recycle_Do 执行回收
- --db
- --[=[
- human.db.recycleData = {
- level = nil,
- exp = nil,
- }
- ]=]--
- local Msg = require("core.Msg")
- local Lang = require("common.Lang")
- local Broadcast = require("broadcast.Broadcast")
- local Util = require("common.Util")
- local BagLogic = require("bag.BagLogic")
- local RoleAttr = require("role.RoleAttr")
- local RoleDefine = require("role.RoleDefine")
- local ObjHuman = require("core.ObjHuman")
- local RecycleConfig = require("excel.recycleItem").RecycleLvList
- local ItemConfig = require("excel.item").item
- local FuwenConfig = require("excel.fuwen").fuwen
- local ItemDefine = require("bag.ItemDefine")
- local FuwenLogic = require("fuwen.FuwenLogic")
- -- local RoleSystemLogic = require("roleSystem.RoleSystemLogic")
- -- local RoleSystemDefine = require("roleSystem.RoleSystemDefine")
- local LOG_TAG = "RecycleItem" -- 本系统的日志标识
- local OPEN_COND_LV = 150 -- 开启功能需要的等级
- local RECYCLE_ITEM_TYPE_ITEM = 1 -- item表道具
- local RECYCLE_ITEM_TYPE_FUWEN = 2 -- 符文
- -- 初始化收纳箱数据
- local function initRecycleData(human)
- human.db.recycleData = { level = 0, exp = 0 }
- end
- -- 获取收纳箱数据
- local function getRecycleData(human)
- return human.db.recycleData
- end
- -- 获取道具/符文的回收值, 仅 val > 0 时可回收
- local function getRecycleVal(itemId)
- if ItemDefine.isFuwen(itemId) then
- local fuwenCfg = FuwenConfig[itemId]
- if fuwenCfg and fuwenCfg.val and fuwenCfg.val > 0 then
- return fuwenCfg.val
- end
- return
- end
- local itemCfg = ItemConfig[itemId]
- if itemCfg and itemCfg.val and itemCfg.val > 0 then
- return itemCfg.val
- end
- end
- -- 收集背包中可回收的item表道具, 返回 {{id, recycleVal, extraInfo}, ...}
- local function collectItemRecycleList(human)
- local itemArr = {}
- local bagData = BagLogic.GetBagData(human)
- if not bagData then
- return itemArr
- end
- for itemId in pairs(bagData) do
- if not ItemDefine.isFuwen(itemId) then
- local itemCfg = ItemConfig[itemId]
- if itemCfg and itemCfg.val and itemCfg.val > 0 then
- itemArr[#itemArr + 1] = {itemId, itemCfg.val, 0}
- end
- end
- end
- return itemArr
- end
- -- 收集符文背包中可回收的符文, extraInfo 为符文背包idx
- local function collectFuwenRecycleList(human)
- local itemArr = {}
- local fuwenBag = FuwenLogic.getFuwenBagData(human)
- if not fuwenBag then
- return itemArr
- end
- for index, fuwenGrid in pairs(fuwenBag) do
- local fuwenId = fuwenGrid and fuwenGrid.id
- if fuwenId then
- local recycleVal = getRecycleVal(fuwenId)
- if recycleVal then
- itemArr[#itemArr + 1] = {fuwenId, recycleVal, index}
- end
- end
- end
- return itemArr
- end
- -- 解析回收请求字符串, 返回 {{id, value}, ...}
- local function parseRecycleEntries(recycleItemStr)
- local entries = Util.parseKVList(recycleItemStr, "|", "-", Util.TONUMBER_ALL)
- if #entries == 0 then
- return
- end
- return entries
- end
- -- 合并相同道具id的回收数量, 避免重复条目导致数量校验/扣除错误
- local function mergeItemRecycleEntries(entries)
- local mergedMap = {}
- for _, entry in ipairs(entries) do
- local itemId, itemCnt = entry[1], entry[2]
- mergedMap[itemId] = (mergedMap[itemId] or 0) + (itemCnt or 0)
- end
- local mergedList = {}
- for itemId, itemCnt in pairs(mergedMap) do
- mergedList[#mergedList + 1] = {itemId, itemCnt}
- end
- return mergedList
- end
- -- 校验item表道具回收, 成功返回 totalExp, 失败返回 nil, errLang
- local function validateItemRecycle(human, entries)
- local totalExp = 0
- for _, entry in ipairs(entries) do
- local itemId, itemCnt = entry[1], entry[2]
- if not itemId or not itemCnt or itemCnt <= 0 then
- return nil, Lang.COMMON_ARGUMENT_ERROR
- end
- if ItemDefine.isFuwen(itemId) then
- return nil, Lang.ITEM_CANNOT_RECYCLE
- end
- local recycleVal = getRecycleVal(itemId)
- if not recycleVal then
- return nil, Lang.ITEM_CANNOT_RECYCLE
- end
- if BagLogic.getItemCnt(human, itemId) < itemCnt then
- return nil, Lang.COMMON_ITEM_NOT_ENOUGH
- end
- totalExp = totalExp + recycleVal * itemCnt
- end
- return totalExp
- end
- -- 校验符文回收, 成功返回 totalExp, 失败返回 nil, errLang
- local function validateFuwenRecycle(human, entries)
- local totalExp = 0
- local indexMap = {}
- for _, entry in ipairs(entries) do
- local fuwenId, index = entry[1], entry[2]
- if not fuwenId or not index or index <= 0 or indexMap[index] then
- return nil, Lang.COMMON_ARGUMENT_ERROR
- end
- indexMap[index] = true
- local recycleVal = getRecycleVal(fuwenId)
- if not recycleVal then
- return nil, Lang.ITEM_CANNOT_RECYCLE
- end
- local fuwenGrid = FuwenLogic.getFuwenGrid(human, index)
- if not fuwenGrid or fuwenGrid.id ~= fuwenId then
- return nil, Lang.COMMON_ITEM_NOT_ENOUGH
- end
- totalExp = totalExp + recycleVal
- end
- return totalExp
- end
- -- 删除待回收的item表道具
- local function deleteItemRecycle(human, entries)
- for _, entry in ipairs(entries) do
- BagLogic.delItem(human, entry[1], entry[2], LOG_TAG)
- end
- end
- -- 删除待回收的符文
- local function deleteFuwenRecycle(human, entries)
- for _, entry in ipairs(entries) do
- FuwenLogic.del(human, entry[2], LOG_TAG)
- end
- end
- -- 回收校验处理器, 按 itemType 分发
- local RECYCLE_VALIDATE_HANDLER = {
- [RECYCLE_ITEM_TYPE_ITEM] = validateItemRecycle,
- [RECYCLE_ITEM_TYPE_FUWEN] = validateFuwenRecycle,
- }
- -- 回收删除处理器, 按 itemType 分发
- local RECYCLE_DELETE_HANDLER = {
- [RECYCLE_ITEM_TYPE_ITEM] = deleteItemRecycle,
- [RECYCLE_ITEM_TYPE_FUWEN] = deleteFuwenRecycle,
- }
- -- 更新收纳箱等级和经验
- local function updateRecycleData(human, newLv, newExp)
- local recycleData = getRecycleData(human)
- if not recycleData then
- initRecycleData(human)
- recycleData = getRecycleData(human)
- end
- recycleData.level = newLv
- recycleData.exp = newExp
- end
- -- 是否开启本系统
- local function isOpen(human)
- -- return RoleSystemLogic.isOpen(human, RoleSystemDefine.ROLE_SYS_ID_2031) -- 待修改
- return human.db.lv >= OPEN_COND_LV
- end
- -- 计算当前等级加成属性
- local function calcCurrentLvAttrs(currentLevel)
- if not currentLevel or currentLevel <= 0 then
- return
- end
- local attrs = {}
- for i=1, currentLevel do
- local cfg = RecycleConfig[i]
- if cfg and cfg.attrs then
- for _,v in ipairs(cfg.attrs) do
- local attrId = v[1]
- local attrVal = v[2]
- attrs[attrId] = (attrs[attrId] or 0) + attrVal
- end
- end
- end
- return attrs
- end
- -- 重算战力
- local function updatePower(human)
- RoleAttr.cleanHeroAttrCache(human)
- RoleAttr.doCalc(human)
- ObjHuman.sendAttr(human, RoleDefine.ZHANDOULI)
- end
- -- 计算出新的等级和经验
- local function calcLv(human, addExp)
- local recycleData = getRecycleData(human)
- local currentLevel = recycleData and recycleData.level or 0
- local currentExp = recycleData and recycleData.exp or 0
- currentExp = currentExp + addExp
- local newLv = currentLevel
- for i=currentLevel+1, #RecycleConfig do
- local cfg = RecycleConfig[i]
- if currentExp < cfg.exp then
- break
- end
- currentExp = currentExp - cfg.exp
- newLv = i
- if currentExp <= 0 then
- break
- end
- end
- return newLv, currentExp
- end
- -- 填充当前等级属性到协议结构
- local function populateCurrentLvAttrs(net, currentLevel)
- local isZero = false
- if currentLevel <= 0 then
- currentLevel = 1
- isZero = true
- end
- local len = 0
- net[0] = len
- local attrs = calcCurrentLvAttrs(currentLevel)
- for attrId, attrVal in pairs(attrs or {}) do
- len = len + 1
- net[0] = len
- net[len].key = attrId
- net[len].value = isZero and 0 or attrVal
- end
- end
- -- 填充下一等级属性到协议结构
- local function populateNextLvAttrs(net, nextLv)
- local isMax = false
- local maxLv = #RecycleConfig
- if maxLv <= nextLv then
- nextLv = maxLv
- isMax = true
- end
- net[0] = 0
- local cfg = RecycleConfig[nextLv]
- if cfg and cfg.attrs then
- net[0] = #cfg.attrs
- for k,v in ipairs(cfg.attrs) do
- net[k].key = v[1]
- net[k].value = isMax and 0 or v[2]
- end
- end
- end
- -- local function populateRecycleItem(net, human)
- -- net[0] = 0
- -- local bagData = BagLogic.GetBagData(human)
- -- if not bagData then
- -- return
- -- end
- -- local len = 0
- -- for itemId in pairs(bagData) do
- -- local itemCfg = ItemConfig[itemId]
- -- if itemCfg and itemCfg.val and itemCfg.val > 0 then
- -- len = len + 1
- -- net[0] = len
- -- net[len].id = itemId
- -- net[len].recycleVal = itemCfg.val
- -- end
- -- end
- -- end
- -- 外部调用, 统计收纳箱加成属性
- function doCalcHero(human, addAttrs)
- if not human then
- return
- end
- local recycleData = getRecycleData(human)
- if not recycleData then
- return
- end
- local currentLevel = recycleData and recycleData.level or 0
- if currentLevel <= 0 then
- return
- end
- local attrs = calcCurrentLvAttrs(currentLevel)
- for attrId, attrVal in pairs(attrs or {}) do
- RoleAttr.updateValue(attrId, attrVal, addAttrs)
- end
- end
- -- 查询收纳箱等级、经验及属性加成
- function RecycleItem_Query(human)
- if not isOpen(human) then
- return Broadcast.sendErr(human, Lang.COMMOM_NOT_ENABLED)
- end
- local recycleData = getRecycleData(human)
- local currentLevel = recycleData and recycleData.level or 0
- local currentExp = recycleData and recycleData.exp or 0
- local maxLevel = #RecycleConfig
- local nextLvExp = 0
- if currentLevel < maxLevel then
- local nextLvCfg = RecycleConfig[currentLevel + 1]
- nextLvExp = nextLvCfg.exp
- end
- local msgRet = Msg.gc.GC_RECYCLE_QUERY
- msgRet.currentLevel = currentLevel
- msgRet.maxLevel = maxLevel
- msgRet.currentExp = currentExp
- msgRet.nextLvExp = nextLvExp
- populateCurrentLvAttrs(msgRet.currentLvAttrs, currentLevel)
- populateNextLvAttrs(msgRet.nextLvAttrs, currentLevel+1)
- -- populateRecycleItem(msgRet.recycleList, human)
- Msg.send(msgRet, human.fd)
- end
- -- 查询可回收道具列表, itemType: 1-item表道具, 2-符文
- function RecycleItem_RecycleItemListQuery(human, itemType)
- if not isOpen(human) then
- return Broadcast.sendErr(human, Lang.COMMOM_NOT_ENABLED)
- end
- if itemType ~= RECYCLE_ITEM_TYPE_ITEM and itemType ~= RECYCLE_ITEM_TYPE_FUWEN then
- return Broadcast.sendErr(human, Lang.COMMON_ARGUMENT_ERROR)
- end
- local msgRet = Msg.gc.GC_RECYCLE_GET_RECYCLE_LIST
- msgRet.recycleList[0] = 0
- msgRet.isStart = 1
- msgRet.isEnd = 0
- local itemArr
- if itemType == RECYCLE_ITEM_TYPE_FUWEN then
- itemArr = collectFuwenRecycleList(human)
- else
- itemArr = collectItemRecycleList(human)
- end
- local itemNum = #itemArr
- if itemNum == 0 then
- msgRet.isEnd = 1
- return Msg.send(msgRet, human.fd)
- end
- local len = 0
- local onceMsgLen = 50
- for _, itemInfo in ipairs(itemArr) do
- len = len + 1
- msgRet.recycleList[0] = len
- msgRet.recycleList[len].id = itemInfo[1]
- msgRet.recycleList[len].recycleVal = itemInfo[2]
- msgRet.recycleList[len].extraInfo = itemInfo[3] or 0
- if len >= onceMsgLen then
- itemNum = itemNum - len
- if itemNum <= 0 then
- msgRet.isEnd = 1
- return Msg.send(msgRet, human.fd)
- end
- Msg.send(msgRet, human.fd)
- len = 0
- msgRet.isStart = 0
- end
- end
- if len > 0 then
- msgRet.isEnd = 1
- Msg.send(msgRet, human.fd)
- end
- end
- -- 执行回收, itemType: 1-item表道具, 2-符文
- function RecycleItem_Recycle_Do(human, itemType, recycleItemStr)
- if not isOpen(human) then
- return Broadcast.sendErr(human, Lang.COMMOM_NOT_ENABLED)
- end
- if itemType ~= RECYCLE_ITEM_TYPE_ITEM and itemType ~= RECYCLE_ITEM_TYPE_FUWEN then
- return Broadcast.sendErr(human, Lang.COMMON_ARGUMENT_ERROR)
- end
- local recycleData = getRecycleData(human)
- local currentLevel = recycleData and recycleData.level or 0
- if currentLevel >= #RecycleConfig then
- return Broadcast.sendErr(human, Lang.COMMON_MAXLEVEL)
- end
- local entries = parseRecycleEntries(recycleItemStr)
- if not entries then
- return Broadcast.sendErr(human, Lang.COMMON_ARGUMENT_ERROR)
- end
- if itemType == RECYCLE_ITEM_TYPE_ITEM then
- entries = mergeItemRecycleEntries(entries)
- end
- local validateHandler = RECYCLE_VALIDATE_HANDLER[itemType]
- local deleteHandler = RECYCLE_DELETE_HANDLER[itemType]
- local totalExp, errLang = validateHandler(human, entries)
- if errLang then
- return Broadcast.sendErr(human, errLang)
- end
- deleteHandler(human, entries)
- local newLv, newExp = calcLv(human, totalExp)
- updateRecycleData(human, newLv, newExp)
- updatePower(human)
- RecycleItem_Query(human)
- RecycleItem_RecycleItemListQuery(human, itemType)
- end
|