|
|
@@ -1,4 +1,9 @@
|
|
|
-- 收纳箱(回收道具)
|
|
|
+--
|
|
|
+-- doCalcHero 统计收纳箱英雄属性加成
|
|
|
+-- RecycleItem_Query 查询收纳箱等级/经验/属性
|
|
|
+-- RecycleItem_RecycleItemListQuery 查询可回收道具列表
|
|
|
+-- RecycleItem_Recycle_Do 执行回收
|
|
|
|
|
|
--db
|
|
|
--[=[
|
|
|
@@ -18,20 +23,191 @@ 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
|
|
|
@@ -101,7 +277,7 @@ local function calcLv(human, addExp)
|
|
|
return newLv, currentExp
|
|
|
end
|
|
|
|
|
|
-
|
|
|
+-- 填充当前等级属性到协议结构
|
|
|
local function populateCurrentLvAttrs(net, currentLevel)
|
|
|
local isZero = false
|
|
|
if currentLevel <= 0 then
|
|
|
@@ -122,6 +298,7 @@ local function populateCurrentLvAttrs(net, currentLevel)
|
|
|
|
|
|
end
|
|
|
|
|
|
+-- 填充下一等级属性到协议结构
|
|
|
local function populateNextLvAttrs(net, nextLv)
|
|
|
local isMax = false
|
|
|
local maxLv = #RecycleConfig
|
|
|
@@ -189,7 +366,7 @@ end
|
|
|
|
|
|
|
|
|
|
|
|
--- 查询部分信息
|
|
|
+-- 查询收纳箱等级、经验及属性加成
|
|
|
function RecycleItem_Query(human)
|
|
|
if not isOpen(human) then
|
|
|
return Broadcast.sendErr(human, Lang.COMMOM_NOT_ENABLED)
|
|
|
@@ -219,29 +396,26 @@ function RecycleItem_Query(human)
|
|
|
Msg.send(msgRet, human.fd)
|
|
|
end
|
|
|
|
|
|
--- 查询可回收道具列表
|
|
|
-function RecycleItem_RecycleItemListQuery(human)
|
|
|
+-- 查询可回收道具列表, 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 bagData = BagLogic.GetBagData(human)
|
|
|
- if not bagData then
|
|
|
- msgRet.isEnd = 1
|
|
|
- return Msg.send(msgRet, human.fd)
|
|
|
- end
|
|
|
-
|
|
|
- local itemArr = {}
|
|
|
- for itemId in pairs(bagData) do
|
|
|
- local itemCfg = ItemConfig[itemId]
|
|
|
- if itemCfg and itemCfg.val and itemCfg.val > 0 then
|
|
|
- itemArr[#itemArr+1] = {itemId, itemCfg.val}
|
|
|
- end
|
|
|
+ local itemArr
|
|
|
+ if itemType == RECYCLE_ITEM_TYPE_FUWEN then
|
|
|
+ itemArr = collectFuwenRecycleList(human)
|
|
|
+ else
|
|
|
+ itemArr = collectItemRecycleList(human)
|
|
|
end
|
|
|
|
|
|
local itemNum = #itemArr
|
|
|
@@ -258,6 +432,7 @@ function RecycleItem_RecycleItemListQuery(human)
|
|
|
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
|
|
|
@@ -278,53 +453,44 @@ function RecycleItem_RecycleItemListQuery(human)
|
|
|
end
|
|
|
end
|
|
|
|
|
|
--- 回收道具
|
|
|
-function RecycleItem_Recycle_Do(human, recycleItemStr)
|
|
|
+-- 执行回收, 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
|
|
|
|
|
|
- local itemList = Util.parseKVString(recycleItemStr, "|", "-", Util.TONUMBER_ALL)
|
|
|
- if not next(itemList) then
|
|
|
+ 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
|
|
|
- local maxLevel = #RecycleConfig
|
|
|
- if currentLevel >= maxLevel then
|
|
|
+ if currentLevel >= #RecycleConfig then
|
|
|
return Broadcast.sendErr(human, Lang.COMMON_MAXLEVEL)
|
|
|
end
|
|
|
|
|
|
- local totalExp = 0
|
|
|
- for itemId, itemCnt in pairs(itemList) do
|
|
|
- local itemCfg = ItemConfig[itemId]
|
|
|
- if not itemCfg or not itemCfg.val or itemCfg.val <= 0 then
|
|
|
- return Broadcast.sendErr(human, Lang.ITEM_CANNOT_RECYCLE)
|
|
|
- end
|
|
|
-
|
|
|
- if BagLogic.getItemCnt(human, itemId) < itemCnt then
|
|
|
- return Broadcast.sendErr(human, Lang.COMMON_ITEM_NOT_ENOUGH)
|
|
|
- end
|
|
|
+ local entries = parseRecycleEntries(recycleItemStr)
|
|
|
+ if not entries then
|
|
|
+ return Broadcast.sendErr(human, Lang.COMMON_ARGUMENT_ERROR)
|
|
|
+ end
|
|
|
|
|
|
- totalExp = totalExp + itemCfg.val * itemCnt
|
|
|
+ if itemType == RECYCLE_ITEM_TYPE_ITEM then
|
|
|
+ entries = mergeItemRecycleEntries(entries)
|
|
|
end
|
|
|
|
|
|
- for itemId, itemCnt in pairs(itemList) do
|
|
|
- if BagLogic.getItemCnt(human, itemId) < itemCnt then
|
|
|
- return Broadcast.sendErr(human, Lang.COMMON_ITEM_NOT_ENOUGH)
|
|
|
- end
|
|
|
- BagLogic.delItem(human, itemId, itemCnt, LOG_TAG)
|
|
|
+ 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)
|
|
|
|
|
|
- -- 更新UI界面数据
|
|
|
RecycleItem_Query(human)
|
|
|
- RecycleItem_RecycleItemListQuery(human)
|
|
|
+ RecycleItem_RecycleItemListQuery(human, itemType)
|
|
|
end
|