XmdsSkillBase.cs 43 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381
  1. using CommonAI.Zone.Formula;
  2. using CommonLang;
  3. using System;
  4. using XmdsCommon.Plugin;
  5. using XmdsCommonServer.Plugin;
  6. using XmdsCommonServer.Plugin.XmdsSkillTemplate.DamageCalculator;
  7. using XmdsCommonServer.Plugin.XmdsSkillTemplate.Skills;
  8. using CommonAI.Zone;
  9. using CommonAI.Zone.Helper;
  10. using XmdsCommonServer.XLS.Data;
  11. using CommonAI.Zone.Instance;
  12. using XmdsCommon.EditorData;
  13. using XmdsCommonServer.Plugin.Units;
  14. using static XmdsCommonSkill.Plugin.Skills.BattleParams;
  15. using CommonAI.Data;
  16. using static CommonAI.Zone.UnitInfo;
  17. using XmdsCommon.Message;
  18. using CommonLang.Log;
  19. using System.Diagnostics;
  20. using System.Collections.Generic;
  21. using XmdsCommonServer.Plugin.Base;
  22. namespace XmdsCommonSkill.Plugin.Skills
  23. {
  24. /// <summary>
  25. /// FileName: XmdsSkillBase.cs
  26. /// Author: Alex.Yu
  27. /// Corporation:...
  28. /// Description:
  29. /// DateTime: 2015/6/25 9:32:33
  30. /// </summary>
  31. #region 战斗数据.
  32. public class BattleParams
  33. {
  34. private static readonly ObjectPool<BattleParams> s_ListPool = new ObjectPool<BattleParams>(s_ListPool_OnCreate);
  35. private XmdsVirtual mAttacker;
  36. private XmdsVirtual mHitter;
  37. private AttackSource mSource;
  38. private GameSkill mGameSkill;
  39. private XmdsAttackProperties mProp;
  40. private XmdsVirtual.AtkResult mAtkResult;
  41. #region 计算结果.
  42. private int mThreatValue; //仇恨值
  43. private int mSkillDamagePer; //技能伤害百分百
  44. private int mSkillDamageModify; //技能伤害修改
  45. private int mFinalCritRate; //最终暴击率
  46. private int mFinalDamage; //最终伤害
  47. private int mHitAdd; //命中增加
  48. private int mCritAdd; //暴击增加
  49. private int mDamageModifyAdd; //伤害绝对值增加
  50. private int mSkillDamageAdd; //技能伤害增加
  51. private int mHitResult; //打击结果
  52. private int mHitDamge; //打击伤害
  53. private DamageType mDamageType = DamageType.Damage;
  54. #endregion
  55. private BattleParams() { }
  56. public static BattleParams AllocAutoRelease()
  57. {
  58. BattleParams ret = s_ListPool.Get();
  59. ret.ReSet();
  60. return ret;
  61. }
  62. private static BattleParams s_ListPool_OnCreate()
  63. {
  64. return new BattleParams();
  65. }
  66. public void ReSet()
  67. {
  68. // this.mHitUnits.Clear();
  69. }
  70. public void Dispose()
  71. {
  72. OnDispose();
  73. s_ListPool.Release(this);
  74. }
  75. private void OnDispose()
  76. {
  77. mAttacker = null;
  78. mHitter = null;
  79. mSource = null;
  80. mGameSkill = null;
  81. mProp = null;
  82. mThreatValue = 0;
  83. mSkillDamagePer = 0;
  84. mSkillDamageModify = 0;
  85. mFinalCritRate = 0;
  86. mFinalDamage = 0;
  87. mHitAdd = 0;
  88. mCritAdd = 0;
  89. mDamageModifyAdd = 0;
  90. mSkillDamageAdd = 0;
  91. mHitDamge = 0;
  92. mHitResult = 0;
  93. mDamageType = DamageType.Damage;
  94. }
  95. /// <summary>
  96. /// 攻击者.
  97. /// </summary>
  98. public XmdsVirtual Attacker
  99. {
  100. set { mAttacker = value; }
  101. get { return mAttacker; }
  102. }
  103. /// <summary>
  104. /// 被攻击者.
  105. /// </summary>
  106. public XmdsVirtual Hitter { get { return mHitter;} set { mHitter = value;} }
  107. /// <summary>
  108. /// 攻击源信息.
  109. /// </summary>
  110. public AttackSource Source {
  111. get {return mSource;}
  112. set
  113. {
  114. mSource = value;
  115. mProp = (mSource.Attack.Properties as XmdsAttackProperties);
  116. }
  117. }
  118. /// <summary>
  119. /// 攻击信息.
  120. /// </summary>
  121. public XmdsAttackProperties AtkProp { get { return mProp; }}
  122. public XmdsVirtual.AtkResult AtkResult
  123. {
  124. get { return mAtkResult; }
  125. set { mAtkResult = value; }
  126. }
  127. /// <summary>
  128. /// 技能信息.
  129. /// </summary>
  130. public GameSkill GameSkill { get{return mGameSkill;} set { mGameSkill = value; } }
  131. /// <summary>
  132. /// 技能伤害百分比.
  133. /// </summary>
  134. public int SkillDamagePer { get { return mSkillDamagePer; } set{ mSkillDamagePer = value;} }
  135. /// <summary>
  136. /// 技能伤害绝对值.
  137. /// </summary>
  138. public int SkillDamageModify { get { return mSkillDamageModify; } set { mSkillDamageModify = value; } }
  139. /// <summary>
  140. /// 最终技能伤害.
  141. /// </summary>
  142. public int FinalSkillDamage { get { return mFinalDamage; } set { mFinalDamage = value; } }
  143. /// <summary>
  144. /// 最终暴击.
  145. /// </summary>
  146. public int FinalCritRate { get { return mFinalCritRate; } set { mFinalCritRate = value; } }
  147. /// <summary>
  148. /// 威胁值.
  149. /// </summary>
  150. public int ThreatValue { get { return mThreatValue; } set { mThreatValue = value; } }
  151. /// <summary>
  152. /// 暴击增加.
  153. /// </summary>
  154. public int CritAdd { get { return mCritAdd; } set { mCritAdd = value; } }
  155. /// <summary>
  156. /// 命中增加.
  157. /// </summary>
  158. public int HitAdd { get { return mHitAdd; } set { mHitAdd = value; } }
  159. /// <summary>
  160. /// 伤害绝对值增加.
  161. /// </summary>
  162. public int DamageModifyAdd { get { return mDamageModifyAdd; } set { mDamageModifyAdd = value; } }
  163. /// <summary>
  164. /// 使用计算公式类型.
  165. /// </summary>
  166. public DamageType UseDamageType { get { return mDamageType; } set { mDamageType = value; } }
  167. /// <summary>
  168. /// 技能伤害增加. 技能伤害固定值
  169. /// </summary>
  170. public int SkillDamageAdd { get { return mSkillDamageAdd; } set { mSkillDamageAdd = value; } }
  171. /// <summary>
  172. /// Hit结果,(伤害计算计算BUFF或其他异常状态作用最终效果.)
  173. /// </summary>
  174. public int HitResult { get { return mHitResult; } set { mHitResult = value; } }
  175. /// <summary>
  176. /// 打击伤害(FinalDamage经过暴击计算的值.)
  177. /// </summary>
  178. public int HitDamge { get { return mHitDamge; } set { mHitDamge = value; } }
  179. }
  180. #endregion
  181. public abstract class XmdsSkillBase : UnitSkill
  182. {
  183. /// <summary>
  184. /// 技能CD.
  185. /// </summary>
  186. protected static HashMap<int, XmdsSkillValue> mSkillCD = new HashMap<int, XmdsSkillValue>();
  187. /// <summary>
  188. /// 技能是否能自动释放.
  189. /// </summary>
  190. protected static HashMap<int, XmdsSkillValue> mSkillCanAuto = new HashMap<int, XmdsSkillValue>();
  191. #region 回调事件.
  192. public delegate void ScriptHandler(BattleParams param);
  193. public delegate bool ScriptHandler_Bool(BattleParams param);
  194. /// <summary>
  195. /// 计算闪避回调.
  196. /// </summary>
  197. protected ScriptHandler event_CalHitRateAdd;
  198. /// <summary>
  199. /// 计算暴击回调.
  200. /// </summary>
  201. protected ScriptHandler event_CalCritRateAdd;
  202. /// <summary>
  203. /// 计算技能伤害.
  204. /// </summary>
  205. protected ScriptHandler event_SkillDamagePer;
  206. /// <summary>
  207. /// 计算技能绝对值.
  208. /// </summary>
  209. protected ScriptHandler event_SkillDamageModify;
  210. /// <summary>
  211. /// 获取技能攻击类型(物理、魔法)
  212. /// </summary>
  213. protected ScriptHandler event_GetAttackType;
  214. /// <summary>
  215. /// 计算技能仇恨.
  216. /// </summary>
  217. protected ScriptHandler event_SkillThreatValue;
  218. /// <summary>
  219. /// 计算技能逻辑.
  220. /// </summary>
  221. protected ScriptHandler event_SkillLogic;
  222. /// <summary>
  223. /// 技能附加伤害加成.
  224. /// </summary>
  225. protected ScriptHandler event_DamageModifyAdd;
  226. /// <summary>
  227. /// 是否走伤害流程.
  228. /// </summary>
  229. protected ScriptHandler event_UseDamageType;
  230. /// <summary>
  231. /// 总技能伤害加成.
  232. /// </summary>
  233. protected ScriptHandler event_SkillDamageAdd;
  234. /// <summary>
  235. /// 计算伤害之后的技能逻辑回调.
  236. /// </summary>
  237. protected ScriptHandler event_SkillLogicAfterCalDamage;
  238. /// <summary>
  239. /// 计算最终伤害修改
  240. /// </summary>
  241. protected ScriptHandler_Bool event_SkillFinalDamageModify;
  242. /// <summary>
  243. /// 计算招架结果类型
  244. /// </summary>
  245. protected ScriptHandler event_SkillAtkRtl;
  246. //技能破定值
  247. protected int mSkillBreakShieldValue;
  248. #endregion
  249. protected enum EventType : int
  250. {
  251. HitRateAdd = 1, //命中增加
  252. CritRateAdd = 2, //暴击几率增加
  253. DamagePer = 3, //--技能伤害
  254. DamageModify = 4, //--伤害修改
  255. AttackType = 5, //--攻击类型
  256. ThreadValue = 6, //--仇恨值
  257. SkillLogic = 7, //--技能逻辑
  258. DamageModifyAdd = 8, //附加伤害
  259. UseFormluaType = 9, //走伤害流程
  260. SkillDamageAdd = 10, //技能伤害加成
  261. SkillLogicAftercalDamage = 11, //伤害计算之后逻辑回调
  262. SkillFinalDamageModify = 12, //技能最终伤害修改
  263. GetCalAtkRlt = 13, //获得招架结果
  264. }
  265. protected void RegistEvent(EventType type, ScriptHandler callBack)
  266. {
  267. switch (type)
  268. {
  269. case EventType.AttackType:
  270. event_GetAttackType = callBack;
  271. break;
  272. case EventType.CritRateAdd:
  273. event_CalCritRateAdd = callBack;
  274. break;
  275. case EventType.HitRateAdd:
  276. event_CalHitRateAdd = callBack;
  277. break;
  278. case EventType.DamagePer:
  279. event_SkillDamagePer = callBack;
  280. break;
  281. case EventType.DamageModify:
  282. event_SkillDamageModify = callBack;
  283. break;
  284. case EventType.ThreadValue:
  285. event_SkillThreatValue = callBack;
  286. break;
  287. case EventType.SkillLogic:
  288. event_SkillLogic = callBack;
  289. break;
  290. case EventType.DamageModifyAdd:
  291. event_DamageModifyAdd = callBack;
  292. break;
  293. case EventType.UseFormluaType:
  294. event_UseDamageType = callBack;
  295. break;
  296. case EventType.SkillDamageAdd:
  297. event_SkillDamageAdd = callBack;
  298. break;
  299. case EventType.SkillLogicAftercalDamage:
  300. event_SkillLogicAfterCalDamage = callBack;
  301. break;
  302. case EventType.GetCalAtkRlt:
  303. event_SkillAtkRtl = callBack;
  304. break;
  305. default: break;
  306. }
  307. }
  308. protected void RegistEvent_Bool(EventType type, ScriptHandler_Bool callBack)
  309. {
  310. switch (type)
  311. {
  312. case EventType.SkillFinalDamageModify:
  313. event_SkillFinalDamageModify = callBack;
  314. break;
  315. default: break;
  316. }
  317. }
  318. public override int SkillID
  319. {
  320. get { return -1; }
  321. }
  322. protected override void OnBaseInit(GameSkill info, XmdsVirtual unit, ref SkillTemplate template)
  323. {
  324. //技能CD由配置表控制.
  325. template.CoolDownMS = this.GetTargetFormulaValue(info.SkillLevel, this.GetSkillCD(info.SkillID));
  326. //控制是否能自动施放.
  327. if (unit != null && unit.mUnit.IsPlayer && this.GetTargetFormulaValue(0, this.GetCanAuto(info.SkillID)) == 0)
  328. {
  329. info.AutoLaunch = false;
  330. }
  331. else
  332. {
  333. info.AutoLaunch = true;
  334. }
  335. OnInitConfig();
  336. OnInit(info, unit, ref template);
  337. this.mSkillBreakShieldValue = XmdsGlobalData.GetSkillBreakShieldValue(info.SkillID);
  338. }
  339. /// <summary>
  340. /// 初始化回调,用于子类重铸.
  341. /// </summary>
  342. /// <param name="info"></param>
  343. /// <param name="unit"></param>
  344. /// <param name="template"></param>
  345. protected virtual void OnInit(GameSkill info, XmdsVirtual unit, ref SkillTemplate template)
  346. {
  347. }
  348. /** 敌伤害,友治疗,自动获取伤害类型 */
  349. protected CommonAI.Data.DamageType AutoGetDamageType(BattleParams param, CommonAI.Data.DamageType alliesDamageType = CommonAI.Data.DamageType.Heal)
  350. {
  351. if(param.Attacker.GetCurPKMode() == PKMode.All)
  352. {
  353. return (param.Attacker == param.Hitter) ? alliesDamageType : CommonAI.Data.DamageType.Damage;
  354. }
  355. else if (param.Attacker.IsAllies(param.Hitter, true, true))
  356. {
  357. //和平模式下,只有队友才有加血
  358. return alliesDamageType;
  359. }
  360. else if (param.Attacker.GetCurPKMode() == PKMode.Peace && param.Hitter.IsPlayerUnit())
  361. {
  362. //和平模式下,非队友,无伤害
  363. return CommonAI.Data.DamageType.None;
  364. }
  365. return (param.Attacker == param.Hitter) ? alliesDamageType : CommonAI.Data.DamageType.Damage;
  366. }
  367. public override bool OnCallDamageProcess(XmdsVirtual attacker, XmdsVirtual hitter, AttackSource source, GameSkill gs, ref XmdsVirtual.AtkResult result, ref int damage)
  368. {
  369. BattleParams param = BattleParams.AllocAutoRelease();
  370. try
  371. { //param.AttackRlt = result.rlt;
  372. param.Attacker = attacker;
  373. param.Hitter = hitter;
  374. param.Source = source;
  375. param.GameSkill = gs;
  376. param.AtkResult = result;
  377. try
  378. {
  379. param = OnDoSkillHitProcess(ref param);
  380. }
  381. catch (Exception error)
  382. {
  383. LogError(string.Format("skill {0} attackUID:{1}, HitterUID: {2}, SceneID:{3} SceneUID:{4} OnCallDamageProcess error:{5} - {6}",
  384. gs.SkillID, (attacker == null ? "anull" : attacker.mUnit.PlayerUUID), (hitter == null ? "hnull" : hitter.mUnit.PlayerUUID),
  385. (attacker == null ? -1 : attacker.mUnit.Parent.GetSceneID()), (attacker == null ? "snull" : attacker.mUnit.Parent.UUID), error.ToString(), error.StackTrace));
  386. }
  387. damage = param.HitResult;
  388. //System.Console.WriteLine("伤害:" + attacker.mUnit.ID + ", 伤害:" + damage);
  389. //仇恨系数.
  390. //result.ThreatValue = param.ThreatValue;
  391. }
  392. finally
  393. {
  394. param.Dispose();
  395. }
  396. result.breakShieldValue = CUtils.CastInt(this.mSkillBreakShieldValue * (1.0f + XmdsUnitProp.PER * attacker.MirrorProp.BreakShieldValue));
  397. return true;
  398. }
  399. #region 工具API.
  400. public virtual int GetTargetFormulaValue(int lv, int[] formula)
  401. {
  402. return XmdsBattleHelper.GetTargetFormulaValue(lv, formula, SkillID);
  403. }
  404. public virtual int GetTargetFormulaValue(int lv, XmdsSkillValue formula)
  405. {
  406. return formula.GetValue(lv);
  407. }
  408. public override int GetSkillValue(AbstractSkillType type) { return 0; }
  409. //public virtual int GetTargetValue(int lv, XmdsSkillValue value)
  410. //{
  411. // bool invaild = false;
  412. // int ret = value.GetValue(lv, out invaild);
  413. // if (invaild)
  414. // {
  415. // LogError(SkillID, lv);
  416. // }
  417. // return ret;
  418. //}
  419. private void LogError(int skill, int lv)
  420. {
  421. XmdsBattleHelper.LogError(string.Format("XmdsSkillBase get Value Error:skill id = {0} lv = {1}", skill, lv));
  422. }
  423. /// <summary>
  424. /// 算基础伤害.
  425. /// </summary>
  426. /// <param name="baseValue"></param>
  427. /// <param name="up"></param>
  428. /// <param name="lv"></param>
  429. /// <returns></returns>
  430. public virtual int CalDamagePer(int baseValue, int lv)
  431. {
  432. //return (lv - 1) + baseValue;
  433. return baseValue;
  434. }
  435. public virtual int CalDamagePer(XmdsSkillValue baseValue, int lv)
  436. {
  437. //return (lv - 1) + baseValue.GetValue(lv); ;
  438. return baseValue.GetValue(lv); ;
  439. }
  440. public virtual int GetThreatValue(int formulaID1, int formulaID2)
  441. {
  442. return 0;
  443. }
  444. #endregion
  445. #region 常态注册.
  446. protected override void OnRegistEvent()
  447. {
  448. RegistEvents();
  449. }
  450. private void RegistEvents()
  451. {
  452. this.RegistEvent(EventType.DamagePer, OnSkillDamagePerEvent);
  453. this.RegistEvent(EventType.DamageModify, OnskillDamageModifyEvent);
  454. this.RegistEvent(EventType.AttackType, OnAttackTypeEvent);
  455. this.RegistEvent(EventType.ThreadValue, OnThreatValueEvent);
  456. this.RegistEvent(EventType.SkillLogic, OnSkillLogicEvent);
  457. this.RegistEvent_Bool(EventType.SkillFinalDamageModify, OnSkillFinalDamageModifyEvent);
  458. this.RegistEvent(EventType.GetCalAtkRlt, OnGetCalAtkRlt);
  459. this.RegistEvent(EventType.SkillLogicAftercalDamage, OnSkillLogicAftercalDamage);
  460. }
  461. /// <summary>
  462. /// 得到仇恨.
  463. /// </summary>
  464. /// <param name="param"></param>
  465. protected virtual void OnThreatValueEvent(BattleParams param)
  466. {
  467. param.ThreatValue = 0;
  468. }
  469. /// <summary>
  470. /// 得到技能百分比.
  471. /// </summary>
  472. /// <param name="param"></param>
  473. protected virtual void OnSkillDamagePerEvent(BattleParams param)
  474. {
  475. }
  476. /// <summary>
  477. /// 得到技能伤害绝对值.
  478. /// </summary>
  479. /// <param name="param"></param>
  480. protected virtual void OnskillDamageModifyEvent(BattleParams param)
  481. {
  482. }
  483. /// <summary>
  484. /// 得到技能伤害类型.
  485. /// </summary>
  486. /// <param name="param"></param>
  487. protected virtual void OnAttackTypeEvent(BattleParams param)
  488. {
  489. }
  490. /// <summary>
  491. /// 技能特殊逻辑.
  492. /// </summary>
  493. /// <param name="param"></param>
  494. protected virtual void OnSkillLogicEvent(BattleParams param)
  495. {
  496. }
  497. protected virtual void OnSkillLogicAftercalDamage(BattleParams param)
  498. {
  499. }
  500. /// <summary>
  501. /// 技能固定伤害.(最终值)
  502. /// reture不执行具体伤害逻辑计算,直接使用给定的伤害值
  503. /// <param name="param"></param>
  504. protected virtual bool OnSkillFinalDamageModifyEvent(BattleParams param)
  505. {
  506. return false;
  507. }
  508. /// <summary>
  509. /// 获得招架结果类型
  510. /// </summary>
  511. /// <param name="param"></param>
  512. protected virtual void OnGetCalAtkRlt(BattleParams param)
  513. {
  514. }
  515. #endregion
  516. private void OnDispose()
  517. {
  518. event_CalHitRateAdd = null;
  519. event_CalCritRateAdd = null;
  520. event_SkillDamagePer = null;
  521. event_SkillDamageModify = null;
  522. event_GetAttackType = null;
  523. event_SkillThreatValue = null;
  524. event_SkillLogic = null;
  525. event_SkillDamageAdd = null;
  526. event_SkillLogicAfterCalDamage = null;
  527. event_SkillFinalDamageModify = null;
  528. event_UseDamageType = null;
  529. event_DamageModifyAdd = null;
  530. }
  531. #region 新计算流程.
  532. protected BattleParams OnDoSkillHitProcess(ref BattleParams param)
  533. {
  534. OnCalAtkRlt(param);
  535. //获得伤害类型.
  536. OnAttackType(param);
  537. //是否使用伤害公式.
  538. OnUseDamageFormula(param);
  539. //获得技能伤害百分比.
  540. OnGetSkillDamagePer(param);
  541. //获得技能固定伤害.
  542. OnGetSkillDamageModify(param);
  543. //获得技能仇恨系数.
  544. OnGetSkillThreatValue(param);
  545. //技能逻辑调用.
  546. OnGetSkillLogic(param);
  547. //绝对伤害和计算伤害,只走一个
  548. if (!OnSkillFinalDamageModify(param))
  549. {
  550. switch (param.UseDamageType)
  551. {
  552. case CommonAI.Data.DamageType.Damage:
  553. OnGetDamage(param);
  554. break;
  555. case CommonAI.Data.DamageType.Heal:
  556. OnGetHeal(param);
  557. break;
  558. case CommonAI.Data.DamageType.None:
  559. param.FinalSkillDamage = 0;
  560. break;
  561. default: break;
  562. }
  563. //计算暴击效果.
  564. OnGetHitDamage(param);
  565. }
  566. OnDispatchEvent(param);
  567. //计算伤害之后的回调.
  568. OnGetSkillLogicAfterCalDamage(param);
  569. //处理吸血效果
  570. if (param.UseDamageType == CommonAI.Data.DamageType.Damage && param.HitResult > 0)
  571. {
  572. ProcessAtkLeech(param);
  573. }
  574. return param;
  575. }
  576. #region 攻击逻辑结果计算.
  577. /// <summary>
  578. /// 计算攻击结果,闪避,暴击,命中.
  579. /// </summary>
  580. /// <param name="param"></param>
  581. private void OnCalAtkRlt(BattleParams param)
  582. {
  583. //外部已经赋值了, 就不需要再计算了
  584. if (param.Source.OutClientState != (byte)XmdsVirtual.UnitHitEventState.Normal)
  585. {
  586. return;
  587. }
  588. XmdsVirtual attacker = param.Attacker;
  589. XmdsVirtual hitter = param.Hitter;
  590. AttackSource atksource = param.Source;
  591. if (atksource.FromExpectTarget == SkillTemplate.CastTarget.Alias ||
  592. atksource.FromExpectTarget == SkillTemplate.CastTarget.AlliesExcludeSelf ||
  593. atksource.FromExpectTarget == SkillTemplate.CastTarget.AlliesIncludeSelf ||
  594. atksource.FromExpectTarget == SkillTemplate.CastTarget.PetForMaster ||
  595. attacker.GetPlayerUUID() == hitter.GetPlayerUUID())
  596. {
  597. //param.Source.OutClientState = (byte)XmdsVirtual.UnitHitEventState.Normal;
  598. if (this.IsHealCritAttack(param))
  599. {
  600. param.Source.OutClientState = (byte)XmdsVirtual.UnitHitEventState.Crit;
  601. }
  602. else
  603. {
  604. param.Source.OutClientState = (byte)XmdsVirtual.UnitHitEventState.Normal;
  605. }
  606. }
  607. else
  608. {
  609. if (hitter.GetMaType() >= (byte)MonsterVisibleDataB2C.MonsterType.MType4 && IsKillMonsterCrit(param))
  610. {
  611. param.Source.OutClientState = (byte)XmdsVirtual.UnitHitEventState.KillMonsterCrit;
  612. //log.Info("斩妖暴击:" + attacker.mInfo.Name + ", " + hitter.mInfo.Name);
  613. }
  614. else
  615. {
  616. if (this.IsCritAttack(param))
  617. {
  618. param.Source.OutClientState = (byte)XmdsVirtual.UnitHitEventState.Crit;
  619. }
  620. else
  621. {
  622. param.Source.OutClientState = (byte)XmdsVirtual.UnitHitEventState.Normal;
  623. }
  624. }
  625. }
  626. //二次计算一下招架结果
  627. if (event_SkillAtkRtl != null)
  628. {
  629. event_SkillAtkRtl.Invoke(param);
  630. }
  631. }
  632. #region 是否斩妖的特殊暴击
  633. private bool IsKillMonsterCrit(BattleParams param)
  634. {
  635. XmdsInstancePlayer attacker = param.Attacker.mUnit as XmdsInstancePlayer;
  636. XmdsInstanceMonster hitter = param.Hitter.mUnit as XmdsInstanceMonster;
  637. int yaoQiLevel = param.Attacker.MirrorProp.YaoQiLevel;
  638. if (attacker != null && hitter != null && yaoQiLevel > 0)
  639. {
  640. HateSystem.HateInfo hateInfo = param.Hitter.mHateSystem.getHateInfo(param.Attacker.mUnit.ID);
  641. if (hateInfo != null && XmdsDataMgr.GetInstance().IsZhanYaoCrit(attacker, param.Hitter.mUnit.Level, yaoQiLevel,
  642. ++hateInfo.hitNums, ref param.Source.OutClientStateExt))
  643. {
  644. hateInfo.hitNums = 0;
  645. return true;
  646. }
  647. }
  648. return false;
  649. }
  650. #endregion
  651. #region 是否暴击.
  652. private bool IsCritAttack(BattleParams param)
  653. {
  654. XmdsVirtual attacker = param.Attacker;
  655. XmdsVirtual hitter = param.Hitter;
  656. OnFinalCritHandler(param);
  657. //如果为普攻,并且下次普攻概率不为0,走这个概率
  658. if(param.GameSkill.SkillType == XmdsSkillType.normalAtk && param.Attacker.MirrorProp.NormalAtkCriteRate > 0)
  659. {
  660. return XmdsDamageCalculator.IsInRandomRange(param.Attacker.MirrorProp.NormalAtkCriteRate, attacker.mUnit.RandomN, (int)XmdsDamageCalculator.PERER);
  661. }
  662. else
  663. {
  664. int critRate = attacker.MirrorProp.CritRate;
  665. if (attacker.IsPlayerUnit() && hitter.IsBoss())
  666. {
  667. critRate += attacker.MirrorProp.ToBossCritRate;
  668. }
  669. int finalCriteRate = critRate + param.CritAdd - hitter.MirrorProp.ResCritRate;
  670. param.FinalCritRate = finalCriteRate;
  671. return XmdsDamageCalculator.IsInRandomRange(finalCriteRate, attacker.mUnit.RandomN, (int)XmdsDamageCalculator.PERER);
  672. }
  673. }
  674. private bool IsHealCritAttack(BattleParams param)
  675. {
  676. /*
  677. 施法者的治疗暴击率 = 治疗暴击系数 * 施法者暴击 /(施法者暴击 + 施法者等级 * 100) +施法者.暴击率 + 被治疗者.受到治疗暴击率
  678. wuyonghui(吴永辉) 07-25 14:56:26
  679. 最后个属性目前还没有,以后会有 (指的是“被治疗者.受到治疗暴击率”)
  680. */
  681. XmdsVirtual attacker = param.Attacker;
  682. float critRate = attacker.MirrorProp.CritRate * XmdsUnitProp.PER;
  683. OnFinalCritHandler(param);
  684. var finalCriteRate = (int)critRate + param.CritAdd;
  685. param.FinalCritRate = finalCriteRate;
  686. return XmdsDamageCalculator.IsInRandomRange(finalCriteRate, attacker.mUnit.RandomN, (int)XmdsDamageCalculator.PERER);
  687. }
  688. private void OnFinalCritHandler(BattleParams param)
  689. {
  690. if (event_CalCritRateAdd != null)
  691. {
  692. event_CalCritRateAdd.Invoke(param);
  693. }
  694. }
  695. #endregion
  696. #endregion
  697. #region 技能攻击效果(逻辑、伤害).
  698. private void OnGetSkillDamagePer(BattleParams param)
  699. {
  700. if (event_SkillDamagePer != null)
  701. {
  702. event_SkillDamagePer.Invoke(param);
  703. }
  704. }
  705. private void OnGetSkillDamageModify(BattleParams param)
  706. {
  707. if (event_SkillDamageModify != null)
  708. {
  709. event_SkillDamageModify.Invoke(param);
  710. }
  711. }
  712. private void OnGetSkillThreatValue(BattleParams param)
  713. {
  714. if (event_SkillThreatValue != null)
  715. {
  716. event_SkillThreatValue.Invoke(param);
  717. }
  718. }
  719. private void OnAttackType(BattleParams param)
  720. {
  721. if (event_GetAttackType != null)
  722. {
  723. event_GetAttackType.Invoke(param);
  724. }
  725. }
  726. private void OnGetSkillLogic(BattleParams param)
  727. {
  728. if (event_SkillLogic != null)
  729. {
  730. event_SkillLogic.Invoke(param);
  731. }
  732. }
  733. protected virtual void OnGetSkillLogicAfterCalDamage(BattleParams param)
  734. {
  735. if (event_SkillLogicAfterCalDamage != null)
  736. {
  737. event_SkillLogicAfterCalDamage.Invoke(param);
  738. }
  739. }
  740. //技能最终伤害调整
  741. private bool OnSkillFinalDamageModify(BattleParams param)
  742. {
  743. if (event_SkillFinalDamageModify != null)
  744. {
  745. return event_SkillFinalDamageModify.Invoke(param);
  746. }
  747. return false;
  748. }
  749. private void OnGetSkillDamageAdd(BattleParams param)
  750. {
  751. if (event_SkillDamageAdd != null)
  752. {
  753. event_SkillDamageAdd.Invoke(param);
  754. }
  755. }
  756. protected void OnGetDamage(BattleParams param)
  757. {
  758. XmdsVirtual attacker = param.Attacker;
  759. XmdsVirtual hitter = param.Hitter;
  760. OnGetDamageModifyAdd(param);
  761. int attackTemp = attacker.MirrorProp.GetFinalAttack(param.Hitter.mUnit.IsMonster);
  762. //计算面板物攻和技能加成效果.
  763. int attack = XmdsDamageCalculator.GetSkillDamage(attackTemp, param.SkillDamagePer, param.SkillDamageModify + param.DamageModifyAdd);
  764. if(attack <= 1 && attackTemp > 10)
  765. {
  766. string stackInfo = new StackTrace().ToString();
  767. int spellID = (param.Source != null && param.Source.FromSpell != null) ? param.Source.FromSpell.ID : 0;
  768. XmdsVirtual.FormatLog(LoggerLevel.ERROR, "攻击异常 : {0}, {1}, {2}, {3}, {4}, {5}, {6}", attackTemp, attack,
  769. param.SkillDamagePer, param.SkillDamageModify, param.DamageModifyAdd, spellID, stackInfo);
  770. }
  771. OnGetSkillDamageAdd(param);
  772. param.FinalSkillDamage = XmdsDamageCalculator.GetDamage(attack, attacker, hitter, param.Source) + param.SkillDamageAdd;
  773. }
  774. //治疗量计算.
  775. private void OnGetHeal(BattleParams param)
  776. {
  777. XmdsVirtual attacker = param.Attacker;
  778. XmdsVirtual hitter = param.Hitter;
  779. int attack = attacker.MirrorProp.MaxAttack;
  780. //计算面板魔攻和技能加成效果.
  781. attack = XmdsDamageCalculator.GetSkillDamage(attack, param.SkillDamagePer, param.SkillDamageModify + param.DamageModifyAdd);
  782. int v = attack;
  783. //治疗量.
  784. //v = CUtils.CastInt(attack * (param.Attacker.MirrorProp.HealEffect / XmdsDamageCalculator.PERER + 1));
  785. //受治疗量.
  786. //v = CUtils.CastInt(v * (hitter.MirrorProp.HealedEffect / XmdsDamageCalculator.PERER + 1));
  787. param.FinalSkillDamage = -v - param.SkillDamageAdd;
  788. //如果治疗效果计算等0,强制转为-1.
  789. if (param.FinalSkillDamage == 0)
  790. {
  791. param.FinalSkillDamage = -1;
  792. }
  793. else if (param.FinalSkillDamage > 0)
  794. {
  795. XmdsVirtual.FormatLog("治疗量计算异常值 = {0}", param.FinalSkillDamage);
  796. }
  797. }
  798. /** 处理技能,普攻吸血效果 */
  799. private void ProcessAtkLeech(BattleParams param)
  800. {
  801. //计算技能吸血和普攻吸血
  802. int damage = param.HitResult;
  803. if(damage <= 0)
  804. {
  805. return;
  806. }
  807. if (param.Attacker.mUnit.CurrentHP < param.Attacker.mUnit.MaxHP)
  808. {
  809. if (param.GameSkill.SkillType == XmdsSkillType.normalAtk)
  810. {
  811. if (param.Attacker.MirrorProp.NormalAtkLeech > 0)
  812. {
  813. int addHP = CUtils.CastInt(damage * XmdsUnitProp.PER * param.Attacker.MirrorProp.NormalAtkLeech);
  814. if (addHP > 0)
  815. param.Attacker.mUnit.AddHP(addHP, param.Attacker.mUnit);
  816. }
  817. }
  818. else if (param.GameSkill.SkillType == XmdsSkillType.active)
  819. {
  820. if (param.Attacker.MirrorProp.ActiveAtkLeech > 0)
  821. {
  822. int addHP = CUtils.CastInt(damage * XmdsUnitProp.PER * param.Attacker.MirrorProp.ActiveAtkLeech);
  823. if (addHP > 0)
  824. param.Attacker.mUnit.AddHP(addHP, param.Attacker.mUnit);
  825. }
  826. }
  827. }
  828. }
  829. private void OnGetHitDamage(BattleParams param)
  830. {
  831. if (param.Source.OutClientState == (int)XmdsVirtual.UnitHitEventState.KillMonsterCrit)
  832. {
  833. param.HitDamge = CUtils.CastInt(param.FinalSkillDamage * (param.Source.OutClientStateExt * XmdsUnitProp.PER));
  834. }
  835. else if (param.Source.OutClientState == (int)XmdsVirtual.UnitHitEventState.Crit)
  836. {
  837. int criteDmgRate;
  838. if (param.UseDamageType == CommonAI.Data.DamageType.Heal)
  839. criteDmgRate = XmdsDamageCalculator.GetCritHealDamage(param.FinalSkillDamage, param.Attacker, param.Hitter);
  840. else
  841. criteDmgRate = XmdsDamageCalculator.GetCritDamage(param.FinalSkillDamage, param.Attacker, param.Hitter);
  842. //MMO-14871: 2021.3.30调整算法
  843. //2021.3.31暂时还原修改
  844. //criteDmgRate = criteDmgRate / 2 + 5000;
  845. if (criteDmgRate > XmdsDamageCalculator.PERER)
  846. {
  847. param.HitDamge = CUtils.CastInt(param.FinalSkillDamage / XmdsDamageCalculator.PERER * criteDmgRate);
  848. }
  849. }
  850. else
  851. {
  852. param.HitDamge = param.FinalSkillDamage;
  853. }
  854. }
  855. private void OnGetDamageModifyAdd(BattleParams param)
  856. {
  857. if (event_DamageModifyAdd != null)
  858. {
  859. event_DamageModifyAdd.Invoke(param);
  860. }
  861. }
  862. private void OnUseDamageFormula(BattleParams param)
  863. {
  864. if (event_UseDamageType != null)
  865. {
  866. event_UseDamageType.Invoke(param);
  867. }
  868. }
  869. private void OnDispatchEvent(BattleParams param)
  870. {
  871. int result = param.HitDamge;
  872. XmdsVirtual.AtkResult r = param.AtkResult;
  873. param.Attacker.DispatchHitEvents(ref result, param.Attacker, param.Hitter, param.Source,
  874. ref r, param.UseDamageType);
  875. param.HitResult = result;
  876. }
  877. #endregion
  878. #endregion
  879. #region 基础事件监听.
  880. protected override void OnBaseDataInit()
  881. {
  882. base.OnBaseDataInit();
  883. if (SkillID != -1)
  884. {
  885. XmdsSkillData data = XmdsDataMgr.GetInstance().GetXmdsSkillData(SkillID);
  886. if (data != null)
  887. {
  888. if(data.CDTime != null)
  889. {
  890. XmdsSkillValue skillCD;
  891. InitData(data, out skillCD, XmdsSkillData.XmdsSkillDataKey.CDTime);
  892. mSkillCD.Put(SkillID, skillCD);
  893. }
  894. if (data.canAuto != null)
  895. {
  896. XmdsSkillValue skillCanAuto;
  897. InitData(data, out skillCanAuto, XmdsSkillData.XmdsSkillDataKey.canAuto);
  898. mSkillCanAuto.Put(SkillID, skillCanAuto);
  899. }
  900. if(data.TalentData != null && data.TalentData.Length > 0)
  901. {
  902. XmdsSkillValue talentInfo;
  903. InitData(data, out talentInfo, XmdsSkillData.XmdsSkillDataKey.TalentData);
  904. XmdsGlobalData.PutTalentData(SkillID, talentInfo);
  905. }
  906. if(data.BreakShieldValue > 0)
  907. {
  908. XmdsGlobalData.PutSkillBreakShieldValue(SkillID, data.BreakShieldValue);
  909. }
  910. }
  911. else
  912. {
  913. XmdsVirtual.FormatLog(string.Format("XmdsSkillBase get Value Error:skill id = {0}", SkillID));
  914. }
  915. }
  916. }
  917. private XmdsSkillValue GetSkillCD(int skillID)
  918. {
  919. XmdsSkillValue outSkillCD;
  920. mSkillCD.TryGetValue(skillID, out outSkillCD);
  921. return (outSkillCD == null) ? XmdsGlobalData.DefaultValue : outSkillCD;
  922. }
  923. private XmdsSkillValue GetCanAuto(int skillID)
  924. {
  925. XmdsSkillValue outData;
  926. mSkillCanAuto.TryGetValue(skillID, out outData);
  927. return (outData == null) ? XmdsGlobalData.DefaultValue : outData;
  928. }
  929. /// <summary>
  930. /// MP预判断.
  931. /// </summary>
  932. /// <param name="skill"></param>
  933. /// <param name="launcher"></param>
  934. /// <returns></returns>
  935. protected override bool OnUnitLaunchSkillEvent(GameSkill skillInfo, ref InstanceUnit.SkillState skill, XmdsVirtual launcher, ref InstanceUnit.LaunchSkillParam param)
  936. {
  937. bool ret = true;
  938. //if (skill.ID == SkillID)
  939. //{
  940. // if (ret == false)
  941. // {
  942. // //发送提示.
  943. // launcher.SendMsgToClient(XmdsConstConfig.TIPS_MP_NOT_ENOUGH);
  944. // }
  945. //}
  946. return ret;
  947. }
  948. #region 技能自动战斗检测.
  949. public override bool SkillAutoLaunchTest(InstanceUnit.SkillState ss, XmdsVirtual launcher)
  950. {
  951. if (OnSkillAutoLaunchTest(ss, launcher))
  952. {
  953. return true;
  954. }
  955. return false;
  956. }
  957. /// <summary>
  958. /// 技能自动战斗自定义检测.
  959. /// </summary>
  960. /// <param name="ss"></param>
  961. /// <param name="launcher"></param>
  962. /// <returns></returns>
  963. protected virtual bool OnSkillAutoLaunchTest(InstanceUnit.SkillState ss, XmdsVirtual launcher)
  964. {
  965. return true;
  966. }
  967. #endregion
  968. /// <summary>
  969. /// 技能施放完毕执行MP扣除.
  970. /// </summary>
  971. /// <param name="costEnergy"></param>
  972. /// <param name="attacker"></param>
  973. /// <param name="state"></param>
  974. /// <returns></returns>
  975. protected override int OnUnitLaunchSkillOver(GameSkill info, XmdsVirtual attacker, InstanceUnit.SkillState state)
  976. {
  977. return 0;
  978. }
  979. #endregion
  980. }
  981. public abstract class XmdsPassiveSkillBase : UnitPassiveSkill
  982. {
  983. /// <summary>
  984. ///计时器.
  985. /// </summary>
  986. private TimeExpire<int> mTimer = null;
  987. private bool mIsCD = false;
  988. /// <summary>
  989. /// CD减少时间.
  990. /// </summary>
  991. private int mDecreaseTotalTimeMS = 0;
  992. public override int SkillID
  993. {
  994. get { return -1; }
  995. }
  996. protected bool IsCD
  997. {
  998. set { mIsCD = true; }
  999. get { return mIsCD; }
  1000. }
  1001. /// <summary>
  1002. /// 获得主技能ID.
  1003. /// </summary>
  1004. /// <returns></returns>
  1005. public virtual int GetMainSkillID()
  1006. {
  1007. return -1;
  1008. }
  1009. protected override void OnUpdate(int intervalMS, bool slowRefresh)
  1010. {
  1011. //计时器刷新.
  1012. TimerUpdate(intervalMS);
  1013. base.OnUpdate(intervalMS, slowRefresh);
  1014. }
  1015. protected void GetNearUnitInfo(XmdsVirtual virInfo, float range, ref int alliesCount, ref int enemyCount)
  1016. {
  1017. int alliesCountTemp = 0;
  1018. int enemyCountTemp = 0;
  1019. using (var list = ListObjectPool<InstanceUnit>.AllocAutoRelease())
  1020. {
  1021. virInfo.mUnit.Parent.getObjectsRoundRange<InstanceUnit>(
  1022. (obj, dx, dy, dr) =>
  1023. {
  1024. var u = obj as InstanceUnit;
  1025. if (u.Virtual is XmdsVirtual_Player && CMath.includeRoundPoint(dx, dy, dr, u.X, u.Y))
  1026. {
  1027. //己方单位.
  1028. if (virInfo.mUnit.Force == u.Force)
  1029. {
  1030. alliesCountTemp++;
  1031. }
  1032. else
  1033. {
  1034. enemyCountTemp++;
  1035. }
  1036. }
  1037. return true;
  1038. },
  1039. virInfo.mUnit.X,
  1040. virInfo.mUnit.Y,
  1041. range,
  1042. list, virInfo.mUnit.AoiStatus);
  1043. }
  1044. alliesCount = alliesCountTemp;
  1045. enemyCount = enemyCountTemp;
  1046. }
  1047. protected List<InstanceUnit> GetNearUnitList(XmdsVirtual virInfo, float range, bool includeSelf = false, int pointForce = 0)
  1048. {
  1049. List<InstanceUnit> list = new List<InstanceUnit>();
  1050. virInfo.mUnit.Parent.getObjectsRoundRange<InstanceUnit>(
  1051. (obj, dx, dy, dr) =>
  1052. {
  1053. if(!includeSelf && obj == virInfo.mUnit)
  1054. {
  1055. return false;
  1056. }
  1057. var u = obj as InstanceUnit;
  1058. if (pointForce > 0 && u.Force != pointForce)
  1059. {
  1060. return false;
  1061. }
  1062. return CMath.includeRoundPoint(dx, dy, dr, u.X, u.Y);
  1063. },
  1064. virInfo.mUnit.X,
  1065. virInfo.mUnit.Y,
  1066. range,
  1067. list, virInfo.mUnit.AoiStatus);
  1068. return list;
  1069. }
  1070. public override int GetCDPassTime()
  1071. {
  1072. if (mTimer != null)
  1073. {
  1074. return mTimer.PassTimeMS;
  1075. }
  1076. return 0;
  1077. }
  1078. public override int GetCDTotalTime()
  1079. {
  1080. if (mTimer != null)
  1081. {
  1082. return mTimer.TotalTimeMS;
  1083. }
  1084. return 0;
  1085. }
  1086. public override void SetCDPassTime(int timeMS)
  1087. {
  1088. if (mTimer != null)
  1089. {
  1090. mTimer.Update(timeMS);
  1091. }
  1092. }
  1093. public override int GetSkillValue(AbstractSkillType type) { return 0; }
  1094. #region Timer相关.
  1095. protected void SetTimer(int timeMS)
  1096. {
  1097. int t = timeMS - GetDecreaseTotalTimeMS();
  1098. t = Math.Max(1000, t);
  1099. if (mTimer == null)
  1100. {
  1101. mTimer = new TimeExpire<int>(t);
  1102. }
  1103. else
  1104. {
  1105. mTimer.Reset(t);
  1106. }
  1107. }
  1108. /// <summary>
  1109. /// 设置CD为true,重算CD.
  1110. /// </summary>
  1111. protected void RestartTimer()
  1112. {
  1113. mIsCD = true;
  1114. if (mTimer != null)
  1115. {
  1116. mTimer.Reset();
  1117. }
  1118. }
  1119. protected void TimerUpdate(int intervalMS)
  1120. {
  1121. if (mTimer != null)
  1122. {
  1123. if (mIsCD == true && mTimer.Update(intervalMS))
  1124. {
  1125. mIsCD = false;
  1126. }
  1127. }
  1128. }
  1129. public virtual int GetTargetFormulaValue(int lv, int[] formula)
  1130. {
  1131. return XmdsBattleHelper.GetTargetFormulaValue(lv, formula, SkillID);
  1132. }
  1133. public virtual int GetTargetFormulaValue(int lv, XmdsSkillValue formula)
  1134. {
  1135. return formula.GetValue(lv);
  1136. }
  1137. public override void SetDecreaseTotalTimeMS(int timeMS)
  1138. {
  1139. mDecreaseTotalTimeMS = timeMS;
  1140. }
  1141. public override int GetDecreaseTotalTimeMS()
  1142. {
  1143. return mDecreaseTotalTimeMS;
  1144. }
  1145. private void LogError(int skill, int lv)
  1146. {
  1147. XmdsBattleHelper.LogError(string.Format("XmdsPassiveSkillBase get Value Error:skill id = {0} lv = {1}", skill, lv));
  1148. }
  1149. #endregion
  1150. }
  1151. }