XmdsSkillBase.cs 43 KB

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