local BattleBuffHandle = require "app/module/battle/helper/battle_buff_handle" local BattleConst = require "app/module/battle/battle_const" local BattleHelper = require "app/module/battle/helper/battle_helper" local BattleTeam = class("BattleTeam") function BattleTeam:init(side, battleController) self.side = side self.battleController = battleController self.unitList = {} self.unitMap = {} self.buffList = {} self.sameBuffCount = {} self.shieldBuffList = {} self.loopFxMap = {} self.comboCount = 0 self.cacheBuffDecr = {} end function BattleTeam:addUnit(unit, isMainUnit) unit:setTeam(self) self.unitMap[unit:getMatchType()] = unit table.insert(self.unitList, unit) if isMainUnit then self.mainUnit = unit end end function BattleTeam:checkPassiveEvent(...) for k, v in ipairs(self.unitList) do v:checkPassiveEvent(...) end end function BattleTeam:prepare() for k, v in ipairs(self.unitList) do v:prepare() end end function BattleTeam:getBuffList() return self.buffList end function BattleTeam:getMainUnit() return self.mainUnit end function BattleTeam:removeAllUnits() for k, v in pairs(self.unitMap) do self.unitMap[k] = nil end local count = #self.unitList for i = 1, count do self.unitList[i]:recycle() table.remove(self.unitList) end self.mainUnit = nil end function BattleTeam:useNormalSkill(matchType, count, isFinalAction, effectType, actionState, callback) self.isFinalAction = isFinalAction local unit = nil if matchType == nil then unit = self.unitList[1] else unit = self.unitMap[matchType] end if unit == nil then return callback() end if unit:getIsLimit() then return callback() end self.mainUnit = unit unit:beforeAttack(actionState) unit:resetBeforeAttack() unit:useNormalSkill(count, effectType, callback) end function BattleTeam:useSkill(matchType, count, isFinalAction, effectType, actionState, callback) self.isFinalAction = isFinalAction local unit = nil if matchType == nil then unit = self.unitList[1] else unit = self.unitMap[matchType] end if unit == nil then return callback() end if unit:getIsLimit() then return callback() end local lastMainUnit = self.mainUnit self.mainUnit = unit unit:beforeAttack(actionState) unit:resetBeforeAttack() if unit:useSkill(1, count, callback) then if lastMainUnit and lastMainUnit ~= unit then lastMainUnit:playSwitchOut() end else if lastMainUnit and lastMainUnit ~= unit then self.mainUnit = lastMainUnit end end end function BattleTeam:useAssistingSkill(assistingList, isFinalAction, callback) self.isFinalAction = isFinalAction if self.mainUnit == nil then return callback() end if self.mainUnit:getIsLimit() then return callback() end local count = #assistingList if count <= 0 then return callback() end self:setCentralizedAttack(true) local function finish() count = count - 1 if count == 0 then self:setCentralizedAttack(false) callback() end end local delay = 0 for _, v in ipairs(assistingList) do local unit = self.unitMap[v.skillMatch] if unit then unit:resetBeforeAttack() unit:useAssistingSkill(v.count, delay, finish) delay = delay + BattleHelper:getSupportInterval() else finish() end end end function BattleTeam:mainUnitUseAllSkills(actionState, callback) self.isFinalAction = true if self.mainUnit == nil then return callback() end if self.mainUnit:getIsLimit() then return callback() end self.mainUnit:beforeAttack(actionState) self.mainUnit:resetBeforeAttack() self.mainUnit:useAllSkills(callback) end function BattleTeam:changeMainUnit(matchType) if self.mainUnit and matchType == self.mainUnit:getMatchType() then return end local unit = self.unitMap[matchType] if unit == nil then return end self.mainUnit:playSwitchOut() self.mainUnit = unit unit:playSwitchIn() end -- 回合结束的时候要结算buff和技能 function BattleTeam:onRoundEnd() for k, v in ipairs(self.unitList) do v:onRoundEnd() end self:doBuffWork() self.comboCount = 0 self:getMainUnit():changeState(BattleConst.UNIT_STATE.IDLE) end function BattleTeam:addShield(buffEffect) if buffEffect then table.insert(self.shieldBuffList, buffEffect) end end function BattleTeam:removeShield(buffEffect) for k, v in ipairs(self.shieldBuffList) do if v == buffEffect then table.remove(self.shieldBuffList, k) break end end end function BattleTeam:handleShield(reduceShield, unit) if #self.shieldBuffList <= 0 then return end local needReedRefreshBuff = false local currShieldBuff = self.shieldBuffList[1] while currShieldBuff do reduceShield = reduceShield + currShieldBuff.result if reduceShield > 0 then currShieldBuff.result = reduceShield reduceShield = 0 break else currShieldBuff.result = 0 for k, v in ipairs(self.buffList) do if v == currShieldBuff then if not needReedRefreshBuff and currShieldBuff.buff:getIcon() then needReedRefreshBuff = true end self:updateBuffState(currShieldBuff.buff, -1) table.remove(self.buffList, k) BattleBuffHandle.removeBuff(unit, currShieldBuff) currShieldBuff = nil break end end if currShieldBuff then table.remove(self.shieldBuffList, 1) end end currShieldBuff = self.shieldBuffList[1] end if needReedRefreshBuff then self.battleController:refreshBuff(self.side, self.buffList) end end function BattleTeam:addBuff(buffEffect) local stack = buffEffect.buff:getStack() local needRecycle if not stack or stack == BattleConst.BUFF_STACK_TYPE.CANT_ADD then local buffName = buffEffect.buff:getName() local buffNum = self.sameBuffCount[buffName] if buffNum and buffNum > 0 then for _, bEffect in ipairs(self.buffList) do if bEffect.buff:getName() == buffName then if bEffect.round < buffEffect.round then bEffect.round = buffEffect.round for fieldName, v in pairs(bEffect) do if fieldName ~= "buff" and fieldName ~= "round" and fieldName ~= "result" then bEffect[fieldName] = buffEffect[fieldName] end end needRecycle = bEffect break else return bEffect end end end end elseif stack == BattleConst.BUFF_STACK_TYPE.ADD_ROUND then local buffName = buffEffect.buff:getName() local buffNum = self.sameBuffCount[buffName] if buffNum and buffNum > 0 then for _, bEffect in ipairs(self.buffList) do if bEffect.buff:getName() == buffName then bEffect.round = bEffect.round + buffEffect.round for fieldName, v in pairs(bEffect) do if fieldName ~= "buff" and fieldName ~= "round" and fieldName ~= "result" then bEffect[fieldName] = buffEffect[fieldName] end end needRecycle = bEffect break end end end elseif stack == BattleConst.BUFF_STACK_TYPE.ADD then end if needRecycle then BattleHelper:recycleBuffEffect(buffEffect) else table.insert(self.buffList, buffEffect) self:updateBuffState(buffEffect.buff, 1) if buffEffect.buff:getIcon() then self.battleController:refreshBuff(self.side, self.buffList) end needRecycle = buffEffect end return needRecycle end function BattleTeam:removeAllBuff() local buffEffect = nil local count = #self.buffList for i = count, 1, -1 do buffEffect = self.buffList[i] if buffEffect and not buffEffect.buff:isCantRemove() then self:updateBuffState(buffEffect.buff, -1) table.remove(self.buffList, i) BattleBuffHandle.removeBuff(self.mainUnit, buffEffect) end end if self.cacheBuffDecr then for decr, list in pairs(self.cacheBuffDecr) do count = #list for i = count, 1, -1 do buffEffect = self.cacheBuffDecr[decr][i] table.remove(self.cacheBuffDecr[decr], i) BattleHelper:recycleBuffEffect(buffEffect) end end end self.battleController:clearBuff(self.side) end function BattleTeam:putCacheBuff(buffEffect) local buffDecr = buffEffect.buff:getDecr() if not self.cacheBuffDecr[buffDecr] then self.cacheBuffDecr[buffDecr] = {} end table.insert(self.cacheBuffDecr[buffDecr], buffEffect) end function BattleTeam:putCacheBuffByDecr(buffDecr) if not buffDecr then return end local needRefresh = false local buffEffect = nil local count = #self.buffList for i = count, 1, -1 do buffEffect = self.buffList[i] if buffEffect and buffEffect.buff:getDecr() == buffDecr and not buffEffect.buff:isCantRemove() then self:updateBuffState(buffEffect.buff, -1) table.remove(self.buffList, i) BattleBuffHandle.removeBuff(self.mainUnit, buffEffect, true) if not self.cacheBuffDecr[buffDecr] then self.cacheBuffDecr[buffDecr] = {} end table.insert(self.cacheBuffDecr[buffDecr], buffEffect) if buffEffect.buff:getIcon() then needRefresh = true end end end if needRefresh then self.battleController:refreshBuff(self.side, self.buffList) end end function BattleTeam:popCacheBuffByDecr(buffDecr) if not buffDecr or not self.cacheBuffDecr or not self.cacheBuffDecr[buffDecr] then return end local list = self.cacheBuffDecr[buffDecr] local needRefresh = false local count = #list local buffEffect for i = count, 1, -1 do buffEffect = self.cacheBuffDecr[buffDecr][i] self:getMainUnit():reTakeEffectByBuffEffect(buffEffect) table.remove(self.cacheBuffDecr[buffDecr]) if buffEffect.buff:getIcon() then needRefresh = true end end if needRefresh then self.battleController:refreshBuff(self.side, self.buffList) end end function BattleTeam:doBuffWork() local count = nil local buffEffect = nil if self.cacheBuffDecr then for decr, list in pairs(self.cacheBuffDecr) do count = #list for i = count, 1, -1 do buffEffect = self.cacheBuffDecr[decr][i] buffEffect.round = buffEffect.round - 1 if buffEffect.round <= 0 then table.remove(self.cacheBuffDecr[decr], i) BattleHelper:recycleBuffEffect(buffEffect) end end end end count = #self.buffList if count <= 0 then return end buffEffect = nil for i = count, 1, -1 do buffEffect = self.buffList[i] buffEffect.round = buffEffect.round - 1 BattleBuffHandle.doBuffWork(self.mainUnit, buffEffect) if buffEffect.round <= 0 then self:updateBuffState(buffEffect.buff, -1) table.remove(self.buffList, i) BattleBuffHandle.removeBuff(self.mainUnit, buffEffect) end end self.battleController:refreshBuff(self.side, self.buffList) end function BattleTeam:removeBuffByName(buffName) local count = #self.buffList if count <= 0 then return end local buffEffect = nil for i = count, 1, -1 do buffEffect = self.buffList[i] if buffEffect.buff:getName() == buffName then self:updateBuffState(buffEffect.buff, -1) table.remove(self.buffList, i) BattleBuffHandle.removeBuff(self.mainUnit, buffEffect) end end self.battleController:refreshBuff(self.side, self.buffList) end function BattleTeam:updateBuffState(buff, num) local buffName = buff:getName() local buffNum = (self.sameBuffCount[buffName] or 0) + num self.sameBuffCount[buffName] = buffNum if buffNum == 0 then -- 移除buff local fxList = buff:getFxContinued() if fxList then local fxCfg = BattleHelper:getFxConfig() for k, v in ipairs(fxList) do local fxInfo = fxCfg[v] if fxInfo then local res = fxInfo.res local count = self.loopFxMap[res] or 0 self.loopFxMap[res] = count - 1 if count == 1 then for k2, v2 in ipairs(self.unitList) do v2:removeFx(res) end end end end end local fxDisappear = buff:getFxDisappear() if fxDisappear then local fxCfg = BattleHelper:getFxConfig() for k, v in ipairs(fxDisappear) do local fxInfo = fxCfg[v] if fxInfo then self.mainUnit:getEffectAndPlay(fxInfo, false) end end end elseif buffNum == 1 then -- 新添加buff local fxList = buff:getFxContinued() if fxList then local fxCfg = BattleHelper:getFxConfig() for k, v in ipairs(fxList) do local fxInfo = fxCfg[v] if fxInfo then local res = fxInfo.res local count = self.loopFxMap[res] or 0 self.loopFxMap[res] = count + 1 if count == 0 then for k2, v2 in ipairs(self.unitList) do v2:getEffectAndPlay(fxInfo, true) end end end end end end end function BattleTeam:getBuffCountByName(buffName) return self.sameBuffCount[buffName] or 0 end function BattleTeam:getLoopFxResCount(res) return self.loopFxMap[res] or 0 end function BattleTeam:getUnitComp() return self.unitMap end function BattleTeam:getIsBoss() if self.mainUnit == nil then return false end return self.mainUnit:getIsBoss() end function BattleTeam:playRunAction() if self.mainUnit then self.mainUnit:playRunAction() end end function BattleTeam:stopRunAction() if self.mainUnit then self.mainUnit:stopRunAction() end end function BattleTeam:recoverHpOnWaveOver(callback) if self.mainUnit then self.mainUnit:recoverHpOnWaveOver(callback) else callback() end end function BattleTeam:getCentralizedAttack() return self.centralizedAttack end function BattleTeam:setCentralizedAttack(centralizedAttack) if not self.isFinalAction and not centralizedAttack then return end self.centralizedAttack = centralizedAttack end function BattleTeam:addCombo() if self.side ~= BattleConst.SIDE_ATK then return end if not self.battleController:getIsAtkStep() then return end self.comboCount = self.comboCount + 1 self.battleController:showCombo(self.comboCount) if self.comboCount == 10 then self.battleController:addTaskProgress(BattleConst.BATTLE_TASK_FIELD.COMBO_OVER_10, 1) end end function BattleTeam:onActionOver() -- 处理反击 local counterAttackCount = self:getMainUnit().unitEntity:getCounterAttackCount() if counterAttackCount <= 0 then return end self:getMainUnit().unitEntity:clearCounterAttackCount() local teamAction = function() ---- 普攻 local skillMatch if self.side == BattleConst.SIDE_ATK then self.battleController.roundStep = BattleConst.BATTLE_ROUND_STEP.ON_ATK_STEP self.battleController.curTeam = self.battleController.atkTeam skillMatch = self:getMainUnit().unitEntity:getMatchType() else self.battleController.roundStep = BattleConst.BATTLE_ROUND_STEP.ON_DEF_STEP self.battleController.curTeam = self.battleController.defTeam end self:useNormalSkill(skillMatch, counterAttackCount, true, BattleConst.EFFECT_TYPE.DIRECT, BattleConst.ATTACK_ACTION_STATE.COUNTERATTACK, function() self.battleController:enterNextTeamAction() end) end self.battleController:addTeamActionList(teamAction, 1) self.comboCount = 0 end function BattleTeam:tick(dt) for k, v in ipairs(self.unitList) do v:tick(dt) end end return BattleTeam