------------------------------------------------------ -- 战意逻辑 ------------------------------------------------------ local Lang = require("common.Lang") local Util = require("common.Util") local Msg = require("core.Msg") local ObjHuman = require("core.ObjHuman") local Broadcast = require("broadcast.Broadcast") local Grid = require("bag.Grid") local BagLogic = require("bag.BagLogic") local ItemDefine = require("bag.ItemDefine") local HeroLogic = require("hero.HeroLogic") local Log = require("common.Log") local FuwenExcel = require("excel.fuwen") local BingshuLogic = require("fuwen.BingshuLogic") -- 战意回退配置 local BATTLE_WILL_ROLLBACK_CONFIG = { [1] = { -- 初级 needItemID = 1050, -- 消耗道具ID needItemCnt = 1, -- 消耗数量:1个 returnBattleWillCnt = 1, -- 返还战意:1个 returnFragmentID = 177, -- 返还战意碎片道具ID returnFragmentCnt = 0, -- 返还战意碎片:0 returnAncientSpiritID = 135, -- 返还远古之灵道具ID returnAncientSpiritCnt = 0 -- 返还远古之灵:0 }, [2] = { -- 中级 needItemID = 1050, needItemCnt = 5, -- 消耗数量:5个 returnBattleWillCnt = 4, -- 返还战意:4个 returnFragmentID = 177, returnFragmentCnt = 10000, -- 返还战意碎片:10,000 returnAncientSpiritID = 135, returnAncientSpiritCnt = 0 }, [3] = { -- 高级 needItemID = 1050, needItemCnt = 12, -- 消耗数量:12个 returnBattleWillCnt = 9, -- 返还战意:9个 returnFragmentID = 177, returnFragmentCnt = 40000, -- 返还战意碎片:40,000 returnAncientSpiritID = 135, returnAncientSpiritCnt = 0 }, [4] = { -- 超级 needItemID = 1050, needItemCnt = 50, -- 消耗数量:50个 returnBattleWillCnt = 19, -- 返还战意:19个 returnFragmentID = 177, returnFragmentCnt = 90000, -- 返还战意碎片:90,000 returnAncientSpiritID = 135, returnAncientSpiritCnt = 100 -- 返还远古之灵:100 } } -- 从配置表中动态获取战意技能组ID -- 配置表中 skill 表的所有技能都是战意技能 local function getBattleWillGroupIDs() local groupIDs = {} local groupIDSet = {} -- 遍历所有兵书技能(isBingshuSkill=1),收集所有 groupID -- 因为整个 skill 表都是战意,所以所有兵书技能的 groupID 都是战意技能组ID for skillID, skillConfig in pairs(FuwenExcel.skill) do if skillConfig and skillConfig.isBingshuSkill == 1 then local groupID = skillConfig.groupID if groupID and not groupIDSet[groupID] then table.insert(groupIDs, groupID) groupIDSet[groupID] = true end end end -- 如果没有找到,使用默认值(兼容性处理) if #groupIDs == 0 then -- Log.write(Log.LOGID_DEBUG, "[getBattleWillGroupIDs] 未找到战意技能,使用默认值: {1001, 1002}") return {1001, 1002} end -- 排序以确保一致性 table.sort(groupIDs) -- Log.write(Log.LOGID_DEBUG, "[getBattleWillGroupIDs] 找到战意技能组ID: "..table.concat(groupIDs, ",")) return groupIDs end -- 缓存战意技能组ID列表(在模块加载时初始化) local BATTLE_WILL_GROUP_IDS = getBattleWillGroupIDs() -- 判断是否是战意技能 local function isBattleWillSkill(skillConfig) if not skillConfig or not skillConfig.groupID then return false end for _, groupID in ipairs(BATTLE_WILL_GROUP_IDS) do if skillConfig.groupID == groupID then return true end end return false end ----------------------------------------- 工具函数 ----------------------------------------- -- 获取战意格子数据(通过索引) -- 战意数据存储在 heroGrid.bingshu[index] 中,需要判断 groupID == 1002 function getBattleWillGrid(heroGrid, index) if not heroGrid then -- Log.write(Log.LOGID_DEBUG, "[getBattleWillGrid] heroGrid为nil") return end if not index then -- Log.write(Log.LOGID_DEBUG, "[getBattleWillGrid] index为nil") return end -- 从bingshu中获取战意数据 if not heroGrid.bingshu then -- Log.write(Log.LOGID_DEBUG, "[getBattleWillGrid] heroGrid.bingshu为nil") return end local bingshuGrid = heroGrid.bingshu[index] if not bingshuGrid then -- Log.write(Log.LOGID_DEBUG, "[getBattleWillGrid] heroGrid.bingshu["..index.."]为nil") return end local skillID = bingshuGrid.skillID if not skillID then -- Log.write(Log.LOGID_DEBUG, "[getBattleWillGrid] skillID为nil, index="..index) return end -- 检查是否是战意技能(groupID=1001"狂暴"或groupID=1002"战意") local skillConfig = FuwenExcel.skill[skillID] if not skillConfig then -- Log.write(Log.LOGID_DEBUG, "[getBattleWillGrid] skillConfig为nil, skillID="..skillID) return end if not isBattleWillSkill(skillConfig) then -- Log.write(Log.LOGID_DEBUG, "[getBattleWillGrid] 不是战意技能, groupID="..(skillConfig.groupID or "nil")..", skillID="..skillID..", index="..index) return end -- Log.write(Log.LOGID_DEBUG, "[getBattleWillGrid] 找到战意技能: index="..index..", skillID="..skillID..", level="..(skillConfig.lv or "nil")) return bingshuGrid, index end -- 查找战意所在的索引(遍历所有bingshu格子) function findBattleWillIndex(heroGrid) if not heroGrid or not heroGrid.bingshu then -- Log.write(Log.LOGID_DEBUG, "[findBattleWillIndex] heroGrid或heroGrid.bingshu为nil") return nil end -- Log.write(Log.LOGID_DEBUG, "[findBattleWillIndex] 开始遍历所有bingshu格子,查找战意技能(groupID=1001或1002)") -- Log.write(Log.LOGID_DEBUG, "[findBattleWillIndex] BINGSHU_MAXCNT="..BingshuLogic.BINGSHU_MAXCNT) -- 遍历所有bingshu格子,查找groupID=1001或1002的技能 for i = 1, BingshuLogic.BINGSHU_MAXCNT do local bingshuGrid = heroGrid.bingshu[i] if bingshuGrid then local skillID = bingshuGrid.skillID --Log.write(Log.LOGID_DEBUG, "[findBattleWillIndex] bingshu["..i.."]存在, skillID="..(skillID or "nil")) if skillID then local skillConfig = FuwenExcel.skill[skillID] if skillConfig then --Log.write(Log.LOGID_DEBUG, "[findBattleWillIndex] bingshu["..i.."] skillConfig存在, skillID="..skillID..", groupID="..(skillConfig.groupID or "nil")..", lv="..(skillConfig.lv or "nil")..", name="..(skillConfig.name or "nil")) if isBattleWillSkill(skillConfig) then --Log.write(Log.LOGID_DEBUG, "[findBattleWillIndex] ✓ 找到战意: index="..i..", skillID="..skillID..", level="..(skillConfig.lv or "nil")..", name="..(skillConfig.name or "nil")..", groupID="..(skillConfig.groupID or "nil")) return i else --Log.write(Log.LOGID_DEBUG, "[findBattleWillIndex] bingshu["..i.."]不是战意, groupID="..(skillConfig.groupID or "nil")) end else --Log.write(Log.LOGID_DEBUG, "[findBattleWillIndex] bingshu["..i.."] skillConfig为nil, skillID="..skillID) end else --Log.write(Log.LOGID_DEBUG, "[findBattleWillIndex] bingshu["..i.."] skillID为nil") end else --Log.write(Log.LOGID_DEBUG, "[findBattleWillIndex] bingshu["..i.."]不存在") end end --Log.write(Log.LOGID_DEBUG, "[findBattleWillIndex] ✗ 未找到战意技能(groupID=1001或1002),已遍历所有"..BingshuLogic.BINGSHU_MAXCNT.."个格子") return nil end -- 获取战意等级 -- 根据skillID判断等级:1002=1级, 2002=2级, 3002=3级, 4002=4级 function getBattleWillLevel(heroGrid, index) local grid, actualIndex = getBattleWillGrid(heroGrid, index) if not grid then -- Log.write(Log.LOGID_DEBUG, "[getBattleWillLevel] grid为nil, index="..(index or "nil")) return 0 end local skillID = grid.skillID if not skillID then -- Log.write(Log.LOGID_DEBUG, "[getBattleWillLevel] skillID为nil") return 0 end -- 通过配置表获取等级 local skillConfig = FuwenExcel.skill[skillID] if skillConfig and isBattleWillSkill(skillConfig) then local level = skillConfig.lv or 0 --Log.write(Log.LOGID_DEBUG, "[getBattleWillLevel] 获取到等级: level="..level..", skillID="..skillID..", index="..(index or "nil")) return level end --Log.write(Log.LOGID_DEBUG, "[getBattleWillLevel] 不是战意技能, skillID="..skillID) return 0 end -- 获取下一级战意技能ID(参考兵书的getNextSkillID) function getNextBattleWillSkillID(skillID) local tconfig = FuwenExcel.skill[skillID] if not tconfig then return end if not isBattleWillSkill(tconfig) then return end for id, config in pairs(FuwenExcel.skill) do if (config.isBingshuSkill == 1) and isBattleWillSkill(config) and (config.groupID == tconfig.groupID) and -- 保持相同的groupID(1001或1002) (config.lv == tconfig.lv + 1) and (#config.bingshuUpNeed > 0) then return id end end end ----------------------------------------- 协议处理 ----------------------------------------- -- 查询回退信息 function sendRollbackQuery(human, heroID, heroIndex, index) --Log.write(Log.LOGID_DEBUG, "[sendRollbackQuery] 收到查询请求: heroID="..(heroID or "nil")..", heroIndex="..(heroIndex or "nil")..", index="..(index or "nil")) local heroGrid = HeroLogic.getHeroGrid(human, heroID, heroIndex) if not heroGrid then --Log.write(Log.LOGID_DEBUG, "[sendRollbackQuery] 英雄不存在: heroID="..(heroID or "nil")..", heroIndex="..(heroIndex or "nil")) return Broadcast.sendErr(human, Lang.COMMON_ARGUMENT_ERROR) end -- 如果传入的index不是战意,尝试查找战意所在的索引 local battleWillIndex = index local grid = getBattleWillGrid(heroGrid, index) if not grid then --Log.write(Log.LOGID_DEBUG, "[sendRollbackQuery] index="..index.."不是战意,尝试查找战意所在位置") battleWillIndex = findBattleWillIndex(heroGrid) if not battleWillIndex then -- Log.write(Log.LOGID_DEBUG, "[sendRollbackQuery] 未找到战意技能") return Broadcast.sendErr(human, "当前战意格子为空,无法回退") end grid = heroGrid.bingshu[battleWillIndex] end local currentLevel = getBattleWillLevel(heroGrid, battleWillIndex) -- Log.write(Log.LOGID_DEBUG, "[sendRollbackQuery] 当前战意等级: "..currentLevel..", index="..battleWillIndex) -- 检查等级是否可回退(等级0为空,不可回退) if currentLevel == 0 or currentLevel < 1 or currentLevel > 4 then -- Log.write(Log.LOGID_DEBUG, "[sendRollbackQuery] 当前等级不可回退: level="..currentLevel) return Broadcast.sendErr(human, "当前战意格子为空,无法回退") end local config = BATTLE_WILL_ROLLBACK_CONFIG[currentLevel] if not config then -- Log.write(Log.LOGID_DEBUG, "[sendRollbackQuery] 配置不存在: level="..currentLevel) return Broadcast.sendErr(human, Lang.COMMON_COMFIG_ERROR) end local msgRet = Msg.gc.GC_BATTLE_WILL_ROLLBACK_QUERY msgRet.heroID = heroID msgRet.heroIndex = heroIndex msgRet.index = battleWillIndex -- 使用实际找到的索引 msgRet.currentLevel = currentLevel msgRet.targetLevel = 0 -- 回退后等级固定为0(空) -- 消耗道具 Grid.makeItem(msgRet.needItem, config.needItemID, config.needItemCnt) -- 获取当前技能的groupID,确定返还的战意ID -- 从技能配置的 bingshuUpNeed 中获取第一个道具ID,那就是对应的战意道具ID local currentSkillID = grid.skillID local currentSkillConfig = FuwenExcel.skill[currentSkillID] local returnBattleWillID = nil if currentSkillConfig and currentSkillConfig.bingshuUpNeed and #currentSkillConfig.bingshuUpNeed > 0 then -- bingshuUpNeed 格式:{{itemID, count}, ...} -- 取第一个道具的ID作为战意道具ID local firstNeed = currentSkillConfig.bingshuUpNeed[1] if firstNeed and type(firstNeed) == "table" and #firstNeed >= 1 then returnBattleWillID = firstNeed[1] --Log.write(Log.LOGID_DEBUG, "[sendRollbackQuery] 从bingshuUpNeed获取战意道具ID: "..returnBattleWillID..", groupID="..(currentSkillConfig.groupID or "nil")..", skillID="..currentSkillID) end end if not returnBattleWillID then --Log.write(Log.LOGID_DEBUG, "[sendRollbackQuery] 无法确定返还战意ID: groupID="..(currentSkillConfig and currentSkillConfig.groupID or "nil")..", skillID="..(currentSkillID or "nil")..", bingshuUpNeed="..(currentSkillConfig and currentSkillConfig.bingshuUpNeed and #currentSkillConfig.bingshuUpNeed or "nil")) end -- 返还物品列表 msgRet.returnItems[0] = 0 local itemCnt = 0 -- 返还战意 if config.returnBattleWillCnt > 0 and returnBattleWillID then itemCnt = itemCnt + 1 if itemCnt <= #msgRet.returnItems then Grid.makeItem(msgRet.returnItems[itemCnt], returnBattleWillID, config.returnBattleWillCnt) end end -- 返还战意碎片 if config.returnFragmentCnt > 0 and config.returnFragmentID > 0 then itemCnt = itemCnt + 1 if itemCnt <= #msgRet.returnItems then Grid.makeItem(msgRet.returnItems[itemCnt], config.returnFragmentID, config.returnFragmentCnt) end end -- 返还远古之灵 if config.returnAncientSpiritCnt > 0 and config.returnAncientSpiritID > 0 then itemCnt = itemCnt + 1 if itemCnt <= #msgRet.returnItems then Grid.makeItem(msgRet.returnItems[itemCnt], config.returnAncientSpiritID, config.returnAncientSpiritCnt) end end msgRet.returnItems[0] = itemCnt --Log.write(Log.LOGID_DEBUG, "[sendRollbackQuery] 发送查询结果: currentLevel="..currentLevel..", index="..battleWillIndex..", needItemCnt="..config.needItemCnt..", returnItemsCount="..itemCnt) Msg.send(msgRet, human.fd) end -- 执行回退 function rollback(human, heroID, heroIndex, index) local heroGrid = HeroLogic.getHeroGrid(human, heroID, heroIndex) if not heroGrid then return Broadcast.sendErr(human, Lang.COMMON_ARGUMENT_ERROR) end -- 检查index范围(1-BINGSHU_MAXCNT) if index and (index < 1 or index > BingshuLogic.BINGSHU_MAXCNT) then return Broadcast.sendErr(human, Lang.COMMON_ARGUMENT_ERROR) end -- 如果传入的index不是战意,尝试查找战意所在的索引 local battleWillIndex = index local grid = nil if index then grid = getBattleWillGrid(heroGrid, index) end if not grid then battleWillIndex = findBattleWillIndex(heroGrid) if not battleWillIndex then return Broadcast.sendErr(human, "当前战意格子为空,无法回退") end grid = heroGrid.bingshu[battleWillIndex] end -- 获取当前技能配置,确定返还的战意ID和等级 local currentSkillID = grid.skillID local currentSkillConfig = FuwenExcel.skill[currentSkillID] if not currentSkillConfig then return Broadcast.sendErr(human, Lang.COMMON_COMFIG_ERROR) end -- 检查是否是战意技能 if not isBattleWillSkill(currentSkillConfig) then return Broadcast.sendErr(human, "当前格子不是战意技能,无法回退") end -- 从技能配置中获取等级(更可靠) local currentLevel = currentSkillConfig.lv or 0 -- 检查等级是否可回退 if currentLevel == 0 or currentLevel < 1 or currentLevel > 4 then return Broadcast.sendErr(human, "当前战意格子为空,无法回退") end -- 根据技能配置的 bingshuUpNeed 确定返还的战意ID -- 从 bingshuUpNeed 中获取第一个道具ID,那就是对应的战意道具ID local returnBattleWillID = nil if currentSkillConfig.bingshuUpNeed and #currentSkillConfig.bingshuUpNeed > 0 then -- bingshuUpNeed 格式:{{itemID, count}, ...} -- 取第一个道具的ID作为战意道具ID local firstNeed = currentSkillConfig.bingshuUpNeed[1] if firstNeed and type(firstNeed) == "table" and #firstNeed >= 1 then returnBattleWillID = firstNeed[1] end end if not returnBattleWillID then --Log.write(Log.LOGID_DEBUG, "[rollback] 无法确定返还战意ID: groupID="..(currentSkillConfig.groupID or "nil")..", skillID="..(currentSkillID or "nil")..", bingshuUpNeed="..(currentSkillConfig.bingshuUpNeed and #currentSkillConfig.bingshuUpNeed or "nil")) return Broadcast.sendErr(human, Lang.COMMON_COMFIG_ERROR) end -- 检查消耗道具(回退消耗) local config = BATTLE_WILL_ROLLBACK_CONFIG[currentLevel] if not config then --Log.write(Log.LOGID_DEBUG, "[rollback] 回退配置不存在: level="..currentLevel) return Broadcast.sendErr(human, Lang.COMMON_COMFIG_ERROR) end if not BagLogic.checkItemCnt(human, config.needItemID, config.needItemCnt) then return Broadcast.sendErr(human, Lang.COMMON_NO_ITEM) end -- 扣除消耗道具 BagLogic.delItem(human, config.needItemID, config.needItemCnt, "bingshu") -- 收集返还物品(根据配置) local returnItemList = {} -- 返还战意 if config.returnBattleWillCnt > 0 and returnBattleWillID then returnItemList[returnBattleWillID] = config.returnBattleWillCnt end -- 返还战意碎片 if config.returnFragmentCnt > 0 and config.returnFragmentID > 0 then returnItemList[config.returnFragmentID] = config.returnFragmentCnt end -- 返还远古之灵 if config.returnAncientSpiritCnt > 0 and config.returnAncientSpiritID > 0 then returnItemList[config.returnAncientSpiritID] = config.returnAncientSpiritCnt end -- 发放返还物品(使用通用道具发放逻辑) if next(returnItemList) then BagLogic.addItemList(human, returnItemList, "bingshu") end -- 更新战意等级为0(清空)- 删除bingshu中的战意技能 if not heroGrid.bingshu then heroGrid.bingshu = {} end local bingshuGrid = heroGrid.bingshu[battleWillIndex] if bingshuGrid then local skillConfig = FuwenExcel.skill[bingshuGrid.skillID] if skillConfig and isBattleWillSkill(skillConfig) then -- 这是战意技能,删除它 heroGrid.bingshu[battleWillIndex] = nil else --Log.write(Log.LOGID_DEBUG, "[rollback] WARNING: bingshu["..battleWillIndex.."]不是战意技能, skillID="..(bingshuGrid.skillID or "nil")) end end ObjHuman.doCalcHero(human, heroIndex) -- 发送英雄数据更新(如果需要) HeroLogic.sendHeroBagDynamic(human, heroID, heroIndex) -- 发送GC_BINGSHU_QUERY刷新所有兵书状态 BingshuLogic.sendQuery(human, heroID, heroIndex) end