Просмотр исходного кода

1.收纳箱增加回收符文功能 2.修改灭魂效果

gitxsm 2 недель назад
Родитель
Сommit
35b9f1982a

+ 18 - 4
script/common/Util.lua

@@ -478,13 +478,13 @@ end
 TONUMBER_KEY   = "key"
 TONUMBER_VALUE = "value"
 TONUMBER_ALL   = "all"
---- 灵活解析键值字符串
+--- 灵活解析键值字符串为列表
 -- @param str           源字符串,如 "1001-10|1002-11"
 -- @param segSep        段分隔符,如 "|"(默认 "|")
 -- @param kvSep         键值分隔符,如 "-"(默认 "-")
 -- @param tonumberMode  可选:"key"只转键,"value"只转值,"all"都转,nil不转
--- @return table        解析后的字典表
-function parseKVString(str, segSep, kvSep, tonumberMode)
+-- @return table        解析后的列表,格式: {{key, value}, ...}
+function parseKVList(str, segSep, kvSep, tonumberMode)
     -- 防护:nil 或空字符串直接返回空表
     if not str or str == "" then
         return {}
@@ -521,13 +521,27 @@ function parseKVString(str, segSep, kvSep, tonumberMode)
                 value = tonumber(value) or value
             end
 
-            result[key] = value
+            result[#result + 1] = {key, value}
         end
     end
 
     return result
 end
 
+--- 灵活解析键值字符串
+-- @param str           源字符串,如 "1001-10|1002-11"
+-- @param segSep        段分隔符,如 "|"(默认 "|")
+-- @param kvSep         键值分隔符,如 "-"(默认 "-")
+-- @param tonumberMode  可选:"key"只转键,"value"只转值,"all"都转,nil不转
+-- @return table        解析后的字典表
+function parseKVString(str, segSep, kvSep, tonumberMode)
+    local result = {}
+    for _, kv in ipairs(parseKVList(str, segSep, kvSep, tonumberMode)) do
+        result[kv[1]] = kv[2]
+    end
+    return result
+end
+
 
 
 -- 根据KEY从小到大排序

+ 2 - 2
script/module/bag/Handler.lua

@@ -100,9 +100,9 @@ function CG_RECYCLE_QUERY(human, msg)
 end
 
 function CG_RECYCLE_RECYCLEITEM(human, msg)
-	RecycleItem.RecycleItem_Recycle_Do(human, msg.recycleItemStr)
+	RecycleItem.RecycleItem_Recycle_Do(human, msg.itemType, msg.recycleItemStr)
 end
 
 function CG_RECYCLE_GET_RECYCLE_LIST(human, msg)
-	RecycleItem.RecycleItem_RecycleItemListQuery(human)
+	RecycleItem.RecycleItem_RecycleItemListQuery(human, msg.itemType)
 end

+ 7 - 3
script/module/bag/Proto.lua

@@ -371,7 +371,8 @@ CG_DUIHUANG_DO = {
 
 RECYCLE_ITEM = {
 	{"id",			1,		"int"},		-- 物品ID
-	{"recycleVal",	1,		"short"},	-- 回收值
+	{"recycleVal",	1,		"int"},	-- 回收值
+	{"extraInfo",	1,		"int"},		-- 额外信息, 如果是item表中的道具,则为0, 如果是符文,则为该符文在符文背包的的idx
 }
 --查询
 CG_RECYCLE_QUERY = {}
@@ -385,7 +386,9 @@ GC_RECYCLE_QUERY = {
 	{"nextLvAttrs",		6,		Attr},			-- 下一级加成属性
 }
 
-CG_RECYCLE_GET_RECYCLE_LIST = {}
+CG_RECYCLE_GET_RECYCLE_LIST = {
+	{"itemType",	1,	"byte"},      -- 1-item表中的道具, 2-符文
+}
 GC_RECYCLE_GET_RECYCLE_LIST = {
 	{"recycleList",		50,		RECYCLE_ITEM},	-- 可回收道具列表
 	{"isStart",			1,		"byte"},      	-- 0-否,1-是
@@ -395,5 +398,6 @@ GC_RECYCLE_GET_RECYCLE_LIST = {
 
 --回收道具
 CG_RECYCLE_RECYCLEITEM = {
-	{"recycleItemStr",		1,		"string"},	-- 回收道具信息, 格式:"道具Id-数量|道具Id-数量"
+	{"itemType",	1,	"byte"},      -- 1-item表中的道具, 2-符文
+	{"recycleItemStr",		1,		"string"},	-- 回收道具信息, 如果是item表中的道具,格式:"道具Id-数量|道具Id-数量", 如果是符文,格式:"道具Id-idx|道具Id-idx"
 }

+ 209 - 43
script/module/bag/RecycleItem.lua

@@ -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

+ 34 - 1
script/module/combat/BeSkill.lua

@@ -546,6 +546,32 @@ local function comboCheck(targetObj, side)
 end
 
 
+-- 是否触发灭魂
+local function triggerMieHunCheck(targetPos)
+	local attacker = CombatImpl.objList[targetPos]
+	if not attacker then
+		return
+	end
+
+	if attacker.beSkillList[BESKILL_TYPE72] then
+		for _,v in ipairs(attacker.beSkillList[BESKILL_TYPE72]) do
+			--local skillConfig = SkillExcel[v[1]]
+			local skillConfig = Skill.GetSkillConfig(v[1])
+			if skillConfig.cmd == "miehun" then
+				local triggerVal, banRound = skillConfig.args[1] or 0, skillConfig.args[2] or 0
+				if banRound <= 0 then
+					return
+				end
+
+				local r = math.random(0, 10000)
+				if triggerVal >= r then
+					return true, banRound
+				end
+			end
+		end
+	end
+end
+
 
 function onSkillID(obj,skillID)
 	--local skillConfig = SkillExcel[skillID]
@@ -1120,7 +1146,14 @@ function onDie(obj, hurt, attackPos)
 			end
 		end
 	end
-	
+
+	-- 灭魂处理, 只针对英雄
+	if not obj.isPet and not obj.isElf then
+		local res, banRound = triggerMieHunCheck(attackPos)
+		if res and banRound then
+			obj.miehunBanReviveUntilRound = CombatImpl.round + banRound
+		end
+	end
 
 	local defendSide = side == CombatDefine.ATTACK_SIDE and CombatDefine.DEFEND_SIDE or CombatDefine.ATTACK_SIDE
 	for _,posData in ipairs(posSortBySpeed[side]) do

+ 24 - 17
script/module/combat/CombatBuff.lua

@@ -169,30 +169,36 @@ end
 
 -- 复活条件判断
 local function reviveCheck(obj)
-	if obj then
-		if obj.hp > 0 then
-			return 1
-		end
+	if not obj then
+		return -1
+	end
 
-		if obj.beBackup then
-			return -1
-		end
+	if obj.hp > 0 then
+		return 1
+	end
 
-		if obj.dieSkill then
-			--local skillConf = SkillExcel[obj.dieSkill]
-			local skillConf = Skill.GetSkillConfig(obj.dieSkill)
-			if skillConf.otherArgs.noRevive == 1 then
-				return -1
-			end
-		end
+	if obj.beBackup then
+		return -1
+	end
 
-		if obj.bufferCmd and obj.bufferCmd["noRevive"] then
+	if obj.dieSkill then
+		--local skillConf = SkillExcel[obj.dieSkill]
+		local skillConf = Skill.GetSkillConfig(obj.dieSkill)
+		if skillConf.otherArgs.noRevive == 1 then
 			return -1
 		end
+	end
 
-		return 0
+	if obj.bufferCmd and obj.bufferCmd["noRevive"] then
+		return -1
 	end
-	return -1
+
+	-- 灭魂判断
+	if obj.miehunBanReviveUntilRound and obj.miehunBanReviveUntilRound >= CombatImpl.round then -- 已有禁止复活标识且未过期
+		return -1
+	end
+
+	return 0
 end
 
 
@@ -929,6 +935,7 @@ function reviceObj(attackPos, obj, bufferID, skillID)
 	BeSkill.onAddBuffer(obj,{id = bufferID})
 
 	obj.dieSkill = nil
+	obj.killerPos = nil
 
 	CombatImpl.InsertAttackOrder(obj.pos)
 

+ 42 - 0
script/module/fuwen/FuwenLogic.lua

@@ -257,6 +257,48 @@ function del(human, index, logType)
 	sendFuwenItemChange(human, index, nil, FuwenDefine.FUWEN_BAG_OP_DEL)
 end
 
+-- 获取符文背包数据
+function getFuwenBagData(human)
+    return human.db.fuwenBag
+end
+
+-- 获取符文背包指定格子
+function getFuwenGrid(human, index)
+    local fuwenBag = human.db.fuwenBag
+    if not fuwenBag then
+        return
+    end
+    return fuwenBag[index]
+end
+
+-- 获取符文背包中指定符文数量
+function getFuwenCntById(human, fuwenId)
+    local cnt = 0
+    for _, fuwenGrid in pairs(human.db.fuwenBag or {}) do
+        if fuwenGrid and fuwenGrid.id == fuwenId then
+            cnt = cnt + 1
+        end
+    end
+    return cnt
+end
+
+-- 按符文ID删除指定数量符文
+function delFuwenById(human, fuwenId, cnt, logType)
+    local indexList = {}
+    for index, fuwenGrid in pairs(human.db.fuwenBag or {}) do
+        if fuwenGrid and fuwenGrid.id == fuwenId then
+            indexList[#indexList + 1] = index
+            if #indexList >= cnt then
+                break
+            end
+        end
+    end
+
+    for _, index in ipairs(indexList) do
+        del(human, index, logType)
+    end
+end
+
 -- 穿上符文
 function putOn(human, heroID, heroIndex, fuwenIndex,pos,noCalc)
     local heroGrid = HeroLogic.getHeroGrid(human, heroID, heroIndex)