PlayerFightQJ4.lua 50 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147
  1. local LastAttakedByMonster = "@上次被怪物攻击的变量"
  2. local HurtTypeDefKeys = {
  3. YI_BAN = "YI_BAN",
  4. ZHUO_YUE = "ZHUO_YUE",
  5. XING_YUN = "XING_YUN",
  6. WU_SHI = "WU_SHI",
  7. SHUANG_BEI = "SHUANG_BEI"
  8. }
  9. FightDamageTypeCache = {}
  10. local this = {}
  11. local FightLog = {}
  12. function excusefightdamage(actor, paramMapList)
  13. local fightResults = {}
  14. for _, paramMap in pairs(paramMapList) do
  15. paramMap["targetnum"] = #paramMapList
  16. local fightResultList = this.ExcuseFightDamage(actor, paramMap)
  17. for _, fightResult in pairs(fightResultList) do
  18. fightResult["target"] = paramMap["target"]
  19. table.insert(fightResults, fightResult)
  20. end
  21. end
  22. if table.count(paramMapList) > 0 then
  23. this.AttackPassiveSkill(actor, paramMapList)
  24. end
  25. return fightResults
  26. end
  27. -- 被动技能
  28. function this.AttackPassiveSkill(actor, paramMapList)
  29. local selfType = getbaseinfo(actor, "mapobjecttype")
  30. if selfType ~= MapObjectType.PLAYER then
  31. return
  32. end
  33. local targetList = {}
  34. local skillId = paramMapList[1].skillid
  35. local skillLevel = paramMapList[1].skilllevel
  36. for _, paramMap in pairs(paramMapList) do
  37. table.insert(targetList, paramMap["target"])
  38. end
  39. PassiveSkill.RoleAttack(actor, targetList, skillId, skillLevel)
  40. end
  41. function this.IsSelfPet(actor, target)
  42. if actor == nil or target == nil then
  43. return false
  44. end
  45. local selfType = getbaseinfo(actor, "mapobjecttype")
  46. local targetType = getbaseinfo(target, "mapobjecttype")
  47. if selfType ~= MapObjectType.PLAYER then
  48. return false
  49. end
  50. if targetType ~= MapObjectType.PET then
  51. return false
  52. end
  53. local masterId = getbaseinfo(target, "master")
  54. local id = getbaseinfo(actor, "id")
  55. if masterId ~= id then
  56. return false
  57. end
  58. return true
  59. end
  60. function this.logTargetAttrInfo(targetActor)
  61. if targetActor == nil then
  62. return
  63. end
  64. local targetAttrInfo = getallattrinfo(targetActor)
  65. if targetAttrInfo == nil then
  66. return
  67. end
  68. local logText = ""
  69. for k, v in pairs(targetAttrInfo) do
  70. local attrId = tonumber(k)
  71. local attrValue = tonumber(v)
  72. if attrValue ~= 0 then
  73. local attrName = ConfigDataManager.getTableValue("cfg_att_info", "attribute", "id", attrId)
  74. if not string.isNullOrEmpty(logText) then
  75. logText = logText .. ","
  76. end
  77. logText = logText .. attrName .. "=" .. attrValue
  78. end
  79. end
  80. if not string.isNullOrEmpty(logText) then
  81. local name = getbaseinfo(targetActor, "rolename")
  82. logText = "攻击目标=" .. name .. ",目标属性【" .. logText .. "】"
  83. end
  84. fightlog(logText)
  85. end
  86. function this.ExcuseFightDamage(actor, paramMap)
  87. --fixme 异步问题,lua队列任务执行时,地图可能已经被销毁
  88. if not mapexists(actor) then
  89. info(actor:toString() .. "执行战斗脚本时,原地图已经被销毁")
  90. return this.BuildFightResult(0, 0, 0, 0, 108, 1)
  91. end
  92. --fightlog("\n==========================================\n战斗日志\n==========================================")
  93. this.initData(paramMap)
  94. local castType = paramMap["castertype"]
  95. local targetType = paramMap["targettype"]
  96. local target = paramMap["target"]
  97. if this.IsSelfPet(actor, target) then
  98. fightlog("攻击自己的召唤兽无效")
  99. local result = this.BuildFightResult(0, 0, 0, 0, 108, 1)
  100. return { result }
  101. end
  102. this.logTargetAttrInfo(target)
  103. if this.CanHit(paramMap) == false then
  104. local result = this.BuildFightResult(0, 0, 0, 0, 108, 1)
  105. return { result }
  106. end
  107. if this.CheckPKCanHurt(paramMap) == false then
  108. fightlog("pk值较高,无法对玩家造成伤害")
  109. local result = this.BuildFightResult(0, 0, 0, 0, 108, 1)
  110. return { result }
  111. end
  112. -- 攻城战是否可以攻击
  113. if not RolandSeige.CanAttackRolandWall(actor, target, castType, targetType) then
  114. local result = this.BuildFightResult(0, 0, 0, 0, 108, 1)
  115. return { result }
  116. end
  117. local originDamage
  118. local elementalDamage = 0
  119. local elementalType
  120. if castType == MapObjectType.PLAYER or castType == MapObjectType.PET then
  121. --攻击者是玩家或者宠物
  122. originDamage = this.PlayerCastDamage(actor, paramMap)
  123. -- 元素伤害
  124. elementalDamage, elementalType = this.ElementalHurt(paramMap)
  125. elseif castType == 2 then
  126. --攻击者是怪物
  127. originDamage = this.MonsterCastDamage(actor, paramMap)
  128. else
  129. error("this.ExcuseFightDamage=>不存在的攻击者类型", castType)
  130. local result = this.BuildFightResult(0, 0, 0, 0, 108, 1)
  131. return { result }
  132. end
  133. originDamage = EquipGem.handleGemAttrs(actor, target, originDamage, castType, targetType)
  134. originDamage = this.handleHuolong(paramMap, originDamage)
  135. originDamage = this.noviceProtect(paramMap, originDamage)
  136. if originDamage == 0 then
  137. local result = this.BuildFightResult(0, 0, 0, 0, 108, 1)
  138. return { result }
  139. end
  140. local originDamage, repeatl = this.getRepeatInfo(paramMap, originDamage)
  141. -- 副本修正伤害
  142. originDamage = this.DupFixDamage(originDamage, paramMap)
  143. elementalDamage = this.DupFixDamage(elementalDamage, paramMap)
  144. -- 反伤
  145. local casterHurt = this.ReflexDamage(paramMap, originDamage + elementalDamage)
  146. this.AfterCalcuDamage(paramMap, originDamage + elementalDamage)
  147. this.RecoverHP(paramMap, originDamage + elementalDamage)
  148. local resultList = {}
  149. local result = {}
  150. local isComboSkill = Skill.isComboSkill(actor, tonumber(paramMap["skillid"]))
  151. if isComboSkill then
  152. result = this.BuildFightResult(casterHurt, originDamage, 0, 0, 301, repeatl, isComboSkill)
  153. elseif TransferCard.GetCurrentTransfermation(actor) > 0 then
  154. -- 变身状态秒杀日志
  155. this.LogMiaoSha(actor, target, targetType, originDamage, paramMap.monsterid, paramMap["skillid"])
  156. result = this.BuildFightResult(casterHurt, originDamage, 0, 0, 401, repeatl, isComboSkill)
  157. else
  158. result = this.BuildFightResult(casterHurt, originDamage, 0, 0, FightDamageTypeCache.GetHurtType(actor), repeatl, isComboSkill)
  159. end
  160. table.insert(resultList, result)
  161. if elementalDamage > 0 then
  162. local elementalResult = this.BuildFightResult(0, elementalDamage, 0, 0, elementalType, 1, isComboSkill)
  163. table.insert(resultList, elementalResult)
  164. end
  165. return resultList
  166. end
  167. -- 副本修正伤害
  168. function this.DupFixDamage(originDamage, paramMap)
  169. local caster = paramMap.caster
  170. local targetType = paramMap.targettype
  171. if targetType == MapObjectType.MONSTER then
  172. if RolandSeige.IsPlayerInRoland(caster) then
  173. return 1
  174. end
  175. end
  176. return originDamage
  177. end
  178. -- 线上秒杀加日志
  179. function this.LogMiaoSha(actor, target, targetType, hurt, monsterCfgId, skillId)
  180. if targetType == MapObjectType.MONSTER then
  181. local monsterType = tonumber(ConfigDataManager.getTableValue("cfg_monster", "type", "id", monsterCfgId))
  182. if monsterType == 2 or monsterType == 3 then
  183. local maxHp = getbaseinfo(target, "maxhp")
  184. if hurt * 2 >= maxHp then
  185. info(actor:toString() .. "变身对BOSS造成巨额伤害。skillId:" .. skillId .. " ;monsterCfg:" .. monsterCfgId)
  186. end
  187. end
  188. end
  189. end
  190. -- 攻击回血
  191. function this.RecoverHP(paramMap, originDamage)
  192. local caster = paramMap["caster"]
  193. local HPAttackRecover = getattrinfo(caster, "HPAttackRecover")
  194. local HPAttackRecoveronus = getattrinfo(caster, "HPAttackRecoveronus")
  195. local attackBlood = getattrinfo(caster, "attackBlood")
  196. local attackRecover = originDamage * attackBlood
  197. local hpRecover = HPAttackRecover * (1 + HPAttackRecoveronus) + attackRecover
  198. local currentHp = getbaseinfo(caster, "hp")
  199. sethp(caster, hpRecover + currentHp)
  200. end
  201. function this.ReflexDamage(paramMap, originDamage)
  202. local casterHurt = 0
  203. local caster = paramMap["caster"]
  204. local target = paramMap["target"]
  205. local damageReflexProbability = getattrinfo(target, "damageReflexProbability")
  206. local damageReflexResistanceProbability = getattrinfo(caster, "damageReflexResistanceProbability")
  207. local rate = damageReflexProbability - damageReflexResistanceProbability
  208. if this.SelectRate(rate) then
  209. local damageReflex = getattrinfo(target, "damageReflex")
  210. local pvpDamageReflexAdd = getattrinfo(target, "pvpDamageReflexAdd")
  211. local pvpDamageReflexReduce = getattrinfo(caster, "pvpDamageReflexReduce")
  212. casterHurt = originDamage * damageReflex + pvpDamageReflexAdd - pvpDamageReflexReduce
  213. casterHurt = math.max(0, casterHurt)
  214. end
  215. return casterHurt
  216. end
  217. --处理重复伤害次数
  218. function this.getRepeatInfo(paramMap, originDamage)
  219. local skillId = paramMap["skillid"]
  220. local skillLevel = paramMap["skilllevel"]
  221. local valueTimes = ConfigDataManager.getTableValue("cfg_skill_info", "valueTimes", "skillID", skillId, "skillLevel", skillLevel)
  222. local repeatl = RandomUtil.selectKey(valueTimes)
  223. repeatl = math.max(repeatl, 1)
  224. originDamage = originDamage * repeatl
  225. return originDamage, repeatl
  226. end
  227. function this.handleHuolong(paramMap, originDamage)
  228. local caster = paramMap["caster"]
  229. local castMapObjectType = getbaseinfo(caster, "mapobjecttype")
  230. if castMapObjectType ~= MapObjectType.MONSTER then
  231. return originDamage
  232. end
  233. local monsterInfo = getmonsterinfo(caster)
  234. local cfgId = monsterInfo["cfgid"]
  235. if tonumber(cfgId) ~= MonsterConfigId.HUOLONG then
  236. return originDamage
  237. end
  238. local target = paramMap["target"]
  239. local targetMaxHp = getattrinfo(target, "maxHP")
  240. local costHp = targetMaxHp * 0.05
  241. return originDamage + costHp
  242. end
  243. function this.noviceProtect(paramMap, originDamage)
  244. local target = paramMap["target"]
  245. local targetType = paramMap["targettype"]
  246. if targetType ~= MapObjectType.PLAYER then
  247. return originDamage
  248. end
  249. local novice = getplaydef(target, NOVICE_PROTECT)
  250. if not novice then
  251. return originDamage
  252. end
  253. if novice then
  254. local currentHp = getbaseinfo(target, "hp")
  255. local haveHp = currentHp - originDamage
  256. local stringHp = ConfigDataManager.getTableValue("cfg_global", "value", "id", "15004")
  257. local hp = tonumber(stringHp)
  258. if haveHp < hp then
  259. return 0
  260. end
  261. end
  262. return originDamage
  263. end
  264. function this.initData(paramMap)
  265. local caster = paramMap["caster"]
  266. local originType = {
  267. [HurtTypeDefKeys.YI_BAN] = "1",
  268. [HurtTypeDefKeys.ZHUO_YUE] = "0",
  269. [HurtTypeDefKeys.XING_YUN] = "0",
  270. [HurtTypeDefKeys.WU_SHI] = "0",
  271. [HurtTypeDefKeys.SHUANG_BEI] = "0",
  272. }
  273. setplaydef(caster, PlayerDefKey.PLAYER_FIGHT_HURT_TYPE, originType)
  274. FightLog = {}
  275. --table.clear(FightLog)
  276. end
  277. function FightDamageTypeCache.GetHurtType(caster)
  278. local resultType = getplaydef(caster, PlayerDefKey.PLAYER_FIGHT_HURT_TYPE)
  279. local yiBanGongJi = resultType[HurtTypeDefKeys.YI_BAN]
  280. local zhuoYueYiJi = resultType[HurtTypeDefKeys.ZHUO_YUE]
  281. local xinYunYiJi = resultType[HurtTypeDefKeys.XING_YUN]
  282. local wuShiFangYu = resultType[HurtTypeDefKeys.WU_SHI]
  283. local shuangBeiYiJi = resultType[HurtTypeDefKeys.SHUANG_BEI]
  284. local typeString = yiBanGongJi .. zhuoYueYiJi .. xinYunYiJi .. wuShiFangYu .. shuangBeiYiJi
  285. local hurtTypeCache = getsysvar(SystemVarConst.NORMAL_DAMAGE_TYPE_CACHE, 0)
  286. local type = hurtTypeCache[typeString]
  287. if type == nil then
  288. error(caster, caster, "获取攻击类型配置失败,结果为", typeString)
  289. type = 101
  290. end
  291. return type
  292. end
  293. function FightDamageTypeCache.GetElementalHurtType(caster, key)
  294. local elementalCache = getsysvar(SystemVarConst.ELEMENTAL_DAMAGE_TYPE_CACHE, 0)
  295. local type = elementalCache[key]
  296. if type == nil then
  297. if string.contains(key, "1") then
  298. error(caster, caster, "获取元素伤害类型配置失败,结果为", key)
  299. end
  300. type = 101
  301. end
  302. return type
  303. end
  304. function this.BuildFightResult(casthurt, targethurt, castershield, targetshield, hurttype, repeatl, combo)
  305. combo = combo or false
  306. local result = {}
  307. result["comboskill"] = combo
  308. result["casthurt"] = casthurt
  309. result["targethurt"] = targethurt
  310. result["castershield"] = castershield
  311. result["targetshield"] = targetshield
  312. result["hurttype"] = hurttype
  313. result["repeat"] = repeatl
  314. result["targethurtshow"] = targethurt / repeatl --飘字体用的伤害:真实伤害除以次数
  315. 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))
  316. result["fightLog"] = FightLog
  317. return result
  318. end
  319. function this.PlayerCastDamage(actor, paramMap)
  320. local finalDamage = 0
  321. --todo 不同公式区分
  322. local skillId = paramMap["skillid"]
  323. local skillLevel = paramMap["skilllevel"]
  324. local config = ConfigDataManager.getTableFirst("cfg_skill_info", "skillID", skillId, "skillLevel", skillLevel)
  325. local damageType = string.tonumber(config.damagetype)
  326. if damageType == 0 then
  327. finalDamage = this.PlayerCastDamageNomal(actor, paramMap)
  328. elseif damageType == 1 then
  329. finalDamage = this.PlayerLinkedDamage(actor, paramMap, config)
  330. end
  331. -- 保底伤害
  332. -- A打B最终伤害<保底伤害时,最终伤害=保底伤害=A最大攻击力*可配置系数
  333. fightlog("A打B最终伤害<保底伤害时,最终伤害=保底伤害=A最大攻击力*可配置系数")
  334. local minDC, maxDC = this.GetDCBySkill(paramMap)
  335. local factor = tonumber(ConfigDataManager.getTableValue("cfg_global", "value", "id", 7000)) / 10000
  336. local minDamage = maxDC * factor
  337. local originFinalDamage = finalDamage
  338. if finalDamage < minDamage then
  339. finalDamage = minDamage
  340. end
  341. fightlog("最终伤害:" .. originFinalDamage .. " 保底伤害:" .. minDamage)
  342. return finalDamage
  343. end
  344. -- 走链接公式
  345. function this.PlayerLinkedDamage(actor, paramMap, skillInfoCfg)
  346. local reqTargetId = paramMap["reqtargetid"]
  347. local target = paramMap["target"]
  348. local damageformulaString = skillInfoCfg.damageformula
  349. local damageformulaSplit = string.split(damageformulaString, "|")
  350. local linedNum = tonumber(damageformulaSplit[1])
  351. local shuaiJianStr = damageformulaSplit[2]
  352. local zhuMuBiaoStr = damageformulaSplit[3]
  353. local fuMuBiaoStr = damageformulaSplit[4]
  354. local shuaiJianDamage = this.LinkedCal(actor, shuaiJianStr)
  355. local zhuMuBiaoDamage = this.LinkedCal(actor, zhuMuBiaoStr)
  356. local fuMuBiaoDamage = this.LinkedCal(actor, fuMuBiaoStr)
  357. local targetNum = paramMap.targetnum
  358. fightlog("触发链式伤害=> 副目标数量:" .. (targetNum - 1) .. "链接数量:" .. linedNum .. " 衰减伤害:" .. shuaiJianDamage .. " 主目标伤害:" .. zhuMuBiaoDamage .. " 副目标伤害:" .. fuMuBiaoDamage)
  359. local damage = 0
  360. if targetNum <= 1 then
  361. damage = linedNum * shuaiJianDamage + zhuMuBiaoDamage
  362. fightlog("无副目标,主目标受到伤害:" .. damage)
  363. else
  364. if targetNum - 1 < linedNum then
  365. -- 副目标数量不足链接数量
  366. if target:toString() == tostring(reqTargetId) then
  367. -- 主目标
  368. damage = (linedNum - targetNum + 1) * shuaiJianDamage + zhuMuBiaoDamage
  369. fightlog("副目标数量不足链接数量,主目标受到伤害:" .. damage)
  370. else
  371. -- 副目标
  372. damage = fuMuBiaoDamage
  373. fightlog("副目标数量不足链接数量,副目标受到伤害:" .. damage)
  374. end
  375. else
  376. if target:toString() == tostring(reqTargetId) then
  377. -- 主目标
  378. damage = zhuMuBiaoDamage
  379. fightlog("副目标数量达到链接数量,主目标受到伤害" .. damage)
  380. else
  381. -- 副目标
  382. damage = fuMuBiaoDamage
  383. fightlog("副目标数量达到链接数量,副目标受到伤害" .. damage)
  384. end
  385. end
  386. end
  387. return damage
  388. end
  389. function this.LinkedCal(actor, configStr)
  390. local split = string.split(configStr, "#")
  391. local attr1 = tonumber(split[1])
  392. local multiple = tonumber(split[2]) / 10000
  393. local attr2 = tonumber(split[3])
  394. local attr1Name = attrid2name(attr1)
  395. local attr2Name = attrid2name(attr2)
  396. local attr1Value = getattrinfo(actor, attr1Name)
  397. local attr2Value = getattrinfo(actor, attr2Name)
  398. return attr1Value * multiple + attr2Value
  399. end
  400. -- 走通用公式
  401. function this.PlayerCastDamageNomal(actor, paramMap)
  402. local caster = paramMap["caster"]
  403. local target = paramMap["target"]
  404. local armor = getattrinfo(target, "armor")
  405. local targetType = paramMap["targettype"]
  406. local armorPenetrate = 0
  407. if targetType == MapObjectType.PLAYER then
  408. armorPenetrate = getattrinfo(caster, "armorPenetrate")
  409. end
  410. local var
  411. if this.IsWuShiFangYu(paramMap) then
  412. fightlog("触发 无视防御")
  413. var = 0
  414. else
  415. var = 1
  416. end
  417. --伤害1=【IF(A幸运一击触发,A幸运攻击,A随机攻击)-(B防御-APVP防御穿透)/2*IF(A无视防御触发,0,1)】+A卓越攻击+A双倍攻击
  418. fightlog("伤害1=【IF(A幸运一击触发,A幸运攻击,A随机攻击)-(B防御-APVP防御穿透)/2*IF(A无视防御触发,0,1)】+A卓越攻击+A双倍攻击")
  419. local damage1 = this.XingYunDamage(paramMap) - math.max(0, (armor - armorPenetrate)) / 2 * var + this.ZhuoYueDamage(paramMap) + this.ShuangBeiYiJi(paramMap)
  420. fightlog("伤害1:" .. damage1)
  421. --伤害2=伤害1 * A使用技能对应技能系数 *(1+A技能伤害加成百分比 - B技能伤害减少百分比)
  422. fightlog("伤害2=伤害1 * A使用技能对应技能系数 *(1+A技能伤害加成百分比 - B技能伤害减少百分比)")
  423. local skillId = paramMap["skillid"]
  424. local skillLevel = paramMap["skilllevel"]
  425. local cfg_skill_infos = ConfigDataManager.getTable("cfg_skill_info", "skillID", skillId, "skillLevel", skillLevel)
  426. if table.isNullOrEmpty(cfg_skill_infos) then
  427. error(actor, " cfg_skill_info表配置不存在 skillId:", skillId, ",skillLevel:", skillLevel)
  428. return 0
  429. end
  430. local cfg_skill_info = cfg_skill_infos[1]
  431. local powerRate = tonumber(cfg_skill_info["powerrate"])
  432. powerRate = powerRate == nil and 0 or powerRate
  433. powerRate = powerRate / 10000
  434. local freeAtt6 = getattrinfo(caster, "freeAtt6")
  435. local freeAtt7 = getattrinfo(target, "freeAtt7")
  436. local damage2 = damage1 * powerRate * (1 + freeAtt6 - freeAtt7)
  437. fightlog("伤害2:" .. damage2)
  438. --伤害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)】
  439. 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)】")
  440. local addtion = this.GetJiaDianAddition(paramMap)
  441. local damageRate = getattrinfo(caster, "damageRate")
  442. local damageAbsorb = getattrinfo(target, "damageAbsorb")
  443. local damageRateDecrement = getattrinfo(target, "damageRateDecrement")
  444. local damage3 = damage2 * (1 + addtion) * (1 + damageRate - damageAbsorb) * (1 - damageRateDecrement)
  445. damage3 = this.physicalSpellDamageReduction(target, damage3, skillId)
  446. damage3 = this.buffDecrement(target, damage3)
  447. if targetType == MapObjectType.MONSTER then
  448. local damageIncreaseRate = getattrinfo(caster, "damageIncreaseRate")
  449. damage3 = damage3 * (1 + damageIncreaseRate)
  450. -- 对怪物造成额外伤害
  451. damage3 = this.monsterExtraDamage(cfg_skill_info["monsterextradamage"], damage3)
  452. end
  453. if targetType == MapObjectType.PLAYER then
  454. local damageBonus = getattrinfo(caster, "damageIncreaseRate")
  455. local damageReductionBonus = getattrinfo(target, "damageReductionBonus")
  456. local absorbDamageToPlayers = getattrinfo(target, "absorbDamageToPlayers")
  457. damage3 = damage3 * (1 + damageBonus - absorbDamageToPlayers) * (1 - damageReductionBonus)
  458. -- 对玩家造成额外伤害
  459. damage3 = this.playerExtraDamage(target, cfg_skill_info["playerextradamage"], damage3)
  460. fightlog("伤害3 对玩家造成额外伤害:" .. damage3)
  461. end
  462. damage3 = this.decayDamage(paramMap, damage3, cfg_skill_info["decaydamage"])
  463. fightlog("伤害3:" .. damage3)
  464. -- 伤害4=伤害3+A技能伤害加成固定值 - B技能伤害减少固定值
  465. fightlog("伤害4=伤害3+A技能伤害加成固定值+A技能伤害固定值 - B技能伤害减少固定值")
  466. local freeAtt1 = getattrinfo(caster, "freeAtt1")
  467. local freeAtt2 = getattrinfo(target, "freeAtt2")
  468. local fixedDamage = tonumber(cfg_skill_info["fixeddamage"])
  469. if fixedDamage == nil then
  470. fixedDamage = 0
  471. end
  472. local damage4 = damage3 + freeAtt1 + fixedDamage - freeAtt2
  473. fightlog("伤害4:" .. damage4)
  474. local finalDamage = 0
  475. if targetType == MapObjectType.PLAYER then
  476. -- 最终伤害=伤害4+APVP出血伤害固定值-BPVP出血伤害抵抗固定值
  477. fightlog("最终伤害=伤害4+APVP出血伤害固定值-BPVP出血伤害抵抗固定值")
  478. local pvpBleedDamageAdd = getattrinfo(caster, "pvpBleedDamageAdd")
  479. local pvpBleedDamageReduce = getattrinfo(target, "pvpBleedDamageReduce")
  480. finalDamage = damage4 + math.max(0, pvpBleedDamageAdd - pvpBleedDamageReduce)
  481. elseif targetType == MapObjectType.MONSTER then
  482. -- 最终伤害=伤害4+A对怪伤害增加固定值
  483. fightlog("最终伤害=伤害4+A对怪伤害增加固定值")
  484. local pveDamageAdd = getattrinfo(caster, "pveDamageAdd")
  485. finalDamage = damage4 + pveDamageAdd
  486. end
  487. -- 处于攻城战副本时,范围伤害修改
  488. finalDamage = this.RolandSeigeAOECal(actor, skillId, finalDamage)
  489. return finalDamage
  490. end
  491. --- 未选中的目标 衰减伤害
  492. function this.decayDamage(paramMap, damage3, decayDamage)
  493. if string.isNullOrEmpty(decayDamage) then
  494. return damage3
  495. end
  496. local reqTargetId = paramMap["reqtargetid"]
  497. local target = paramMap["target"]
  498. -- 未选中的目标 衰减伤害
  499. if tonumber(target:toString()) == reqTargetId then
  500. return damage3
  501. end
  502. local originDamage3 = damage3
  503. damage3 = damage3 * (1 - (tonumber(decayDamage) / 10000))
  504. fightlog("伤害3 未选中的目标衰减伤害 原始伤害3:" .. originDamage3 .. "计算后的伤害3:" .. damage3 .. "衰减伤害配置" .. decayDamage)
  505. return damage3
  506. end
  507. function this.playerExtraDamage(target, playerExtraDamageStr, damage3)
  508. local playerExtraDamage = string.toIntIntMap(playerExtraDamageStr)
  509. local originDamage3 = damage3
  510. if table.isNullOrEmpty(playerExtraDamage) then
  511. return damage3
  512. end
  513. local currentHp = getbaseinfo(target, "hp")
  514. for type, value in pairs(playerExtraDamage) do
  515. if type == 1 then
  516. -- 百分比
  517. damage3 = damage3 * (1 + (currentHp * value / 10000))
  518. elseif type == 2 then
  519. -- 固定数值
  520. damage3 = damage3 + value
  521. end
  522. end
  523. fightlog("伤害3 对玩家造成额外伤害 原始伤害3:" .. originDamage3 .. "计算后的伤害3:" .. damage3 .. "额外伤害配置" .. playerExtraDamageStr)
  524. return damage3
  525. end
  526. function this.monsterExtraDamage(monsterExtraDamageStr, damage3)
  527. local monsterExtraDamage = string.toIntIntMap(monsterExtraDamageStr)
  528. local originDamage3 = damage3
  529. if table.isNullOrEmpty(monsterExtraDamage) then
  530. return damage3
  531. end
  532. for type, value in pairs(monsterExtraDamage) do
  533. if type == 1 then
  534. -- 百分比
  535. damage3 = damage3 * (1 + (value / 10000))
  536. elseif type == 2 then
  537. -- 固定数值
  538. damage3 = damage3 + value
  539. end
  540. end
  541. fightlog("伤害3 对怪物造成额外伤害 原始伤害3:" .. originDamage3 .. "计算后的伤害3:" .. damage3 .. "额外伤害配置" .. monsterExtraDamageStr)
  542. return damage3
  543. end
  544. --- 目标属性概率减伤
  545. function this.buffDecrement(actor, damage)
  546. local damageRateDecrement5 = getattrinfo(actor, "damageRateDecrement5")
  547. if damageRateDecrement5 ~= 0 then
  548. local successRate = math.random(0, 100)
  549. if successRate <= 5 then
  550. damage = damage * (1 - damageRateDecrement5)
  551. end
  552. end
  553. local damageRateDecrement10 = getattrinfo(actor, "damageRateDecrement10")
  554. if damageRateDecrement10 ~= 0 then
  555. local successRate = math.random(0, 100)
  556. if successRate <= 10 then
  557. damage = damage * (1 - damageRateDecrement10)
  558. end
  559. end
  560. return damage
  561. end
  562. --- 物理法术伤害减免
  563. function this.physicalSpellDamageReduction(actor, damage, skillId)
  564. local powerSource = ConfigDataManager.getTableValue("cfg_skill", "powerSource", "id", skillId)
  565. if string.isNullOrEmpty(powerSource) then
  566. return damage
  567. end
  568. powerSource = tonumber(powerSource)
  569. if SkillPowerSource.PHYSICAL == powerSource then
  570. local physicalDamageReduction = getattrinfo(actor, "physicalDamageReduction")
  571. damage = damage * (1 - physicalDamageReduction)
  572. return damage
  573. end
  574. if SkillPowerSource.SPELL == powerSource then
  575. local MagicalDamageReduction = getattrinfo(actor, "MagicalDamageReduction")
  576. damage = damage * (1 - MagicalDamageReduction)
  577. return damage
  578. end
  579. return damage
  580. end
  581. function this.RolandSeigeAOECal(actor, skillId, originDamage)
  582. if RolandSeige.IsPlayerInRoland(actor) then
  583. local aoe = tonumber(ConfigDataManager.getTableValue("cfg_skill", "aoe", "id", skillId))
  584. if aoe == 1 then
  585. local rate = tonumber(ConfigDataManager.getTableValue("cfg_repGlobal", "value", "id", RepGlobalConfig.ROLAND_SEIGE.AOE_DAMAGE_FIX))
  586. return originDamage * (rate / 100)
  587. end
  588. end
  589. return originDamage
  590. end
  591. function this.MonsterCastDamage(actor, paramMap)
  592. local caster = paramMap["caster"]
  593. local target = paramMap["target"]
  594. local armor = getattrinfo(target, "armor")
  595. --伤害1=【IF(A幸运一击触发,A幸运攻击,A随机攻击)】+A卓越攻击+A双倍攻击
  596. fightlog("伤害1=【IF(A幸运一击触发,A幸运攻击,A随机攻击)】+A卓越攻击+A双倍攻击")
  597. local damage1 = this.XingYunDamage(paramMap) + this.ZhuoYueDamage(paramMap) + this.ShuangBeiYiJi(paramMap)
  598. fightlog("伤害1:" .. damage1)
  599. --伤害2=伤害1 * A使用技能对应技能系数 *(1+A技能伤害加成百分比 - B技能伤害减少百分比)
  600. fightlog("伤害2=伤害1 * A使用技能对应技能系数 *(1+A技能伤害加成百分比 - B技能伤害减少百分比)")
  601. local skillId = paramMap["skillid"]
  602. local skillLevel = paramMap["skilllevel"]
  603. local powerRate = tonumber(ConfigDataManager.getTableValue("cfg_skill_info", "powerRate", "skillID", skillId, "skillLevel", skillLevel))
  604. powerRate = powerRate == nil and 0 or powerRate
  605. powerRate = powerRate / 10000
  606. local freeAtt6 = getattrinfo(caster, "freeAtt6")
  607. local freeAtt7 = getattrinfo(target, "freeAtt7")
  608. local damage2 = damage1 * powerRate * (1 + freeAtt6 - freeAtt7)
  609. fightlog("伤害2:" .. damage2)
  610. --伤害3=伤害2 *(1+A加点伤害加成)*(1+A伤害加成 - B伤害吸收)*(1 - B伤害减少)*(1 - B对怪伤害减少百分比)*【1 - IF(受多只怪物攻击,B多怪减伤百分比,0)】
  611. fightlog("伤害3=伤害2 *(1+A加点伤害加成)*(1+A伤害加成 - B伤害吸收)*(1 - B伤害减少)*(1 - B对怪伤害减少百分比)*【1 - IF(受多只怪物攻击,B多怪减伤百分比,0)】")
  612. local addtion = this.GetJiaDianAddition(paramMap)
  613. local damageRate = getattrinfo(caster, "damageRate")
  614. local damageAbsorb = getattrinfo(target, "damageAbsorb")
  615. local damageRateDecrement = getattrinfo(target, "damageRateDecrement")
  616. local damageReceiveDecrement = getattrinfo(target, "damageReceiveDecrement")
  617. local damage3 = damage2 * (1 + addtion) * (1 + damageRate - damageAbsorb) * (1 - damageRateDecrement) * (1 - damageReceiveDecrement)
  618. damage3 = this.physicalSpellDamageReduction(target, damage3, skillId)
  619. damage3 = this.buffDecrement(target, damage3)
  620. if this.IfAttackedMutipleMonster(paramMap) then
  621. local freeAtt9 = getattrinfo(target, "freeAtt9")
  622. damage3 = damage3 * (1 - freeAtt9)
  623. end
  624. local targetType = paramMap["targettype"]
  625. if targetType == MapObjectType.PLAYER then
  626. -- 对玩家造成额外伤害
  627. local playerExtraDamageStr = ConfigDataManager.getTableValue("cfg_skill_info", "playerextradamage", "skillID", skillId, "skillLevel", skillLevel)
  628. damage3 = this.playerExtraDamage(target, playerExtraDamageStr, damage3)
  629. end
  630. fightlog("伤害3:" .. damage3)
  631. -- 伤害4=伤害3 - B防御/2*IF(A无视防御触发,0,1)+A技能伤害加成固定值 - B技能伤害减少固定值
  632. fightlog("伤害4=伤害3 - B防御/2*IF(A无视防御触发,0,1)+A技能伤害加成固定值 - B技能伤害减少固定值")
  633. if this.IsWuShiFangYu(paramMap) == false then
  634. damage3 = damage3 - armor / 2
  635. end
  636. local freeAtt1 = getattrinfo(caster, "freeAtt1")
  637. local freeAtt2 = getattrinfo(target, "freeAtt2")
  638. local damage4 = damage3 + freeAtt1 - freeAtt2
  639. fightlog("伤害4:" .. damage4)
  640. -- 最终伤害=伤害4-B对怪伤害减少固定值
  641. fightlog("最终伤害=伤害4-B对怪伤害减少固定值")
  642. local pveDamageReduce = getattrinfo(target, "pveDamageReduce")
  643. local finalDamage = damage4 - pveDamageReduce
  644. --todo 保底伤害 怪物打玩家最终伤害<保底伤害时,最终伤害=保底伤害(怪物属性表配置)
  645. fightlog("怪物打玩家最终伤害<保底伤害时,最终伤害=保底伤害(怪物属性表配置)")
  646. local monInfo = getmonsterinfo(caster)
  647. local monsterConfig = monInfo["cfgid"]
  648. local minDamage = tonumber(ConfigDataManager.getTableValue("cfg_monster", "guaranteedDamage", "id", monsterConfig))
  649. if finalDamage < minDamage then
  650. finalDamage = minDamage
  651. end
  652. fightlog("最终伤害:" .. finalDamage .. " 保底伤害:" .. minDamage)
  653. return finalDamage
  654. end
  655. -- 元素伤害
  656. function this.ElementalHurt(paramMap)
  657. local caster = paramMap.caster
  658. local target = paramMap.target
  659. local hurtTypeKey
  660. -- 圣光
  661. local shengGuangDamage = 0
  662. local HolyUnMissRate = getattrinfo(caster, "HolyUnMissRate")
  663. local HolyResistUnMissRate = getattrinfo(target, "HolyResistUnMissRate")
  664. local HolyAttack = getattrinfo(caster, "HolyAttack")
  665. if not this.SelectRate(math.max(0, HolyResistUnMissRate - HolyUnMissRate)) and HolyAttack > 0 then
  666. local HolyDamageIncreased = getattrinfo(caster, "HolyDamageIncreased")
  667. local HolyDamageIncreasedBonus = getattrinfo(caster, "HolyDamageIncreasedBonus")
  668. local HolyDamageReduction = getattrinfo(target, "HolyDamageReduction")
  669. local HolyDamageReductionBonus = getattrinfo(target, "HolyDamageReductionBonus")
  670. shengGuangDamage = HolyAttack * (1 + HolyDamageIncreasedBonus - HolyDamageReductionBonus) + HolyDamageIncreased - HolyDamageReduction
  671. shengGuangDamage = math.max(shengGuangDamage, 0)
  672. if shengGuangDamage > 0 then
  673. hurtTypeKey = "1"
  674. else
  675. hurtTypeKey = "0"
  676. end
  677. else
  678. hurtTypeKey = "0"
  679. end
  680. -- 黑暗
  681. local heiAnDamage = 0
  682. local DarkUnMissRate = getattrinfo(caster, "DarkUnMissRate")
  683. local DarkResistUnMissRate = getattrinfo(target, "DarkResistUnMissRate")
  684. local DarkAttack = getattrinfo(caster, "DarkAttack")
  685. if not this.SelectRate(math.max(0, DarkResistUnMissRate - DarkUnMissRate)) and DarkAttack > 0 then
  686. local DarkDamageIncreased = getattrinfo(caster, "DarkDamageIncreased")
  687. local DarkDamageIncreasedBonus = getattrinfo(caster, "DarkDamageIncreasedBonus")
  688. local DarkDamageReduction = getattrinfo(target, "DarkDamageReduction")
  689. local DarkDamageReductionBonus = getattrinfo(target, "DarkDamageReductionBonus")
  690. heiAnDamage = DarkAttack * (1 + DarkDamageIncreasedBonus - DarkDamageReductionBonus) + DarkDamageIncreased - DarkDamageReduction
  691. heiAnDamage = math.max(heiAnDamage, 0)
  692. if heiAnDamage > 0 then
  693. hurtTypeKey = hurtTypeKey .. "1"
  694. else
  695. hurtTypeKey = hurtTypeKey .. "0"
  696. end
  697. else
  698. hurtTypeKey = hurtTypeKey .. "0"
  699. end
  700. -- 雷电
  701. local leiDianDamage = 0
  702. local ThunderUnMissRate = getattrinfo(caster, "ThunderUnMissRate")
  703. local ThunderResistUnMissRate = getattrinfo(target, "ThunderResistUnMissRate")
  704. local ThunderAttack = getattrinfo(caster, "ThunderAttack")
  705. if not this.SelectRate(math.max(0, ThunderResistUnMissRate - ThunderUnMissRate)) and ThunderAttack > 0 then
  706. local ThunderDamageIncreased = getattrinfo(caster, "ThunderDamageIncreased")
  707. local ThunderDamageIncreasedBonus = getattrinfo(caster, "ThunderDamageIncreasedBonus")
  708. local ThunderDamageReduction = getattrinfo(target, "ThunderDamageReduction")
  709. local ThunderDamageReductionBonus = getattrinfo(target, "ThunderDamageReductionBonus")
  710. leiDianDamage = ThunderAttack * (1 + ThunderDamageIncreasedBonus - ThunderDamageReductionBonus) + ThunderDamageIncreased - ThunderDamageReduction
  711. leiDianDamage = math.max(leiDianDamage, 0)
  712. if leiDianDamage > 0 then
  713. hurtTypeKey = hurtTypeKey .. "1"
  714. else
  715. hurtTypeKey = hurtTypeKey .. "0"
  716. end
  717. else
  718. hurtTypeKey = hurtTypeKey .. "0"
  719. end
  720. -- 风暴
  721. local fengBaoDmage = 0
  722. local StormUnMissRate = getattrinfo(caster, "StormUnMissRate")
  723. local StormResistUnMissRate = getattrinfo(target, "StormResistUnMissRate")
  724. local StormAttack = getattrinfo(caster, "StormAttack")
  725. if not this.SelectRate(math.max(0, StormResistUnMissRate - StormUnMissRate)) and StormAttack > 0 then
  726. local StormDamageIncreased = getattrinfo(caster, "StormDamageIncreased")
  727. local StormDamageIncreasedBonus = getattrinfo(caster, "StormDamageIncreasedBonus")
  728. local StormDamageReduction = getattrinfo(target, "StormDamageReduction")
  729. local StormDamageReductionBonus = getattrinfo(target, "StormDamageReductionBonus")
  730. fengBaoDmage = StormAttack * (1 + StormDamageIncreasedBonus - StormDamageReductionBonus) + StormDamageIncreased - StormDamageReduction
  731. fengBaoDmage = math.max(fengBaoDmage, 0)
  732. if fengBaoDmage > 0 then
  733. hurtTypeKey = hurtTypeKey .. "1"
  734. else
  735. hurtTypeKey = hurtTypeKey .. "0"
  736. end
  737. else
  738. hurtTypeKey = hurtTypeKey .. "0"
  739. end
  740. local totalDamage = shengGuangDamage + heiAnDamage + leiDianDamage + fengBaoDmage
  741. totalDamage = math.max(0, totalDamage)
  742. -- 伤害类型(飘字)
  743. local hurtType = FightDamageTypeCache.GetElementalHurtType(caster, hurtTypeKey)
  744. return totalDamage, hurtType
  745. end
  746. function this.XingYunDamage(paramMap)
  747. local caster = paramMap["caster"]
  748. local target = paramMap["target"]
  749. local minDC, maxDC = this.GetDCBySkill(paramMap)
  750. if this.IsXingYunYiJi(paramMap) then
  751. fightlog("触发 幸运一击")
  752. --A幸运攻击=A最大攻击 *(1+A幸运一击伤害加成 - B幸运一击伤害减少)
  753. local criticalDamageBonus = getattrinfo(caster, "criticalDamageBonus")
  754. local criticalDamageReducationBonus = getattrinfo(target, "criticalDamageReducationBonus")
  755. return maxDC * (1 + criticalDamageBonus - criticalDamageReducationBonus)
  756. else
  757. return math.randomFloat(minDC, maxDC)
  758. end
  759. end
  760. function this.ZhuoYueDamage(paramMap)
  761. local caster = paramMap["caster"]
  762. local target = paramMap["target"]
  763. local skillId = paramMap["skillid"]
  764. local skillLevel = paramMap["skilllevel"]
  765. local minDC, maxDC = this.GetDCBySkill(paramMap)
  766. --A卓越攻击=A随机攻击 * IF(A卓越一击触发,A卓越一击伤害系数,0)*(1+A卓越一击伤害加成 - B卓越一击伤害减少)
  767. local coefficient
  768. if this.IsZhuoYueYiJi(paramMap) then
  769. fightlog("触发 卓越一击")
  770. coefficient = tonumber(ConfigDataManager.getTableValue("cfg_skill_info", "excellentRate", "skillID", skillId, "skillLevel", skillLevel))
  771. if coefficient == nil then
  772. coefficient = 0
  773. else
  774. coefficient = coefficient / 10000
  775. end
  776. else
  777. coefficient = 0
  778. end
  779. local excellentDamageBonus = getattrinfo(caster, "excellentDamageBonus")
  780. local excellentDamageReducationBonus = getattrinfo(target, "excellentDamageReducationBonus")
  781. return math.randomFloat(minDC, maxDC) * coefficient * (1 + excellentDamageBonus - excellentDamageReducationBonus)
  782. end
  783. function this.ShuangBeiYiJi(paramMap)
  784. local caster = paramMap["caster"]
  785. local target = paramMap["target"]
  786. local minDC, maxDC = this.GetDCBySkill(paramMap)
  787. --A双倍攻击=A随机攻击 * IF(A双倍一击触发,1,0)*(1+A双倍一击伤害加成 - B双倍一击伤害减少)
  788. local coefficient
  789. if this.IsShuangBeiYiJi(paramMap) then
  790. fightlog("触发 双倍一击")
  791. coefficient = 1
  792. else
  793. coefficient = 0
  794. end
  795. local doubleDamageBonus = getattrinfo(caster, "doubleDamageBonus")
  796. local doubleDamageReducationBonus = getattrinfo(target, "doubleDamageReducationBonus")
  797. return math.randomFloat(minDC, maxDC) * coefficient * (1 + doubleDamageBonus - doubleDamageReducationBonus)
  798. end
  799. function this.IfAttackedMutipleMonster(paramMap)
  800. local caster = paramMap["caster"]
  801. local target = paramMap["target"]
  802. local castType = paramMap["castertype"]
  803. local targetType = paramMap["targettype"]
  804. if castType ~= 2 or targetType ~= 1 then
  805. return false
  806. end
  807. local monsterId = caster:toString()
  808. local lastDataList = getplaydef(target, LastAttakedByMonster)
  809. local nowMillis = getbaseinfo("now")
  810. if type(lastDataList) ~= "table" then
  811. setplaydef(target, LastAttakedByMonster, { monsterId, nowMillis })
  812. return false
  813. end
  814. local lastMonsterId = lastDataList[1]
  815. local lastMillis = lastDataList[2]
  816. local duration = nowMillis - lastMillis
  817. if lastMonsterId == monsterId or duration < 1000 then
  818. setplaydef(target, LastAttakedByMonster, { monsterId, nowMillis })
  819. return false
  820. end
  821. setplaydef(target, LastAttakedByMonster, { monsterId, nowMillis })
  822. return true
  823. end
  824. function this.GetJiaDianAddition(paramMap)
  825. local caster = paramMap["caster"]
  826. local skillId = paramMap["skillid"]
  827. local skillLevel = paramMap["skilllevel"]
  828. local injuryType = tonumber(ConfigDataManager.getTableValue("cfg_skill_info", "injuryType", "skillID", skillId, "skillLevel", skillLevel))
  829. if injuryType == 1 then
  830. local addtion = getattrinfo(caster, "PhysicalDamage")
  831. return addtion
  832. elseif injuryType == 2 then
  833. local addtion = getattrinfo(caster, "MagicDamage")
  834. return addtion
  835. elseif injuryType == 3 then
  836. local addtion = getattrinfo(caster, "freeAtt8")
  837. return addtion
  838. else
  839. local maxDC = getattrinfo(caster, "maxDC")
  840. local maxMC = getattrinfo(caster, "maxMC")
  841. local maxCurDC = getattrinfo(caster, "maximumCurseAttackPower")
  842. if maxDC >= maxMC and maxDC >= maxCurDC then
  843. local addtion = getattrinfo(caster, "PhysicalDamage")
  844. return addtion
  845. elseif maxMC >= maxDC and maxMC >= maxCurDC then
  846. local addtion = getattrinfo(caster, "MagicDamage")
  847. return addtion
  848. elseif maxCurDC >= maxDC and maxCurDC >= maxMC then
  849. local addtion = getattrinfo(caster, "freeAtt8")
  850. return addtion
  851. end
  852. error("不存在的伤害类型" .. injuryType .. "skillId:" .. skillId)
  853. return 0
  854. end
  855. end
  856. function this.GetDCBySkill(paramMap)
  857. local caster = paramMap["caster"]
  858. local skillId = paramMap["skillid"]
  859. local skillLevel = paramMap["skilllevel"]
  860. local injuryType = tonumber(ConfigDataManager.getTableValue("cfg_skill_info", "injuryType", "skillID", skillId, "skillLevel", skillLevel))
  861. if injuryType == 1 then
  862. local maxDC = getattrinfo(caster, "maxDC")
  863. local minDC = getattrinfo(caster, "minDC")
  864. return minDC, maxDC
  865. elseif injuryType == 2 then
  866. local maxMC = getattrinfo(caster, "maxMC")
  867. local minMC = getattrinfo(caster, "minMC")
  868. return minMC, maxMC
  869. elseif injuryType == 3 then
  870. local maxMC = getattrinfo(caster, "maximumCurseAttackPower")
  871. local minMC = getattrinfo(caster, "minimumCurseAttackPower")
  872. return minMC, maxMC
  873. else
  874. local maxDC = getattrinfo(caster, "maxDC")
  875. local maxMC = getattrinfo(caster, "maxMC")
  876. local maxCurDC = getattrinfo(caster, "maximumCurseAttackPower")
  877. if maxDC >= maxMC and maxDC >= maxCurDC then
  878. local minDC = getattrinfo(caster, "minDC")
  879. return minDC, maxDC
  880. elseif maxMC >= maxDC and maxMC >= maxCurDC then
  881. local minMC = getattrinfo(caster, "minMC")
  882. return minMC, maxMC
  883. elseif maxCurDC >= maxDC and maxCurDC >= maxMC then
  884. local minCurDC = getattrinfo(caster, "minimumCurseAttackPower")
  885. return minCurDC, maxCurDC
  886. end
  887. return 0, 0
  888. end
  889. end
  890. function this.CanHit(paramMap)
  891. local caster = paramMap["caster"]
  892. local target = paramMap["target"]
  893. local castType = paramMap["castertype"]
  894. local targetType = paramMap["targettype"]
  895. local hitRate
  896. local missRate
  897. if castType == 2 or targetType == 2 then
  898. --pve
  899. hitRate = getattrinfo(caster, "hitRate")
  900. missRate = getattrinfo(target, "missRate")
  901. else
  902. --pvp
  903. hitRate = getattrinfo(caster, "pvpattackRate")
  904. missRate = getattrinfo(target, "eraRate")
  905. end
  906. local basicMiss = getattrinfo(target, "freeAtt10")
  907. --todo 命中概率=1 - (1 - 1 / ((B防御率 - A攻击率) / (B防御率 + A攻击率) * 0.8 + 1)) - B基础闪避率
  908. fightlog("命中概率=1 - (1 - 1 / ((B防御率 - A攻击率) / (B防御率 + A攻击率) * 0.8 + 1)) - B基础闪避率")
  909. fightlog("A攻击率:" .. hitRate .. " B防御率:" .. missRate .. " B基础闪避率:" .. basicMiss)
  910. local probability
  911. if missRate + hitRate == 0 then
  912. probability = 1
  913. else
  914. probability = 1 - (1 - 1 / ((missRate - hitRate) / (missRate + hitRate) * 0.8 + 1)) - basicMiss
  915. end
  916. local hit = this.SelectRate(probability)
  917. fightlog("命中概率:" .. string.numToPercent(probability) .. " 命中:" .. tostring(hit))
  918. return hit
  919. end
  920. function this.IsXingYunYiJi(paramMap)
  921. --A幸运一击触发概率=A幸运一击概率 *(1 - B幸运一击概率抵抗)
  922. local caster = paramMap["caster"]
  923. local target = paramMap["target"]
  924. local criticalDamageChance = getattrinfo(caster, "criticalDamageChance")
  925. local criticalDamageResistanceChance = getattrinfo(target, "criticalDamageResistanceChance")
  926. local probability = criticalDamageChance * (1 - criticalDamageResistanceChance)
  927. local result = this.SelectRate(probability)
  928. if result then
  929. local resultType = getplaydef(caster, PlayerDefKey.PLAYER_FIGHT_HURT_TYPE)
  930. resultType[HurtTypeDefKeys.YI_BAN] = "0"
  931. resultType[HurtTypeDefKeys.XING_YUN] = "1"
  932. setplaydef(caster, PlayerDefKey.PLAYER_FIGHT_HURT_TYPE, resultType)
  933. end
  934. return result
  935. end
  936. function this.IsZhuoYueYiJi(paramMap)
  937. --A卓越一击触发概率=A卓越一击概率*(1-B卓越一击概率抵抗)
  938. local caster = paramMap["caster"]
  939. local target = paramMap["target"]
  940. local excellentDamageChance = getattrinfo(caster, "excellentDamageChance")
  941. local excellentDamageResistanceChance = getattrinfo(target, "excellentDamageResistanceChance")
  942. local probability = excellentDamageChance * (1 - excellentDamageResistanceChance)
  943. local result = this.SelectRate(probability)
  944. if result then
  945. local resultType = getplaydef(caster, PlayerDefKey.PLAYER_FIGHT_HURT_TYPE)
  946. resultType[HurtTypeDefKeys.YI_BAN] = "0"
  947. resultType[HurtTypeDefKeys.ZHUO_YUE] = "1"
  948. setplaydef(caster, PlayerDefKey.PLAYER_FIGHT_HURT_TYPE, resultType)
  949. end
  950. return result
  951. end
  952. function this.IsWuShiFangYu(paramMap)
  953. --A无视防御概率=A无视防御率 *(1 - B无视防御抵抗)
  954. local caster = paramMap["caster"]
  955. local target = paramMap["target"]
  956. local unMissRate = getattrinfo(caster, "unMissRate")
  957. local unMissResistanceRate = getattrinfo(target, "unMissResistanceRate")
  958. local probability = unMissRate * (1 - unMissResistanceRate)
  959. local result = this.SelectRate(probability)
  960. if result then
  961. local resultType = getplaydef(caster, PlayerDefKey.PLAYER_FIGHT_HURT_TYPE)
  962. resultType[HurtTypeDefKeys.YI_BAN] = "0"
  963. resultType[HurtTypeDefKeys.WU_SHI] = "1"
  964. setplaydef(caster, PlayerDefKey.PLAYER_FIGHT_HURT_TYPE, resultType)
  965. end
  966. return result
  967. end
  968. function this.IsShuangBeiYiJi(paramMap)
  969. --A双倍一击触发概率=A双倍一击概率 *(1 - B双倍一击概率抵抗)
  970. local caster = paramMap["caster"]
  971. local target = paramMap["target"]
  972. local doubleDamageChance = getattrinfo(caster, "doubleDamageChance")
  973. local doubleDamageResistanceChance = getattrinfo(target, "doubleDamageResistanceChance")
  974. local probability = doubleDamageChance * (1 - doubleDamageResistanceChance)
  975. local result = this.SelectRate(probability)
  976. if result then
  977. local resultType = getplaydef(caster, PlayerDefKey.PLAYER_FIGHT_HURT_TYPE)
  978. resultType[HurtTypeDefKeys.YI_BAN] = "0"
  979. resultType[HurtTypeDefKeys.SHUANG_BEI] = "1"
  980. setplaydef(caster, PlayerDefKey.PLAYER_FIGHT_HURT_TYPE, resultType)
  981. end
  982. return result
  983. end
  984. function this.SelectRate(probability)
  985. local randomNum = math.random()
  986. if randomNum <= probability then
  987. return true
  988. else
  989. return false
  990. end
  991. end
  992. function this.CheckPKCanHurt(paramMap)
  993. local caster = paramMap["caster"]
  994. local target = paramMap["target"]
  995. local castType = paramMap["castertype"]
  996. local targetType = paramMap["targettype"]
  997. if castType == 1 and targetType == 1 then
  998. -- PK值判断是否可以造成伤害
  999. local pkValue = tonumber(pk.getpkvalue(caster))
  1000. local pkCountTableInfo = ConfigDataManager.getTable("cfg_pk_count", "pvpDamage", 1)
  1001. if pkCountTableInfo and #pkCountTableInfo > 0 then
  1002. local maxPkValue = 0
  1003. for _, v in ipairs(pkCountTableInfo) do
  1004. local nameColor = tostring(v["namecolor"])
  1005. local split = string.split(nameColor, "#")
  1006. local minValue = tonumber(split[1])
  1007. local maxValue = tonumber(split[2])
  1008. if pkValue >= minValue and pkValue <= maxValue then
  1009. -- PK值在此区间内不造成伤害
  1010. tipinfo(caster, "pk值较高,无法对玩家造成伤害")
  1011. return false
  1012. end
  1013. maxPkValue = maxPkValue > maxValue and maxPkValue or maxValue
  1014. end
  1015. if pkValue and pkValue ~= 0 and pkValue > maxPkValue then
  1016. tipinfo(caster, "pk值较高,无法对玩家造成伤害")
  1017. return false
  1018. end
  1019. else
  1020. error("pkCountTableInfo is null")
  1021. end
  1022. -- PK值判断end
  1023. end
  1024. return true
  1025. end
  1026. function this.AfterCalcuDamage(paramMap, finalDamage)
  1027. -- 如果攻击的怪物是秘境副本的BOSS则累加记录实时伤害
  1028. local caster = paramMap["caster"]
  1029. local target = paramMap["target"]
  1030. local castType = paramMap["castertype"]
  1031. local targetType = paramMap["targettype"]
  1032. if castType == 1 and targetType == 2 then
  1033. local monsterId = paramMap["monsterid"]
  1034. local bossChallenge = ConfigDataManager.getTable("cfg_BOSS_challenge", "monsterType", BossType.SECRET_REALM_BOSS)
  1035. for i = 1, #bossChallenge do
  1036. if tonumber(monsterId) == tonumber(bossChallenge[i].monsterid) then
  1037. -- 存储实时伤害
  1038. SecretRealm.savePlayerHurtInfo(caster, target, finalDamage < 0 and 1 or finalDamage)
  1039. end
  1040. end
  1041. -- 保存战盟boos造成伤害的玩家
  1042. WarAlliance.savePlayerInvloveInfo(caster, target, finalDamage, monsterId)
  1043. end
  1044. end
  1045. function fightlog(desc)
  1046. table.insert(FightLog, desc .. "\n")
  1047. end
  1048. -- 服务器启动调用,缓存表数据
  1049. function FightDamageTypeCache.Cache()
  1050. local normalCache = {}
  1051. local elementalCache = {}
  1052. local tableList = ConfigDataManager.getList("cfg_damage_number")
  1053. for index, valueMap in ipairs(tableList) do
  1054. local id = valueMap["id"]
  1055. local attributeA = valueMap["attributea"]
  1056. local attributeB = valueMap["attributeb"]
  1057. local attributeC = valueMap["attributec"]
  1058. local attributeD = valueMap["attributed"]
  1059. local attributeE = valueMap["attributee"]
  1060. local keyString = attributeA .. attributeB .. attributeC .. attributeD .. attributeE
  1061. if string.contains(keyString, "1") then
  1062. if normalCache[keyString] ~= nil then
  1063. gameDebug.assertPrint(false, "cfg_damage_number缓存战斗飘字类型重复,id:" .. id .. ";key:" .. keyString)
  1064. end
  1065. normalCache[keyString] = id
  1066. end
  1067. -- 元素伤害
  1068. local attributeF = valueMap["attributef"]
  1069. local attributeG = valueMap["attributeg"]
  1070. local attributeH = valueMap["attributeh"]
  1071. local attributeI = valueMap["attributei"]
  1072. local elementalKey = attributeF .. attributeG .. attributeH .. attributeI
  1073. if string.contains(elementalKey, "1") then
  1074. if elementalCache[elementalKey] ~= nil then
  1075. gameDebug.assertPrint(false, "cfg_damage_number缓存元素战斗飘字类型重复,id:" .. ";key:" .. elementalKey)
  1076. end
  1077. elementalCache[elementalKey] = id
  1078. end
  1079. end
  1080. setsysvar(SystemVarConst.NORMAL_DAMAGE_TYPE_CACHE, normalCache)
  1081. setsysvar(SystemVarConst.ELEMENTAL_DAMAGE_TYPE_CACHE, elementalCache)
  1082. end