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. namespace XmdsCommonSkill.Plugin.Skills
  24. {
  25. /// <summary>
  26. /// FileName: XmdsSkillBase.cs
  27. /// Author: Alex.Yu
  28. /// Corporation:...
  29. /// Description:
  30. /// DateTime: 2015/6/25 9:32:33
  31. /// </summary>
  32. #region 战斗数据.
  33. public class BattleParams
  34. {
  35. private static readonly ObjectPool<BattleParams> s_ListPool = new ObjectPool<BattleParams>(s_ListPool_OnCreate);
  36. private XmdsVirtual mAttacker;
  37. private XmdsVirtual mHitter;
  38. private AttackSource mSource;
  39. private GameSkill mGameSkill;
  40. private XmdsAttackProperties mProp;
  41. private XmdsVirtual.AtkResult mAtkResult;
  42. #region 计算结果.
  43. private int mThreatValue; //仇恨值
  44. private int mSkillDamagePer; //技能伤害百分百
  45. private int mSkillDamageModify; //技能伤害修改
  46. private int mFinalCritRate; //最终暴击率
  47. private int mFinalDamage; //最终伤害
  48. private int mHitAdd; //命中增加
  49. private int mCritAdd; //暴击增加
  50. private int mDamageModifyAdd; //伤害绝对值增加
  51. private int mSkillDamageAdd; //技能伤害增加
  52. private int mHitResult; //打击结果
  53. private int mHitDamge; //打击伤害
  54. private DamageType mDamageType = DamageType.Damage;
  55. #endregion
  56. private BattleParams() { }
  57. public static BattleParams AllocAutoRelease()
  58. {
  59. BattleParams ret = s_ListPool.Get();
  60. ret.ReSet();
  61. return ret;
  62. }
  63. private static BattleParams s_ListPool_OnCreate()
  64. {
  65. return new BattleParams();
  66. }
  67. public void ReSet()
  68. {
  69. // this.mHitUnits.Clear();
  70. }
  71. public void Dispose()
  72. {
  73. OnDispose();
  74. s_ListPool.Release(this);
  75. }
  76. private void OnDispose()
  77. {
  78. mAttacker = null;
  79. mHitter = null;
  80. mSource = null;
  81. mGameSkill = null;
  82. mProp = null;
  83. mThreatValue = 0;
  84. mSkillDamagePer = 0;
  85. mSkillDamageModify = 0;
  86. mFinalCritRate = 0;
  87. mFinalDamage = 0;
  88. mHitAdd = 0;
  89. mCritAdd = 0;
  90. mDamageModifyAdd = 0;
  91. mSkillDamageAdd = 0;
  92. mHitDamge = 0;
  93. mHitResult = 0;
  94. mDamageType = DamageType.Damage;
  95. }
  96. /// <summary>
  97. /// 攻击者.
  98. /// </summary>
  99. public XmdsVirtual Attacker
  100. {
  101. set { mAttacker = value; }
  102. get { return mAttacker; }
  103. }
  104. /// <summary>
  105. /// 被攻击者.
  106. /// </summary>
  107. public XmdsVirtual Hitter { get { return mHitter;} set { mHitter = value;} }
  108. /// <summary>
  109. /// 攻击源信息.
  110. /// </summary>
  111. public AttackSource Source {
  112. get {return mSource;}
  113. set
  114. {
  115. mSource = value;
  116. mProp = (mSource.Attack.Properties as XmdsAttackProperties);
  117. }
  118. }
  119. /// <summary>
  120. /// 攻击信息.
  121. /// </summary>
  122. public XmdsAttackProperties AtkProp { get { return mProp; }}
  123. public XmdsVirtual.AtkResult AtkResult
  124. {
  125. get { return mAtkResult; }
  126. set { mAtkResult = value; }
  127. }
  128. /// <summary>
  129. /// 技能信息.
  130. /// </summary>
  131. public GameSkill GameSkill { get{return mGameSkill;} set { mGameSkill = value; } }
  132. /// <summary>
  133. /// 技能伤害百分比.
  134. /// </summary>
  135. public int SkillDamagePer { get { return mSkillDamagePer; } set{ mSkillDamagePer = value;} }
  136. /// <summary>
  137. /// 技能伤害绝对值.
  138. /// </summary>
  139. public int SkillDamageModify { get { return mSkillDamageModify; } set { mSkillDamageModify = value; } }
  140. /// <summary>
  141. /// 最终技能伤害.
  142. /// </summary>
  143. public int FinalSkillDamage { get { return mFinalDamage; } set { mFinalDamage = value; } }
  144. /// <summary>
  145. /// 最终暴击.
  146. /// </summary>
  147. public int FinalCritRate { get { return mFinalCritRate; } set { mFinalCritRate = value; } }
  148. /// <summary>
  149. /// 威胁值.
  150. /// </summary>
  151. public int ThreatValue { get { return mThreatValue; } set { mThreatValue = value; } }
  152. /// <summary>
  153. /// 暴击增加.
  154. /// </summary>
  155. public int CritAdd { get { return mCritAdd; } set { mCritAdd = value; } }
  156. /// <summary>
  157. /// 命中增加.
  158. /// </summary>
  159. public int HitAdd { get { return mHitAdd; } set { mHitAdd = value; } }
  160. /// <summary>
  161. /// 伤害绝对值增加.
  162. /// </summary>
  163. public int DamageModifyAdd { get { return mDamageModifyAdd; } set { mDamageModifyAdd = value; } }
  164. /// <summary>
  165. /// 使用计算公式类型.
  166. /// </summary>
  167. public DamageType UseDamageType { get { return mDamageType; } set { mDamageType = value; } }
  168. /// <summary>
  169. /// 技能伤害增加. 技能伤害固定值
  170. /// </summary>
  171. public int SkillDamageAdd { get { return mSkillDamageAdd; } set { mSkillDamageAdd = value; } }
  172. /// <summary>
  173. /// Hit结果,(伤害计算计算BUFF或其他异常状态作用最终效果.)
  174. /// </summary>
  175. public int HitResult { get { return mHitResult; } set { mHitResult = value; } }
  176. /// <summary>
  177. /// 打击伤害(FinalDamage经过暴击计算的值.)
  178. /// </summary>
  179. public int HitDamge { get { return mHitDamge; } set { mHitDamge = value; } }
  180. }
  181. #endregion
  182. public abstract class XmdsSkillBase : UnitSkill
  183. {
  184. /// <summary>
  185. /// 技能CD.
  186. /// </summary>
  187. protected static HashMap<int, XmdsSkillValue> mSkillCD = new HashMap<int, XmdsSkillValue>();
  188. /// <summary>
  189. /// 技能是否能自动释放.
  190. /// </summary>
  191. protected static HashMap<int, bool> mSkillCanAuto = new HashMap<int, bool>();
  192. #region 回调事件.
  193. public delegate void ScriptHandler(BattleParams param);
  194. public delegate bool ScriptHandler_Bool(BattleParams param);
  195. /// <summary>
  196. /// 计算闪避回调.
  197. /// </summary>
  198. protected ScriptHandler event_CalHitRateAdd;
  199. /// <summary>
  200. /// 计算暴击回调.
  201. /// </summary>
  202. protected ScriptHandler event_CalCritRateAdd;
  203. /// <summary>
  204. /// 计算技能伤害.
  205. /// </summary>
  206. protected ScriptHandler event_SkillDamagePer;
  207. /// <summary>
  208. /// 计算技能绝对值.
  209. /// </summary>
  210. protected ScriptHandler event_SkillDamageModify;
  211. /// <summary>
  212. /// 获取技能攻击类型(物理、魔法)
  213. /// </summary>
  214. protected ScriptHandler event_GetAttackType;
  215. /// <summary>
  216. /// 计算技能仇恨.
  217. /// </summary>
  218. protected ScriptHandler event_SkillThreatValue;
  219. /// <summary>
  220. /// 计算技能逻辑.
  221. /// </summary>
  222. protected ScriptHandler event_SkillLogic;
  223. /// <summary>
  224. /// 技能附加伤害加成.
  225. /// </summary>
  226. protected ScriptHandler event_DamageModifyAdd;
  227. /// <summary>
  228. /// 是否走伤害流程.
  229. /// </summary>
  230. protected ScriptHandler event_UseDamageType;
  231. /// <summary>
  232. /// 总技能伤害加成.
  233. /// </summary>
  234. protected ScriptHandler event_SkillDamageAdd;
  235. /// <summary>
  236. /// 计算伤害之后的技能逻辑回调.
  237. /// </summary>
  238. protected ScriptHandler event_SkillLogicAfterCalDamage;
  239. /// <summary>
  240. /// 计算最终伤害修改
  241. /// </summary>
  242. protected ScriptHandler_Bool event_SkillFinalDamageModify;
  243. /// <summary>
  244. /// 计算招架结果类型
  245. /// </summary>
  246. protected ScriptHandler event_SkillAtkRtl;
  247. //技能破定值
  248. protected int mSkillBreakShieldValue;
  249. #endregion
  250. protected enum EventType : int
  251. {
  252. HitRateAdd = 1, //命中增加
  253. CritRateAdd = 2, //暴击几率增加
  254. DamagePer = 3, //--技能伤害
  255. DamageModify = 4, //--伤害修改
  256. AttackType = 5, //--攻击类型
  257. ThreadValue = 6, //--仇恨值
  258. SkillLogic = 7, //--技能逻辑
  259. DamageModifyAdd = 8, //附加伤害
  260. UseFormluaType = 9, //走伤害流程
  261. SkillDamageAdd = 10, //技能伤害加成
  262. SkillLogicAftercalDamage = 11, //伤害计算之后逻辑回调
  263. SkillFinalDamageModify = 12, //技能最终伤害修改
  264. GetCalAtkRlt = 13, //获得招架结果
  265. }
  266. protected void RegistEvent(EventType type, ScriptHandler callBack)
  267. {
  268. switch (type)
  269. {
  270. case EventType.AttackType:
  271. event_GetAttackType = callBack;
  272. break;
  273. case EventType.CritRateAdd:
  274. event_CalCritRateAdd = callBack;
  275. break;
  276. case EventType.HitRateAdd:
  277. event_CalHitRateAdd = callBack;
  278. break;
  279. case EventType.DamagePer:
  280. event_SkillDamagePer = callBack;
  281. break;
  282. case EventType.DamageModify:
  283. event_SkillDamageModify = callBack;
  284. break;
  285. case EventType.ThreadValue:
  286. event_SkillThreatValue = callBack;
  287. break;
  288. case EventType.SkillLogic:
  289. event_SkillLogic = callBack;
  290. break;
  291. case EventType.DamageModifyAdd:
  292. event_DamageModifyAdd = callBack;
  293. break;
  294. case EventType.UseFormluaType:
  295. event_UseDamageType = callBack;
  296. break;
  297. case EventType.SkillDamageAdd:
  298. event_SkillDamageAdd = callBack;
  299. break;
  300. case EventType.SkillLogicAftercalDamage:
  301. event_SkillLogicAfterCalDamage = callBack;
  302. break;
  303. case EventType.GetCalAtkRlt:
  304. event_SkillAtkRtl = callBack;
  305. break;
  306. default: break;
  307. }
  308. }
  309. protected void RegistEvent_Bool(EventType type, ScriptHandler_Bool callBack)
  310. {
  311. switch (type)
  312. {
  313. case EventType.SkillFinalDamageModify:
  314. event_SkillFinalDamageModify = callBack;
  315. break;
  316. default: break;
  317. }
  318. }
  319. public override int SkillID
  320. {
  321. get { return -1; }
  322. }
  323. protected override void OnBaseInit(GameSkill info, XmdsVirtual unit, ref SkillTemplate template)
  324. {
  325. //技能CD由配置表控制.
  326. template.CoolDownMS = this.GetTargetFormulaValue(info.SkillLevel, this.GetSkillCD(info.SkillID));
  327. //控制是否能自动施放.
  328. if (unit != null && unit.mUnit.IsPlayer && !this.IsCanAuto(info.SkillID))
  329. {
  330. info.AutoLaunch = false;
  331. }
  332. else if(info.SkillID != XmdsComSrvData.BOSS_CARD_SKILLID)
  333. {
  334. info.AutoLaunch = true;
  335. }
  336. OnInitConfig();
  337. OnInit(info, unit, ref template);
  338. this.mSkillBreakShieldValue = XmdsGlobalData.GetSkillBreakShieldValue(info.SkillID);
  339. }
  340. /// <summary>
  341. /// 初始化回调,用于子类重铸.
  342. /// </summary>
  343. /// <param name="info"></param>
  344. /// <param name="unit"></param>
  345. /// <param name="template"></param>
  346. protected virtual void OnInit(GameSkill info, XmdsVirtual unit, ref SkillTemplate template)
  347. {
  348. }
  349. /** 敌伤害,友治疗,自动获取伤害类型 */
  350. protected CommonAI.Data.DamageType AutoGetDamageType(BattleParams param, CommonAI.Data.DamageType alliesDamageType = CommonAI.Data.DamageType.Heal)
  351. {
  352. if(param.Attacker.GetCurPKMode() == PKMode.All)
  353. {
  354. return (param.Attacker == param.Hitter) ? alliesDamageType : CommonAI.Data.DamageType.Damage;
  355. }
  356. else if (param.Attacker.IsAllies(param.Hitter, true, true))
  357. {
  358. //和平模式下,只有队友才有加血
  359. return alliesDamageType;
  360. }
  361. else if (param.Attacker.GetCurPKMode() == PKMode.Peace && param.Hitter.IsPlayerUnit())
  362. {
  363. //和平模式下,非队友,无伤害
  364. return CommonAI.Data.DamageType.None;
  365. }
  366. return (param.Attacker == param.Hitter) ? alliesDamageType : CommonAI.Data.DamageType.Damage;
  367. }
  368. public override bool OnCallDamageProcess(XmdsVirtual attacker, XmdsVirtual hitter, AttackSource source, GameSkill gs, ref XmdsVirtual.AtkResult result, ref int damage)
  369. {
  370. BattleParams param = BattleParams.AllocAutoRelease();
  371. try
  372. { //param.AttackRlt = result.rlt;
  373. param.Attacker = attacker;
  374. param.Hitter = hitter;
  375. param.Source = source;
  376. param.GameSkill = gs;
  377. param.AtkResult = result;
  378. try
  379. {
  380. param = OnDoSkillHitProcess(ref param);
  381. }
  382. catch (Exception error)
  383. {
  384. LogError(string.Format("skill {0} attackUID:{1}, HitterUID: {2}, SceneID:{3} SceneUID:{4} OnCallDamageProcess error:{5} - {6}",
  385. gs.SkillID, (attacker == null ? "anull" : attacker.mUnit.PlayerUUID), (hitter == null ? "hnull" : hitter.mUnit.PlayerUUID),
  386. (attacker == null ? -1 : attacker.mUnit.Parent.GetSceneID()), (attacker == null ? "snull" : attacker.mUnit.Parent.UUID), error.ToString(), error.StackTrace));
  387. }
  388. damage = param.HitResult;
  389. //System.Console.WriteLine("伤害:" + attacker.mUnit.ID + ", 伤害:" + damage);
  390. //仇恨系数.
  391. //result.ThreatValue = param.ThreatValue;
  392. }
  393. finally
  394. {
  395. param.Dispose();
  396. }
  397. result.breakShieldValue = CUtils.CastInt(this.mSkillBreakShieldValue * (1.0f + XmdsUnitProp.PER * attacker.MirrorProp.BreakShieldValue));
  398. return true;
  399. }
  400. #region 工具API.
  401. public virtual int GetTargetFormulaValue(int lv, int[] formula)
  402. {
  403. return XmdsBattleHelper.GetTargetFormulaValue(lv, formula, SkillID);
  404. }
  405. public virtual int GetTargetFormulaValue(int lv, XmdsSkillValue formula)
  406. {
  407. return formula.GetValue(lv);
  408. }
  409. public override int GetSkillValue(AbstractSkillType type) { return 0; }
  410. //public virtual int GetTargetValue(int lv, XmdsSkillValue value)
  411. //{
  412. // bool invaild = false;
  413. // int ret = value.GetValue(lv, out invaild);
  414. // if (invaild)
  415. // {
  416. // LogError(SkillID, lv);
  417. // }
  418. // return ret;
  419. //}
  420. private void LogError(int skill, int lv)
  421. {
  422. XmdsBattleHelper.LogError(string.Format("XmdsSkillBase get Value Error:skill id = {0} lv = {1}", skill, lv));
  423. }
  424. /// <summary>
  425. /// 算基础伤害.
  426. /// </summary>
  427. /// <param name="baseValue"></param>
  428. /// <param name="up"></param>
  429. /// <param name="lv"></param>
  430. /// <returns></returns>
  431. public virtual int CalDamagePer(int baseValue, int lv)
  432. {
  433. //return (lv - 1) + baseValue;
  434. return baseValue;
  435. }
  436. public virtual int CalDamagePer(XmdsSkillValue baseValue, int lv)
  437. {
  438. //return (lv - 1) + baseValue.GetValue(lv); ;
  439. return baseValue.GetValue(lv); ;
  440. }
  441. public virtual int GetThreatValue(int formulaID1, int formulaID2)
  442. {
  443. return 0;
  444. }
  445. #endregion
  446. #region 常态注册.
  447. protected override void OnRegistEvent()
  448. {
  449. RegistEvents();
  450. }
  451. private void RegistEvents()
  452. {
  453. this.RegistEvent(EventType.DamagePer, OnSkillDamagePerEvent);
  454. this.RegistEvent(EventType.DamageModify, OnskillDamageModifyEvent);
  455. this.RegistEvent(EventType.AttackType, OnAttackTypeEvent);
  456. this.RegistEvent(EventType.ThreadValue, OnThreatValueEvent);
  457. this.RegistEvent(EventType.SkillLogic, OnSkillLogicEvent);
  458. this.RegistEvent_Bool(EventType.SkillFinalDamageModify, OnSkillFinalDamageModifyEvent);
  459. this.RegistEvent(EventType.GetCalAtkRlt, OnGetCalAtkRlt);
  460. this.RegistEvent(EventType.SkillLogicAftercalDamage, OnSkillLogicAftercalDamage);
  461. }
  462. /// <summary>
  463. /// 得到仇恨.
  464. /// </summary>
  465. /// <param name="param"></param>
  466. protected virtual void OnThreatValueEvent(BattleParams param)
  467. {
  468. param.ThreatValue = 0;
  469. }
  470. /// <summary>
  471. /// 得到技能百分比.
  472. /// </summary>
  473. /// <param name="param"></param>
  474. protected virtual void OnSkillDamagePerEvent(BattleParams param)
  475. {
  476. }
  477. /// <summary>
  478. /// 得到技能伤害绝对值.
  479. /// </summary>
  480. /// <param name="param"></param>
  481. protected virtual void OnskillDamageModifyEvent(BattleParams param)
  482. {
  483. }
  484. /// <summary>
  485. /// 得到技能伤害类型.
  486. /// </summary>
  487. /// <param name="param"></param>
  488. protected virtual void OnAttackTypeEvent(BattleParams param)
  489. {
  490. }
  491. /// <summary>
  492. /// 技能特殊逻辑.
  493. /// </summary>
  494. /// <param name="param"></param>
  495. protected virtual void OnSkillLogicEvent(BattleParams param)
  496. {
  497. }
  498. protected virtual void OnSkillLogicAftercalDamage(BattleParams param)
  499. {
  500. }
  501. /// <summary>
  502. /// 技能固定伤害.(最终值)
  503. /// reture不执行具体伤害逻辑计算,直接使用给定的伤害值
  504. /// <param name="param"></param>
  505. protected virtual bool OnSkillFinalDamageModifyEvent(BattleParams param)
  506. {
  507. return false;
  508. }
  509. /// <summary>
  510. /// 获得招架结果类型
  511. /// </summary>
  512. /// <param name="param"></param>
  513. protected virtual void OnGetCalAtkRlt(BattleParams param)
  514. {
  515. }
  516. #endregion
  517. private void OnDispose()
  518. {
  519. event_CalHitRateAdd = null;
  520. event_CalCritRateAdd = null;
  521. event_SkillDamagePer = null;
  522. event_SkillDamageModify = null;
  523. event_GetAttackType = null;
  524. event_SkillThreatValue = null;
  525. event_SkillLogic = null;
  526. event_SkillDamageAdd = null;
  527. event_SkillLogicAfterCalDamage = null;
  528. event_SkillFinalDamageModify = null;
  529. event_UseDamageType = null;
  530. event_DamageModifyAdd = null;
  531. }
  532. #region 新计算流程.
  533. protected BattleParams OnDoSkillHitProcess(ref BattleParams param)
  534. {
  535. OnCalAtkRlt(param);
  536. //获得伤害类型.
  537. OnAttackType(param);
  538. //是否使用伤害公式.
  539. OnUseDamageFormula(param);
  540. //获得技能伤害百分比.
  541. OnGetSkillDamagePer(param);
  542. //获得技能固定伤害.
  543. OnGetSkillDamageModify(param);
  544. //获得技能仇恨系数.
  545. OnGetSkillThreatValue(param);
  546. //技能逻辑调用.
  547. OnGetSkillLogic(param);
  548. //绝对伤害和计算伤害,只走一个
  549. if (!OnSkillFinalDamageModify(param))
  550. {
  551. switch (param.UseDamageType)
  552. {
  553. case CommonAI.Data.DamageType.Damage:
  554. OnGetDamage(param);
  555. break;
  556. case CommonAI.Data.DamageType.Heal:
  557. OnGetHeal(param);
  558. break;
  559. case CommonAI.Data.DamageType.None:
  560. param.FinalSkillDamage = 0;
  561. break;
  562. default: break;
  563. }
  564. //计算暴击效果.
  565. OnGetHitDamage(param);
  566. }
  567. OnDispatchEvent(param);
  568. //计算伤害之后的回调.
  569. OnGetSkillLogicAfterCalDamage(param);
  570. //处理吸血效果
  571. if (param.UseDamageType == CommonAI.Data.DamageType.Damage && param.HitResult > 0)
  572. {
  573. ProcessAtkLeech(param);
  574. }
  575. return param;
  576. }
  577. #region 攻击逻辑结果计算.
  578. /// <summary>
  579. /// 计算攻击结果,闪避,暴击,命中.
  580. /// </summary>
  581. /// <param name="param"></param>
  582. private void OnCalAtkRlt(BattleParams param)
  583. {
  584. //外部已经赋值了, 就不需要再计算了
  585. if (param.Source.OutClientState != (byte)XmdsVirtual.UnitHitEventState.Normal)
  586. {
  587. return;
  588. }
  589. XmdsVirtual attacker = param.Attacker;
  590. XmdsVirtual hitter = param.Hitter;
  591. AttackSource atksource = param.Source;
  592. if (atksource.FromExpectTarget == SkillTemplate.CastTarget.Alias ||
  593. atksource.FromExpectTarget == SkillTemplate.CastTarget.AlliesExcludeSelf ||
  594. atksource.FromExpectTarget == SkillTemplate.CastTarget.AlliesIncludeSelf ||
  595. atksource.FromExpectTarget == SkillTemplate.CastTarget.PetForMaster ||
  596. attacker.GetPlayerUUID() == hitter.GetPlayerUUID())
  597. {
  598. //param.Source.OutClientState = (byte)XmdsVirtual.UnitHitEventState.Normal;
  599. if (this.IsHealCritAttack(param))
  600. {
  601. param.Source.OutClientState = (byte)XmdsVirtual.UnitHitEventState.Crit;
  602. }
  603. else
  604. {
  605. param.Source.OutClientState = (byte)XmdsVirtual.UnitHitEventState.Normal;
  606. }
  607. }
  608. else
  609. {
  610. if (IsKillMonsterCrit(param))
  611. {
  612. param.Source.OutClientState = (byte)XmdsVirtual.UnitHitEventState.KillMonsterCrit;
  613. //log.Info("斩妖暴击:" + attacker.mInfo.Name + ", " + hitter.mInfo.Name);
  614. }
  615. else
  616. {
  617. if (this.IsCritAttack(param))
  618. {
  619. param.Source.OutClientState = (byte)XmdsVirtual.UnitHitEventState.Crit;
  620. }
  621. else
  622. {
  623. param.Source.OutClientState = (byte)XmdsVirtual.UnitHitEventState.Normal;
  624. }
  625. }
  626. }
  627. //二次计算一下招架结果
  628. if (event_SkillAtkRtl != null)
  629. {
  630. event_SkillAtkRtl.Invoke(param);
  631. }
  632. }
  633. #region 是否斩妖的特殊暴击
  634. private bool IsKillMonsterCrit(BattleParams param)
  635. {
  636. XmdsInstancePlayer attacker = param.Attacker.mUnit as XmdsInstancePlayer;
  637. XmdsInstanceMonster hitter = param.Hitter.mUnit as XmdsInstanceMonster;
  638. int yaoQiLevel = param.Attacker.MirrorProp.YaoQiLevel;
  639. if (attacker != null && hitter != null && yaoQiLevel > 0)
  640. {
  641. HateSystem.HateInfo hateInfo = param.Hitter.mHateSystem.getHateInfo(param.Attacker.mUnit.ID);
  642. if (hateInfo != null && XmdsDataMgr.GetInstance().IsZhanYaoCrit(attacker, param.Hitter.mUnit.Level, yaoQiLevel,
  643. ++hateInfo.hitNums, ref param.Source.OutClientStateExt))
  644. {
  645. hateInfo.hitNums = 0;
  646. return true;
  647. }
  648. }
  649. return false;
  650. }
  651. #endregion
  652. #region 是否暴击.
  653. private bool IsCritAttack(BattleParams param)
  654. {
  655. XmdsVirtual attacker = param.Attacker;
  656. XmdsVirtual hitter = param.Hitter;
  657. OnFinalCritHandler(param);
  658. //如果为普攻,并且下次普攻概率不为0,走这个概率
  659. if(param.GameSkill.SkillType == XmdsSkillType.normalAtk && param.Attacker.MirrorProp.NormalAtkCriteRate > 0)
  660. {
  661. return XmdsDamageCalculator.IsInRandomRange(param.Attacker.MirrorProp.NormalAtkCriteRate, attacker.mUnit.RandomN, (int)XmdsDamageCalculator.PERER);
  662. }
  663. else
  664. {
  665. int critRate = attacker.MirrorProp.CritRate;
  666. if (attacker.IsPlayerUnit() && hitter.IsBoss())
  667. {
  668. critRate += attacker.MirrorProp.ToBossCritRate;
  669. }
  670. int finalCriteRate = critRate + param.CritAdd - hitter.MirrorProp.ResCritRate;
  671. param.FinalCritRate = finalCriteRate;
  672. return XmdsDamageCalculator.IsInRandomRange(finalCriteRate, attacker.mUnit.RandomN, (int)XmdsDamageCalculator.PERER);
  673. }
  674. }
  675. private bool IsHealCritAttack(BattleParams param)
  676. {
  677. /*
  678. 施法者的治疗暴击率 = 治疗暴击系数 * 施法者暴击 /(施法者暴击 + 施法者等级 * 100) +施法者.暴击率 + 被治疗者.受到治疗暴击率
  679. wuyonghui(吴永辉) 07-25 14:56:26
  680. 最后个属性目前还没有,以后会有 (指的是“被治疗者.受到治疗暴击率”)
  681. */
  682. XmdsVirtual attacker = param.Attacker;
  683. float critRate = attacker.MirrorProp.CritRate * XmdsUnitProp.PER;
  684. OnFinalCritHandler(param);
  685. var finalCriteRate = (int)critRate + param.CritAdd;
  686. param.FinalCritRate = finalCriteRate;
  687. return XmdsDamageCalculator.IsInRandomRange(finalCriteRate, attacker.mUnit.RandomN, (int)XmdsDamageCalculator.PERER);
  688. }
  689. private void OnFinalCritHandler(BattleParams param)
  690. {
  691. if (event_CalCritRateAdd != null)
  692. {
  693. event_CalCritRateAdd.Invoke(param);
  694. }
  695. }
  696. #endregion
  697. #endregion
  698. #region 技能攻击效果(逻辑、伤害).
  699. private void OnGetSkillDamagePer(BattleParams param)
  700. {
  701. if (event_SkillDamagePer != null)
  702. {
  703. event_SkillDamagePer.Invoke(param);
  704. }
  705. }
  706. private void OnGetSkillDamageModify(BattleParams param)
  707. {
  708. if (event_SkillDamageModify != null)
  709. {
  710. event_SkillDamageModify.Invoke(param);
  711. }
  712. }
  713. private void OnGetSkillThreatValue(BattleParams param)
  714. {
  715. if (event_SkillThreatValue != null)
  716. {
  717. event_SkillThreatValue.Invoke(param);
  718. }
  719. }
  720. private void OnAttackType(BattleParams param)
  721. {
  722. if (event_GetAttackType != null)
  723. {
  724. event_GetAttackType.Invoke(param);
  725. }
  726. }
  727. private void OnGetSkillLogic(BattleParams param)
  728. {
  729. if (event_SkillLogic != null)
  730. {
  731. event_SkillLogic.Invoke(param);
  732. }
  733. }
  734. protected virtual void OnGetSkillLogicAfterCalDamage(BattleParams param)
  735. {
  736. if (event_SkillLogicAfterCalDamage != null)
  737. {
  738. event_SkillLogicAfterCalDamage.Invoke(param);
  739. }
  740. }
  741. //技能最终伤害调整
  742. private bool OnSkillFinalDamageModify(BattleParams param)
  743. {
  744. if (event_SkillFinalDamageModify != null)
  745. {
  746. return event_SkillFinalDamageModify.Invoke(param);
  747. }
  748. return false;
  749. }
  750. private void OnGetSkillDamageAdd(BattleParams param)
  751. {
  752. if (event_SkillDamageAdd != null)
  753. {
  754. event_SkillDamageAdd.Invoke(param);
  755. }
  756. }
  757. protected void OnGetDamage(BattleParams param)
  758. {
  759. XmdsVirtual attacker = param.Attacker;
  760. XmdsVirtual hitter = param.Hitter;
  761. OnGetDamageModifyAdd(param);
  762. int attackTemp = attacker.MirrorProp.GetFinalAttack(param.Hitter.mUnit.IsMonster);
  763. //计算面板物攻和技能加成效果.
  764. int attack = XmdsDamageCalculator.GetSkillDamage(attackTemp, param.SkillDamagePer, param.SkillDamageModify + param.DamageModifyAdd);
  765. if(attack <= 1 && attackTemp > 10)
  766. {
  767. string stackInfo = new StackTrace().ToString();
  768. int spellID = (param.Source != null && param.Source.FromSpell != null) ? param.Source.FromSpell.ID : 0;
  769. XmdsVirtual.FormatLog(LoggerLevel.ERROR, "攻击异常 : {0}, {1}, {2}, {3}, {4}, {5}, {6}", attackTemp, attack,
  770. param.SkillDamagePer, param.SkillDamageModify, param.DamageModifyAdd, spellID, 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. }