593 lines
14 KiB
Lua
593 lines
14 KiB
Lua
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 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 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:setIsFinalBlock(isFinalBlock)
|
|
if not self.isFinalBlock and not isFinalBlock then
|
|
return
|
|
end
|
|
self.isFinalBlock = isFinalBlock
|
|
end
|
|
|
|
function BattleTeam:getIsFinalBlock()
|
|
return self.isFinalBlock
|
|
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 |