SkillHitFighterInfo.cs 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491
  1. using UnityEngine;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. public struct stDamageParam
  5. {
  6. public long targetId;
  7. public int targetBaseId;
  8. public int targetTeamSide;
  9. public SFloat perfectDodge;
  10. public SFloat dodge;
  11. public SFloat critRate;
  12. public bool IsPerfectDodge;
  13. public bool IsDodge;
  14. public bool IsCrit;
  15. public SFloat attack;
  16. public SFloat magicAttack;
  17. public SFloat physicDamPercent;
  18. public SFloat magicDamPercent;
  19. public SFloat antiPhysicDamPercent;
  20. public SFloat antiMagicDamPercent;
  21. public SFloat casterNatureDamPer;
  22. public SFloat targetAntiNatureDamPer;
  23. public SFloat critDamPercent;
  24. public SFloat realHurt;
  25. public SFloat defense;
  26. public SFloat defPercent;
  27. public SFloat ignoreDefense;
  28. public SFloat decreaseDefPercent;
  29. public SFloat magicDefense;
  30. public SFloat magicDefPercent;
  31. public SFloat ignoreMagicDefense;
  32. public SFloat decreaseMagicDefPercent;
  33. public SInt damage;
  34. public SInt realDamage;
  35. public void Reset()
  36. {
  37. perfectDodge = 0;
  38. dodge = 0;
  39. critRate = 0;
  40. IsPerfectDodge = false;
  41. IsDodge = false;
  42. IsCrit = false;
  43. attack = 0;
  44. magicAttack = 0;
  45. physicDamPercent = 0;
  46. magicDamPercent = 0;
  47. antiPhysicDamPercent = 0;
  48. antiMagicDamPercent = 0;
  49. casterNatureDamPer = 0;
  50. targetAntiNatureDamPer = 0;
  51. critDamPercent = 0;
  52. realHurt = 0;
  53. defense = 0;
  54. defPercent = 0;
  55. ignoreDefense = 0;
  56. decreaseDefPercent = 0;
  57. magicDefense = 0;
  58. magicDefPercent = 0;
  59. ignoreMagicDefense = 0;
  60. decreaseMagicDefPercent = 0;
  61. damage = 0;
  62. realDamage = 0;
  63. }
  64. public string ToString()
  65. {
  66. string str = string.Format(" perfectDodge:{21},dodge:{22},critRate:{23}" +
  67. "IsPerfectDodge:{0},IsDodge:{1}," +
  68. "IsCrit:{2},attack:{3},magicAttack:{4},physicDamPercent:{5}," +
  69. "magicDamPercent:{6},antiPhysicDamPercent:{7},antiMagicDamPercent:{8}," +
  70. "casterNatureDamPer:{9},targetAntiNatureDamPer:{10},critDamPercent:{11},realHurt:{12}," +
  71. "defense:{13},defPercent:{14},ignoreDefense:{15},decreaseDefPercent:{16}" +
  72. "magicDefense:{17},magicDefPercent:{18},ignoreMagicDefense:{19},decreaseMagicDefPercent:{20}",
  73. IsPerfectDodge,IsDodge,IsCrit,
  74. attack,magicAttack,physicDamPercent, magicDamPercent,
  75. antiPhysicDamPercent, antiMagicDamPercent, casterNatureDamPer, targetAntiNatureDamPer, critDamPercent, realHurt,
  76. defense, defPercent, ignoreDefense, decreaseDefPercent, magicDefense, magicDefPercent, ignoreMagicDefense, decreaseMagicDefPercent,
  77. perfectDodge,dodge,critRate);
  78. return str;
  79. }
  80. }
  81. public class SkillHitFighterInfo
  82. {
  83. public Fighter Caster { get; private set; } //施法者
  84. public Fighter Target { get; private set; } //目标
  85. public SkillActionAttackInfo AttackInfo { get; private set; }
  86. public Bullet HitBullet { get; private set; }
  87. public SFloat Damage { get; set; } //自身+元素 总伤害
  88. public SFloat BaseDamge { get; set; } //自身总伤害
  89. public SFloat NatureDamge { get; set; } //元素总伤害
  90. public SFloat ReflectDamage { get; set; }
  91. //护盾吸收
  92. public SFloat Absorb { get; set; }
  93. public SFloat Attack { get; set; }
  94. //吸收治疗
  95. public SFloat SuckDamge { get; set; }
  96. //暴击
  97. public bool IsCrit { get; private set; }
  98. //闪避
  99. public bool IsDodge { get; private set; }
  100. //完美闪避
  101. public bool IsPerfectDodge { get; private set; }
  102. //免疫
  103. public bool IsImmunity { get; private set; }
  104. public bool HitflyCheckFlag { get; private set; }
  105. public bool HitBreakCheckFlag { get; private set; }
  106. public BaseSkill Skill { get; private set; }
  107. public SkillData SkillDataInfo { get; private set; }
  108. public bool IsDamage { get; private set; }
  109. public bool IsKillEnemyHit { get; set; }
  110. public SkillActionFrameEvent FixHurtWordEvent { get; set; }
  111. private stDamageParam mHitParam;
  112. public stDamageParam HitParam
  113. {
  114. get { return mHitParam; }
  115. }
  116. private int mBuffId;
  117. public int BuffId
  118. {
  119. get { return mBuffId; }
  120. }
  121. public SkillHitFighterInfo (Fighter caster,
  122. Fighter target,
  123. int buffId,
  124. SkillActionAttackInfo attackInfo,
  125. Bullet bullet = null)
  126. {
  127. Caster = caster;
  128. Target = target;
  129. mBuffId = buffId;
  130. AttackInfo = attackInfo;
  131. HitBullet = bullet;
  132. Skill = attackInfo.skill;
  133. if(Skill!=null)
  134. SkillDataInfo = Skill.SkillDataInfo;
  135. Damage = 0;
  136. BaseDamge = 0;
  137. NatureDamge = 0;
  138. ReflectDamage = 0;
  139. Absorb = 0;
  140. SuckDamge = 0;
  141. IsCrit = false;
  142. IsDodge = false;
  143. IsImmunity = false;
  144. HitflyCheckFlag = true;
  145. HitBreakCheckFlag = true;
  146. IsKillEnemyHit = false;
  147. if (Target != null)
  148. {
  149. mHitParam.targetId = target.Id;
  150. mHitParam.targetBaseId = target.Actor.BaseId;
  151. mHitParam.targetTeamSide = (int)target.TeamSide;
  152. }
  153. }
  154. public SInt CalculateDamage (Damage_Type damageType,int hitType)
  155. {
  156. mHitParam.Reset();
  157. //无敌状态
  158. if (Target.StateData.IsInvincible)
  159. {
  160. return 0;
  161. }
  162. string skillName = this.Skill != null ? this.Skill.SkillName : "";
  163. SFloat fNatureAddPercent = 0;
  164. StrategyMgr.Instance.GetAllAntiVals(Caster, Target, out fNatureAddPercent);
  165. if (!Target.FuncMgr.HaveIgoreDodgeFunction())
  166. {
  167. if((hitType & (int)BuffHitType.Perfect_Dodge) == (int)BuffHitType.Perfect_Dodge)
  168. {
  169. PerfectDodge();
  170. mHitParam.IsPerfectDodge = IsPerfectDodge;
  171. if (IsPerfectDodge)
  172. {
  173. mHitParam.damage = 0;
  174. return 0;
  175. }
  176. }
  177. if((hitType & (int)BuffHitType.Dodge) == (int)BuffHitType.Dodge)
  178. {
  179. RandomDodge();
  180. mHitParam.IsDodge = IsDodge;
  181. if (IsDodge)
  182. {
  183. mHitParam.damage = 0;
  184. return 0;
  185. }
  186. }
  187. }
  188. if((hitType & (int)BuffHitType.Critical) == ((int)BuffHitType.Critical))
  189. RandomCrit();
  190. mHitParam.IsCrit = IsCrit;
  191. mHitParam.realHurt = 0;
  192. mHitParam.critDamPercent = Caster.CritDamagePercent;
  193. Caster.HitTarget = Target;
  194. //神威
  195. SFloat p = BattleFormulaParamMgr.Instance.GetParam(37);
  196. SFloat GodPwerPercent = Caster.GetAttrByType(ActorData.Attr_GodPow) - Target.GetAttrByType(ActorData.Attr_GodPow);
  197. GodPwerPercent = Mathf.Max((1 + GodPwerPercent / (10 + Mathf.Abs(GodPwerPercent) *p) * 0.01f),0.01f);
  198. //统一计算
  199. Attack = Caster.Attack * Caster.GetBuffPercentValue(Buff_Function_Type.Phyx_Damage_Change_Percent) +
  200. Caster.MagicAttack * Caster.GetBuffPercentValue(Buff_Function_Type.Magic_Damage_Change_Percent) +
  201. Caster.GetBuffFunctionValue(Buff_Function_Type.Fixed_Damage_Change_Value);
  202. if (Caster.FuncMgr.TickEventList != null)
  203. {
  204. for (int idx = Caster.FuncMgr.TickEventList.Count - 1; idx >= 0; idx--)
  205. {
  206. var ev = Caster.FuncMgr.TickEventList[idx];
  207. if (ev.Type == Buff_Function_Type.Add_Hurt_From_Caster_Attr)
  208. {
  209. Attack += Caster.GetAttrByType(ev.Data.fromAttr) * ev.Data.value * 0.01f;
  210. }
  211. if (ev.Type == Buff_Function_Type.Add_Hurt_From_Target_Attr)
  212. {
  213. if (Target != null)
  214. {
  215. Attack += Target.GetAttrByType(ev.Data.fromAttr) * ev.Data.value * 0.01f;
  216. }
  217. }
  218. if (ev.Type == Buff_Function_Type.Target_Hurt_FixVal_ByTargetCostHp)
  219. {
  220. if (Target != null)
  221. {
  222. Attack += (int)(ev.Data.value * 0.01f * (Target.MaxLife - Target.Life));
  223. }
  224. }
  225. if (ev.Type == Buff_Function_Type.Target_Hurt_FixVal_BySourceCostHp)
  226. {
  227. if (Target != null)
  228. {
  229. Attack += (int)(ev.Data.value * 0.01f * (Caster.MaxLife - Caster.Life));
  230. }
  231. }
  232. if (ev.Type == Buff_Function_Type.Target_Hurt_FixVal_BySourceTargetAttrDiff)
  233. {
  234. if (Target != null)
  235. {
  236. Attack += (int)Mathf.Max((Caster.GetAttrByType(ev.Data.fromAttr) - Target.GetAttrByType(ev.Data.fromAttr)) * ev.Data.value * 0.01f,0.0f);
  237. }
  238. }
  239. }
  240. }
  241. Attack *= (1 + Caster.GetBuffPercentValue(Buff_Function_Type.Damage_Change_Percent));
  242. if (IsCrit)
  243. {
  244. SFloat a = BattleFormulaParamMgr.Instance.GetParam(23);
  245. if (damageType == Damage_Type.Attack_Type_Physic)
  246. {
  247. mHitParam.attack = Attack;
  248. mHitParam.physicDamPercent = Caster.PhysicDamagePercent;
  249. mHitParam.antiPhysicDamPercent = Target.AntiPhysicDamPercent;
  250. BaseDamge = (int)(mHitParam.attack *
  251. Mathf.Max((1 + mHitParam.physicDamPercent - mHitParam.antiPhysicDamPercent), 0.01f) *
  252. (a + mHitParam.critDamPercent));
  253. BaseDamge *= GodPwerPercent;
  254. NatureDamge = (int)(BaseDamge * Mathf.Max(fNatureAddPercent, 0));
  255. Damage = BaseDamge + NatureDamge;
  256. }
  257. else if (damageType == Damage_Type.Attack_Type_Magic)
  258. {
  259. mHitParam.magicAttack = Attack;
  260. mHitParam.magicDamPercent = Caster.MagicDamagePercent;
  261. mHitParam.antiMagicDamPercent = Target.AntiMagicDamPercent;
  262. BaseDamge = (int)(mHitParam.magicAttack *
  263. Mathf.Max((1 + mHitParam.magicDamPercent - mHitParam.antiMagicDamPercent), 0.01f) *
  264. (a + mHitParam.critDamPercent));
  265. BaseDamge *= GodPwerPercent;
  266. NatureDamge = (int)(BaseDamge * Mathf.Max(fNatureAddPercent, 0));
  267. Damage = BaseDamge + NatureDamge;
  268. }
  269. else
  270. {
  271. BaseDamge = Attack;
  272. NatureDamge = 0;
  273. Damage = Attack;
  274. }
  275. EventMgr.DispatchEvent<Fighter,BaseSkill>(new CoreEvent<Fighter, BaseSkill>(ECoreEventType.EID_Fighter_Damage_WithCrit, Caster,Skill));
  276. }
  277. else
  278. {
  279. if (damageType == Damage_Type.Attack_Type_Physic)
  280. {
  281. SFloat a = BattleFormulaParamMgr.Instance.GetParam(19);
  282. SFloat b = BattleFormulaParamMgr.Instance.GetParam(20);
  283. SFloat def = Target.Defense * (1 + Target.DefPercent - Caster.IgnoreDefense);
  284. if (def < 0)
  285. def = 0;
  286. SFloat decreaseDefPercent = ((9 * def) / (a + def * b));
  287. mHitParam.attack = Attack;
  288. mHitParam.defense = def;
  289. mHitParam.decreaseDefPercent = decreaseDefPercent;
  290. mHitParam.physicDamPercent = Caster.PhysicDamagePercent;
  291. mHitParam.antiPhysicDamPercent = Target.AntiPhysicDamPercent;
  292. BaseDamge = (int)(Mathf.Max((mHitParam.attack - mHitParam.defense),1) * (1 - mHitParam.decreaseDefPercent) *
  293. Mathf.Max(1+ mHitParam.physicDamPercent - mHitParam.antiPhysicDamPercent, 0.01f));
  294. BaseDamge *= GodPwerPercent;
  295. NatureDamge = (int)(BaseDamge * Mathf.Max(fNatureAddPercent, 0));
  296. Damage = BaseDamge + NatureDamge;
  297. }
  298. else if (damageType == Damage_Type.Attack_Type_Magic)
  299. {
  300. //Debug.Log("damage Type = Magic");
  301. SFloat a = BattleFormulaParamMgr.Instance.GetParam(21);
  302. SFloat b = BattleFormulaParamMgr.Instance.GetParam(22);
  303. SFloat def = Target.MagicDefense * (1 + Target.MagicDefPercent - Caster.IgnoreMagicDefense);
  304. if (def < 0)
  305. def = 0;
  306. SFloat decreaseMagicDefPercent = ((9 * def) / (a + def * b));
  307. mHitParam.magicAttack = Attack;
  308. mHitParam.magicDefense = def;
  309. mHitParam.decreaseMagicDefPercent = decreaseMagicDefPercent;
  310. mHitParam.magicDamPercent = Caster.MagicDamagePercent;
  311. mHitParam.antiMagicDamPercent = Target.AntiMagicDamPercent;
  312. BaseDamge = (int)(Mathf.Max((mHitParam.magicAttack - mHitParam.magicDefense), 1) *
  313. (1 - mHitParam.decreaseMagicDefPercent) * Mathf.Max(1 + mHitParam.magicDamPercent - mHitParam.antiMagicDamPercent, 0.01f));
  314. BaseDamge *= GodPwerPercent;
  315. NatureDamge = (int)(BaseDamge * Mathf.Max(fNatureAddPercent, 0));
  316. Damage = BaseDamge + NatureDamge;
  317. }
  318. else
  319. {
  320. BaseDamge = Attack;
  321. NatureDamge = 0;
  322. Damage = Attack;
  323. }
  324. }
  325. //吸收
  326. SFloat SuckPrecent;
  327. int nMaxSuck;
  328. bool bIsSuckDamage = Target.IsSuckDamage(damageType, out SuckPrecent, out nMaxSuck);
  329. if(bIsSuckDamage)
  330. {
  331. nMaxSuck = (int)(nMaxSuck * 0.01f * Target.MaxLife);
  332. SuckDamge = SuckPrecent * 0.01f * Damage;
  333. SuckDamge = Mathf.Min(nMaxSuck,(int)SuckDamge);
  334. if(SuckDamge < 1)
  335. {
  336. SuckDamge = 1;
  337. }
  338. }
  339. //反弹
  340. if (damageType == Damage_Type.Attack_Type_Physic)
  341. ReflectDamage = Damage * Target.PhysicDamageReflectPercent;
  342. else
  343. ReflectDamage = Damage * Target.MagicDamageReflectPercent;
  344. if (BattleMgr.Instance.Battle.CanPrintLog)
  345. DebugHelper.LogError("------fighter:" + Caster.Id + " skillName: " + skillName + mHitParam.ToString());
  346. Caster.HitTarget = null;
  347. if (Damage < 1)
  348. {
  349. Damage = 1;
  350. BaseDamge = Damage;
  351. }
  352. else
  353. {
  354. Damage = Mathf.Round(Damage);
  355. }
  356. IsKillEnemyHit = Target.Life <= Damage && !Target.IsUndead;
  357. mHitParam.damage = (int)Damage;
  358. return (int)Damage;
  359. }
  360. public void SetRealDamage(int damage)
  361. {
  362. mHitParam.realDamage = damage;
  363. }
  364. //完美闪避
  365. void PerfectDodge()
  366. {
  367. SFloat randomValue = Caster.Battle.RandomValue(true);
  368. IsPerfectDodge = randomValue < Target.PerfectDodgeRate;
  369. //if (BattleMgr.Instance.Battle.IsPlayRecord || BattleMgr.Instance.Battle.IsKillingBoss)
  370. // DebugHelper.LogError(Caster.Id + "----------------target:" + Target.Name + " PerfectDodgeRate:" + Target.PerfectDodgeRate + " frameCnt:" + Time.frameCount);
  371. }
  372. //普通闪避
  373. void RandomDodge ()
  374. {
  375. SFloat Hit = Caster.GetBuffFunctionValue(Buff_Function_Type.Change_Hit_Value);
  376. SFloat Doge = Target.GetBuffFunctionValue(Buff_Function_Type.Change_Doge_Value);
  377. SFloat FunPrecent = Doge - Hit;
  378. SFloat a = BattleFormulaParamMgr.Instance.GetParam(16);
  379. SFloat p1 = Mathf.Max(25 + Target.Dodge - Caster.Hit, 0) / (5 + Mathf.Max((Target.Dodge - Caster.Hit) * a, 0));
  380. SFloat p2 = Mathf.Max(p1 + FunPrecent, 0);
  381. SFloat percent = Mathf.Min(p2, 95) * 0.01f ;
  382. SFloat dodgeRate =Mathf.Max(percent, 0);
  383. SFloat randomValue = Caster.Battle.RandomValue(true);
  384. IsDodge = randomValue < dodgeRate;
  385. //if (BattleMgr.Instance.Battle.IsPlayRecord || BattleMgr.Instance.Battle.IsKillingBoss)
  386. // DebugHelper.LogError(Caster.Id + "----------------target:" + Target.Name + " RandomDodge:" + dodgeRate);
  387. }
  388. //暴击伤害判断
  389. void RandomCrit ()
  390. {
  391. SFloat Crit = Caster.GetBuffFunctionValue(Buff_Function_Type.Change_Crit_Value);
  392. SFloat Ten = Target.GetBuffFunctionValue(Buff_Function_Type.Change_Ten_Value);
  393. SFloat FunPrecent = Crit - Ten;
  394. SFloat a = BattleFormulaParamMgr.Instance.GetParam(17);
  395. SFloat b = BattleFormulaParamMgr.Instance.GetParam(18);
  396. SFloat p1 = (1 + Mathf.Max((Caster.Crit - Target.Ten), 0) / (a + Mathf.Max((Caster.Crit - Target.Ten), 0) * b));
  397. SFloat p2 = Mathf.Max(p1 + FunPrecent, 0);
  398. SFloat critRate = Mathf.Min(p2 * 0.01f, 1);
  399. SFloat randomValue = Caster.Battle.RandomValue(true);
  400. IsCrit = randomValue < critRate;
  401. //if (BattleMgr.Instance.Battle.IsPlayRecord || BattleMgr.Instance.Battle.IsKillingBoss)
  402. // DebugHelper.LogError("----------------fighter:" + Caster.Id + " Target:" + Target.Name + " critRate:" + critRate);
  403. }
  404. }