From a623c25f6fa1624c13bf117898c49cc34e7f6843 Mon Sep 17 00:00:00 2001 From: xiekaidong Date: Mon, 26 Jun 2023 15:28:40 +0800 Subject: [PATCH] =?UTF-8?q?pvp=E6=88=98=E6=96=97=E6=A6=82=E5=BF=B5?= =?UTF-8?q?=E5=BC=95=E5=85=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lua/app/common/data_manager.lua | 3 +- lua/app/module/battle/battle_const.lua | 2 +- lua/app/module/battle/battle_manager.lua | 11 + .../controller/battle_base_controller.lua | 2873 +++++++++++++++++ .../battle_base_controller.lua.meta | 10 + .../battle/controller/battle_controller.lua | 4 +- .../controller/battle_controller_pvp.lua | 173 + .../controller/battle_controller_pvp.lua.meta | 10 + .../skill/battle_rogue_skill_handle.lua | 96 +- lua/app/ui/battle/battle_base_ui.lua | 2280 +++++++++++++ lua/app/ui/battle/battle_base_ui.lua.meta | 10 + lua/app/ui/battle/battle_ui_pvp.lua | 224 ++ lua/app/ui/battle/battle_ui_pvp.lua.meta | 10 + lua/app/ui/battle/cell/tiny_buff_cell.lua | 15 + .../ui/battle/cell/tiny_buff_cell.lua.meta | 10 + lua/app/userdata/battle/battle_base_data.lua | 720 +++++ .../userdata/battle/battle_base_data.lua.meta | 10 + lua/app/userdata/battle/battle_data.lua | 692 +--- lua/app/userdata/battle/battle_pvp_data.lua | 9 + .../userdata/battle/battle_pvp_data.lua.meta | 10 + lua/app/userdata/hero/hero_entity.lua | 2 +- 21 files changed, 6433 insertions(+), 741 deletions(-) create mode 100644 lua/app/module/battle/controller/battle_base_controller.lua create mode 100644 lua/app/module/battle/controller/battle_base_controller.lua.meta create mode 100644 lua/app/module/battle/controller/battle_controller_pvp.lua create mode 100644 lua/app/module/battle/controller/battle_controller_pvp.lua.meta create mode 100644 lua/app/ui/battle/battle_base_ui.lua create mode 100644 lua/app/ui/battle/battle_base_ui.lua.meta create mode 100644 lua/app/ui/battle/battle_ui_pvp.lua create mode 100644 lua/app/ui/battle/battle_ui_pvp.lua.meta create mode 100644 lua/app/ui/battle/cell/tiny_buff_cell.lua create mode 100644 lua/app/ui/battle/cell/tiny_buff_cell.lua.meta create mode 100644 lua/app/userdata/battle/battle_base_data.lua create mode 100644 lua/app/userdata/battle/battle_base_data.lua.meta create mode 100644 lua/app/userdata/battle/battle_pvp_data.lua create mode 100644 lua/app/userdata/battle/battle_pvp_data.lua.meta diff --git a/lua/app/common/data_manager.lua b/lua/app/common/data_manager.lua index 51f82c91..5288df8c 100644 --- a/lua/app/common/data_manager.lua +++ b/lua/app/common/data_manager.lua @@ -13,6 +13,7 @@ function DataManager:init() self:initManager("HeroData", "app/userdata/hero/hero_data") self:initManager("BagData", "app/userdata/bag/bag_data") self:initManager("BattleData", "app/userdata/battle/battle_data") + self:initManager("BattlePVPData", "app/userdata/battle/battle_pvp_data") self:initManager("FormationData", "app/userdata/formation/formation_data") self:initManager("TutorialData", "app/userdata/tutorial/tutorial_data") self:initManager("MailData", "app/userdata/mail/mail_data") @@ -33,7 +34,7 @@ function DataManager:initManager(name, path) self._cacheManager[name] = self[name] end - if name == "BattleData" and self._cacheManager[name] then + if (name == "BattleData" or name == "BattlePVPData") and self._cacheManager[name] then else self[name] = require(path):create() end diff --git a/lua/app/module/battle/battle_const.lua b/lua/app/module/battle/battle_const.lua index cfc161c8..74165e26 100644 --- a/lua/app/module/battle/battle_const.lua +++ b/lua/app/module/battle/battle_const.lua @@ -1,8 +1,8 @@ local BattleConst = {} BattleConst.ROW_COUNT = 7 +BattleConst.PVP_ROW_COUNT = 10 BattleConst.COLUMN_COUNT = 7 -BattleConst.PVP_COLUMN_COUNT = 10 BattleConst.HALF_ROW_COUNT = 4 -- 计算偏移 math.ceil(ROW_COUNT / 2) BattleConst.HALF_COLUMN_COUNT = 4 -- 计算偏移 math.ceil(COLUMN_COUNT / 2) BattleConst.GRID_STEP_H = 94 diff --git a/lua/app/module/battle/battle_manager.lua b/lua/app/module/battle/battle_manager.lua index 0335b795..555b42a1 100644 --- a/lua/app/module/battle/battle_manager.lua +++ b/lua/app/module/battle/battle_manager.lua @@ -47,6 +47,7 @@ function BattleManager:isInBattle() return self.battleController ~= nil end +-- params = {atkFormation= {elementType = heroEntity}, defFormation= ?} function BattleManager:playBattle(battleType, params, returnFunc) UIManager:showLoading(UIManager.LOADING_TYPE.CLOUD, function() params = params or {} @@ -61,6 +62,16 @@ end function BattleManager:_play(battleType, params) params.battleType = battleType + if not params.atkFormation then + params.atkFormation = {} + local formation = DataManager.FormationData:getStageFormation() + for elementType, heroId in pairs(formation) do + local heroEntity = DataManager.HeroData:getHeroById(heroId) + if heroEntity then + params.atkFormation[elementType] = heroEntity + end + end + end local controllerPath = BATTLE_CONTROLLER[battleType] or BATTLE_CONTROLLER_BASE self.battleController = require(controllerPath):create() self.battleController:init(params) diff --git a/lua/app/module/battle/controller/battle_base_controller.lua b/lua/app/module/battle/controller/battle_base_controller.lua new file mode 100644 index 00000000..ad613b97 --- /dev/null +++ b/lua/app/module/battle/controller/battle_base_controller.lua @@ -0,0 +1,2873 @@ +local BattleScheduler = require "app/module/battle/helper/battle_scheduler" +local BattlePassive = require "app/module/battle/helper/battle_passive" +local BattlePool = require "app/module/battle/helper/battle_pool" +local BattleHelper = require "app/module/battle/helper/battle_helper" +local BattleBuffEntity = require "app/userdata/battle/skill/battle_buff_entity" +local BattleTeam = require "app/module/battle/team/battle_team" +local BATTLE_BOARD_SKILL_HANDLE = require "app/module/battle/skill/battle_board_skill_handle" +local BATTLE_ROGUE_SKILL_HANDLE = require "app/module/battle/skill/battle_rogue_skill_handle" +local BATTLE_GRID_EFFECT_HANDLE = require "app/module/battle/skill/battle_grid_effect_handle" +local BATTLE_INSTRUCTIONS_HELPER = require "app/module/battle/helper/battle_instructions_helper" +local BattleBuffHandle = require "app/module/battle/helper/battle_buff_handle" +local BattleBaseController = class("BattleBaseController") +local BattleConst = GConst.BattleConst +local ELIMINATION_TOUCH_EVENT = GConst.ELIMINATION_TOUCH_EVENT +local BUFF_NAME_TO_ATTR = BattleConst.BUFF_NAME_TO_ATTR +local GRID_BREAK_CONDITION = BattleConst.GRID_BREAK_CONDITION + +function BattleBaseController:getBoardConfig() + return {} +end + +function BattleBaseController:getChapterConfig() + return {} +end + +function BattleBaseController:getChapterId() + return 0 +end + +function BattleBaseController:getBuffs() + return {} +end + +function BattleBaseController:getBattleUIPath() + return "app/ui/battle/battle_ui" +end + +---- 障碍格子图片 +function BattleBaseController:getBlockIcon() + local chapterInfo = self:getChapterConfig()[self.chapterId] + if not chapterInfo then + return "battle_hinder_4" + end + return chapterInfo.block_icon +end + +function BattleBaseController:getChessBoardBgName() + local chapterInfo = self:getChapterConfig()[self.chapterId] + if not chapterInfo then + return "chessboard_1" + end + return chapterInfo.chess_board +end + +function BattleBaseController:refreshWave() + if not self.battleUI then + return + end + self.battleUI:refreshWave(self.waveIndex) +end + +-- 战斗结束 +function BattleBaseController:controllBattleEnd() +end + +-- 不同模块的战斗需要初始化的东西 +function BattleBaseController:initOther() +end + +-- 怪物攻击力加成 +function BattleBaseController:getMonsterAtkAddition() + return BattleConst.DEFAULT_FACTOR +end + +-- 怪物血量加成 +function BattleBaseController:getMonsterHpAddition() + return BattleConst.DEFAULT_FACTOR +end + +-- 需要额外加载的资源 +function BattleBaseController:loadOtherRes(callback) + return callback() +end + +function BattleBaseController:tick(dt) +end + +-- 一共有多少波 +function BattleBaseController:getMaxWave() + local config = self:getChapterConfig()[self.chapterId] + if not config or not config.monster then + return 0 + end + return #config.monster +end + +function BattleBaseController:getMinEliminationCount() + if not self.minEliminationCount then + self.minEliminationCount = GFunc.getConstIntValue("element_combo") + end + return self.minEliminationCount +end + +function BattleBaseController:generateNextMonster() + local config = self:getChapterConfig()[self.chapterId] + local monsterId = config.monster[self.waveIndex + 1] + if monsterId == nil then + return self:enterNextWave() + end + local isBoss = self.defTeam:getIsBoss() + local unitEntity = self.battleData:addMonster(monsterId, true) + local modelId = unitEntity:getModelId() + BattleHelper:loadBattleHeroModel(modelId, self.battleUI:getBattleNode(), function(spineObject) + self.defTeam:removeAllUnits() + local monsterComp = spineObject:addLuaComponent(GConst.BattleConst.TYPEOF_LUA_COMP.BATTLE_MONSTER_COMPONENT) + monsterComp:initWithEntity(modelId, unitEntity, self) + self.defTeam:addUnit(monsterComp, true) + self:handleBuffs(GConst.BattleConst.SIDE_DEF) + self.battleUI:refreshDefHp(unitEntity:getHp(), unitEntity:getHpPercent()) + local bornTime = monsterComp:getAnimationDuration(GConst.BattleConst.SPINE_ANIMATION_NAME.BORN) + if isBoss then -- 如果是boss就跑过去 + local count = 0 + local function onFinish() + count = count + 1 + if count == 2 then + self.atkTeam:stopRunAction() + self:onRoundEnd(true) + end + end + self.atkTeam:playRunAction() + self.atkTeam:recoverHpOnWaveOver(onFinish) + + isBoss = self.defTeam:getIsBoss() + if isBoss then + local monsterInfo = ConfigManager:getConfig("monster")[monsterId] + self.battleUI:showBossEnterAni(bornTime, ModuleManager.HeroManager:getMonsterName(monsterInfo.monster_base), monsterComp, function() + monsterComp:playEnterBattlefield(true, onFinish) + end) + else + monsterComp:playEnterBattlefield(true, onFinish) + end + else + local count = 0 + local function onFinish() + count = count + 1 + if count == 2 then + self:onRoundEnd(true) + end + end + self.atkTeam:recoverHpOnWaveOver(onFinish) + + isBoss = self.defTeam:getIsBoss() + if isBoss then + local monsterInfo = ConfigManager:getConfig("monster")[monsterId] + self.battleUI:showBossEnterAni(bornTime, ModuleManager.HeroManager:getMonsterName(monsterInfo.monster_base), monsterComp, function() + monsterComp:playEnterBattlefield(false, onFinish) + end) + else + monsterComp:playEnterBattlefield(false, onFinish) + end + end + end) +end + +function BattleBaseController:findNextDefUnit() + self:generateNextMonster() +end + +function BattleBaseController:onDefDead(callback) + self.defTeam:getMainUnit():playDead(function() + local monsterId = self.defTeam:getMainUnit().unitEntity:getDeathSummon() + if monsterId > 0 then + self:generateMonsterById(monsterId, function() + if callback then + callback() + end + self:handleBuffs(BattleConst.SIDE_DEF) + end) + else + if callback then + callback() + end + end + end) +end + +function BattleBaseController:onLinkChange() + self.battleUI:hideAllSfxLine() + self.linkChangeNeedFalsePosMap = table.clearOrCreate(self.linkChangeNeedFalsePosMap) + for posId, entity in pairs(self.battleData:getGridEnties()) do + if entity:getCell() then + self.linkChangeNeedFalsePosMap[posId] = entity:getCell() + end + end + + local sequence = self.battleData:getGridSequence() + local mainElementType + + for index, info in ipairs(sequence) do + local entity = self.battleData:getGridEntity(info.posId) + if not mainElementType then + local skillId = entity:getSkillId() + if not skillId then + mainElementType = entity:getElementType() + break + end + end + end + + local count = #sequence + + for index, info in ipairs(sequence) do + local entity = self.battleData:getGridEntity(info.posId) + if entity:getCell() then + entity:getCell():showHighLight(true, mainElementType, self.battleUI) + end + if self.linkChangeNeedFalsePosMap[info.posId] then + self.linkChangeNeedFalsePosMap[info.posId] = nil + end + if index < count then + local nextPosId = sequence[index + 1].posId + self.battleUI:getSfxLine(index, function(obj) + local curPos = ModuleManager.BattleManager:getPosInfo(info.posId) + local nextPos = ModuleManager.BattleManager:getPosInfo(nextPosId) + local pos, z = ModuleManager.BattleManager:getPosCenterAndDir(curPos, nextPos) + obj:setLocalScale(25, 25, 25) + obj:setLocalPosition(pos.x, pos.y, 0) + obj:setEulerAngles(0, 0, z) + end) + end + if index == count then + if entity:getCell() then + entity:getCell():showAni() + end + end + end + + for posId, cell in pairs(self.linkChangeNeedFalsePosMap) do + cell:showHighLight(false) + end + + for posId, info in pairs(self.battleData:getSkillInfluenceGrids()) do + local entity = self.battleData:getGridEntity(posId) + if info.direction ~= BattleConst.BOARD_RANGE_TYPE.RANDOM then + if entity:getCell() then + entity:getCell():showCircle(true) + end + end + end + + if not self.atkTeam:getMainUnit().unitEntity:getActiveSkillLimit() then + local aniSequence, influenceElementType, lineCount, elementTypeMap, linkElementType = self:calculateCurElimination(true) + self.battleUI:refreshSkill(elementTypeMap, count > 0) + end + + if mainElementType then + self.atkTeam:changeMainUnit(mainElementType) + end +end + +function BattleBaseController:getInitBoard() + if not self.boradList then + self.boradList = {} + self.fixedRandomGrid = {} + self.mysteryBoxIndexMap = {} + + local config = self:getChapterConfig()[self.chapterId] + local boardCfg = self:getBoardConfig() + for _, boardId in ipairs(config.board) do + local cfg = boardCfg[boardId] + if cfg then + table.insert(self.boradList, {board = GFunc.getTable(cfg.board), mysteryBoard = GFunc.getTable(cfg.mystery_box_board)}) + table.insert(self.fixedRandomGrid, GFunc.getTable(cfg.control_element)) + end + end + end + + return self.boradList, self.fixedRandomGrid, self.mysteryBoxIndexMap +end + +function BattleBaseController:getNotInvolvedSkills() + if not self.notInvolvedSkills then + self.notInvolvedSkills = {} + local config = self:getChapterConfig()[self.chapterId] + if config.not_involved_skill then + for _, skillId in ipairs(config.not_involved_skill) do + self.notInvolvedSkills[skillId] = true + end + end + end + + return self.notInvolvedSkills +end + +function BattleBaseController:getFixedRogueSkill() + if not self.fixedRogueSkill then + self.fixedRogueSkill = {} + end + + return self.fixedRogueSkill +end + +function BattleBaseController:getSealElementType() + if not self.sealElementType then + self.sealElementType = {} + local config = self:getChapterConfig()[self.chapterId] + if config.seal_element then + for _, elementType in ipairs(config.seal_element) do + self.sealElementType[elementType] = true + end + end + end + + return self.sealElementType +end + +function BattleBaseController:handleBuffs(side) + for _, buffInfo in ipairs(self:getBuffs()) do + local buffEntity = buffInfo.buffEntity + local buffTargetSide = buffEntity:getTargetSide() + local target + if buffTargetSide == BattleConst.SIDE_DEF then + target = self.defTeam:getMainUnit() + elseif buffTargetSide == BattleConst.SIDE_ATK then + target = self.atkTeam:getMainUnit() + elseif buffTargetSide == BattleConst.SIDE_ATK_ALL then + if not side or side == buffTargetSide then + for matchtype, comp in pairs(self.atkTeam:getUnitComp()) do + local buffEntity = BattleBuffEntity:create() + buffEntity:init(buffInfo.effect, comp.unitEntity) + buffEntity:setTargetSide(buffTargetSide) + comp:takeEffect(buffEntity, comp) + end + end + else + local matchType = BattleConst.SIDE_OBJ_TO_MATCH_TYPE[buffTargetSide] + if matchType then + target = self.atkTeam:getUnitComp()[matchType] + end + end + + if target then + if side then + if buffTargetSide == side then + buffEntity:setOwner(target) + target:takeEffect(buffEntity, target) + end + else + buffEntity:setOwner(target) + target:takeEffect(buffEntity, target) + end + end + end +end + +function BattleBaseController:ctor() + self.battleData = DataManager.BattleData +end + +function BattleBaseController:init(params) + params = params or {} + self.battleType = params.battleType or GConst.BattleConst.BATTLE_TYPE.STAGE + self.waveDurationTime = 0 + self.totalDurationTime = 0 + self.eliminateCount = 0 + self.eliminateTotalCount = 0 + self.maxLinkCount = 0 + self.realTime = 0 + self.taskProgress = {} + self.waveRoundCount = {} + self.lastRoundBreakedGridType = {} + self.waitingFillCount = 0 + self.needWaitingBoardOver = nil + self.curWaveMonsterDead = false + + self.chapterId = self:getChapterId() + self.waveIndex = 0 + self.maxWaveIndex = self:getMaxWave() + self.victory = false + self.roundStep = BattleConst.BATTLE_ROUND_STEP.WAIT_BEGIN + self.effectTexts = {} + self.instructions = {} + self.gotMysteryBoxIndexs = {} + self.showMysteryBoxIndexs = {} + self.delayEffectTextList = {} + self.delayEffectTextCount = 0 + self.time = 0 + self.battleData:init(params) + BattleScheduler:init() + BattlePool:init() + BattleHelper:init() + BattlePassive:init() + self:setTimeScale(self.battleData:getTimeScale()) + self:bindData() + self:initBattleTeam() + self:initOther() + self:prepareFight() +end + +function BattleBaseController:bindData() + self.battleData:bind("timeSpeed", ModuleManager.BattleManager, function() + self:setTimeScale( self.battleData:getTimeScale()) + end, false) +end + +function BattleBaseController:unBindAll() + self.battleData:unBind("timeSpeed", ModuleManager.BattleManager) +end + +function BattleBaseController:initBattleTeam() + self.atkTeam = BattleTeam:create() + self.atkTeam:init(BattleConst.SIDE_ATK, self) + self.defTeam = BattleTeam:create() + self.defTeam:init(BattleConst.SIDE_DEF, self) +end + +function BattleBaseController:setIsPauseHpProgress(value) + self.battleUI:setIsPauseHpProgress(value) +end + +function BattleBaseController:moveBattlefield(time) + self.battleUI:moveBattlefield(time) +end + +function BattleBaseController:refreshBuff(side, buffList) + self.battleUI:refreshBuff(side, buffList) +end + +function BattleBaseController:clearBuff(side) + self.battleUI:clearBuff(side) +end + +function BattleBaseController:showBuffTips(side, autoClose) + if side == BattleConst.SIDE_ATK then + local buffList = self.atkTeam:getBuffList() + if #buffList <= 0 then + return + end + self.battleUI:showLeftBuffTips(buffList, autoClose) + else + local buffList = self.defTeam:getBuffList() + if #buffList <= 0 then + return + end + self.battleUI:showRightBuffTips(buffList, autoClose) + end +end + +function BattleBaseController:showCombo(count) + self.battleUI:showCombo(count) +end + +function BattleBaseController:hideCombo() + self.battleUI:hideCombo() +end + +function BattleBaseController:showCounterAttack(count, side) + self.battleUI:showCounterAttack(count, side) +end + +function BattleBaseController:hideCounterAttack() + self.battleUI:hideCounterAttack() +end + +function BattleBaseController:prepareFight() + local count = 0 + local totalCount = 3 + local function onPreloadFinished() + count = count + 1 + if count == totalCount then + self:onLoadComplete() + end + end + UIManager:closeAllUI() + self.battleUI = UIManager:showUI(self:getBattleUIPath(), {battleControllerPVP = self}) + self.battleUI:addLoadUICompleteListener(function() + BattleHelper:setEffectTextCache(self.battleUI:getBattleNumberRed(), + self.battleUI:getBattleNumberGreen(), + self.battleUI:getBattleNumberBlue(), + self.battleUI:getBattleNumberWhite(), + self.battleUI:getBattleNumberSpecial()) + self:initAtkUnits(onPreloadFinished) + self:initDefUnits(onPreloadFinished) + self.battleUI:refreshChessBoard(self:getChessBoardBgName()) + end) + BattleHelper:setBaseOrder(self.battleUI:getUIOrder()) + self:loadOtherRes(onPreloadFinished) +end + +function BattleBaseController:initAtkUnits(callback) + local atkTeamEntity = self.battleData:getAtkTeam() + local count = 0 + local totalCount = atkTeamEntity:getMembersCount() + local function onloadFinished() + count = count + 1 + if count == totalCount then + self.battleUI:refreshAtkHp(atkTeamEntity:getHp(), atkTeamEntity:getHpPercent()) + callback() + end + end + local members = atkTeamEntity:getAllMembers() + for k, v in pairs(members) do + local modelId = v:getModelId() + BattleHelper:loadBattleHeroModel(modelId, self.battleUI:getBattleNode(), function(spineObject) + local heroComp = spineObject:addLuaComponent(BattleConst.TYPEOF_LUA_COMP.BATTLE_HERO_COMPONENT) + heroComp:initWithEntity(modelId, v, self) + if v:getIsMainUnit() then + self.atkTeam:addUnit(heroComp, true) + else + self.atkTeam:addUnit(heroComp) + heroComp:hideOutsideScreen() + end + onloadFinished() + end) + end + if totalCount == 0 then + callback() + end +end + +function BattleBaseController:initDefUnits(callback) + local config = self:getChapterConfig()[self.chapterId] + self.battleUI:loadBg(config.scene) + local unitEntity = self.battleData:addMonster(config.monster[1]) + local modelId = unitEntity:getModelId() + BattleHelper:loadBattleHeroModel(modelId, self.battleUI:getBattleNode(), function(spineObject) + local monsterComp = spineObject:addLuaComponent(BattleConst.TYPEOF_LUA_COMP.BATTLE_MONSTER_COMPONENT) + monsterComp:initWithEntity(modelId, unitEntity, self) + self.defTeam:addUnit(monsterComp, true) + self.battleUI:refreshDefHp(unitEntity:getHp(), unitEntity:getHpPercent()) + callback() + end) +end + +function BattleBaseController:refreshHp(side, num, percent) + if side == BattleConst.SIDE_ATK then + self.battleUI:refreshAtkHp(num, percent) + else + self.battleUI:refreshDefHp(num, percent) + end +end + +function BattleBaseController:getOtherSideMainUnit(side) + if side == BattleConst.SIDE_ATK then + return self.defTeam:getMainUnit() + else + return self.atkTeam:getMainUnit() + end +end + +function BattleBaseController:getOtherSideTeam(side) + if side == BattleConst.SIDE_ATK then + return self.defTeam + else + return self.atkTeam + end +end + +function BattleBaseController:onLoadComplete() + UIManager:closeLoading() + self:handleBuffs() + self:battleStart() +end + +function BattleBaseController:battleStart() + self.atkTeam:prepare() + self.defTeam:prepare() + self.isBattleStart = true + self.tickSid = BattleScheduler:scheduleGlobal(function(dt, originDt) + self:_tick(dt, originDt) + end, 0) + self:enterNextWave() +end + +function BattleBaseController:addTimeSpeed() + if self.skillSlowDownDuration then + return + end + self.battleData:addTimeSpeed() +end + +function BattleBaseController:resetTimeSpeed(isDeadReset) + if isDeadReset then + if self.skillSlowDownDuration then + return + end + end + + self.battleData:resetTimeSpeed() + if self.skillSlowDownDuration then + self.skillSlowDownDuration = nil + end +end + +function BattleBaseController:setSkillSlowDown(timeScale, duration) + self.skillSlowDownDuration = duration + self.battleData:setSkillTimeSpeed(timeScale) +end + +function BattleBaseController:setTimeScale(timeScale) + GFunc.setDOTweenTimeScale(GConst.DOTWEEN_IDS.BATTLE, timeScale) + BattleScheduler:setTimeScale(timeScale) + BattleHelper:setTimeScale(timeScale) +end + +function BattleBaseController:_findNextDefUnit() + if self.isBossWave then -- 如果上一波是boss波次,则重新生成棋盘 + self:putBoardCacheSkill(function() + self.atkTeam:onRoundEnd() + self:findNextDefUnit() + self:generateBoard() + end) + else + self.atkTeam:onRoundEnd() + self:findNextDefUnit() + end +end + +---- start 回合步骤 +function BattleBaseController:enterNextWave() + if self.waveIndex ~= 0 and self.curWaveMonsterDead then + if self.isBossWave then + self:addTaskProgress(BattleConst.BATTLE_TASK_FIELD.KILL_BOSS, 1) + else + self:addTaskProgress(BattleConst.BATTLE_TASK_FIELD.KILL_NORMAL_MONSTER, 1) + end + self:setTaskProgress(BattleConst.BATTLE_TASK_FIELD.PASS_WAVE, self.waveIndex) + end + + if self.waveIndex >= self.maxWaveIndex then + self.victory = self.curWaveMonsterDead + self:postWaveOver(not self.curWaveMonsterDead) + self:battleEnd() + return + end + + local atkTeam = self.battleData:getAtkTeam() + if not atkTeam or atkTeam:getIsDead() then + self.victory = false + self:postWaveOver(true) + self:battleEnd() + return + end + + if self.waveIndex ~= 0 then -- 第一波 + self:postWaveOver(false) + end + + self.curWaveMonsterDead = false + self.waveIndex = self.waveIndex + 1 + self:refreshWave(self.waveIndex) + if self.waveIndex == 1 then -- 第一波 + self.needWaitingBoardOver = true + self:generateBoard(true) + else + -- 上报关卡结束 + self.defTeam:prepare() + end + + self.waveDurationTime = 0 + self.eliminateCount = 0 + + self.isBossWave = self.defTeam:getMainUnit().unitEntity:getIsBoss() + self:postFightStart() + if not self.needWaitingBoardOver then + self:enterRoundBegin() + end + if not self.isBossWave then + self.battleUI:hideBuffTips() + end +end + +function BattleBaseController:enterRoundBegin() + self.needWaitingBoardOver = nil + self.waveRoundCount[self.waveIndex] = (self.waveRoundCount[self.waveIndex] or 0) + 1 + self:takeGridEffect() + self:enterEliminationBegin() + table.clear(self.lastRoundBreakedGridType) +end + +function BattleBaseController:takeGridEffect() + local gridEntities = self.battleData:getGridEnties() + local effectGrid = {} + for posId, entity in pairs(gridEntities) do + if entity:getEffectType() then + table.insert(effectGrid, entity) + end + end + + effectGrid = table.shuffle(effectGrid) + local availableEffectTypeMap + for _, entity in ipairs(effectGrid) do + local effectType = entity:getEffectType() + if effectType ~= BattleConst.GRID_EFFECT_TYPE.CROSS_MOVE_NOT_BREAK and (not availableEffectTypeMap or not availableEffectTypeMap[effectType]) then + local succ = BATTLE_GRID_EFFECT_HANDLE.gridEffectOn(entity:getPosId(), gridEntities, BattleConst.GRID_EFFECT_TRIGGER_TYPE.ON_ROUND_BEGIN, self) + if succ and (effectType == BattleConst.GRID_EFFECT_TYPE.CROSS_SPREAD or + effectType == BattleConst.GRID_EFFECT_TYPE.CROSS_SPREAD_NOT_BREAK) then + if not availableEffectTypeMap then + availableEffectTypeMap = {} + end + availableEffectTypeMap[effectType] = true + end + end + end + + for _, entity in ipairs(effectGrid) do -- gridEffect == 6的最后处理 + local effectType = entity:getEffectType() + if effectType == BattleConst.GRID_EFFECT_TYPE.CROSS_MOVE_NOT_BREAK and (not availableEffectTypeMap or not availableEffectTypeMap[effectType]) then + local succ = BATTLE_GRID_EFFECT_HANDLE.gridEffectOn(entity:getPosId(), gridEntities, BattleConst.GRID_EFFECT_TRIGGER_TYPE.ON_ROUND_BEGIN, self) + if succ then + if not availableEffectTypeMap then + availableEffectTypeMap = {} + end + availableEffectTypeMap[effectType] = true + end + end + end +end + +function BattleBaseController:enterEliminationBegin() + self.roundStep = BattleConst.BATTLE_ROUND_STEP.ON_BEGIN + self:onEliminationBegin() + self:enterRefreshBoard(true) +end + +function BattleBaseController:enterElimination(needDelay) + if self.showSelectSkillSid then + ModuleManager.BattleManager:unscheduleGlobal(self.showSelectSkillSid) + self.showSelectSkillSid = nil + end + + if self.battleData:useAddlvCount() then + self:tryShowSelectSkillComp(needDelay) + return + end + + self.battleUI:hideAllBoardSfxs() + + -- 检查棋盘 + local find, pathList = self:findAttention() + if not find then -- 如果没找到,就要打乱棋盘 + self:shuffleBoard(function() + self.roundStep = BattleConst.BATTLE_ROUND_STEP.ON_ELIMINATION + end) + else + self.attentionList = pathList + -- ModuleManager.BattleManager:performWithDelayGlobal(function() + -- for _, posId in ipairs(pathList) do + -- local entity = self.battleData:getGridEntity(posId) + -- if entity and entity:getCell() then + -- entity:getCell():showAni() + -- end + -- end + -- end, 2) + self.roundStep = BattleConst.BATTLE_ROUND_STEP.ON_ELIMINATION + end +end + +function BattleBaseController:enterBattleStep() + self.roundStep = BattleConst.BATTLE_ROUND_STEP.ON_TEAM_ACTION + if not self.battleTeamActionList then + self.battleTeamActionList = {} + else + for i = #self.battleTeamActionList, 1, -1 do + self.battleTeamActionList[i] = nil + end + end + + local atkAction = function() + self.roundStep = BattleConst.BATTLE_ROUND_STEP.ON_ATK_STEP + self:exeInstructions(function() + self:enterNextTeamAction() + end) + end + + local defAction = function() + self.roundStep = BattleConst.BATTLE_ROUND_STEP.ON_DEF_STEP + self.defTeam:mainUnitUseAllSkills(BattleConst.ATTACK_ACTION_STATE.NORMAL, function() + self:enterNextTeamAction() + end) + end + + if self.battleData:getAtkTeam():getFirstHand() < self.battleData:getDefTeam():getFirstHand() then + self:addTeamActionList(defAction, 1) + self:addTeamActionList(atkAction, 2) + else + self:addTeamActionList(atkAction, 1) + self:addTeamActionList(defAction, 2) + end + + self:enterNextTeamAction() +end + + +function BattleBaseController:addTeamActionList(func, index) + if not self.battleTeamActionList then + self.battleTeamActionList = {} + end + + index = index or 1 + table.insert(self.battleTeamActionList, index, func) +end + +function BattleBaseController:enterNextTeamAction() + self.atkTeam:onActionOver() + self.defTeam:onActionOver() + + self.roundStep = BattleConst.BATTLE_ROUND_STEP.ON_TEAM_ACTION_OVER + self:hideCombo() + self:hideCounterAttack() + + if self:checkTeamIsDead(function() self:enterRoundEnd() end) then + return + end + + if not self.battleTeamActionList or not self.battleTeamActionList[1] then + self:enterRoundEnd() + return + end + + local action = table.remove(self.battleTeamActionList, 1) + action() +end + +function BattleBaseController:checkTeamIsDead(callback) + local defTeam = self.battleData:getDefTeam() + if not defTeam or defTeam:getIsDead() then -- 怪物死了, 直接进入刷新逻辑 + self.curWaveMonsterDead = true + self:onDefDead(function() + self.defTeam:removeAllBuff() + if self.battleData:getDefTeam():getIsDead() then + if self.waveIndex >= self.maxWaveIndex then + if callback() then + callback() + end + else + self:_findNextDefUnit() + end + else + if callback() then + callback() + end + end + end) + return true + end + + local atkTeam = self.battleData:getAtkTeam() + if not atkTeam or atkTeam:getIsDead() then -- 英雄死了, 直接结算 + self:enterNextWave() + return true + end + + return false +end + +function BattleBaseController:getIsAtkStep() + return self.roundStep == BattleConst.BATTLE_ROUND_STEP.ON_ATK_STEP +end + +function BattleBaseController:enterRefreshBoard(isRoundBeginCheck, callback) + if not isRoundBeginCheck then + self.roundStep = BattleConst.BATTLE_ROUND_STEP.ON_REFRESH_BOARD + end + self.onFillBoardOverCallback = callback + self.isRoundBeginCheck = isRoundBeginCheck + if self.isRoundBeginCheck and self.waitingFillCount > 0 then + self.isWaitingFill = true + return + end + + self:fillBoard(self.isRoundBeginCheck) +end + +function BattleBaseController:enterRoundEnd() + self.roundStep = BattleConst.BATTLE_ROUND_STEP.ON_END + local defTeam = self.battleData:getDefTeam() + if not defTeam or defTeam:getIsDead() then -- 怪物死了, 直接进入刷新逻辑 + self.curWaveMonsterDead = true + self.atkTeam:onRoundEnd() + self:enterNextWave() + return + end + + local atkTeam = self.battleData:getAtkTeam() + if not atkTeam or atkTeam:getIsDead() then -- 英雄死了, 直接结算 + self.defTeam:onRoundEnd() + self:enterNextWave() + return + end + + self.atkTeam:onRoundEnd() + self.defTeam:onRoundEnd() + + if self:checkTeamIsDead(function() self:enterNextWave() end) then + return + end + + self:onRoundEnd() +end + +function BattleBaseController:onRoundEnd(toNextWave) + if toNextWave then + self:enterNextWave() + else + self:enterRoundBegin() + end +end + +---- end回合步骤 +function BattleBaseController:onTouchEvent(eventType, posId, isVirtual) + if self.roundStep ~= BattleConst.BATTLE_ROUND_STEP.ON_ELIMINATION then + return + end + local entity = self.battleData:getGridEntity(posId) + if not entity or not entity:canLink() then + return + end + + if eventType == ELIMINATION_TOUCH_EVENT.DOWN then + self:onLinkStart(entity, posId, isVirtual) + elseif eventType == ELIMINATION_TOUCH_EVENT.ENTER then + if self.battleData:getIsVirtual() and not isVirtual then + return + end + + self:onLinkEnter(entity, posId, isVirtual) + elseif eventType == ELIMINATION_TOUCH_EVENT.EXIT then + + else -- 取消和抬起 + self:onLinkCancelOrUp(entity, posId, isVirtual) + end +end + +function BattleBaseController:onLinkStart(entity, posId, isVirtual) + if DataManager.TutorialData:getIsInTutorial() then + local elementList = DataManager.TutorialData:getTargetElement() + if elementList then + local find = false + for _, curPosId in ipairs(elementList) do + if curPosId == posId then + find = true + break + end + end + if not find then + return + end + end + end + + if not isVirtual then + self.battleUI:showTutorialFinger() + end + if #self.battleData:getGridSequence() > 0 then + self:clearGridSequence() + end + self.battleData:insertGridSequence(posId, self:snapshotBoard(), isVirtual) + local skillEntity = self.battleData:getSkillEntityBySkillId(entity:getSkillId()) + local maskElementType = entity:getElementType(skillEntity) + self.battleUI:showBoardMask(maskElementType, skillEntity and entity:getPosId()) + self:findSkillInfluenceGrids() + self:onLinkChange() + + if not isVirtual then + AudioManager:playEffect(AudioManager.EFFECT_ID.LINK_BO_1) + if skillEntity then + AudioManager:playEffect(AudioManager.EFFECT_ID.LINK_SKILL) + end + end +end + +function BattleBaseController:onLinkEnter(entity, posId, isVirtual) + local sequence = self.battleData:getGridSequence() + local sequenceCount = #sequence + local info = sequence[sequenceCount] + local lastPosId = info and info.posId + if not lastPosId then + return + end + local outLineMap = BattleConst.GRID_OUT_LINE_POS_ID[lastPosId] + if not outLineMap or not outLineMap[posId] then + return + end + + if self.battleData:alreadyInsertSequence(posId) then + local info = sequence[#sequence - 1] + local beforePosId = info and info.posId + if beforePosId == posId then -- 进入的是倒数第二个,则移除倒数第一个 + local snapshot = self.battleData:removeGridSequence(lastPosId) + if snapshot then -- 如果有快照,则恢复一次 + for posId, info in pairs(snapshot) do + self.battleData:setInfoBySnapshop(posId, info) + end + end + + local lastEntity = self.battleData:getGridEntity(beforePosId) + local lastSkillEntity = self.battleData:getSkillEntityBySkillId(lastEntity:getSkillId()) + local maskElementType = lastEntity:getElementType(lastSkillEntity) + + local _, skillPosId = self.battleData:getSequenceHadSkill() + self.battleUI:showBoardMask(maskElementType, skillPosId) + + self:findSkillInfluenceGrids() + self:onLinkChange() + end + return + end + + local skillId = entity:getSkillId() + local skillEntity = self.battleData:getSkillEntityBySkillId(skillId) + local elementType = entity:getElementType(skillEntity) + + local lastEntity = self.battleData:getGridEntity(lastPosId) + local lastSkillId = lastEntity:getSkillId() + local lastSkillEntity = self.battleData:getSkillEntityBySkillId(lastSkillId) + local lastElementType = lastEntity:getElementType(lastSkillEntity) + + local hadSkillId, skillPosId = self.battleData:getSequenceHadSkill() + if skillEntity and hadSkillId then + return + end + + if not elementType or not lastElementType then + else + if lastElementType ~= elementType then + return + end + end + + local maskElementType = elementType or lastElementType + if not skillPosId then + if skillId then + skillPosId = posId + end + end + self.battleUI:showBoardMask(maskElementType, skillPosId) + + self.battleData:insertGridSequence(posId, self:snapshotBoard(), isVirtual) + if lastEntity:getNeedChangePos() and not entity:getNeedChangePos() then -- 需要移动到队列末尾 + local lastSkillId = lastEntity:getSkillId() + local skillId = entity:getSkillId() + self:setGridSkillId(lastPosId, skillId) + self:setGridSkillId(posId, lastSkillId) + end + + local newElementType = elementType or lastElementType + if newElementType then + entity:setElementType(newElementType) + lastEntity:setElementType(newElementType) + end + + entity:addLinkSkillCount() + + self:findSkillInfluenceGrids() + self:onLinkChange() + + if not isVirtual then + if sequenceCount + 1 == self:getMinEliminationCount() then + AudioManager:playEffect(AudioManager.EFFECT_ID.LINK_READY) + end + AudioManager:playEffect(AudioManager:getBoEffectID(sequenceCount + 1)) + if skillEntity then + AudioManager:playEffect(AudioManager.EFFECT_ID.LINK_SKILL) + end + end +end + + +function BattleBaseController:onLinkCancelOrUp(entity, posId, isVirtual) + if isVirtual then + return + end + + local tutorialElementList + if DataManager.TutorialData:getIsInTutorial() then + tutorialElementList = DataManager.TutorialData:getTargetElement() + end + + self.battleUI:showBoardMask(nil) + local sequence = self.battleData:getGridSequence() + local count = #sequence + if count < self:getMinEliminationCount() then + self:clearGridSequence() + + AudioManager:playEffect(AudioManager.EFFECT_ID.LINK_CANCEL) + if tutorialElementList then + self.battleUI:showTutorialFinger(tutorialElementList) + end + return + end + + AudioManager:playEffect(AudioManager.EFFECT_ID.LINK_OVER) + + if tutorialElementList then + local posIdmap = {} + for _, info in ipairs(sequence) do + posIdmap[info.posId] = true + end + EventManager:dispatchEvent(EventManager.CUSTOM_EVENT.ELIMINATION_OVER, posIdmap) + else + self:onLinkOver() + end +end + +function BattleBaseController:clearGridSequence() + local sequence = self.battleData:getGridSequence() + local count = #sequence + if count <= 0 then + self.battleData:clearGridSequence() + self:onLinkChange() + return + end + + local snapshot = self.battleData:getFirstSequenceSnapshot() + if snapshot then -- 如果有快照,则恢复一次 + for posId, info in pairs(snapshot) do + self.battleData:setInfoBySnapshop(posId, info) + end + end + + self.battleData:clearGridSequence() + self:onLinkChange() +end + +function BattleBaseController:onLinkOver() + self.battleUI:hideAllSfxLine() + local sequence = self.battleData:getGridSequence() + local count = #sequence + if count < self:getMinEliminationCount() then + return + end + + local skillId = self.battleData:getSequenceHadSkill() + local skillEntity + if skillId then + skillEntity = self.battleData:getSkillEntityBySkillId(skillId) + self:addTaskProgress(BattleConst.BATTLE_TASK_FIELD.BOARD_SKILL_RELEASE_COUNT, 1) + end + + local aniSequence, influenceElementTypeMap, lineCount, elementTypeMap, linkElementType, effectGridMap = self:calculateCurElimination() + + if not self.atkTeam:getMainUnit().unitEntity:getActiveSkillLimit() then + self.battleData:addSkillEnergy(elementTypeMap) + end + self.battleData:clearGridSequence() + self.battleUI:disableUITouch() + self.battleUI:eliminationAni(aniSequence, effectGridMap, function() + self:enterRefreshBoard(nil, function() + self:generateInstructions(skillEntity, linkElementType, lineCount, influenceElementTypeMap, elementTypeMap) + end) + end) + + self.eliminateCount = self.eliminateCount + 1 + self.eliminateTotalCount = self.eliminateTotalCount + 1 + if count > self.maxLinkCount then + self.maxLinkCount = count + end +end + +function BattleBaseController:calculateCurElimination(onlyCheck) + local sequence = self.battleData:getGridSequence() + local skillId = self.battleData:getSequenceHadSkill() + local skillEntity + if skillId then + skillEntity = self.battleData:getSkillEntityBySkillId(skillId) + end + self.breakedMap = table.clearOrCreate(self.breakedMap) + self.boomGridIds = table.clearOrCreate(self.boomGridIds) + self.sequenceMap = table.clearOrCreate(self.sequenceMap) + self.aniSequence = table.clearOrCreate(self.aniSequence) + for idx, info in ipairs(sequence) do + self.sequenceMap[info.posId] = idx + end + + local time = 0 + local skillTime = BattleConst.SKILL_ELIMINATION_TIME + for idx, info in ipairs(sequence) do + local posId = info.posId + self:dealGridBreak(posId, GRID_BREAK_CONDITION.LINE, time, self.breakedMap, self.sequenceMap, self.aniSequence, self.boomGridIds, onlyCheck) + time = time + BattleConst.ELIMINATION_INTERVAL + end + + local randomPosList, influenceElementTypeMap + for i, info in ipairs(self.aniSequence) do + if info.isSkill and skillEntity then + randomPosList, influenceElementTypeMap = self:dealSkillElement(info.timeIdx + skillTime, self.breakedMap, self.sequenceMap, self.aniSequence, self.boomGridIds, onlyCheck) + local aniUnit = self.aniSequence[i] + if not BattleConst.NO_EFFECT_GRID_SKILL_TYPE[skillEntity:getSkillType()] then + aniUnit.rangeList = skillEntity:getBoardRange() + aniUnit.randomPosList = randomPosList + end + break + end + end + + self.elementTypeMap = table.clearOrCreate(self.elementTypeMap) + self.effectGridMap = table.clearOrCreate(self.effectGridMap) + local linkElementType + local lineCount = 0 + local gridEntities = self.battleData:getGridEnties() + for _, info in ipairs(self.aniSequence) do + local entity = gridEntities[info.posId] + local elementType = entity:getElementType() + if not info.noAni and info.isIdle then + if not info.isSkill then + if not entity:isElmentTypeInvalid() then + self.elementTypeMap[elementType] = (self.elementTypeMap[elementType] or 0) + 1 + end + if self.boomGridIds[info.posId] and self.boomGridIds[info.posId][GRID_BREAK_CONDITION.LINE] then + lineCount = lineCount + 1 + linkElementType = elementType + end + end + end + if entity:getEffectType() and info.isIdle then + self.effectGridMap[info.posId] = true + end + end + + return self.aniSequence, influenceElementTypeMap, lineCount, self.elementTypeMap, linkElementType, self.effectGridMap +end + +function BattleBaseController:dealGridBreak(posId, condition, time, breakedMap, sequenceMap, aniSequence, gridMap, onlyCheck) + self:setGridBreakCondition(gridMap, posId, condition) + if breakedMap[posId] or (sequenceMap[posId] and condition ~= GRID_BREAK_CONDITION.LINE) then + return + end + + local gridEntities = self.battleData:getGridEnties() + local entity = gridEntities[posId] + local breaked, isIdle = entity:tryBreakGrid(condition, true) + local aniUnit = self:getEliminattionAniInfo(posId, time) + aniUnit.noAni = entity:isElmentTypeInvalid() + aniUnit.isIdle = isIdle + if entity:getSkillId() then + aniUnit.isSkill = true + end + + if breaked or entity:canBreakByThisCondition(condition) then + breakedMap[posId] = true + + aniUnit.breakSfxName = entity:getBreakSfx() + aniUnit.callback = function() + self.lastRoundBreakedGridType[entity:getGridType()] = true + entity:tryBreakGrid(condition) + end + + table.insert(aniSequence, aniUnit) + end + + if isIdle then + if condition == GRID_BREAK_CONDITION.LINE then + local outline = BattleConst.UP_DOWN_LEFT_RIGHT[posId] + for _, id in ipairs(outline) do + self:dealGridBreak(id, GRID_BREAK_CONDITION.AROUND, time, breakedMap, sequenceMap, aniSequence, gridMap, onlyCheck) + end + end + if entity:getEffectType() then + local succ, list = BATTLE_GRID_EFFECT_HANDLE.gridEffectOn(posId, gridEntities, BattleConst.GRID_EFFECT_TRIGGER_TYPE.ON_GRID_BREAK, self, onlyCheck) + if list then + aniUnit.aniPosList = table.clearOrCreate(aniUnit.aniPosList) + aniUnit.overCallback = aniUnit.callback + aniUnit.callback = nil + for index, id in ipairs(list) do + if id ~= posId then + local timeIdx = time + BattleConst.GRID_BREAK_EFFECT_INTERVAL * (index - 1) -- 因为第一个是自己,所以-1 + self:dealGridBreak(id, GRID_BREAK_CONDITION.SKILL, timeIdx, breakedMap, sequenceMap, aniSequence, gridMap, onlyCheck) + table.insert(aniUnit.aniPosList, id) + end + end + + ---- 技能效果特效 + aniUnit.effectSfxName = entity:getEffectSfx() + aniUnit.effectSfxFlow = entity:getEffectSfxFlow() + aniUnit.effectSfxDir = entity:getEffectParams()[1] + end + end + aniUnit.bftcTime = entity:getBftcTime() + if entity:getBreakFlyToCharacter() then + aniUnit.breakFlyToCharacter = true + aniUnit.noAni = false + aniUnit.overCallback = aniUnit.callback + aniUnit.callback = nil + if entity:getBreakFlyToCharacterIcon() then + aniUnit.callback = function() + local cell = entity:getCell() + if not cell then + return + end + cell:setGridTypeIcon(entity:getBreakFlyToCharacterIcon()) + end + end + end + end + + return isIdle +end + +function BattleBaseController:dealSkillElement(time, breakedMap, sequenceMap, aniSequence, boomGridIds, onlyCheck) + local randomPosList + local influenceElementTypeMap = {} + for posId, info in pairs(self.battleData:getSkillInfluenceGrids()) do + local entity = self.battleData:getGridEntity(posId) + if not entity:getIsIdle() then + if entity:isEmptyIdle() then + if info.direction == BattleConst.BOARD_RANGE_TYPE.RANDOM then + if not randomPosList then + randomPosList = {} + end + table.insert(randomPosList, posId) + end + influenceElementTypeMap[entity:getElementType()] = (influenceElementTypeMap[entity:getElementType()] or 0) + 1 + end + self:dealGridBreak(posId, GRID_BREAK_CONDITION.SKILL, time, breakedMap, sequenceMap, aniSequence, boomGridIds, onlyCheck) + end + end + + return randomPosList, influenceElementTypeMap +end + +function BattleBaseController:getEliminattionAniInfo(posId, timeIdx) + return { + posId = posId, + noAni = nil, + aniPosList = nil, + breakSfxName = nil, + timeIdx = timeIdx, + conditions = nil, + isSkill = false, + isIdle = false, + callback = nil, + overCallback = nil, + bftcTime = 0, + effectSfxName = nil, + effectSfxFlow = nil, + effectSfxDir = nil, + } +end + +function BattleBaseController:setGridBreakCondition(gridMap, posId, condition) + if not gridMap[posId] then + gridMap[posId] = {} + gridMap[posId][condition] = true + end + gridMap[posId][condition] = true +end + +function BattleBaseController:tryShowSelectSkillComp(needDelay, onlyCommonSkill) + local skillList = self:getRandomSkillList(nil, onlyCommonSkill) + if needDelay then + self.showSelectSkillSid = ModuleManager.BattleManager:performWithDelayGlobal(function() + self.battleUI:showSelectSkillComp(skillList, onlyCommonSkill) + self.showSelectSkillSid = nil + end, 0.3) + else + self.battleUI:showSelectSkillComp(skillList, onlyCommonSkill) + end + + BIReport:postShowFightSkillSelect(self.battleType, skillList, self.chapterId, self.totalDurationTime, self.waveIndex) +end + + +function BattleBaseController:fillBoard(isRoundBeginCheck) + self.fillBoardPathMap = table.clearOrCreate(self.fillBoardPathMap) + self.fillColumnCount = table.clearOrCreate(self.fillColumnCount) + self.fillGridMap = table.clearOrCreate(self.fillGridMap) + for c = 1, BattleConst.COLUMN_COUNT do + for r = BattleConst.ROW_COUNT, 1, -1 do + local posId = ModuleManager.BattleManager:getPosId(r, c) + local entity = self.battleData:getGridEntity(posId) + if entity:getIsIdle() then + self:fillThisPos(posId, self.fillColumnCount, self.fillGridMap) + end + end + end + + while true do + local find = false + for c = 1, BattleConst.COLUMN_COUNT do + local list = self.fillGridMap[c] + if list and list[1] then -- 此列有需要填充的元素 + local entity = table.remove(list, 1) + if entity then + self.battleData:setGridInfo(entity:getPosId(), self:getRandomGridInfo()) + end + find = true + end + end + + if not find then + break + end + end + + for c = 1, BattleConst.COLUMN_COUNT do + for r = BattleConst.ROW_COUNT, 1, -1 do + local posId = ModuleManager.BattleManager:getPosId(r, c) + local entity = self.battleData:getGridEntity(posId) + if #entity:getPath() > 0 then + self.fillBoardPathMap[posId] = entity:getPath() + entity:clearPath() + end + end + end + + self.battleUI:fallGrid(self.fillBoardPathMap, isRoundBeginCheck, function() + self:onFillBoardOver(isRoundBeginCheck) + self.isRoundBeginCheck = nil + self.isWaitingFill = false + end) +end + +function BattleBaseController:onFillBoardOver(isRoundBeginCheck) + self.battleUI:enableUITouch() + + if not isRoundBeginCheck then -- 检查一些表现 + if self.showMysteryBoxIndexs[1] then -- 检查宝箱 + local index = table.remove(self.showMysteryBoxIndexs, 1) + local boardList, _, mysteryBoxIndexMap = self:getInitBoard() + local rewards = mysteryBoxIndexMap[index] + ModuleManager.BattleManager:showBoxOpenUI(rewards, function() + self:onFillBoardOver() + end) + return + end + + if self.battleData:useCommonSelectSkillCount() then -- 检查神灯 + self:tryShowSelectSkillComp(false, true) + return + end + end + + if self.onFillBoardOverCallback then + self.onFillBoardOverCallback() + end + + if isRoundBeginCheck then + EventManager:dispatchEvent(EventManager.CUSTOM_EVENT.BOARD_FILL_OVER) + self:popBoardCacheSkill(function() + self:generateSkill(function() + self:enterElimination(true) + end) + end) + else + self:generateSkill(function() + self.battleUI:refreshSkill() + self:enterBattleStep() + end) + end +end + +function BattleBaseController:generateInstructions(skillEntity, elementType, lineCount, influenceElementTypeMap, elementTypeMap) + self.instructions = BATTLE_INSTRUCTIONS_HELPER.generateInstructions(skillEntity, elementType, lineCount, influenceElementTypeMap, elementTypeMap, self) +end + + +function BattleBaseController:exeInstructions(callback) + if not self.instructions or #self.instructions <= 0 then + callback() + return + end + local instruction = table.remove(self.instructions) + local func = BattleBaseController._doInstruction[instruction.name] + if func then + func(self, instruction, function() + self.battleData:resetTimeSpeed() + self:exeInstructions(callback) + end) + else + self:exeInstructions(callback) + end +end + +function BattleBaseController:getIsLastInstruction() + if not self.instructions or not self.instructions[1] then + return true + end + + return false +end + +function BattleBaseController:generateBoard(isFirst) + local boardList, _, mysteryBoxIndexMap = self:getInitBoard() + if self.curBoardIndex and self.curBoardIndex >= #boardList then + if isFirst then + self.needWaitingBoardOver = false + end + return + end + + if not self.battleUI then + if isFirst then + self.needWaitingBoardOver = false + end + return + end + + self.curBoardIndex = (self.curBoardIndex or 0) + 1 + if not boardList[self.curBoardIndex] then -- 容错 + if isFirst then + self.needWaitingBoardOver = false + end + return + end + local board = boardList[self.curBoardIndex].board + local mysteryBoard = boardList[self.curBoardIndex].mysteryBoard + if mysteryBoard and mysteryBoxIndexMap and mysteryBoxIndexMap[self.curBoardIndex] then + board = mysteryBoard + end + self.battleUI:switchBoard(function() + self.battleData:refreshBoard(board, self:getBlockIcon()) + self.battleUI:initGridCell(function() + if isFirst then + self.needWaitingBoardOver = false + end + end) + end, function() + end, isFirst) +end + +function BattleBaseController:onGotMysteryBoxIndexs() + self.gotMysteryBoxIndexs[self.curBoardIndex] = true + table.insert(self.showMysteryBoxIndexs, self.curBoardIndex) +end + + +function BattleBaseController:putBoardCacheSkill(callback) + if not self.battleUI then + return + end + self.battleData:cacheBoardSkill() + local skillList, skillCount = self.battleData:getCacheBoardSkill() + self.battleUI:cacheSkillAni(skillList, false, callback) +end + +function BattleBaseController:popBoardCacheSkill(callback) + local skillList, skillCount = self.battleData:getCacheBoardSkill() + self.battleData:clearCacheBoardSkill() + if self.battleUI and skillCount > 0 then + self.popSkillPosIdList = table.clearOrCreate(self.popSkillPosIdList) + for posId, entity in pairs(self.battleData:getGridEnties()) do + if entity:isEmptyIdle() and not entity:getIsIdle() then + table.insert(self.popSkillPosIdList, posId) + end + end + + self.popSkillPosIdList = table.shuffle(self.popSkillPosIdList) + self.popNewSkillId = table.clearOrCreate(self.popNewSkillId) + for index, info in ipairs(skillList) do + if self.popSkillPosIdList[1] then + self.popNewSkillId[index] = info + self.popNewSkillId[index].posId = table.remove(self.popSkillPosIdList) + self:setGridSkillId(self.popNewSkillId[index].posId, info.skillId, true) + else + break + end + end + + self.battleUI:cacheSkillAni(self.popNewSkillId, true, function() + for index, info in ipairs(self.popNewSkillId) do + self.battleData:setGridDirty(info.posId) + end + + if callback then + callback() + end + end) + else + if callback then + callback() + end + end +end + +function BattleBaseController:generateSkill(callback) + self.generateSkillMap = table.clearOrCreate(self.generateSkillMap) + self.generateExcludeMap = table.clearOrCreate(self.generateExcludeMap) + for _, skillEntity in pairs(self.battleData:getSkillEntities()) do + if skillEntity:getEnergyEnough() then + local list = self:getSkillElementList(skillEntity:getPosition(), 1, true, self.generateExcludeMap) + if list[1] then + self.generateSkillMap[skillEntity:getPosition()] = + { + skillId = skillEntity:getSkillId(), + posId = list[1] + } + self.generateExcludeMap[list[1]] = true + end + end + end + + if not self.battleUI then + if callback then + callback() + end + return + end + + self.battleUI:generateSkillAni(self.generateSkillMap, function() + for elementType, info in pairs(self.generateSkillMap) do + self:setGridSkillId(info.posId, info.skillId) + end + + if callback then + callback() + end + end) +end + +function BattleBaseController:setGridSkillId(posId, skillId, noDirty) + local entity = self.battleData:getGridEntity(posId) + if entity then + entity:setSkilId(skillId, noDirty) + local skillEntity = self.battleData:getSkillEntityBySkillId(skillId) + if skillEntity and entity:getElementType() ~= skillEntity:getPosition() then + entity:setElementType(skillEntity:getPosition(), noDirty) + end + end +end + + +function BattleBaseController:generateGridType(skillTypeParameter, monsterPos) + if not skillTypeParameter then + return + end + + self.generateGridTypeList = table.clearOrCreate(self.generateGridTypeList) + local count = 0 + for posId, entity in pairs(self.battleData:getGridEnties()) do + if entity:isEmptyIdle() then + table.insert(self.generateGridTypeList, entity) + count = count + 1 + end + end + self.generateGridTypeList = table.shuffle(self.generateGridTypeList) + if count > 0 then + self.generateGridTypeMap = table.clearOrCreate(self.generateGridTypeMap) + local minCount = math.min(skillTypeParameter[2], count) + for i = minCount, 1, -1 do + local entity = table.remove(self.generateGridTypeList, math.random(1, i)) + self.generateGridTypeMap[entity:getPosId()] = { + gridType = skillTypeParameter[1], + elementType = entity:getElementType() + } + end + + self.battleUI:showMonsterSkillAni(self.generateGridTypeMap, monsterPos, function() + for posId, info in pairs(self.generateGridTypeMap) do + self.battleData:setGridInfo(posId, info) + end + end) + end +end + + +function BattleBaseController:lockElement(lcokElementType, isUnlock) + if not self.lockElementElementTypeMap then + self.lockElementElementTypeMap = table.clearOrCreate(self.lockElementElementTypeMap) + else + for k, v in pairs(self.lockElementElementTypeMap) do + self.lockElementElementTypeMap[k] = table.clearOrCreate(self.lockElementElementTypeMap[k]) + end + end + if not self.lockElementMap then + self.lockElementMap = table.clearOrCreate(self.lockElementMap) + else + for k, v in pairs(self.lockElementMap) do + self.lockElementMap[k] = table.clearOrCreate(self.lockElementMap[k]) + end + end + self.lockElementList = table.clearOrCreate(self.lockElementList) + local locked = false + for posId, entity in pairs(self.battleData:getGridEnties()) do + local elementType = entity:getElementType() + if not isUnlock then + if entity:isEmptyIdle() then + local elementTypeMapUnit = self.lockElementElementTypeMap[elementType] + if not elementTypeMapUnit or not elementTypeMapUnit[1] then + self.lockElementElementTypeMap[elementType] = table.clearOrCreate(self.lockElementElementTypeMap[elementType]) + elementTypeMapUnit = self.lockElementElementTypeMap[elementType] + if not isUnlock then + table.insert(self.lockElementList, elementType) + end + end + + table.insert(elementTypeMapUnit, posId) + end + if entity:isLock() then + locked = true + end + else + if entity:isLock() then + if not self.lockElementMap[elementType] then + self.lockElementMap[elementType] = table.clearOrCreate(self.lockElementMap[elementType]) + end + table.insert(self.lockElementMap[elementType], posId) + end + end + end + + if isUnlock then + for elementType, list in pairs(self.lockElementMap) do + self.battleData:cacheLockElement(elementType, nil) + for _, posId in ipairs(list) do + self.battleData:setGridType(posId, BattleConst.GRID_TYPE.EMPTY) + end + end + else + if locked then -- 锁定过就不新锁了 + return + end + local elementType = lcokElementType + if elementType == BattleConst.ELEMENT_TYPE.NONE then + if not self.lockElementList[1] then + return + end + elementType = self.lockElementList[math.random(1, #self.lockElementList)] + end + self.battleData:cacheLockElement(elementType, true) + local list = self.lockElementElementTypeMap[elementType] + if list then + for _, posId in ipairs(list) do + self.battleData:setGridType(posId, BattleConst.GRID_TYPE.LOCK) + end + end + end +end + + +function BattleBaseController:getSkillElementList(elementType, count, useAlternate, excludeMap) + self.getSkillElementListResult = table.clearOrCreate(self.getSkillElementListResult) + local gridEntities = self.battleData:getGridEnties() + if not gridEntities then + return self.getSkillElementListResult + end + + self.getSkillElementListSameElementList = table.clearOrCreate(self.getSkillElementListSameElementList) + self.getSkillElementListAlternateList = table.clearOrCreate(self.getSkillElementListAlternateList) + local addCount = 0 + + for row = 1, BattleConst.ROW_COUNT do + for column = 1, BattleConst.COLUMN_COUNT do + local posId = ModuleManager.BattleManager:getPosId(row, column) + local entity = gridEntities[posId] + if entity and entity:canChangeInfo() and not excludeMap[posId] then + if entity:getElementType() == elementType then + table.insert(self.getSkillElementListSameElementList, posId) + else + table.insert(self.getSkillElementListAlternateList, posId) + end + end + end + + local remainCount = count - addCount + if remainCount <= 0 then + return self.getSkillElementListResult + end + + for i = 1, remainCount do + if not self.getSkillElementListSameElementList[i] then + break + end + table.insert(self.getSkillElementListResult, table.remove(self.getSkillElementListSameElementList, math.random(1, #self.getSkillElementListSameElementList))) + addCount = addCount + 1 + if addCount >= count then + return self.getSkillElementListResult + end + end + + if addCount < count and useAlternate then + for i = 1, count - addCount do + if not self.getSkillElementListAlternateList[1] then + break + end + table.insert(self.getSkillElementListResult, table.remove(self.getSkillElementListAlternateList, math.random(1, #self.getSkillElementListAlternateList))) + addCount = addCount + 1 + if addCount >= count then + return self.getSkillElementListResult + end + end + end + + if addCount >= count then + return self.getSkillElementListResult + end + end + + return self.getSkillElementListResult +end + + +---- 从一个点直接遍历所有相关的路径 +function BattleBaseController:fillThisPos(posId, columnCount, gridMap) + local entity = self.battleData:getGridEntity(posId) + if not entity or not entity:getIsIdle() then + return + end + + local list = BattleConst.UP_LINE_FILL_LIST[posId] + if not list[1] then -- 第一排 + local rc = ModuleManager.BattleManager:getPosRC(posId) + local c = rc.c + if not columnCount[c] then + columnCount[c] = 0 + end + columnCount[c] = columnCount[c] + 1 + + local fallPosId = posId + local fallEntity = self.battleData:getGridEntity(fallPosId) + if not fallEntity then -- 异常情况,理论上不可能不存在 + return + end + + local newStartPosId + for i = columnCount[c], 1, -1 do + newStartPosId = ModuleManager.BattleManager:getFirstLineLastRowPosId(i, c) + local curPos = ModuleManager.BattleManager:getPosInfo(newStartPosId) + fallEntity:addPath({x = curPos.x, y = curPos.y}) + end + + local curPos = ModuleManager.BattleManager:getPosInfo(posId) + fallEntity:addPath({x = curPos.x, y = curPos.y}) + + self.battleData:exchangeGridEntities(posId, fallPosId) + if not gridMap[c] then + gridMap[c] = {} + end + table.insert(gridMap[c], fallEntity) + else + for index, fallPosId in ipairs(list) do + local fallEntity = self.battleData:getGridEntity(fallPosId) + if not fallEntity then -- 异常情况,理论上不可能不存在 + return + end + if not fallEntity:isCantFallType() then + if fallEntity:getIsIdle() then + self:fillThisPos(fallPosId, columnCount, gridMap) + end + fallEntity = self.battleData:getGridEntity(fallPosId) + if not fallEntity:getIsIdle() then + if not fallEntity:getPath()[1] then + local curPos = ModuleManager.BattleManager:getPosInfo(fallPosId) + fallEntity:addPath({x = curPos.x, y = curPos.y}) + end + + local curPos = ModuleManager.BattleManager:getPosInfo(posId) + fallEntity:addPath({x = curPos.x, y = curPos.y}) + + self.battleData:exchangeGridEntities(posId, fallPosId) + self:fillThisPos(fallPosId, columnCount, gridMap) + return + end + end + end + end +end + + +function BattleBaseController:getRandomGridInfo() + local list, fixedRandomGrid = self:getInitBoard() + local fixedRandomList = fixedRandomGrid[self.curBoardIndex] + + local gridType = 0 + local elementType + if fixedRandomList and fixedRandomList[1] then + elementType = table.remove(fixedRandomList, 1) + else + local map = self.battleData:getElementTypeMap() + self.getRandomGridInfoIndexs = table.clearOrCreate(self.getRandomGridInfoIndexs) + self.getRandomGridInfoTypeList = table.clearOrCreate(self.getRandomGridInfoTypeList) + for typeName, typeNum in pairs(BattleConst.ELEMENT_TYPE) do + if not self:getSealElementType()[typeNum] and self.battleData:getSkillEntityByElement(typeNum) then + local weight = ((map[typeNum] or 0) + 1) * BattleConst.ELEMENT_WIGHT + if weight > BattleConst.MAX_ELEMENT_WIGHT then + weight = BattleConst.MAX_ELEMENT_WIGHT + end + table.insert(self.getRandomGridInfoIndexs, weight) + table.insert(self.getRandomGridInfoTypeList, typeNum) + end + end + + local index = GFunc.getRandomIndex(self.getRandomGridInfoIndexs) + elementType = self.getRandomGridInfoTypeList[index] + end + + return {gridType = gridType, elementType = elementType} +end + + +function BattleBaseController:findSkillInfluenceGrids() + local girds = self.battleData:clearSkillInfluenceGrids() + for posId, _ in pairs(girds) do + local entity = self.battleData:getGridEntity(posId) + if entity:getCell() then + entity:getCell():showCircle(false) + end + end + + local sequence = self.battleData:getGridSequence() + self.skillInfluenceGridsSequenceEntities = table.clearOrCreate(self.skillInfluenceGridsSequenceEntities) + for _, info in ipairs(sequence) do + local entity = self.battleData:getGridEntity(info.posId) + table.insert(self.skillInfluenceGridsSequenceEntities, entity) + end + + for _, info in ipairs(sequence) do + local entity = self.battleData:getGridEntity(info.posId) + local skillId = entity:getSkillId() + if skillId then + local skillEntity = self.battleData:getSkillEntityBySkillId(skillId) + if skillEntity then + BATTLE_BOARD_SKILL_HANDLE.activeBoardSkill(info.posId, skillEntity, self.battleData:getGridEnties(), self.skillInfluenceGridsSequenceEntities, self) + end + end + end +end + +function BattleBaseController:getRandomSkillList(getCount, onlyCommonSkill, excludeMap) + local fixedList = self:getFixedRogueSkill() + if fixedList[1] then + return table.remove(fixedList, 1) + end + + getCount = getCount or BattleConst.SKILL_SELECT_COUNT + self.randomSkillList = table.clearOrCreate(self.randomSkillList) + self.randomSkillMap = table.clearOrCreate(self.randomSkillMap) + self.randomSkillNewSkillPool = table.clearOrCreate(self.randomSkillNewSkillPool) + self.randomSkillSkillWeight = table.clearOrCreate(self.randomSkillSkillWeight) + local cfg = ConfigManager:getConfig("skill_rogue") + local skillPool = self.battleData:getSkillPool() + local count = 0 + + if not onlyCommonSkill then + for elementType, list in pairs(skillPool) do -- 先遍历一下未解锁的技能 + if not self.battleData:isUnlockedSkillElementType(elementType) then + local skillEntity = self.battleData:getSkillEntityByElement(elementType) + if skillEntity then + local skillId = skillEntity:getUnlockId() + if skillId and not self.randomSkillMap[skillId] then + local skillCfg = cfg[skillId] + table.insert(self.randomSkillNewSkillPool, skillId) + table.insert(self.randomSkillSkillWeight, skillCfg.weight) + count = count + 1 + self.randomSkillMap[skillId] = true + end + end + end + end + + if count >= 3 then -- 如果未解锁的技能大于等于3,则直接返回三个解锁技能 + for i = 1, 3 do + local index = GFunc.getRandomIndex(self.randomSkillSkillWeight) + local skillId = table.remove(self.randomSkillNewSkillPool, index) + table.remove(self.randomSkillSkillWeight, index) + count = count - 1 + table.insert(self.randomSkillList, skillId) + end + + return table.shuffle(self.randomSkillList) + end + + if excludeMap then + for skillId, _ in pairs(excludeMap) do + self.randomSkillMap[skillId] = true + end + end + + for elementType, list in pairs(skillPool) do + if self.battleData:isUnlockedSkillElementType(elementType) then + for _, skillId in ipairs(list) do + local skillCfg = cfg[skillId] + if skillCfg and (not skillCfg.limit_times or self.battleData:getSkillCount(skillId) < skillCfg.limit_times) then + + if not self.randomSkillMap[skillId] and (not skillCfg.unlock or self.battleData:getSkillCount(skillCfg.unlock) > 0) then + table.insert(self.randomSkillNewSkillPool, skillId) + table.insert(self.randomSkillSkillWeight, skillCfg.weight) + count = count + 1 + self.randomSkillMap[skillId] = true + end + end + end + end + end + + if count > 0 then + local index = GFunc.getRandomIndex(self.randomSkillSkillWeight) + local skillId = table.remove(self.randomSkillNewSkillPool, index) + table.remove(self.randomSkillSkillWeight, index) + count = count - 1 + table.insert(self.randomSkillList, skillId) + getCount = getCount - 1 + end + end + + for skillId, info in pairs(cfg) do + if not self:getNotInvolvedSkills()[skillId] then + if info.universal then + if not info.limit_times or self.battleData:getSkillCount(skillId) < info.limit_times then + if not self.randomSkillMap[skillId] then + table.insert(self.randomSkillNewSkillPool, skillId) + table.insert(self.randomSkillSkillWeight, info.weight) + count = count + 1 + end + end + end + end + end + + for i = 1, getCount do + local index = GFunc.getRandomIndex(self.randomSkillSkillWeight) + local skillId = table.remove(self.randomSkillNewSkillPool, index) + table.remove(self.randomSkillSkillWeight, index) + count = count - 1 + table.insert(self.randomSkillList, skillId) + if count <= 0 then + break + end + end + + local result = table.shuffle(self.randomSkillList) + return result +end + +function BattleBaseController:onSelectSkill(skillId, value, pos) + self.battleData:addSkillCount(skillId, value) + BATTLE_ROGUE_SKILL_HANDLE.takeEffect(skillId, self.battleData, self, value) + + local skillEntities = self.battleData:getSkillEntities() + for _, entity in pairs(skillEntities) do + entity:gotUpSKill(skillId) + end + + BIReport:postFightSkillSelect(self.battleType, {skillId}, self.chapterId, self.totalDurationTime, self.waveIndex) + + local elementType = ModuleManager.HeroManager:getSkillRoguePosition(skillId) + + if elementType then + if self.battleUI then + self.battleUI:gotOneSkillAni(skillId, elementType, function() + self:selectSKillNextToStep() + self.battleUI:refreshBoard() + self.battleUI:refreshSkill() + end, pos) + return + end + end + + self:selectSKillNextToStep() + + self.battleUI:showCommonSkillTips(skillId) +end + +function BattleBaseController:selectSKillNextToStep() + if self.roundStep == BattleConst.BATTLE_ROUND_STEP.ON_REFRESH_BOARD then + self:onFillBoardOver() + else + self:enterElimination() + end +end + + +function BattleBaseController:changeElementType(count, elementType) + self.changeElementTypeMap = table.clearOrCreate(self.changeElementTypeMap) + self.changeElementTypeList = table.clearOrCreate(self.changeElementTypeList) + local listCount = 0 + for _, entity in pairs(self.battleData:getGridEnties()) do + if entity:canChangeInfo() and entity:getElementType() ~= elementType then + table.insert(self.changeElementTypeList, entity) + listCount = listCount + 1 + end + end + + count = math.min(count, listCount) + for i = 1, count do + if listCount <= 0 then + break + end + local index = math.random(1, listCount) + self.changeElementTypeList[index], self.changeElementTypeList[listCount] = self.changeElementTypeList[listCount], self.changeElementTypeList[index] + local entity = table.remove(self.changeElementTypeList) + listCount = listCount - 1 + self.changeElementTypeMap[entity] = elementType + end + + self:changeElementTypeByMap(self.changeElementTypeMap) +end + +function BattleBaseController:changeElementTypeByMap(changeMap) + local index = 1 + for entity, elementType in pairs(changeMap) do + self.battleData:setGridInfo(entity:getPosId(), {gridType = entity:getGridType(), elementType = elementType}) + self.battleUI:playChangeElementSfx(entity:getPosId(), index) + index = index + 1 + end +end + +function BattleBaseController:killGrids(posIdList) + if not posIdList[1] then + return + end + + for _, posId in ipairs(posIdList) do + local entity = self.battleData:getGridEntity(posId) + entity:setIsIdle(true) + end + + self.battleUI:removeGridOutOfScreen(posIdList) +end + +function BattleBaseController:killRowOrColumn(infoList) + self.killRowOrColumnMap = table.clearOrCreate(self.killRowOrColumnMap) + for _, info in ipairs(infoList) do + if info.posList then + for i, posId in ipairs(info.posList) do + if not self.killRowOrColumnMap[posId] then + self.killRowOrColumnMap[posId] = true + local entity = self.battleData:getGridEntity(posId) + entity:setIsIdle(true) + end + end + self.battleUI:removeGridOutOfScreen(info.posList) + end + end +end + +function BattleBaseController:addHeroAttr(attrName, value) + if not self.battleData or not self.battleData.atkTeam then + return + end + + local attr = BUFF_NAME_TO_ATTR[attrName] + if attr then + self.battleData.atkTeam:addAttr(attr[1], value, attr[2]) + else + local func = BattleBuffHandle.addAttribute[attrName] + if func then + local unitComp + for matchType, comp in pairs(self.atkTeam:getUnitComp()) do + unitComp = comp + break + end + if unitComp then + func(unitComp, value) + end + end + end +end + +---- 快照一次棋盘 +function BattleBaseController:snapshotBoard() + local snapshot = {} + for _, entity in pairs(self.battleData:getGridEnties()) do + snapshot[entity:getPosId()] = entity:getSnapshoptInfo() + end + return snapshot +end + +function BattleBaseController:showAttention() + if not self.attentionList then + return + end + + if self.attentionSid then + ModuleManager.BattleManager:unscheduleGlobal(self.attentionSid) + self.attentionSid = nil + end + + self.attentionSid = ModuleManager.BattleManager:performWithDelayGlobal(function() + for _, posId in ipairs(self.attentionList) do + local entity = self.battleData:getGridEntity(posId) + if entity and entity:getCell() then + entity:getCell():showAni() + end + end + end, 2) +end + + +function BattleBaseController:shuffleBoard(callback) + local changeInfo = self:getShuffleBoardInfo() + if changeInfo then + self.battleData:setGridEntitiesPosId(changeInfo) + self.battleUI:shuffleBoard(changeInfo, callback) + else + self.resetList = table.clearOrCreate(self.resetList) + for posId, entity in pairs(self.battleData:getGridEnties()) do + if entity:isCanFallStatus() then + table.insert(self.resetList, entity) + end + end + local resetInfo = self:resetGrids(self.resetList) + if not resetInfo then + if EDITOR_MODE then + Logger.logHighlight("----- 处于无法消除状态 -----") + end + if callback then + callback() + end + else + if self.resetGridSid then + ModuleManager.BattleManager:unscheduleGlobal(self.resetGridSid) + self.resetGridSid = nil + end + + self.resetGridSid = ModuleManager.BattleManager:performWithDelayGlobal(function() + local count = 1 + for posId, info in pairs(resetInfo) do + self.battleData:setInfoBySnapshop(posId, info) + self.battleUI:playChangeElementSfx(posId, count) + count = count + 1 + end + self.resetGridSid = nil + if callback then + callback() + end + end, 0.5) + end + end +end + +function BattleBaseController:getShuffleBoardInfo() + self.shuffleBoardPosList = table.clearOrCreate(self.shuffleBoardPosList) + self.shuffleBoardAnySkillList = table.clearOrCreate(self.shuffleBoardAnySkillList) + self.shuffleBoardPosMap = table.clearOrCreate(self.shuffleBoardPosMap) + self.shuffleBoardCountMap = table.clearOrCreate(self.shuffleBoardCountMap) + self.shuffleBoardCantLinkMap = table.clearOrCreate(self.shuffleBoardCantLinkMap) + if not self.shuffleBoardList then + self.shuffleBoardList = table.clearOrCreate(self.shuffleBoardList) + else + for elementType, _ in pairs(self.shuffleBoardList) do + self.shuffleBoardList[elementType] = table.clearOrCreate(self.shuffleBoardList[elementType]) + end + end + local anySkillCount = 0 + for posId, entity in pairs(self.battleData:getGridEnties()) do + if entity:isCanFallStatus() then + if entity:getSkillId() then + local skillEntity = self.battleData:getSkillEntityBySkillId(entity:getSkillId()) + local elementType = skillEntity:getPosition() + if skillEntity:getIgnoreElementType() then + table.insert(self.shuffleBoardAnySkillList, entity) + anySkillCount = anySkillCount + 1 + else + if not self.shuffleBoardList[elementType] then + self.shuffleBoardList[elementType] = table.clearOrCreate(self.shuffleBoardList[elementType]) + end + table.insert(self.shuffleBoardList[elementType], entity) + self.shuffleBoardCountMap[elementType] = (self.shuffleBoardCountMap[elementType] or 0) + 1 + end + else + local elementType = entity:getElementType() + if not self.shuffleBoardList[elementType] then + self.shuffleBoardList[elementType] = table.clearOrCreate(self.shuffleBoardList[elementType]) + end + table.insert(self.shuffleBoardList[elementType], entity) + self.shuffleBoardCountMap[elementType] = (self.shuffleBoardCountMap[elementType] or 0) + 1 + if not entity:canLink() then + self.shuffleBoardCantLinkMap[elementType] = (self.shuffleBoardCantLinkMap[elementType] or 0) + 1 + end + end + table.insert(self.shuffleBoardPosList, posId) + self.shuffleBoardPosMap[posId] = true + end + end + + for elementType, list in pairs(self.shuffleBoardList) do + table.sort(self.shuffleBoardList[elementType], function(a, b) + if a:getSkillId() and not b:getSkillId() then + return false + elseif not a:getSkillId() and b:getSkillId() then + return true + else + return a:getPosId() < b:getPosId() + end + end) + end + + + local needCount = self:getMinEliminationCount() + local find = false + for elementType, list in pairs(self.shuffleBoardList) do + local count = self.shuffleBoardCountMap[elementType] or 0 + local cantLinkCount = self.shuffleBoardCantLinkMap[elementType] or 0 + local skillCount = 0 + if anySkillCount > 0 then + skillCount = 1 + end + if count + skillCount - cantLinkCount >= needCount then + local haveSkill = false + local listCount = 0 + self.shuffleBoardTempList = table.clearOrCreate(self.shuffleBoardTempList) + find = false + local add = false + for _, entity in ipairs(list) do + add = false + if haveSkill then + if not entity:getSkillId() then + add = entity:canLink() + end + else + if entity:getSkillId() then + haveSkill = true + end + add = entity:canLink() + end + if add then + table.insert(self.shuffleBoardTempList, entity) + listCount = listCount + 1 + + if listCount >= needCount then -- 可连接的 普通的元素+元素技能 + find = true + break + end + end + end + + if listCount >= needCount then -- 可连接的 普通的元素+元素技能 + find = true + break + elseif not haveSkill and skillCount > 0 then -- 可连接的 普通元素 + 任意元素技能 + table.insert(self.shuffleBoardTempList, self.shuffleBoardAnySkillList[1]) + listCount = listCount + 1 + if listCount >= needCount then + find = true + break + end + end + end + end + + if find then + return self:shufflePos(self.shuffleBoardTempList, self.shuffleBoardPosMap, needCount, self.shuffleBoardPosList) + end +end + +function BattleBaseController:shufflePos(tempList, posMap, needCount, posList) + local gotPos, useMap, list = self:findCanLinkPosList(posMap, needCount) + + if gotPos and list[1] then + self.shufflePosInfo = table.clearOrCreate(self.shufflePosInfo) + self.shufflerPosUsedPos = table.clearOrCreate(self.shufflerPosUsedPos) + self.shufflerSetedPos = table.clearOrCreate(self.shufflerSetedPos) + for index, entity in ipairs(tempList) do + self.shufflePosInfo[entity:getPosId()] = list[index] + self.shufflerPosUsedPos[list[index]] = true + self.shufflerSetedPos[entity:getPosId()] = true + end + + self.shufflePosList1 = table.clearOrCreate(self.shufflePosList1) + self.shufflePosList2 = table.clearOrCreate(self.shufflePosList2) + for index = #posList, 1, -1 do + local posId = posList[index] + if not self.shufflerPosUsedPos[posId] then + table.insert(self.shufflePosList2, posId) + end + if not self.shufflerSetedPos[posId] then + table.insert(self.shufflePosList1, posId) + end + end + + self.shufflePosList2 = table.shuffle(self.shufflePosList2) + for index, posId in ipairs(self.shufflePosList1) do + if not self.shufflePosList2[index] then + break + end + self.shufflePosInfo[posId] = self.shufflePosList2[index] + end + + return self.shufflePosInfo + end +end + +function BattleBaseController:findAttention() + local find = false + for r = 1, GConst.BattleConst.ROW_COUNT do + for c = 1, GConst.BattleConst.COLUMN_COUNT do + local posId = ModuleManager.BattleManager:getPosId(r, c) + local gridEntity = self.battleData:getGridEntity(posId) + local mainElementType = gridEntity:getElementType() + if gridEntity:canChangeInfo() then + self.findAttentionPathList = table.clearOrCreate(self.findAttentionPathList) + self.findAttentionPosIdMap = table.clearOrCreate(self.findAttentionPosIdMap) + self:findLinkLine(posId, self.findAttentionPosIdMap, false, mainElementType, self.findAttentionPathList) + if table.nums(self.findAttentionPathList) >= self:getMinEliminationCount() then + find = true + break + end + end + end + if find then + break + end + end + + return find, self.findAttentionPathList +end + +function BattleBaseController:_dealResetGridsDataFunc(posList) + self.dealResetFunc1PosMap = table.clearOrCreate(self.dealResetFunc1PosMap) + self.dealResetFunc1LockElementMap = table.clearOrCreate(self.dealResetFunc1LockElementMap) + self.dealResetFunc1KeepSnapList = table.clearOrCreate(self.dealResetFunc1KeepSnapList) + self.dealResetFunc1KeepSnapSkillList = table.clearOrCreate(self.dealResetFunc1KeepSnapSkillList) + self.dealResetFunc1EmptySnapList = table.clearOrCreate(self.dealResetFunc1EmptySnapList) + local emptyCount = 0 + for _, entity in ipairs(posList) do + local posId = entity:getPosId() + self.dealResetFunc1PosMap[posId] = entity + if entity:isEmptyIdle() then + emptyCount = emptyCount + 1 + table.insert(self.dealResetFunc1EmptySnapList, entity:getSnapshoptInfo()) + elseif entity:isLock() and not entity:getSkillId() then + self.dealResetFunc1LockElementMap[entity:getElementType()] = true + emptyCount = emptyCount + 1 + local snapInfo = entity:getSnapshoptInfo() + snapInfo.gridType = BattleConst.GRID_TYPE.EMPTY + table.insert(self.dealResetFunc1EmptySnapList, snapInfo) + else + if entity:getSkillId() then + table.insert(self.dealResetFunc1KeepSnapSkillList, entity:getSnapshoptInfo()) + else + table.insert(self.dealResetFunc1KeepSnapList, entity:getSnapshoptInfo()) + end + end + end + + return self.dealResetFunc1PosMap, self.dealResetFunc1LockElementMap, emptyCount, self.dealResetFunc1KeepSnapList, self.dealResetFunc1KeepSnapSkillList, self.dealResetFunc1EmptySnapList +end + + +function BattleBaseController:_dealResetGridsDataFunc2(useMap, emptySnapList, mainElement, backupSkill, keepSnapList, posMap, canRandomElmentList, elementCount, lockElementMap) + self.dealResetFunc2ResetPosInfo = table.clearOrCreate(self.dealResetFunc2ResetPosInfo) + for posId, _ in pairs(useMap) do + local snapInfo + if emptySnapList[1] then + snapInfo = table.remove(emptySnapList) + snapInfo.elementType = mainElement + snapInfo.posId = posId + snapInfo.gridType = BattleConst.GRID_TYPE.EMPTY + else + snapInfo = backupSkill + end + self.dealResetFunc2ResetPosInfo[posId] = snapInfo + end + + for _, snap in ipairs(emptySnapList) do + table.insert(keepSnapList, snap) + end + + keepSnapList = table.shuffle(keepSnapList) + + for posId, entity in pairs(posMap) do + if not useMap[posId] then + local snapInfo + if keepSnapList[1] then + snapInfo = table.remove(keepSnapList) + snapInfo.posId = posId + if not snapInfo.skillId or snapInfo.skillId <= 0 then + if snapInfo.gridType == BattleConst.GRID_TYPE.EMPTY then + snapInfo.elementType = canRandomElmentList[math.random(1, elementCount)] + if lockElementMap[snapInfo.elementType] then + snapInfo.gridType = BattleConst.GRID_TYPE.LOCK + end + end + end + end + + if snapInfo then + self.dealResetFunc2ResetPosInfo[posId] = snapInfo + end + end + end + + return self.dealResetFunc2ResetPosInfo +end + +function BattleBaseController:resetGrids(posList) + local needCount = self:getMinEliminationCount() + if not posList[needCount] then + return + end + + local posMap, lockElementMap, emptyCount, keepSnapList, keepSnapSkillList, emptySnapList = self:_dealResetGridsDataFunc(posList) + + local canUseSkillCount = 0 + if keepSnapSkillList[1] then -- 技能可以直接链接, 不判断元素技能了 + canUseSkillCount = 1 + end + + if emptyCount + canUseSkillCount < needCount then -- 格子不够 + return + end + + local backupSkill + if emptyCount < needCount then + backupSkill = table.remove(keepSnapSkillList) + end + + for _, snap in ipairs(keepSnapSkillList) do + table.insert(keepSnapList, snap) + end + + local gotPos, useMap = self:findCanLinkPosList(posMap, needCount) + if not gotPos then + return + end + + self.canRandomElmentList = table.clearOrCreate(self.canRandomElmentList) + + local elementCount = 0 + for typeName, typeNum in pairs(BattleConst.ELEMENT_TYPE) do + if not lockElementMap[typeNum] and not self:getSealElementType()[typeNum] and self.battleData:getSkillEntityByElement(typeNum) then + table.insert(self.canRandomElmentList, typeNum) + elementCount = elementCount + 1 + end + end + + if elementCount <= 0 then + return + end + + local mainElement = self.canRandomElmentList[math.random(1, elementCount)] + + for typeNum, _ in pairs(lockElementMap) do + table.insert(self.canRandomElmentList, typeNum) + elementCount = elementCount + 1 + end + + local resetPosInfo = self:_dealResetGridsDataFunc2(useMap, emptySnapList, mainElement, backupSkill, keepSnapList, posMap, self.canRandomElmentList, elementCount, lockElementMap) + + return resetPosInfo +end + +function BattleBaseController:findCanLinkPosList(posMap, needCount) + self.findCanLinkList = table.clearOrCreate(self.findCanLinkList) + self.findCanUseMap = table.clearOrCreate(self.findCanUseMap) + local gotPos = false + for posId, _ in pairs(posMap) do + table.clear(self.findCanLinkList) + table.clear(self.findCanUseMap) + local count = 0 + local findPodId = posId + gotPos = false + while true do + local aounrdList = BattleConst.GRID_OUT_LINE_POS_ID[findPodId] + if not aounrdList then + break + end + local got = false + for id, status in pairs(aounrdList) do + if posMap[id] and not self.findCanUseMap[id] then + table.insert(self.findCanLinkList, id) + count = count + 1 + self.findCanUseMap[id] = true + findPodId = id + got = true + break + end + end + if not got then + break + end + if count >= needCount then + gotPos = true + break + end + end + + if gotPos then + break + end + end + + return gotPos, self.findCanUseMap, self.findCanLinkList +end + +function BattleBaseController:findLinkLine(posId, posIdMap, hadSkill, mainElementType, lineList) + posIdMap[posId] = true + table.insert(lineList, posId) + local list = BattleConst.GRID_OUT_LINE_POS_ID[posId] + if not list then + return hadSkill + end + + if #lineList >= self:getMinEliminationCount() then + return hadSkill + end + + local lineCount = 0 + local maxLineList + local maxPosIdMap + local maxGotSkill + for aroundposId, _ in pairs(list) do + if not posIdMap[aroundposId] then + local gridEntity = self.battleData:getGridEntity(aroundposId) + if gridEntity then + if gridEntity:canLink() and not gridEntity:getSkillId() then + if not mainElementType or gridEntity:getElementType() == mainElementType then + mainElementType = mainElementType or gridEntity:getElementType() + local tempIdMap = GFunc.getTable(posIdMap) + local newList = GFunc.getTable(lineList) + local gotSkill = self:findLinkLine(aroundposId, tempIdMap, hadSkill, mainElementType, newList) + local count = #newList + if count > lineCount then + lineCount = count + maxLineList = newList + maxPosIdMap = tempIdMap + maxGotSkill = gotSkill + end + end + elseif gridEntity:getSkillId() and not hadSkill and mainElementType then + local skillId = gridEntity:getSkillId() + local skillEntity = self.battleData:getSkillEntityBySkillId(skillId) + if skillEntity then + if skillEntity:getIgnoreElementType() or skillEntity:getPosition() == mainElementType then + local tempIdMap = GFunc.getTable(posIdMap) + local newList = GFunc.getTable(lineList) + local gotSkill = self:findLinkLine(aroundposId, tempIdMap, true, mainElementType, newList) + local count = #newList + if count > lineCount then + lineCount = count + maxLineList = newList + maxPosIdMap = tempIdMap + maxGotSkill = gotSkill + end + end + end + end + end + end + end + + if lineCount > 0 then + for index, id in ipairs(maxLineList) do + lineList[index] = id + end + + for _, id in pairs(maxPosIdMap) do + posIdMap[id] = true + end + + hadSkill = maxGotSkill + end + + return hadSkill +end + +function BattleBaseController:generateMonsterById(monsterId, callback) + local unitEntity = self.battleData:addMonster(monsterId, true) + local modelId = unitEntity:getModelId() + BattleHelper:loadBattleHeroModel(modelId, self.battleUI:getBattleNode(), function(spineObject) + self.defTeam:removeAllUnits() + local monsterComp = spineObject:addLuaComponent(GConst.BattleConst.TYPEOF_LUA_COMP.BATTLE_MONSTER_COMPONENT) + monsterComp:initWithEntity(modelId, unitEntity, self) + self.defTeam:addUnit(monsterComp, true) + self.battleUI:refreshDefHp(unitEntity:getHp(), unitEntity:getHpPercent()) + monsterComp:playEnterBattlefield(false, callback) + end) +end + +function BattleBaseController:addBattleExp(exp) + if not self.battleData or not exp then + return + end + self.battleData:addExp(exp) +end + +function BattleBaseController:addTaskProgress(fieldName, count) + if not count then + return + end + self.taskProgress[fieldName] = (self.taskProgress[fieldName] or 0) + count +end + +function BattleBaseController:setTaskProgress(fieldName, count) + if not count then + return + end + self.taskProgress[fieldName] = count +end + + +function BattleBaseController:getTaskProgress() + return self.taskProgress +end + +function BattleBaseController:addFillWaitingCount() + self.waitingFillCount = self.waitingFillCount + 1 +end + +function BattleBaseController:reduceFillWaitingCount() + self.waitingFillCount = self.waitingFillCount - 1 +end + +function BattleBaseController:_tick(dt, originDt) + self.realTime = self.realTime + dt + self.waveDurationTime = self.waveDurationTime + originDt + self.totalDurationTime = self.totalDurationTime + originDt + if self.isPause then + return + end + if self.needWaitingBoardOver == false then + self:enterRoundBegin() + end + if self.waitingFillCount <= 0 and self.isWaitingFill and self.isRoundBeginCheck then + self:fillBoard(self.isRoundBeginCheck) + end + self.time = self.time + dt + self.atkTeam:tick(dt) + self.defTeam:tick(dt) + local count = #self.effectTexts + for i = count, 1, -1 do + self.effectTexts[i]:tick(dt) + if self.effectTexts[i]:getDuration() < 0 then + BattleHelper:recycleEffectText(self.effectTexts[i]) + table.remove(self.effectTexts, i) + end + end + self:checkDelayEffectText(dt) + self:checkSkillSlowDown(dt) + self:tick(dt) +end + +function BattleBaseController:battleEnd() + if self.battleEndSid then + ModuleManager.BattleManager:unscheduleGlobal(self.battleEndSid) + self.battleEndSid = nil + end + self.battleUI:disableUITouch() + self.battleEndSid = ModuleManager.BattleManager:performWithDelayGlobal(function() + if self.battleUI then + self.battleUI:enableUITouch() + end + self:controllBattleEnd() + if self.victory then + ModuleManager.TaskManager:addTaskProgress(GConst.TaskConst.TASK_TYPE.X_BATTLE_VICTORY) + end + end, 1) +end + +function BattleBaseController:clear() + if self.alreadyClear then + return + end + self.alreadyClear = true + if self.tickSid then + BattleScheduler:unscheduleGlobal(self.tickSid) + self.tickSid = nil + end + BattleScheduler:clear() + BattleHelper:clear() + BattlePassive:clear() + BattlePool:clear() + self:unBindAll() + self.battleData:resetTimeSpeed() + ModuleManager.BattleManager:unscheduleAll() +end + +function BattleBaseController:endBattleAndExit() + ModuleManager.BattleManager:exitBattle() +end + +function BattleBaseController:checkSkillSlowDown(dt) + if self.skillSlowDownDuration == nil then + return + end + self.skillSlowDownDuration = self.skillSlowDownDuration - dt + if self.skillSlowDownDuration >= 0 then + return + end + self.skillSlowDownDuration = nil + self:resetTimeSpeed() +end + +function BattleBaseController:checkDelayEffectText(dt) + if self.delayEffectTextCount <= 0 then + return + end + for i = self.delayEffectTextCount, 1, -1 do + local delayEffectText = self.delayEffectTextList[i] + delayEffectText.time = delayEffectText.time - dt + if delayEffectText.time <= 0 then + local effectTextComp = BattleHelper:getEffectText(self.battleUI:getNumberNode(), delayEffectText.colorType) + effectTextComp:showEffectNumber(delayEffectText.effectType, delayEffectText.num, delayEffectText.x, delayEffectText.y, delayEffectText.showCombo) + table.insert(self.effectTexts, effectTextComp) + local tailDelayEffectText = self.delayEffectTextList[self.delayEffectTextCount] + delayEffectText.colorType = tailDelayEffectText.colorType + delayEffectText.effectType = tailDelayEffectText.effectType + delayEffectText.num = tailDelayEffectText.num + delayEffectText.x = tailDelayEffectText.x + delayEffectText.y = tailDelayEffectText.y + delayEffectText.time = tailDelayEffectText.time + delayEffectText.showCombo = tailDelayEffectText.showCombo + self.delayEffectTextCount = self.delayEffectTextCount - 1 + end + end +end + +function BattleBaseController:showEffectNumber(colorType, effectType, num, x, y, delayTime, showCombo) + if delayTime > 0 then + self.delayEffectTextCount = self.delayEffectTextCount + 1 + local obj = self.delayEffectTextList[self.delayEffectTextCount] + if obj == nil then + obj = {} + self.delayEffectTextList[self.delayEffectTextCount] = obj + end + obj.colorType = colorType + obj.effectType = effectType + obj.num = num + obj.x = x + obj.y = y + obj.time = delayTime + obj.showCombo = showCombo + else + local effectTextComp = BattleHelper:getEffectText(self.battleUI:getNumberNode(), colorType) + effectTextComp:showEffectNumber(effectType, num, x, y, showCombo) + table.insert(self.effectTexts, effectTextComp) + end +end + +function BattleBaseController:getFxNode() + return self.battleUI:getFxNode() +end + +function BattleBaseController:shakeScreen(shakeType, duration) + self.battleUI:shakeScreen(shakeType, duration) +end + +local function _addCurRoundAttr(self, instruction, callback) + if instruction.effectList then + local defComp = self:getOtherSideMainUnit(BattleConst.SIDE_ATK) + local mainComp = self:getOtherSideMainUnit(BattleConst.SIDE_DEF) + for _, effect in ipairs(instruction.effectList) do + local target + if effect:getTargetSide() == BattleConst.SIDE_DEF then + target = defComp + elseif effect:getTargetSide() == BattleConst.SIDE_ATK then + target = mainComp + else + local matchType = BattleConst.SIDE_OBJ_TO_MATCH_TYPE[effect:getTargetSide()] + if matchType then + target = self.atkTeam:getUnitComp()[matchType] + end + end + if target then + mainComp:takeEffect(effect, target) + end + end + end + + callback() +end + +local function _assisting(self, instruction, callback) + self.atkTeam:useAssistingSkill(instruction.assistingList, #self.instructions == 0, callback) +end + +local function _generalAttack(self, instruction, callback) + self.atkTeam:useNormalSkill(instruction.skillMatch, instruction.count, #self.instructions == 0, BattleConst.EFFECT_TYPE.DIRECT, BattleConst.ATTACK_ACTION_STATE.NORMAL, callback) +end + +local function _playSkill(self, instruction, callback) + self.atkTeam:useSkill(instruction.skillMatch, instruction.count, #self.instructions == 0, BattleConst.EFFECT_TYPE.DIRECT, BattleConst.ATTACK_ACTION_STATE.NORMAL, callback) +end + +BattleBaseController._doInstruction = { + [BattleConst.INSTRUCTION_NAME.ADD_CUR_ROUND_ATTR] = _addCurRoundAttr, + [BattleConst.INSTRUCTION_NAME.ASSISTING] = _assisting, + [BattleConst.INSTRUCTION_NAME.GENERAL_ATTACK] = _generalAttack, + [BattleConst.INSTRUCTION_NAME.PLAY_SKILL] = _playSkill, +} + +return BattleBaseController \ No newline at end of file diff --git a/lua/app/module/battle/controller/battle_base_controller.lua.meta b/lua/app/module/battle/controller/battle_base_controller.lua.meta new file mode 100644 index 00000000..bd1a7ba8 --- /dev/null +++ b/lua/app/module/battle/controller/battle_base_controller.lua.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 06696c742e709a642ba2189a9c75b45a +ScriptedImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 2 + userData: + assetBundleName: + assetBundleVariant: + script: {fileID: 11500000, guid: 3b8b241bab4a4ac9a22fcce9c64f1242, type: 3} diff --git a/lua/app/module/battle/controller/battle_controller.lua b/lua/app/module/battle/controller/battle_controller.lua index 50a16dcd..27104697 100644 --- a/lua/app/module/battle/controller/battle_controller.lua +++ b/lua/app/module/battle/controller/battle_controller.lua @@ -418,7 +418,7 @@ function BattleController:init(params) self.delayEffectTextList = {} self.delayEffectTextCount = 0 self.time = 0 - self.battleData:init() + self.battleData:init(params) BattleScheduler:init() BattlePool:init() BattleHelper:init() @@ -2034,7 +2034,7 @@ end function BattleController:onSelectSkill(skillId, value, pos) self.battleData:addSkillCount(skillId, value) - BATTLE_ROGUE_SKILL_HANDLE.takeEffect(skillId, self.battleData, self, value) + BATTLE_ROGUE_SKILL_HANDLE.takeEffect(skillId, self.battleData, self, value, BattleConst.SIDE_ATK) local skillEntities = self.battleData:getSkillEntities() for _, entity in pairs(skillEntities) do diff --git a/lua/app/module/battle/controller/battle_controller_pvp.lua b/lua/app/module/battle/controller/battle_controller_pvp.lua new file mode 100644 index 00000000..6377cbd7 --- /dev/null +++ b/lua/app/module/battle/controller/battle_controller_pvp.lua @@ -0,0 +1,173 @@ +local BattleHelper = require "app/module/battle/helper/battle_helper" +local BattleBaseController = require "app/module/battle/controller/battle_base_controller" +local BattleControllerPVP = class("BattleControllerPVP", BattleBaseController) +local BattleConst = GConst.BattleConst + +-- *************各个子模块的战斗需要重写的方法 START************* +function BattleControllerPVP:getBoardConfig() + return {} +end + +function BattleControllerPVP:getChapterConfig() + return {} +end + +function BattleControllerPVP:getChapterId() + return 0 +end + +function BattleControllerPVP:getBuffs() + return {} +end + +-- 战斗对应的ui +function BattleControllerPVP:getBattleUIPath() + return "app/ui/battle/battle_ui_pvp" +end + +-- 战斗结束 +function BattleControllerPVP:controllBattleEnd() +end + +-- 一共有多少波 +function BattleControllerPVP:getMaxWave() + return 1 +end + +function BattleControllerPVP:findNextDefUnit() + self:enterRoundEnd(true) +end + +function BattleControllerPVP:onLinkChange() + self.battleUI:hideAllSfxLine() + self.linkChangeNeedFalsePosMap = table.clearOrCreate(self.linkChangeNeedFalsePosMap) + for posId, entity in pairs(self.battleData:getGridEnties()) do + if entity:getCell() then + self.linkChangeNeedFalsePosMap[posId] = entity:getCell() + end + end + + local sequence = self.battleData:getGridSequence() + local mainElementType + + for index, info in ipairs(sequence) do + local entity = self.battleData:getGridEntity(info.posId) + if not mainElementType then + local skillId = entity:getSkillId() + if not skillId then + mainElementType = entity:getElementType() + break + end + end + end + + local count = #sequence + + for index, info in ipairs(sequence) do + local entity = self.battleData:getGridEntity(info.posId) + if entity:getCell() then + entity:getCell():showHighLight(true, mainElementType, self.battleUI) + end + if self.linkChangeNeedFalsePosMap[info.posId] then + self.linkChangeNeedFalsePosMap[info.posId] = nil + end + if index < count then + local nextPosId = sequence[index + 1].posId + self.battleUI:getSfxLine(index, function(obj) + local curPos = ModuleManager.BattleManager:getPosInfo(info.posId) + local nextPos = ModuleManager.BattleManager:getPosInfo(nextPosId) + local pos, z = ModuleManager.BattleManager:getPosCenterAndDir(curPos, nextPos) + obj:setLocalScale(25, 25, 25) + obj:setLocalPosition(pos.x, pos.y, 0) + obj:setEulerAngles(0, 0, z) + end) + end + if index == count then + if entity:getCell() then + entity:getCell():showAni() + end + end + end + + for posId, cell in pairs(self.linkChangeNeedFalsePosMap) do + cell:showHighLight(false) + end + + for posId, info in pairs(self.battleData:getSkillInfluenceGrids()) do + local entity = self.battleData:getGridEntity(posId) + if info.direction ~= BattleConst.BOARD_RANGE_TYPE.RANDOM then + if entity:getCell() then + entity:getCell():showCircle(true) + end + end + end + + if not self.atkTeam:getMainUnit().unitEntity:getActiveSkillLimit() then + local aniSequence, influenceElementType, lineCount, elementTypeMap, linkElementType = self:calculateCurElimination(true) + self.battleUI:refreshSkill(elementTypeMap, count > 0) + end + + if mainElementType then + self.atkTeam:changeMainUnit(mainElementType) + end +end + +function BattleControllerPVP:postWaveOver(atkDead, isQuit) + +end + +function BattleControllerPVP:postFightStart() + +end + +function BattleControllerPVP:onEliminationBegin() + +end + +function BattleControllerPVP:refreshWave() + if not self.battleUI then + return + end + self.battleUI:refreshWave(self.waveIndex) +end + +-- *************各个子模块的战斗需要重写的方法 END************* + +function BattleControllerPVP:ctor() + self.battleData = DataManager.BattlePVPData +end + +function BattleControllerPVP:initDefUnits(callback) + local defTeamEntity = self.battleData:getDefTeam() + local count = 0 + local totalCount = defTeamEntity:getMembersCount() + local function onloadFinished() + count = count + 1 + if count == totalCount then + self.battleUI:refreshAtkHp(defTeamEntity:getHp(), defTeamEntity:getHpPercent()) + callback() + end + end + local members = defTeamEntity:getAllMembers() + for k, v in pairs(members) do + local modelId = v:getModelId() + BattleHelper:loadBattleHeroModel(modelId, self.battleUI:getBattleNode(), function(spineObject) + local heroComp = spineObject:addLuaComponent(BattleConst.TYPEOF_LUA_COMP.BATTLE_HERO_COMPONENT) + heroComp:initWithEntity(modelId, v, self) + if v:getIsMainUnit() then + self.defTeam:addUnit(heroComp, true) + else + self.defTeam:addUnit(heroComp) + heroComp:hideOutsideScreen() + end + onloadFinished() + end) + end + if totalCount == 0 then + callback() + end +end + + + +return BattleControllerPVP \ No newline at end of file diff --git a/lua/app/module/battle/controller/battle_controller_pvp.lua.meta b/lua/app/module/battle/controller/battle_controller_pvp.lua.meta new file mode 100644 index 00000000..8809c44f --- /dev/null +++ b/lua/app/module/battle/controller/battle_controller_pvp.lua.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: cf144ebf0bb8b7b46b1341ca0f899c3e +ScriptedImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 2 + userData: + assetBundleName: + assetBundleVariant: + script: {fileID: 11500000, guid: 3b8b241bab4a4ac9a22fcce9c64f1242, type: 3} diff --git a/lua/app/module/battle/skill/battle_rogue_skill_handle.lua b/lua/app/module/battle/skill/battle_rogue_skill_handle.lua index 7e59e3bc..4595e43b 100644 --- a/lua/app/module/battle/skill/battle_rogue_skill_handle.lua +++ b/lua/app/module/battle/skill/battle_rogue_skill_handle.lua @@ -4,7 +4,7 @@ local BattleBuffEntity = require "app/userdata/battle/skill/battle_buff_entity" local BattleRogueSkillHandle = {} -local _changeBaseSkill = function(skillId, skillInfo, battleData, battleController) +local _changeBaseSkill = function(skillId, skillInfo, battleBaseData, battleController, value, side) local elementType = skillInfo.skill_position if not elementType or not skillInfo.parameter then return @@ -14,14 +14,14 @@ local _changeBaseSkill = function(skillId, skillInfo, battleData, battleControll return end - local skillEntity = battleData:getSkillEntityByElement(elementType) + local skillEntity = battleBaseData:getSkillEntityByElement(elementType, side) if skillEntity then local skillId = skillEntity:getSkillId() - battleData:changeSkillId(elementType, newSkillId) - if not battleData.atkTeam then + battleBaseData:changeSkillId(elementType, newSkillId, side) + if not battleBaseData.atkTeam then return end - local unitEntity = battleData.atkTeam:getAllMembers()[elementType] + local unitEntity = battleBaseData.atkTeam:getAllMembers()[elementType] if unitEntity then unitEntity:changeSkillId(skillId, newSkillId) for effectType, effect in pairs(skillEntity:getSkillRoundAdd()) do -- 技能回合数 @@ -39,54 +39,54 @@ local _changeBaseSkill = function(skillId, skillInfo, battleData, battleControll end end -local _addEliminationRange = function(skillId, skillInfo, battleData, battleController) +local _addEliminationRange = function(skillId, skillInfo, battleData, battleController, value, side) local elementType = skillInfo.skill_position if not elementType or not skillInfo.boardrange then return end - local entity = battleData:getSkillEntityByElement(elementType) + local entity = battleData:getSkillEntityByElement(elementType, side) if entity then entity:addBoardRange(skillInfo.boardrange) end end -local _canLinkAnyElement = function(skillId, skillInfo, battleData, battleController) +local _canLinkAnyElement = function(skillId, skillInfo, battleData, battleController, value, side) local elementType = skillInfo.skill_position if not elementType then return end - local entity = battleData:getSkillEntityByElement(elementType) + local entity = battleData:getSkillEntityByElement(elementType, side) if entity then entity:setIgnoreElementType(true) end end -local _addLinkAtkp = function(skillId, skillInfo, battleData, battleController) +local _addLinkAtkp = function(skillId, skillInfo, battleData, battleController, value, side) local elementType = skillInfo.skill_position if not elementType or not skillInfo.effect then return end - if not battleController.battleData or not battleController.battleData.atkTeam then + if not battleData.atkTeam then return end - local unitEntity = battleController.battleData.atkTeam:getAllMembers()[elementType] + local unitEntity = battleData.atkTeam:getAllMembers()[elementType] if not unitEntity then return end for _, effect in ipairs(skillInfo.effect) do - local entity = battleData:getSkillEntityByElement(elementType) + local entity = battleData:getSkillEntityByElement(elementType, side) if entity then entity:addLinkEffect(effect, unitEntity, skillInfo.obj) end end end -local _changeElementType = function(skillId, skillInfo, battleData, battleController) +local _changeElementType = function(skillId, skillInfo, battleData, battleController, value, side) if not skillInfo.boardrange or not skillInfo.parameter then return end @@ -100,7 +100,7 @@ local _changeElementType = function(skillId, skillInfo, battleData, battleContro battleController:changeElementType(count, elementType) end -local _addAttr = function(skillId, skillInfo, battleData, battleController, value) +local _addAttr = function(skillId, skillInfo, battleData, battleController, value, side) if not skillInfo.attr then return end @@ -111,15 +111,15 @@ local _addAttr = function(skillId, skillInfo, battleData, battleController, valu battleController:addHeroAttr(skillInfo.attr.type, value) end -local _unlockSkill = function(skillId, skillInfo, battleData, battleController, value) +local _unlockSkill = function(skillId, skillInfo, battleData, battleController, value, side) if not skillInfo.skill_position then return end - battleData:unlockSkillEntity(skillInfo.skill_position) + battleData:unlockSkillEntity(skillInfo.skill_position, side) end -local _addSkillEffectParams = function(skillId, skillInfo, battleData, battleController) +local _addSkillEffectParams = function(skillId, skillInfo, battleData, battleController, value, side) local elementType = skillInfo.skill_position if not elementType or not skillInfo.parameter then return @@ -131,7 +131,7 @@ local _addSkillEffectParams = function(skillId, skillInfo, battleData, battleCon end local effect - local entity = battleData:getSkillEntityByElement(elementType) + local entity = battleData:getSkillEntityByElement(elementType, side) if entity and entity:getEffect() then local effectCfg = entity:getEffect()[index] if effectCfg then @@ -144,7 +144,7 @@ local _addSkillEffectParams = function(skillId, skillInfo, battleData, battleCon return end - local skillEntity = battleData:getSkillEntityByElement(elementType) + local skillEntity = battleData:getSkillEntityByElement(elementType, side) if skillEntity then local skillId = skillEntity:getSkillId() skillEntity:addSkillEffecuNumAdd(effect) @@ -157,7 +157,7 @@ local _addSkillEffectParams = function(skillId, skillInfo, battleData, battleCon end end -local _addSkillRound = function(skillId, skillInfo, battleData, battleController) +local _addSkillRound = function(skillId, skillInfo, battleData, battleController, value, side) local elementType = skillInfo.skill_position if not elementType or not skillInfo.parameter then return @@ -170,7 +170,7 @@ local _addSkillRound = function(skillId, skillInfo, battleData, battleController end local effect - local entity = battleData:getSkillEntityByElement(elementType) + local entity = battleData:getSkillEntityByElement(elementType, side) if entity and entity:getEffect() then local effectCfg = entity:getEffect()[index] if effectCfg then @@ -183,7 +183,7 @@ local _addSkillRound = function(skillId, skillInfo, battleData, battleController return end - local skillEntity = battleData:getSkillEntityByElement(elementType) + local skillEntity = battleData:getSkillEntityByElement(elementType, side) if skillEntity then local skillId = skillEntity:getSkillId() skillEntity:addSkillRoundAdd(effect) @@ -196,7 +196,7 @@ local _addSkillRound = function(skillId, skillInfo, battleData, battleController end end -local _addSkillEffect = function(skillId, skillInfo, battleData, battleController) +local _addSkillEffect = function(skillId, skillInfo, battleData, battleController, value, side) if not skillInfo.effect then return end @@ -236,43 +236,43 @@ local _addSkillEffect = function(skillId, skillInfo, battleData, battleControlle end end -local _addSkillInInfluenceAtkp = function(skillId, skillInfo, battleData, battleController) +local _addSkillInInfluenceAtkp = function(skillId, skillInfo, battleData, battleController, value, side) local elementType = skillInfo.skill_position if not elementType or not skillInfo.effect then return end - if not battleController.battleData or not battleController.battleData.atkTeam then + if not battleData.atkTeam then return end - local unitEntity = battleController.battleData.atkTeam:getAllMembers()[elementType] + local unitEntity = battleData.atkTeam:getAllMembers()[elementType] if not unitEntity then return end - local entity = battleData:getSkillEntityByElement(elementType) + local entity = battleData:getSkillEntityByElement(elementType, side) for _, effect in ipairs(skillInfo.effect) do entity:addInInfluenceEffect(effect, unitEntity, skillInfo.obj) end end -local _addSkillAttackBeforeEffect = function(skillId, skillInfo, battleData, battleController) +local _addSkillAttackBeforeEffect = function(skillId, skillInfo, battleData, battleController, value, side) local elementType = skillInfo.skill_position if not elementType or not skillInfo.effect then return end - if not battleController.battleData or not battleController.battleData.atkTeam then + if not battleData.atkTeam then return end - local unitEntity = battleController.battleData.atkTeam:getAllMembers()[elementType] + local unitEntity = battleData.atkTeam:getAllMembers()[elementType] if not unitEntity then return end - local entity = battleData:getSkillEntityByElement(elementType) + local entity = battleData:getSkillEntityByElement(elementType, side) if entity then if skillInfo.cover_unlock then entity:removeSkillAttackBeforeEffect(skillInfo.cover_unlock) @@ -283,22 +283,22 @@ local _addSkillAttackBeforeEffect = function(skillId, skillInfo, battleData, bat end end -local _addSkillElementCountEffect = function(skillId, skillInfo, battleData, battleController) +local _addSkillElementCountEffect = function(skillId, skillInfo, battleData, battleController, value, side) local elementType = skillInfo.skill_position if not elementType or not skillInfo.effect then return end - if not battleController.battleData or not battleController.battleData.atkTeam then + if not battleData.atkTeam then return end - local unitEntity = battleController.battleData.atkTeam:getAllMembers()[elementType] + local unitEntity = battleData.atkTeam:getAllMembers()[elementType] if not unitEntity then return end - local entity = battleData:getSkillEntityByElement(elementType) + local entity = battleData:getSkillEntityByElement(elementType, side) if entity then if skillInfo.cover_unlock then entity:removeElementCountEffect(skillInfo.cover_unlock) @@ -309,22 +309,22 @@ local _addSkillElementCountEffect = function(skillId, skillInfo, battleData, bat end end -local _addLinkCountMoreEffect = function(skillId, skillInfo, battleData, battleController) +local _addLinkCountMoreEffect = function(skillId, skillInfo, battleData, battleController, value, side) local elementType = skillInfo.skill_position if not elementType or not skillInfo.effect or not skillInfo.parameter then return end - if not battleController.battleData or not battleController.battleData.atkTeam then + if not battleData.atkTeam then return end - local unitEntity = battleController.battleData.atkTeam:getAllMembers()[elementType] + local unitEntity = battleData.atkTeam:getAllMembers()[elementType] if not unitEntity then return end - local entity = battleData:getSkillEntityByElement(elementType) + local entity = battleData:getSkillEntityByElement(elementType, side) if entity then if skillInfo.cover_unlock then entity:removeLinkCountMoreEffects(skillInfo.cover_unlock) @@ -338,22 +338,22 @@ local _addLinkCountMoreEffect = function(skillId, skillInfo, battleData, battleC end end -local _addLinkCountPowerEffect = function(skillId, skillInfo, battleData, battleController) +local _addLinkCountPowerEffect = function(skillId, skillInfo, battleData, battleController, value, side) local elementType = skillInfo.skill_position if not elementType or not skillInfo.effect or not skillInfo.parameter then return end - if not battleController.battleData or not battleController.battleData.atkTeam then + if not battleData.atkTeam then return end - local unitEntity = battleController.battleData.atkTeam:getAllMembers()[elementType] + local unitEntity = battleData.atkTeam:getAllMembers()[elementType] if not unitEntity then return end - local entity = battleData:getSkillEntityByElement(elementType) + local entity = battleData:getSkillEntityByElement(elementType, side) if entity then if skillInfo.cover_unlock then entity:removeLinkCountPowerEffects(skillInfo.cover_unlock) @@ -367,7 +367,7 @@ local _addLinkCountPowerEffect = function(skillId, skillInfo, battleData, battle end end -local _addSkillRatio = function(skillId, skillInfo, battleData, battleController) +local _addSkillRatio = function(skillId, skillInfo, battleData, battleController, value, side) local elementType = skillInfo.skill_position if not elementType or not skillInfo.parameter then return @@ -380,7 +380,7 @@ local _addSkillRatio = function(skillId, skillInfo, battleData, battleController end local effect - local skillEntity = battleData:getSkillEntityByElement(elementType) + local skillEntity = battleData:getSkillEntityByElement(elementType, side) if skillEntity and skillEntity:getEffect() then local effectCfg = skillEntity:getEffect()[index] if effectCfg then @@ -424,7 +424,7 @@ BattleRogueSkillHandle._effectOn = { [16] = _addSkillRatio, -- 增加技能效果概率 } -function BattleRogueSkillHandle.takeEffect(skillId, battleData, battleController, value) +function BattleRogueSkillHandle.takeEffect(skillId, battleData, battleController, value, side) local cfg = SKILL_ROGUE_CFG[skillId] if not cfg or not cfg.type then return @@ -432,7 +432,7 @@ function BattleRogueSkillHandle.takeEffect(skillId, battleData, battleController local func = BattleRogueSkillHandle._effectOn[cfg.type] if func then - func(skillId, cfg, battleData, battleController, value) + func(skillId, cfg, battleData, battleController, value, side) end end diff --git a/lua/app/ui/battle/battle_base_ui.lua b/lua/app/ui/battle/battle_base_ui.lua new file mode 100644 index 00000000..8cab7bd3 --- /dev/null +++ b/lua/app/ui/battle/battle_base_ui.lua @@ -0,0 +1,2280 @@ +local UIPrefabObject = require "app/bf/unity/uiprefab_object" +local BattleBaseUI = class("BattleBaseUI", BaseUI) + +local GRID_CELL = "app/ui/battle/cell/grid_cell" +local GRID_CELL_PATH = "assets/prefabs/ui/battle/cell/grid_cell.prefab" +local SKILL_NODE_CELL = "app/ui/battle/cell/skill_node_cell" +local TINY_BUFF_CELL = "app/ui/battle/cell/tiny_buff_cell" +local BG_PATH = "assets/arts/textures/background/battle/%s.png" +local BATTLE_COMMON_PATH = "assets/arts/textures/background/battle_common/%s.png" + +local BOARD_SFX_ORDER = GConst.UI_EFFECT_ORDER.LEVEL4 + 1 +local SIDE_ATK = GConst.BattleConst.SIDE_ATK +local SIDE_DEF = GConst.BattleConst.SIDE_DEF +local CacheVector2 = CS.UnityEngine.Vector2(0, 0) +local DEFAULT_X = 10000 +local CACHE_SKILL_POS_1 = {x = 10, y = 360} +local CACHE_SKILL_POS_2 = {x = 10, y = 420} +local MAX_LASTSIBLING_TYPE = { + [8] = true, + [9] = true, + [10] = true, + [11] = true, +} + +---------------------------------必须重写的方法---------------------------------- +function BattleBaseUI:initBaseInfo() + -- local uiMap = self.root:genAllChildren() + -- self.uiMap = uiMap + -- self.gridNode = ? + -- self.boardNode = ? + -- self.boardNode:setAnchoredPositionX(DEFAULT_X) + -- self.boardMask2D = self.gridNode:getComponent(GConst.TYPEOF_UNITY_CLASS.UI_RECT_MASK_2D) + -- self.boardMask = ? + -- self.boardMask:setVisible(false) + -- self.boardCacheNode = ? + -- self.boardCacheNode:setVisible(false) + -- self.boardCacheBox = ? + -- self.boardCacheBox:setAnchoredPositionX(DEFAULT_X) + -- self.battleRoot = ? + -- self.maxLayerNode = ? +end + +function BattleBaseUI:initBg() + -- self.bg = ? + -- self.bg:setLocalScale(0, 0, 0) + -- local width = self.bg:fastGetSizeDelta() + -- self.bg:setAnchoredPositionX(width/4) +end + +function BattleBaseUI:initSkill() + local uiMap = self.root:genAllChildren() + local atkNode = nil + local defNode = nil + local atkCellPrefix = nil + local defCellPrefix = nil + self:_initSkill(atkNode, atkCellPrefix, defNode, defCellPrefix) +end + +function BattleBaseUI:initBuff() + local atkBuffPrefix = nil + local defBuffPrefix = nil + local battleBuffTipsRoot = nil + local battleBuffTipsMask = nil + local battleBuffTipsBg = nil + local battleBuffTipsBuff = nil + self:_initBuff(atkBuffPrefix, defBuffPrefix, battleBuffTipsRoot, battleBuffTipsMask, battleBuffTipsBg, battleBuffTipsBuff) +end + +function BattleBaseUI:initBattlefield() + self.battleNode = nil +end + +function BattleBaseUI:initNumberNode() + self.battleNumberNode = nil + self.battleNumberRed = nil + self.battleNumberGreen = nil + self.battleNumberBlue = nil + self.battleNumberWhite = nil + self.battleNumberSpecial = nil +end + +function BattleBaseUI:initComboNode() + self.comboNode = nil + self.comboBg1 = nil + self.comboTx1 = nil + self.comboTx2 = nil + self.comboFx1 = nil + self.comboFx2 = nil + self.comboFx3 = nil + self:_initComboNode() +end + +function BattleBaseUI:initHpNode() + self.hpProgressLeft = self.uiMap[""]:getComponent(GConst.TYPEOF_UNITY_CLASS.BF_SLIDER) + self.hpProgressRight = self.uiMap[""]:getComponent(GConst.TYPEOF_UNITY_CLASS.BF_SLIDER) + self.hpTextLeft = self.uiMap[""] + self.hpTextRight = self.uiMap[""] + self.hpProgressYellowLeft = self.uiMap[""]:getComponent(GConst.TYPEOF_UNITY_CLASS.BF_SLIDER) + self.hpProgressYellowRight = self.uiMap[""]:getComponent(GConst.TYPEOF_UNITY_CLASS.BF_SLIDER) + self:_initHpNode() +end + +function BattleBaseUI:initFxNode() + self.fxNode = nil +end + +function BattleBaseUI:hideGenerateSkillGridCells() + local generateSkillCellPrefix = nil + self:_hideGenerateSkillGridCells(generateSkillCellPrefix) +end + +function BattleBaseUI:initSkillLineSfx() + if not self.skillLineSfxs then + self.skillLineSfxs = {} + self.skillLineSfxs[13] = self.uiMap["battle_ui_pvp.board_root_node.ani_node.sfx_skill_b01_2_1h"] + self.skillLineSfxs[11] = self.uiMap["battle_ui_pvp.board_root_node.ani_node.sfx_skill_b01_2_1v"] + self.skillLineSfxs[15] = self.uiMap["battle_ui_pvp.board_root_node.ani_node.sfx_skill_b01_2_1l"] + self.skillLineSfxs[17] = self.uiMap["battle_ui_pvp.board_root_node.ani_node.sfx_skill_b01_2_1r"] + + self.skillLineSfxs[23] = self.uiMap["battle_ui_pvp.board_root_node.ani_node.sfx_skill_b01_1_2h"] + self.skillLineSfxs[21] = self.uiMap["battle_ui_pvp.board_root_node.ani_node.sfx_skill_b01_1_2v"] + self.skillLineSfxs[25] = self.uiMap["battle_ui_pvp.board_root_node.ani_node.sfx_skill_b01_1_2l"] + self.skillLineSfxs[27] = self.uiMap["battle_ui_pvp.board_root_node.ani_node.sfx_skill_b01_1_2r"] + + self.skillLineSfxs[33] = self.uiMap["battle_ui_pvp.board_root_node.ani_node.sfx_skill_b01_3h"] + self.skillLineSfxs[31] = self.uiMap["battle_ui_pvp.board_root_node.ani_node.sfx_skill_b01_3v"] + self.skillLineSfxs[35] = self.uiMap["battle_ui_pvp.board_root_node.ani_node.sfx_skill_b01_3l"] + self.skillLineSfxs[37] = self.uiMap["battle_ui_pvp.board_root_node.ani_node.sfx_skill_b01_3r"] + end + + if not self.skillLightSfxs then + self.skillLightSfxs = {} + self.skillLightSfxs.point = self.uiMap["battle_ui_pvp.board_root_node.ani_node.sfx_skill_b03"] + self.skillLightSfxs[11] = self.uiMap["battle_ui_pvp.board_root_node.ani_node.sfx_skill_b04_1"] + self.skillLightSfxs[12] = self.uiMap["battle_ui_pvp.board_root_node.ani_node.sfx_skill_b04_2"] + self.skillLightSfxs[13] = self.uiMap["battle_ui_pvp.board_root_node.ani_node.sfx_skill_b04_3"] + self.skillLightSfxs[14] = self.uiMap["battle_ui_pvp.board_root_node.ani_node.sfx_skill_b04_4"] + self.skillLightSfxs[15] = self.uiMap["battle_ui_pvp.board_root_node.ani_node.sfx_skill_b04_5"] + + self.skillLightSfxs[21] = self.uiMap["battle_ui_pvp.board_root_node.ani_node.sfx_skill_b05_1"] + self.skillLightSfxs[22] = self.uiMap["battle_ui_pvp.board_root_node.ani_node.sfx_skill_b05_2"] + self.skillLightSfxs[23] = self.uiMap["battle_ui_pvp.board_root_node.ani_node.sfx_skill_b05_3"] + self.skillLightSfxs[24] = self.uiMap["battle_ui_pvp.board_root_node.ani_node.sfx_skill_b05_4"] + self.skillLightSfxs[25] = self.uiMap["battle_ui_pvp.board_root_node.ani_node.sfx_skill_b05_5"] + end +end + +function BattleBaseUI:initGenerateSkillEffect() + local generateSkillEffecPrefix = nil + self:_initGenerateSkillEffect(generateSkillEffecPrefix) +end + +function BattleBaseUI:initCounterAttack() + self.counterAttackNode = nil + self.counterTx = nil + self.counterTxbgComp = nil + self.counterTxTmp = self.counterTx:getComponent(GConst.TYPEOF_UNITY_CLASS.UI_TEXT_MESH_PRO) + self.counterAttackNode:setVisible(false) +end + +--------------------------------end必须重写的方法-------------------------------- +----------------------------------按需重写的方法 可以为nil,已容错---------------- +function BattleBaseUI:initTutorialNode() +end + +function BattleBaseUI:initCommonSkillDescTips() + -- local uiMap = self.root:genAllChildren() + -- self.skillDescTipsNode = ? + -- self.skillDescTips = ? + -- self.skillDescTipsNode:setVisible(false) +end + +function BattleBaseUI:initSkillSelectCells() + -- self.skillSelectCell = ? +end + +function BattleBaseUI:initSelectSkillNode() + -- self.selectSkillComp = ? +end + +function BattleBaseUI:initBossEnterAni() + -- local uiMap = self.root:genAllChildren() + -- self.bossEnterNode = ? + -- self.bossEnterImg = ? + -- self.bossName = ? + -- self.bossEnterNodeAnimator = self.bossEnterNode:getComponent(GConst.TYPEOF_UNITY_CLASS.ANIMATOR) + -- self.bossEnterNodeAnimator.enabled = false + -- self.bossEnterNodeCanvasGroup = self.bossEnterNode:getComponent(GConst.TYPEOF_UNITY_CLASS.CANVAS_GROUP) + -- self.bossEnterNode:setVisible(false) +end + +--------------------------------end按需重写的方法-------------------------------- + +function BattleBaseUI:ctor(parmas) + self.battleController = parmas.battleController + self.battleData = self.battleController.battleData +end + +function BattleBaseUI:onPressBackspace() + if self.battleBuffTipsRoot then + if self.battleBuffTipsRoot:getTransform().localScale.x > 0 then + self:hideBuffTips() + return + end + end + + ModuleManager.BattleManager:showPauseUI(self.battleController.battleType) +end + +function BattleBaseUI:onClose() + self:clear() +end + +function BattleBaseUI:onLoadRootComplete() + local uiMap = self.root:genAllChildren() + self.uiMap = uiMap + self:_display() + self:_addListeners() + self:_bind() +end + +function BattleBaseUI:_display() + self:initBaseInfo() + self:initBg() + self:initSkill() + self:initBuff() + self:initBattlefield() + self:initNumberNode() + self:initComboNode() + self:initHpNode() + self:initFxNode() + self:hideGenerateSkillGridCells() + self:initTutorialNode() + self:initUISfxs() + self:initSkillSelectCells() + self:hideAllSfxSmoke() + self:initSkillLineSfx() + self:initGenerateSkillEffect() + self:initSelectSkillNode() + self:initCommonSkillDescTips() + self:initBossEnterAni() + self:initCounterAttack() +end + +function BattleBaseUI:_addListeners() +end + +function BattleBaseUI:_bind() +end + +function BattleBaseUI:_initComboNode() + self.comboAnimator = self.comboNode:getComponent(GConst.TYPEOF_UNITY_CLASS.ANIMATOR) + self.comboNodeVisible = false + self.comboNode:setVisible(false) + self.comboBg1:setVisible(false) + self.comboTxComp1 = self.comboTx1:getComponent(GConst.TYPEOF_UNITY_CLASS.UI_TEXT) + self.comboTxComp2 = self.comboTx2:getComponent(GConst.TYPEOF_UNITY_CLASS.UI_TEXT) + self.comboFx1:setActive(false) + self.comboFxVisible1 = false + self.comboFx2:setActive(false) + self.comboFxVisible2 = false + self.comboFx3:setActive(false) + self.comboFxVisible3 = false +end + +function BattleBaseUI:_initHpNode() + self.hpProgressLeft.value = 1 + self.hpProgressRight.value = 1 + self.hpProgressYellowLeft.value = 1 + self.hpProgressYellowRight.value = 1 + self.hpPercentLeft = 1 + self.hpPercentRight = 1 +end + +function BattleBaseUI:_initSkill(atkNode, atkCellPrefix, defNode, defCellPrefix) + if self.skillNodeCells then + return + end + self.skillNodeCells = { + [SIDE_ATK] = {}, + [SIDE_DEF] = {}, + } + + local initSKillCell = function(obj, elementType, sideSkillCells) + sideSkillCells[elementType] = CellManager:addCellComp(obj, SKILL_NODE_CELL) + local skillEntity = DataManager.BattleData:getSkillEntities()[elementType] + if skillEntity then + sideSkillCells[elementType]:refresh(skillEntity) + end + sideSkillCells[elementType]:getBaseObject():setActive(skillEntity ~= nil) + sideSkillCells[elementType]:addClickListener(function() + ModuleManager.TipsManager:showBattleBoardSkillTips(elementType, obj) + end) + end + + for name, elementType in pairs(GConst.BattleConst.ELEMENT_TYPE) do + if defCellPrefix then + local obj = self.uiMap[defCellPrefix .. elementType] + if obj then + initSKillCell(obj, elementType, self.skillNodeCells[SIDE_DEF]) + end + end + + if atkCellPrefix then + local objDef = self.uiMap[atkCellPrefix .. elementType] + if objDef then + initSKillCell(objDef, elementType, self.skillNodeCells[SIDE_ATK]) + end + end + end + + if defNode then + defNode:getComponent(GConst.TYPEOF_UNITY_CLASS.BF_HORIZONTAL_OR_VERTICAL_LAYOUT):RefreshLayout() + end + if atkNode then + atkNode:getComponent(GConst.TYPEOF_UNITY_CLASS.BF_HORIZONTAL_OR_VERTICAL_LAYOUT):RefreshLayout() + end +end + +function BattleBaseUI:_initBuff(atkBuffPrefix, defBuffPrefix, battleBuffTipsRoot, battleBuffTipsMask, battleBuffTipsBg, battleBuffTipsBuff) + if self.tinyBuffCells then + return + end + self.tinyBuffCells = { + [SIDE_ATK] = {}, + [SIDE_DEF] = {}, + } + for i = 1, 8 do + if defBuffPrefix then + local obj = self.uiMap[defBuffPrefix .. i] + if obj then + self.tinyBuffCells[SIDE_DEF][i] = CellManager:addCellComp(obj, TINY_BUFF_CELL) + end + end + + if atkBuffPrefix then + local obj = self.uiMap[atkBuffPrefix .. i] + if obj then + self.tinyBuffCells[SIDE_ATK][i] = CellManager:addCellComp(obj, TINY_BUFF_CELL) + end + end + end + for side, cellList in pairs(self.tinyBuffCells) do + for index, cell in ipairs(cellList) do + cell:getBaseObject():setVisible(false) + end + end + -- buff的tips + self.battleBuffTipsRoot = battleBuffTipsRoot + self.battleBuffTipsRoot:setLocalScale(0, 0, 0) + battleBuffTipsMask:addClickListener(function() + if self.autoCloseBuffSid then + self:unscheduleGlobal(self.autoCloseBuffSid) + self.autoCloseBuffSid = nil + end + self.battleBuffTipsRoot:setLocalScale(0, 0, 0) + end) + self.battleBuffTipsBg = battleBuffTipsBg + self.battleBuffTipsBuff = battleBuffTipsBuff + self.battleBuffTipsBuffList = {} + local children = self.battleBuffTipsBg:getChildList() + if children then + for k, v in ipairs(children) do + table.insert(self.battleBuffTipsBuffList, v) + end + end +end + +function BattleBaseUI:refreshBuff(side, buffList) + if not self.tinyBuffCells then + return + end + local buffObj = nil + local count = #buffList + local buffCellCount = #self.tinyBuffCells[side] + local index = 1 + for i = 1, count do + buffObj = buffList[i] + if buffObj and buffObj.buff:getIcon() and not buffObj.buff:getNotShowIcon() then + local cell = self.tinyBuffCells[side][i] + if cell then + cell:getBaseObject():setVisible(true) + cell:refresh(buffObj.buff:getIcon(), buffObj.round) + end + index = i + 1 + if index > buffCellCount then + break + end + end + end + for i = index, buffCellCount do + local cell = self.tinyBuffCells[side][i] + if cell then + cell:getBaseObject():setVisible(false) + end + end +end + +function BattleBaseUI:clearBuff(side) + if not self.tinyBuffCells or not self.tinyBuffCells[side] then + return + end + for index, cell in ipairs(self.tinyBuffCells[side]) do + cell:getBaseObject():setVisible(false) + end +end + +function BattleBaseUI:refreshChessBoard(boardBg) + self.boardNode:setTexture(string.format(BATTLE_COMMON_PATH, boardBg), function() + self.boardNode:setAnchoredPositionX(0) + end) +end + +function BattleBaseUI:loadBg(bgName) + self.bg:setTexture(string.format(BG_PATH, bgName), function() + self.bg:setLocalScale(1, 1, 1) + end) +end + +function BattleBaseUI:showLeftBuffTips(buffList, autoClose) + self:showBuffTips(buffList, autoClose) +end + +function BattleBaseUI:showRightBuffTips(buffList, autoClose) + self:showBuffTips(buffList, autoClose) +end + +function BattleBaseUI:showTutorialFinger(posIdList) +end + +function BattleBaseUI:moveBattlefield(time) +end + +function BattleBaseUI:getBattleNode() + return self.battleNode +end + +function BattleBaseUI:getNumberNode() + return self.battleNumberNode +end + +function BattleBaseUI:getBattleNumberRed() + return self.battleNumberRed +end + +function BattleBaseUI:getBattleNumberGreen() + return self.battleNumberGreen +end + +function BattleBaseUI:getBattleNumberBlue() + return self.battleNumberBlue +end + +function BattleBaseUI:getBattleNumberWhite() + return self.battleNumberWhite +end + +function BattleBaseUI:getBattleNumberSpecial() + return self.battleNumberSpecial +end + +function BattleBaseUI:getBattleBuffTipsObj(index) + if self.battleBuffTipsBuffList[index] then + return self.battleBuffTipsBuffList[index] + end + local prefab = CS.UnityEngine.Object.Instantiate(self.battleBuffTipsBuff:getGameObject()) + local prefabObject = UIPrefabObject:create() + prefabObject:initWithPrefab(self.battleBuffTipsBuff:getAssetPath(), prefab) + prefabObject:initPrefabHelper() + prefabObject:setParent(self.battleBuffTipsBg, false) + table.insert(self.battleBuffTipsBuffList, prefabObject) + return prefabObject +end + +function BattleBaseUI:showBuffTips(buffList, autoClose) + if #buffList <= 0 then + return + end + self.battleBuffTipsRoot:setLocalScale(1, 1, 1) + local buffObj = nil + local count = #buffList + local index = 1 + local addY = 0 + for i = 1, count do + buffObj = buffList[i] + if buffObj and buffObj.buff:getIcon() and not buffObj.buff:getNotShowIcon() then + local buffTipsObj = self:getBattleBuffTipsObj(index) + buffTipsObj:setLocalScale(1, 1, 1) + buffTipsObj:setAnchoredPositionY(-addY) + local buffTipsObjMap = buffTipsObj:genAllChildren() + buffTipsObjMap["buff.icon"]:setSprite(GConst.ATLAS_PATH.ICON_BUFF, buffObj.buff:getIcon()) + local round = buffObj.round + if round <= 1 or round > 9 then + buffTipsObjMap["buff.round"]:setText(GConst.EMPTY_STRING) + else + buffTipsObjMap["buff.round"]:setText(tostring(round)) + end + local descTx = buffTipsObjMap["buff.desc"] + descTx:setText(buffObj.buff:getDesc()) + descTx:getComponent(GConst.TYPEOF_UNITY_CLASS.UI_TEXT_MESH_PRO):ForceMeshUpdate() + local height = descTx:getComponent(GConst.TYPEOF_UNITY_CLASS.UI_TEXT_MESH_PRO).renderedHeight + if height > 30 then + addY = addY + 56 + height - 30 + else + addY = addY + 56 + end + index = index + 1 + end + end + if index <= 1 then -- 没有找到buff + self.battleBuffTipsRoot:setLocalScale(0, 0, 0) + return + end + + for i = index, #self.battleBuffTipsBuffList do + self.battleBuffTipsBuffList[i]:setLocalScale(0, 0, 0) + end + self.battleBuffTipsBg:setSizeDeltaY(addY + 10) + + if self.autoCloseBuffSid then + self:unscheduleGlobal(self.autoCloseBuffSid) + self.autoCloseBuffSid = nil + end + + if autoClose then + self.autoCloseBuffSid = self:performWithDelayGlobal(function() + self.battleBuffTipsRoot:setLocalScale(0, 0, 0) + end, 1.5) + end + + return addY +end + +function BattleBaseUI:hideBuffTips() + if self.autoCloseBuffSid then + self:unscheduleGlobal(self.autoCloseBuffSid) + self.autoCloseBuffSid = nil + end + + if not self.battleBuffTipsRoot then + return + end + self.battleBuffTipsRoot:setLocalScale(0, 0, 0) +end + +function BattleBaseUI:playSkillLineSfx(posId, boradRangeList, randomPosList) + if not boradRangeList or not boradRangeList[1] or not self.skillLineSfxs then + return + end + + local directionAndRange = {} + for _, info in ipairs(boradRangeList) do + if info.type == GConst.BattleConst.BOARD_RANGE_TYPE.RANDOM then + directionAndRange[GConst.BattleConst.BOARD_RANGE_TYPE.RANDOM] = info.range + elseif info.type == GConst.BattleConst.BOARD_RANGE_TYPE.UP or + info.type == GConst.BattleConst.BOARD_RANGE_TYPE.DOWN then + directionAndRange[GConst.BattleConst.BOARD_RANGE_TYPE.UP] = info.range + elseif info.type == GConst.BattleConst.BOARD_RANGE_TYPE.LEFT or + info.type == GConst.BattleConst.BOARD_RANGE_TYPE.RIGHT then + directionAndRange[GConst.BattleConst.BOARD_RANGE_TYPE.LEFT] = info.range + elseif info.type == GConst.BattleConst.BOARD_RANGE_TYPE.LEFT_UP or + info.type == GConst.BattleConst.BOARD_RANGE_TYPE.LEFT_DOWN then + directionAndRange[GConst.BattleConst.BOARD_RANGE_TYPE.LEFT_UP] = info.range + elseif info.type == GConst.BattleConst.BOARD_RANGE_TYPE.RIGHT_UP or + info.type == GConst.BattleConst.BOARD_RANGE_TYPE.RIGHT_DOWN then + directionAndRange[GConst.BattleConst.BOARD_RANGE_TYPE.RIGHT_UP] = info.range + end + end + + local pos = ModuleManager.BattleManager:getPosInfo(posId) + for dir, range in pairs(directionAndRange) do + local index = range * 10 + dir + local obj = self.skillLineSfxs[index] + if obj then + obj:setAnchoredPosition(pos.x, pos.y) + obj:setActive(true) + obj:play() + end + end + + if randomPosList and randomPosList[1] then + local count = math.min(#randomPosList, 5) -- 特效最多5个 + self.skillLightSfxs.point:setAnchoredPosition(pos.x, pos.y) + self.skillLightSfxs.point:setActive(true) + self.skillLightSfxs.point:play() + for i = 1, count do + local tartgetPos = randomPosList[i] + tartgetPos = ModuleManager.BattleManager:getPosInfo(tartgetPos) + local obj = self.skillLightSfxs[20 + i] + if obj then + obj:setAnchoredPosition(tartgetPos.x, tartgetPos.y) + obj:setActive(true) + obj:play() + end + + obj = self.skillLightSfxs[10 + i] + local yOffset = tartgetPos.y - pos.y + local xOffset = tartgetPos.x - pos.x + local height = math.sqrt(xOffset * xOffset + yOffset * yOffset) + if obj then + obj:setAnchoredPosition(pos.x, pos.y) + obj:setLocalScaleX(0.3 * height / 94) + obj:setEulerAngles(0, 0, - math.deg(math.atan(xOffset, yOffset)) + 90) + obj:setActive(true) + obj:play() + end + end + end +end + +function BattleBaseUI:playChangeElementSfx(posId, index) + if not self.root.changeElementSfxs then + self.root.changeElementSfxs = {} + end + + local pos = ModuleManager.BattleManager:getPosInfo(posId) + local info = self.root.changeElementSfxs[index] + if info then + local obj = info.obj + if obj then + obj:setAnchoredPosition(pos.x, pos.y) + obj:setActive(true) + obj:play() + end + else + self.root.changeElementSfxs[index] = { + isLoaded = true + } + EffectManager:loadUIEffectAsync(GConst.BattleConst.CHANGE_ELEMENT_SFX, self, self.gridNode, GConst.UI_EFFECT_ORDER.LEVEL5, function(obj) + self.root.changeElementSfxs[index].obj = obj + obj:setAnchoredPosition(pos.x, pos.y) + obj:play() + end) + end +end + +function BattleBaseUI:initUISfxs() + if self.root.gridBreakSfxObjs then + for breakSfxPath, map in pairs(self.root.gridBreakSfxObjs) do + for index, info in pairs(map) do + if info.obj then + info.obj:setActive(true) + info.obj:getComponent(GConst.TYPEOF_UNITY_CLASS.BF_EFFECT_HELPER):SetSortingOrder(self:getUIOrder(), GConst.UI_EFFECT_ORDER.LEVEL5) + info.obj:setActive(false) + end + end + end + end + + if self.root.gridEffectSfx then + for breakSfxPath, list in pairs(self.root.gridEffectSfx) do + for index, info in pairs(list) do + if info.obj then + info.obj:setActive(true) + info.obj:getComponent(GConst.TYPEOF_UNITY_CLASS.BF_EFFECT_HELPER):SetSortingOrder(self:getUIOrder(), GConst.UI_EFFECT_ORDER.LEVEL5) + info.obj:setActive(false) + end + end + end + end + + if self.root.lineSfxObjs then + for index, info in pairs(self.root.lineSfxObjs) do + if info.obj then + info.obj:setActive(true) + info.obj:getComponent(GConst.TYPEOF_UNITY_CLASS.BF_EFFECT_HELPER):SetSortingOrder(self:getUIOrder(), BOARD_SFX_ORDER) + info.obj:setActive(false) + end + end + end + + if self.root.smokeSfxObjs then + for index, info in pairs(self.root.smokeSfxObjs) do + if info.obj then + info.obj:setActive(true) + info.obj:getComponent(GConst.TYPEOF_UNITY_CLASS.BF_EFFECT_HELPER):SetSortingOrder(self:getUIOrder(), BOARD_SFX_ORDER) + info.obj:setActive(false) + end + end + end + + if self.root.changeElementSfxs then + for index, info in pairs(self.root.changeElementSfxs) do + if info.obj then + info.obj:setActive(true) + info.obj:getComponent(GConst.TYPEOF_UNITY_CLASS.BF_EFFECT_HELPER):SetSortingOrder(self:getUIOrder(), GConst.UI_EFFECT_ORDER.LEVEL5) + info.obj:setActive(false) + end + end + end +end + +function BattleBaseUI:hideAllBoardSfxs() + if self.generateSkillSfxs then + for _, obj in pairs(self.generateSkillSfxs) do + obj:setActive(false) + end + end + + if self.skillLineSfxs then + for _, obj in pairs(self.skillLineSfxs) do + obj:setActive(false) + end + end + + if self.skillLightSfxs then + for _, obj in pairs(self.skillLightSfxs) do + obj:setActive(false) + end + end + + if self.root.gridBreakSfxObjs then + for breakSfxPath, map in pairs(self.root.gridBreakSfxObjs) do + for index, info in pairs(map) do + if info.obj then + info.obj:setActive(false) + end + end + end + end + + if self.root.lineSfxObjs then + for index, info in pairs(self.root.lineSfxObjs) do + if info.obj then + info.obj:setActive(false) + end + end + end + + if self.root.smokeSfxObjs then + for index, info in pairs(self.root.smokeSfxObjs) do + if info.obj then + info.obj:setActive(false) + end + end + end +end + +function BattleBaseUI:hideCombo() + if not self.comboNodeVisible then + return + end + self.comboNodeVisible = false + if self.comboSid then + self:unscheduleGlobal(self.comboSid) + end + self.comboSid = self:performWithDelayGlobal(function() + self.comboSid = nil + self.comboNode:setVisible(false) + if self.comboFxVisible1 then + self.comboFxVisible1 = false + self.comboFx1:setActive(false) + end + if self.comboFxVisible2 then + self.comboFxVisible2 = false + self.comboFx2:setActive(false) + end + if self.comboFxVisible3 then + self.comboFxVisible3 = false + self.comboFx3:setActive(false) + end + end, 0.5) +end + +function BattleBaseUI:showCombo(count) + if count > 99 then + count = 99 + end + self.comboNodeVisible = true + self.comboNode:setVisible(true) + if count <= 5 then + if self.comboFxVisible1 then + self.comboFxVisible1 = false + self.comboFx1:setActive(false) + end + if self.comboFxVisible2 then + self.comboFxVisible2 = false + self.comboFx2:setActive(false) + end + if self.comboFxVisible3 then + self.comboFxVisible3 = false + self.comboFx3:setActive(false) + end + self.comboBg1:setVisible(false) + self.comboTx1:setText(GConst.INT_TO_STRING[count], self.comboTxComp1) + self.comboTx1:setAnchoredPositionX(0) + self.comboTx2:setText(GConst.EMPTY_STRING, self.comboTxComp2) + self.comboAnimator:Play(GConst.BattleConst.ANIMATOR_HASH_NAME_BATTLE_COMBO_1, -1, 0) + elseif count <= 10 then + if self.comboFxVisible1 then + self.comboFxVisible1 = false + self.comboFx1:setActive(false) + end + if self.comboFxVisible2 then + self.comboFxVisible2 = false + self.comboFx2:setActive(false) + end + if not self.comboFxVisible3 then + self.comboFxVisible3 = true + self.comboFx3:setActive(true) + end + self.comboBg1:setVisible(true) + self.comboTx1:setText(GConst.INT_TO_STRING[count], self.comboTxComp1) + if count == 10 then + self.comboTx1:setAnchoredPositionX(-26) + else + self.comboTx1:setAnchoredPositionX(0) + end + self.comboTx2:setText(GConst.EMPTY_STRING, self.comboTxComp2) + self.comboAnimator:Play(GConst.BattleConst.ANIMATOR_HASH_NAME_BATTLE_COMBO_2, -1, 0) + else + if not self.comboFxVisible1 then + self.comboFxVisible1 = true + self.comboFx1:setActive(true) + end + if not self.comboFxVisible2 then + self.comboFxVisible2 = true + self.comboFx2:setActive(true) + end + if self.comboFxVisible3 then + self.comboFxVisible3 = false + self.comboFx3:setActive(false) + end + self.comboBg1:setVisible(true) + self.comboTx1:setText(GConst.EMPTY_STRING, self.comboTxComp1) + self.comboTx2:setText(GConst.INT_TO_STRING[count], self.comboTxComp2) + self.comboAnimator:Play(GConst.BattleConst.ANIMATOR_HASH_NAME_BATTLE_COMBO_3, -1, 0) + end +end + +function BattleBaseUI:showCounterAttack(count, side) + local x = 280 + local horizontal = 180 + if side == GConst.BattleConst.SIDE_ATK then + x = -280 + horizontal = 0 + self.counterTxTmp.alignment = CS.TMPro.TextAlignmentOptions.MidlineLeft + else + self.counterTxTmp.alignment = CS.TMPro.TextAlignmentOptions.MidlineRight + end + self.counterTxbgComp:setEulerAngles(0, horizontal, 0) + self.counterAttackNode:setAnchoredPositionX(x) + self.counterTx:setText(I18N:getGlobalText(I18N.GlobalConst.COUNTER_ATTACK_DESC) .. "x" .. count) + self.counterAttackNode:setVisible(true) +end + +function BattleBaseUI:hideCounterAttack() + self.counterAttackNode:setVisible(false) +end + +function BattleBaseUI:getFxNode() + return self.fxNode +end + +function BattleBaseUI:setIsPauseHpProgress(value) + if self.isPauseHpProgress == value then + return + end + self.isPauseHpProgress = value + if not value then + local timeLeft = math.abs(self.hpProgressYellowLeft.value - self.hpPercentLeft) + if timeLeft > 0.01 then + local delayTime = math.abs(self.hpProgressLeft.value - self.hpPercentLeft)*2 + if delayTime > 0.05 then + if self.hpProgressYellowLeftSid then + self:unscheduleGlobal(self.hpProgressYellowLeftSid) + end + self.hpProgressYellowLeftSid = self:performWithDelayGlobal(function() + self:playHpProgressYellowLeftTween(timeLeft) + end, delayTime) + else + self:playHpProgressYellowLeftTween(timeLeft) + end + else + if self.hpProgressYellowLeftTween then + self.hpProgressYellowLeftTween:Pause() + end + self.hpProgressYellowLeft.value = self.hpPercentLeft + end + local timeRight = math.abs(self.hpProgressYellowRight.value - self.hpPercentRight) + if timeRight > 0.01 then + local delayTime = math.abs(self.hpProgressRight.value - self.hpPercentRight)*2 + if delayTime > 0.05 then + if self.hpProgressYellowRightSid then + self:unscheduleGlobal(self.hpProgressYellowRightSid) + end + self.hpProgressYellowRightSid = self:performWithDelayGlobal(function() + self:playHpProgressYellowRightTween(timeRight) + end, delayTime) + else + self:playHpProgressYellowRightTween(timeRight) + end + else + if self.hpProgressYellowRightTween then + self.hpProgressYellowRightTween:Pause() + end + self.hpProgressYellowRight.value = self.hpPercentRight + end + end +end + +function BattleBaseUI:playHpProgressYellowLeftTween(time) + if self.hpProgressYellowLeftTween == nil then + self.hpProgressYellowLeftTween = GFunc.DOBFSliderValue(self.hpProgressYellowLeft, self.hpPercentLeft, time, false) + self.hpProgressYellowLeftTween:SetIntId(GConst.DOTWEEN_IDS.BATTLE) + self.hpProgressYellowLeftTween:SetAutoKill(false) + else + self.hpProgressYellowLeftTween:ChangeEndValue(self.hpPercentLeft, time, true) + self.hpProgressYellowLeftTween:Restart() + end +end + +function BattleBaseUI:playHpProgressYellowRightTween(time) + if self.hpProgressYellowRightTween == nil then + self.hpProgressYellowRightTween = GFunc.DOBFSliderValue(self.hpProgressYellowRight, self.hpPercentRight, time, false) + self.hpProgressYellowRightTween:SetIntId(GConst.DOTWEEN_IDS.BATTLE) + self.hpProgressYellowRightTween:SetAutoKill(false) + else + self.hpProgressYellowRightTween:ChangeEndValue(self.hpPercentRight, time, true) + self.hpProgressYellowRightTween:Restart() + end +end + +function BattleBaseUI:refreshAtkHp(num, percent) + self.hpTextLeft:setText(GFunc.num2Str(num)) + if not self.isPauseHpProgress then + if self.hpProgressLeftTween then + self.hpProgressLeftTween:Pause() + end + if self.hpProgressYellowLeftTween then + self.hpProgressYellowLeftTween:Pause() + end + if self.hpProgressYellowLeftSid then + self:unscheduleGlobal(self.hpProgressYellowLeftSid) + self.hpProgressYellowLeftSid = nil + end + self.hpProgressLeft.value = percent + self.hpProgressYellowLeft.value = percent + self.hpPercentLeft = percent + return + end + if self.hpPercentLeft == percent then + return + end + self.hpPercentLeft = percent + local time = math.abs(self.hpProgressLeft.value - percent)*2 + if self.hpProgressLeftTween == nil then + self.hpProgressLeftTween = GFunc.DOBFSliderValue(self.hpProgressLeft, percent, time, false) + self.hpProgressLeftTween:SetIntId(GConst.DOTWEEN_IDS.BATTLE) + self.hpProgressLeftTween:SetAutoKill(false) + else + self.hpProgressLeftTween:ChangeEndValue(percent, time, true) + self.hpProgressLeftTween:Restart() + end +end + +function BattleBaseUI:refreshDefHp(num, percent) + self.hpTextRight:setText(GFunc.num2Str(num)) + if not self.isPauseHpProgress then + if self.hpProgressRightTween then + self.hpProgressRightTween:Pause() + end + if self.hpProgressYellowRightTween then + self.hpProgressYellowRightTween:Pause() + end + if self.hpProgressYellowRightSid then + self:unscheduleGlobal(self.hpProgressYellowRightSid) + self.hpProgressYellowRightSid = nil + end + self.hpProgressRight.value = percent + self.hpProgressYellowRight.value = percent + self.hpPercentRight = percent + return + end + if self.hpPercentRight == percent then + return + end + self.hpPercentRight = percent + local time = math.abs(self.hpProgressRight.value - percent)*2 + if self.hpProgressRightTween == nil then + self.hpProgressRightTween = GFunc.DOBFSliderValue(self.hpProgressRight, percent, time, false) + self.hpProgressRightTween:SetIntId(GConst.DOTWEEN_IDS.BATTLE) + self.hpProgressRightTween:SetAutoKill(false) + else + self.hpProgressRightTween:ChangeEndValue(percent, time, true) + self.hpProgressRightTween:Restart() + end +end + +function BattleBaseUI:refreshSkill(elementMap, showSfx, side) + side = side or SIDE_ATK + if not self.skillNodeCells or not self.skillNodeCells[side] then + return + end + + local skillCellMap = self.skillNodeCells[side] + for elementType, skillEntity in pairs(self.battleData:getSkillEntities()) do + local skillCell = skillCellMap[elementType] + if skillCell then + skillCell:refresh(skillEntity, elementMap, showSfx) + end + end +end + + +-- shakeType: 奇数是水平震动 偶数是垂直震动 +function BattleBaseUI:shakeScreen(shakeType, duration) + self.battleRoot:setLocalPosition(0, 0, 0) + if self.shakeTween == nil then + local length = ConfigManager:getConfig("const")["shake_level_" .. math.ceil(shakeType / 2)].value + if shakeType % 2 == 0 then + CacheVector2.x = 0 + CacheVector2.y = length + self.shakeTween = self.battleRoot:getTransform():DOShakeAnchorPos(duration, CacheVector2, 100, 90, false, false) + else + CacheVector2.x = length + CacheVector2.y = 0 + self.shakeTween = self.battleRoot:getTransform():DOShakeAnchorPos(duration, CacheVector2, 100, 90, false, false) + end + self.shakeTween:SetIntId(GConst.DOTWEEN_IDS.BATTLE) + self.shakeTween:SetAutoKill(false) + self.shakeType = shakeType + self.shakeDuration = duration + elseif self.shakeType == shakeType and self.shakeDuration == duration then + self.shakeTween:Restart() + else + self.shakeTween:Kill() + local length = ConfigManager:getConfig("const")["shake_level_" .. math.ceil(shakeType / 2)].value + if shakeType % 2 == 0 then + CacheVector2.x = 0 + CacheVector2.y = length + self.shakeTween = self.battleRoot:getTransform():DOShakeAnchorPos(duration, CacheVector2, 100, 90, false, false) + else + CacheVector2.x = length + CacheVector2.y = 0 + self.shakeTween = self.battleRoot:getTransform():DOShakeAnchorPos(duration, CacheVector2, 100, 90, false, false) + end + self.shakeTween:SetIntId(GConst.DOTWEEN_IDS.BATTLE) + self.shakeTween:SetAutoKill(false) + self.shakeType = shakeType + self.shakeDuration = duration + end + self.shakeTween.timeScale = self.battleData:getTimeScale() +end + +function BattleBaseUI:initGridCell(callback) + self.onInitGridCellOverCallback = callback + if self.root.gridCells then + self.gridCells = self.root.gridCells + self.gridInitOver = true + end + + if self.gridCells and self.gridInitOver then + self:onInitGridCellOver() + return + end + + self.gridCells = {} + local gridEntities = self.battleData:getGridEnties() + self.cellLoadRemianCount = table.nums(gridEntities) + for posId, entity in pairs(gridEntities) do + CellManager:loadCellAsync(GRID_CELL_PATH, GRID_CELL, self.gridNode, function(cell) + self.gridCells[posId] = cell + cell:getBaseObject():setAnchoredPositionX(DEFAULT_X) -- 初始化时放到屏幕外 + + self.cellLoadRemianCount = self.cellLoadRemianCount - 1 + if self.cellLoadRemianCount <= 0 then + self.gridInitOver = true + self:onInitGridCellOver() + self.root.gridCells = self.gridCells + end + end) + end +end + +function BattleBaseUI:onInitGridCellOver() + for posId, cell in pairs(self.gridCells) do + local entity = self.battleData:getGridEntity(posId) + if entity then + cell:hideAni() + cell:setOrder(self:getUIOrder()) + cell:refresh(entity) + cell:addTouchListener(function(eventType) + if self.battleController then + self.battleController:onTouchEvent(eventType, entity:getPosId()) + end + end) + cell:unBindAll() + cell:bind(entity, "isDirty", function() + cell:refresh(entity, self.curElementType) + end) + local pos = entity:getPos() + cell:getBaseObject():setAnchoredPosition(pos.x, pos.y) + entity:setCell(cell) + end + end + + local callback = self.onInitGridCellOverCallback + self.onInitGridCellOverCallback = nil + if callback then + callback() + end +end + +function BattleBaseUI:switchBoard(downCallback, callback, isFirst) + if isFirst then + if downCallback then + downCallback() + end + if callback then + callback() + end + return + end + + if downCallback then + downCallback() + end + + if callback then + callback() + end +end + +function BattleBaseUI:showBoardMask(elementType, skillPosId) + if not self.gridCells then + return + end + if self.curElementType == elementType and self.skillPosId == skillPosId then + return + end + + self.curElementType = elementType + self.skillPosId = skillPosId + self:refreshBoard() +end + +function BattleBaseUI:refreshBoard() + local entities = self.battleData:getGridEnties() + for posId, entity in pairs(entities) do + if entity and entity:getCell() then + entity:getCell():refresh(entity, self.curElementType, self.skillPosId) + end + end +end + +function BattleBaseUI:eliminationAni(aniSequence, effectGridMap, callback, side) + self:showMask(true) + if not aniSequence then + if callback then + callback() + end + return + end + + self.boardMask:getTransform():SetAsLastSibling() + if self.eliminationAniSeq then + self.eliminationAniSeq:Kill() + self.eliminationAniSeq = nil + end + + self.eliminationAniSeq = self.root:createBindTweenSequence() + self.eliminationAniSeq:AppendCallback(function() + if self.boardMask2D then + self.boardMask2D.enabled = false + end + end) + + if not self.posIdMap then + self.posIdMap = {} + end + + local breakSfxNameIndexMap = {} + for index, info in ipairs(aniSequence) do + if not self.posIdMap[info.posId] then + local pos = ModuleManager.BattleManager:getPosInfo(info.posId) + self.posIdMap[info.posId] = true + local entity = self.battleData:getGridEntity(info.posId) + + local time = info.timeIdx + if entity and entity:getCell() then + entity:getCell():refresh(entity) + + if info.callback then + self.eliminationAniSeq:InsertCallback(time, function() + if info.callback then + info.callback() + end + end) + end + + self:dealGridBreakSfx(time, info, breakSfxNameIndexMap) + self:dealGridEffectSfx(time, info, breakSfxNameIndexMap, entity) + + time = time + (info.bftcTime or 0) + if info.isIdle then + if entity:getSkillId() then + entity:getCell():hideSkillSfx() + end + local baseObject = entity:getCell():getBaseObject() + baseObject:getTransform():SetAsLastSibling() + local anitime = 0 + if info.aniPosList then + local posList = {} + local count = 0 + for _, posId in ipairs(info.aniPosList) do + table.insert(posList, ModuleManager.BattleManager:getPosInfo(posId)) + count = count + 1 + end + anitime = count * GConst.BattleConst.GRID_BREAK_EFFECT_INTERVAL + self.eliminationAniSeq:Insert(time, baseObject:getTransform():DOLocalPath(posList, anitime):SetEase(CS.DG.Tweening.Ease.Linear)) + else + if info.noAni then + self.eliminationAniSeq:InsertCallback(time, function() + baseObject:setAnchoredPositionX(DEFAULT_X) + end) + else + if info.rangeList then + self.eliminationAniSeq:InsertCallback(time, function() + self:playSkillLineSfx(info.posId, info.rangeList, info.randomPosList) + end) + end + self.eliminationAniSeq:Insert(time, baseObject:getTransform():DOScale(1.3, 0.1)) + self.eliminationAniSeq:InsertCallback(time + 0.2, function() + self:getSfxSmoke(index, function(obj) + obj:setAnchoredPosition(pos.x, pos.y) + obj:play() + end) + end) + local targetPos = self:getElementSkillPos(entity:getElementType(), side) + if info.breakFlyToCharacter then + targetPos = self.battleController.atkTeam:getMainUnit():getBaseObject():getTransform().position + local sPoint = UIManager:getUICameraComponent():WorldToScreenPoint(targetPos) + targetPos = CS.BF.Utils.RectTransformScreenPointToLocalPointInRectangle(self.boardNode:getTransform(), sPoint.x, sPoint.y, UIManager:getUICameraComponent()) + end + self.eliminationAniSeq:Insert(time + 0.2, baseObject:getTransform():DOAnchorPos(targetPos, 0.3)) + self.eliminationAniSeq:Insert(time + 0.2, baseObject:getTransform():DOScale(0.5, 0.3)) + anitime = 0.5 + end + end + self.eliminationAniSeq:InsertCallback(time + anitime, function() + baseObject:setAnchoredPositionX(DEFAULT_X) + if info.overCallback then + info.overCallback() + end + end) + end + end + end + end + + local list + for posId, _ in pairs(effectGridMap) do + local entity = self.battleData:getGridEntity(posId) + local baseObject = entity:getCell():getBaseObject() + baseObject:getTransform():SetAsLastSibling() + if MAX_LASTSIBLING_TYPE[entity:getGridType()] then + if not list then + list = {} + end + table.insert(list, baseObject) + end + end + + if list then + for _, baseObject in ipairs(list) do + baseObject:getTransform():SetAsLastSibling() + end + end + + self.eliminationAniSeq:AppendCallback(function() + for posId, _ in pairs(self.posIdMap) do + local entity = self.battleData:getGridEntity(posId) + + if entity and entity:getCell() then + entity:getCell():hideAni() + end + end + + self.posIdMap = {} + if self.boardMask2D then + self.boardMask2D.enabled = true + end + + if callback then + callback() + end + + self:refreshSkill() + self:resetParentAllSfxGridBreak() + self.eliminationAniSeq = nil + end) +end + +function BattleBaseUI:dealGridBreakSfx(time, info, breakSfxNameIndexMap) + if info.breakSfxName then + breakSfxNameIndexMap[info.breakSfxName] = (breakSfxNameIndexMap[info.breakSfxName] or 0) + 1 + local breakIndex = breakSfxNameIndexMap[info.breakSfxName] + self.eliminationAniSeq:InsertCallback(time, function() + self:getSfxGridBreak(info.breakSfxName, breakIndex, function(obj) + local pos = ModuleManager.BattleManager:getPosInfo(info.posId) + obj:setLocalPosition(pos.x, pos.y, 0) + obj:play() + end) + end) + end +end + +function BattleBaseUI:dealGridEffectSfx(time, info, breakSfxNameIndexMap, entity) + if not self.eliminationAniSeq then + return + end + + self.flowEffects = table.clearOrCreate(self.flowEffects) + if info.effectSfxName then + breakSfxNameIndexMap[info.effectSfxName] = (breakSfxNameIndexMap[info.effectSfxName] or 0) + 1 + local breakIndex = breakSfxNameIndexMap[info.effectSfxName] + self.eliminationAniSeq:InsertCallback(time, function() + self:getSfxGridBreak(info.effectSfxName, breakIndex, function(obj) + if not self.eliminationAniSeq then -- 动画已结束 + obj:setActive(false) + return + end + if info.effectSfxFlow then + obj:setParent(entity:getCell():getBaseObject(), false) + obj:setLocalPosition(0, 0, 0) + obj:play() + table.insert(self.flowEffects, obj) + else + local pos = ModuleManager.BattleManager:getPosInfo(info.posId) + obj:setLocalPosition(pos.x, pos.y, 0) + obj:play() + end + if info.effectSfxDir == GConst.BattleConst.BOARD_RANGE_TYPE.UP then + obj:setLocalEulerAngles(0, 0, 0) + elseif info.effectSfxDir == GConst.BattleConst.BOARD_RANGE_TYPE.DOWN then + obj:setLocalEulerAngles(0, 0, 180) + elseif info.effectSfxDir == GConst.BattleConst.BOARD_RANGE_TYPE.LEFT then + obj:setLocalEulerAngles(0, 0, 90) + elseif info.effectSfxDir == GConst.BattleConst.BOARD_RANGE_TYPE.RIGHT then + obj:setLocalEulerAngles(0, 0, -90) + else + obj:setLocalEulerAngles(0, 0, 0) + end + end) + end) + end +end + +function BattleBaseUI:showGridEffectSfx(posId, sfxName, callback, customTime, zEuler) + self:getSfxGridEffect(sfxName, function(info) + info.isIdle = false + local pos = ModuleManager.BattleManager:getPosInfo(posId) + customTime = customTime or info.obj:getDuration() + info.obj:setLocalPosition(pos.x, pos.y, 0) + info.obj:setLocalEulerAngles(0, 0, zEuler) + info.obj:setActive(true) + info.obj:playComplete(function() + info.isIdle = true + info.obj:setActive(false) + end, customTime, function() + if callback then + callback() + end + end) + end) +end + +function BattleBaseUI:moveGridCells(gridEntityList, callback) + if not gridEntityList then + if callback then + callback() + end + end + + if self.moveGridCellsSeq then + self.moveGridCellsSeq:Kill() + self.moveGridCellsSeq = nil + end + + self.moveGridCellsSeq = self.root:createBindTweenSequence() + for _, entity in pairs(gridEntityList) do + local posId = entity:getPosId() + local baseObject = entity:getCell():getBaseObject() + local pos = ModuleManager.BattleManager:getPosInfo(posId) + if entity:getEffectType() then + baseObject:getTransform():SetAsLastSibling() + end + self.moveGridCellsSeq:Insert(0, baseObject:getTransform():DOLocalMove(pos, 1)) + end + self.moveGridCellsSeq:AppendCallback(function() + if callback then + callback() + end + end) +end + +function BattleBaseUI:generateSkillAni(map, callback, side) + if table.nums(map) <= 0 or table.nums(self.generateSkillGridEntities) <= 0 then + if callback then + callback() + end + return + end + + self:hideGenerateSkillGridCells() + if self.generateSkillAniSeq then + self.generateSkillAniSeq:Kill() + self.generateSkillAniSeq = nil + end + + self.generateSkillAniSeq = self.root:createBindTweenSequence() + local count = 0 + for elementType, info in pairs(map) do + local entity = self.generateSkillGridEntities[elementType] + if entity and entity:getCell() then + count = count + 1 + entity:setSkilId(info.skillId) + local cell = entity:getCell() + cell:refresh(entity) + self.generateSkillAniSeq:AppendCallback(function() + local pos = self:getElementSkillPos(elementType, side) + cell:getBaseObject():setAnchoredPosition(pos.x, pos.y) + end) + local pos = ModuleManager.BattleManager:getPosInfo(info.posId) + self.generateSkillAniSeq:Append(cell:getBaseObject():getTransform():DOAnchorPos(pos, 0.5)) + if self.generateSkillSfxs and self.generateSkillSfxs[count] then + self.generateSkillSfxs[count]:setAnchoredPosition(pos.x, pos.y) + self.generateSkillAniSeq:AppendCallback(function() + self.generateSkillSfxs[count]:setActive(true) + self.generateSkillSfxs[count]:play() + end) + end + end + end + self.generateSkillAniSeq:AppendCallback(function() + if callback then + callback() + end + self:hideGenerateSkillGridCells() + end) +end + +function BattleBaseUI:_hideGenerateSkillGridCells(generateSkillCellPrefix) + if not self.generateSkillGridEntities then + local uiMap = self.root:genAllChildren() + self.generateSkillGridEntities = {} + if generateSkillCellPrefix then + for name, elementType in pairs(GConst.BattleConst.ELEMENT_TYPE) do + local obj = uiMap[generateSkillCellPrefix .. elementType] + if obj then + local cell = CellManager:addCellComp(obj, GRID_CELL) + local entity = self.battleData:getNewGridEntity() + entity:setCell(cell) + self.generateSkillGridEntities[elementType] = entity + end + end + end + end + + for _, entity in pairs(self.generateSkillGridEntities) do + if entity:getCell() then + entity:getCell():getBaseObject():setAnchoredPositionX(DEFAULT_X) + end + end +end + +function BattleBaseUI:_initGenerateSkillEffect(generateSkillEffecPrefix) + if not self.generateSkillSfxs then + local uiMap = self.root:genAllChildren() + self.generateSkillSfxs = {} + if generateSkillEffecPrefix then + for i = 1, 5 do + self.generateSkillSfxs[i] = uiMap[generateSkillEffecPrefix .. i] + end + end + end + + for _, obj in pairs(self.generateSkillSfxs) do + obj:setActive(true) + obj:getComponent(GConst.TYPEOF_UNITY_CLASS.BF_EFFECT_HELPER):SetSortingOrder(self:getUIOrder(), GConst.UI_EFFECT_ORDER.LEVEL5) + obj:setActive(false) + end +end + +function BattleBaseUI:_initSkillLineSfx() + for _, obj in pairs(self.skillLineSfxs) do + obj:setActive(true) + obj:getComponent(GConst.TYPEOF_UNITY_CLASS.BF_EFFECT_HELPER):SetSortingOrder(self:getUIOrder(), GConst.UI_EFFECT_ORDER.LEVEL5) + obj:setActive(false) + end + + for _, obj in pairs(self.skillLightSfxs) do + obj:setActive(true) + obj:getComponent(GConst.TYPEOF_UNITY_CLASS.BF_EFFECT_HELPER):SetSortingOrder(self:getUIOrder(), GConst.UI_EFFECT_ORDER.LEVEL5) + obj:setActive(false) + end +end + +function BattleBaseUI:showMonsterSkillAni(map, monsterPos, callback) + if table.nums(map) <= 0 or table.nums(self.monsterSkillGridEntities) <= 0 then + if callback then + callback() + end + return + end + + self:hideMonsterSkillGridCells() + if self.monsterSkillAniSeq then + self.monsterSkillAniSeq:Kill() + self.monsterSkillAniSeq = nil + end + + local sPoint = UIManager:getUICameraComponent():WorldToScreenPoint(monsterPos) + monsterPos = CS.BF.Utils.RectTransformScreenPointToLocalPointInRectangle(self.boardNode:getTransform(), sPoint.x, sPoint.y, UIManager:getUICameraComponent()) + + self.monsterSkillAniSeq = self.root:createBindTweenSequence() + local count = 1 + for posId, info in pairs(map) do + local entity = self.monsterSkillGridEntities[count] + if entity and entity:getCell() then + entity:setGridType(info.gridType) + entity:setElementType(GConst.BattleConst.ELEMENT_TYPE.EMPTY) + count = count + 1 + local cell = entity:getCell() + cell:refresh(entity) + cell:getBaseObject():setAnchoredPosition(monsterPos.x, monsterPos.y) + cell:getBaseObject():setLocalScale(0.3, 0.3, 0.3) + local pos = ModuleManager.BattleManager:getPosInfo(posId) + if count == 1 then + self.monsterSkillAniSeq:Append(cell:getBaseObject():getTransform():DOAnchorPos(pos, 0.3)) + else + self.monsterSkillAniSeq:Join(cell:getBaseObject():getTransform():DOAnchorPos(pos, 0.3)) + end + self.monsterSkillAniSeq:Join(cell:getBaseObject():getTransform():DOScale(1, 0.3)) + end + end + self.monsterSkillAniSeq:AppendCallback(function() + if callback then + callback() + end + self:hideMonsterSkillGridCells() + end) +end + +function BattleBaseUI:hideMonsterSkillGridCells() + if not self.monsterSkillGridEntities then + local uiMap = self.root:genAllChildren() + self.monsterSkillGridEntities = {} + -- for name, elementType in pairs(GConst.BattleConst.ELEMENT_TYPE) do + -- local obj = uiMap["battle_ui.bg_2.ani_node.grid_cell_m" .. elementType] + -- if obj then + -- local cell = CellManager:addCellComp(obj, GRID_CELL) + -- local entity = DataManager.BattleData:getNewGridEntity() + -- entity:setCell(cell) + -- table.insert(self.monsterSkillGridEntities, entity) + -- end + -- end + end + + for _, entity in ipairs(self.monsterSkillGridEntities) do + if entity:getCell() then + entity:getCell():getBaseObject():setAnchoredPositionX(DEFAULT_X) + end + end +end + +function BattleBaseUI:gotOneSkillAni(skillId, elementType, callback, startPos, side) + if not skillId or not self.skillSelectCell then + if callback then + callback() + end + return + end + + self.skillSelectCell:refresh(skillId) + self.skillSelectCell:getBaseObject():setAnchoredPosition(startPos.x, startPos.y) + self.skillSelectCell:getBaseObject():setVisible(true) + if self.gotOneSkillAniSeq then + self.gotOneSkillAniSeq:Kill() + self.gotOneSkillAniSeq = nil + end + + self.gotOneSkillAniSeq = self.root:createBindTweenSequence() + local pos = self:getElementSkillPos(elementType, side) + self.gotOneSkillAniSeq:Append(self.skillSelectCell:getBaseObject():getTransform():DOAnchorPos(pos, 0.7)) + self.gotOneSkillAniSeq:Join(self.skillSelectCell:getBaseObject():getTransform():DOScale(0.76, 0.7)) + self.gotOneSkillAniSeq:AppendCallback(function() + self.skillSelectCell:getBaseObject():setAnchoredPositionX(DEFAULT_X) + if callback then + callback() + end + end) +end + +function BattleBaseUI:shuffleBoard(changeInfo, callback) + if self.shuffleBoardSeq then + self.shuffleBoardSeq:Kill() + self.shuffleBoardSeq = nil + end + + self.shuffleBoardSeq = self.root:createBindTweenSequence() + for posId, tartgetPos in pairs(changeInfo) do + local entity = self.battleData:getGridEntity(posId) + local cell = entity:getCell() + local posId = entity:getPosId() + if cell then + local pos = ModuleManager.BattleManager:getPosInfo(posId) + self.shuffleBoardSeq:Insert(0, cell:getBaseObject():getTransform():DOAnchorPos(pos, 1)) + end + end + self.shuffleBoardSeq:AppendCallback(function() + if callback then + callback() + end + end) +end + +function BattleBaseUI:removeGridOutOfScreen(posIdList) + for _, posId in ipairs(posIdList) do + self:removeOneGridOutOfScreen(posId) + end +end + +function BattleBaseUI:removeOneGridOutOfScreen(posId) + local entity = self.battleData:getGridEntity(posId) + local cell = entity:getCell() + cell:getBaseObject():setAnchoredPositionX(DEFAULT_X) +end + +function BattleBaseUI:fallGrid(listInfo, isRoundBeginCheck, callback) + if isRoundBeginCheck then + self:showMask(false) + else + self.boardMask:getTransform():SetAsLastSibling() + end + self.fallAniCount = 0 + for posId, info in pairs(listInfo) do + local entity = self.battleData:getGridEntity(posId) + local cell = entity:getCell() + if cell then + self.fallAniCount = self.fallAniCount + 1 + if cell.fallSeq then + cell.fallSeq:Kill() + cell.fallSeq = nil + end + local baseObject = cell:getBaseObject() + cell.fallSeq = baseObject:createBindTweenSequence() + baseObject:setAnchoredPosition(info[1].x, info[1].y) + local count = #info + local time = GConst.BattleConst.ONE_STEP_TIME * count + cell.fallSeq:Append(baseObject:getTransform():DOLocalPath(info, time):SetEase(CS.DG.Tweening.Ease.InQuad)) + cell.fallSeq:AppendCallback(function() + self.fallAniCount = self.fallAniCount - 1 + if self.fallAniCount == 0 then + if callback then + callback() + end + end + end) + cell.fallSeq:InsertCallback(time + math.random() * 0.1 - 0.2, function() + cell:showAni() + end) + end + end + if self.fallAniCount == 0 and callback then + callback() + end +end + +function BattleBaseUI:cacheSkillAni(skillInfo, isPop, callback) + local skillInfoCount = #skillInfo + if skillInfoCount <= 0 then + if callback then + callback() + end + return + end + + self:disableUITouch() + + if not self.root.skillAniGridEntities then + self.root.skillAniGridEntities = {} + end + + for _, entity in ipairs(self.root.skillAniGridEntities) do + local cell = entity:getCell() + if cell then + cell:getBaseObject():setAnchoredPositionX(DEFAULT_X) -- 放到屏幕外 + end + end + + local gridEntityCount = #self.root.skillAniGridEntities + if gridEntityCount < skillInfoCount then + for i = gridEntityCount, skillInfoCount do + CellManager:loadCellAsync(GRID_CELL_PATH, GRID_CELL, self.boardCacheNode, function(cell) + cell:getBaseObject():setAnchoredPositionX(DEFAULT_X) -- 初始化时放到屏幕外 + local entity = self.battleData:getNewGridEntity() + entity:setCell(cell) + cell:hideAni() + table.insert(self.root.skillAniGridEntities, entity) + if i == skillInfoCount then + if isPop then + self:doCachePopAni(skillInfo, callback) + else + self:doCacheAni(skillInfo, callback) + end + end + end) + end + else + if isPop then + self:doCachePopAni(skillInfo, callback) + else + self:doCacheAni(skillInfo, callback) + end + end +end + +function BattleBaseUI:doCacheAni(skillInfo, callback) + if self.cacheSkillAniSeq then + self.cacheSkillAniSeq:Kill() + self.cacheSkillAniSeq = nil + end + + if not self.root.skillAniGridEntities then + if callback then + callback() + end + return + end + + self.boardCacheNode:setVisible(true) + + local w, h = GFunc.getUIExpandScreenSize() + local w = w / 2 + 100 + self.cacheSkillAniSeq = self.root:createBindTweenSequence() + self.cacheSkillAniSeq:AppendCallback(function() + self.boardCacheBox:setAnchoredPositionX(- w) + end) + + for index, info in ipairs(skillInfo) do + local entity = self.root.skillAniGridEntities[index] + if entity then + entity:setSkilId(info.skillId) + local pos = ModuleManager.BattleManager:getPosInfo(info.posId) + local cell = entity:getCell() + if cell then + cell:refresh(entity) + local obj = cell:getBaseObject() + self.cacheSkillAniSeq:InsertCallback(0.5 * (index - 1), function() + obj:setAnchoredPosition(pos.x, pos.y) + local gridEntity = self.battleData:getGridEntity(info.posId) + if gridEntity and gridEntity:getCell() then + gridEntity:getCell():getBaseObject():setAnchoredPositionX(DEFAULT_X) -- 放到屏幕外 + end + end) + + self.cacheSkillAniSeq:Insert(0.5 * (index - 1) + 0.02, obj:getTransform():DOAnchorPos(CACHE_SKILL_POS_2, 0.7)) + end + end + end + + self.cacheSkillAniSeq:Append(self.boardCacheBox:getTransform():DOAnchorPosX(0, 0.5)) + for index, info in ipairs(skillInfo) do + local entity = self.root.skillAniGridEntities[index] + if entity then + local cell = entity:getCell() + if cell then + local obj = cell:getBaseObject() + if index == 1 then + self.cacheSkillAniSeq:Append(obj:getTransform():DOAnchorPos(CACHE_SKILL_POS_1, 0.3)) + else + self.cacheSkillAniSeq:Join(obj:getTransform():DOAnchorPos(CACHE_SKILL_POS_1, 0.3)) + end + end + end + end + self.cacheSkillAniSeq:AppendCallback(function() + for index, entity in ipairs(self.root.skillAniGridEntities) do + if entity and entity:getCell() then + entity:getCell():getBaseObject():setAnchoredPositionX(DEFAULT_X) + end + end + end) + self.cacheSkillAniSeq:Append(self.boardCacheBox:getTransform():DOAnchorPosX(w, 0.5)) + self.cacheSkillAniSeq:AppendCallback(function() + self.boardCacheNode:setVisible(false) + self:enableUITouch() + if callback then + callback() + end + end) +end + +function BattleBaseUI:doCachePopAni(skillInfo, callback) + if self.cacheSkillAniSeq then + self.cacheSkillAniSeq:Kill() + self.cacheSkillAniSeq = nil + end + + if not self.root.skillAniGridEntities then + if callback then + callback() + end + return + end + + self.boardCacheNode:setVisible(true) + local w, h = GFunc.getUIExpandScreenSize() + local w = w / 2 + 100 + self.cacheSkillAniSeq = self.root:createBindTweenSequence() + self.cacheSkillAniSeq:AppendCallback(function() + self.boardCacheBox:setAnchoredPositionX(- w) + end) + self.cacheSkillAniSeq:Append(self.boardCacheBox:getTransform():DOAnchorPosX(0, 0.5)) + for index, info in ipairs(skillInfo) do + local entity = self.root.skillAniGridEntities[index] + if entity then + entity:setSkilId(info.skillId) + local pos = ModuleManager.BattleManager:getPosInfo(info.posId) + local cell = entity:getCell() + if cell then + cell:refresh(entity) + local obj = cell:getBaseObject() + self.cacheSkillAniSeq:InsertCallback(0, function() + obj:setAnchoredPositionX(DEFAULT_X) + end) + self.cacheSkillAniSeq:InsertCallback(0.5 + 0.5 * (index - 1), function() + obj:setAnchoredPosition(CACHE_SKILL_POS_1.x, CACHE_SKILL_POS_1. y) + end) + + self.cacheSkillAniSeq:Insert(0.5 + 0.5 * (index - 1) + 0.02, obj:getTransform():DOAnchorPos(CACHE_SKILL_POS_2, 0.3)) + end + end + end + self.cacheSkillAniSeq:Append(self.boardCacheBox:getTransform():DOAnchorPosX(w, 0.5)) + + for index, info in ipairs(skillInfo) do + local entity = self.root.skillAniGridEntities[index] + if entity then + local pos = ModuleManager.BattleManager:getPosInfo(info.posId) + local cell = entity:getCell() + if cell then + local obj = cell:getBaseObject() + if index == 1 then + self.cacheSkillAniSeq:Append(obj:getTransform():DOAnchorPos(pos, 0.7)) + else + self.cacheSkillAniSeq:Join(obj:getTransform():DOAnchorPos(pos, 0.7)) + end + end + end + end + + self.cacheSkillAniSeq:AppendCallback(function() + self.boardCacheNode:setVisible(false) + self:enableUITouch() + if callback then + callback() + end + end) +end + +function BattleBaseUI:showMask(show) + if not self.boardMask then + return + end + self.boardMask:setVisible(show) +end + +function BattleBaseUI:getElementSkillPos(elementType, side) + side = side or SIDE_ATK + if not self.skillPoss then + self.skillPoss = { + [SIDE_ATK] = {}, + [SIDE_DEF] = {}, + } + end + + if not self.skillPoss[side][elementType] then + local cell = self.skillNodeCells[side][elementType] + if not cell then + self.skillPoss[side][elementType] = BF.Vector2(0, 0) + else + local targetPos = cell:getBaseObject():getTransform().position + local sPoint = UIManager:getUICameraComponent():WorldToScreenPoint(targetPos) + targetPos = CS.BF.Utils.RectTransformScreenPointToLocalPointInRectangle(self.boardNode:getTransform(), sPoint.x, sPoint.y, UIManager:getUICameraComponent()) + self.skillPoss[side][elementType] = targetPos + end + end + + return self.skillPoss[side][elementType] +end + +function BattleBaseUI:refreshWave(wave, iconAtlas, iconName) +end + +function BattleBaseUI:getSfxLine(index, func) + self.hidingAllSfxLine = false + + if not self.root.lineSfxObjs then + self.root.lineSfxObjs = {} + end + if self.root.lineSfxObjs[index] then + if self.root.lineSfxObjs[index].obj and func then + local obj = self.root.lineSfxObjs[index].obj + obj:setActive(true) + func(obj) + end + else + self.root.lineSfxObjs[index] = { + isLoaded = true + } + EffectManager:loadUIEffectAsync(GConst.BattleConst.LINE_SFX, self, self.gridNode, BOARD_SFX_ORDER, function(obj) + self.root.lineSfxObjs[index].obj = obj + if self.hidingAllSfxLine then + obj:setActive(false) + else + if func then + func(obj) + end + end + end) + end +end + +function BattleBaseUI:hideAllSfxLine() + self.hidingAllSfxLine = true + if not self.root.lineSfxObjs then + return + end + for inde, info in pairs(self.root.lineSfxObjs) do + if info.obj then + info.obj:setActive(false) + end + end +end + +function BattleBaseUI:resetParentAllSfxGridBreak() + if not self.flowEffects then + return + end + + for _, obj in ipairs(self.flowEffects) do + obj:setActive(false) + obj:setParent(self.gridNode, true) + end +end + +function BattleBaseUI:getSfxGridBreak(breakSfxPath, index, func) + if not breakSfxPath then + return + end + + self.hidingAllSfxGridBreak = false + + if not self.root.gridBreakSfxObjs then + self.root.gridBreakSfxObjs = {} + end + if not self.root.gridBreakSfxObjs[breakSfxPath] then + self.root.gridBreakSfxObjs[breakSfxPath] = {} + end + if self.root.gridBreakSfxObjs[breakSfxPath][index] then + if self.root.gridBreakSfxObjs[breakSfxPath][index].obj and func then + local obj = self.root.gridBreakSfxObjs[breakSfxPath][index].obj + obj:setActive(true) + func(obj) + end + else + self.root.gridBreakSfxObjs[breakSfxPath][index] = { + isLoaded = true + } + EffectManager:loadUIEffectAsync(breakSfxPath, self, self.gridNode, GConst.UI_EFFECT_ORDER.LEVEL5, function(obj) + self.root.gridBreakSfxObjs[breakSfxPath][index].obj = obj + if self.hidingAllSfxGridBreak then + obj:setActive(false) + else + if func then + func(obj) + end + end + end) + end +end + +function BattleBaseUI:hideAllSfxGridBreak() + self.hidingAllSfxLine = false + if not self.root.gridBreakSfxObjs then + return + end + for breakSfxPath, map in pairs(self.root.gridBreakSfxObjs) do + for index, info in pairs(map) do + if info.obj then + info.obj:setParent(self.gridNode, false) + info.obj:setActive(false) + end + end + end +end + +function BattleBaseUI:getSfxGridEffect(effectSfxPath, func) + if not effectSfxPath then + return + end + + if not self.root.gridEffectSfx then + self.root.gridEffectSfx = {} + end + if not self.root.gridEffectSfx[effectSfxPath] then + self.root.gridEffectSfx[effectSfxPath] = {} + end + local count = 0 + for index, info in pairs(self.root.gridEffectSfx[effectSfxPath]) do + if info.isIdle then + func(self.root.gridEffectSfx[effectSfxPath][index]) + return + end + count = count + 1 + end + + local index = count + 1 + self.root.gridEffectSfx[effectSfxPath][index] = { + isLoaded = true, + } + EffectManager:loadUIEffectAsync(effectSfxPath, self, self.gridNode, GConst.UI_EFFECT_ORDER.LEVEL5, function(obj) + self.root.gridEffectSfx[effectSfxPath][index].obj = obj + self.root.gridEffectSfx[effectSfxPath][index].isIdle = true + if func then + func(self.root.gridEffectSfx[effectSfxPath][index]) + end + end) +end + +function BattleBaseUI:getSfxSmoke(index, func) + self.hidingAllSfxSmoke = false + + if not self.root.smokeSfxObjs then + self.root.smokeSfxObjs = {} + end + if self.root.smokeSfxObjs[index] then + if self.root.smokeSfxObjs[index].obj and func then + local obj = self.root.smokeSfxObjs[index].obj + obj:setActive(true) + func(obj) + end + else + self.root.smokeSfxObjs[index] = { + isLoaded = true + } + EffectManager:loadUIEffectAsync(GConst.BattleConst.LINK_SMOKE, self, self.gridNode, BOARD_SFX_ORDER, function(obj) + self.root.smokeSfxObjs[index].obj = obj + obj:setLocalScale(1.5, 1.5, 1.5) + if self.hidingAllSfxSmoke then + obj:setActive(false) + else + if func then + func(obj) + end + end + end) + end +end + +function BattleBaseUI:hideAllSfxSmoke() + self.hidingAllSfxSmoke = true + if not self.root.smokeSfxObjs then + return + end + for inde, info in pairs(self.root.smokeSfxObjs) do + if info.obj then + info.obj:setActive(false) + end + end +end + +function BattleBaseUI:showSelectSkillComp(skillList, isCommon) + if not self.selectSkillComp then + return + end + self.selectSkillComp:refresh(skillList, isCommon) +end + +function BattleBaseUI:showCommonSkillTips(skillId) + if not self.skillDescTipsNode then + return + end + -- 需要合并显示 + local rogueCfg = ConfigManager:getConfig("skill_rogue") + local curCfg = rogueCfg[skillId] + if not curCfg or curCfg.universal ~= 1 then + return + end + + local value = 0 + local selectSkillMap = DataManager.BattleData:getSelectSkillMap() + if selectSkillMap[skillId] then + value = selectSkillMap[skillId].value + end + + if curCfg.toast_mark then + for id, info in pairs(rogueCfg) do + if selectSkillMap[id] and id ~= skillId and info.toast_mark == curCfg.toast_mark then + value = value + selectSkillMap[id].value + end + end + end + + + if self.showCommonSkillTipsSid then + self:unscheduleGlobal(self.showCommonSkillTipsSid) + self.showCommonSkillTipsSid = nil + end + self.skillDescTipsNode:setVisible(true) + self.skillDescTips:setText(ModuleManager.HeroManager:getSkillRogueDesc(skillId, value)) + self.showCommonSkillTipsSid = self:performWithDelayGlobal(function() + self.skillDescTipsNode:setVisible(false) + end, 1.5) +end + +function BattleBaseUI:showBossEnterAni(bornTime, bossName, monsterComp, callback) + if not self.bossEnterNode then + if callback then + callback() + end + self.battleController:showBuffTips(SIDE_DEF, true) + return + end + AudioManager:playEffect(AudioManager.EFFECT_ID.BOSS_WARNING) + self.bossEnterNode:setVisible(true) + self.bossEnterImg:setVisible(false) + self.bossName:setText(bossName) + self.bossName:setAnchoredPositionX(-756) + self.bossEnterNodeCanvasGroup.alpha = 0 + monsterComp:getBaseObject():setLocalPosition(DEFAULT_X, 0, 0) + if self.bossEnterAniSeq then + self.bossEnterAniSeq:Kill() + self.bossEnterAniSeq = nil + end + self.bossEnterAniSeq = self.root:createBindTweenSequence() + self.bossEnterAniSeq:Append(self.bossEnterNodeCanvasGroup:DOFade(1, 0.2)) + self.bossEnterAniSeq:AppendCallback(function() + self.bossEnterImg:setVisible(true) + self.bossEnterImg:playAnim("idle", false, true) + -- CS.UnityEngine.Animator.StringToHash("born") 结果是1155742626 + self.bossEnterNodeAnimator.enabled = true + self.bossEnterNodeAnimator:Play(1155742626, -1, 0) + monsterComp:initPosition() + monsterComp:getBaseObject():setParent(self.maxLayerNode, false) + if callback then + callback() + end + end) + self.bossEnterAniSeq:AppendInterval(2) + self.bossEnterAniSeq:Append(self.bossEnterNodeCanvasGroup:DOFade(0, 0.2)) + self.bossEnterAniSeq:AppendCallback(function() + monsterComp:getBaseObject():setParent(self:getBattleNode(), false) + self.bossEnterNode:setVisible(false) + self.battleController:showBuffTips(SIDE_DEF, true) + self.bossEnterNodeAnimator.enabled = false + end) +end + +function BattleBaseUI:clear() + if self.alreadyClear then + return + end + self.alreadyClear = true + if self.battleNode then + self.battleNode:removeAllChildren() + end + if self.fxNode then + self.fxNode:removeAllChildren() + end + if self.battleNumberNode then + self.battleNumberNode:removeAllChildren() + end + if self.hpProgressYellowLeftSid then + self:unscheduleGlobal(self.hpProgressYellowLeftSid) + self.hpProgressYellowLeftSid = nil + end + if self.hpProgressYellowRightSid then + self:unscheduleGlobal(self.hpProgressYellowRightSid) + self.hpProgressYellowRightSid = nil + end + if self.hpProgressLeftTween then + self.hpProgressLeftTween:Kill() + self.hpProgressLeftTween = nil + end + if self.hpProgressYellowLeftTween then + self.hpProgressYellowLeftTween:Kill() + self.hpProgressYellowLeftTween = nil + end + if self.hpProgressRightTween then + self.hpProgressRightTween:Kill() + self.hpProgressRightTween = nil + end + if self.hpProgressYellowRightTween then + self.hpProgressYellowRightTween:Kill() + self.hpProgressYellowRightTween = nil + end + if self.bgMoveTween then + self.bgMoveTween:Kill() + self.bgMoveTween = nil + end + if self.shakeTween then + self.shakeTween:Kill() + self.shakeTween = nil + end + + if self.showTutorialFingerSeq then + self.showTutorialFingerSeq:Kill() + self.showTutorialFingerSeq = nil + end + + if self.switchBoardSeq then + self.switchBoardSeq:Kill() + self.switchBoardSeq = nil + end + + if self.eliminationAniSeq then + self.eliminationAniSeq:Kill() + self.eliminationAniSeq = nil + end + + if self.generateSkillAniSeq then + self.generateSkillAniSeq:Kill() + self.generateSkillAniSeq = nil + end + + if self.gotOneSkillAniSeq then + self.gotOneSkillAniSeq:Kill() + self.gotOneSkillAniSeq = nil + end + + if self.shuffleBoardSeq then + self.shuffleBoardSeq:Kill() + self.shuffleBoardSeq = nil + end + + if self.gridCells then + for _, cell in pairs(self.gridCells) do + if cell.fallSeq then + cell.fallSeq:Kill() + cell.fallSeq = nil + end + end + end + + if self.cacheSkillAniSeq then + self.cacheSkillAniSeq:Kill() + self.cacheSkillAniSeq = nil + end + + if self.monsterSkillAniSeq then + self.monsterSkillAniSeq:Kill() + self.monsterSkillAniSeq = nil + end + + if self.showCommonSkillTipsSid then + self:unscheduleGlobal(self.showCommonSkillTipsSid) + self.showCommonSkillTipsSid = nil + end + + if self.autoCloseBuffSid then + self:unscheduleGlobal(self.autoCloseBuffSid) + self.autoCloseBuffSid = nil + end + + if self.bossEnterAniSeq then + self.bossEnterAniSeq:Kill() + self.bossEnterAniSeq = nil + end + + if self.moveGridCellsSeq then + self.moveGridCellsSeq:Kill() + self.moveGridCellsSeq = nil + end +end + +return BattleBaseUI \ No newline at end of file diff --git a/lua/app/ui/battle/battle_base_ui.lua.meta b/lua/app/ui/battle/battle_base_ui.lua.meta new file mode 100644 index 00000000..09d383f7 --- /dev/null +++ b/lua/app/ui/battle/battle_base_ui.lua.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 700cd627202b40748b9047674c4628fa +ScriptedImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 2 + userData: + assetBundleName: + assetBundleVariant: + script: {fileID: 11500000, guid: 3b8b241bab4a4ac9a22fcce9c64f1242, type: 3} diff --git a/lua/app/ui/battle/battle_ui_pvp.lua b/lua/app/ui/battle/battle_ui_pvp.lua new file mode 100644 index 00000000..6b1a3132 --- /dev/null +++ b/lua/app/ui/battle/battle_ui_pvp.lua @@ -0,0 +1,224 @@ +local BattleBaseUI = require "app/ui/battle/battle_base_ui" +local BattleUIPVP = class("BattleUIPVP", BattleBaseUI) + +local DEFAULT_X = 10000 +local BOARD_POS_UP = BF.Vector2(0, 47) +local BOARD_POS_DOWN = BF.Vector2(0, -740) + +---------------------------------必须重写的方法---------------------------------- +function BattleBaseUI:initBaseInfo() + local uiMap = self.root:genAllChildren() + self.uiMap = uiMap + self.gridNode = uiMap["battle_ui_pvp.board_root_node.board_node_atk.grid_node"] + self.boardNode = uiMap["battle_ui_pvp.board_root_node.board_node_atk"] + self.boardNode:setAnchoredPositionX(DEFAULT_X) + self.boardMask2D = self.gridNode:getComponent(GConst.TYPEOF_UNITY_CLASS.UI_RECT_MASK_2D) + self.boardMask = uiMap["battle_ui_pvp.board_root_node.board_node_atk.grid_node.board_mask"] + self.boardMask:setVisible(false) + self.boardCacheNode = uiMap["battle_ui.bg_2.board_cache_node"] + self.boardCacheNode:setVisible(false) + self.boardCacheBox = uiMap["battle_ui.bg_2.board_cache_node.skill_box"] + self.boardCacheBox:setAnchoredPositionX(DEFAULT_X) + self.battleRoot = uiMap["battle_ui.battle_root"] + self.maxLayerNode = uiMap["battle_ui.battle_root.battle_node.max_layer_show_node"] +end + +function BattleUIPVP:initBg() + self.bg = self.uiMap["battle_ui.battle_root.bg"] + self.bg:setLocalScale(0, 0, 0) + local width = self.bg:fastGetSizeDelta() + self.bg:setAnchoredPositionX(width/4) +end + +function BattleUIPVP:initSkill() + local uiMap = self.root:genAllChildren() + local atkNode = uiMap["battle_ui_pvp.bottom_node.skill_node"] + local defNode = uiMap["battle_ui_pvp.top_node.skill_node"] + local atkCellPrefix = "battle_ui_pvp.bottom_node.skill_node.skill_node_cell_" + local defCellPrefix = "battle_ui_pvp.top_node.skill_node.skill_node_cell_" + self:_initSkill(atkNode, atkCellPrefix, defNode, defCellPrefix) +end + +function BattleUIPVP:initBuff() + local atkBuffPrefix = "battle_ui_pvp.bottom_node.buff.tiny_buff_cell_" + local defBuffPrefix = "battle_ui_pvp.top_node.buff.tiny_buff_cell_" + local battleBuffTipsRoot = self.uiMap["battle_ui_pvp.battle_buff_tips"] + local battleBuffTipsMask = self.uiMap["battle_ui_pvp.battle_buff_tips.mask"] + local battleBuffTipsBg = self.uiMap["battle_ui_pvp.battle_buff_tips.bg"] + local battleBuffTipsBuff = self.uiMap["battle_ui_pvp.battle_buff_tips.bg.buff"] + self:_initBuff(atkBuffPrefix, defBuffPrefix, battleBuffTipsRoot, battleBuffTipsMask, battleBuffTipsBg, battleBuffTipsBuff) +end + +function BattleUIPVP:initBattlefield() + self.battleNode = self.uiMap["battle_ui.battle_root.battle_node"] +end + +function BattleUIPVP:initNumberNode() + self.battleNumberNode = self.uiMap["battle_ui_pvp.battle_root.battle_number_node"] + self.battleNumberRed = self.uiMap["battle_ui_pvp.cache_node.battle_number_red"] + self.battleNumberGreen = self.uiMap["battle_ui_pvp.cache_node.battle_number_green"] + self.battleNumberBlue = self.uiMap["battle_ui_pvp.cache_node.battle_number_blue"] + self.battleNumberWhite = self.uiMap["battle_ui_pvp.cache_node.battle_number_white"] + self.battleNumberSpecial = self.uiMap["battle_ui_pvp.cache_node.battle_number_special"] +end + +function BattleBaseUI:initComboNode() + self.comboNode = self.uiMap["battle_ui_pvp.battle_root.combo"] + self.comboBg1 = self.uiMap["battle_ui_pvp.battle_root.combo.bg.bg_1"] + self.comboTx1 = self.uiMap["battle_ui_pvp.battle_root.combo.number.text.text_1"] + self.comboTx2 = self.uiMap["battle_ui_pvp.battle_root.combo.number.text.text_2"] + self.comboFx1 = self.uiMap["battle_ui_pvp.battle_root.combo.bg.vfx_ui_hit_b01"] + self.comboFx2 = self.uiMap["battle_ui_pvp.battle_root.combo.bg.vfx_ui_hit_b02"] + self.comboFx3 = self.uiMap["battle_ui_pvp.battle_root.combo.bg.vfx_ui_hit_b03"] + self:_initComboNode() +end + +function BattleBaseUI:initHpNode() + self.hpProgressLeft = self.uiMap["battle_ui_pvp.bottom_node.hp_node.hp_progress"]:getComponent(GConst.TYPEOF_UNITY_CLASS.BF_SLIDER) + self.hpProgressRight = self.uiMap["battle_ui_pvp.top_node.hp_node.hp_progress"]:getComponent(GConst.TYPEOF_UNITY_CLASS.BF_SLIDER) + self.hpTextLeft = self.uiMap["battle_ui_pvp.bottom_node.hp_node.hp"] + self.hpTextRight = self.uiMap["battle_ui_pvp.top_node.hp_node.hp"] + self.hpProgressYellowLeft = self.uiMap["battle_ui_pvp.bottom_node.hp_node.hp_progress_yellow"]:getComponent(GConst.TYPEOF_UNITY_CLASS.BF_SLIDER) + self.hpProgressYellowRight = self.uiMap["battle_ui_pvp.top_node.hp_node.hp_progress_yellow"]:getComponent(GConst.TYPEOF_UNITY_CLASS.BF_SLIDER) + self:_initHpNode() +end + +function BattleUIPVP:initFxNode() + self.fxNode = self.uiMap["battle_ui.battle_root.batttle_fx_node"] +end + +function BattleUIPVP:hideGenerateSkillGridCells() + local generateSkillCellPrefix = "battle_ui_pvp.board_root_node.ani_node.grid_cell_" + self:_hideGenerateSkillGridCells(generateSkillCellPrefix) +end + +function BattleBaseUI:initSkillLineSfx() + if not self.skillLineSfxs then + self.skillLineSfxs = {} + self.skillLineSfxs[13] = self.uiMap["battle_ui_pvp.board_root_node.ani_node.sfx_skill_b01_2_1h"] + self.skillLineSfxs[11] = self.uiMap["battle_ui_pvp.board_root_node.ani_node.sfx_skill_b01_2_1v"] + self.skillLineSfxs[15] = self.uiMap["battle_ui_pvp.board_root_node.ani_node.sfx_skill_b01_2_1l"] + self.skillLineSfxs[17] = self.uiMap["battle_ui_pvp.board_root_node.ani_node.sfx_skill_b01_2_1r"] + + self.skillLineSfxs[23] = self.uiMap["battle_ui_pvp.board_root_node.ani_node.sfx_skill_b01_1_2h"] + self.skillLineSfxs[21] = self.uiMap["battle_ui_pvp.board_root_node.ani_node.sfx_skill_b01_1_2v"] + self.skillLineSfxs[25] = self.uiMap["battle_ui_pvp.board_root_node.ani_node.sfx_skill_b01_1_2l"] + self.skillLineSfxs[27] = self.uiMap["battle_ui_pvp.board_root_node.ani_node.sfx_skill_b01_1_2r"] + + self.skillLineSfxs[33] = self.uiMap["battle_ui_pvp.board_root_node.ani_node.sfx_skill_b01_3h"] + self.skillLineSfxs[31] = self.uiMap["battle_ui_pvp.board_root_node.ani_node.sfx_skill_b01_3v"] + self.skillLineSfxs[35] = self.uiMap["battle_ui_pvp.board_root_node.ani_node.sfx_skill_b01_3l"] + self.skillLineSfxs[37] = self.uiMap["battle_ui_pvp.board_root_node.ani_node.sfx_skill_b01_3r"] + end + + if not self.skillLightSfxs then + self.skillLightSfxs = {} + self.skillLightSfxs.point = self.uiMap["battle_ui_pvp.board_root_node.ani_node.sfx_skill_b03"] + self.skillLightSfxs[11] = self.uiMap["battle_ui_pvp.board_root_node.ani_node.sfx_skill_b04_1"] + self.skillLightSfxs[12] = self.uiMap["battle_ui_pvp.board_root_node.ani_node.sfx_skill_b04_2"] + self.skillLightSfxs[13] = self.uiMap["battle_ui_pvp.board_root_node.ani_node.sfx_skill_b04_3"] + self.skillLightSfxs[14] = self.uiMap["battle_ui_pvp.board_root_node.ani_node.sfx_skill_b04_4"] + self.skillLightSfxs[15] = self.uiMap["battle_ui_pvp.board_root_node.ani_node.sfx_skill_b04_5"] + + self.skillLightSfxs[21] = self.uiMap["battle_ui_pvp.board_root_node.ani_node.sfx_skill_b05_1"] + self.skillLightSfxs[22] = self.uiMap["battle_ui_pvp.board_root_node.ani_node.sfx_skill_b05_2"] + self.skillLightSfxs[23] = self.uiMap["battle_ui_pvp.board_root_node.ani_node.sfx_skill_b05_3"] + self.skillLightSfxs[24] = self.uiMap["battle_ui_pvp.board_root_node.ani_node.sfx_skill_b05_4"] + self.skillLightSfxs[25] = self.uiMap["battle_ui_pvp.board_root_node.ani_node.sfx_skill_b05_5"] + end +end + +function BattleUIPVP:initGenerateSkillEffect() + local generateSkillEffecPrefix = "battle_ui_pvp.board_root_node.ani_node.grid_cell_" + self:_initGenerateSkillEffect(generateSkillEffecPrefix) +end + +function BattleUIPVP:initCounterAttack() + self.counterAttackNode = self.uiMap["battle_ui_pvp.battle_root.counter_attack"] + self.counterTx = self.uiMap["battle_ui_pvp.battle_root.counter_attack.text_number"] + self.counterTxbgComp = self.uiMap["battle_ui_pvp.battle_root.counter_attack.bg"] + self.counterTxTmp = self.counterTx:getComponent(GConst.TYPEOF_UNITY_CLASS.UI_TEXT_MESH_PRO) + self.counterAttackNode:setVisible(false) +end + +--------------------------------end必须重写的方法-------------------------------- + +function BattleUIPVP:getPrefabPath() + return "assets/prefabs/ui/battle/battle_ui_pvp.prefab" +end + +function BattleUIPVP:getBGMId() + return AudioManager.BGM_ID.BATTLE +end + +function BattleUIPVP:_display() + BattleBaseUI._display(self) + self:refreshAvatar() +end + +function BattleUIPVP:_addListeners() + local uiMap = self.root:genAllChildren() + uiMap["battle_ui.top_node.close_btn"]:addClickListener(function() + ModuleManager.BattleManager:showPauseUI(self.battleController.battleType) + end) +end + +function BattleUIPVP:refreshAvatar() + -- 等数据 +end + +function BattleUIPVP:showLeftBuffTips(buffList, autoClose) + local addY = self:showBuffTips(buffList, autoClose) + self.battleBuffTipsBg:setAnchoredPosition(-175, -1018 + addY) +end + +function BattleUIPVP:showRightBuffTips(buffList, autoClose) + self:showBuffTips(buffList, autoClose) + self.battleBuffTipsBg:setAnchoredPosition(175, -188) +end + +function BattleUIPVP:switchBoard(downCallback, callback, isFirst) + if self.switchBoardSeq then + self.switchBoardSeq:Kill() + self.switchBoardSeq = nil + end + + if isFirst then + if downCallback then + downCallback() + end + if callback then + callback() + end + self.boardNode:setAnchoredPositionY(BOARD_POS_UP.y) + return + end + + self.switchBoardSeq = self.root:createBindTweenSequence() + self.switchBoardSeq:Append(self.boardNode:getTransform():DOAnchorPos(BOARD_POS_DOWN, 0.5)) + self.switchBoardSeq:AppendCallback(function() + if downCallback then + downCallback() + end + end) + self.switchBoardSeq:Append(self.boardNode:getTransform():DOAnchorPos(BOARD_POS_UP, 0.5)) + self.switchBoardSeq:AppendCallback(function() + if callback then + callback() + end + end) +end + +function BattleUIPVP:refreshWave(wave, iconAtlas, iconName) + local uiMap = self.root:genAllChildren() + local icon = uiMap["battle_ui_pvp.bottom_node.round_icon"] + local desc = uiMap["battle_ui_pvp.bottom_node.round_text"] + desc:setText(wave) + GFunc.centerImgAndTx(icon, desc, 10) + + iconAtlas = iconAtlas or GConst.ATLAS_PATH.COMMON + iconName = iconName or "common_dec_3" + icon:setSprite(iconAtlas, iconName) +end + +return BattleUIPVP \ No newline at end of file diff --git a/lua/app/ui/battle/battle_ui_pvp.lua.meta b/lua/app/ui/battle/battle_ui_pvp.lua.meta new file mode 100644 index 00000000..7dc60a3a --- /dev/null +++ b/lua/app/ui/battle/battle_ui_pvp.lua.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 00c01ea12e6e5c34aa6c429a97788617 +ScriptedImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 2 + userData: + assetBundleName: + assetBundleVariant: + script: {fileID: 11500000, guid: 3b8b241bab4a4ac9a22fcce9c64f1242, type: 3} diff --git a/lua/app/ui/battle/cell/tiny_buff_cell.lua b/lua/app/ui/battle/cell/tiny_buff_cell.lua new file mode 100644 index 00000000..8aebe0ac --- /dev/null +++ b/lua/app/ui/battle/cell/tiny_buff_cell.lua @@ -0,0 +1,15 @@ +local TinyBuffCell = class("TinyBuffCell", BaseCell) + +function TinyBuffCell:refresh(buffName, round) + if round <= 1 or round > 9 then + round:setText(GConst.EMPTY_STRING) + else + round:setText(tostring(round)) + end + + local uiMap = self:getUIMap() + uiMap["tiny_buff_cell.buff_icon"]:setSprite(GConst.ATLAS_PATH.ICON_BUFF, buffName) + uiMap["tiny_buff_cell.round_text"]:setText(round) +end + +return TinyBuffCell \ No newline at end of file diff --git a/lua/app/ui/battle/cell/tiny_buff_cell.lua.meta b/lua/app/ui/battle/cell/tiny_buff_cell.lua.meta new file mode 100644 index 00000000..d71ac149 --- /dev/null +++ b/lua/app/ui/battle/cell/tiny_buff_cell.lua.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 1356c2d5313eee54ebd648608b523117 +ScriptedImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 2 + userData: + assetBundleName: + assetBundleVariant: + script: {fileID: 11500000, guid: 3b8b241bab4a4ac9a22fcce9c64f1242, type: 3} diff --git a/lua/app/userdata/battle/battle_base_data.lua b/lua/app/userdata/battle/battle_base_data.lua new file mode 100644 index 00000000..af9d6e15 --- /dev/null +++ b/lua/app/userdata/battle/battle_base_data.lua @@ -0,0 +1,720 @@ +local BattleTeamEntity = require "app/userdata/battle/team/battle_team_entity" +local BattleSkillEntity = require "app/userdata/battle/skill/battle_skill_entity" +local BattleBaseData = class("BattleBaseData", BaseData) + +local SKILL_CFG = ConfigManager:getConfig("skill") +local BattleConst = GConst.BattleConst +local BATTLE_GRID_ENTITY = require "app/userdata/battle/battle_grid_entity" +local BATTLE_BOARD_SKILL_ENTITY = require "app/userdata/battle/skill/battle_board_skill_entity" + +local ATTR_TYPE = GConst.ATTR_TYPE +local DEFAULT_FACTOR = BattleConst.DEFAULT_FACTOR +local TIME_SPEED_LEVEL_0 = 0 +local TIME_SPEED_LEVEL_1 = 1 +local TIME_SPEED_LEVEL_2 = 2 +local TIME_SPEED_LEVEL_3 = 3 +local TIME_SPEED_LEVEL_SKILL = 100 +local SIDE_ATK = BattleConst.SIDE_ATK +local SIDE_DEF = BattleConst.SIDE_DEF + +----------------------------------按需重写的方法------------------------------- +function BattleBaseData:getRowCount() + return BattleConst.PVP_ROW_COUNT +end +---------------------------------end按需重写的方法------------------------------- + +function BattleBaseData:init(params) + self:clear() + self.battleLv = 1 + self.curBattleExp = 0 + self.needBattleExp = self:getLvNeedExp() + self.addLvCount = 0 + self.commonSelectSkillCount = 0 + self.timeScale = BattleConst.TIME_SCALE.LEVEL_1 + self.lockElementMap = {} + self.data.timeSpeed = 1 + self.data.lvDirty = false + self.adRefreshSkillCount = 0 + self.refreshSkillCount = 0 + BattleSkillEntity.sid = 0 + self.atkTeam = self:initTeam(SIDE_ATK, params.atkFormation) + self.defTeam = self:initTeam(SIDE_DEF, params.defFormation) + self:initRogueSkills(SIDE_ATK, params.atkFormation) + self:initRogueSkills(SIDE_DEF, params.defFormation) +end + +function BattleBaseData:getTimeScale() + return self.timeScale +end + +function BattleBaseData:pauseBattle() + self.cacheSpeed = self.data.timeSpeed + self.cacheTimeScale = self.timeScale + self:setTimeSpeed(TIME_SPEED_LEVEL_0) +end + +function BattleBaseData:resumeBattle() + if self.cacheSpeed == nil then + return + end + if self.data.timeSpeed ~= TIME_SPEED_LEVEL_0 then + return + end + self:setTimeSpeed(self.cacheSpeed or TIME_SPEED_LEVEL_1, self.cacheTimeScale) +end + +function BattleBaseData:resetTimeSpeed() + if self.cacheSpeed then -- 目前处于暂停状态 + self.cacheSpeed = TIME_SPEED_LEVEL_1 + return + end + if self.data.timeSpeed <= TIME_SPEED_LEVEL_1 then + return + end + self:setTimeSpeed(TIME_SPEED_LEVEL_1) +end + +function BattleBaseData:addTimeSpeed() + if self.data.timeSpeed >= TIME_SPEED_LEVEL_3 then + return + end + if self.cacheSpeed then -- 目前处于暂停状态 + if self.cacheSpeed < TIME_SPEED_LEVEL_3 then + self.cacheSpeed = self.cacheSpeed + 1 + end + return + end + local timeSpeed = self.data.timeSpeed + 1 + self:setTimeSpeed(timeSpeed) +end + +function BattleBaseData:setSkillTimeSpeed(timeScale) + self:setTimeSpeed(TIME_SPEED_LEVEL_SKILL, timeScale) +end + +function BattleBaseData:setTimeSpeed(timeSpeed, timeScale) + if timeSpeed == self.data.timeSpeed then + return + end + if timeSpeed == TIME_SPEED_LEVEL_0 then + self.timeScale = 0 + elseif timeSpeed == TIME_SPEED_LEVEL_1 then + self.timeScale = BattleConst.TIME_SCALE.LEVEL_1 + elseif timeSpeed == TIME_SPEED_LEVEL_2 then + self.timeScale = BattleConst.TIME_SCALE.LEVEL_2 + elseif timeSpeed == TIME_SPEED_LEVEL_3 then + self.timeScale = BattleConst.TIME_SCALE.LEVEL_3 + else + self.timeScale = timeScale or BattleConst.TIME_SCALE.LEVEL_1 + end + self.data.timeSpeed = timeSpeed +end + +function BattleBaseData:initRogueSkills(side, formation) + if not self.skillPool then + self.skillPool = {} + self.skillMap = {} + end + if not self.skillPool[side] then + self.skillPool[side] = {} + end + if not self.skillMap[side] then + self.skillMap[side] = {} + end + + if not formation then + return + end + local skillmap = {} + for matchType, heroEntity in pairs(formation) do + local skillId = heroEntity:getBaseSkill() + local cfg = SKILL_CFG[skillId] + self.skillMap[side][cfg.position] = BATTLE_BOARD_SKILL_ENTITY:create(skillId) + self.skillMap[side][cfg.position]:addUpSkills(heroEntity:getRogueSkillList()) + self.skillMap[side][cfg.position]:setUnlockId(heroEntity:getUnlockRogueId()) + for _, id in ipairs(heroEntity:getActiveRogueSkills()) do + if not skillmap[id] then + if not self.skillPool[side][cfg.position] then + self.skillPool[side][cfg.position] = {} + end + table.insert(self.skillPool[side][cfg.position], id) + skillmap[id] = true + end + end + end +end + +function BattleBaseData:refreshBoard(board, blockIcon) + local r = 1 + local c = 1 + + for i, info in ipairs(board) do + if c > BattleConst.COLUMN_COUNT then + c = c - BattleConst.COLUMN_COUNT + r = r + 1 + end + + local posId = ModuleManager.BattleManager:getPosId(r, c) + local data = { + posId = posId, + gridType = info[1] or BattleConst.GRID_TYPE.EMPTY, + elementType = info[2] or BattleConst.ELEMENT_TYPE.RED + } + if not self.gridEntities then + self.gridEntities = {} + end + if self.gridEntities[data.posId] then + self.gridEntities[data.posId]:clear() + self.gridEntities[data.posId]:setGridType(data.gridType) + self.gridEntities[data.posId]:setElementType(data.elementType) + else + self.gridEntities[data.posId] = BATTLE_GRID_ENTITY:create(data) + end + self.gridEntities[data.posId]:determineIdleStatus() + self.gridEntities[data.posId]:setObstacleIcon(blockIcon) + c = c + 1 + end +end + +function BattleBaseData:getNewGridEntity(posId, gridType, elementType) + local data = { + posId = posId or 0, + gridType = gridType or BattleConst.GRID_TYPE.EMPTY, + elementType = elementType or BattleConst.ELEMENT_TYPE.RED + } + return BATTLE_GRID_ENTITY:create(data) +end + +function BattleBaseData:clear() + self:clearGridSequence() + self:clearCacheBoardSkill() + + self.gridEntities = {} + self.skillMap = {} + self.selectSkillMap = {} +end + +function BattleBaseData:getElementTypeMap() + local elementTypeMap = {} + if self.gridEntities then + for posId, entity in pairs(self.gridEntities) do + if entity:canLink() then + local elementType = entity:getElementType() + elementTypeMap[elementType] = (elementTypeMap[elementType] or 0) + 1 + end + end + end + return elementTypeMap +end + +function BattleBaseData:getGridSequence() + return self.gridSequence +end + +function BattleBaseData:alreadyInsertSequence(posId) + return self.gridSequenceMap[posId] == true +end + +function BattleBaseData:getIsVirtual() + return self.isVirtual +end + +function BattleBaseData:getSequenceHadSkill() + for _, info in ipairs(self:getGridSequence()) do + local entity = self.gridEntities[info.posId] + if entity and entity:getSkillId() then + return entity:getSkillId(), entity:getPosId() + end + end + return +end + +function BattleBaseData:insertGridSequence(posId, snapshot, isVirtual) + if self:alreadyInsertSequence(posId) then + return false + end + + self.gridSequenceMap[posId] = true + self.isVirtual = isVirtual + table.insert(self.gridSequence, {posId = posId, snapshot = snapshot}) + return true +end + +function BattleBaseData:removeGridSequence(posId) + if not self:alreadyInsertSequence(posId) then + return + end + + local count = #self.gridSequence + local lastPosId = self.gridSequence[count].posId + local snapshot = self.gridSequence[count].snapshot + if lastPosId ~= posId then + return + end + + table.remove(self.gridSequence, count) + self.gridSequenceMap[lastPosId] = false + return snapshot +end + +function BattleBaseData:getFirstSequenceSnapshot() + if not self.gridSequence[1] then + return + end + + local snapshot = self.gridSequence[1].snapshot + return snapshot +end + +function BattleBaseData:cacheSkillInfluenceGrids(grids) + if not self.skillInfluenceGrids then + self.skillInfluenceGrids = {} + end + for posId, info in pairs(grids) do + self.skillInfluenceGrids[posId] = info + end +end + +function BattleBaseData:getSkillInfluenceGrids() + return self.skillInfluenceGrids or {} +end + +function BattleBaseData:clearSkillInfluenceGrids() + local grids = self:getSkillInfluenceGrids() + self.skillInfluenceGrids = {} -- 技能影响的格子 + return grids +end + +function BattleBaseData:clearGridSequence() + self.gridSequence = {} -- 格子队列 + self.gridSequenceMap = {} -- 格子队列对应的map,方面查找 + self.isVirtual = nil + self:clearSkillInfluenceGrids() +end + +function BattleBaseData:getGridEnties() + return self.gridEntities or {} +end + +function BattleBaseData:getGridEntity(posId) + return self.gridEntities[posId] +end + +function BattleBaseData:exchangeGridEntities(posId1, posId2) + local e1 = self.gridEntities[posId1] + local e2 = self.gridEntities[posId2] + e1:setPosId(posId2) + e2:setPosId(posId1) + e2:setIsIdle(false) + self.gridEntities[posId1] = e2 + self.gridEntities[posId2] = e1 +end + +function BattleBaseData:setGridEntitiesPosId(changeInfo) + local map = {} + for posId, targetPosId in pairs(changeInfo) do + local entity = self.gridEntities[posId] + entity:setPosId(targetPosId) + map[targetPosId] = entity + end + + for posId, entity in pairs(map) do + self.gridEntities[posId] = entity + end +end + +function BattleBaseData:setGridInfo(posId, gridInfo) + local entity = self.gridEntities[posId] + if not entity then + return + end + + if gridInfo.gridType then + entity:setGridType(gridInfo.gridType) + end + + if gridInfo.elementType then + entity:setElementType(gridInfo.elementType) + end + + entity:setSkilId() -- 清除skillId + entity:determineIdleStatus() +end + +function BattleBaseData:setInfoBySnapshop(posId, snapInfo) + local entity = self.gridEntities[posId] + if not entity then + return + end + entity:setInfoBySnapshop(snapInfo) +end + +function BattleBaseData:setGridType(posId, gridType, noDirty) + local entity = self.gridEntities[posId] + if not entity then + return + end + entity:setGridType(gridType, noDirty) + entity:determineIdleStatus() +end + +function BattleBaseData:setGridDirty(posId) + local entity = self.gridEntities[posId] + if not entity then + return + end + entity:setDirty() +end + +function BattleBaseData:lockAllSkillGrid(lock) + if not self.gridEntities then + return + end + + for posId, entity in pairs(self.gridEntities) do + if entity:getSkillId() then + local gridType = GConst.BattleConst.GRID_TYPE.EMPTY + if lock then + gridType = GConst.BattleConst.GRID_TYPE.LOCK + end + self:setGridType(posId, gridType) + end + end +end + +function BattleBaseData:getSkillEntities(side) + side = side or SIDE_ATK + if self.skillMap then + return self.skillMap[side] or {} + end +end + +function BattleBaseData:getSkillEntityByElement(elementType, side) + local skillMap = self:getSkillEntities(side) + if not skillMap then + return + end + return skillMap[elementType] +end + +function BattleBaseData:getSkillEntityBySkillId(skillId, side) + local skillMap = self:getSkillEntities(side) + if not skillMap or not skillId then + return + end + local cfg = SKILL_CFG[skillId] + if not cfg then + return + end + return skillMap[cfg.position] +end + +function BattleBaseData:unlockSkillEntity(elementType, side) + local skillMap = self:getSkillEntities(side) + if skillMap and skillMap[elementType] then + skillMap[elementType]:setUnlock() + end +end + +function BattleBaseData:isUnlockedSkillElementType(elementType, side) + local skillMap = self:getSkillEntities(side) + if not skillMap or not skillMap[elementType] then + return false + end + return skillMap[elementType]:getUnlocked() +end + +function BattleBaseData:addSkillEnergy(elementMap, side) + local skillMap = self:getSkillEntities(side) + if not skillMap then + return + end + + for elementType, entity in pairs(skillMap) do + if entity:getUnlocked() then + entity:addEnergy(elementMap[elementType] or 0) + end + end +end + +function BattleBaseData:addSkillCount(skillId, value, side) + side = side or SIDE_ATK + if not self.selectSkillMap then + self.selectSkillMap = {} + end + if not self.selectSkillMap[side] then + self.selectSkillMap[side] = {} + end + if not self.selectSkillMap[side][skillId] then + self.selectSkillMap[side][skillId] = { + count = 0, + value = 0 + } + end + self.selectSkillMap[side][skillId].count = self.selectSkillMap[side][skillId].count + 1 + if value then + self.selectSkillMap[side][skillId].value = (self.selectSkillMap[side][skillId].value) + value + end +end + +function BattleBaseData:getSkillCount(skillId, side) + side = side or SIDE_ATK + if self.selectSkillMap[side] and self.selectSkillMap[side][skillId] then + return self.selectSkillMap[side][skillId].count + end + return 0 +end + +function BattleBaseData:getSelectSkillMap(side) + side = side or SIDE_ATK + return self.selectSkillMap and self.selectSkillMap[side] or {} +end + +function BattleBaseData:getSkillPool(side) + side = side or SIDE_ATK + return self.skillPool and self.skillPool[side] or {} +end + +function BattleBaseData:changeSkillId(elementType, newId, side) + if not newId then + return + end + + local entity = self:getSkillEntityByElement(elementType, side) + if entity then + entity:refreshSkillId(newId) + end +end + +function BattleBaseData:cacheLockElement(elementType, status) + self.lockElementMap[elementType] = status +end + +function BattleBaseData:getCacheLockedElement(elementType) + return self.lockElementMap[elementType] +end + +function BattleBaseData:cacheBoardSkill() + self.cacheSkillList = {} + self.cacheSkillCount = 0 + local list + local count = 0 + for posId, entity in pairs(self:getGridEnties()) do + if entity:getSkillId() then + if not list then + list = {} + end + table.insert(list, {skillId = entity:getSkillId(), posId = posId}) + count = count + 1 + end + end + + if list then + if count > BattleConst.MAX_CACHE_SKILL_COUNT then + count = BattleConst.MAX_CACHE_SKILL_COUNT + end + + for i = 1, count do + if not list[1] then + break + end + local info = table.remove(list, math.random(1, #list)) + table.insert(self.cacheSkillList, info) + self.cacheSkillCount = self.cacheSkillCount + 1 + end + end +end + +function BattleBaseData:getCacheBoardSkill() + if not self.cacheSkillList then + return self.cacheSkillList, 0 + end + return self.cacheSkillList, self.cacheSkillCount +end + +function BattleBaseData:clearCacheBoardSkill() + self.cacheSkillList = {} + self.cacheSkillCount = 0 +end + +function BattleBaseData:getBattleLv() + return self.battleLv +end + +function BattleBaseData:getBattleExp() + return self.curBattleExp +end + +function BattleBaseData:getBattleNeedExp() + return self.needBattleExp +end + +function BattleBaseData:getLvNeedExp(lv) + lv = lv or self.battleLv + local cfg = ConfigManager:getConfig("battle_exp") + if not cfg[lv] then + return cfg[ConfigManager:getConfigNum("battle_exp")].exp + end + return cfg[lv].exp +end + +function BattleBaseData:addExp(exp) + self.curBattleExp = self.curBattleExp + exp + while self.curBattleExp >= self.needBattleExp do + self.curBattleExp = self.curBattleExp - self.needBattleExp + self.addLvCount = self.addLvCount + 1 + self.battleLv = self.battleLv + 1 + self.needBattleExp = self:getLvNeedExp() + end + self.data.lvDirty = not self.data.lvDirty +end + +function BattleBaseData:useAddlvCount() + if self.addLvCount <= 0 then + self.addLvCount = 0 + return false + end + self.addLvCount = self.addLvCount - 1 + return true +end + +function BattleBaseData:addCommonSelectSkillCount(count) + self.commonSelectSkillCount = self.commonSelectSkillCount + (count or 1) +end + +function BattleBaseData:useCommonSelectSkillCount() + if self.commonSelectSkillCount <= 0 then + self.commonSelectSkillCount = 0 + return false + end + self.commonSelectSkillCount = self.commonSelectSkillCount - 1 + return true +end + +function BattleBaseData:addRefreshSkillCount(isAd) + if isAd then + self.adRefreshSkillCount = self.adRefreshSkillCount + 1 + end + self.refreshSkillCount = self.refreshSkillCount + 1 +end + +function BattleBaseData:getRefreshSkillCount() + return self.refreshSkillCount +end + +function BattleBaseData:getADRefreshSkillCount() + return self.adRefreshSkillCount +end + +function BattleBaseData:initTeam(side, formation) + local data = nil + data = self:initHeroData(formation) + local team = BattleTeamEntity:create() + team:init(side, data) + return team +end + +function BattleBaseData:getAtkTeam() + return self.atkTeam +end + +function BattleBaseData:getDefTeam() + return self.defTeam +end + +function BattleBaseData:initHeroData(formation) + local units = {} + if formation then + local skillCfg = ConfigManager:getConfig("skill") + for matchType, heroEntity in pairs(formation) do + local heroAttr = heroEntity:getAllAttr() + local skillId = heroEntity:getBaseSkill() + local hp = heroAttr[ATTR_TYPE.hp] // DEFAULT_FACTOR + local unitData = { + id = heroEntity:getCfgId(), + modelId = heroEntity:getModelId(), + matchType = matchType, + normalSkills = heroEntity:getHurtSkill(), + assistingSkill = heroEntity:getAssistingSkill(), + body = 2, -- 英雄默认是中体型 + attr = { + hp = hp, + max_hp = hp, + atk = 0, + atk_red = heroAttr[ATTR_TYPE.atk_red] // DEFAULT_FACTOR, + atk_yellow = heroAttr[ATTR_TYPE.atk_yellow] // DEFAULT_FACTOR, + atk_green = heroAttr[ATTR_TYPE.atk_green] // DEFAULT_FACTOR, + atk_blue = heroAttr[ATTR_TYPE.atk_blue] // DEFAULT_FACTOR, + atk_purple = heroAttr[ATTR_TYPE.atk_purple] // DEFAULT_FACTOR, + } + } + local skillInfo = skillCfg[skillId] + if skillInfo then + if skillInfo.effect_type == 1 then -- 主动 + unitData.activeSkills = {skillId} + elseif skillInfo.effect_type == 2 then -- 被动 + unitData.passiveSkills = {skillId} + end + end + table.insert(units, unitData) + end + end + local data = { + units = units + } + return data +end + +function BattleBaseData:addMonster(monsterId, newTeam, battleController) + local monsterInfo = ConfigManager:getConfig("monster")[monsterId] + local hp = monsterInfo.hp // DEFAULT_FACTOR + local atk = monsterInfo.atk // DEFAULT_FACTOR + if battleController then + hp = hp * (DEFAULT_FACTOR + battleController:getMonsterHpAddition()) // DEFAULT_FACTOR + atk = atk * (DEFAULT_FACTOR + battleController:getMonsterAtkAddition()) // DEFAULT_FACTOR + end + local unitData = { + id = monsterId, + modelId = monsterInfo.model_id, + matchType = 0, + normalSkills = monsterInfo.hurt_skill, + normalSkillCount = monsterInfo.atk_times or 0, + activeSkills = monsterInfo.skill, + passiveSkills = monsterInfo.passive_skill, + assistingSkill = nil, + isBoss = monsterInfo.is_boss, + exp = monsterInfo.monster_exp or 0, + body = monsterInfo.body, + hpSkinHp = monsterInfo.monster_hp, + hpSkinSkin = monsterInfo.monster_hp_skin, + hpExp = monsterInfo.monster_hp_exp, + attr = { + hp = hp, + max_hp = hp, + atk = atk, + atk_red = 0, + atk_yellow = 0, + atk_green = 0, + atk_blue = 0, + atk_purple = 0, + } + } + if newTeam then + self.defTeam:init(BattleConst.SIDE_DEF) + end + return self.defTeam:addUnit(unitData) +end + +function BattleBaseData:getNormalAttackName(index) + if self.normalAttackName == nil then + self.normalAttackName = {} + end + local name = self.normalAttackName[index] + if name == nil then + name = string.format("attack%02d", index) + self.normalAttackName[index] = name + end + return name +end + +return BattleBaseData \ No newline at end of file diff --git a/lua/app/userdata/battle/battle_base_data.lua.meta b/lua/app/userdata/battle/battle_base_data.lua.meta new file mode 100644 index 00000000..0ae5c673 --- /dev/null +++ b/lua/app/userdata/battle/battle_base_data.lua.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 837e21ae713803145940e1f74b06f5fd +ScriptedImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 2 + userData: + assetBundleName: + assetBundleVariant: + script: {fileID: 11500000, guid: 3b8b241bab4a4ac9a22fcce9c64f1242, type: 3} diff --git a/lua/app/userdata/battle/battle_data.lua b/lua/app/userdata/battle/battle_data.lua index ed50a53a..2210d6dc 100644 --- a/lua/app/userdata/battle/battle_data.lua +++ b/lua/app/userdata/battle/battle_data.lua @@ -1,694 +1,10 @@ -local BattleTeamEntity = require "app/userdata/battle/team/battle_team_entity" -local BattleSkillEntity = require "app/userdata/battle/skill/battle_skill_entity" +local BattleBaseData = require "app/userdata/battle/battle_base_data" +local BattleData = class("BattleData", BattleBaseData) -local BattleData = class("BattleData", BaseData) - -local SKILL_CFG = ConfigManager:getConfig("skill") local BattleConst = GConst.BattleConst -local BATTLE_GRID_ENTITY = require "app/userdata/battle/battle_grid_entity" -local BATTLE_BOARD_SKILL_ENTITY = require "app/userdata/battle/skill/battle_board_skill_entity" -local ATTR_TYPE = GConst.ATTR_TYPE -local DEFAULT_FACTOR = BattleConst.DEFAULT_FACTOR -local TIME_SPEED_LEVEL_0 = 0 -local TIME_SPEED_LEVEL_1 = 1 -local TIME_SPEED_LEVEL_2 = 2 -local TIME_SPEED_LEVEL_3 = 3 -local TIME_SPEED_LEVEL_SKILL = 100 - -function BattleData:init() - self:clear() - self.battleLv = 1 - self.curBattleExp = 0 - self.needBattleExp = self:getLvNeedExp() - self.addLvCount = 0 - self.commonSelectSkillCount = 0 - self.timeScale = BattleConst.TIME_SCALE.LEVEL_1 - self.lockElementMap = {} - self.data.timeSpeed = 1 - self.data.lvDirty = false - self.adRefreshSkillCount = 0 - self.refreshSkillCount = 0 - BattleSkillEntity.sid = 0 - self.atkTeam = self:initTeam(BattleConst.SIDE_ATK) - self.defTeam = self:initTeam(BattleConst.SIDE_DEF) - self:initRogueSkills() -end - -function BattleData:getTimeScale() - return self.timeScale -end - -function BattleData:pauseBattle() - self.cacheSpeed = self.data.timeSpeed - self.cacheTimeScale = self.timeScale - self:setTimeSpeed(TIME_SPEED_LEVEL_0) -end - -function BattleData:resumeBattle() - if self.cacheSpeed == nil then - return - end - if self.data.timeSpeed ~= TIME_SPEED_LEVEL_0 then - return - end - self:setTimeSpeed(self.cacheSpeed or TIME_SPEED_LEVEL_1, self.cacheTimeScale) -end - -function BattleData:resetTimeSpeed() - if self.cacheSpeed then -- 目前处于暂停状态 - self.cacheSpeed = TIME_SPEED_LEVEL_1 - return - end - if self.data.timeSpeed <= TIME_SPEED_LEVEL_1 then - return - end - self:setTimeSpeed(TIME_SPEED_LEVEL_1) -end - -function BattleData:addTimeSpeed() - if self.data.timeSpeed >= TIME_SPEED_LEVEL_3 then - return - end - if self.cacheSpeed then -- 目前处于暂停状态 - if self.cacheSpeed < TIME_SPEED_LEVEL_3 then - self.cacheSpeed = self.cacheSpeed + 1 - end - return - end - local timeSpeed = self.data.timeSpeed + 1 - self:setTimeSpeed(timeSpeed) -end - -function BattleData:setSkillTimeSpeed(timeScale) - self:setTimeSpeed(TIME_SPEED_LEVEL_SKILL, timeScale) -end - -function BattleData:setTimeSpeed(timeSpeed, timeScale) - if timeSpeed == self.data.timeSpeed then - return - end - if timeSpeed == TIME_SPEED_LEVEL_0 then - self.timeScale = 0 - elseif timeSpeed == TIME_SPEED_LEVEL_1 then - self.timeScale = BattleConst.TIME_SCALE.LEVEL_1 - elseif timeSpeed == TIME_SPEED_LEVEL_2 then - self.timeScale = BattleConst.TIME_SCALE.LEVEL_2 - elseif timeSpeed == TIME_SPEED_LEVEL_3 then - self.timeScale = BattleConst.TIME_SCALE.LEVEL_3 - else - self.timeScale = timeScale or BattleConst.TIME_SCALE.LEVEL_1 - end - self.data.timeSpeed = timeSpeed -end - -function BattleData:initRogueSkills() - self.skillPool = {} - self.skillMap = {} - local skillmap = {} - local formation = DataManager.FormationData:getStageFormation() - for matchType, heroId in pairs(formation) do - if heroId > 0 then - local heroEntity = DataManager.HeroData:getHeroById(heroId) - if heroEntity then - local skillId = heroEntity:getBaseSkill() - local cfg = SKILL_CFG[skillId] - self.skillMap[cfg.position] = BATTLE_BOARD_SKILL_ENTITY:create(skillId) - self.skillMap[cfg.position]:addUpSkills(heroEntity:getRogueSkillList()) - self.skillMap[cfg.position]:setUnlockId(heroEntity:getUnlockRogueId()) - for _, id in ipairs(heroEntity:getActiveTogueSkills()) do - if not skillmap[id] then - if not self.skillPool[cfg.position] then - self.skillPool[cfg.position] = {} - end - table.insert(self.skillPool[cfg.position], id) - skillmap[id] = true - end - end - end - end - end -end - -function BattleData:refreshBoard(board, blockIcon) - for i, info in ipairs(board) do - local r = 1 - local c = 1 - local zheng = i // BattleConst.ROW_COUNT - local yu = i % BattleConst.ROW_COUNT - if yu > 0 then - r = zheng + 1 - c = yu - else - r = zheng - c = BattleConst.ROW_COUNT - end - - local posId = ModuleManager.BattleManager:getPosId(r, c) - local data = { - posId = posId, - gridType = info[1] or BattleConst.GRID_TYPE.EMPTY, - elementType = info[2] or BattleConst.ELEMENT_TYPE.RED - } - if self.gridEntities[data.posId] then - self.gridEntities[data.posId]:clear() - self.gridEntities[data.posId]:setGridType(data.gridType) - self.gridEntities[data.posId]:setElementType(data.elementType) - else - self.gridEntities[data.posId] = BATTLE_GRID_ENTITY:create(data) - end - self.gridEntities[data.posId]:determineIdleStatus() - self.gridEntities[data.posId]:setObstacleIcon(blockIcon) - end -end - -function BattleData:getNewGridEntity(posId, gridType, elementType) - local data = { - posId = posId or 0, - gridType = gridType or BattleConst.GRID_TYPE.EMPTY, - elementType = elementType or BattleConst.ELEMENT_TYPE.RED - } - return BATTLE_GRID_ENTITY:create(data) -end - -function BattleData:clear() - self:clearGridSequence() - self:clearCacheBoardSkill() - - self.gridEntities = {} - self.skillMap = {} - self.selectSkillMap = {} -end - -function BattleData:getElementTypeMap() - local elementTypeMap = {} - if self.gridEntities then - for posId, entity in pairs(self.gridEntities) do - if entity:canLink() then - local elementType = entity:getElementType() - elementTypeMap[elementType] = (elementTypeMap[elementType] or 0) + 1 - end - end - end - return elementTypeMap -end - -function BattleData:getGridSequence() - return self.gridSequence -end - -function BattleData:alreadyInsertSequence(posId) - return self.gridSequenceMap[posId] == true -end - -function BattleData:getIsVirtual() - return self.isVirtual -end - -function BattleData:getSequenceHadSkill() - for _, info in ipairs(self:getGridSequence()) do - local entity = self.gridEntities[info.posId] - if entity and entity:getSkillId() then - return entity:getSkillId(), entity:getPosId() - end - end - return -end - -function BattleData:insertGridSequence(posId, snapshot, isVirtual) - if self:alreadyInsertSequence(posId) then - return false - end - - self.gridSequenceMap[posId] = true - self.isVirtual = isVirtual - table.insert(self.gridSequence, {posId = posId, snapshot = snapshot}) - return true -end - -function BattleData:removeGridSequence(posId) - if not self:alreadyInsertSequence(posId) then - return - end - - local count = #self.gridSequence - local lastPosId = self.gridSequence[count].posId - local snapshot = self.gridSequence[count].snapshot - if lastPosId ~= posId then - return - end - - table.remove(self.gridSequence, count) - self.gridSequenceMap[lastPosId] = false - return snapshot -end - -function BattleData:getFirstSequenceSnapshot(posId) - if not self.gridSequence[1] then - return - end - - local snapshot = self.gridSequence[1].snapshot - return snapshot -end - -function BattleData:cacheSkillInfluenceGrids(grids) - if not self.skillInfluenceGrids then - self.skillInfluenceGrids = {} - end - for posId, info in pairs(grids) do - self.skillInfluenceGrids[posId] = info - end -end - -function BattleData:getSkillInfluenceGrids() - return self.skillInfluenceGrids or {} -end - -function BattleData:clearSkillInfluenceGrids() - local grids = self:getSkillInfluenceGrids() - self.skillInfluenceGrids = {} -- 技能影响的格子 - return grids -end - -function BattleData:clearGridSequence() - self.gridSequence = {} -- 格子队列 - self.gridSequenceMap = {} -- 格子队列对应的map,方面查找 - self.isVirtual = nil - self:clearSkillInfluenceGrids() -end - -function BattleData:getGridEnties() - return self.gridEntities or {} -end - -function BattleData:getGridEntity(posId) - return self.gridEntities[posId] -end - -function BattleData:exchangeGridEntities(posId1, posId2) - local e1 = self.gridEntities[posId1] - local e2 = self.gridEntities[posId2] - e1:setPosId(posId2) - e2:setPosId(posId1) - e2:setIsIdle(false) - self.gridEntities[posId1] = e2 - self.gridEntities[posId2] = e1 -end - -function BattleData:setGridEntitiesPosId(changeInfo) - local map = {} - for posId, targetPosId in pairs(changeInfo) do - local entity = self.gridEntities[posId] - entity:setPosId(targetPosId) - map[targetPosId] = entity - end - - for posId, entity in pairs(map) do - self.gridEntities[posId] = entity - end -end - -function BattleData:setGridInfo(posId, gridInfo) - local entity = self.gridEntities[posId] - if not entity then - return - end - - if gridInfo.gridType then - entity:setGridType(gridInfo.gridType) - end - - if gridInfo.elementType then - entity:setElementType(gridInfo.elementType) - end - - entity:setSkilId() -- 清除skillId - entity:determineIdleStatus() -end - -function BattleData:setInfoBySnapshop(posId, snapInfo) - local entity = self.gridEntities[posId] - if not entity then - return - end - entity:setInfoBySnapshop(snapInfo) -end - -function BattleData:setGridType(posId, gridType, noDirty) - local entity = self.gridEntities[posId] - if not entity then - return - end - entity:setGridType(gridType, noDirty) - entity:determineIdleStatus() -end - -function BattleData:setGridDirty(posId) - local entity = self.gridEntities[posId] - if not entity then - return - end - entity:setDirty() -end - -function BattleData:lockAllSkillGrid(lock) - if not self.gridEntities then - return - end - - for posId, entity in pairs(self.gridEntities) do - if entity:getSkillId() then - local gridType = GConst.BattleConst.GRID_TYPE.EMPTY - if lock then - gridType = GConst.BattleConst.GRID_TYPE.LOCK - end - self:setGridType(posId, gridType) - end - end -end - -function BattleData:getSkillEntities() - return self.skillMap -end - -function BattleData:getSkillEntityByElement(elementType) - if not self.skillMap then - return - end - return self.skillMap[elementType] -end - -function BattleData:getSkillEntityBySkillId(skillId) - if not self.skillMap or not skillId then - return - end - local cfg = SKILL_CFG[skillId] - if not cfg then - return - end - return self.skillMap[cfg.position] -end - -function BattleData:unlockSkillEntity(elementType) - if self.skillMap[elementType] then - self.skillMap[elementType]:setUnlock() - end -end - -function BattleData:isUnlockedSkillElementType(elementType) - if not self.skillMap[elementType] then - return false - end - return self.skillMap[elementType]:getUnlocked() -end - -function BattleData:addSkillEnergy(elementMap) - if not self.skillMap then - return - end - - for elementType, entity in pairs(self.skillMap) do - if entity:getUnlocked() then - entity:addEnergy(elementMap[elementType] or 0) - end - end -end - -function BattleData:addSkillCount(skillId, value) - if not self.selectSkillMap[skillId] then - self.selectSkillMap[skillId] = { - count = 0, - value = 0 - } - end - self.selectSkillMap[skillId].count = self.selectSkillMap[skillId].count + 1 - if value then - self.selectSkillMap[skillId].value = (self.selectSkillMap[skillId].value) + value - end -end - -function BattleData:getSkillCount(skillId) - if self.selectSkillMap[skillId] then - return self.selectSkillMap[skillId].count - end - return 0 -end - -function BattleData:getSelectSkillMap() - return self.selectSkillMap -end - -function BattleData:getSkillPool() - return self.skillPool -end - -function BattleData:changeSkillId(elementType, newId) - if not newId then - return - end - - local entity = self:getSkillEntityByElement(elementType) - if entity then - entity:refreshSkillId(newId) - end -end - -function BattleData:cacheLockElement(elementType, status) - self.lockElementMap[elementType] = status -end - -function BattleData:getCacheLockedElement(elementType) - return self.lockElementMap[elementType] -end - -function BattleData:cacheBoardSkill() - self.cacheSkillList = {} - self.cacheSkillCount = 0 - local list - local count = 0 - for posId, entity in pairs(self:getGridEnties()) do - if entity:getSkillId() then - if not list then - list = {} - end - table.insert(list, {skillId = entity:getSkillId(), posId = posId}) - count = count + 1 - end - end - - if list then - if count > BattleConst.MAX_CACHE_SKILL_COUNT then - count = BattleConst.MAX_CACHE_SKILL_COUNT - end - - for i = 1, count do - if not list[1] then - break - end - local info = table.remove(list, math.random(1, #list)) - table.insert(self.cacheSkillList, info) - self.cacheSkillCount = self.cacheSkillCount + 1 - end - end -end - -function BattleData:getCacheBoardSkill() - if not self.cacheSkillList then - return self.cacheSkillList, 0 - end - return self.cacheSkillList, self.cacheSkillCount -end - -function BattleData:clearCacheBoardSkill() - self.cacheSkillList = {} - self.cacheSkillCount = 0 -end - -function BattleData:getBattleLv() - return self.battleLv -end - -function BattleData:getBattleExp() - return self.curBattleExp -end - -function BattleData:getBattleNeedExp() - return self.needBattleExp -end - -function BattleData:getLvNeedExp(lv) - lv = lv or self.battleLv - local cfg = ConfigManager:getConfig("battle_exp") - if not cfg[lv] then - return cfg[ConfigManager:getConfigNum("battle_exp")].exp - end - return cfg[lv].exp -end - -function BattleData:addExp(exp) - self.curBattleExp = self.curBattleExp + exp - while self.curBattleExp >= self.needBattleExp do - self.curBattleExp = self.curBattleExp - self.needBattleExp - self.addLvCount = self.addLvCount + 1 - self.battleLv = self.battleLv + 1 - self.needBattleExp = self:getLvNeedExp() - end - self.data.lvDirty = not self.data.lvDirty -end - -function BattleData:useAddlvCount() - if self.addLvCount <= 0 then - self.addLvCount = 0 - return false - end - self.addLvCount = self.addLvCount - 1 - return true -end - -function BattleData:addCommonSelectSkillCount(count) - self.commonSelectSkillCount = self.commonSelectSkillCount + (count or 1) -end - -function BattleData:useCommonSelectSkillCount() - if self.commonSelectSkillCount <= 0 then - self.commonSelectSkillCount = 0 - return false - end - self.commonSelectSkillCount = self.commonSelectSkillCount - 1 - return true -end - -function BattleData:addRefreshSkillCount(isAd) - if isAd then - self.adRefreshSkillCount = self.adRefreshSkillCount + 1 - end - self.refreshSkillCount = self.refreshSkillCount + 1 -end - -function BattleData:getRefreshSkillCount() - return self.refreshSkillCount -end - -function BattleData:getADRefreshSkillCount() - return self.adRefreshSkillCount -end - -function BattleData:initTeam(side) - local data = nil - if side == BattleConst.SIDE_ATK then - data = self:initHeroData() - end - local team = BattleTeamEntity:create() - team:init(side, data) - return team -end - -function BattleData:getAtkTeam() - return self.atkTeam -end - -function BattleData:getDefTeam() - return self.defTeam -end - -function BattleData:initHeroData() - local units = {} - local skillCfg = ConfigManager:getConfig("skill") - local formation = DataManager.FormationData:getStageFormation() - for matchType, heroId in pairs(formation) do - if heroId > 0 then - local heroEntity = DataManager.HeroData:getHeroById(heroId) - if heroEntity then - local heroAttr = heroEntity:getAllAttr() - local skillId = heroEntity:getBaseSkill() - local hp = heroAttr[ATTR_TYPE.hp] // DEFAULT_FACTOR - local unitData = { - id = heroId, - modelId = heroEntity:getModelId(), - matchType = matchType, - normalSkills = heroEntity:getHurtSkill(), - assistingSkill = heroEntity:getAssistingSkill(), - body = 2, -- 英雄默认是中体型 - attr = { - hp = hp, - max_hp = hp, - atk = 0, - atk_red = heroAttr[ATTR_TYPE.atk_red] // DEFAULT_FACTOR, - atk_yellow = heroAttr[ATTR_TYPE.atk_yellow] // DEFAULT_FACTOR, - atk_green = heroAttr[ATTR_TYPE.atk_green] // DEFAULT_FACTOR, - atk_blue = heroAttr[ATTR_TYPE.atk_blue] // DEFAULT_FACTOR, - atk_purple = heroAttr[ATTR_TYPE.atk_purple] // DEFAULT_FACTOR, - } - } - local skillInfo = skillCfg[skillId] - if skillInfo then - if skillInfo.effect_type == 1 then -- 主动 - unitData.activeSkills = {skillId} - elseif skillInfo.effect_type == 2 then -- 被动 - unitData.passiveSkills = {skillId} - end - end - table.insert(units, unitData) - end - end - end - local data = { - units = units - } - return data -end - -function BattleData:addMonster(monsterId, newTeam, battleController) - local monsterInfo = ConfigManager:getConfig("monster")[monsterId] - local hp = monsterInfo.hp // DEFAULT_FACTOR - local atk = monsterInfo.atk // DEFAULT_FACTOR - if battleController then - hp = hp * (DEFAULT_FACTOR + battleController:getMonsterHpAddition()) // DEFAULT_FACTOR - atk = atk * (DEFAULT_FACTOR + battleController:getMonsterAtkAddition()) // DEFAULT_FACTOR - end - local unitData = { - id = monsterId, - modelId = monsterInfo.model_id, - matchType = 0, - normalSkills = monsterInfo.hurt_skill, - normalSkillCount = monsterInfo.atk_times or 0, - activeSkills = monsterInfo.skill, - passiveSkills = monsterInfo.passive_skill, - assistingSkill = nil, - isBoss = monsterInfo.is_boss, - exp = monsterInfo.monster_exp or 0, - body = monsterInfo.body, - hpSkinHp = monsterInfo.monster_hp, - hpSkinSkin = monsterInfo.monster_hp_skin, - hpExp = monsterInfo.monster_hp_exp, - attr = { - hp = hp, - max_hp = hp, - atk = atk, - atk_red = 0, - atk_yellow = 0, - atk_green = 0, - atk_blue = 0, - atk_purple = 0, - } - } - if newTeam then - self.defTeam:init(BattleConst.SIDE_DEF) - end - return self.defTeam:addUnit(unitData) -end - -function BattleData:getNormalAttackName(index) - if self.normalAttackName == nil then - self.normalAttackName = {} - end - local name = self.normalAttackName[index] - if name == nil then - name = string.format("attack%02d", index) - self.normalAttackName[index] = name - end - return name +function BattleBaseData:getRowCount() + return BattleConst.PVP_ROW_COUNT end return BattleData \ No newline at end of file diff --git a/lua/app/userdata/battle/battle_pvp_data.lua b/lua/app/userdata/battle/battle_pvp_data.lua new file mode 100644 index 00000000..51e00148 --- /dev/null +++ b/lua/app/userdata/battle/battle_pvp_data.lua @@ -0,0 +1,9 @@ +local BattleBaseData = require "app/userdata/battle/battle_base_data" +local BattlePVPData = class("BattlePVPData", BattleBaseData) +local BattleConst = GConst.BattleConst + +function BattlePVPData:getRowCount() + return BattleConst.PVP_ROW_COUNT +end + +return BattlePVPData \ No newline at end of file diff --git a/lua/app/userdata/battle/battle_pvp_data.lua.meta b/lua/app/userdata/battle/battle_pvp_data.lua.meta new file mode 100644 index 00000000..e10a09ef --- /dev/null +++ b/lua/app/userdata/battle/battle_pvp_data.lua.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: b35afc8876bdb8043912672742db5042 +ScriptedImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 2 + userData: + assetBundleName: + assetBundleVariant: + script: {fileID: 11500000, guid: 3b8b241bab4a4ac9a22fcce9c64f1242, type: 3} diff --git a/lua/app/userdata/hero/hero_entity.lua b/lua/app/userdata/hero/hero_entity.lua index ab4bfe07..576f37b8 100644 --- a/lua/app/userdata/hero/hero_entity.lua +++ b/lua/app/userdata/hero/hero_entity.lua @@ -264,7 +264,7 @@ function HeroEntity:getRogueSkillList() return self.rogueSkillList end -function HeroEntity:getActiveTogueSkills() +function HeroEntity:getActiveRogueSkills() local list = {} for i = 1, self:getActiveRogueCount() do local id = self:getRogueSkillList()[i]