2019-03-12 14:05:45 +08:00
|
|
|
|
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
|
|
|
|
|
|
|
|
|
|
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.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.CalBaseDamage(atkRole, defRole, baseDamage, baseFactor)
|
|
|
|
|
local atkData, defData = atkRole.data, defRole.data
|
|
|
|
|
if not baseFactor then baseFactor = 1 end
|
|
|
|
|
|
|
|
|
|
--伤害 =(基础伤害*(1+己伤害加成-目标伤害减免)*(1+己方属性伤害加成-目标属性伤害减免),10%*己攻)
|
|
|
|
|
local damage = baseDamage * baseFactor *
|
|
|
|
|
(1 + atkData:GetData(RoleDataName.DamageBocusFactor)) * (1 - defData:GetData(RoleDataName.DamageReduceFactor)) *
|
|
|
|
|
(1 + atkData:GetData(RoleDataName.FireDamageBocusFactor)) * (1 - defData:GetData(RoleDataName.FireDamageReduceFactor)) * --火系
|
|
|
|
|
(1 + atkData:GetData(RoleDataName.WindDamageBocusFactor)) * (1 - defData:GetData(RoleDataName.WindDamageReduceFactor)) * --风系
|
|
|
|
|
(1 + atkData:GetData(RoleDataName.IceDamageBocusFactor)) * (1 - defData:GetData(RoleDataName.IceDamageReduceFactor)) * --冰系
|
|
|
|
|
(1 + atkData:GetData(RoleDataName.LandDamageBocusFactor)) * (1 - defData:GetData(RoleDataName.LandDamageReduceFactor)) * --地系
|
|
|
|
|
(1 + atkData:GetData(RoleDataName.LightDamageBocusFactor)) * (1 - defData:GetData(RoleDataName.LightDamageReduceFactor)) * --光系
|
|
|
|
|
(1 + atkData:GetData(RoleDataName.DarkDamageBocusFactor)) * (1 - defData:GetData(RoleDataName.DarkDamageReduceFactor)) --暗系
|
|
|
|
|
return damage
|
|
|
|
|
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.CalCrit(atkRole, defRole)
|
|
|
|
|
local bCrit = Random.Range01() <= clamp(atkRole:GetRoleData(RoleDataName.Crit), 0, 1)
|
|
|
|
|
|
|
|
|
|
if bCrit then
|
|
|
|
|
atkRole.Event:DispatchEvent(BattleEventName.RoleCrit, defRole)
|
|
|
|
|
defRole.Event:DispatchEvent(BattleEventName.RoleBeCrit, atkRole)
|
|
|
|
|
end
|
|
|
|
|
return bCrit
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
function BattleUtil.CalShield(atkRole, defRole, damage)
|
2019-03-21 14:33:56 +08:00
|
|
|
|
local buff
|
|
|
|
|
for i=1, defRole.shield.size do
|
|
|
|
|
buff = defRole.shield.buffer[i]
|
|
|
|
|
if damage < buff.shieldValue then
|
|
|
|
|
buff.shieldValue = buff.shieldValue - damage
|
|
|
|
|
buff.damageSum = buff.damageSum + damage
|
|
|
|
|
return 0
|
|
|
|
|
else
|
|
|
|
|
buff.damageSum = buff.damageSum + buff.shieldValue
|
|
|
|
|
damage = damage - buff.shieldValue
|
|
|
|
|
buff.shieldValue = 0
|
|
|
|
|
buff.disperse = true
|
2019-03-12 14:05:45 +08:00
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
return damage
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
function BattleUtil.ApplyDamage(atkRole, defRole, damage, bCrit)
|
|
|
|
|
if not bCrit then bCrit = false end
|
|
|
|
|
damage = floor(damage + 0.5)
|
|
|
|
|
local finalDmg = defRole.data:SubValue(RoleDataName.Hp, damage)
|
|
|
|
|
if finalDmg > 0 then
|
|
|
|
|
if atkRole then
|
|
|
|
|
atkRole.Event:DispatchEvent(BattleEventName.RoleDamage, defRole, damage, bCrit)
|
|
|
|
|
end
|
|
|
|
|
defRole.Event:DispatchEvent(BattleEventName.RoleBeDamaged, atkRole, damage, bCrit)
|
|
|
|
|
|
|
|
|
|
if defRole:GetRoleData(RoleDataName.Hp) <= 0 then
|
|
|
|
|
defRole.isDead = true
|
|
|
|
|
defRole.Event:DispatchEvent(BattleEventName.RoleDead)
|
|
|
|
|
BattleLogic.Event:DispatchEvent(BattleEventName.BattleRoleDead, defRole)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
return finalDmg
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
--执行完整的命中,伤害,暴击计算,返回命中,暴击
|
|
|
|
|
function BattleUtil.CalDamage(atkRole, defRole, damageType, baseFactor)
|
2019-03-21 14:33:56 +08:00
|
|
|
|
if atkRole.isTeam and not defRole.isDead then
|
|
|
|
|
return BattleUtil.ApplyDamage(atkRole, defRole, damageType), false
|
|
|
|
|
end
|
2019-03-12 14:05:45 +08:00
|
|
|
|
local bCrit = false
|
|
|
|
|
local baseDamage
|
|
|
|
|
bCrit = BattleUtil.CalCrit(atkRole, defRole)
|
|
|
|
|
local defence = 0
|
|
|
|
|
if damageType == 1 then --1 物理 2 魔法
|
|
|
|
|
defence = defRole:GetRoleData(RoleDataName.PhysicalDefence)
|
|
|
|
|
else
|
|
|
|
|
defence = defRole:GetRoleData(RoleDataName.MagicDefence)
|
|
|
|
|
end
|
|
|
|
|
local attack = 0
|
|
|
|
|
if atkRole.GetAttackFunc then
|
|
|
|
|
attack = atkRole.GetAttackFunc(bCrit)
|
|
|
|
|
else
|
|
|
|
|
attack = atkRole:GetRoleData(RoleDataName.Attack)
|
|
|
|
|
end
|
|
|
|
|
--计算暴击
|
|
|
|
|
if bCrit or defRole.isFlagCrit then
|
|
|
|
|
local critDamageFactor = atkRole:GetRoleData(RoleDataName.CritDamageFactor)
|
|
|
|
|
baseDamage = attack * critDamageFactor - 0.5 * defence
|
|
|
|
|
else
|
|
|
|
|
baseDamage = attack - 0.5 * defence
|
|
|
|
|
end
|
|
|
|
|
baseDamage = BattleUtil.CalBaseDamage(atkRole, defRole, baseDamage, baseFactor)
|
|
|
|
|
baseDamage = max(baseDamage, 0.1 * attack)
|
2019-03-21 14:33:56 +08:00
|
|
|
|
|
|
|
|
|
local func
|
|
|
|
|
for i=1, atkRole.exCalDmgList.size do
|
|
|
|
|
func = atkRole.exCalDmgList.buffer[i]
|
|
|
|
|
baseDamage = func(baseDamage)
|
|
|
|
|
end
|
|
|
|
|
|
2019-03-12 14:05:45 +08:00
|
|
|
|
baseDamage = BattleUtil.CalShield(atkRole, defRole, baseDamage)
|
|
|
|
|
local finalDmg = 0 --计算实际造成的扣血
|
|
|
|
|
if not defRole.isDead then
|
|
|
|
|
finalDmg = BattleUtil.ApplyDamage(atkRole, defRole, baseDamage, bCrit)
|
|
|
|
|
end
|
|
|
|
|
return finalDmg, bCrit
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
function BattleUtil.ApplyTreat(castRole, targetRole, value, baseFactor)
|
|
|
|
|
if not baseFactor then baseFactor = 1 end
|
|
|
|
|
local maxHp = targetRole:GetRoleData(RoleDataName.MaxHp)
|
|
|
|
|
local hp = targetRole:GetRoleData(RoleDataName.Hp)
|
|
|
|
|
local factor = castRole:GetRoleData(RoleDataName.TreatFacter)
|
|
|
|
|
local treat = min(floor(value * baseFactor * factor + 0.5), maxHp - hp)
|
|
|
|
|
targetRole.data:AddValue(RoleDataName.Hp, treat)
|
|
|
|
|
castRole.Event:DispatchEvent(BattleEventName.RoleTreat, targetRole, treat)
|
|
|
|
|
targetRole.Event:DispatchEvent(BattleEventName.RoleBeTreated, castRole, treat)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
function BattleUtil.RandomAction(rand, action)
|
|
|
|
|
if Random.Range01() <= rand and action then
|
|
|
|
|
action()
|
|
|
|
|
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.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) * 100
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|