-- 角色 local Buff = require "adv.AdvBuff" local Skill = require "adv.AdvSkill" local Passive = require "adv.AdvPassive" local BaseObject = class("BaseObject") function BaseObject:ctor(battle) self.battle = battle self.hpMax = 0 self.hp = 0 self.atk = 0 self.def = 0 self.aType = 0 --攻击类型 self.lock = nil self.passives = {} --固有技能 self.buffs = {} --buff self.skillOrder = {} --战斗内技能序列 self.isDead = false end --初始化角色 function BaseObject:initData(data) self.hpMax = data.hpMax or data.hp self.hp = data.hp --可变化的值 self.atk = data.atk self.miss = data.miss self.hit = data.hit self.def = data.def --基础值记录 self._atk = data._atk or self.atk self._miss = data._miss or self.miss self._hit = data._hit or self.hit self._def = data._def or self.def end -- 角色初始化完以后才是 技能和被动技能 方便初始化 buff 的 释放对象 function BaseObject:initAfter(data) for _, passive in ipairs(data.passives or {}) do table.insert(self.passives, Passive.new(self, passive)) end for _, buff in ipairs(data.buffs or {}) do table.insert(self.buffs, Buff.load(self, buff)) end end function BaseObject:reset(data) self.passives = {} self.buffs = {} self:initData(data) self:initAfter(data) end function BaseObject:afterRound() for _, passive in ipairs(self.passives) do passive:afterRound(self) end for _, buff in ipairs(self.buffs) do buff:afterRound() end end function BaseObject:clearRound() for i = #self.passives, 1, -1 do if self.passives[i].isDel then self.passives[i]:endPassive() table.remove(self.passives, i) end end for i = #self.buffs, 1, -1 do if self.buffs[i].isDel then self.battle.adv:backBuff(self.id, self.buffs[i].id, true) self.buffs[i]:endBuff() table.remove(self.buffs, i) end end end function BaseObject:clear() self.buffs = {} self.passives = {} end function BaseObject:battleBegin() for _, passive in ipairs(self.passives) do passive:battleBegin() end end function BaseObject:battleEnd() for _, buff in ipairs(self.buffs) do buff:battleEnd() end end function BaseObject:addPassive(params) local skillId = params.id local skillData = csvdb["adv_map_passiveCsv"][skillId] if not skillData then return end local level = params.level or 1 if not skillData[level] then return end table.insert(self.passives, Passive.new(self, { id = skillId, level = level })) self.battle.adv:backPassive(self.id, skillId) end function BaseObject:addBuff(buffId, releaser) local buffData = csvdb["adv_map_buffCsv"][buffId] if not buffData then return end for _, buff in ipairs(self.buffs) do if not buff.isDel and (buff:getType() == Buff.CLEAR_BUFF or buff:getType() == Buff.IMMNUE_BUFF) then if buff:canEffect(buffId, buffData.group) then buff:effect() return end end end table.insert(self.buffs, Buff.create(self, releaser, {id = buffId})) self.battle.adv:backBuff(self.id, buffId) end function BaseObject:hadBuff(bType) for _, buff in ipairs(self.buffs) do if not buff.isDel and buff:getType() == bType then return true end end end function BaseObject:hadBuffById(bId) for _, buff in ipairs(self.buffs) do if not buff.isDel and buff.id == bId then return true end end end -- 通用的buff 效果汇总 -- 0 固定 1百分比 两种分类 function BaseObject:getCommonBuffEffect(bType) local effect, count = {[0] = 0, [1] = 0}, 0 for _, buff in ipairs(self.buffs) do if not buff.isDel and buff:getType() == bType then local cType, value = buff:effect() if cType then effect[cType] = effect[cType] + value count = count + 1 end end end effect[1] = effect[1] / 100 return effect, count --效果 和生效的buff 个数 end --伤害反弹 function BaseObject:getBackHurtBuff(isAtk) local effect = {[0] = 0, [1] = 0} for _, buff in ipairs(self.buffs) do if not buff.isDel and buff:getType() == Buff.BACK_HURT then local cType, value, aType = buff:effect() -- aType 0 全部 1 普通攻击 if cType then if aType == 0 or isAtk then effect[cType] = effect[cType] + value end end end end return effect end --释放者伤害变化 function BaseObject:getHurtChange() local change = self:getCommonBuffEffect(Buff.HURT_CHANGE) return change end --受伤者受伤变化 function BaseObject:getInjuredChange() local change = self:getCommonBuffEffect(Buff.INJURED_CHANGE) return change end --重新计算属性 function BaseObject:reSetAttr(field) local old = self[field] self[field] = self["_" .. field] --重置一下 local fieldToBuff = {atk = Buff.ATK_CHANGE, hit = Buff.HIT_CHANGE, miss = Buff.MISS_CHANGE, def = Buff.DEF_CHANGE} local effect = self:getCommonBuffEffect(fieldToBuff[field]) self[field] = math.ceil((self[field] + effect[0]) * (1 + effect[1])) local delta = self[field] - old if delta ~= 0 then if field == "atk" then self.battle.adv:backAtkChange(self.id, delta) elseif field == "def" then self.battle.adv:backDefChange(self.id, delta) end end end --计算打出伤害加成后的值 function BaseObject:getHurtValue(value) value = value or self.atk local hurtChange = self:getHurtChange() return math.max(0, (value + hurtChange[0]) * (1 + hurtChange[1])) end --计算自己伤害减免后的值 function BaseObject:getInjuredValue(value) local injuredChange = self:getInjuredChange() return math.max(0, (value + injuredChange[0]) * (1 + injuredChange[1]) - self.def) end --最终伤害 = [ (敌方攻击 - 己方防御) * (1+伤害增加百分比-伤害减少百分比)*(1+受伤增加百分比-受伤减少百分比)+(伤害增加固定值-伤害增加固定值+受伤增加固定值-受伤增加固定值)]*(1+侍宠百分比)-侍宠固定值 -- params -- hurtType 1 普攻伤害 2 buff伤害 3 反弹伤害 4 真实伤害 5 客户端发回来的伤害 --直接作用 --进入这个方法之前计算好释放者加成的伤害 function BaseObject:hurt(value, releaser, params) params = params or {} if params.hurtType and params.hurtType == 1 then releaser:triggerPassive(Passive.SELF_ATK) for _, team in ipairs(releaser:getTeam(1, true)) do team:triggerPassive(Passive.TEAM_ATK) end if self:hadBuff(Buff.IMMNUE_ATK) then return end --无视普通攻击 local hit = releaser.hit - self.miss --命中率 if hit < math.randomInt(1, 100) then --miss self.battle.adv:backMiss(self.id) return end self:triggerPassive(Passive.SELF_HURT, {trigger = releaser}) for _, team in ipairs(self:getTeam(1, true)) do team:triggerPassive(Passive.TEAM_HURT, {trigger = releaser}) end end if params.hurtType ~= 5 then if not params.hurtType or params.hurtType ~= 4 then value = self:getInjuredValue(value) --减伤计算 end if value == 0 then return end -- 舍身和恃宠 local team = self:getTeam(1) local transfer = {} local absorb = {} for _, one in ipairs(team) do local change1, count1 = one:getCommonBuffEffect(Buff.INJURED_CHANGE) local change2, count2 = one:getCommonBuffEffect(Buff.HURT_ABSORB) if count1 > 0 then table.insert(transfer, {one, change1, count1}) end if count2 > 0 then table.insert(absorb, {one, change2, count2}) end end if #absorb == 1 then --舍身优先级高 --舍身生效 if absorb[1][1] ~= self then --舍身的人不是自己才有效 local absorbV = (value - absorb[1][2][0]) * absorb[1][2][1] + absorb[1][2][0] --固定值先生效 value = value - absorbV absorb[1][1]:hurt(absorbV, releaser, params) end else if #transfer == 1 and transfer[1][1] == self and #team > 1 then --侍宠 生效 local transferValue = (value - transfer[1][2][0])* transfer[1][2][1] + transfer[1][2][0] --固定值先生效 value = value - transferValue local oneValue = transferValue / (#team - 1) for _, one in ipairs(team) do if one ~= self then one:hurt(oneValue, releaser, params) end end end end end value = math.max(0, math.ceil(value)) if value == 0 then return end -- 反弹伤害 if params.hurtType ~= 3 and params.hurtType ~= 5 and releaser and not releaser.isDead then local backEffect = self:getBackHurtBuff(params.hurtType == 1) local backValue = math.max(0, value * backEffect[1] + backEffect[0]) releaser:hurt(backValue, releaser, {hurtType = 3}) end --受伤了~ self.battle.adv:backHpChange(self.id, -value) self.hp = math.max(0, self.hp - value) if self.cutHp then self:cutHp(value) end if self.hp == 0 then self:triggerPassive(Passive.SELF_DEAD) for _, team in ipairs(self:getTeam(1, true)) do team:triggerPassive(Passive.TEAM_DEAD) end self.isDead = true self.battle.adv:backDead(self.id) end self:triggerPassive(Passive.HURT_PERCENT_SELF, {value = value / self.hpMax}) for _, team in ipairs(self:getTeam(1, true)) do team:triggerPassive(Passive.HURT_PERCENT_TEAM, {value = value / self.hpMax}) end end --恢复 function BaseObject:recover(value, releaser, params) params = params or {} value = math.max(0, math.ceil(value)) self.hp = math.min(self.hpMax, self.hp + value) self.battle.adv:backHpChange(self.id, value) end function BaseObject:addSpecialSkill(skillId, skillLevel, target) local skillData = {id = skillId, level = skillLevel, target = target} table.insert(self.skillOrder, skillData) end function BaseObject:releaseSkill(skillId, target) if self:hadBuff(Buff.CANT_SKILL) then return end -- 针对 怪物 local skill = Skill.new(self, {id = skillId, target = target}) --返回客户端 for _, target in ipairs(skill:getTargets()) do self.battle.adv:backSkill(self.id, skillId, target.id) end skill:doEffect() for _, team in ipairs(self:getTeam(2)) do team:triggerPassive(Passive.TARGET_SKILL) end for _, team in ipairs(self:getTeam(1, true)) do team:triggerPassive(Passive.TEAM_SKILL) end end --0 全部 1 我方 2 敌方 function BaseObject:getTeam(nType, noSelf) nType = nType or 0 local team = {} local function addPlayer() if not noSelf or self.battle.player ~= self then if not self.battle.player.isDead then table.insert(team, self.battle.player) end end end local function addEnemy() for _, enemy in pairs(self.battle.enemys) do if not noSelf or enemy ~= self then if not enemy.isDead and not enemy.lock then -- 已经翻开的 table.insert(team, enemy) end end end end if nType == 0 then addPlayer() addEnemy() elseif nType == 1 then if not self.monsterId then --玩家 addPlayer() else addEnemy() end elseif nType == 2 then if not self.monsterId then --玩家 addEnemy() else addPlayer() end end return team end function BaseObject:getDB() local db = {} db.hpMax = self.hpMax db.hp = self.hp local baseAttr = {"atk", "miss", "hit", "def"} for _, field in pairs(baseAttr) do db[field] = self[field] db["_"..field] = self["_" .. field] end db.passives = {} for _, passive in ipairs(self.passives) do table.insert(db.passives, passive:getDB()) end db.buffs = {} for _, buff in ipairs(self.buffs) do table.insert(db.buffs, buff:getDB()) end return db end function BaseObject:triggerPassive(condType, params) if self.isDead then return end for _, passive in ipairs(self.passives) do passive:trigger(condType, params) --检查触发 end end function BaseObject:changeSp() end local Enemy = class("Enemy", BaseObject) function Enemy:ctor(battle, mId, monsterId, roomId, blockId, lock, enemy) Enemy.super.ctor(self, battle) self.id = mId self.monsterId = monsterId --数据id self.roomId = roomId self.blockId = blockId self.lock = lock self:initData(enemy) end function Enemy:unlock(id) self.id = id self.lock = nil end local Player = class("Player", BaseObject) function Player:ctor(battle, data) Player.super.ctor(self, battle) self:initData(data) end function Player:cutHp(value) self.battle.adv:scoreChange(AdvScoreType.Hurt, value) end function Player:initData(data) Player.super.initData(self, data) self.level = data.level or 1 --level 每增加1级 属性增长 growth * baseAttr self.growth = data.growth or 0 self.exp = data.exp or 0 self.sp = data.sp or 100 end function Player:addExp(value) -- todo end --cType 0 or nil 值 1 百分比 function Player:changeSp(value, cType) cType = cType or 0 if cType == 0 then self.sp = self.sp + value elseif cType == 1 then self.sp = self.sp + self.sp * value / 100 end self.sp = math.floor(math.max(0, self.sp)) self.battle.adv:pushBackEvent(AdvBackEventType.SpChange) end function Player:getDB() local db = Player.super.getDB(self) for _ , field in pairs({"level", "exp", "growth", "sp"}) do db[field] = self[field] end return db end return table.pack(Player, Enemy)