diff --git a/lua/app/game.lua b/lua/app/game.lua index 592831de..cedb921e 100644 --- a/lua/app/game.lua +++ b/lua/app/game.lua @@ -405,6 +405,21 @@ if NOT_PUBLISH then end end + if (Input.GetKeyDown(KeyCode.Space)) and Input.GetKey(KeyCode.LeftControl) then + local battleController = ModuleManager.BattleManager.battleController + if not battleController then + return + end + local heler = require "app/module/battle/helper/board_helper" + local path = heler:findPvpLinkOptimalSolution(battleController, 1, 7) + if path then + for _, id in ipairs(path) do + local entity = battleController.battleData:getGridEnties()[id] + entity:getCell():showHighLight(true) + end + end + end + if (Input.GetKeyDown(KeyCode.RightArrow) or Input.GetKeyDown(KeyCode.LeftArrow)) and Input.GetKey(KeyCode.LeftControl) then if not ModuleManager.DevToolManager.set_board_info then Logger.logHighlight("请先去gm面板设置浏览的棋盘信息!") diff --git a/lua/app/module/battle/controller/battle_controller_pvp.lua b/lua/app/module/battle/controller/battle_controller_pvp.lua index ff55287e..1aaf255f 100644 --- a/lua/app/module/battle/controller/battle_controller_pvp.lua +++ b/lua/app/module/battle/controller/battle_controller_pvp.lua @@ -1,4 +1,5 @@ local BattleHelper = require "app/module/battle/helper/battle_helper" +local board_heler = require "app/module/battle/helper/board_helper" local BattleBaseController = require "app/module/battle/controller/battle_base_controller" local BattleControllerPVP = class("BattleControllerPVP", BattleBaseController) local BattleConst = GConst.BattleConst @@ -239,10 +240,45 @@ function BattleControllerPVP:enterElimination(needDelay) if not find then -- 如果没找到,就要打乱棋盘 self:shuffleBoard(function() self.roundStep = BattleConst.BATTLE_ROUND_STEP.ON_ELIMINATION + self:checkDefBoard() end) else self.attentionList = pathList self.roundStep = BattleConst.BATTLE_ROUND_STEP.ON_ELIMINATION + self:checkDefBoard() + end +end + +function BattleControllerPVP:checkDefBoard() + if self:getCurActionSide() == SIDE_DEF then + local path = board_heler:findPvpLinkOptimalSolution(self, self:getAtkMinRow(), 1) + if path and #path >= self:getMinEliminationCount() then + if self.showCheckDefBoardSeq then + self.showCheckDefBoardSeq:Kill() + self.showCheckDefBoardSeq = nil + end + self.showCheckDefBoardSeq = self.battleUI.root:createBindTweenSequence() + local lastPosId + for index, posId in ipairs(path) do + lastPosId = posId + local time = index * 0.3 + self.showCheckDefBoardSeq:InsertCallback(time, function() + local eventType + if index == 1 then + eventType = GConst.ELIMINATION_TOUCH_EVENT.DOWN + else + eventType = GConst.ELIMINATION_TOUCH_EVENT.ENTER + end + self:onTouchEvent(eventType, posId) + end) + end + self.showCheckDefBoardSeq:AppendInterval(0.5) + self.showCheckDefBoardSeq:AppendCallback(function() + self:onTouchEvent(GConst.ELIMINATION_TOUCH_EVENT.UP, lastPosId) + end) + else -- 没有找到,直接进入下一波 + self:enterNextTeamAction() + end end end diff --git a/lua/app/module/battle/helper/board_helper.lua b/lua/app/module/battle/helper/board_helper.lua index 7f7d76a4..0b387cf4 100644 --- a/lua/app/module/battle/helper/board_helper.lua +++ b/lua/app/module/battle/helper/board_helper.lua @@ -1,18 +1,142 @@ local BoardHelper = {} +local BattleConst = GConst.BattleConst -function BoardHelper:findPvpLinkOptimalSolution(battleController, minRow, maxRow) +function BoardHelper:getEmptyTable() + if not self.tempEmptyTables then + self.tempEmptyTables = {} + end + if not self.tempEmptyTables[1] then + table.insert(self.tempEmptyTables, {}) + end + return table.remove(self.tempEmptyTables) +end + +function BoardHelper:recycleedEmptyTable(emptyTable) + if not emptyTable then + return + end + emptyTable = table.clear(emptyTable) + if self.tempEmptyTables then + table.insert(self.tempEmptyTables, emptyTable) + end +end + +function BoardHelper:findPvpLinkOptimalSolution(battleController, startRow, endRow) local battleData = battleController.battleData - local gridEntities = {} + local gridMap = BoardHelper:getEmptyTable() + local minRow = math.min(startRow, endRow) + local maxRow = math.max(startRow, endRow) for row = minRow, maxRow do -- 遍历所有的可使用格子 - for column = 1, GConst.BattleConst.COLUMN_COUNT do + for column = 1, BattleConst.COLUMN_COUNT do local posId = ModuleManager.BattleManager:getPosId(row, column) local gridEntity = battleData:getGridEnties()[posId] if gridEntity and gridEntity:canLink() then - table.insert(gridEntities, gridEntity) + gridMap[posId] = gridEntity end end end + local maxPath + local maxPathCount = 0 + for posId, entity in pairs(gridMap) do + local mainElementType + if not entity:getSkillId() then + mainElementType = entity:getElementType() + local tree = BoardHelper:getEmptyTable() + self:getCanlinkTree(posId, gridMap, tree, mainElementType) + + local checked = BoardHelper:getEmptyTable() + local haveSkill = false + local path = self:findMaxPath(posId, tree, checked, haveSkill, gridMap) + local count = #path + if count > maxPathCount then + maxPath = path + maxPathCount = count + end + for posId, info in pairs(tree) do + BoardHelper:recycleedEmptyTable(info) + end + BoardHelper:recycleedEmptyTable(tree) + BoardHelper:recycleedEmptyTable(checked) + end + end + + BoardHelper:recycleedEmptyTable(gridMap) + + return maxPath +end + +function BoardHelper:findMaxPath(posId, tree, checked, haveSkill, gridMap) + if not checked[posId] and tree[posId] then + local newPath + local newPathCount = 0 + local newHaveSkill = false + local newChecked = GFunc.getTable(checked) + newChecked[posId] = true + for nextPosId, _ in pairs(tree[posId]) do + local entity = gridMap[nextPosId] + if not entity:getSkillId() or not haveSkill then + if entity:getSkillId() then + haveSkill = true + end + local p, getSkill = self:findMaxPath(nextPosId, tree, newChecked, haveSkill, gridMap) + if p then + local count = #p + if getSkill and not newHaveSkill then + newPath = GFunc.getTable(p) + newPathCount = count + newHaveSkill = getSkill + else + if not getSkill and newHaveSkill then + BoardHelper:recycleedEmptyTable(p) + else + if count > newPathCount then + newPath = GFunc.getTable(p) + newPathCount = count + newHaveSkill = getSkill + else + BoardHelper:recycleedEmptyTable(p) + end + end + end + end + end + end + if not newPath then + newPath = BoardHelper:getEmptyTable() + end + table.insert(newPath, 1, posId) + if not newHaveSkill then + newHaveSkill = gridMap[posId]:getSkillId() ~= nil + end + + return newPath, newHaveSkill + end +end + +function BoardHelper:getCanlinkTree(posId, gridMap, tree, mainElementType) + if tree[posId] then + return + end + + local ids = self:getAroundPosIds(posId, gridMap, mainElementType) + tree[posId] = ids + for aroundPosId, status in pairs(ids) do + self:getCanlinkTree(aroundPosId, gridMap, tree, mainElementType) + end +end + +function BoardHelper:getAroundPosIds(posId, gridMap, mainElementType) + local ids = BoardHelper:getEmptyTable() + local aroundPosIds = BattleConst.GRID_OUT_LINE_POS_ID[posId] + if aroundPosIds then + for id, status in pairs(aroundPosIds) do + if gridMap[id] and (gridMap[id]:getElementType() == mainElementType or gridMap[id]:getSkillId()) then + ids[id] = true + end + end + end + return ids end return BoardHelper \ No newline at end of file diff --git a/lua/app/ui/battle/battle_ui_pvp.lua b/lua/app/ui/battle/battle_ui_pvp.lua index babf61f6..9f20c9cd 100644 --- a/lua/app/ui/battle/battle_ui_pvp.lua +++ b/lua/app/ui/battle/battle_ui_pvp.lua @@ -20,6 +20,7 @@ function BattleUIPVP:initBaseInfo() self.boardCacheBox:setAnchoredPositionX(DEFAULT_X) self.battleRoot = uiMap["battle_ui_pvp.battle_root"] self.maxLayerNode = uiMap["battle_ui_pvp.battle_root.battle_node.max_layer_show_node"] + self.touchMask = uiMap["battle_ui_pvp.board_root_node.touch_mask"] end function BattleUIPVP:initBg() @@ -209,12 +210,16 @@ function BattleUIPVP:refreshWave(wave, iconAtlas, iconName) end function BattleBaseUI:enterShowBoardAni(callback) + local isAtkAction = self.battleController.curActionSide == GConst.BattleConst.SIDE_ATK + if self.touchMask then + self.touchMask:setVisible(not isAtkAction) + end self:clearEnterShowBoardSeq() self.enterShowBoardSeq = self.root:createBindTweenSequence() self.enterShowBoardSeq:Append(self:getBoardRootNode():getTransform():DOLocalMoveX(0, 0.5)) self.enterShowBoardSeq:AppendCallback(function() local str - if self.battleController.curActionSide == GConst.BattleConst.SIDE_ATK then + if isAtkAction then str = I18N:getGlobalText(I18N.GlobalConst.ARENA_BATTLE_DESC_1) else str = I18N:getGlobalText(I18N.GlobalConst.ARENA_BATTLE_DESC_2) @@ -231,6 +236,7 @@ function BattleBaseUI:enterHideBoardAni(callback) self.enterShowBoardSeq = self.root:createBindTweenSequence() local w, h = GFunc.getUIExpandScreenSize() self.enterShowBoardSeq:Append(self:getBoardRootNode():getTransform():DOLocalMoveX(w / 2 + 360, 0.5)) + self.enterShowBoardSeq:AppendInterval(0.5) self.enterShowBoardSeq:AppendCallback(function() if callback then callback() diff --git a/lua/app/ui/gm/gm_tool_ui.lua b/lua/app/ui/gm/gm_tool_ui.lua index b85a2472..d63c4535 100644 --- a/lua/app/ui/gm/gm_tool_ui.lua +++ b/lua/app/ui/gm/gm_tool_ui.lua @@ -114,6 +114,24 @@ function GMToolUI:sendMsg(gmCommand) isMystery = args.args[4] ~= nil } self:closeUI() + elseif args.args[1] == "add_skill" then -- 特殊处理 + if not ModuleManager.BattleManager:isInBattle() then + Logger.logHighlight("不在战斗中") + return + end + local posId = tonumber(args.args[2]) + local skillElement = tonumber(args.args[3]) + local side = GConst.BattleConst.SIDE_ATK + if args.args[4] then + side = tonumber(args.args[4]) + end + local controller = ModuleManager.BattleManager.battleController + local battleData = controller.battleData + local entity = battleData:getSkillEntityByElement(skillElement, side) + if entity then + battleData:getGridEnties()[posId]:setSkilId(entity:getSkillId(), false, side) + end + self:closeUI() elseif args.args[1] == "check_skill_sound" then self:checkSkillSoundExist() self:closeUI()