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.enemys = {} --怪 self.cachePassiveEvent = {} self:initPlayer() self:initEnemys() self:initAfter() if self.isNewPlayer then self.player:triggerPassive(Passive.BORN_ONCE) self.player:addExp((self.adv.level - 1) * 40) end end function Battle:initAfter() self.player:initAfter(self.adv.owner:getProperty("advTeam").player) for idx, mapEnemys in pairs(self.enemys) do for _, enemy in ipairs(mapEnemys) do enemy:initAfter(self.adv:getBlock(enemy.roomId, enemy.blockId, idx).event.enemy) end end end --[[ 队伍总属性 = 基础属性 + 等级 × 成长率 基础属性: 固定属性,与章节、队伍够成、养成无关,由策划给出 等级: 根据进入时的关卡,获得一个【初始等级】;消灭怪物获得经验后,累计N点会提升等级 羁绊加成: 加成条件与“战斗”相同,加成目标改为【冒险队】 成长率: 由【队伍总生存力】决定 成长率 =(总生存力 / 80)^0.52 + INT(总角色等级 / 50)* 1 --]] function Battle:initPlayer() local advTeam = self.adv.owner:getProperty("advTeam") if not next(advTeam.heros) then return end local player = advTeam.player if not player then player = {} player.passives = {} local heroLevel = 0 for slot, heroId in pairs(advTeam.heros) do local hero = self.adv.owner.heros[heroId] if hero then heroLevel = heroLevel + hero:getProperty("level") local advSkillId = csvdb["unitCsv"][self.adv.owner.heros[heroId]:getProperty("type")]["adv"] if advSkillId > 1000 then table.insert(player.passives, {id = advSkillId, level = hero:getSkillLevel(4)}) end end end player.growth = (self.adv.owner:getRealBattleValue(advTeam.heros) / 80) ^ 0.52 + math.floor(heroLevel / 50) / 50 player.level = 1 player.exp = 0 player.sp = 100 local activeRelation = self.adv.owner:getHeroActiveRelation() local baseAttr = csvdb["adv_unitCsv"][self.adv.chapterId] for _, attr in pairs(AttsEnumEx) do if baseAttr[attr] then player[attr] = baseAttr[attr] + player.growth * (player.level - 1) end end player.hpMax = player.hp or 0 self.isNewPlayer = true advTeam.player = player end self.player = Player.new(self, player) end function Battle:initEnemys() for idx, map in pairs(self.adv.maps) do self:initMapEnemys(idx) end end function Battle:initMapEnemys(mapIdx) self.enemys[mapIdx] = {} local map = self.adv.maps[mapIdx] if map then for _, room in pairs(map.rooms) do for _, block in pairs(room.blocks) do self:addEnemy(room, block, mapIdx) end end end if self.cachePassiveEvent[mapIdx] then for _, passiveC in ipairs(self.cachePassiveEvent or {}) do for _, enemy in ipairs(self.enemys[mapIdx]) do enemy:triggerPassive(passiveC[1], passiveC[2]) end end end self.cachePassiveEvent[mapIdx] = nil end function Battle:addEnemy(room, block, mapIdx) mapIdx = mapIdx or self.adv:getCurMapIdx() if block:isMonster() 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.level enemy.atk = enemyCsv.atk + enemyCsv.levelatk * self.adv.level enemy.hit = enemyCsv.hit + enemyCsv.levelhit * self.adv.level enemy.miss = enemyCsv.miss + enemyCsv.levelmiss * self.adv.level enemy.def = enemyCsv.def + enemyCsv.leveldef * self.adv.level enemy.passives = {} for _, id in ipairs(enemyCsv.mapPassive: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, mapIdx) table.insert(self.enemys[mapIdx], player) return player end end function Battle:getEnemy(roomId, blockId, mapIdx) mapIdx = mapIdx or self.adv:getCurMapIdx() for _, enemy in ipairs(self.enemys[mapIdx] or {}) do if enemy.roomId == roomId and enemy.blockId == blockId then return enemy end end end function Battle:getEnemyById(id) for idx, mapEnemys in pairs(self.enemys) do for _, enemy in ipairs(mapEnemys) do if enemy.id == id then return enemy end end end end function Battle:getRBByEnemyId(enemyId) local enemy = self:getEnemyById(enemyId) return enemy.roomId, enemy.blockId, enemy.mapIdx end --触发全员被动技能 function Battle:triggerPassive(condType, params, mapIdx) mapIdx = mapIdx or self.adv:getCurMapIdx() self.player:triggerPassive(condType, params) if not self.enemys[mapIdx] then -- 缓存一下 self.cachePassiveEvent[mapIdx] = self.cachePassiveEvent[mapIdx] or {} table.insert(self.cachePassiveEvent[mapIdx], {condType, params}) else for _, enemy in ipairs(self.enemys[mapIdx]) do enemy:triggerPassive(condType, params) end end end --回合 function Battle:afterRound() local mapIdx = self.adv:getCurMapIdx() self.player:afterRound() table.sort(self.enemys[mapIdx], function(e1, e2) return e1.id < e2.id end) for _, enemy in ipairs(self.enemys[mapIdx]) do enemy:afterRound() end self.player:clearRound() for _, enemy in ipairs(self.enemys[mapIdx]) do enemy:clearRound() end for i = #self.enemys[mapIdx], 1, -1 do if self.enemys[mapIdx][i].isDead then local enemy = table.remove(self.enemys[mapIdx], i) self.adv:enemyDead(enemy, enemy.isDead == 1) enemy:clear() end end if self.player.isDead then self.adv:over(false) end end function Battle:battleBegin(roomId, blockId, params) local enemy = self:getEnemy(roomId, blockId) if not enemy then return end local player = params.player -- 玩家没死就是怪死了 if player.hp > 0 then enemy:hurt(enemy.hp, self.player, {hurtType = 5}) self.player:effectBattleBuff() self.adv.owner:checkTaskEnter("AdvBattleWin", {id = self.adv.chapterId}) end if player.hp > self.player.hp then self.player:recover(player.hp - self.player.hp, player) else self.player:hurt(math.max(0, math.ceil(self.player.hp - player.hp)), enemy, {hurtType = 5}) --战斗血量只会变少 end self.player:changeSp(math.floor(player.sp - self.player.sp) , 0) --战斗魔力只会变少 end --写入数据 function Battle:saveDB() for idx, mapEnemys in pairs(self.enemys) do for _, enemy in ipairs(mapEnemys) do local block = self.adv:getBlock(enemy.roomId, enemy.blockId, idx) if block and block:isMonster() then block.event.enemy = enemy:getDB() end end end end return Battle