XmdsVirtual.Skills.cs 44 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857
  1. using CommonAI.data;
  2. using CommonAI.Data;
  3. using CommonAI.Zone;
  4. using CommonAI.Zone.Helper;
  5. using CommonAI.Zone.Instance;
  6. using CommonAI.ZoneClient;
  7. using CommonAI.ZoneServer.JSGModule;
  8. using CommonLang;
  9. using System;
  10. using System.Collections.Generic;
  11. using System.Linq;
  12. using System.Text;
  13. using XmdsCommon.EditorData;
  14. using XmdsCommon.JSGModule.Interface;
  15. using XmdsCommon.Plugin;
  16. using XmdsCommonServer.Message;
  17. using XmdsCommonServer.Plugin.Base;
  18. using XmdsCommonServer.Plugin.Units;
  19. using XmdsCommonServer.Plugin.XmdsSkillTemplate;
  20. using XmdsCommonServer.Plugin.XmdsSkillTemplate.DamageCalculator;
  21. using XmdsCommonServer.Plugin.XmdsSkillTemplate.Skills;
  22. using XmdsCommonServer.XLS.Data;
  23. using XmdsCommonSkill.Plugin.CardSkill;
  24. using static CommonAI.Zone.Instance.InstanceUnit;
  25. namespace XmdsCommonServer.Plugin
  26. {
  27. /// <summary>
  28. /// FileName: XmdsVirtual.cs
  29. /// Author: Alex.Yu
  30. /// Corporation:...
  31. /// Description:
  32. /// DateTime: 2015/5/12 10:20:46
  33. /// </summary>
  34. public partial class XmdsVirtual
  35. {
  36. //技能初始化辅助类.
  37. protected XmdsSkillHelper mSkillHelper = null;
  38. /// <summary>
  39. /// 初始化技能辅助类.
  40. /// </summary>
  41. public XmdsSkillHelper SkillHelper { get { return mSkillHelper; } }
  42. //卡牌技能类
  43. private IJSCardSkillModule mCardModule;
  44. //玩家本地缓存数据
  45. private IPlayerCache mPlayerCache;
  46. public IJSCardSkillModule CardModule { get { return mCardModule; } }
  47. private HashMap<int, BuffTemplate> mTrySendBuff = new HashMap<int, BuffTemplate>();
  48. private HashMap<int, SpellTemplate> mTrySendSpell = new HashMap<int, SpellTemplate>();
  49. private HashMap<int, SpellTemplate> mLaunchSpellOver = new HashMap<int, SpellTemplate>();
  50. //扩展字段
  51. //法师:标记剑影是否强化过
  52. public int extValue = 0;
  53. #region 技能相关.
  54. private void ReGetUnitSkills(List<GameSkill> ls, List<GameSkill> retList)
  55. {
  56. GameSkill gs = null;
  57. for (int i = ls.Count - 1; i >= 0; i--)
  58. {
  59. gs = ls[i];
  60. if (gs.SkillID == 0)
  61. {
  62. ls.RemoveAt(i);
  63. }
  64. else if (this.IsPlayerUnit() || getSkillType(ref gs))//玩家的技能来自游戏服,不管表格类型
  65. {
  66. retList.Add(gs);
  67. }
  68. }
  69. }
  70. private void CreateCreateCardModule()
  71. {
  72. if (this.mCardModule == null)
  73. {
  74. if (this.mUnit.IsPlayer)
  75. {
  76. this.mCardModule = XmdsGlobalData.GetPlayerCardModule(this);
  77. }
  78. else if (this.mUnit.IsMonster && this.IsBoss())
  79. {
  80. this.mCardModule = new JSGMonsterCardModule(this);
  81. }
  82. else
  83. {
  84. this.mCardModule = new JSGOtherCardModule();
  85. }
  86. }
  87. }
  88. public void InitCardModule()
  89. {
  90. this.mCardModule.Init(this);
  91. if(this.mUnit.VisibleInfo != null)
  92. {
  93. this.mUnit.VisibleInfo.setVisibleCardData(this.mCardModule.GetCardInterface());
  94. }
  95. }
  96. protected void checkSkillData(XmdsUnitData data)
  97. {
  98. //过滤data 防止无效的gameSkill.
  99. List<GameSkill> retList = new List<GameSkill>();
  100. // 常规技能
  101. if (data.Skills != null && data.Skills.UnitSkills != null)
  102. {
  103. this.ReGetUnitSkills(data.Skills.UnitSkills, retList);
  104. }
  105. // 卡牌技能
  106. if(data.CardSkills != null && data.CardSkills.UnitSkills != null)
  107. {
  108. this.ReGetUnitSkills(data.CardSkills.UnitSkills, retList);
  109. }
  110. #region Mock数据.
  111. GameSkill gs = null;
  112. //如果为空判断为编辑器环境,走MOCK数据.
  113. //if (data.Skills == null || data.Skills.UnitSkills == null || data.Skills.UnitSkills.Count == 0)
  114. {
  115. //单位普攻.
  116. if (mInfo.BaseSkillID != null && mInfo.BaseSkillID.SkillID != 0)
  117. {
  118. gs = new GameSkill();
  119. gs.SkillID = this.mInfo.BaseSkillID.SkillID;
  120. gs.SkillType = XmdsSkillType.normalAtk;
  121. gs.SkillLevel = 1;
  122. retList.Add(gs);
  123. }
  124. //单位技能.
  125. for (int i = 0; i < this.mInfo.Skills.Count; i++)
  126. {
  127. gs = new GameSkill();
  128. gs.SkillID = this.mInfo.Skills[i].SkillID;
  129. gs.SkillLevel = 1;
  130. if (getSkillType(ref gs))
  131. {
  132. retList.Add(gs);
  133. }
  134. }
  135. if (data.Skills == null)
  136. {
  137. XmdsUnitSkillInfo info = new XmdsUnitSkillInfo();
  138. info.UnitSkills = retList;
  139. data.Skills = info;
  140. }
  141. else
  142. {
  143. data.Skills.UnitSkills = retList;
  144. }
  145. }
  146. #endregion
  147. if (mSkillHelper == null)
  148. {
  149. mSkillHelper = new XmdsSkillHelper();
  150. }
  151. }
  152. private bool getSkillType(ref GameSkill gs)
  153. {
  154. XmdsSkillData skillData = XmdsDataMgr.GetInstance().GetXmdsSkillData(gs.SkillID);
  155. if (skillData != null && skillData.SkillType > 0)
  156. {
  157. gs.SkillType = (XmdsSkillType)skillData.SkillType;
  158. return true;
  159. }
  160. else
  161. {
  162. SkillTemplate st = XmdsBattleSkill.GetSkillTemplate(gs.SkillID);
  163. if (st != null)
  164. {
  165. gs.SkillType = (st.Properties as XmdsSkillProperties).SkillType;
  166. return true;
  167. }
  168. else
  169. {
  170. log.Warn("checkSkillData 找不到单位:" + this.mUnit.Info.ID + ", 技能ID: " + gs.SkillID);
  171. }
  172. }
  173. return false;
  174. }
  175. //重新调用一下基础技能的initOver
  176. public bool ReInitOverBaseSkill(GameSkill info)
  177. {
  178. AbstractSkill baseSkill = this.SkillHelper.GetPlayerSkillById(this.SkillHelper.GetBaseSkillID());
  179. if (baseSkill == null)
  180. {
  181. log.Error("找不到单位基础技能:" + this.mUnit.PlayerUUID + ", 技能初始化:" + info.SkillID + ", 基础技能: " + this.SkillHelper.GetBaseSkillID());
  182. return false;
  183. }
  184. // 借用一下这个接口,懒得写新的了
  185. baseSkill.InitOver(this, info);
  186. return true;
  187. }
  188. //初始化技能.
  189. protected virtual void InitSkillInfo(XmdsUnitData data)
  190. {
  191. this.checkSkillData(data);
  192. mFinishSkillInit = true;
  193. mSkillHelper.InitSkill(data.Skills, this);
  194. }
  195. public bool ChangeSkill(int oldSkillID, int newSkillID, SkillLevelData skillData)
  196. {
  197. try
  198. {// 同技能只改表数值的话,无需重新init,赋值
  199. if (oldSkillID == newSkillID)
  200. {
  201. GameSkill gs = this.SkillHelper.GetGameSkill(newSkillID);
  202. if (gs == null)
  203. {
  204. log.Warn("相同技能替换,更新数值,技能不存在: " + newSkillID + ", " + this.mUnit.PlayerUUID);
  205. return false;
  206. }
  207. gs.SkillLevel = skillData.SkillLevel;
  208. gs.TalentSkillLevel1 = skillData.TalentSkillLevel1;
  209. gs.TalentSkillLevel2 = skillData.TalentSkillLevel2;
  210. gs.TalentSkillLevel3 = skillData.TalentSkillLevel3;
  211. if (gs.SkillType == XmdsSkillType.passive || gs.SkillType == XmdsSkillType.petGivePassive)
  212. {
  213. UnitPassiveSkill skill = this.mSkillHelper.GetPlayerSkillByIdExt(newSkillID);
  214. skill.SkillDataChange(gs, this);
  215. }
  216. else
  217. {
  218. UnitSkill skill = this.mSkillHelper.GetPlayerSkillById(newSkillID);
  219. skill.SkillDataChange(gs, this);
  220. }
  221. }
  222. else
  223. {
  224. GameSkill oldSkill = null;
  225. long skillCD = 0;
  226. if (oldSkillID > 0)
  227. {
  228. skillCD = this.GetSkillTimestampMS(oldSkillID);
  229. oldSkill = this.RemoveSkill(oldSkillID);
  230. }
  231. if (newSkillID > 0)
  232. {
  233. //激活指定技能.
  234. GameSkill gs = gs = new GameSkill();
  235. gs.SkillID = newSkillID;
  236. gs.SkillType = skillData.skillType;
  237. gs.SkillLevel = skillData.SkillLevel;
  238. gs.TalentSkillLevel1 = skillData.TalentSkillLevel1;
  239. gs.TalentSkillLevel2 = skillData.TalentSkillLevel2;
  240. gs.TalentSkillLevel3 = skillData.TalentSkillLevel3;
  241. gs.SkillTimestampMS = skillCD;
  242. gs.AutoLaunch = gs.SkillType != XmdsSkillType.cardSkill;
  243. if (gs.SkillType == XmdsSkillType.passive || gs.SkillType == XmdsSkillType.petGivePassive)
  244. {
  245. AbstractSkill skill = this.mSkillHelper.AddPassiveSkill(gs);
  246. }
  247. else
  248. {
  249. AbstractSkill skill = this.mSkillHelper.AddActiveSkill(gs, gs.SkillType == XmdsSkillType.normalAtk);
  250. if (gs.SkillType == XmdsSkillType.cardSkill && this.CardModule != null)
  251. {
  252. //this.CardModule.InitSkill
  253. }
  254. }
  255. //if (skillCD > 0)
  256. //{
  257. // SkillState skillState = this.SetSkillCD(newSkillID, skillCD);
  258. // if (skillState != null)
  259. // {
  260. // skillState.Reset();
  261. // }
  262. //}
  263. }
  264. }
  265. }
  266. catch (Exception e)
  267. {
  268. log.Warn("ChangeSkill catch: " + oldSkillID + ", " + newSkillID + ", " + e);
  269. }
  270. return true;
  271. }
  272. private void UpdateSkillHelper(int intervalMS, bool slowRefresh)
  273. {
  274. if (mSkillHelper != null)
  275. {
  276. mSkillHelper.Update(intervalMS, slowRefresh);
  277. }
  278. }
  279. #endregion
  280. public bool AllowAutoLaunch(int skillid)
  281. {
  282. bool ret = false;
  283. if (mSkillHelper != null)
  284. {
  285. var gs = mSkillHelper.GetGameSkill(skillid);
  286. if (gs != null)
  287. {
  288. ret = gs.AutoLaunch;
  289. }
  290. }
  291. return ret;
  292. }
  293. public bool TryLaunchSpell(LaunchSpell launch, ref SpellTemplate spell, out JSGCreateSpellData createData, ref float startX, ref float startY)
  294. {
  295. SpellTemplate redirect;
  296. if (mTrySendSpell.TryGetValue(spell.ID, out redirect))
  297. {
  298. spell = redirect;
  299. }
  300. DispatchTrySendSpellEvent(launch, ref spell, out createData, ref startX, ref startY);
  301. return true;
  302. }
  303. public bool TrySendBuff(ref BuffTemplate buff, XmdsVirtual target, out object tag)
  304. {
  305. //无敌中,负面BUFF无效.
  306. if (target.IsInvincible && buff.IsHarmful == true)
  307. {
  308. target.SendBattleHintNumberB2C(0, XmdsVirtual.UnitHitEventState.Immunity);
  309. tag = null;
  310. return false;
  311. }
  312. bool ret = true;
  313. tag = null;
  314. if (buff.IsHarmful == true)
  315. {
  316. //给别人施加debuff.
  317. this.OnHitOthter(target);
  318. }
  319. //无敌时不受负面BUFF影响.
  320. //if (target.mUnit.IsInvincible && buff.IsHarmful == true)
  321. //{
  322. // ret = false;
  323. //}
  324. if (ret == true)
  325. {
  326. //重定向buff.
  327. BuffTemplate redirect;
  328. if (mTrySendBuff.TryGetValue(buff.ID, out redirect))
  329. {
  330. buff = redirect;
  331. }
  332. var temp = buff.Properties as XmdsBuffProperties;
  333. List<XmdsBuffVirtual> list = temp.GetBuffVirtualList();
  334. //克隆BUFF能力.
  335. if (list != null && list.Count > 0)
  336. {
  337. List<XmdsBuffVirtual> cList = new List<XmdsBuffVirtual>();
  338. Type ctype = null;
  339. UnitBuff dst = null;
  340. UnitBuff src = null;
  341. for (int i = 0; i < list.Count; i++)
  342. {
  343. src = list[i] as UnitBuff;
  344. ctype = src.GetType();
  345. dst = CommonLang.Property.ReflectionUtil.CreateInstance(ctype) as UnitBuff;
  346. src.CopyTo(dst);
  347. cList.Add(dst);
  348. }
  349. tag = cList;
  350. }
  351. //判断能否添加.
  352. target.DispatchTryAddBuffEvent(ref buff, target, ref ret);
  353. }
  354. return ret;
  355. }
  356. public void SendAddBuffEvent(XmdsVirtual hitter, BuffTemplate buff)
  357. {
  358. //this.DispatchSendBuffEvent(buff, hitter);
  359. }
  360. public void RegistSendBuff(BuffTemplate buff)
  361. {
  362. //if(mTrySendBuff.ContainsKey(buff.ID))
  363. //{
  364. // FormatLog(CommonLang.Log.LoggerLevel.ERROR, "RegistSendBuff 重复利用buff : {0}, {1}", this.mInfo.Name, buff.ID);
  365. //}
  366. mTrySendBuff.Put(buff.ID, buff);
  367. }
  368. public void RegistSendSpell(SpellTemplate spell)
  369. {
  370. mTrySendSpell.Put(spell.ID, spell);
  371. }
  372. public BuffTemplate GetRegistBuff(int id)
  373. {
  374. BuffTemplate ret = null;
  375. if (mTrySendBuff.TryGetValue(id, out ret))
  376. {
  377. return ret;
  378. }
  379. return null;
  380. }
  381. public UnitBuff GetRegisBuffVirtual(int id, int index = 0)
  382. {
  383. if (index < 0) return null;
  384. UnitBuff ret = null;
  385. BuffTemplate bt = GetRegistBuff(id);
  386. XmdsBuffVirtual zbv = null;
  387. if (bt != null)
  388. {
  389. List<XmdsBuffVirtual> list = (bt.Properties as XmdsBuffProperties).GetBuffVirtualList();
  390. if (list != null && index < list.Count)
  391. {
  392. zbv = list[index];
  393. if (zbv != null)
  394. {
  395. ret = zbv as UnitBuff;
  396. }
  397. }
  398. }
  399. return ret;
  400. }
  401. /// <summary>
  402. /// 判断是否可放技能.
  403. /// </summary>
  404. /// <param name="skill"></param>
  405. /// <returns></returns>
  406. public virtual bool TryLaunchSkill(InstanceUnit.SkillState skill, ref InstanceUnit.LaunchSkillParam param)
  407. {
  408. #region
  409. if (!this.mUnit.IsCanLaunchSkill(skill.ID))
  410. {
  411. SendMsgToClient(CommonAI.XmdsConstConfig.TIPS_CAN_NOT_USE_SKILL);
  412. return false;
  413. }
  414. if (this.mUnit.IsCannotMove && skill.Data.ActionPriority < 0)
  415. {
  416. SendMsgToClient(CommonAI.XmdsConstConfig.CANNOT_LAUNCH_DISPACEMENTSKILL);
  417. return false;
  418. }
  419. //需要的能量是否足够(战士某些技能需要怒气)
  420. if(!this.LaunchSkillCheckTalentInfo(skill))
  421. {
  422. return false;
  423. }
  424. #endregion
  425. #region 普攻不能取消普攻.
  426. //TODO 屏蔽普攻不能取消普攻.
  427. /*
  428. if (this.mUnit.CurrentState is InstanceUnit.StateSkill)
  429. {
  430. if ((this.mUnit.CurrentState as InstanceUnit.StateSkill).SkillData.ID == skill.ID)
  431. {
  432. if (skill.Data.IsManuallyCancelable == false)
  433. {
  434. return false;
  435. }
  436. else
  437. {
  438. //直接交由skillstate.tryluanch判断.
  439. return true;
  440. }
  441. }
  442. }
  443. */
  444. #endregion
  445. //坐骑状态检查,如果是坐骑状态,主动切换骑乘.
  446. MountOnLaunchSkillCheck();
  447. bool ret = false;
  448. //XmdsSkillProperties prop = (XmdsSkillProperties)skill.Data.Properties;
  449. //if (prop.IsRandomNormalAttack)
  450. //{
  451. // skill.SetAutoIncreaseActionIndex(false);
  452. // byte k = (byte)(this.mUnit.RandomN.Next(0, skill.Data.ActionQueue.Count));
  453. // skill.SetActionIndex(k);
  454. //}
  455. DispatchTryLaunchSkillEvent(ref skill, ref ret, ref param);
  456. // 存储多段式技能判定
  457. if (ret && skill.CanStoreTimes)
  458. {
  459. ret = skill.OveryLayer > 0;
  460. }
  461. return ret;
  462. }
  463. /** 检测技能天赋信息 */
  464. public bool LaunchSkillCheckTalentInfo(InstanceUnit.SkillState skill)
  465. {
  466. //需要的能量是否足够(战士某些技能需要怒气)
  467. if (this.mUnit.IsPlayer && skill.ActionIndex == -1 && (this.GetUnitPro() == XmdsUnitPro.Sword || this.GetUnitPro() == XmdsUnitPro.Magic))
  468. {
  469. XmdsSkillValue data = XmdsGlobalData.GetTalentData(skill.Data.ID);
  470. if (data != null)
  471. {
  472. //天赋值
  473. if (data.GetValue(1) > 0 && this.Talent_Value() < data.GetValue(1))
  474. {
  475. return false;
  476. }
  477. //天赋等级
  478. if (!data.IsSingleCfg() && data.GetValue(2) > 0 && this.Talent_Lv() < data.GetValue(2))
  479. {
  480. return false;
  481. }
  482. }
  483. }
  484. return true;
  485. }
  486. #region 技能监听回调.
  487. //技能成功施放回调.
  488. private void OnLaunchSkillHandler(InstanceUnit obj, CommonAI.Zone.Instance.InstanceUnit.SkillState skill)
  489. {
  490. XmdsSkillProperties skillProp = skill.Data.Properties as XmdsSkillProperties;
  491. //增加Buff判断,部分buff效果可使技能使用效果发生变更.
  492. DispatchLaunchsSkillOverEvent(this, skill);
  493. //天赋点扣除
  494. if (this.mUnit.IsPlayer && skill.ActionIndex <= 0 && (this.GetUnitPro() == XmdsUnitPro.Sword || this.GetUnitPro() == XmdsUnitPro.Magic))
  495. {
  496. XmdsSkillValue data = XmdsGlobalData.GetTalentData(skill.Data.ID);
  497. if (data != null && data.GetValue() > 0)
  498. {
  499. this.Talent_Use(data.GetValue());
  500. }
  501. }
  502. //能量扣除.
  503. //mUnit.AddMP(-cost);
  504. }
  505. //回调增加技能.
  506. private void OnSkillAddHandler(InstanceUnit unit, CommonAI.Zone.Instance.InstanceUnit.SkillState sk)
  507. {
  508. }
  509. //回调移除技能.
  510. private void OnSkillRemoveHandler(InstanceUnit unit, CommonAI.Zone.Instance.InstanceUnit.SkillState sk)
  511. {
  512. if (mSkillHelper != null)
  513. {
  514. mSkillHelper.RemoveSkill(sk);
  515. }
  516. }
  517. //状态机切换.
  518. private void OnStateChangedHandler(InstanceUnit obj, InstanceUnit.State old_state, InstanceUnit.State new_state)
  519. {
  520. if (old_state != null && old_state is InstanceUnit.StateSkill)
  521. {
  522. InstanceUnit.StateSkill stateSkill = old_state as InstanceUnit.StateSkill;
  523. //获得技能ID.
  524. int id = stateSkill.SkillData.ID;
  525. DispatchStateSkillEndEvent(this, stateSkill);
  526. }
  527. if (new_state is InstanceUnit.StatePickObject)
  528. {
  529. TakeOffMount();
  530. }
  531. }
  532. private void OnSkillHitTargetHandler()
  533. {
  534. //吸血,待完善
  535. }
  536. #endregion
  537. /// <summary>
  538. /// 检查当前buff状态,是否可添加.
  539. /// </summary>
  540. /// <returns></returns>
  541. private bool CanAddBuff(ref BuffTemplate buff, XmdsVirtual target)
  542. {
  543. bool ret = false;
  544. //获取当前BUFF是哪种能力.
  545. XmdsBuffProperties prop = buff.Properties as XmdsBuffProperties;
  546. //XmdsBuffProperties.XmdsBuffAbility ab = prop.BuffAbilityList;
  547. ////判断该种BUFF是否被约束.
  548. //switch (ab)
  549. //{
  550. // case XmdsBuffProperties.XmdsBuffAbility.FROZEN:
  551. // case XmdsBuffProperties.XmdsBuffAbility.STUN:
  552. // case XmdsBuffProperties.XmdsBuffAbility.Silent:
  553. // break;
  554. // default: break;
  555. //}
  556. return ret;
  557. }
  558. /// <summary>
  559. /// 外部获取当前技能状态信息,排除被动技能
  560. /// </summary>
  561. /// <returns></returns>
  562. public XmdsSkillStatusData GetSkillStatusData()
  563. {
  564. XmdsSkillStatusData ret = new XmdsSkillStatusData();
  565. ret.SkillTimestampMSMap = new HashMap<int, long>();
  566. //生成同步时间戳.
  567. long SkillTimestampMS = TimeUtil.GetTimestampMS();
  568. IEnumerable<InstanceUnit.SkillState> sslist = mUnit.SkillStatus;
  569. //主动技能.
  570. foreach (InstanceUnit.SkillState s in sslist)
  571. {
  572. if (s.ActionIndex > 0 && s.IsHasNext())
  573. {
  574. s.ForceIntoCD();
  575. }
  576. if(s.GetSkillType() == XmdsSkillType.cardSkill)
  577. {
  578. continue;
  579. }
  580. ret.SkillTimestampMSMap.Add(s.ID, SkillTimestampMS + s.TotalCDTime - s.PassTime);
  581. }
  582. //被动技能.
  583. //if (SkillHelper.mPassiveSkills != null)
  584. //{
  585. // for (int i = 0; i < SkillHelper.mPassiveSkills.Count; i++)
  586. // {
  587. // UnitPassiveSkill ups = SkillHelper.mPassiveSkills[i];
  588. // ret.SkillTimestampMSMap.Add(ups.SkillID, SkillTimestampMS + ups.GetCDTotalTime() - ups.GetCDPassTime());
  589. // }
  590. //}
  591. return ret;
  592. }
  593. public long GetSkillTimestampMS(int skillID)
  594. {
  595. InstanceUnit.SkillState ss = this.mUnit.getSkillState(skillID);
  596. if (ss != null)
  597. {
  598. long SkillTimestampMS = TimeUtil.GetTimestampMS() + ss.TotalCDTime - ss.PassTime;
  599. return SkillTimestampMS;
  600. }
  601. return 0;
  602. }
  603. private int CalSkillCDTime(long timestamp)
  604. {
  605. long curTime = TimeUtil.GetTimestampMS();
  606. long dif = timestamp - curTime;
  607. return (int)dif;
  608. }
  609. private InstanceUnit.SkillState SetSkillCD(int skillid, long timestamp)
  610. {
  611. InstanceUnit.SkillState ss = this.mUnit.getSkillState(skillid);
  612. if (ss == null)
  613. {
  614. return null;
  615. }
  616. int time = CalSkillCDTime(timestamp);
  617. //大于0代表还处于CD中.
  618. if (time > 0 && time <= ss.TotalCDTime)
  619. {
  620. ss.IsInMutilTime = false;
  621. this.mUnit.SetSkillPassTime(skillid, ss.TotalCDTime - time);
  622. }
  623. return ss;
  624. }
  625. private void SetSkillCDDecreasePercent(int skillid, int percent)
  626. {
  627. if (percent == 0)
  628. {
  629. return;
  630. }
  631. InstanceUnit.SkillState ss = this.mUnit.getSkillState(skillid);
  632. if (ss == null)
  633. {
  634. return;
  635. }
  636. int cd = ss.Data.CoolDownMS;
  637. int dt = (int)(cd * (percent * 1.0f / XmdsDamageCalculator.PERER));
  638. ss.AddDecreaseTotalTimeMS(dt);
  639. }
  640. public void DestorySkill()
  641. {
  642. if (mSkillHelper != null)
  643. {
  644. mSkillHelper.Dispose();
  645. mSkillHelper = null;
  646. }
  647. foreach (var buf in mTrySendBuff.Values)
  648. {
  649. var bvlist = (buf.Properties as XmdsBuffProperties).GetBuffVirtualList();
  650. foreach (var bv in bvlist)
  651. {
  652. bv.Dispose();
  653. }
  654. bvlist.Clear();
  655. }
  656. mTrySendBuff.Clear();
  657. mTrySendSpell.Clear();
  658. }
  659. /// <summary>
  660. /// 技能信息辅助类.
  661. /// </summary>
  662. public class XmdsSkillHelper
  663. {
  664. //普通技能.
  665. private SkillTemplate mBaseSkill = null;
  666. //单位拥有的技能.
  667. private HashMap<int, GameSkill> mSkillMap = null;
  668. //单位自己的主动技能模板.
  669. private HashMap<int, SkillTemplate> mActiveSkillTemplateMap = null;
  670. //单位拥有的被动技能.
  671. internal List<UnitPassiveSkill> mPassiveSkills = null;
  672. //单位拥有的主动技能.
  673. internal List<UnitSkill> mActiveSkills = null;
  674. //宿主.
  675. private XmdsVirtual mOwner = null;
  676. public XmdsSkillHelper()
  677. {
  678. //主动技能表.
  679. if (mActiveSkillTemplateMap == null)
  680. {
  681. mActiveSkillTemplateMap = new HashMap<int, SkillTemplate>();
  682. }
  683. if (mActiveSkills == null)
  684. {
  685. mActiveSkills = new List<UnitSkill>();
  686. }
  687. }
  688. public void InitSkill(XmdsUnitSkillInfo sks, XmdsVirtual owner)
  689. {
  690. if (mSkillMap != null) { mSkillMap.Clear(); }
  691. else { mSkillMap = new HashMap<int, GameSkill>(); }
  692. mOwner = owner;
  693. //主动技能初始化.
  694. if (sks != null)
  695. {
  696. InitSkill(sks.UnitSkills);
  697. }
  698. }
  699. public String GetAllSkills()
  700. {
  701. String skillText = "";
  702. foreach (KeyValuePair<int, GameSkill> pair in mSkillMap)
  703. {
  704. skillText += pair.Key + ", ";
  705. }
  706. return skillText;
  707. }
  708. /// <summary>
  709. /// 获得主动、被动技能列表.
  710. /// </summary>
  711. /// <param name="src"></param>
  712. /// <param name="active"></param>
  713. /// <param name="passive"></param>
  714. private void GetActivePassiveSkillList(List<GameSkill> src, ref List<GameSkill> active, ref List<GameSkill> passive)
  715. {
  716. GameSkill gs = null;
  717. for (int i = 0; i < src.Count; i++)
  718. {
  719. gs = src[i];
  720. if (JSGModule.IsActiveSkill(gs.SkillType))
  721. {
  722. active.Add(gs);
  723. }
  724. else if (JSGModule.IsPassiveSkill(gs.SkillType))
  725. {
  726. passive.Add(gs);
  727. }
  728. }
  729. }
  730. #region 主动技能.
  731. /// <summary>
  732. /// 初始化主动技能.
  733. /// </summary>
  734. /// <param name="gameSkills"></param>
  735. public void InitActiveSkills(List<GameSkill> gameSkills)
  736. {
  737. try
  738. {
  739. if (gameSkills == null || gameSkills.Count == 0) { return; }
  740. //需要判断BUFF状态,记录单位技能信息.
  741. GameSkill gs = null;
  742. UnitSkill us = null;
  743. SkillTemplate st = null;
  744. for (int i = 0; i < gameSkills.Count; i++)
  745. {
  746. gs = gameSkills[i];
  747. if (mSkillMap.ContainsKey(gameSkills[i].SkillID))
  748. {
  749. continue;
  750. }
  751. //主动技能初始化只有初始化成功的技能会在技能MAP中.
  752. //存放技能等级信息.
  753. mSkillMap.Add(gameSkills[i].SkillID, gameSkills[i]);
  754. us = InitXmdsSkillScript(gs, ref st);
  755. if (us != null && st != null)
  756. {
  757. mActiveSkillTemplateMap.Add(st.ID, st);
  758. //UnitSkill us = XmdsBattleSkill.GetUnitSkill(gs.SkillID);
  759. mActiveSkills.Add(us);
  760. //if(st.ID != us.SkillID)
  761. //{
  762. // log.Warn("初始化技能,使用脚本不一致, 技能" + st.ID + ", 使用:" + us.SkillID);
  763. //}
  764. }
  765. else
  766. {
  767. FormatLog(string.Format("XmdsVirtual.Skill can not find SkillScript {0},", gs.SkillID));
  768. }
  769. }
  770. #region 重置单位技能.
  771. List<SkillTemplate> temp = new List<SkillTemplate>();
  772. for (int i = 0; i < gameSkills.Count; i++)
  773. {
  774. gs = gameSkills[i];
  775. if (mActiveSkillTemplateMap.TryGetValue(gs.SkillID, out st))
  776. {
  777. //分辨出普通攻击.
  778. if (gs.SkillType == XmdsSkillType.normalAtk)
  779. {
  780. mBaseSkill = st;
  781. }
  782. else
  783. {
  784. temp.Add(st);
  785. }
  786. }
  787. }
  788. if (temp.Count > 0 || mBaseSkill != null)
  789. {
  790. //重置技能.
  791. mOwner.mUnit.InitSkills(mBaseSkill, temp.ToArray());
  792. }
  793. for (int i = 0; i < temp.Count; i++)
  794. {
  795. if (mSkillMap.TryGetValue(temp[i].ID, out gs))
  796. {
  797. mOwner.SetSkillCD(temp[i].ID, gs.SkillTimestampMS);
  798. mOwner.SetSkillCDDecreasePercent(temp[i].ID, gs.SkillCDDecreasePercent);
  799. // 人物, 宠物的技能是否自动释放走配置表
  800. if (mOwner is XmdsVirtual_Player || mOwner is XmdsVirtual_Pet)
  801. {
  802. SkillState skillState = mOwner.mUnit.getSkillState(temp[i].ID);
  803. if (skillState != null)
  804. {
  805. skillState.setAutoLaunch(gs.AutoLaunch);
  806. }
  807. }
  808. }
  809. }
  810. //UnitSkillList.Clear();
  811. //UnitSkillList = null;
  812. #endregion
  813. }
  814. catch (Exception error)
  815. {
  816. FormatLog(CommonLang.Log.LoggerLevel.ERROR, "单位【{0}】初始化技能错误:{1}", mOwner.mInfo.Name, error.ToString());
  817. }
  818. }
  819. public void notifyActiveSkillInitOver(List<GameSkill> gameSkills)
  820. {
  821. if (mActiveSkills == null)
  822. {
  823. return;
  824. }
  825. for (int i = 0; i < mActiveSkills.Count; i++)
  826. {
  827. GameSkill gameSkill = null;
  828. for (int j = 0; j < gameSkills.Count; j++)
  829. {
  830. if (mActiveSkills[i].SkillID == gameSkills[j].SkillID)
  831. {
  832. gameSkill = gameSkills[j];
  833. break;
  834. }
  835. }
  836. mActiveSkills[i].InitOver(mOwner, gameSkill);
  837. }
  838. }
  839. public void notifyPassiveSkillInitOver(List<GameSkill> gameSkills)
  840. {
  841. if (mPassiveSkills == null)
  842. {
  843. return;
  844. }
  845. for (int i = 0; i < mPassiveSkills.Count; i++)
  846. {
  847. GameSkill gameSkill = null;
  848. for (int j = 0; j < gameSkills.Count; j++)
  849. {
  850. if (mPassiveSkills[i].SkillID == gameSkills[j].SkillID)
  851. {
  852. gameSkill = gameSkills[j];
  853. break;
  854. }
  855. }
  856. mPassiveSkills[i].InitOver(mOwner, gameSkill);
  857. }
  858. }
  859. //public bool changeActiveSkill(int oldSkillID, int newSkillID)
  860. //{
  861. // try
  862. // {
  863. // if (oldSkillID == 0 || oldSkillID == newSkillID)
  864. // {
  865. // return false;
  866. // }
  867. // GameSkill oldSkill = mSkillMap.Get(oldSkillID);
  868. // GameSkill newSkill = mSkillMap.Get(newSkillID);
  869. // if (oldSkill == null || newSkill != null)
  870. // {
  871. // return false;
  872. // }
  873. // oldSkill.SkillID = newSkillID;
  874. // newSkill = oldSkill;
  875. // SkillTemplate st = null;
  876. // UnitSkill us = InitXmdsSkillScript(newSkill, ref st);
  877. // if (us == null || st == null)
  878. // {
  879. // FormatLog(string.Format("XmdsVirtual.Skill can not find SkillScript {0},", newSkill.SkillID));
  880. // return false;
  881. // }
  882. // mSkillMap.Remove(oldSkillID);
  883. // mSkillMap.Add(newSkillID, newSkill);
  884. // mActiveSkillTemplateMap.Remove(oldSkillID);
  885. // mActiveSkillTemplateMap.Add(us.SkillID, st);
  886. // for (int i = 0; i < mActiveSkills.Count; i++)
  887. // {
  888. // if (mActiveSkills[i].SkillID == oldSkillID)
  889. // {
  890. // mActiveSkills.RemoveAt(i);
  891. // mActiveSkills.Add(us);
  892. // break;
  893. // }
  894. // }
  895. // #region 重置单位技能.
  896. // List<SkillTemplate> temp = new List<SkillTemplate>();
  897. // if (mActiveSkillTemplateMap.TryGetValue(newSkillID, out st))
  898. // {
  899. // //分辨出普通攻击.
  900. // if (newSkill.SkillType == XmdsSkillType.normalAtk)
  901. // {
  902. // mBaseSkill = st;
  903. // }
  904. // else
  905. // {
  906. // temp.Add(st);
  907. // }
  908. // }
  909. // if (temp.Count > 0 || mBaseSkill != null)
  910. // {
  911. // //重置技能.
  912. // mOwner.mUnit.InitSkills(mBaseSkill, temp.ToArray());
  913. // }
  914. // // 人物, 宠物的技能是否自动释放走配置表
  915. // if (mOwner is XmdsVirtual_Player || mOwner is XmdsVirtual_Pet)
  916. // {
  917. // SkillState skillState = mOwner.mUnit.getSkillState(newSkill.SkillID);
  918. // if (skillState != null)
  919. // {
  920. // skillState.setAutoLaunch(newSkill.AutoLaunch);
  921. // }
  922. // }
  923. // mOwner.SetSkillCD(st.ID, newSkill.SkillTimestampMS);
  924. // mOwner.SetSkillCDDecreasePercent(st.ID, newSkill.SkillCDDecreasePercent);
  925. // for (int i = 0; i < mActiveSkills.Count; i++)
  926. // {
  927. // if (mActiveSkills[i].SkillID == newSkillID)
  928. // {
  929. // mActiveSkills[i].InitOver(mOwner, newSkill);
  930. // break;
  931. // }
  932. // }
  933. // #endregion
  934. // }
  935. // catch (Exception error)
  936. // {
  937. // FormatLog(CommonLang.Log.LoggerLevel.ERROR, "单位【{0}】初始化技能错误:{1}", mOwner.mInfo.Name, error.ToString());
  938. // return false;
  939. // }
  940. // return true;
  941. //}
  942. private UnitSkill InitXmdsSkillScript(GameSkill gs, ref SkillTemplate st)
  943. {
  944. UnitSkill us = null;
  945. try
  946. {
  947. //获取技能脚本.
  948. us = XmdsBattleSkill.GetUnitSkill(gs.SkillID);
  949. //如果UnitSkill为NULL,则读取默认脚本.
  950. if (us == null)
  951. {
  952. FormatLog(CommonLang.Log.LoggerLevel.INFO, string.Format("单位{0}主动技能{1}未找到脚本,使用默认脚本代替", mOwner.mInfo.TemplateID, gs.SkillID));
  953. us = XmdsBattleSkill.GetUnitSkill(XmdsBattleSkill.DefaultSkillScriptID);
  954. // 宠物或者人物如果没有配置对应的技能文件,就设置为不自动释放技能
  955. if (this.mOwner is XmdsVirtual_Pet || this.mOwner is XmdsVirtual_Player)
  956. {
  957. gs.AutoLaunch = false;
  958. }
  959. }
  960. //主动技能特殊逻辑初始化.
  961. st = XmdsBattleSkill.GetSkillTemplate(gs.SkillID);
  962. if (st == null)
  963. {
  964. FormatLog(CommonLang.Log.LoggerLevel.ERROR, string.Format("未找到技能模板{0}", gs.SkillID));
  965. }
  966. //对技能进行脚本重铸.
  967. us.Init(gs, mOwner, ref st);
  968. }
  969. catch (Exception err)
  970. {
  971. log.Error("InitXmdsSkillScript异常, 技能id" + gs.SkillID + ", 单位ID: " + mOwner.mInfo.TemplateID + ", e : " + err);
  972. }
  973. return us;
  974. }
  975. #endregion
  976. #region 被动技能技能.
  977. //初始化被动技能.
  978. public void InitPassiveSkills(List<GameSkill> skills)
  979. {
  980. try
  981. {
  982. if (skills == null || skills.Count == 0) { return; }
  983. mPassiveSkills = new List<UnitPassiveSkill>();
  984. UnitPassiveSkill sk = null;
  985. for (int i = 0; i < skills.Count; i++)
  986. {
  987. if (mSkillMap.ContainsKey(skills[i].SkillID))
  988. {
  989. continue;
  990. }
  991. sk = InitXmdsPassiveSkillScript(skills[i]);
  992. mSkillMap.Add(skills[i].SkillID, skills[i]);
  993. mPassiveSkills.Add(sk);
  994. SetPassiveSkillCD(sk, skills[i].SkillTimestampMS);
  995. SetPassiveSkillCDDecrease(sk, skills[i].SkillCDDecreasePercent);
  996. }
  997. }
  998. catch (Exception error)
  999. {
  1000. FormatLog(CommonLang.Log.LoggerLevel.ERROR, "单位【{0}】初始化被动技能错误:{1}", mOwner.mInfo.Name, error.ToString());
  1001. }
  1002. }
  1003. private void SetPassiveSkillCD(UnitPassiveSkill sk, long timestamp)
  1004. {
  1005. int time = mOwner.CalSkillCDTime(timestamp);
  1006. //大于0代表还处于CD中.
  1007. if (time > 0 && time <= sk.GetCDTotalTime())
  1008. {
  1009. sk.SetCDPassTime(sk.GetCDTotalTime() - time);
  1010. }
  1011. }
  1012. private void SetPassiveSkillCDDecrease(UnitPassiveSkill sk, int timeMS)
  1013. {
  1014. if (sk != null)
  1015. {
  1016. int t = (int)(timeMS * 1.0f / XmdsDamageCalculator.PERER);
  1017. int oldt = sk.GetDecreaseTotalTimeMS();
  1018. int newt = oldt + t;
  1019. sk.SetDecreaseTotalTimeMS(newt);
  1020. }
  1021. }
  1022. //初始化被动技能脚本.
  1023. private UnitPassiveSkill InitXmdsPassiveSkillScript(GameSkill gs)
  1024. {
  1025. UnitPassiveSkill ret = null;
  1026. try
  1027. {
  1028. ret = XmdsBattleSkill.GetPassiveSkill(gs.SkillID);
  1029. if (ret == null)
  1030. {
  1031. throw new Exception("被动技能脚本未找到:" + this.mOwner.mUnit.PlayerUUID);
  1032. }
  1033. else
  1034. {
  1035. ret.Init(gs, mOwner);
  1036. }
  1037. }
  1038. catch (Exception err)
  1039. {
  1040. ThrowXmdsException(gs.SkillID, mOwner.mInfo.TemplateID, err.ToString());
  1041. }
  1042. return ret;
  1043. }
  1044. /// <summary>
  1045. /// 报错方法.
  1046. /// </summary>
  1047. /// <param name="skill"></param>
  1048. /// <param name="unit"></param>
  1049. /// <param name="error"></param>
  1050. private void ThrowXmdsException(int skill, int unit, string error)
  1051. {
  1052. string msg = string.Format("XmdsSkill Init Error id : SkillID = {0} UnitID = {1},Error = {2}", skill, unit, error.ToString());
  1053. log.Error(msg);
  1054. throw new Exception(msg);
  1055. }
  1056. //更新技能状态.
  1057. private void UpdatePassiveSkills(int intervalMS, bool slowRefresh)
  1058. {
  1059. if (mPassiveSkills != null)
  1060. {
  1061. for (int i = 0; i < mPassiveSkills.Count; i++)
  1062. {
  1063. mPassiveSkills[i].Update(intervalMS, slowRefresh);
  1064. }
  1065. }
  1066. }
  1067. private void UpdateActiveSkills(int intervalMS, bool slowRefresh)
  1068. {
  1069. if (mActiveSkills != null)
  1070. {
  1071. for (int i = 0; i < mActiveSkills.Count; i++)
  1072. {
  1073. UnitSkill skillInfo = mActiveSkills[i];
  1074. if (skillInfo == null || !skillInfo.IsActive)
  1075. {
  1076. continue;
  1077. }
  1078. skillInfo.Update(intervalMS, slowRefresh);
  1079. }
  1080. }
  1081. }
  1082. #endregion
  1083. #region 常用API.
  1084. /// <summary>
  1085. /// 是否有该技能.
  1086. /// </summary>
  1087. /// <param name="id"></param>
  1088. /// <returns></returns>
  1089. public bool ContainSkill(int id)
  1090. {
  1091. return mSkillMap.ContainsKey(id);
  1092. }
  1093. /// <summary>
  1094. /// 获取技能信息.
  1095. /// </summary>
  1096. /// <param name="id"></param>
  1097. /// <returns></returns>
  1098. public GameSkill GetGameSkill(int id)
  1099. {
  1100. GameSkill ret = null;
  1101. mSkillMap.TryGetValue(id, out ret);
  1102. return ret;
  1103. }
  1104. //获取玩家技能
  1105. public UnitSkill GetPlayerSkillById(int skillId)
  1106. {
  1107. if (mActiveSkills == null)
  1108. {
  1109. return null;
  1110. }
  1111. for (int i = 0; i < mActiveSkills.Count; i++)
  1112. {
  1113. if (mActiveSkills[i].SkillID == skillId)
  1114. {
  1115. return mActiveSkills[i];
  1116. }
  1117. }
  1118. return null;
  1119. }
  1120. //获取玩家技能
  1121. public UnitPassiveSkill GetPlayerSkillByIdExt(int skillId)
  1122. {
  1123. if (mPassiveSkills == null)
  1124. {
  1125. return null;
  1126. }
  1127. for (int i = 0; i < mPassiveSkills.Count; i++)
  1128. {
  1129. if (mPassiveSkills[i].SkillID == skillId)
  1130. {
  1131. return mPassiveSkills[i];
  1132. }
  1133. }
  1134. return null;
  1135. }
  1136. /// <summary>
  1137. /// 获取主动技能模板.
  1138. /// </summary>
  1139. /// <param name="id"></param>
  1140. /// <returns></returns>
  1141. public SkillTemplate GetUnitSkillTemplate(int id)
  1142. {
  1143. SkillTemplate ret = null;
  1144. mActiveSkillTemplateMap.TryGetValue(id, out ret);
  1145. return ret;
  1146. }
  1147. public void RemoveSkill(CommonAI.Zone.Instance.InstanceUnit.SkillState sk)
  1148. {
  1149. if (mSkillMap != null)
  1150. {
  1151. GameSkill gs = null;
  1152. if (mSkillMap.TryGetValue(sk.ID, out gs))
  1153. {
  1154. mOwner.RemoveEventBySkillID(gs.SkillID);
  1155. mSkillMap.Remove(sk.ID);
  1156. }
  1157. for (int i = 0; i < mActiveSkills.Count; i++)
  1158. {
  1159. if (mActiveSkills[i].SkillID == sk.ID)
  1160. {
  1161. mActiveSkills.RemoveAt(i);
  1162. break;
  1163. }
  1164. }
  1165. }
  1166. if (mActiveSkillTemplateMap != null)
  1167. {
  1168. mActiveSkillTemplateMap.RemoveByKey(sk.ID);
  1169. mActiveSkillTemplateMap.Remove(sk.ID);
  1170. }
  1171. }
  1172. public void Update(int intervalMS, bool slowRefresh)
  1173. {
  1174. UpdatePassiveSkills(intervalMS, slowRefresh);
  1175. //2021.11.02优化:主动技能慢刷新,打开需要注明原因
  1176. if(slowRefresh)
  1177. {
  1178. UpdateActiveSkills(intervalMS, slowRefresh);
  1179. }
  1180. }
  1181. public int GetBaseSkillID()
  1182. {
  1183. if (mBaseSkill != null)
  1184. {
  1185. return mBaseSkill.ID;
  1186. }
  1187. return 0;
  1188. }
  1189. /// <summary>
  1190. /// 增加技能.
  1191. /// </summary>
  1192. /// <param name="list"></param>
  1193. public void AddSkill(List<GameSkill> list)
  1194. {
  1195. if (list != null && list.Count > 0)
  1196. {
  1197. List<GameSkill> active = new List<GameSkill>();
  1198. List<GameSkill> passive = new List<GameSkill>();
  1199. GetActivePassiveSkillList(list, ref active, ref passive);
  1200. GameSkill gs = null;
  1201. //主动技能.
  1202. for (int i = 0; i < active.Count; i++)
  1203. {
  1204. gs = active[i];
  1205. AddActiveSkill(gs);
  1206. }
  1207. for (int i = 0; i < passive.Count; i++)
  1208. {
  1209. gs = passive[i];
  1210. AddPassiveSkill(gs);
  1211. }
  1212. }
  1213. }
  1214. public UnitSkill AddActiveSkill(GameSkill gs, bool is_default = false)
  1215. {
  1216. SkillTemplate st = null;
  1217. UnitSkill us = null;
  1218. //存放技能等级信息.
  1219. mSkillMap.Put(gs.SkillID, gs);
  1220. us = InitXmdsSkillScript(gs, ref st);
  1221. if (st != null)
  1222. {
  1223. if (mActiveSkillTemplateMap == null)
  1224. {
  1225. mActiveSkillTemplateMap = new HashMap<int, SkillTemplate>();
  1226. }
  1227. mActiveSkillTemplateMap.Put(st.ID, st);
  1228. //us = XmdsBattleSkill.GetUnitSkill(gs.SkillID);
  1229. mOwner.mUnit.AddSkill(st, gs.AutoLaunch, is_default);
  1230. SkillState skillState = mOwner.SetSkillCD(gs.SkillID, gs.SkillTimestampMS);
  1231. mOwner.SetSkillCDDecreasePercent(gs.SkillID, gs.SkillCDDecreasePercent);
  1232. if (skillState != null)
  1233. {
  1234. skillState.Reset(true);
  1235. }
  1236. if (us != null)
  1237. {
  1238. mActiveSkills.Add(us);
  1239. us.InitOver(mOwner, gs);
  1240. }
  1241. }
  1242. return us;
  1243. }
  1244. public UnitPassiveSkill AddPassiveSkill(GameSkill gs)
  1245. {
  1246. UnitPassiveSkill ups = InitXmdsPassiveSkillScript(gs);
  1247. mSkillMap.Put(gs.SkillID, gs);
  1248. SetPassiveSkillCD(ups, gs.SkillTimestampMS);
  1249. SetPassiveSkillCDDecrease(ups, gs.SkillCDDecreasePercent);
  1250. if (mPassiveSkills == null)
  1251. {
  1252. mPassiveSkills = new List<UnitPassiveSkill>();
  1253. }
  1254. mPassiveSkills.Add(ups);
  1255. ups.InitOver(mOwner, gs);
  1256. return ups;
  1257. }
  1258. /// <summary>
  1259. /// 减少技能.
  1260. /// </summary>
  1261. /// <param name="list"></param>
  1262. public void RemoveSkill(List<GameSkill> list)
  1263. {
  1264. if (list != null && list.Count > 0)
  1265. {
  1266. List<GameSkill> active = new List<GameSkill>();
  1267. List<GameSkill> passive = new List<GameSkill>();
  1268. GetActivePassiveSkillList(list, ref active, ref passive);
  1269. GameSkill gs = null;
  1270. //主动技能.
  1271. for (int i = 0; i < active.Count; i++)
  1272. {
  1273. gs = active[i];
  1274. RemoveActiveSkill(gs.SkillID);
  1275. }
  1276. //删除被动技能.
  1277. for (int i = 0; i < passive.Count; i++)
  1278. {
  1279. if (mSkillMap.TryGetValue(passive[i].SkillID, out gs))
  1280. {
  1281. RemovePassiveSkill(gs.SkillID);
  1282. }
  1283. }
  1284. }
  1285. }
  1286. public void RemoveActiveSkill(int skillID)
  1287. {
  1288. if (mBaseSkill != null && skillID == mBaseSkill.ID)
  1289. {
  1290. mBaseSkill = null;
  1291. }
  1292. mOwner.mUnit.RemoveSkill(skillID); //调用该API收到remove事件再删除技能.
  1293. }
  1294. public void RemovePassiveSkill(int skillID)
  1295. {
  1296. mSkillMap.RemoveByKey(skillID);
  1297. for (int k = 0; k < mPassiveSkills.Count; k++)
  1298. {
  1299. if (mPassiveSkills[k].SkillID == skillID)
  1300. {
  1301. mPassiveSkills[k].Dispose(mOwner);
  1302. mPassiveSkills.RemoveAt(k);
  1303. mOwner.RemoveEventBySkillID(skillID);
  1304. break;
  1305. }
  1306. }
  1307. }
  1308. /// <summary>
  1309. /// 初始化技能.
  1310. /// </summary>
  1311. /// <param name="list"></param>
  1312. private void InitSkill(List<GameSkill> list)
  1313. {
  1314. List<GameSkill> active = new List<GameSkill>();
  1315. List<GameSkill> passive = new List<GameSkill>();
  1316. if (list.Count == 0)
  1317. {
  1318. return;
  1319. }
  1320. else if (this.mOwner.mUnit.IsPlayer)
  1321. {
  1322. //玩家有一些特殊的逻辑放到天赋被动里面
  1323. }
  1324. GetActivePassiveSkillList(list, ref active, ref passive);
  1325. InitPassiveSkills(passive);
  1326. InitActiveSkills(active);
  1327. //通知技能,初始化完成
  1328. notifyActiveSkillInitOver(active);
  1329. notifyPassiveSkillInitOver(passive);
  1330. this.mOwner.InitCardModule();
  1331. }
  1332. /// <summary>
  1333. /// 重置技能.
  1334. /// </summary>
  1335. /// <param name="list"></param>
  1336. public void ResetSkill(List<GameSkill> list, XmdsVirtual owner)
  1337. {
  1338. //1清除所有技能.
  1339. ClearSkill();
  1340. if (mSkillMap == null)
  1341. {
  1342. mSkillMap = new HashMap<int, GameSkill>();
  1343. }
  1344. mOwner = owner;
  1345. //2重新初始化技能.
  1346. InitSkill(list);
  1347. }
  1348. public void ReplaceSkill(List<GameSkill> list)
  1349. {
  1350. if (list == null) { return; }
  1351. GameSkill gs = null;
  1352. GameSkill new_gs = null;
  1353. for (int i = 0; i < list.Count; i++)
  1354. {
  1355. new_gs = list[i];
  1356. gs = null;
  1357. mSkillMap.TryGetValue(new_gs.SkillID, out gs);
  1358. if (gs != null)
  1359. {
  1360. gs.SkillLevel = new_gs.SkillLevel;
  1361. gs.TalentSkillLevel1 = new_gs.TalentSkillLevel1;
  1362. gs.TalentSkillLevel2 = new_gs.TalentSkillLevel2;
  1363. gs.TalentSkillLevel3 = new_gs.TalentSkillLevel3;
  1364. if (gs.SkillType == XmdsSkillType.passive)
  1365. {
  1366. if (mPassiveSkills != null)
  1367. {
  1368. for (int k = 0; k < mPassiveSkills.Count; k++)
  1369. {
  1370. if (mPassiveSkills[k].SkillID == gs.SkillID)
  1371. {
  1372. //去除原有CD修改值.
  1373. SetPassiveSkillCDDecrease(mPassiveSkills[k], -gs.SkillCDDecreasePercent);
  1374. //重新设置CD修改值.
  1375. SetPassiveSkillCDDecrease(mPassiveSkills[k], new_gs.SkillCDDecreasePercent);
  1376. //技能效果变化.
  1377. mPassiveSkills[k].SkillDataChange(gs, mOwner);
  1378. }
  1379. }
  1380. }
  1381. }
  1382. else
  1383. {
  1384. //去除原有CD修改值.
  1385. mOwner.SetSkillCDDecreasePercent(gs.SkillID, -gs.SkillCDDecreasePercent);
  1386. //重新设置CD修改值.
  1387. mOwner.SetSkillCDDecreasePercent(new_gs.SkillID, new_gs.SkillCDDecreasePercent);
  1388. for (int k = 0; k < mActiveSkills.Count; k++)
  1389. {
  1390. if (mActiveSkills[k].SkillID == new_gs.SkillID)
  1391. {
  1392. mActiveSkills[k].SkillDataChange(new_gs, mOwner);
  1393. break;
  1394. }
  1395. }
  1396. }
  1397. gs.SkillCDDecreasePercent = new_gs.SkillCDDecreasePercent;
  1398. }
  1399. }
  1400. }
  1401. /// <summary>
  1402. /// 清理技能.
  1403. /// </summary>
  1404. public void ClearSkill()
  1405. {
  1406. List<GameSkill> ret = new List<GameSkill>();
  1407. GameSkill g = null;
  1408. if (mSkillMap != null)
  1409. {
  1410. foreach (KeyValuePair<int, GameSkill> pair in mSkillMap)
  1411. {
  1412. g = new GameSkill();
  1413. g.SkillID = pair.Key;
  1414. g.SkillType = pair.Value.SkillType;
  1415. ret.Add(g);
  1416. }
  1417. RemoveSkill(ret);
  1418. }
  1419. }
  1420. public void Dispose()
  1421. {
  1422. ClearSkill();
  1423. mBaseSkill = null;
  1424. if (mSkillMap != null)
  1425. {
  1426. mSkillMap.Clear();
  1427. mSkillMap = null;
  1428. }
  1429. if (mActiveSkillTemplateMap != null)
  1430. {
  1431. mActiveSkillTemplateMap.Clear();
  1432. mActiveSkillTemplateMap = null;
  1433. }
  1434. if (mPassiveSkills != null)
  1435. {
  1436. mPassiveSkills.Clear();
  1437. mPassiveSkills = null;
  1438. }
  1439. mOwner = null;
  1440. }
  1441. #endregion
  1442. #region 特殊硬编码技能.
  1443. #endregion
  1444. }
  1445. /// <summary>
  1446. /// 技能状态信息.
  1447. /// </summary>
  1448. public class XmdsSkillStatusData
  1449. {
  1450. /// <summary>
  1451. /// 技能(技能ID,到期时间戳).
  1452. /// </summary>.
  1453. public HashMap<int, long> SkillTimestampMSMap = null;
  1454. }
  1455. //-----------------------职业天赋相关的接口-----------------------
  1456. public virtual IPlayerCache GetPlayerCache()
  1457. {
  1458. return this.mPlayerCache;
  1459. }
  1460. public virtual void SetPlayerCache(IPlayerCache cache)
  1461. {
  1462. this.mPlayerCache = cache;
  1463. }
  1464. public virtual void Talent__Add(int value)
  1465. {
  1466. if (this.mPlayerCache != null)
  1467. {
  1468. this.mPlayerCache.AddTalentValue(value);
  1469. }
  1470. }
  1471. public virtual void Talent_Use(int value)
  1472. {
  1473. if (this.mPlayerCache != null)
  1474. {
  1475. this.mPlayerCache.UseTalentValue(value);
  1476. }
  1477. }
  1478. public virtual int Talent_Value()
  1479. {
  1480. return mPlayerCache == null ? 0 : mPlayerCache.GetTalentValue();
  1481. }
  1482. public virtual int Talent_Lv()
  1483. {
  1484. return mPlayerCache == null ? 0 : mPlayerCache.GetTalentLv();
  1485. }
  1486. public virtual bool Talent_Refresh(bool notify = true)
  1487. {
  1488. if (this.mPlayerCache != null)
  1489. {
  1490. return this.mPlayerCache.Refresh(notify);
  1491. }
  1492. return false;
  1493. }
  1494. public virtual void Talent_MarkValid(bool isValid)
  1495. {
  1496. if (this.mPlayerCache != null)
  1497. {
  1498. this.mPlayerCache.MarkValid(isValid);
  1499. }
  1500. }
  1501. //---------------------------------------------------------------------
  1502. #region BUFF跨场景.
  1503. /*
  1504. /// <summary>
  1505. /// BUFF信息集合.
  1506. /// </summary>
  1507. public class XmdsBuffStatus
  1508. {
  1509. public List<XmdsBuffStatusData> mDatas = null;
  1510. }
  1511. /// <summary>
  1512. /// Buff状态信息.
  1513. /// </summary>
  1514. public class XmdsBuffStatusData
  1515. {
  1516. /// <summary>
  1517. /// BUFF模板.
  1518. /// </summary>
  1519. public int BuffTemplateID = 0;
  1520. /// <summary>
  1521. /// BUFF时间戳.
  1522. /// </summary>
  1523. public long BuffTimestampMS = 0;
  1524. }
  1525. */
  1526. #endregion
  1527. #region 技能API测试功能.
  1528. protected void Mock_RemoveSkill(int skillID)
  1529. {
  1530. PlayerSkillChangeEventR2B evt = new PlayerSkillChangeEventR2B();
  1531. evt.OperateID = PlayerSkillChangeEventR2B.SkillOperate.Remove;
  1532. List<GameSkill> list = new List<GameSkill>();
  1533. GameSkill gs = new GameSkill();
  1534. gs.SkillID = skillID;
  1535. list.Add(gs);
  1536. evt.SkillList = list;
  1537. OnPlayerSkillsChanged(evt);
  1538. }
  1539. protected void Mock_AddSkill(int skillID)
  1540. {
  1541. PlayerSkillChangeEventR2B evt = new PlayerSkillChangeEventR2B();
  1542. evt.OperateID = PlayerSkillChangeEventR2B.SkillOperate.Add;
  1543. List<GameSkill> list = new List<GameSkill>();
  1544. GameSkill gs = new GameSkill();
  1545. gs.SkillID = skillID;
  1546. gs.SkillLevel = 1;
  1547. gs.SkillType = XmdsSkillType.active;
  1548. list.Add(gs);
  1549. evt.SkillList = list;
  1550. OnPlayerSkillsChanged(evt);
  1551. }
  1552. protected void Mock_ResetSkill(List<GameSkill> list)
  1553. {
  1554. PlayerSkillChangeEventR2B evt = new PlayerSkillChangeEventR2B();
  1555. evt.OperateID = PlayerSkillChangeEventR2B.SkillOperate.Reset;
  1556. evt.SkillList = list;
  1557. OnPlayerSkillsChanged(evt);
  1558. }
  1559. protected void Mock_ReplaceSkill(List<GameSkill> list)
  1560. {
  1561. PlayerSkillChangeEventR2B evt = new PlayerSkillChangeEventR2B();
  1562. evt.OperateID = PlayerSkillChangeEventR2B.SkillOperate.Replace;
  1563. evt.SkillList = list;
  1564. OnPlayerSkillsChanged(evt);
  1565. }
  1566. #endregion
  1567. }
  1568. }