miduo_client/Assets/ManagedResources/~Lua/Modules/Battle/Logic/Misc/BattleUtil.lua

1411 lines
52 KiB
Lua
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

BattleUtil = {}
--local BattleUtil = BattleUtil
local floor = math.floor
local max = math.max
local min = math.min
--local Random = Random
--local RoleDataName = RoleDataName
--local BattleEventName = BattleEventName
BattleUtil.Passivity = require("Modules/Battle/Logic/Base/Passivity")
local function table_removebyvalue(array, value, removeall)
local c, i, max = 0, 1, #array
while i <= max do
if array[i] == value then
table.remove(array, i)
c = c + 1
i = i - 1
max = max - 1
if not removeall then
break
end
end
i = i + 1
end
return c
end
local function clamp(v, minValue, maxValue)
if v < minValue then
return minValue
end
if v > maxValue then
return maxValue
end
return v
end
function BattleUtil.ErrorCorrection(f) --进行精度处理,避免前后端计算不一致
return floor(f * 100000 + 0.5) / 100000
end
function BattleUtil.FP_Mul(...)
local f = 1
for i, v in ipairs{...} do
f = floor(f * v * 100000 + 0.5) / 100000
end
return f
end
-- 选择前排
function BattleUtil.ChooseFRow(arr)
local tempArr = {}
for _, r in ipairs(arr) do
--不是放逐
if r.position <= 3 and not r:IsRealDead() and not r.isExile then
table.insert(tempArr, r)
end
end
table.sort(tempArr, function(a, b)
return a.position < b.position
end)
return tempArr
end
-- 选择后排
function BattleUtil.ChooseBRow(arr)
local tempArr = {}
for _, r in ipairs(arr) do
if r.position > 3 and not r:IsRealDead() and not r.isExile then
table.insert(tempArr, r)
end
end
table.sort(tempArr, function(a, b)
return a.position < b.position
end)
return tempArr
end
-- 选择一列(col == 0 表示第三列哦)
function BattleUtil.ChooseCol(arr, col)
local tempArr = {}
for _, role in ipairs(arr) do
if role.position % 3 == col and not role.isExile then
table.insert(tempArr, role)
end
end
table.sort(tempArr, function(a, b)
return a.position < b.position
end)
return tempArr
end
-- 选择两列
function BattleUtil.ChooseTowCol(arr)
local teamArr={}
--第一列
local oneArr = {}
for _, role in ipairs(arr) do
if role.position % 3 == 1 then
table.insert(oneArr, role)
end
end
local one=#oneArr
--第二列
local twoArr = {}
for _, role in ipairs(arr) do
if role.position % 3 == 2 then
table.insert(twoArr, role)
end
end
local two=#twoArr
--第三列
local threeArr = {}
for _, role in ipairs(arr) do
if role.position % 3 == 0 then
table.insert(threeArr, role)
end
end
local three=#threeArr
--如果每列人数相同,就选前两列
if one==two and two==three then
for key, value in pairs(oneArr) do
table.insert(teamArr,value)
end
for key, value in pairs(twoArr) do
table.insert(teamArr,value)
end
else
--如果第一列数量>第二列数量就把第一列选入
if one>two then
if one>0 then
for key, value in pairs(oneArr) do
table.insert(teamArr,value)
end
end
--如果第二列数量>=第三列数量就把第二列选入
if two>=three then
if two>0 then
for key, value in pairs(twoArr) do
table.insert(teamArr,value)
end
end
else
--如果第三列数量>第二列数量就把第三列选入
if three>0 then
for key, value in pairs(threeArr) do
table.insert(teamArr,value)
end
end
end
else
--如果第二列数量>第一列数量就把第二列选入
if two>0 then
for key, value in pairs(twoArr) do
table.insert(teamArr,value)
end
end
--如果第一列数量>第三列数量就把第一列选入
if one>=three then
if one>0 then
for key, value in pairs(oneArr) do
table.insert(teamArr,value)
end
end
else
--如果第三列数量>第一列数量就把第三列选入
if three>0 then
for key, value in pairs(threeArr) do
table.insert(teamArr,value)
end
end
end
end
end
table.sort(teamArr, function(a, b)
return a.position < b.position
end)
return teamArr
end
-- 根据属性排序
function BattleUtil.SortByProp(arr, prop, sort)
BattleUtil.Sort(arr, function(a, b)
local r1 = a:GetRoleData(prop)
local r2 = b:GetRoleData(prop)
if sort == 1 then return r1 > r2 else return r1 < r2 end
end)
return arr
end
-- 按百分比血量排序
function BattleUtil.SortByHpFactor(arr, sort)
BattleUtil.Sort(arr, function(a, b)
local r1 = a:GetRoleData(RoleDataName.Hp) / a:GetRoleData(RoleDataName.MaxHp)
local r2 = b:GetRoleData(RoleDataName.Hp) / b:GetRoleData(RoleDataName.MaxHp)
if sort == 1 then return r1 > r2 else return r1 < r2 end
end)
return arr
end
-- 按百分比血量排序
function BattleUtil.SortByHpFactorAndHp(arr, sort)
BattleUtil.Sort(arr, function(a, b)
local r1 = a:GetRoleData(RoleDataName.Hp) / a:GetRoleData(RoleDataName.MaxHp)
local r2 = b:GetRoleData(RoleDataName.Hp) / b:GetRoleData(RoleDataName.MaxHp)
if sort == 1 then
if r1==r2 then
return a:GetRoleData(RoleDataName.Hp)<b:GetRoleData(RoleDataName.Hp)
else
return r1 > r2
end
else
if r1==r2 then
return a:GetRoleData(RoleDataName.Hp)<b:GetRoleData(RoleDataName.Hp)
else
return r1 < r2
end
end
end)
return arr
end
--移除队列有不灭的单位
function BattleUtil.RemoveNoDeadRole(arr)
for i = 1, #arr do
local role=arr[i]
if BattleLogic.BuffMgr:HasBuff(role,BuffName.NoDead) then
table_removebyvalue(arr,role)
end
end
end
--按怒气排序
function BattleUtil.SortByRage(arr, sort)
BattleUtil.Sort(arr, function(a, b)
local r1 = a.Rage
local r2 = b.Rage
if sort == 1 then
if r1==r2 then
return a.position>b.position
else
return r1 < r2
end
else
if r1==r2 then
return a.position>b.position
else
return r1 > r2
end
end
end)
return arr
end
-- 获取技能最大目标数
function BattleUtil.GetMaxTargetNum(chooseId)
local chooseType = floor(chooseId / 100000) % 10
local chooseLimit = floor(chooseId / 10000) % 10
local chooseWeight = floor(chooseId / 100) % 100
local sort = floor(chooseId / 10) % 10
local num = chooseId % 10
--
if chooseType == 3 or chooseType == 4 then
return 1
else
if num == 0 then
if chooseLimit == 0 then
if chooseWeight == 7 then
return 4
elseif chooseLimit == 8 then
return 1
else
return 6
end
elseif chooseLimit == 1 or chooseLimit == 2 then
return 3
elseif chooseLimit == 3 then
return 2
end
else
return num
end
end
end
--
function BattleUtil.ChooseTarget(role, chooseId)
local chooseType = floor(chooseId / 100000) % 10
local chooseLimit = floor(chooseId / 10000) % 10
local chooseWeight = floor(chooseId / 100) % 100
local sort = floor(chooseId / 10) % 10
local num = chooseId % 10
local arr
-- 选择类型
if chooseType == 1 then
arr = RoleManager.Query(function (r) return r.camp == role.camp end)
elseif chooseType == 2 then
if role.lockTarget and not role.lockTarget:IsRealDead() and not role.lockTarget.isExile and num == 1 then --嘲讽时对单个敌军生效
return {role.lockTarget}
end
arr = RoleManager.Query(function (r) return r.camp ~= role.camp end)
elseif chooseType == 3 then
if role.ctrl_blind then --致盲时自身变随机友军
arr = RoleManager.Query(function (r) return r.camp == role.camp end)
BattleUtil.RandomList(arr)
return {arr[1]}
end
return {role}
elseif chooseType == 4 then
if role.lockTarget and not role.lockTarget:IsRealDead() and not role.lockTarget.isExile then --嘲讽时对仇恨目标生效
return {role.lockTarget}
end
if role.ctrl_blind then --致盲时仇恨目标变随机
arr = RoleManager.Query(function (r) return r.camp ~= role.camp end)
BattleUtil.RandomList(arr)
return {arr[1]}
end
return {RoleManager.GetAggro(role)}
else
arr = RoleManager.Query()
end
--选择范围
if chooseLimit == 0 then --选择全体不做任何操作
elseif chooseLimit == 1 then-- 前排
local tempArr = BattleUtil.ChooseFRow(arr)
if #tempArr == 0 then -- 没有选择后排
tempArr = BattleUtil.ChooseBRow(arr)
end
arr = tempArr
elseif chooseLimit == 2 then-- 后排
local tempArr = BattleUtil.ChooseBRow(arr)
if #tempArr == 0 then -- 没有选择前排
tempArr = BattleUtil.ChooseFRow(arr)
end
arr = tempArr
elseif chooseLimit == 3 then-- 对列
local target=RoleManager.GetAggro(role)
if target then
local myCol = target.position % 3
local tempArr = BattleUtil.ChooseCol(arr, myCol)
if #tempArr == 0 then -- 对列没有人,按顺序找到有人得列
for i = 1, 3 do
local col = i % 3 -- 0 表示第三列嗷
tempArr = BattleUtil.ChooseCol(arr, col)
if #tempArr ~= 0 then
break
end
end
end
arr = tempArr
end
elseif chooseLimit == 4 then -- 处于灼烧状态
local tempArr = {}
for i = 1, #arr do
if BattleLogic.BuffMgr:HasBuff(arr[i], BuffName.DOT, function (buff) return buff.damageType == DotType.Burn end,role,1) then
table.insert(tempArr, arr[i])
end
end
arr = tempArr
elseif chooseLimit == 5 then -- 人阵营
local tempArr = {}
for i = 1, #arr do
if arr[i].element == BattleRoleElementType.REN then
table.insert(tempArr, arr[i])
end
end
arr = tempArr
elseif chooseLimit == 6 then --两纵排单位
local tempArr=BattleUtil.ChooseTowCol(arr)
arr=tempArr
end
-- 选择条件
if chooseWeight == 0 or role.ctrl_blind then --致盲时排序无效
BattleUtil.RandomList(arr)
elseif chooseWeight == 1 then -- 生命值
BattleUtil.SortByProp(arr, RoleDataName.Hp, sort)
elseif chooseWeight == 2 then -- 血量百分比
BattleUtil.SortByHpFactor(arr, sort)
--选血量百分比最低的 不选择有不灭的,如果伤害要选有不灭的 需处理
BattleUtil.RemoveNoDeadRole(arr)
elseif chooseWeight == 3 then -- 攻击力
BattleUtil.SortByProp(arr, RoleDataName.Attack, sort)
elseif chooseWeight == 4 then -- 防御
BattleUtil.SortByProp(arr, RoleDataName.PhysicalDefence, sort)
elseif chooseWeight == 5 then -- 护甲
BattleUtil.SortByProp(arr, RoleDataName.PhysicalDefence, sort)
elseif chooseWeight == 6 then -- 魔抗
BattleUtil.SortByProp(arr, RoleDataName.MagicDefence, sort)
elseif chooseWeight == 7 then -- 对位及其相邻目标
arr = RoleManager.GetNeighbor(role, chooseType)
elseif chooseWeight == 8 then -- 对位
if num==1 then
arr=RoleManager.GetAggroHero(role,arr)
else
arr = RoleManager.GetArrAggroList(role, arr)
end
-- elseif chooseWeight == 9 then -- 展位距离
-- BattleUtil.Sort(arr, function(a, b)
-- local r1 = math.abs(role.position - a.position) * 10 + a.position
-- local r2 = math.abs(role.position - b.position) * 10 + b.position
-- if sort == 1 then return r1 > r2 else return r1 < r2 end
-- end)
elseif chooseWeight ==9 then --攻击最高且没被放逐过
local list=role.exileTargets
local tempArr = {}
local team = RoleManager.Query(function (r) return r.camp ~= role.camp end)
if list then
for key, value in pairs(team) do
if not value:IsRealDead() and not BattleUtil.ChecklistIsContainValue(role.exileTargets,value) then
--return arr[i]
table.insert(tempArr,value)
end
end
end
BattleUtil.SortByProp(tempArr,RoleDataName.Attack,sort)
arr=tempArr
elseif chooseWeight ==10 then --剩余血量百分比低于25%且生命绝对值最小
return BattleUtil.GetHpPctLessThanPctHero(arr,0.25)
elseif chooseWeight ==11 then --剩余血量百分比低于32%且生命绝对值最小
return BattleUtil.GetHpPctLessThanPctHero(arr,0.32)
elseif chooseWeight ==12 then --剩余血量百分比低于40%且生命绝对值最小
return BattleUtil.GetHpPctLessThanPctHero(arr,0.40)
elseif chooseWeight ==13 then --剩余血量百分比低于50%且生命绝对值最小
return BattleUtil.GetHpPctLessThanPctHero(arr,0.50)
end
local finalArr = {}
if num == 0 then
finalArr = arr
else
for i = 1, num do
if arr[i] then
table.insert(finalArr, arr[i])
end
end
end
-- table.sort(finalArr, function(a, b)
-- return a.position < b.position
-- end)
return finalArr
end
--获取生命百分比少于指定百分比且生命置最少
function BattleUtil.GetHpPctLessThanPctHero(arr,pct)
local hp=0
local hero=nil
for i = 1, #arr[i] do
local aaa=arr[i]
local curHp=aaa:GetRoleData(RoleDataName.Hp)
local r1 = curHp / aaa:GetRoleData(RoleDataName.MaxHp)
if r1<pct then
if hero==nil then
hero=aaa
hp=curHp
else
if curHp<hp then
hero=aaa
hp=curHp
end
end
end
end
return hero
end
function BattleUtil.CreateBuffId(skill, index)
local id = 0
if skill.preAI then --主动技能生成buff
id = skill.owner.uid * 10000 + index
else --被动技能生成buff
id = skill.owner.uid * 1000 + index
end
return id
end
-- 计算命中率
function BattleUtil.CalHit(atkRole, defRole)
--命中率 = clamp(自身命中率-敌方闪避率,0,1)
local hit = atkRole:GetRoleData(RoleDataName.Hit)
local dodge = defRole:GetRoleData(RoleDataName.Dodge)
local bHit = Random.Range01() <= clamp(hit - dodge, 0, 1)
if bHit then
else
atkRole.Event:DispatchEvent(BattleEventName.RoleDodge)
defRole.Event:DispatchEvent(BattleEventName.RoleBeDodge)
end
return bHit
end
-- 计算护盾
function BattleUtil.CalShield(atkRole, defRole, damage,skill)
for i=1, defRole.shield.size do
local buff = defRole.shield.buffer[i]
damage = buff:CountShield(damage, atkRole,skill)
end
return damage
end
-- 计算护盾
function BattleUtil.CalAllReduceShield(atkRole, defRole, damage,skill)
for i=1, defRole.shield.size do
local buff = defRole.shield.buffer[i]
damage = buff:CountAllReduce(damage, atkRole,skill)
end
return damage
end
-- 提前计算护盾后伤害
function BattleUtil.PreCountShield(defRole, damage)
for i=1, defRole.shield.size do
local buff = defRole.shield.buffer[i]
damage = buff:PreCountShield(damage)
end
return damage
end
--检测是否为boss
function BattleUtil.CheckIsBoss(role)
if not role then
return false
end
if role.enemyType==EnemyType.Boss then
--弹免疫
role.Event:DispatchEvent(BattleEventName.ShowHintText, BattleArtFontType.Immune)
return true
else
return false
end
end
-- 秒杀
function BattleUtil.Seckill(skill, atkRole, defRole)
-- 灵兽无效
if defRole.type == BattleUnitType.Monster or defRole.type == BattleUnitType.Player then
return
end
local damage = defRole:GetRoleData(RoleDataName.Hp)
local finalDmg = defRole.data:SubValue(RoleDataName.Hp, damage)
if finalDmg >= 0 then
if defRole:GetRoleData(RoleDataName.Hp) <= 0 and not defRole:IsDead() then
defRole:SetDead(damage)
defRole.Event:DispatchEvent(BattleEventName.RoleDead, atkRole,skill)
atkRole.Event:DispatchEvent(BattleEventName.RoleKill, defRole,skill)
BattleLogic.Event:DispatchEvent(BattleEventName.BattleRoleDead, defRole, atkRole)
atkRole.Event:DispatchEvent(BattleEventName.Seckill, defRole,damage,nil,finalDmg)
defRole.Event:DispatchEvent(BattleEventName.BeSeckill, atkRole)
BattleLogic.Event:DispatchEvent(BattleEventName.Seckill, atkRole, defRole)
end
atkRole.Event:DispatchEvent(BattleEventName.RoleDamage, defRole, damage, false, finalDmg, 0, false, skill)
defRole.Event:DispatchEvent(BattleEventName.RoleBeDamaged, atkRole, damage, false, finalDmg, 0, false, skill)
BattleLogic.Event:DispatchEvent(BattleEventName.RoleDamage, atkRole, defRole, damage, false, finalDmg, 0, false, skill)
BattleLogic.Event:DispatchEvent(BattleEventName.RoleBeDamaged, defRole, atkRole, damage, false, finalDmg, 0, false, skill)
if skill then
atkRole.Event:DispatchEvent(BattleEventName.RoleHit, defRole, damage, nil, finalDmg, nil, skill)
defRole.Event:DispatchEvent(BattleEventName.RoleBeHit, atkRole, damage, nil, finalDmg, nil, skill)
end
end
-- 用于记录统计
BattleLogic.Event:DispatchEvent(BattleEventName.RecordSecKill, atkRole, defRole)
end
-- 秒杀定额血量
function BattleUtil.SeckillHP(skill, atkRole, defRole, pro)
-- 灵兽无效
if defRole.type == BattleUnitType.Monster or defRole.type == BattleUnitType.Player then
return
end
local damage = floor(BattleUtil.FP_Mul(defRole:GetRoleData(RoleDataName.MaxHp),pro))
local finalDmg = defRole.data:SubValue(RoleDataName.Hp, damage)
if finalDmg >= 0 then
if defRole:GetRoleData(RoleDataName.Hp) <= 0 and not defRole:IsDead() then
defRole:SetDead(damage)
defRole.Event:DispatchEvent(BattleEventName.RoleDead, atkRole)
atkRole.Event:DispatchEvent(BattleEventName.RoleKill, defRole,skill)
BattleLogic.Event:DispatchEvent(BattleEventName.BattleRoleDead, defRole, atkRole)
atkRole.Event:DispatchEvent(BattleEventName.Seckill, defRole,damage,nil,finalDmg)
defRole.Event:DispatchEvent(BattleEventName.BeSeckill, atkRole)
BattleLogic.Event:DispatchEvent(BattleEventName.Seckill, atkRole, defRole)
end
atkRole.Event:DispatchEvent(BattleEventName.RoleDamage, defRole, damage, false, finalDmg, 0, false, skill)
defRole.Event:DispatchEvent(BattleEventName.RoleBeDamaged, atkRole, damage, false, finalDmg, 0, false, skill)
BattleLogic.Event:DispatchEvent(BattleEventName.RoleDamage, atkRole, defRole, damage, false, finalDmg, 0, false, skill)
BattleLogic.Event:DispatchEvent(BattleEventName.RoleBeDamaged, defRole, atkRole, damage, false, finalDmg, 0, false, skill)
if skill then
atkRole.Event:DispatchEvent(BattleEventName.RoleHit, defRole, damage, nil, finalDmg, nil, skill)
defRole.Event:DispatchEvent(BattleEventName.RoleBeHit, atkRole, damage, nil, finalDmg, nil, skill)
end
end
-- 用于记录统计
BattleLogic.Event:DispatchEvent(BattleEventName.RecordSecKill, atkRole, defRole)
end
-- 计算真实伤害
function BattleUtil.ApplyDamage(skill, atkRole, defRole, damage, bCrit, damageType, dotType,isDirect)
-- 灵兽无效
if defRole.type == BattleUnitType.Monster or defRole.type == BattleUnitType.Player then
return
end
bCrit = bCrit or false
damageType = damageType or 0
-- if atkRole.isTeam then
-- --max技能基础伤害*1+已方异妖伤害加成-目标异妖伤害减免30%×技能基础伤害)
-- local arr = RoleManager.Query(function (r) return r.camp == atkRole.camp end)
-- local n = 0
-- for i=1, #arr do
-- n = n + arr[i]:GetRoleData(RoleDataName.TeamDamageBocusFactor)
-- end
-- damage = floor(max(damage * (1 + n / #arr - defRole:GetRoleData(RoleDataName.TeamDamageReduceFactor)), 0.3 * damage))
-- end
--加入被动效果
local damagingFunc = function(dmgDeduction)
damage = damage - dmgDeduction
end
atkRole.Event:DispatchEvent(BattleEventName.PassiveDamaging, damagingFunc, defRole, damage, skill, dotType, bCrit,damageType, dotType,isDirect)
defRole.Event:DispatchEvent(BattleEventName.PassiveBeDamaging, damagingFunc, atkRole, damage, skill, dotType, bCrit)
BattleLogic.Event:DispatchEvent(BattleEventName.PassiveDamaging, damagingFunc, atkRole, defRole, damage, skill, dotType, bCrit,damageType, dotType,isDirect)
-- 计算护盾减伤
damage = BattleUtil.CalShield(atkRole, defRole, damage,skill)
-- 造成的最终伤害
local damagingFunc = function(dmgDeduction)
damage = damage - dmgDeduction
end
atkRole.Event:DispatchEvent(BattleEventName.FinalDamage, damagingFunc, defRole, damage, skill, dotType, bCrit, damageType)
defRole.Event:DispatchEvent(BattleEventName.FinalBeDamage, damagingFunc, atkRole, damage, skill, dotType, bCrit, damageType)
defRole.Event:DispatchEvent(BattleEventName.FinalBeDamageEnd, damagingFunc, atkRole, damage, skill, dotType, bCrit, damageType,isDirect)
BattleLogic.Event:DispatchEvent(BattleEventName.FinalDamage, damagingFunc, atkRole, defRole, damage, skill, dotType, bCrit, damageType)
--
return BattleUtil.FinalDamage(skill, atkRole, defRole, damage, bCrit, damageType, dotType,isDirect)
end
-- 计算真实伤害(没有被动增伤)
function BattleUtil.ApplyDamageNoPassive(skill, atkRole, defRole, damage, bCrit, damageType, dotType,isDirect)
-- 灵兽无效
if defRole.type == BattleUnitType.Monster or defRole.type == BattleUnitType.Player then
return
end
-- 计算护盾减伤
damage = BattleUtil.CalShield(atkRole, defRole, damage,skill)
-- 造成的最终伤害
local damagingFunc = function(dmgDeduction)
damage = damage - dmgDeduction
end
defRole.Event:DispatchEvent(BattleEventName.FinalBeDamageEnd, damagingFunc, atkRole, damage, skill, dotType, bCrit, damageType,isDirect)
BattleLogic.Event:DispatchEvent(BattleEventName.FinalDamage, damagingFunc, atkRole, defRole, damage, skill, dotType, bCrit, damageType)
--
return BattleUtil.FinalDamage(skill, atkRole, defRole, damage, bCrit, damageType, dotType,isDirect)
end
-- 怒气计算
function BattleUtil.CalRage(caster, target, value, countType,isBorrow)
-- 角色身上有无敌盾,不扣除怒气 by:wangzhenxing 2020/08/10 14:56
if (countType==3 or countType==4) -- 降怒
and (target.isImmuneReduceRage -- 免疫降怒 或者 有无敌盾
or BattleLogic.BuffMgr:HasBuff(target, BuffName.Shield, function (buff) return buff.shieldType and buff.shieldType == ShieldTypeName.AllReduce end))
then
return
end
local lastRage=target.Rage
--如果每回合减的怒气超过了每回合上限就不再减怒
if (countType==3 or countType==4) and target.RoundMaxSubRage~=0 and target.RoundMaxSubRage<=target.AllSubRage then
return
end
--这个减的怒气+已经间的怒气> 怒气限制
if (countType==3 or countType==4) and target.RoundMaxSubRage~=0 and value+target.AllSubRage>target.RoundMaxSubRage then
value=target.RoundMaxSubRage-target.AllSubRage
end
-- 操作怒气
local deltaRage = target:AddRage(value, countType)
if (countType==3 or countType==4) and target.RoundMaxSubRage~=0 then
target.AllSubRage=target.AllSubRage-deltaRage
end
BattleLogic.Event:DispatchEvent(BattleEventName.RecordRageChange, caster, target, deltaRage,countType,value,lastRage,isBorrow)
-- 用于记录统计
BattleLogic.Event:DispatchEvent(BattleEventName.RecordRage, caster, target, deltaRage)
end
--检测是否有是金翅大鹏有不灭效果
function BattleUtil.CheckIsNoDead(target)
if target then
return target.isHaveNoDead or BattleLogic.BuffMgr:HasBuff(target,BuffName.NoDead)
end
return false
end
--检测列表是否包含值
function BattleUtil.ChecklistIsContainValue(_list,_value)
if _list and _value then
for key, value in pairs(_list) do
if value ==_value then
return true
end
end
end
return false
end
-- 根据id获取额外技能
function BattleUtil.GetExtraSkillbyId(id)
if id==1 then
return ExtraReleaseSkill.skill1
elseif id==2 then
return ExtraReleaseSkill.skill2
elseif id==3 then
return ExtraReleaseSkill.skill3
elseif id==4 then
return ExtraReleaseSkill.skill4
elseif id==5 then
return ExtraReleaseSkill.skill5
elseif id==6 then
return ExtraReleaseSkill.skill6
end
end
function BattleUtil.FinalDamage(skill, atkRole, defRole, damage, bCrit, damageType, dotType,isDirect)
-- 灵兽无效
if defRole.type == BattleUnitType.Monster or defRole.type == BattleUnitType.Player then
return
end
if damage < 0 then damage = 0 end
if skill and skill.type==BattleSkillType.Special then
skill.owner.superSkillDamage=damage
end
--计算血量防护
local realDamage=damage
--血量防护只会防直接伤害
if defRole.bloodShield and skill then
realDamage=math.abs(defRole.bloodShield:CountBloodValue(damage))
-- damage=realDamage
end
--御甲过滤后的伤害只会处理扣血 by: wangzhenxing shihongyi 2021/09/27
local finalDmg = defRole.data:SubValue(RoleDataName.Hp,realDamage)
if finalDmg >= 0 then
if defRole:GetRoleData(RoleDataName.Hp) <= 0 and not defRole:IsDead() then
defRole:SetDead(damage)
defRole.Event:DispatchEvent(BattleEventName.RoleDead, atkRole)
atkRole.Event:DispatchEvent(BattleEventName.RoleKill, defRole,skill)
BattleLogic.Event:DispatchEvent(BattleEventName.BattleRoleDead, defRole, atkRole,skill,dotType)
end
atkRole.Event:DispatchEvent(BattleEventName.RoleDamage, defRole, damage, bCrit, finalDmg, damageType, dotType, skill)
defRole.Event:DispatchEvent(BattleEventName.RoleBeDamaged, atkRole, damage, bCrit, finalDmg, damageType, dotType, skill)
BattleLogic.Event:DispatchEvent(BattleEventName.RoleDamage, atkRole, defRole, damage, bCrit, finalDmg, damageType, dotType, skill)
BattleLogic.Event:DispatchEvent(BattleEventName.RoleBeDamaged, defRole, atkRole, damage, bCrit, finalDmg, damageType, dotType, skill)
if bCrit then
atkRole.Event:DispatchEvent(BattleEventName.RoleCrit, defRole, damage, bCrit, finalDmg, damageType, skill)
defRole.Event:DispatchEvent(BattleEventName.RoleBeCrit, atkRole, damage, bCrit, finalDmg, damageType, skill)
end
if skill then
atkRole.Event:DispatchEvent(BattleEventName.RoleHit, defRole, damage, bCrit, finalDmg, damageType, skill,isDirect)
defRole.Event:DispatchEvent(BattleEventName.RoleBeHit, atkRole, damage, bCrit, finalDmg, damageType, skill,isDirect)
--如果目标是主燃烧目标 or 目标身上有燃烧效果
if atkRole.curMainTarget==defRole or BattleLogic.BuffMgr:HasBuff(defRole, BuffName.DOT,function(buff) return buff.damageType == 1 end) then
atkRole.Event:DispatchEvent(BattleEventName.HitRoleInBurn,skill,defRole)
end
end
--如果不是技能带的伤害,并且是直接伤害就,,,,,
--用于处理不触发特性并且是直接伤害的伤害 isDirect 暂时先为bool值后期可根据需求做修改扩展 by:王振兴 2020/10/12 16:18
if isDirect and not skill then
atkRole.Event:DispatchEvent(BattleEventName.RoleHit, defRole, damage, bCrit, finalDmg, damageType, skill,isDirect)
defRole.Event:DispatchEvent(BattleEventName.RoleBeHit, atkRole, damage, bCrit, finalDmg, damageType, skill,isDirect)
end
end
-- 战斗记录用
BattleLogic.Event:DispatchEvent(BattleEventName.RecordDamage, atkRole, defRole, damage)
--
BattleLogManager.Log(
"Final Damage",
"acamp", atkRole.camp,
"apos", atkRole.position,
"tcamp", defRole.camp,
"tpos", defRole.position,
"damage", damage,
"dotType", tostring(dotType)
)
return finalDmg
end
--计算盾的最终伤害
function BattleUtil.FinalDamageCountShield(skill, atkRole, defRole, damage, bCrit, damageType, dotType,isDirect)
-- 灵兽无效
if defRole.type == BattleUnitType.Monster or defRole.type == BattleUnitType.Player then
return
end
-- 计算护盾减伤
damage = BattleUtil.CalShield(atkRole, defRole, damage,skill)
if damage < 0 then damage = 0 end
if skill and skill.type==BattleSkillType.Special then
skill.owner.superSkillDamage=damage
end
--计算血量防护
local realDamage=damage
--血量防护只会防直接伤害
if defRole.bloodShield and skill then
realDamage=math.abs(defRole.bloodShield:CountBloodValue(damage))
-- damage=realDamage
end
--检测历战之躯
-- 造成的最终伤害
local damagingFunc = function(dmgDeduction)
realDamage = realDamage - dmgDeduction
damage=realDamage
end
defRole.Event:DispatchEvent(BattleEventName.CheckLiZhanZhiQu, damagingFunc, atkRole, realDamage, skill, dotType, bCrit, damageType,isDirect)
--LogError("最后扣除伤害=="..realDamage)
--御甲过滤后的伤害只会处理扣血 by: wangzhenxing shihongyi 2021/09/27
local finalDmg = defRole.data:SubValue(RoleDataName.Hp,realDamage)
if finalDmg >= 0 then
if defRole:GetRoleData(RoleDataName.Hp) <= 0 and not defRole:IsDead() then
defRole:SetDead(damage)
defRole.Event:DispatchEvent(BattleEventName.RoleDead, atkRole)
atkRole.Event:DispatchEvent(BattleEventName.RoleKill, defRole,skill)
BattleLogic.Event:DispatchEvent(BattleEventName.BattleRoleDead, defRole, atkRole,skill,dotType)
end
atkRole.Event:DispatchEvent(BattleEventName.RoleDamage, defRole, damage, bCrit, finalDmg, damageType, dotType, skill)
defRole.Event:DispatchEvent(BattleEventName.RoleBeDamaged, atkRole, damage, bCrit, finalDmg, damageType, dotType, skill)
BattleLogic.Event:DispatchEvent(BattleEventName.RoleDamage, atkRole, defRole, damage, bCrit, finalDmg, damageType, dotType, skill)
BattleLogic.Event:DispatchEvent(BattleEventName.RoleBeDamaged, defRole, atkRole, damage, bCrit, finalDmg, damageType, dotType, skill)
if bCrit then
atkRole.Event:DispatchEvent(BattleEventName.RoleCrit, defRole, damage, bCrit, finalDmg, damageType, skill)
defRole.Event:DispatchEvent(BattleEventName.RoleBeCrit, atkRole, damage, bCrit, finalDmg, damageType, skill)
end
if skill then
atkRole.Event:DispatchEvent(BattleEventName.RoleHit, defRole, damage, bCrit, finalDmg, damageType, skill,isDirect)
defRole.Event:DispatchEvent(BattleEventName.RoleBeHit, atkRole, damage, bCrit, finalDmg, damageType, skill,isDirect)
--如果目标是主燃烧目标 or 目标身上有燃烧效果
if atkRole.curMainTarget==defRole or BattleLogic.BuffMgr:HasBuff(defRole, BuffName.DOT,function(buff) return buff.damageType == 1 end) then
atkRole.Event:DispatchEvent(BattleEventName.HitRoleInBurn,skill,defRole)
end
end
--如果不是技能带的伤害,并且是直接伤害就,,,,,
--用于处理不触发特性并且是直接伤害的伤害 isDirect 暂时先为bool值后期可根据需求做修改扩展 by:王振兴 2020/10/12 16:18
if isDirect and not skill then
atkRole.Event:DispatchEvent(BattleEventName.RoleHit, defRole, damage, bCrit, finalDmg, damageType, skill,isDirect)
defRole.Event:DispatchEvent(BattleEventName.RoleBeHit, atkRole, damage, bCrit, finalDmg, damageType, skill,isDirect)
end
end
-- 战斗记录用
BattleLogic.Event:DispatchEvent(BattleEventName.RecordDamage, atkRole, defRole, damage)
--
BattleLogManager.Log(
"Final Damage",
"acamp", atkRole.camp,
"apos", atkRole.position,
"tcamp", defRole.camp,
"tpos", defRole.position,
"damage", damage,
"dotType", tostring(dotType)
)
return finalDmg
end
--执行完整的命中,伤害,暴击计算,返回命中,暴击
--skill造成伤害的技能 atkRole攻击者 defRole受击者 damageType伤害类型 baseFactor伤害系数 ignoreDef无视防御参数 dotType是持续伤害类型
function BattleUtil.CalDamage(skill, atkRole, defRole, damageType, baseFactor, ignoreDef, dotType)
-- 灵兽无效
if defRole.type == BattleUnitType.Monster or defRole.type == BattleUnitType.Player then
return
end
-- 判断是否命中
if skill and not skill:CheckTargetIsHit(defRole) and atkRole.type==BattleUnitType.Role then
BattleLogic.Event:DispatchEvent(BattleEventName.HitMiss, atkRole, defRole, skill)
atkRole.Event:DispatchEvent(BattleEventName.HitMiss, defRole, skill)
defRole.Event:DispatchEvent(BattleEventName.BeHitMiss, atkRole, skill)
return 0
end
-- 如果是队伍技能计算真实伤害则damageType为伤害值
if atkRole.isTeam and not defRole:IsDead() then
return BattleUtil.ApplyDamage(skill, atkRole, defRole, damageType), false
end
-- 计算技能额外伤害系数加成
baseFactor = baseFactor or 1
local factorFunc = function(exFactor) baseFactor = baseFactor + exFactor end
atkRole.Event:DispatchEvent(BattleEventName.RoleDamageBefore, defRole, factorFunc, damageType, skill)
defRole.Event:DispatchEvent(BattleEventName.RoleBeDamagedBefore, atkRole, factorFunc, damageType, skill)
baseFactor = BattleUtil.ErrorCorrection(baseFactor)
local baseDamage
-- 防御(据伤害类型决定)
local defence = 0
if damageType == 1 then --1 物理 2 魔法
defence = defRole:GetRoleData(RoleDataName.PhysicalDefence)
else
defence = defRole:GetRoleData(RoleDataName.MagicDefence)
end
-- 攻击力
local attack = atkRole:GetRoleData(RoleDataName.Attack)
-- 无视防御系数
ignoreDef = 1 - (ignoreDef or 0)
-- 基础伤害 = 攻击力 - 防御力
baseDamage = max(attack - BattleUtil.FP_Mul(defence, ignoreDef), 0)
-- 基础伤害增加系数
local addDamageFactor = 1 + atkRole:GetRoleData(RoleDataName.DamageBocusFactor) - defRole:GetRoleData(RoleDataName.DamageReduceFactor)
-- 是否暴击: 暴击率 = 自身暴击率 - 对方抗暴率
local bCrit = false
local critRandom = Random.Range01()
--特殊处理 白骨精附加的普攻不会必定暴击
local mustCrit=atkRole.mustCrit
if atkRole.roleId==10091 and skill and skill.type==BattleSkillType.Normal and skill.isAdd then
mustCrit=false
end
local critCondition = clamp(atkRole:GetRoleData(RoleDataName.Crit) - defRole:GetRoleData(RoleDataName.Tenacity), 0, 1)
bCrit = critRandom <= critCondition
bCrit =mustCrit or bCrit or defRole.isFlagCrit == true -- 必定暴击
-- 计算暴伤害系数
local critDamageFactor = 1
local critDamageReduceFactor = 0 -- 暴击伤害减免
--计算暴击
if bCrit then
--加入被动效果 触发暴击被动
local cl = {}
local onCritDamageReduceFactor = function(v, ct)
if v then
table.insert(cl, {v, ct})
end
end
atkRole.Event:DispatchEvent(BattleEventName.CritDamageReduceFactor, onCritDamageReduceFactor, atkRole, defRole)
defRole.Event:DispatchEvent(BattleEventName.CritDamageReduceFactor, onCritDamageReduceFactor, atkRole, defRole)
BattleLogic.Event:DispatchEvent(BattleEventName.CritDamageReduceFactor, onCritDamageReduceFactor, atkRole, defRole)
critDamageReduceFactor = max(BattleUtil.CountChangeList(critDamageReduceFactor, cl), 0)
-- 计算额外暴击伤害
critDamageFactor = 1.3 + atkRole:GetRoleData(RoleDataName.CritDamageFactor) - critDamageReduceFactor
--加入被动效果 触发暴击被动
local critFunc = function(critEx) critDamageFactor = critEx end
atkRole.Event:DispatchEvent(BattleEventName.PassiveCriting, critFunc,skill)
end
-- 公式伤害 = 基础伤害 * 基础伤害系数 * 增伤系数 * 爆伤系数
local fixDamage = floor(BattleUtil.FP_Mul(baseDamage, baseFactor, addDamageFactor, critDamageFactor))
-- 公式计算完成
local damageFunc = function(damage) fixDamage = damage end
atkRole.Event:DispatchEvent(BattleEventName.RoleDamageAfter, defRole, damageFunc, fixDamage,skill)
defRole.Event:DispatchEvent(BattleEventName.RoleBeDamagedAfter, atkRole, damageFunc, fixDamage)
fixDamage = max(floor(attack * 0.1), fixDamage)
local finalDmg = 0 --计算实际造成的扣血
if not defRole:IsRealDead() then
finalDmg = BattleUtil.ApplyDamage(skill, atkRole, defRole, fixDamage, bCrit, damageType, dotType)
end
return finalDmg, bCrit
end
function BattleUtil.CalTreat(castRole, targetRole, value, baseFactor,skill)
-- 灵兽无效
if targetRole.type == BattleUnitType.Monster or targetRole.type == BattleUnitType.Player then
return
end
BattleLogic.Event:DispatchEvent(BattleEventName.DisposeRoleCtrl_noheal, castRole,targetRole)
if targetRole.ctrl_noheal or targetRole:IsDead() then --禁疗和死亡无法加血
--禁疗并且没有死亡的单位显示血量+0 不走后面代码,防止触发后面的被动 by:王振兴 2021/1/27
if targetRole.ctrl_noheal and not targetRole:IsDead() then
targetRole.Event:DispatchEvent(BattleEventName.RoleBeTreated, castRole, 0, 0)
end
return
end
-- 是否暴击: 暴击率 = 自身暴击率 - 对方抗暴率
local bCrit = false
local critRandom = Random.Range01()
local critCondition = castRole:GetRoleData(RoleDataName.Crit)
bCrit = critRandom <= critCondition
bCrit = bCrit or targetRole.isFlagCrit == true -- 必定暴击
-- 计算暴伤害系数
local critDamageFactor = 1
--计算暴击
if bCrit then
--伤害有个+1.3 不知道干什么用的就给去了 by:wangxhenxing 2020/10/10 18:46
critDamageFactor = 1.3 + castRole:GetRoleData(RoleDataName.CritDamageFactor)
end
-- 基础伤害增加系数
local addDamageFactor = 1 + castRole:GetRoleData(RoleDataName.DamageBocusFactor)
targetRole.Event:DispatchEvent(BattleEventName.RoleBeHealed, castRole)
BattleUtil.ApplyTreat(castRole, targetRole, value, baseFactor,critDamageFactor,addDamageFactor,skill)
end
function BattleUtil.FinalTreat(castRole, targetRole, value, baseFactor,skill)
-- 灵兽无效
if targetRole.type == BattleUnitType.Monster or targetRole.type == BattleUnitType.Player then
return
end
BattleLogic.Event:DispatchEvent(BattleEventName.DisposeRoleCtrl_noheal, castRole,targetRole)
if targetRole.ctrl_noheal or targetRole:IsDead() then --禁疗和死亡无法加血
--禁疗并且没有死亡的单位显示血量+0 不走后面代码,防止触发后面的被动 by:王振兴 2021/1/27
if targetRole.ctrl_noheal and not targetRole:IsDead() then
targetRole.Event:DispatchEvent(BattleEventName.RoleBeTreated, castRole, 0, 0)
end
return
end
targetRole.Event:DispatchEvent(BattleEventName.RoleBeHealed, castRole)
local maxHp = targetRole:GetRoleData(RoleDataName.MaxHp)
local hp = targetRole:GetRoleData(RoleDataName.Hp)
baseFactor = baseFactor or 1
local baseTreat = BattleUtil.FP_Mul(value, baseFactor)
--baseTreat = BattleUtil.CountChangeList(baseTreat, cl)
-- 取整
local baseTreat = floor(baseTreat + 0.5)
local treat = min(baseTreat, maxHp - hp)
if treat > 0 then
targetRole.data:AddValue(RoleDataName.Hp, treat)
end
castRole.Event:DispatchEvent(BattleEventName.RoleTreat, targetRole, treat, baseTreat)
targetRole.Event:DispatchEvent(BattleEventName.RoleBeTreated, castRole, treat, baseTreat)
--添加发送到battleLogic的治疗消息用于计算总的战斗伤害值
BattleLogic.Event:DispatchEvent(BattleEventName.RoleBeTreated, castRole, treat, baseTreat)
-- 战斗记录用
BattleLogic.Event:DispatchEvent(BattleEventName.RecordTreat, castRole, targetRole, baseTreat)
BattleLogManager.Log(
"Final Treat",
"acamp", castRole.camp,
"apos", castRole.position,
"tcamp", targetRole.camp,
"tpos", targetRole.position,
"value", value
)
end
function BattleUtil.ApplyTreat(castRole, targetRole, value, baseFactor,critDamageFactor,addDamageFactor,skill)
-- 灵兽无效
if targetRole.type == BattleUnitType.Monster then
return
end
BattleLogic.Event:DispatchEvent(BattleEventName.DisposeRoleCtrl_noheal, castRole,targetRole)
if targetRole.ctrl_noheal or targetRole:IsDead() then --禁疗和死亡无法加血
--禁疗并且没有死亡的单位显示血量+0 不走后面代码,防止触发后面的被动 by:王振兴 2021/1/27
if targetRole.ctrl_noheal and not targetRole:IsDead() then
targetRole.Event:DispatchEvent(BattleEventName.RoleBeTreated, castRole, 0, 0)
end
return
end
baseFactor = baseFactor or 1
local maxHp = targetRole:GetRoleData(RoleDataName.MaxHp)
local hp = targetRole:GetRoleData(RoleDataName.Hp)
-- 计算被动对治疗系数的影响
local treatFactorFunc = function(df, dt)
baseFactor = BattleUtil.CountValue(baseFactor, df, dt)
end
castRole.Event:DispatchEvent(BattleEventName.PassiveTreatingFactor, treatFactorFunc, targetRole,skill)
targetRole.Event:DispatchEvent(BattleEventName.PassiveBeTreatedFactor, treatFactorFunc, castRole)
local factor = castRole.isTeam and 1 or castRole:GetRoleData(RoleDataName.TreatFacter) --释放者为team则不计算治疗加成属性
local factor2 = targetRole:GetRoleData(RoleDataName.CureFacter)
local baseTreat = BattleUtil.FP_Mul(value, baseFactor, factor, factor2,critDamageFactor,addDamageFactor)
--加入被动效果
local cl = {}
local function treatingFunc(v, ct)
if v then
table.insert(cl, {v, ct})
end
end
-- local treatingFunc = function(exFactor) baseTreat = floor(baseTreat * (exFactor + 1) + 0.5) end
castRole.Event:DispatchEvent(BattleEventName.PassiveTreating, treatingFunc, targetRole)
targetRole.Event:DispatchEvent(BattleEventName.PassiveBeTreated, treatingFunc, castRole)
baseTreat = BattleUtil.CountChangeList(baseTreat, cl)
-- 取整
local baseTreat = floor(baseTreat + 0.5)
local treat = min(baseTreat, maxHp - hp)
if treat > 0 then
targetRole.data:AddValue(RoleDataName.Hp, treat)
end
castRole.Event:DispatchEvent(BattleEventName.RoleTreat, targetRole, treat, baseTreat)
targetRole.Event:DispatchEvent(BattleEventName.RoleBeTreated, castRole, treat, baseTreat)
--添加发送到battleLogic的治疗消息用于计算总的战斗伤害值
BattleLogic.Event:DispatchEvent(BattleEventName.RoleBeTreated, castRole, treat, baseTreat)
-- 战斗记录用
BattleLogic.Event:DispatchEvent(BattleEventName.RecordTreat, castRole, targetRole, baseTreat)
BattleLogManager.Log(
"Final Treat",
"acamp", castRole.camp,
"apos", castRole.position,
"tcamp", targetRole.camp,
"tpos", targetRole.position,
"value", value
)
end
-- 检测命中
function BattleUtil.CheckIsHit(atkRole, defRole,skill)
-- 是否命中: 命中 = 自身命中率 - 对方闪避率
local isHit = false
local mustHit = atkRole.mustHit
--特殊处理 白骨精附加的普攻不会必定暴击
if atkRole.roleId==10091 and skill and skill.type==BattleSkillType.Normal and skill.isAdd then
mustHit=false
end
local hitRandom = Random.Range01()
local hitCondition = clamp(atkRole:GetRoleData(RoleDataName.Hit) - defRole:GetRoleData(RoleDataName.Dodge), 0, 1)
isHit = hitRandom <= hitCondition
return mustHit or isHit
end
--获取table的长度
function BattleUtil.LengthOfTable(table)
if not table then
return 0
end
local length = 0
for i, v in pairs(table) do
length = length + 1
end
return length
end
function BattleUtil.RandomAction(rand, action)
if Random.Range01() <= rand and action then
action()
return true
end
return false
end
--
function BattleUtil.RandomControl(rand, ctrl, caster, target, round)
local cl = {}
local function _CallBack(v, ct)
if v then
table.insert(cl, {v, ct})
end
end
caster.Event:DispatchEvent(BattleEventName.PassiveRandomControl, _CallBack, ctrl, target)
target.Event:DispatchEvent(BattleEventName.PassiveBeRandomControl, _CallBack, ctrl, target)
rand = BattleUtil.CountChangeList(rand, cl)
local buff = Buff.Create(caster, BuffName.Control, round, ctrl)
local isAdd=BattleUtil.RandomAction(rand, function()
target:AddBuff(buff)
end)
if not isAdd then
buff.target=target
BattleLogic.Event:DispatchEvent(BattleEventName.RoleAddBuffFail,buff)
end
return isAdd
end
--
function BattleUtil.RandomDot(rand, dot, caster, target, round, interval, damage)
local cl = {}
local dcl = {}
local function _CallBack(v, ct, dv, dct)
if v then
table.insert(cl, {v, ct})
end
if dv then
table.insert(dcl, {dv, dct})
end
end
caster.Event:DispatchEvent(BattleEventName.PassiveRandomDot, _CallBack, dot)
target.Event:DispatchEvent(BattleEventName.PassiveBeRandomDot, _CallBack, dot)
rand = BattleUtil.CountChangeList(rand, cl)
damage = floor(BattleUtil.CountChangeList(damage, dcl))
return BattleUtil.RandomAction(rand, function()
local buff = Buff.Create(caster, BuffName.DOT, round, interval, dot, damage)
buff.isRealDamage = true
target:AddBuff(buff)
end)
end
function BattleUtil.RandomList(arr)
if #arr <= 1 then return end
local index
for i=#arr, 1, -1 do
index = Random.RangeInt(1, i)
arr[i], arr[index] = arr[index], arr[i]
end
end
function BattleUtil.Sort(arr, comp)
if #arr <= 1 then return arr end
for i=1, #arr do
for j = #arr, i+1, -1 do
if comp(arr[j-1], arr[j]) then
arr[j-1], arr[j] = arr[j], arr[j-1]
end
end
end
return arr
end
function BattleUtil.GetPropertyName(type)
if type == 1 then
return RoleDataName.Strength
elseif type == 2 then
return RoleDataName.Energy
elseif type == 3 then
return RoleDataName.Vitality
elseif type == 4 then
return RoleDataName.Dexterity
elseif type == 5 then
return RoleDataName.Speed
elseif type == 6 then
return RoleDataName.PhysicalAttack
elseif type == 7 then
return RoleDataName.MagicAttack
elseif type == 8 then
return RoleDataName.PhysicalDefence
elseif type == 9 then
return RoleDataName.MagicDefence
end
end
function BattleUtil.GetHPPencent(role)
return role:GetRoleData(RoleDataName.Hp) / role:GetRoleData(RoleDataName.MaxHp)
end
-- 计算数值
function BattleUtil.CountValue(v1, v2, ct)
local v = v1
if ct == 1 then --加算
v = v + v2
elseif ct == 2 then --乘加算(百分比属性加算)
v = v * (1 + v2)
elseif ct == 3 then --减算
v = v - v2
elseif ct == 4 then --乘减算(百分比属性减算)
v = v * (1 - v2)
elseif ct == 5 then -- 覆盖
v = v2
end
-- 做一个正确性检测
-- v = BattleUtil.ErrorCorrection(v)
return v
end
-- 计算数值改变
function BattleUtil.CountChangeList(v, changeList)
local aplist = {}
local splist = {}
local cplist = {}
local fv = v
-- 先算绝对值
for _, change in ipairs(changeList) do
local cv = change[1]
local ct = change[2]
if ct then
if ct == 1 or ct == 3 then
fv = BattleUtil.CountValue(fv, cv, ct)
elseif ct == 2 then
table.insert(aplist, change)
elseif ct == 4 then
table.insert(splist, change)
elseif ct == 5 then
table.insert(cplist, change)
end
end
end
-- 加乘(对基数进行加乘)
for _, change in ipairs(aplist) do
local cv = change[1]
local ct = change[2]
fv = fv + (BattleUtil.CountValue(v, cv, ct) - v)
end
-- 减乘(对最终数值进行减乘算)
for _, change in ipairs(splist) do
local cv = change[1]
local ct = change[2]
fv = BattleUtil.CountValue(fv, cv, ct)
end
-- 覆盖
for _, change in ipairs(cplist) do
local cv = change[1]
local ct = change[2]
fv = BattleUtil.CountValue(fv, cv, ct)
end
return fv
end
-- 检测技能伤害治疗加乘
function BattleUtil.CheckSkillDamageHeal(f, caster, target)
local cl = {}
local function _CallBack(v, ct)
if v then
table.insert(cl, {v, ct})
end
end
caster.Event:DispatchEvent(BattleEventName.PassiveSkillDamageHeal, _CallBack)
target.Event:DispatchEvent(BattleEventName.PassiveBeSkillDamageHeal, _CallBack)
f = BattleUtil.CountChangeList(f, cl)
return f
end
-- 检测技能伤害治疗加乘
function BattleUtil.CheckSeckill(bf, kf, caster, target)
local bcl = {}
local kcl = {}
local function _CallBack(bv, bct, kv, kct)
if bv and bct then
table.insert(bcl, {bv, bct})
end
if kv and kct then
table.insert(kcl, {kv, kct})
end
end
caster.Event:DispatchEvent(BattleEventName.PassiveSeckill, _CallBack)
target.Event:DispatchEvent(BattleEventName.PassiveBeSeckill, _CallBack)
bf = BattleUtil.CountChangeList(bf, bcl)
kf = BattleUtil.CountChangeList(kf, kcl)
return bf, kf
end
-- 获取位置类型
-- 1 前排
-- 2 后排
function BattleUtil.GetRolePosType(pos)
if pos <= 3 then
return 1
elseif pos > 3 then
return 2
end
end
-- 根据位置类型获取数据
function BattleUtil.GetRoleListByPosType(camp, posType)
if posType == 1 then
return RoleManager.Query(function (r) return r.camp == camp and r.position <= 3 end)
elseif posType == 2 then
return RoleManager.Query(function (r) return r.camp == camp and r.position > 3 end)
end
end
-- 通用增加属性的方法
function BattleUtil.AddProp(role, prop, value, ct)
if ct == 1 then --加算
role.data:AddValue(BattlePropList[prop], value)
elseif ct == 2 then --乘加算(百分比属性加算)
role.data:AddPencentValue(BattlePropList[prop], value)
elseif ct == 3 then --减算
role.data:SubValue(BattlePropList[prop], value)
elseif ct == 4 then --乘减算(百分比属性减算)
role.data:SubPencentValue(BattlePropList[prop], value)
end
end
-- 比较值(默认返回true)
-- 0不比较返回默认true
-- 1大于
-- 2小于
-- 3等于
-- 4大于等于
-- 5小于等于
function BattleUtil.CompareValue(v1, v2, comType)
if comType == 1 then
return v1 > v2
elseif comType == 2 then
return v1 < v2
elseif comType == 3 then
return v1 == v2
elseif comType == 4 then
return v1 >= v2
elseif comType == 5 then
return v1 <= v2
end
return true
end