123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974 |
- local LastAttakedByMonster = "@上次被怪物攻击的变量"
- local HurtTypeDefKeys = {
- YI_BAN = "YI_BAN",
- ZHUO_YUE = "ZHUO_YUE",
- XING_YUN = "XING_YUN",
- WU_SHI = "WU_SHI",
- SHUANG_BEI = "SHUANG_BEI"
- }
- FightDamageTypeCache = {}
- local this = {}
- local FightLog = {}
- function excusefightdamage(actor, paramMapList)
- local fightResults = {}
- for _, paramMap in pairs(paramMapList) do
- local fightResultList = this.ExcuseFightDamage(actor, paramMap)
- for _, fightResult in pairs(fightResultList) do
- fightResult["target"] = paramMap["target"]
- table.insert(fightResults, fightResult)
- end
- end
- if table.count(paramMapList) > 0 then
- this.AttackPassiveSkill(actor, paramMapList)
- end
- return fightResults
- end
- -- 被动技能
- function this.AttackPassiveSkill(actor, paramMapList)
- local selfType = getbaseinfo(actor, "mapobjecttype")
- if selfType ~= MapObjectType.PLAYER then
- return
- end
- local targetList = {}
- local skillId = paramMapList[1].skillid
- local skillLevel = paramMapList[1].skilllevel
- for _, paramMap in pairs(paramMapList) do
- table.insert(targetList, paramMap["target"])
- end
- PassiveSkill.RoleAttack(actor, targetList, skillId, skillLevel)
- end
- function this.IsSelfPet(actor, target)
- if actor == nil or target == nil then
- return false
- end
- local selfType = getbaseinfo(actor, "mapobjecttype")
- local targetType = getbaseinfo(target, "mapobjecttype")
- if selfType ~= MapObjectType.PLAYER then
- return false
- end
- if targetType ~= MapObjectType.PET then
- return false
- end
- local masterId = getbaseinfo(target, "master")
- local id = getbaseinfo(actor, "id")
- if masterId ~= id then
- return false
- end
- return true
- end
- function this.logTargetAttrInfo(targetActor)
- if targetActor == nil then
- return
- end
- local targetAttrInfo = getallattrinfo(targetActor)
- if targetAttrInfo == nil then
- return
- end
- local logText = ""
- for k, v in pairs(targetAttrInfo) do
- local attrId = tonumber(k)
- local attrValue = tonumber(v)
- if attrValue ~= 0 then
- local attrName = ConfigDataManager.getTableValue("cfg_att_info", "attribute", "id", attrId)
- if not string.isNullOrEmpty(logText) then
- logText = logText .. ","
- end
- logText = logText .. attrName .. "=" .. attrValue
- end
- end
- if not string.isNullOrEmpty(logText) then
- local name = getbaseinfo(targetActor, "rolename")
- logText = "攻击目标=" .. name .. ",目标属性【" .. logText .. "】"
- end
- fightlog(logText)
- end
- function this.ExcuseFightDamage(actor, paramMap)
- --fixme 异步问题,lua队列任务执行时,地图可能已经被销毁
- if not mapexists(actor) then
- info(actor:toString() .. "执行战斗脚本时,原地图已经被销毁")
- return this.BuildFightResult(0, 0, 0, 0, 108, 1)
- end
- --fightlog("\n==========================================\n战斗日志\n==========================================")
- this.initData(paramMap)
- local castType = paramMap["castertype"]
- local targetType = paramMap["targettype"]
- local target = paramMap["target"]
- if this.IsSelfPet(actor, target) then
- fightlog("攻击自己的召唤兽无效")
- local result = this.BuildFightResult(0, 0, 0, 0, 108, 1)
- return { result }
- end
- this.logTargetAttrInfo(target)
- if this.CanHit(paramMap) == false then
- local result = this.BuildFightResult(0, 0, 0, 0, 108, 1)
- return { result }
- end
- if this.CheckPKCanHurt(paramMap) == false then
- fightlog("pk值较高,无法对玩家造成伤害")
- local result = this.BuildFightResult(0, 0, 0, 0, 108, 1)
- return { result }
- end
- -- 攻城战是否可以攻击
- if not RolandSeige.CanAttackRolandWall(actor, target, castType, targetType) then
- local result = this.BuildFightResult(0, 0, 0, 0, 108, 1)
- return { result }
- end
- local originDamage
- local elementalDamage = 0
- local elementalType
- if castType == MapObjectType.PLAYER or castType == MapObjectType.PET then
- --攻击者是玩家或者宠物
- originDamage = this.PlayerCastDamage(actor, paramMap)
- -- 元素伤害
- elementalDamage, elementalType = this.ElementalHurt(paramMap)
- elseif castType == 2 then
- --攻击者是怪物
- originDamage = this.MonsterCastDamage(actor, paramMap)
- else
- error("this.ExcuseFightDamage=>不存在的攻击者类型", castType)
- local result = this.BuildFightResult(0, 0, 0, 0, 108, 1)
- return { result }
- end
- originDamage = EquipGem.handleGemAttrs(actor, target, originDamage, castType, targetType)
- originDamage = this.handleHuolong(paramMap, originDamage)
- originDamage = this.noviceProtect(paramMap, originDamage)
- if originDamage == 0 then
- local result = this.BuildFightResult(0, 0, 0, 0, 108, 1)
- return { result }
- end
- local originDamage, repeatl = this.getRepeatInfo(paramMap, originDamage)
- -- 副本修正伤害
- originDamage = this.DupFixDamage(originDamage, paramMap)
- elementalDamage = this.DupFixDamage(elementalDamage, paramMap)
- -- 反伤
- local casterHurt = this.ReflexDamage(paramMap, originDamage + elementalDamage)
- this.AfterCalcuDamage(paramMap, originDamage + elementalDamage)
- this.RecoverHP(paramMap, originDamage + elementalDamage)
- local resultList = {}
- local result = {}
- local isComboSkill = Skill.isComboSkill(actor, tonumber(paramMap["skillid"]))
- if isComboSkill then
- result = this.BuildFightResult(casterHurt, originDamage, 0, 0, 301, repeatl, isComboSkill)
- elseif TransferCard.GetCurrentTransfermation(actor) > 0 then
- -- 变身状态秒杀日志
- this.LogMiaoSha(actor, target, targetType, originDamage, paramMap.monsterid, paramMap["skillid"])
- result = this.BuildFightResult(casterHurt, originDamage, 0, 0, 401, repeatl, isComboSkill)
- else
- result = this.BuildFightResult(casterHurt, originDamage, 0, 0, FightDamageTypeCache.GetHurtType(actor), repeatl, isComboSkill)
- end
- table.insert(resultList, result)
- if elementalDamage > 0 then
- local elementalResult = this.BuildFightResult(0, elementalDamage, 0, 0, elementalType, 1, isComboSkill)
- table.insert(resultList, elementalResult)
- end
- return resultList
- end
- -- 副本修正伤害
- function this.DupFixDamage(originDamage, paramMap)
- local caster = paramMap.caster
- local targetType = paramMap.targettype
- if targetType == MapObjectType.MONSTER then
- if RolandSeige.IsPlayerInRoland(caster) then
- return 1
- end
- end
- return originDamage
- end
- -- 线上秒杀加日志
- function this.LogMiaoSha(actor, target, targetType, hurt, monsterCfgId, skillId)
- if targetType == MapObjectType.MONSTER then
- local monsterType = tonumber(ConfigDataManager.getTableValue("cfg_monster", "type", "id", monsterCfgId))
- if monsterType == 2 or monsterType == 3 then
- local maxHp = getbaseinfo(target, "maxhp")
- if hurt * 2 >= maxHp then
- info(actor:toString() .. "变身对BOSS造成巨额伤害。skillId:" .. skillId .. " ;monsterCfg:" .. monsterCfgId)
- end
- end
- end
- end
- -- 攻击回血
- function this.RecoverHP(paramMap, originDamage)
- local caster = paramMap["caster"]
- local HPAttackRecover = getattrinfo(caster, "HPAttackRecover")
- local HPAttackRecoveronus = getattrinfo(caster, "HPAttackRecoveronus")
- local attackBlood = getattrinfo(caster, "attackBlood")
- local attackRecover = originDamage * attackBlood
- local hpRecover = HPAttackRecover * (1 + HPAttackRecoveronus) + attackRecover
- local currentHp = getbaseinfo(caster, "hp")
- sethp(caster, hpRecover + currentHp)
- end
- function this.ReflexDamage(paramMap, originDamage)
- local casterHurt = 0
- local caster = paramMap["caster"]
- local target = paramMap["target"]
- local damageReflexProbability = getattrinfo(target, "damageReflexProbability")
- local damageReflexResistanceProbability = getattrinfo(caster, "damageReflexResistanceProbability")
- local rate = damageReflexProbability - damageReflexResistanceProbability
- if this.SelectRate(rate) then
- local damageReflex = getattrinfo(target, "damageReflex")
- local pvpDamageReflexAdd = getattrinfo(target, "pvpDamageReflexAdd")
- local pvpDamageReflexReduce = getattrinfo(caster, "pvpDamageReflexReduce")
- casterHurt = originDamage * damageReflex + pvpDamageReflexAdd - pvpDamageReflexReduce
- casterHurt = math.max(0, casterHurt)
- end
- return casterHurt
- end
- --处理重复伤害次数
- function this.getRepeatInfo(paramMap, originDamage)
- local skillId = paramMap["skillid"]
- local skillLevel = paramMap["skilllevel"]
- local valueTimes = ConfigDataManager.getTableValue("cfg_skill_info", "valueTimes", "skillID", skillId, "skillLevel", skillLevel)
- local repeatl = RandomUtil.selectKey(valueTimes)
- repeatl = math.max(repeatl, 1)
- originDamage = originDamage * repeatl
- return originDamage, repeatl
- end
- function this.handleHuolong(paramMap, originDamage)
- local caster = paramMap["caster"]
- local castMapObjectType = getbaseinfo(caster, "mapobjecttype")
- if castMapObjectType ~= MapObjectType.MONSTER then
- return originDamage
- end
- local monsterInfo = getmonsterinfo(caster)
- local cfgId = monsterInfo["cfgid"]
- if tonumber(cfgId) ~= MonsterConfigId.HUOLONG then
- return originDamage
- end
- local target = paramMap["target"]
- local targetMaxHp = getattrinfo(target, "maxHP")
- local costHp = targetMaxHp * 0.05
- return originDamage + costHp
- end
- function this.noviceProtect(paramMap, originDamage)
- local target = paramMap["target"]
- local targetType = paramMap["targettype"]
- if targetType ~= MapObjectType.PLAYER then
- return originDamage
- end
- local novice = getplaydef(target, NOVICE_PROTECT)
- if not novice then
- return originDamage
- end
- if novice then
- local currentHp = getbaseinfo(target, "hp")
- local haveHp = currentHp - originDamage
- local stringHp = ConfigDataManager.getTableValue("cfg_global", "value", "id", "15004")
- local hp = tonumber(stringHp)
- if haveHp < hp then
- return 0
- end
- end
- return originDamage
- end
- function this.initData(paramMap)
- local caster = paramMap["caster"]
- local originType = {
- [HurtTypeDefKeys.YI_BAN] = "1",
- [HurtTypeDefKeys.ZHUO_YUE] = "0",
- [HurtTypeDefKeys.XING_YUN] = "0",
- [HurtTypeDefKeys.WU_SHI] = "0",
- [HurtTypeDefKeys.SHUANG_BEI] = "0",
- }
- setplaydef(caster, PlayerDefKey.PLAYER_FIGHT_HURT_TYPE, originType)
- table.clear(FightLog)
- end
- function FightDamageTypeCache.GetHurtType(caster)
- local resultType = getplaydef(caster, PlayerDefKey.PLAYER_FIGHT_HURT_TYPE)
- local yiBanGongJi = resultType[HurtTypeDefKeys.YI_BAN]
- local zhuoYueYiJi = resultType[HurtTypeDefKeys.ZHUO_YUE]
- local xinYunYiJi = resultType[HurtTypeDefKeys.XING_YUN]
- local wuShiFangYu = resultType[HurtTypeDefKeys.WU_SHI]
- local shuangBeiYiJi = resultType[HurtTypeDefKeys.SHUANG_BEI]
- local typeString = yiBanGongJi .. zhuoYueYiJi .. xinYunYiJi .. wuShiFangYu .. shuangBeiYiJi
- local hurtTypeCache = getsysvar(SystemVarConst.NORMAL_DAMAGE_TYPE_CACHE, 0)
- local type = hurtTypeCache[typeString]
- if type == nil then
- error(caster, caster, "获取攻击类型配置失败,结果为", typeString)
- type = 101
- end
- return type
- end
- function FightDamageTypeCache.GetElementalHurtType(caster, key)
- local elementalCache = getsysvar(SystemVarConst.ELEMENTAL_DAMAGE_TYPE_CACHE, 0)
- local type = elementalCache[key]
- if type == nil then
- if string.contains(key, "1") then
- error(caster, caster, "获取元素伤害类型配置失败,结果为", key)
- end
- type = 101
- end
- return type
- end
- function this.BuildFightResult(casthurt, targethurt, castershield, targetshield, hurttype, repeatl, combo)
- combo = combo or false
- local result = {}
- result["comboskill"] = combo
- result["casthurt"] = casthurt
- result["targethurt"] = targethurt
- result["castershield"] = castershield
- result["targetshield"] = targetshield
- result["hurttype"] = hurttype
- result["repeat"] = repeatl
- result["targethurtshow"] = targethurt / repeatl --飘字体用的伤害:真实伤害除以次数
- fightlog(string.joinVar("目标扣血", math.floor(targethurt)) .. string.joinVar("攻击者扣血", math.floor(casthurt)) .. string.joinVar("目标扣护盾", math.floor(targetshield)) .. string.joinVar("攻击者扣护盾", math.floor(castershield)) .. string.joinVar("伤害类型", hurttype) .. string.joinVar("伤害次数", repeatl, true))
- result["fightLog"] = FightLog
- return result
- end
- function this.PlayerCastDamage(actor, paramMap)
- local caster = paramMap["caster"]
- local target = paramMap["target"]
- local armor = getattrinfo(target, "armor")
- local targetType = paramMap["targettype"]
- local armorPenetrate = 0
- if targetType == MapObjectType.PLAYER then
- armorPenetrate = getattrinfo(caster, "armorPenetrate")
- end
- local var
- if this.IsWuShiFangYu(paramMap) then
- fightlog("触发 无视防御")
- var = 0
- else
- var = 1
- end
- --伤害1=【IF(A幸运一击触发,A幸运攻击,A随机攻击)-(B防御-APVP防御穿透)/2*IF(A无视防御触发,0,1)】+A卓越攻击+A双倍攻击
- fightlog("伤害1=【IF(A幸运一击触发,A幸运攻击,A随机攻击)-(B防御-APVP防御穿透)/2*IF(A无视防御触发,0,1)】+A卓越攻击+A双倍攻击")
- local damage1 = this.XingYunDamage(paramMap) - math.max(0, (armor - armorPenetrate)) / 2 * var + this.ZhuoYueDamage(paramMap) + this.ShuangBeiYiJi(paramMap)
- fightlog("伤害1:" .. damage1)
- --伤害2=伤害1 * A使用技能对应技能系数 *(1+A技能伤害加成百分比 - B技能伤害减少百分比)
- fightlog("伤害2=伤害1 * A使用技能对应技能系数 *(1+A技能伤害加成百分比 - B技能伤害减少百分比)")
- local skillId = paramMap["skillid"]
- local skillLevel = paramMap["skilllevel"]
- local powerRate = tonumber(ConfigDataManager.getTableValue("cfg_skill_info", "powerRate", "skillID", skillId, "skillLevel", skillLevel))
- powerRate = powerRate == nil and 0 or powerRate
- powerRate = powerRate / 10000
- local freeAtt6 = getattrinfo(caster, "freeAtt6")
- local freeAtt7 = getattrinfo(target, "freeAtt7")
- local damage2 = damage1 * powerRate * (1 + freeAtt6 - freeAtt7)
- fightlog("伤害2:" .. damage2)
- --伤害3=伤害2 *(1+A加点伤害加成)*(1+A伤害加成 - B伤害吸收)*(1 - B伤害减少)*【1+IF(B为怪物,A对怪伤害加成,0)*【1+IF(B为玩家,A对玩家伤害加成,0)-IF(B为玩家,B对玩家伤害吸收,0)】*【1-IF(B为玩家,B对玩家伤害减免,0)】
- fightlog("伤害3=伤害2 *(1+A加点伤害加成)*(1+A伤害加成 - B伤害吸收)*(1 - B伤害减少)*【1+IF(B为怪物,A对怪伤害加成,0)*【1+IF(B为玩家,A对玩家伤害加成,0)-IF(B为玩家,B对玩家伤害吸收,0)】*【1-IF(B为玩家,B对玩家伤害减免,0)】")
- local addtion = this.GetJiaDianAddition(paramMap)
- local damageRate = getattrinfo(caster, "damageRate")
- local damageAbsorb = getattrinfo(target, "damageAbsorb")
- local damageRateDecrement = getattrinfo(target, "damageRateDecrement")
- local damage3 = damage2 * (1 + addtion) * (1 + damageRate - damageAbsorb) * (1 - damageRateDecrement)
- local damage3 = this.buffDecrement(target,damage3)
- if paramMap["targettype"] == 2 then
- local damageIncreaseRate = getattrinfo(caster, "damageIncreaseRate")
- damage3 = damage3 * (1 + damageIncreaseRate)
- end
- if paramMap["targettype"] == 1 then
- local damageBonus = getattrinfo(caster, "damageIncreaseRate")
- local damageReductionBonus = getattrinfo(target, "damageReductionBonus")
- local absorbDamageToPlayers = getattrinfo(target, "absorbDamageToPlayers")
- damage3 = damage3 * (1 + damageBonus - absorbDamageToPlayers) * (1 - damageReductionBonus)
- end
- fightlog("伤害3:" .. damage3)
- -- 伤害4=伤害3+A技能伤害加成固定值 - B技能伤害减少固定值
- fightlog("伤害4=伤害3+A技能伤害加成固定值+A技能伤害固定值 - B技能伤害减少固定值")
- local freeAtt1 = getattrinfo(caster, "freeAtt1")
- local freeAtt2 = getattrinfo(target, "freeAtt2")
- local fixedDamage = tonumber(ConfigDataManager.getTableValue("cfg_skill_info", "fixedDamage", "skillID", skillId, "skillLevel", skillLevel))
- if fixedDamage == nil then
- fixedDamage = 0
- end
- local damage4 = damage3 + freeAtt1 + fixedDamage - freeAtt2
- fightlog("伤害4:" .. damage4)
- local finalDamage = 0
- if targetType == MapObjectType.PLAYER then
- -- 最终伤害=伤害4+APVP出血伤害固定值-BPVP出血伤害抵抗固定值
- fightlog("最终伤害=伤害4+APVP出血伤害固定值-BPVP出血伤害抵抗固定值")
- local pvpBleedDamageAdd = getattrinfo(caster, "pvpBleedDamageAdd")
- local pvpBleedDamageReduce = getattrinfo(target, "pvpBleedDamageReduce")
- finalDamage = damage4 + math.max(0, pvpBleedDamageAdd - pvpBleedDamageReduce)
- elseif targetType == MapObjectType.MONSTER then
- -- 最终伤害=伤害4+A对怪伤害增加固定值
- fightlog("最终伤害=伤害4+A对怪伤害增加固定值")
- local pveDamageAdd = getattrinfo(caster, "pveDamageAdd")
- finalDamage = damage4 + pveDamageAdd
- end
- -- 处于攻城战副本时,范围伤害修改
- finalDamage = this.RolandSeigeAOECal(actor, skillId, finalDamage)
- -- A打B最终伤害<保底伤害时,最终伤害=保底伤害=A最大攻击力*可配置系数
- fightlog("A打B最终伤害<保底伤害时,最终伤害=保底伤害=A最大攻击力*可配置系数")
- local minDC, maxDC = this.GetDCBySkill(paramMap)
- local factor = tonumber(ConfigDataManager.getTableValue("cfg_global", "value", "id", 7000)) / 10000
- local minDamage = maxDC * factor
- local originFinalDamage = finalDamage
- if finalDamage < minDamage then
- finalDamage = minDamage
- end
- fightlog("最终伤害:" .. originFinalDamage .. " 保底伤害:" .. minDamage)
- return finalDamage
- end
- --- 目标属性概率减伤
- function this.buffDecrement(actor,damage)
- local damageRateDecrement5 = getattrinfo(actor, "damageRateDecrement5")
- if damageRateDecrement5 ~= 0 then
- local successRate = math.random(0, 100)
- if successRate <= 5 then
- damage = damage * (1 - damageRateDecrement5)
- end
- end
- local damageRateDecrement10 = getattrinfo(actor, "damageRateDecrement10")
- if damageRateDecrement10 ~= 0 then
- local successRate = math.random(0, 100)
- if successRate <= 10 then
- damage = damage * (1 - damageRateDecrement10)
- end
- end
- return damage
- end
- function this.RolandSeigeAOECal(actor, skillId, originDamage)
- if RolandSeige.IsPlayerInRoland(actor) then
- local aoe = tonumber(ConfigDataManager.getTableValue("cfg_skill", "aoe", "id", skillId))
- if aoe == 1 then
- local rate = tonumber(ConfigDataManager.getTableValue("cfg_repGlobal", "value", "id", RepGlobalConfig.ROLAND_SEIGE.AOE_DAMAGE_FIX))
- return originDamage * (rate / 100)
- end
- end
- return originDamage
- end
- function this.MonsterCastDamage(actor, paramMap)
- local caster = paramMap["caster"]
- local target = paramMap["target"]
- local armor = getattrinfo(target, "armor")
- --伤害1=【IF(A幸运一击触发,A幸运攻击,A随机攻击)】+A卓越攻击+A双倍攻击
- fightlog("伤害1=【IF(A幸运一击触发,A幸运攻击,A随机攻击)】+A卓越攻击+A双倍攻击")
- local damage1 = this.XingYunDamage(paramMap) + this.ZhuoYueDamage(paramMap) + this.ShuangBeiYiJi(paramMap)
- fightlog("伤害1:" .. damage1)
- --伤害2=伤害1 * A使用技能对应技能系数 *(1+A技能伤害加成百分比 - B技能伤害减少百分比)
- fightlog("伤害2=伤害1 * A使用技能对应技能系数 *(1+A技能伤害加成百分比 - B技能伤害减少百分比)")
- local skillId = paramMap["skillid"]
- local skillLevel = paramMap["skilllevel"]
- local powerRate = tonumber(ConfigDataManager.getTableValue("cfg_skill_info", "powerRate", "skillID", skillId, "skillLevel", skillLevel))
- powerRate = powerRate == nil and 0 or powerRate
- powerRate = powerRate / 10000
- local freeAtt6 = getattrinfo(caster, "freeAtt6")
- local freeAtt7 = getattrinfo(target, "freeAtt7")
- local damage2 = damage1 * powerRate * (1 + freeAtt6 - freeAtt7)
- fightlog("伤害2:" .. damage2)
- --伤害3=伤害2 *(1+A加点伤害加成)*(1+A伤害加成 - B伤害吸收)*(1 - B伤害减少)*(1 - B对怪伤害减少百分比)*【1 - IF(受多只怪物攻击,B多怪减伤百分比,0)】
- fightlog("伤害3=伤害2 *(1+A加点伤害加成)*(1+A伤害加成 - B伤害吸收)*(1 - B伤害减少)*(1 - B对怪伤害减少百分比)*【1 - IF(受多只怪物攻击,B多怪减伤百分比,0)】")
- local addtion = this.GetJiaDianAddition(paramMap)
- local damageRate = getattrinfo(caster, "damageRate")
- local damageAbsorb = getattrinfo(target, "damageAbsorb")
- local damageRateDecrement = getattrinfo(target, "damageRateDecrement")
- local damageReceiveDecrement = getattrinfo(target, "damageReceiveDecrement")
- local damage3 = damage2 * (1 + addtion) * (1 + damageRate - damageAbsorb) * (1 - damageRateDecrement) * (1 - damageReceiveDecrement)
- local damage3 = this.buffDecrement(target,damage3)
- if this.IfAttackedMutipleMonster(paramMap) then
- local freeAtt9 = getattrinfo(target, "freeAtt9")
- damage3 = damage3 * (1 - freeAtt9)
- end
- fightlog("伤害3:" .. damage3)
- -- 伤害4=伤害3 - B防御/2*IF(A无视防御触发,0,1)+A技能伤害加成固定值 - B技能伤害减少固定值
- fightlog("伤害4=伤害3 - B防御/2*IF(A无视防御触发,0,1)+A技能伤害加成固定值 - B技能伤害减少固定值")
- if this.IsWuShiFangYu(paramMap) == false then
- damage3 = damage3 - armor / 2
- end
- local freeAtt1 = getattrinfo(caster, "freeAtt1")
- local freeAtt2 = getattrinfo(target, "freeAtt2")
- local damage4 = damage3 + freeAtt1 - freeAtt2
- fightlog("伤害4:" .. damage4)
- -- 最终伤害=伤害4-B对怪伤害减少固定值
- fightlog("最终伤害=伤害4-B对怪伤害减少固定值")
- local pveDamageReduce = getattrinfo(target, "pveDamageReduce")
- local finalDamage = damage4 - pveDamageReduce
- --todo 保底伤害 怪物打玩家最终伤害<保底伤害时,最终伤害=保底伤害(怪物属性表配置)
- fightlog("怪物打玩家最终伤害<保底伤害时,最终伤害=保底伤害(怪物属性表配置)")
- local monInfo = getmonsterinfo(caster)
- local monsterConfig = monInfo["cfgid"]
- local minDamage = tonumber(ConfigDataManager.getTableValue("cfg_monster", "guaranteedDamage", "id", monsterConfig))
- if finalDamage < minDamage then
- finalDamage = minDamage
- end
- fightlog("最终伤害:" .. finalDamage .. " 保底伤害:" .. minDamage)
- return finalDamage
- end
- -- 元素伤害
- function this.ElementalHurt(paramMap)
- local caster = paramMap.caster
- local target = paramMap.target
- local hurtTypeKey
- -- 圣光
- local shengGuangDamage = 0
- local HolyUnMissRate = getattrinfo(caster, "HolyUnMissRate")
- local HolyResistUnMissRate = getattrinfo(target, "HolyResistUnMissRate")
- local HolyAttack = getattrinfo(caster, "HolyAttack")
- if not this.SelectRate(math.max(0, HolyResistUnMissRate - HolyUnMissRate)) and HolyAttack > 0 then
- local HolyDamageIncreased = getattrinfo(caster, "HolyDamageIncreased")
- local HolyDamageIncreasedBonus = getattrinfo(caster, "HolyDamageIncreasedBonus")
- local HolyDamageReduction = getattrinfo(target, "HolyDamageReduction")
- local HolyDamageReductionBonus = getattrinfo(target, "HolyDamageReductionBonus")
- shengGuangDamage = HolyAttack * (1 + HolyDamageIncreasedBonus - HolyDamageReductionBonus) + HolyDamageIncreased - HolyDamageReduction
- shengGuangDamage = math.max(shengGuangDamage, 0)
- if shengGuangDamage > 0 then
- hurtTypeKey = "1"
- else
- hurtTypeKey = "0"
- end
- else
- hurtTypeKey = "0"
- end
- -- 黑暗
- local heiAnDamage = 0
- local DarkUnMissRate = getattrinfo(caster, "DarkUnMissRate")
- local DarkResistUnMissRate = getattrinfo(target, "DarkResistUnMissRate")
- local DarkAttack = getattrinfo(caster, "DarkAttack")
- if not this.SelectRate(math.max(0, DarkResistUnMissRate - DarkUnMissRate)) and DarkAttack > 0 then
- local DarkDamageIncreased = getattrinfo(caster, "DarkDamageIncreased")
- local DarkDamageIncreasedBonus = getattrinfo(caster, "DarkDamageIncreasedBonus")
- local DarkDamageReduction = getattrinfo(target, "DarkDamageReduction")
- local DarkDamageReductionBonus = getattrinfo(target, "DarkDamageReductionBonus")
- heiAnDamage = DarkAttack * (1 + DarkDamageIncreasedBonus - DarkDamageReductionBonus) + DarkDamageIncreased - DarkDamageReduction
- heiAnDamage = math.max(heiAnDamage, 0)
- if heiAnDamage > 0 then
- hurtTypeKey = hurtTypeKey .. "1"
- else
- hurtTypeKey = hurtTypeKey .. "0"
- end
- else
- hurtTypeKey = hurtTypeKey .. "0"
- end
- -- 雷电
- local leiDianDamage = 0
- local ThunderUnMissRate = getattrinfo(caster, "ThunderUnMissRate")
- local ThunderResistUnMissRate = getattrinfo(target, "ThunderResistUnMissRate")
- local ThunderAttack = getattrinfo(caster, "ThunderAttack")
- if not this.SelectRate(math.max(0, ThunderResistUnMissRate - ThunderUnMissRate)) and ThunderAttack > 0 then
- local ThunderDamageIncreased = getattrinfo(caster, "ThunderDamageIncreased")
- local ThunderDamageIncreasedBonus = getattrinfo(caster, "ThunderDamageIncreasedBonus")
- local ThunderDamageReduction = getattrinfo(target, "ThunderDamageReduction")
- local ThunderDamageReductionBonus = getattrinfo(target, "ThunderDamageReductionBonus")
- leiDianDamage = ThunderAttack * (1 + ThunderDamageIncreasedBonus - ThunderDamageReductionBonus) + ThunderDamageIncreased - ThunderDamageReduction
- leiDianDamage = math.max(leiDianDamage, 0)
- if leiDianDamage > 0 then
- hurtTypeKey = hurtTypeKey .. "1"
- else
- hurtTypeKey = hurtTypeKey .. "0"
- end
- else
- hurtTypeKey = hurtTypeKey .. "0"
- end
- -- 风暴
- local fengBaoDmage = 0
- local StormUnMissRate = getattrinfo(caster, "StormUnMissRate")
- local StormResistUnMissRate = getattrinfo(target, "StormResistUnMissRate")
- local StormAttack = getattrinfo(caster, "StormAttack")
- if not this.SelectRate(math.max(0, StormResistUnMissRate - StormUnMissRate)) and StormAttack > 0 then
- local StormDamageIncreased = getattrinfo(caster, "StormDamageIncreased")
- local StormDamageIncreasedBonus = getattrinfo(caster, "StormDamageIncreasedBonus")
- local StormDamageReduction = getattrinfo(target, "StormDamageReduction")
- local StormDamageReductionBonus = getattrinfo(target, "StormDamageReductionBonus")
- fengBaoDmage = StormAttack * (1 + StormDamageIncreasedBonus - StormDamageReductionBonus) + StormDamageIncreased - StormDamageReduction
- fengBaoDmage = math.max(fengBaoDmage, 0)
- if fengBaoDmage > 0 then
- hurtTypeKey = hurtTypeKey .. "1"
- else
- hurtTypeKey = hurtTypeKey .. "0"
- end
- else
- hurtTypeKey = hurtTypeKey .. "0"
- end
- local totalDamage = shengGuangDamage + heiAnDamage + leiDianDamage + fengBaoDmage
- totalDamage = math.max(0, totalDamage)
- -- 伤害类型(飘字)
- local hurtType = FightDamageTypeCache.GetElementalHurtType(caster, hurtTypeKey)
- return totalDamage, hurtType
- end
- function this.XingYunDamage(paramMap)
- local caster = paramMap["caster"]
- local target = paramMap["target"]
- local minDC, maxDC = this.GetDCBySkill(paramMap)
- if this.IsXingYunYiJi(paramMap) then
- fightlog("触发 幸运一击")
- --A幸运攻击=A最大攻击 *(1+A幸运一击伤害加成 - B幸运一击伤害减少)
- local criticalDamageBonus = getattrinfo(caster, "criticalDamageBonus")
- local criticalDamageReducationBonus = getattrinfo(target, "criticalDamageReducationBonus")
- return maxDC * (1 + criticalDamageBonus - criticalDamageReducationBonus)
- else
- return math.randomFloat(minDC, maxDC)
- end
- end
- function this.ZhuoYueDamage(paramMap)
- local caster = paramMap["caster"]
- local target = paramMap["target"]
- local skillId = paramMap["skillid"]
- local skillLevel = paramMap["skilllevel"]
- local minDC, maxDC = this.GetDCBySkill(paramMap)
- --A卓越攻击=A随机攻击 * IF(A卓越一击触发,A卓越一击伤害系数,0)*(1+A卓越一击伤害加成 - B卓越一击伤害减少)
- local coefficient
- if this.IsZhuoYueYiJi(paramMap) then
- fightlog("触发 卓越一击")
- coefficient = tonumber(ConfigDataManager.getTableValue("cfg_skill_info", "excellentRate", "skillID", skillId, "skillLevel", skillLevel))
- if coefficient == nil then
- coefficient = 0
- else
- coefficient = coefficient / 10000
- end
- else
- coefficient = 0
- end
- local excellentDamageBonus = getattrinfo(caster, "excellentDamageBonus")
- local excellentDamageReducationBonus = getattrinfo(target, "excellentDamageReducationBonus")
- return math.randomFloat(minDC, maxDC) * coefficient * (1 + excellentDamageBonus - excellentDamageReducationBonus)
- end
- function this.ShuangBeiYiJi(paramMap)
- local caster = paramMap["caster"]
- local target = paramMap["target"]
- local minDC, maxDC = this.GetDCBySkill(paramMap)
- --A双倍攻击=A随机攻击 * IF(A双倍一击触发,1,0)*(1+A双倍一击伤害加成 - B双倍一击伤害减少)
- local coefficient
- if this.IsShuangBeiYiJi(paramMap) then
- fightlog("触发 双倍一击")
- coefficient = 1
- else
- coefficient = 0
- end
- local doubleDamageBonus = getattrinfo(caster, "doubleDamageBonus")
- local doubleDamageReducationBonus = getattrinfo(target, "doubleDamageReducationBonus")
- return math.randomFloat(minDC, maxDC) * coefficient * (1 + doubleDamageBonus - doubleDamageReducationBonus)
- end
- function this.IfAttackedMutipleMonster(paramMap)
- local caster = paramMap["caster"]
- local target = paramMap["target"]
- local castType = paramMap["castertype"]
- local targetType = paramMap["targettype"]
- if castType ~= 2 or targetType ~= 1 then
- return false
- end
- local monsterId = caster:toString()
- local lastDataList = getplaydef(target, LastAttakedByMonster)
- local nowMillis = getbaseinfo("now")
- if type(lastDataList) ~= "table" then
- setplaydef(target, LastAttakedByMonster, { monsterId, nowMillis })
- return false
- end
- local lastMonsterId = lastDataList[1]
- local lastMillis = lastDataList[2]
- local duration = nowMillis - lastMillis
- if lastMonsterId == monsterId or duration < 1000 then
- setplaydef(target, LastAttakedByMonster, { monsterId, nowMillis })
- return false
- end
- setplaydef(target, LastAttakedByMonster, { monsterId, nowMillis })
- return true
- end
- function this.GetJiaDianAddition(paramMap)
- local caster = paramMap["caster"]
- local skillId = paramMap["skillid"]
- local skillLevel = paramMap["skilllevel"]
- local injuryType = tonumber(ConfigDataManager.getTableValue("cfg_skill_info", "injuryType", "skillID", skillId, "skillLevel", skillLevel))
- if injuryType == 1 then
- local addtion = getattrinfo(caster, "PhysicalDamage")
- return addtion
- elseif injuryType == 2 then
- local addtion = getattrinfo(caster, "MagicDamage")
- return addtion
- elseif injuryType == 3 then
- local addtion = getattrinfo(caster, "freeAtt8")
- return addtion
- else
- local maxDC = getattrinfo(caster, "maxDC")
- local maxMC = getattrinfo(caster, "maxMC")
- local maxCurDC = getattrinfo(caster, "maximumCurseAttackPower")
- if maxDC >= maxMC and maxDC >= maxCurDC then
- local addtion = getattrinfo(caster, "PhysicalDamage")
- return addtion
- elseif maxMC >= maxDC and maxMC >= maxCurDC then
- local addtion = getattrinfo(caster, "MagicDamage")
- return addtion
- elseif maxCurDC >= maxDC and maxCurDC >= maxMC then
- local addtion = getattrinfo(caster, "freeAtt8")
- return addtion
- end
- error("不存在的伤害类型" .. injuryType .. "skillId:" .. skillId)
- return 0
- end
- end
- function this.GetDCBySkill(paramMap)
- local caster = paramMap["caster"]
- local skillId = paramMap["skillid"]
- local skillLevel = paramMap["skilllevel"]
- local injuryType = tonumber(ConfigDataManager.getTableValue("cfg_skill_info", "injuryType", "skillID", skillId, "skillLevel", skillLevel))
- if injuryType == 1 then
- local maxDC = getattrinfo(caster, "maxDC")
- local minDC = getattrinfo(caster, "minDC")
- return minDC, maxDC
- elseif injuryType == 2 then
- local maxMC = getattrinfo(caster, "maxMC")
- local minMC = getattrinfo(caster, "minMC")
- return minMC, maxMC
- elseif injuryType == 3 then
- local maxMC = getattrinfo(caster, "maximumCurseAttackPower")
- local minMC = getattrinfo(caster, "minimumCurseAttackPower")
- return minMC, maxMC
- else
- local maxDC = getattrinfo(caster, "maxDC")
- local maxMC = getattrinfo(caster, "maxMC")
- local maxCurDC = getattrinfo(caster, "maximumCurseAttackPower")
- if maxDC >= maxMC and maxDC >= maxCurDC then
- local minDC = getattrinfo(caster, "minDC")
- return minDC, maxDC
- elseif maxMC >= maxDC and maxMC >= maxCurDC then
- local minMC = getattrinfo(caster, "minMC")
- return minMC, maxMC
- elseif maxCurDC >= maxDC and maxCurDC >= maxMC then
- local minCurDC = getattrinfo(caster, "minimumCurseAttackPower")
- return minCurDC, maxCurDC
- end
- return 0, 0
- end
- end
- function this.CanHit(paramMap)
- local caster = paramMap["caster"]
- local target = paramMap["target"]
- local castType = paramMap["castertype"]
- local targetType = paramMap["targettype"]
- local hitRate
- local missRate
- if castType == 2 or targetType == 2 then
- --pve
- hitRate = getattrinfo(caster, "hitRate")
- missRate = getattrinfo(target, "missRate")
- else
- --pvp
- hitRate = getattrinfo(caster, "pvpattackRate")
- missRate = getattrinfo(target, "eraRate")
- end
- local basicMiss = getattrinfo(target, "freeAtt10")
- --todo 命中概率=1 - (1 - 1 / ((B防御率 - A攻击率) / (B防御率 + A攻击率) * 0.8 + 1)) - B基础闪避率
- fightlog("命中概率=1 - (1 - 1 / ((B防御率 - A攻击率) / (B防御率 + A攻击率) * 0.8 + 1)) - B基础闪避率")
- fightlog("A攻击率:" .. hitRate .. " B防御率:" .. missRate .. " B基础闪避率:" .. basicMiss)
- local probability
- if missRate + hitRate == 0 then
- probability = 1
- else
- probability = 1 - (1 - 1 / ((missRate - hitRate) / (missRate + hitRate) * 0.8 + 1)) - basicMiss
- end
- local hit = this.SelectRate(probability)
- fightlog("命中概率:" .. string.numToPercent(probability) .. " 命中:" .. tostring(hit))
- return hit
- end
- function this.IsXingYunYiJi(paramMap)
- --A幸运一击触发概率=A幸运一击概率 *(1 - B幸运一击概率抵抗)
- local caster = paramMap["caster"]
- local target = paramMap["target"]
- local criticalDamageChance = getattrinfo(caster, "criticalDamageChance")
- local criticalDamageResistanceChance = getattrinfo(target, "criticalDamageResistanceChance")
- local probability = criticalDamageChance * (1 - criticalDamageResistanceChance)
- local result = this.SelectRate(probability)
- if result then
- local resultType = getplaydef(caster, PlayerDefKey.PLAYER_FIGHT_HURT_TYPE)
- resultType[HurtTypeDefKeys.YI_BAN] = "0"
- resultType[HurtTypeDefKeys.XING_YUN] = "1"
- setplaydef(caster, PlayerDefKey.PLAYER_FIGHT_HURT_TYPE, resultType)
- end
- return result
- end
- function this.IsZhuoYueYiJi(paramMap)
- --A卓越一击触发概率=A卓越一击概率*(1-B卓越一击概率抵抗)
- local caster = paramMap["caster"]
- local target = paramMap["target"]
- local excellentDamageChance = getattrinfo(caster, "excellentDamageChance")
- local excellentDamageResistanceChance = getattrinfo(target, "excellentDamageResistanceChance")
- local probability = excellentDamageChance * (1 - excellentDamageResistanceChance)
- local result = this.SelectRate(probability)
- if result then
- local resultType = getplaydef(caster, PlayerDefKey.PLAYER_FIGHT_HURT_TYPE)
- resultType[HurtTypeDefKeys.YI_BAN] = "0"
- resultType[HurtTypeDefKeys.ZHUO_YUE] = "1"
- setplaydef(caster, PlayerDefKey.PLAYER_FIGHT_HURT_TYPE, resultType)
- end
- return result
- end
- function this.IsWuShiFangYu(paramMap)
- --A无视防御概率=A无视防御率 *(1 - B无视防御抵抗)
- local caster = paramMap["caster"]
- local target = paramMap["target"]
- local unMissRate = getattrinfo(caster, "unMissRate")
- local unMissResistanceRate = getattrinfo(target, "unMissResistanceRate")
- local probability = unMissRate * (1 - unMissResistanceRate)
- local result = this.SelectRate(probability)
- if result then
- local resultType = getplaydef(caster, PlayerDefKey.PLAYER_FIGHT_HURT_TYPE)
- resultType[HurtTypeDefKeys.YI_BAN] = "0"
- resultType[HurtTypeDefKeys.WU_SHI] = "1"
- setplaydef(caster, PlayerDefKey.PLAYER_FIGHT_HURT_TYPE, resultType)
- end
- return result
- end
- function this.IsShuangBeiYiJi(paramMap)
- --A双倍一击触发概率=A双倍一击概率 *(1 - B双倍一击概率抵抗)
- local caster = paramMap["caster"]
- local target = paramMap["target"]
- local doubleDamageChance = getattrinfo(caster, "doubleDamageChance")
- local doubleDamageResistanceChance = getattrinfo(target, "doubleDamageResistanceChance")
- local probability = doubleDamageChance * (1 - doubleDamageResistanceChance)
- local result = this.SelectRate(probability)
- if result then
- local resultType = getplaydef(caster, PlayerDefKey.PLAYER_FIGHT_HURT_TYPE)
- resultType[HurtTypeDefKeys.YI_BAN] = "0"
- resultType[HurtTypeDefKeys.SHUANG_BEI] = "1"
- setplaydef(caster, PlayerDefKey.PLAYER_FIGHT_HURT_TYPE, resultType)
- end
- return result
- end
- function this.SelectRate(probability)
- local randomNum = math.random()
- if randomNum <= probability then
- return true
- else
- return false
- end
- end
- function this.CheckPKCanHurt(paramMap)
- local caster = paramMap["caster"]
- local target = paramMap["target"]
- local castType = paramMap["castertype"]
- local targetType = paramMap["targettype"]
- if castType == 1 and targetType == 1 then
- -- PK值判断是否可以造成伤害
- local pkValue = tonumber(pk.getpkvalue(caster))
- local pkCountTableInfo = ConfigDataManager.getTable("cfg_pk_count", "pvpDamage", 1)
- if pkCountTableInfo and #pkCountTableInfo > 0 then
- local maxPkValue = 0
- for _, v in ipairs(pkCountTableInfo) do
- local nameColor = tostring(v["namecolor"])
- local split = string.split(nameColor, "#")
- local minValue = tonumber(split[1])
- local maxValue = tonumber(split[2])
- if pkValue >= minValue and pkValue <= maxValue then
- -- PK值在此区间内不造成伤害
- tipinfo(caster, "pk值较高,无法对玩家造成伤害")
- return false
- end
- maxPkValue = maxPkValue > maxValue and maxPkValue or maxValue
- end
- if pkValue and pkValue ~= 0 and pkValue > maxPkValue then
- tipinfo(caster, "pk值较高,无法对玩家造成伤害")
- return false
- end
- else
- error("pkCountTableInfo is null")
- end
- -- PK值判断end
- end
- return true
- end
- function this.AfterCalcuDamage(paramMap, finalDamage)
- -- 如果攻击的怪物是秘境副本的BOSS则累加记录实时伤害
- local caster = paramMap["caster"]
- local target = paramMap["target"]
- local castType = paramMap["castertype"]
- local targetType = paramMap["targettype"]
- if castType == 1 and targetType == 2 then
- local monsterId = paramMap["monsterid"]
- local bossChallenge = ConfigDataManager.getTable("cfg_BOSS_challenge", "monsterType", BossType.SECRET_REALM_BOSS)
- for i = 1, #bossChallenge do
- if tonumber(monsterId) == tonumber(bossChallenge[i].monsterid) then
- -- 存储实时伤害
- SecretRealm.savePlayerHurtInfo(caster, target, finalDamage < 0 and 1 or finalDamage)
- end
- end
- -- 保存战盟boos造成伤害的玩家
- WarAlliance.savePlayerInvloveInfo(caster, target, finalDamage, monsterId)
- end
- end
- function fightlog(desc)
- table.insert(FightLog, desc .. "\n")
- end
- -- 服务器启动调用,缓存表数据
- function FightDamageTypeCache.Cache()
- local normalCache = {}
- local elementalCache = {}
- local tableList = ConfigDataManager.getList("cfg_damage_number")
- for index, valueMap in ipairs(tableList) do
- local id = valueMap["id"]
- local attributeA = valueMap["attributea"]
- local attributeB = valueMap["attributeb"]
- local attributeC = valueMap["attributec"]
- local attributeD = valueMap["attributed"]
- local attributeE = valueMap["attributee"]
- local keyString = attributeA .. attributeB .. attributeC .. attributeD .. attributeE
- if string.contains(keyString, "1") then
- if normalCache[keyString] ~= nil then
- gameDebug.assertPrint(false, "cfg_damage_number缓存战斗飘字类型重复,id:" .. id .. ";key:" .. keyString)
- end
- normalCache[keyString] = id
- end
- -- 元素伤害
- local attributeF = valueMap["attributef"]
- local attributeG = valueMap["attributeg"]
- local attributeH = valueMap["attributeh"]
- local attributeI = valueMap["attributei"]
- local elementalKey = attributeF .. attributeG .. attributeH .. attributeI
- if string.contains(elementalKey, "1") then
- if elementalCache[elementalKey] ~= nil then
- gameDebug.assertPrint(false, "cfg_damage_number缓存元素战斗飘字类型重复,id:" .. ";key:" .. elementalKey)
- end
- elementalCache[elementalKey] = id
- end
- end
- setsysvar(SystemVarConst.NORMAL_DAMAGE_TYPE_CACHE, normalCache)
- setsysvar(SystemVarConst.ELEMENTAL_DAMAGE_TYPE_CACHE, elementalCache)
- end
|