local Player, Enemy = table.unpack(require "adv.advPlayer") local Buff = require "adv.AdvBuff" local Passive = require "adv.AdvPassive" local Battle = class("Battle") function Battle:ctor(adv) self.adv = adv self.player = nil --玩家 self.isNewPlayer = false self.enemy = nil self.enemys = {} --怪 self.tempData = {} -- 临时回合数据 self:initPlayer() self:initEnemys() self:initAfter() if self.isNewPlayer then self.player:triggerPassive(Passive.BORN_ONCE) end end function Battle:initAfter() self.player:initAfter(self.adv.advTeam.player) for _, enemy in pairs(self.enemys) do enemy:initAfter(self.adv.rooms[enemy.roomId].blocks[enemy.blockId].event.enemy) end if self.adv.advTeam.enemyId then local enemy = self:getEnemyById(self.adv.advTeam.enemyId) self.enemy = enemy end end function Battle:initPlayer() if not next(self.adv.advTeam.heros) then return end if not self.adv.advTeam.player then local hp = 0 local player = {} player.passives = {} for slot, heroId in pairs(self.adv.advTeam.heros) do if self.adv.owner.heros[heroId] then hp = hp + self.adv.owner.heros[heroId]:getProperty("battleV") local advSkillId = csvdb["unitCsv"][self.adv.owner.heros[heroId]:getSkinId()]["adv"] if advSkillId > 1000 then table.insert(player.passives, {id = advSkillId, level = self.adv.owner.heros[heroId]:getSkillLevel(4)}) end end end player.hp = hp player.atk = tonumber(string.format("%0.0f", player.hp * 0.1)) --todo 系数是临时的 player.def = 0 player.miss = 0 player.hit = 100 self.adv.advTeam.player = player self.isNewPlayer = true end self.player = Player.new(self, self.adv.advTeam.player) end function Battle:initEnemys() for _, room in pairs(self.adv.rooms) do for _, block in pairs(room.blocks) do self:addEnemy(room, block) end end end function Battle:addEnemy(room, block) if block.event and (block.event.etype == AdvEventType.BOSS or block.event.etype == AdvEventType.Monster) then if not block.event.enemy then local enemyCsv = csvdb["event_monsterCsv"][block.event.id] local enemy = {} enemy.hp = enemyCsv.hp + enemyCsv.levelhp * self.adv.advInfo.level enemy.atk = enemyCsv.atk + enemyCsv.levelatk * self.adv.advInfo.level enemy.hit = enemyCsv.hit + enemyCsv.levelhit * self.adv.advInfo.level enemy.miss = enemyCsv.miss + enemyCsv.levelmiss * self.adv.advInfo.level enemy.def = enemyCsv.def + enemyCsv.leveldef * self.adv.advInfo.level enemy.passives = {} for _, id in ipairs(enemyCsv.passive:toArray(true, "=")) do table.insert(enemy.passives, {id = id}) end block.event.enemy = enemy end local player = Enemy.new(self, block.event.mId or 999, block.event.id, room.roomId, block.blockId, not block.isOpen, block.event.enemy) table.insert(self.enemys, player) return player end end function Battle:getEnemy(roomId, blockId) for _, enemy in ipairs(self.enemys) do if enemy.roomId == roomId and enemy.blockId == blockId then return enemy end end end function Battle:getEnemyById(id) for _, enemy in ipairs(self.enemys) do if enemy.id == id then return enemy end end end function Battle:getRBByEnemyId(enemyId) local enemy = self:getEnemyById(enemyId) return enemy.roomId, enemy.blockId end function Battle:isBattleEnd() if not self.enemy then return true end end --战斗开始 function Battle:battleBegin(roomId, blockId) self.tempData = {} -- 清理上次战斗数据 if self.enemy then self.player:reset(self.adv.advTeam.player) self.enemy:reset(self.adv.rooms[self.enemy.roomId].blocks[self.enemy.blockId].event.enemy) end local enemy = self:getEnemy(roomId, blockId) if enemy then self.enemy = enemy self.player:battleBegin() self.enemy:battleBegin() self:doBattleTurn() end end -- 检查回合数同步 function Battle:checkTurn(turn) if self.tempData[turn] then return true end end -- 战斗内一回合 function Battle:doBattleTurn() local enemy = self.enemy -- 玩家先出手 self.adv:backAtk(nil, enemy.id) self:doPlayerTurn(self.player, enemy) --是否无法攻击 if not enemy.isDead and not enemy:hadBuff(Buff.CANT_BACK_ATK) then self.adv:backAtk(enemy.id, nil) self:doPlayerTurn(enemy, self.player) end -- 判定死亡 if enemy.isDead or self.player.isDead then local deadPlayer = enemy.isDead and enemy or self.player deadPlayer:battleEnd() self.enemy = nil else self.adv:backTurnEnd() end self:getTempDB() end --战斗内角色回合逻辑 function Battle:doPlayerTurn(atkPlayer, hurtPlayer) atkPlayer:beforeTurn() if #(atkPlayer.skillOrder) > 0 then atkPlayer:releaseSpecialSkill() else hurtPlayer:hurt(atkPlayer:getHurtValue(), atkPlayer, {hurtType = 1}) end atkPlayer:afterTurn() atkPlayer:clearTurn() end --触发全员被动技能 function Battle:triggerPassive(condType, params) self.player:triggerPassive(condType, params) for _, enemy in ipairs(self.enemys) do enemy:triggerPassive(condType, params) end end --回合 function Battle:afterRound() self.player:afterRound() table.sort(self.enemys, function(e1, e2) return e1.id < e2.id end) for _, enemy in ipairs(self.enemys) do enemy:afterRound() end self.player:clearRound() for _, enemy in ipairs(self.enemys) do enemy:clearRound() end for i = #self.enemys, 1, -1 do if self.enemys[i].isDead then self.adv:enemyDead(self.enemys[i].roomId, self.enemys[i].blockId) self.enemys[i]:clear() table.remove(self.enemys, i) end end if self.adv.advInfo.power > 0 then self.adv:changePower(-1) else self.player:hurt(self.player.hpMax / 10, nil, {hurtType = 4}) end if self.player.isDead then self.adv:over(false) end end -- 写入临时数据 function Battle:getTempDB() local turnDB = {} if self.enemy then turnDB.enemy = self.enemy:getDB() end turnDB.player = self.player:getDB() table.insert(self.tempData, turnDB) end --写入数据 function Battle:getDB() if not self.enemy then self.adv.advTeam.enemyId = nil else self.adv.advTeam.enemyId = self.enemy.id return end self.adv.advTeam.player = self.player:getDB() for _, enemy in ipairs(self.enemys) do local block = self.adv.rooms[enemy.roomId].blocks[enemy.blockId] block.event.enemy = enemy:getDB() end end return Battle