XmdsVirtual.Skills.cs 44 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855
  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 long mPreLaunchTime;
  489. private void OnLaunchSkillHandler(InstanceUnit obj, CommonAI.Zone.Instance.InstanceUnit.SkillState skill)
  490. {
  491. XmdsSkillProperties skillProp = skill.Data.Properties as XmdsSkillProperties;
  492. //增加Buff判断,部分buff效果可使技能使用效果发生变更.
  493. DispatchLaunchsSkillOverEvent(this, skill);
  494. //天赋点扣除
  495. if (this.mUnit.IsPlayer && skill.ActionIndex <= 0 && (this.GetUnitPro() == XmdsUnitPro.Sword || this.GetUnitPro() == XmdsUnitPro.Magic))
  496. {
  497. XmdsSkillValue data = XmdsGlobalData.GetTalentData(skill.Data.ID);
  498. if (data != null && data.GetValue() > 0)
  499. {
  500. if (!this.Talent_Use(data.GetValue()))
  501. {
  502. long timePass = System.DateTime.Now.Ticks - mPreLaunchTime;
  503. log.Warn("天赋扣除异常:" + this.mUnit.PlayerUUID + ", SceneID: " + this.mUnit.Parent.GetSceneID() + ", " + timePass);
  504. }
  505. }
  506. }
  507. //能量扣除.
  508. //mUnit.AddMP(-cost);
  509. mPreLaunchTime = System.DateTime.Now.Ticks;
  510. }
  511. //回调增加技能.
  512. private void OnSkillAddHandler(InstanceUnit unit, CommonAI.Zone.Instance.InstanceUnit.SkillState sk)
  513. {
  514. }
  515. //回调移除技能.
  516. private void OnSkillRemoveHandler(InstanceUnit unit, CommonAI.Zone.Instance.InstanceUnit.SkillState sk)
  517. {
  518. if (mSkillHelper != null)
  519. {
  520. mSkillHelper.RemoveSkill(sk);
  521. }
  522. }
  523. //状态机切换.
  524. private void OnStateChangedHandler(InstanceUnit obj, InstanceUnit.State old_state, InstanceUnit.State new_state)
  525. {
  526. if (old_state != null && old_state is InstanceUnit.StateSkill)
  527. {
  528. InstanceUnit.StateSkill stateSkill = old_state as InstanceUnit.StateSkill;
  529. //获得技能ID.
  530. int id = stateSkill.SkillData.ID;
  531. DispatchStateSkillEndEvent(this, stateSkill);
  532. }
  533. if (new_state is InstanceUnit.StatePickObject)
  534. {
  535. TakeOffMount();
  536. }
  537. }
  538. private void OnSkillHitTargetHandler()
  539. {
  540. //吸血,待完善
  541. }
  542. #endregion
  543. /// <summary>
  544. /// 检查当前buff状态,是否可添加.
  545. /// </summary>
  546. /// <returns></returns>
  547. private bool CanAddBuff(ref BuffTemplate buff, XmdsVirtual target)
  548. {
  549. bool ret = false;
  550. //获取当前BUFF是哪种能力.
  551. XmdsBuffProperties prop = buff.Properties as XmdsBuffProperties;
  552. //XmdsBuffProperties.XmdsBuffAbility ab = prop.BuffAbilityList;
  553. ////判断该种BUFF是否被约束.
  554. //switch (ab)
  555. //{
  556. // case XmdsBuffProperties.XmdsBuffAbility.FROZEN:
  557. // case XmdsBuffProperties.XmdsBuffAbility.STUN:
  558. // case XmdsBuffProperties.XmdsBuffAbility.Silent:
  559. // break;
  560. // default: break;
  561. //}
  562. return ret;
  563. }
  564. /// <summary>
  565. /// 外部获取当前技能状态信息,排除被动技能
  566. /// </summary>
  567. /// <returns></returns>
  568. public XmdsSkillStatusData GetSkillStatusData()
  569. {
  570. XmdsSkillStatusData ret = new XmdsSkillStatusData();
  571. ret.SkillTimestampMSMap = new HashMap<int, long>();
  572. //生成同步时间戳.
  573. long SkillTimestampMS = TimeUtil.GetTimestampMS();
  574. IEnumerable<InstanceUnit.SkillState> sslist = mUnit.SkillStatus;
  575. //主动技能.
  576. foreach (InstanceUnit.SkillState s in sslist)
  577. {
  578. if (s.ActionIndex > 0 && s.IsHasNext())
  579. {
  580. s.ForceIntoCD();
  581. }
  582. if(s.GetSkillType() == XmdsSkillType.cardSkill)
  583. {
  584. continue;
  585. }
  586. ret.SkillTimestampMSMap.Add(s.ID, SkillTimestampMS + s.TotalCDTime - s.PassTime);
  587. }
  588. //被动技能.
  589. //if (SkillHelper.mPassiveSkills != null)
  590. //{
  591. // for (int i = 0; i < SkillHelper.mPassiveSkills.Count; i++)
  592. // {
  593. // UnitPassiveSkill ups = SkillHelper.mPassiveSkills[i];
  594. // ret.SkillTimestampMSMap.Add(ups.SkillID, SkillTimestampMS + ups.GetCDTotalTime() - ups.GetCDPassTime());
  595. // }
  596. //}
  597. return ret;
  598. }
  599. public long GetSkillTimestampMS(int skillID)
  600. {
  601. InstanceUnit.SkillState ss = this.mUnit.getSkillState(skillID);
  602. if (ss != null)
  603. {
  604. long SkillTimestampMS = TimeUtil.GetTimestampMS() + ss.TotalCDTime - ss.PassTime;
  605. return SkillTimestampMS;
  606. }
  607. return 0;
  608. }
  609. private int CalSkillCDTime(long timestamp)
  610. {
  611. long curTime = TimeUtil.GetTimestampMS();
  612. long dif = timestamp - curTime;
  613. return (int)dif;
  614. }
  615. private InstanceUnit.SkillState SetSkillCD(int skillid, long timestamp)
  616. {
  617. InstanceUnit.SkillState ss = this.mUnit.getSkillState(skillid);
  618. if (ss == null)
  619. {
  620. return null;
  621. }
  622. int time = CalSkillCDTime(timestamp);
  623. //大于0代表还处于CD中.
  624. if (time > 0 && time <= ss.TotalCDTime)
  625. {
  626. ss.IsInMutilTime = false;
  627. this.mUnit.SetSkillPassTime(skillid, ss.TotalCDTime - time);
  628. }
  629. return ss;
  630. }
  631. private void SetSkillCDDecreasePercent(int skillid, int percent)
  632. {
  633. if (percent == 0)
  634. {
  635. return;
  636. }
  637. InstanceUnit.SkillState ss = this.mUnit.getSkillState(skillid);
  638. if (ss == null)
  639. {
  640. return;
  641. }
  642. int cd = ss.Data.CoolDownMS;
  643. int dt = (int)(cd * (percent * 1.0f / XmdsDamageCalculator.PERER));
  644. ss.AddDecreaseTotalTimeMS(dt);
  645. }
  646. public void DestorySkill()
  647. {
  648. if (mSkillHelper != null)
  649. {
  650. mSkillHelper.Dispose();
  651. mSkillHelper = null;
  652. }
  653. foreach (var buf in mTrySendBuff.Values)
  654. {
  655. var bvlist = (buf.Properties as XmdsBuffProperties).GetBuffVirtualList();
  656. foreach (var bv in bvlist)
  657. {
  658. bv.Dispose();
  659. }
  660. bvlist.Clear();
  661. }
  662. mTrySendBuff.Clear();
  663. mTrySendSpell.Clear();
  664. }
  665. /// <summary>
  666. /// 技能信息辅助类.
  667. /// </summary>
  668. public class XmdsSkillHelper
  669. {
  670. //普通技能.
  671. private SkillTemplate mBaseSkill = null;
  672. //单位拥有的技能.
  673. private HashMap<int, GameSkill> mSkillMap = null;
  674. //单位自己的主动技能模板.
  675. private HashMap<int, SkillTemplate> mActiveSkillTemplateMap = null;
  676. //单位拥有的被动技能.
  677. internal List<UnitPassiveSkill> mPassiveSkills = null;
  678. //单位拥有的主动技能.
  679. internal List<UnitSkill> mActiveSkills = null;
  680. //宿主.
  681. private XmdsVirtual mOwner = null;
  682. public XmdsSkillHelper()
  683. {
  684. //主动技能表.
  685. if (mActiveSkillTemplateMap == null)
  686. {
  687. mActiveSkillTemplateMap = new HashMap<int, SkillTemplate>();
  688. }
  689. if (mActiveSkills == null)
  690. {
  691. mActiveSkills = new List<UnitSkill>();
  692. }
  693. }
  694. public void InitSkill(XmdsUnitSkillInfo sks, XmdsVirtual owner)
  695. {
  696. if (mSkillMap != null) { mSkillMap.Clear(); }
  697. else { mSkillMap = new HashMap<int, GameSkill>(); }
  698. mOwner = owner;
  699. //主动技能初始化.
  700. if (sks != null)
  701. {
  702. InitSkill(sks.UnitSkills);
  703. }
  704. }
  705. public String GetAllSkills()
  706. {
  707. String skillText = "";
  708. foreach (KeyValuePair<int, GameSkill> pair in mSkillMap)
  709. {
  710. skillText += pair.Key + ", ";
  711. }
  712. return skillText;
  713. }
  714. /// <summary>
  715. /// 获得主动、被动技能列表.
  716. /// </summary>
  717. /// <param name="src"></param>
  718. /// <param name="active"></param>
  719. /// <param name="passive"></param>
  720. private void GetActivePassiveSkillList(List<GameSkill> src, ref List<GameSkill> active, ref List<GameSkill> passive)
  721. {
  722. GameSkill gs = null;
  723. for (int i = 0; i < src.Count; i++)
  724. {
  725. gs = src[i];
  726. if (JSGModule.IsActiveSkill(gs.SkillType))
  727. {
  728. active.Add(gs);
  729. }
  730. else if (JSGModule.IsPassiveSkill(gs.SkillType))
  731. {
  732. passive.Add(gs);
  733. }
  734. }
  735. }
  736. #region 主动技能.
  737. /// <summary>
  738. /// 初始化主动技能.
  739. /// </summary>
  740. /// <param name="gameSkills"></param>
  741. public void InitActiveSkills(List<GameSkill> gameSkills)
  742. {
  743. try
  744. {
  745. if (gameSkills == null || gameSkills.Count == 0) { return; }
  746. //需要判断BUFF状态,记录单位技能信息.
  747. GameSkill gs = null;
  748. UnitSkill us = null;
  749. SkillTemplate st = null;
  750. for (int i = 0; i < gameSkills.Count; i++)
  751. {
  752. gs = gameSkills[i];
  753. if (mSkillMap.ContainsKey(gameSkills[i].SkillID))
  754. {
  755. continue;
  756. }
  757. //主动技能初始化只有初始化成功的技能会在技能MAP中.
  758. //存放技能等级信息.
  759. mSkillMap.Add(gameSkills[i].SkillID, gameSkills[i]);
  760. us = InitXmdsSkillScript(gs, ref st);
  761. if (us != null && st != null)
  762. {
  763. mActiveSkillTemplateMap.Add(st.ID, st);
  764. //UnitSkill us = XmdsBattleSkill.GetUnitSkill(gs.SkillID);
  765. mActiveSkills.Add(us);
  766. //if(st.ID != us.SkillID)
  767. //{
  768. // log.Warn("初始化技能,使用脚本不一致, 技能" + st.ID + ", 使用:" + us.SkillID);
  769. //}
  770. }
  771. else
  772. {
  773. FormatLog(string.Format("XmdsVirtual.Skill can not find SkillScript {0},", gs.SkillID));
  774. }
  775. }
  776. #region 重置单位技能.
  777. List<SkillTemplate> temp = new List<SkillTemplate>();
  778. for (int i = 0; i < gameSkills.Count; i++)
  779. {
  780. gs = gameSkills[i];
  781. if (mActiveSkillTemplateMap.TryGetValue(gs.SkillID, out st))
  782. {
  783. //分辨出普通攻击.
  784. if (gs.SkillType == XmdsSkillType.normalAtk)
  785. {
  786. mBaseSkill = st;
  787. }
  788. else
  789. {
  790. temp.Add(st);
  791. }
  792. }
  793. }
  794. if (temp.Count > 0 || mBaseSkill != null)
  795. {
  796. //重置技能.
  797. mOwner.mUnit.InitSkills(mBaseSkill, temp.ToArray());
  798. }
  799. for (int i = 0; i < temp.Count; i++)
  800. {
  801. if (mSkillMap.TryGetValue(temp[i].ID, out gs))
  802. {
  803. mOwner.SetSkillCD(temp[i].ID, gs.SkillTimestampMS);
  804. mOwner.SetSkillCDDecreasePercent(temp[i].ID, gs.SkillCDDecreasePercent);
  805. // 人物, 宠物的技能是否自动释放走配置表
  806. if (mOwner is XmdsVirtual_Player || mOwner is XmdsVirtual_Pet)
  807. {
  808. SkillState skillState = mOwner.mUnit.getSkillState(temp[i].ID);
  809. if (skillState != null)
  810. {
  811. skillState.setAutoLaunch(gs.AutoLaunch);
  812. }
  813. }
  814. }
  815. }
  816. //UnitSkillList.Clear();
  817. //UnitSkillList = null;
  818. #endregion
  819. }
  820. catch (Exception error)
  821. {
  822. FormatLog(CommonLang.Log.LoggerLevel.ERROR, "单位【{0}】初始化技能错误:{1}", mOwner.mInfo.Name, error.ToString());
  823. }
  824. }
  825. public void notifyActiveSkillInitOver(List<GameSkill> gameSkills)
  826. {
  827. if (mActiveSkills == null)
  828. {
  829. return;
  830. }
  831. for (int i = 0; i < mActiveSkills.Count; i++)
  832. {
  833. GameSkill gameSkill = null;
  834. for (int j = 0; j < gameSkills.Count; j++)
  835. {
  836. if (mActiveSkills[i].SkillID == gameSkills[j].SkillID)
  837. {
  838. gameSkill = gameSkills[j];
  839. break;
  840. }
  841. }
  842. mActiveSkills[i].InitOver(mOwner, gameSkill);
  843. }
  844. }
  845. public void notifyPassiveSkillInitOver(List<GameSkill> gameSkills)
  846. {
  847. if (mPassiveSkills == null)
  848. {
  849. return;
  850. }
  851. for (int i = 0; i < mPassiveSkills.Count; i++)
  852. {
  853. GameSkill gameSkill = null;
  854. for (int j = 0; j < gameSkills.Count; j++)
  855. {
  856. if (mPassiveSkills[i].SkillID == gameSkills[j].SkillID)
  857. {
  858. gameSkill = gameSkills[j];
  859. break;
  860. }
  861. }
  862. mPassiveSkills[i].InitOver(mOwner, gameSkill);
  863. }
  864. }
  865. //public bool changeActiveSkill(int oldSkillID, int newSkillID)
  866. //{
  867. // try
  868. // {
  869. // if (oldSkillID == 0 || oldSkillID == newSkillID)
  870. // {
  871. // return false;
  872. // }
  873. // GameSkill oldSkill = mSkillMap.Get(oldSkillID);
  874. // GameSkill newSkill = mSkillMap.Get(newSkillID);
  875. // if (oldSkill == null || newSkill != null)
  876. // {
  877. // return false;
  878. // }
  879. // oldSkill.SkillID = newSkillID;
  880. // newSkill = oldSkill;
  881. // SkillTemplate st = null;
  882. // UnitSkill us = InitXmdsSkillScript(newSkill, ref st);
  883. // if (us == null || st == null)
  884. // {
  885. // FormatLog(string.Format("XmdsVirtual.Skill can not find SkillScript {0},", newSkill.SkillID));
  886. // return false;
  887. // }
  888. // mSkillMap.Remove(oldSkillID);
  889. // mSkillMap.Add(newSkillID, newSkill);
  890. // mActiveSkillTemplateMap.Remove(oldSkillID);
  891. // mActiveSkillTemplateMap.Add(us.SkillID, st);
  892. // for (int i = 0; i < mActiveSkills.Count; i++)
  893. // {
  894. // if (mActiveSkills[i].SkillID == oldSkillID)
  895. // {
  896. // mActiveSkills.RemoveAt(i);
  897. // mActiveSkills.Add(us);
  898. // break;
  899. // }
  900. // }
  901. // #region 重置单位技能.
  902. // List<SkillTemplate> temp = new List<SkillTemplate>();
  903. // if (mActiveSkillTemplateMap.TryGetValue(newSkillID, out st))
  904. // {
  905. // //分辨出普通攻击.
  906. // if (newSkill.SkillType == XmdsSkillType.normalAtk)
  907. // {
  908. // mBaseSkill = st;
  909. // }
  910. // else
  911. // {
  912. // temp.Add(st);
  913. // }
  914. // }
  915. // if (temp.Count > 0 || mBaseSkill != null)
  916. // {
  917. // //重置技能.
  918. // mOwner.mUnit.InitSkills(mBaseSkill, temp.ToArray());
  919. // }
  920. // // 人物, 宠物的技能是否自动释放走配置表
  921. // if (mOwner is XmdsVirtual_Player || mOwner is XmdsVirtual_Pet)
  922. // {
  923. // SkillState skillState = mOwner.mUnit.getSkillState(newSkill.SkillID);
  924. // if (skillState != null)
  925. // {
  926. // skillState.setAutoLaunch(newSkill.AutoLaunch);
  927. // }
  928. // }
  929. // mOwner.SetSkillCD(st.ID, newSkill.SkillTimestampMS);
  930. // mOwner.SetSkillCDDecreasePercent(st.ID, newSkill.SkillCDDecreasePercent);
  931. // for (int i = 0; i < mActiveSkills.Count; i++)
  932. // {
  933. // if (mActiveSkills[i].SkillID == newSkillID)
  934. // {
  935. // mActiveSkills[i].InitOver(mOwner, newSkill);
  936. // break;
  937. // }
  938. // }
  939. // #endregion
  940. // }
  941. // catch (Exception error)
  942. // {
  943. // FormatLog(CommonLang.Log.LoggerLevel.ERROR, "单位【{0}】初始化技能错误:{1}", mOwner.mInfo.Name, error.ToString());
  944. // return false;
  945. // }
  946. // return true;
  947. //}
  948. private UnitSkill InitXmdsSkillScript(GameSkill gs, ref SkillTemplate st)
  949. {
  950. UnitSkill us = null;
  951. try
  952. {
  953. //获取技能脚本.
  954. us = XmdsBattleSkill.GetUnitSkill(gs.SkillID);
  955. //如果UnitSkill为NULL,则读取默认脚本.
  956. if (us == null)
  957. {
  958. FormatLog(CommonLang.Log.LoggerLevel.INFO, string.Format("单位{0}主动技能{1}未找到脚本,使用默认脚本代替", mOwner.mInfo.TemplateID, gs.SkillID));
  959. us = XmdsBattleSkill.GetUnitSkill(XmdsBattleSkill.DefaultSkillScriptID);
  960. // 宠物或者人物如果没有配置对应的技能文件,就设置为不自动释放技能
  961. if (this.mOwner is XmdsVirtual_Pet || this.mOwner is XmdsVirtual_Player)
  962. {
  963. gs.AutoLaunch = false;
  964. }
  965. }
  966. //主动技能特殊逻辑初始化.
  967. st = XmdsBattleSkill.GetSkillTemplate(gs.SkillID);
  968. if (st == null)
  969. {
  970. FormatLog(CommonLang.Log.LoggerLevel.ERROR, string.Format("未找到技能模板{0}", gs.SkillID));
  971. }
  972. //对技能进行脚本重铸.
  973. us.Init(gs, mOwner, ref st);
  974. }
  975. catch (Exception err)
  976. {
  977. log.Error("InitXmdsSkillScript异常, 技能id" + gs.SkillID + ", 单位ID: " + mOwner.mInfo.TemplateID + ", e : " + err);
  978. }
  979. return us;
  980. }
  981. #endregion
  982. #region 被动技能技能.
  983. //初始化被动技能.
  984. public void InitPassiveSkills(List<GameSkill> skills)
  985. {
  986. try
  987. {
  988. if (skills == null || skills.Count == 0) { return; }
  989. mPassiveSkills = new List<UnitPassiveSkill>();
  990. UnitPassiveSkill sk = null;
  991. for (int i = 0; i < skills.Count; i++)
  992. {
  993. if (mSkillMap.ContainsKey(skills[i].SkillID))
  994. {
  995. continue;
  996. }
  997. sk = InitXmdsPassiveSkillScript(skills[i]);
  998. mSkillMap.Add(skills[i].SkillID, skills[i]);
  999. mPassiveSkills.Add(sk);
  1000. SetPassiveSkillCD(sk, skills[i].SkillTimestampMS);
  1001. SetPassiveSkillCDDecrease(sk, skills[i].SkillCDDecreasePercent);
  1002. }
  1003. }
  1004. catch (Exception error)
  1005. {
  1006. FormatLog(CommonLang.Log.LoggerLevel.ERROR, "单位【{0}】初始化被动技能错误:{1}", mOwner.mInfo.Name, error.ToString());
  1007. }
  1008. }
  1009. private void SetPassiveSkillCD(UnitPassiveSkill sk, long timestamp)
  1010. {
  1011. int time = mOwner.CalSkillCDTime(timestamp);
  1012. //大于0代表还处于CD中.
  1013. if (time > 0 && time <= sk.GetCDTotalTime())
  1014. {
  1015. sk.SetCDPassTime(sk.GetCDTotalTime() - time);
  1016. }
  1017. }
  1018. private void SetPassiveSkillCDDecrease(UnitPassiveSkill sk, int timeMS)
  1019. {
  1020. if (sk != null)
  1021. {
  1022. int t = (int)(timeMS * 1.0f / XmdsDamageCalculator.PERER);
  1023. int oldt = sk.GetDecreaseTotalTimeMS();
  1024. int newt = oldt + t;
  1025. sk.SetDecreaseTotalTimeMS(newt);
  1026. }
  1027. }
  1028. //初始化被动技能脚本.
  1029. private UnitPassiveSkill InitXmdsPassiveSkillScript(GameSkill gs)
  1030. {
  1031. UnitPassiveSkill ret = null;
  1032. try
  1033. {
  1034. ret = XmdsBattleSkill.GetPassiveSkill(gs.SkillID);
  1035. if (ret == null)
  1036. {
  1037. throw new Exception("被动技能脚本未找到:" + this.mOwner.mUnit.PlayerUUID);
  1038. }
  1039. else
  1040. {
  1041. ret.Init(gs, mOwner);
  1042. }
  1043. }
  1044. catch (Exception err)
  1045. {
  1046. ThrowXmdsException(gs.SkillID, mOwner.mInfo.TemplateID, err.ToString());
  1047. }
  1048. return ret;
  1049. }
  1050. /// <summary>
  1051. /// 报错方法.
  1052. /// </summary>
  1053. /// <param name="skill"></param>
  1054. /// <param name="unit"></param>
  1055. /// <param name="error"></param>
  1056. private void ThrowXmdsException(int skill, int unit, string error)
  1057. {
  1058. string msg = string.Format("XmdsSkill Init Error id : SkillID = {0} UnitID = {1},Error = {2}", skill, unit, error.ToString());
  1059. log.Error(msg);
  1060. throw new Exception(msg);
  1061. }
  1062. //更新技能状态.
  1063. private void UpdatePassiveSkills(int intervalMS, bool slowRefresh)
  1064. {
  1065. if (mPassiveSkills != null)
  1066. {
  1067. for (int i = 0; i < mPassiveSkills.Count; i++)
  1068. {
  1069. mPassiveSkills[i].Update(intervalMS, slowRefresh);
  1070. }
  1071. }
  1072. }
  1073. private void UpdateActiveSkills(int intervalMS, bool slowRefresh)
  1074. {
  1075. if (mActiveSkills != null)
  1076. {
  1077. for (int i = 0; i < mActiveSkills.Count; i++)
  1078. {
  1079. UnitSkill skillInfo = mActiveSkills[i];
  1080. if (skillInfo == null || !skillInfo.IsActive)
  1081. {
  1082. continue;
  1083. }
  1084. skillInfo.Update(intervalMS, slowRefresh);
  1085. }
  1086. }
  1087. }
  1088. #endregion
  1089. #region 常用API.
  1090. /// <summary>
  1091. /// 是否有该技能.
  1092. /// </summary>
  1093. /// <param name="id"></param>
  1094. /// <returns></returns>
  1095. public bool ContainSkill(int id)
  1096. {
  1097. return mSkillMap.ContainsKey(id);
  1098. }
  1099. /// <summary>
  1100. /// 获取技能信息.
  1101. /// </summary>
  1102. /// <param name="id"></param>
  1103. /// <returns></returns>
  1104. public GameSkill GetGameSkill(int id)
  1105. {
  1106. GameSkill ret = null;
  1107. mSkillMap.TryGetValue(id, out ret);
  1108. return ret;
  1109. }
  1110. //获取玩家技能
  1111. public UnitSkill GetPlayerSkillById(int skillId)
  1112. {
  1113. if (mActiveSkills == null)
  1114. {
  1115. return null;
  1116. }
  1117. for (int i = 0; i < mActiveSkills.Count; i++)
  1118. {
  1119. if (mActiveSkills[i].SkillID == skillId)
  1120. {
  1121. return mActiveSkills[i];
  1122. }
  1123. }
  1124. return null;
  1125. }
  1126. //获取玩家技能
  1127. public UnitPassiveSkill GetPlayerSkillByIdExt(int skillId)
  1128. {
  1129. if (mPassiveSkills == null)
  1130. {
  1131. return null;
  1132. }
  1133. for (int i = 0; i < mPassiveSkills.Count; i++)
  1134. {
  1135. if (mPassiveSkills[i].SkillID == skillId)
  1136. {
  1137. return mPassiveSkills[i];
  1138. }
  1139. }
  1140. return null;
  1141. }
  1142. /// <summary>
  1143. /// 获取主动技能模板.
  1144. /// </summary>
  1145. /// <param name="id"></param>
  1146. /// <returns></returns>
  1147. public SkillTemplate GetUnitSkillTemplate(int id)
  1148. {
  1149. SkillTemplate ret = null;
  1150. mActiveSkillTemplateMap.TryGetValue(id, out ret);
  1151. return ret;
  1152. }
  1153. public void RemoveSkill(CommonAI.Zone.Instance.InstanceUnit.SkillState sk)
  1154. {
  1155. if (mSkillMap != null)
  1156. {
  1157. GameSkill gs = null;
  1158. if (mSkillMap.TryGetValue(sk.ID, out gs))
  1159. {
  1160. mOwner.RemoveEventBySkillID(gs.SkillID);
  1161. mSkillMap.Remove(sk.ID);
  1162. }
  1163. for (int i = 0; i < mActiveSkills.Count; i++)
  1164. {
  1165. if (mActiveSkills[i].SkillID == sk.ID)
  1166. {
  1167. mActiveSkills.RemoveAt(i);
  1168. break;
  1169. }
  1170. }
  1171. }
  1172. if (mActiveSkillTemplateMap != null)
  1173. {
  1174. mActiveSkillTemplateMap.RemoveByKey(sk.ID);
  1175. mActiveSkillTemplateMap.Remove(sk.ID);
  1176. }
  1177. }
  1178. public void Update(int intervalMS, bool slowRefresh)
  1179. {
  1180. UpdatePassiveSkills(intervalMS, slowRefresh);
  1181. //2021.11.02优化:主动技能慢刷新,打开需要注明原因
  1182. if(slowRefresh)
  1183. {
  1184. UpdateActiveSkills(intervalMS, slowRefresh);
  1185. }
  1186. }
  1187. public int GetBaseSkillID()
  1188. {
  1189. if (mBaseSkill != null)
  1190. {
  1191. return mBaseSkill.ID;
  1192. }
  1193. return 0;
  1194. }
  1195. /// <summary>
  1196. /// 增加技能.
  1197. /// </summary>
  1198. /// <param name="list"></param>
  1199. public void AddSkill(List<GameSkill> list)
  1200. {
  1201. if (list != null && list.Count > 0)
  1202. {
  1203. List<GameSkill> active = new List<GameSkill>();
  1204. List<GameSkill> passive = new List<GameSkill>();
  1205. GetActivePassiveSkillList(list, ref active, ref passive);
  1206. GameSkill gs = null;
  1207. //主动技能.
  1208. for (int i = 0; i < active.Count; i++)
  1209. {
  1210. gs = active[i];
  1211. AddActiveSkill(gs);
  1212. }
  1213. for (int i = 0; i < passive.Count; i++)
  1214. {
  1215. gs = passive[i];
  1216. AddPassiveSkill(gs);
  1217. }
  1218. }
  1219. }
  1220. public UnitSkill AddActiveSkill(GameSkill gs, bool is_default = false)
  1221. {
  1222. SkillTemplate st = null;
  1223. UnitSkill us = null;
  1224. //存放技能等级信息.
  1225. mSkillMap.Put(gs.SkillID, gs);
  1226. us = InitXmdsSkillScript(gs, ref st);
  1227. if (st != null)
  1228. {
  1229. if (mActiveSkillTemplateMap == null)
  1230. {
  1231. mActiveSkillTemplateMap = new HashMap<int, SkillTemplate>();
  1232. }
  1233. mActiveSkillTemplateMap.Put(st.ID, st);
  1234. //us = XmdsBattleSkill.GetUnitSkill(gs.SkillID);
  1235. mOwner.mUnit.AddSkill(st, gs.AutoLaunch, is_default);
  1236. SkillState skillState = mOwner.SetSkillCD(gs.SkillID, gs.SkillTimestampMS);
  1237. mOwner.SetSkillCDDecreasePercent(gs.SkillID, gs.SkillCDDecreasePercent);
  1238. if (skillState != null)
  1239. {
  1240. skillState.Reset(true);
  1241. }
  1242. if (us != null)
  1243. {
  1244. mActiveSkills.Add(us);
  1245. us.InitOver(mOwner, gs);
  1246. }
  1247. }
  1248. return us;
  1249. }
  1250. public UnitPassiveSkill AddPassiveSkill(GameSkill gs)
  1251. {
  1252. UnitPassiveSkill ups = InitXmdsPassiveSkillScript(gs);
  1253. mSkillMap.Put(gs.SkillID, gs);
  1254. SetPassiveSkillCD(ups, gs.SkillTimestampMS);
  1255. SetPassiveSkillCDDecrease(ups, gs.SkillCDDecreasePercent);
  1256. if (mPassiveSkills == null)
  1257. {
  1258. mPassiveSkills = new List<UnitPassiveSkill>();
  1259. }
  1260. mPassiveSkills.Add(ups);
  1261. ups.InitOver(mOwner, gs);
  1262. return ups;
  1263. }
  1264. /// <summary>
  1265. /// 减少技能.
  1266. /// </summary>
  1267. /// <param name="list"></param>
  1268. public void RemoveSkill(List<GameSkill> list)
  1269. {
  1270. if (list != null && list.Count > 0)
  1271. {
  1272. List<GameSkill> active = new List<GameSkill>();
  1273. List<GameSkill> passive = new List<GameSkill>();
  1274. GetActivePassiveSkillList(list, ref active, ref passive);
  1275. GameSkill gs = null;
  1276. //主动技能.
  1277. for (int i = 0; i < active.Count; i++)
  1278. {
  1279. gs = active[i];
  1280. RemoveActiveSkill(gs.SkillID);
  1281. }
  1282. //删除被动技能.
  1283. for (int i = 0; i < passive.Count; i++)
  1284. {
  1285. if (mSkillMap.TryGetValue(passive[i].SkillID, out gs))
  1286. {
  1287. RemovePassiveSkill(gs.SkillID);
  1288. }
  1289. }
  1290. }
  1291. }
  1292. public void RemoveActiveSkill(int skillID)
  1293. {
  1294. if (mBaseSkill != null && skillID == mBaseSkill.ID)
  1295. {
  1296. mBaseSkill = null;
  1297. }
  1298. mOwner.mUnit.RemoveSkill(skillID); //调用该API收到remove事件再删除技能.
  1299. }
  1300. public void RemovePassiveSkill(int skillID)
  1301. {
  1302. mSkillMap.RemoveByKey(skillID);
  1303. for (int k = 0; k < mPassiveSkills.Count; k++)
  1304. {
  1305. if (mPassiveSkills[k].SkillID == skillID)
  1306. {
  1307. mPassiveSkills[k].Dispose(mOwner);
  1308. mPassiveSkills.RemoveAt(k);
  1309. mOwner.RemoveEventBySkillID(skillID);
  1310. break;
  1311. }
  1312. }
  1313. }
  1314. /// <summary>
  1315. /// 初始化技能.
  1316. /// </summary>
  1317. /// <param name="list"></param>
  1318. private void InitSkill(List<GameSkill> list)
  1319. {
  1320. List<GameSkill> active = new List<GameSkill>();
  1321. List<GameSkill> passive = new List<GameSkill>();
  1322. if (list.Count == 0)
  1323. {
  1324. return;
  1325. }
  1326. else if (this.mOwner.mUnit.IsPlayer)
  1327. {
  1328. //玩家有一些特殊的逻辑放到天赋被动里面
  1329. }
  1330. GetActivePassiveSkillList(list, ref active, ref passive);
  1331. InitPassiveSkills(passive);
  1332. InitActiveSkills(active);
  1333. //通知技能,初始化完成
  1334. notifyActiveSkillInitOver(active);
  1335. notifyPassiveSkillInitOver(passive);
  1336. this.mOwner.InitCardModule();
  1337. }
  1338. /// <summary>
  1339. /// 重置技能.
  1340. /// </summary>
  1341. /// <param name="list"></param>
  1342. public void ResetSkill(List<GameSkill> list, XmdsVirtual owner)
  1343. {
  1344. //1清除所有技能.
  1345. ClearSkill();
  1346. if (mSkillMap == null)
  1347. {
  1348. mSkillMap = new HashMap<int, GameSkill>();
  1349. }
  1350. mOwner = owner;
  1351. //2重新初始化技能.
  1352. InitSkill(list);
  1353. }
  1354. public void ReplaceSkill(List<GameSkill> list)
  1355. {
  1356. if (list == null) { return; }
  1357. GameSkill gs = null;
  1358. GameSkill new_gs = null;
  1359. for (int i = 0; i < list.Count; i++)
  1360. {
  1361. new_gs = list[i];
  1362. gs = null;
  1363. mSkillMap.TryGetValue(new_gs.SkillID, out gs);
  1364. if (gs != null)
  1365. {
  1366. gs.SkillLevel = new_gs.SkillLevel;
  1367. gs.TalentSkillLevel1 = new_gs.TalentSkillLevel1;
  1368. gs.TalentSkillLevel2 = new_gs.TalentSkillLevel2;
  1369. gs.TalentSkillLevel3 = new_gs.TalentSkillLevel3;
  1370. if (gs.SkillType == XmdsSkillType.passive)
  1371. {
  1372. if (mPassiveSkills != null)
  1373. {
  1374. for (int k = 0; k < mPassiveSkills.Count; k++)
  1375. {
  1376. if (mPassiveSkills[k].SkillID == gs.SkillID)
  1377. {
  1378. //去除原有CD修改值.
  1379. SetPassiveSkillCDDecrease(mPassiveSkills[k], -gs.SkillCDDecreasePercent);
  1380. //重新设置CD修改值.
  1381. SetPassiveSkillCDDecrease(mPassiveSkills[k], new_gs.SkillCDDecreasePercent);
  1382. //技能效果变化.
  1383. mPassiveSkills[k].SkillDataChange(gs, mOwner);
  1384. }
  1385. }
  1386. }
  1387. }
  1388. else
  1389. {
  1390. //去除原有CD修改值.
  1391. mOwner.SetSkillCDDecreasePercent(gs.SkillID, -gs.SkillCDDecreasePercent);
  1392. //重新设置CD修改值.
  1393. mOwner.SetSkillCDDecreasePercent(new_gs.SkillID, new_gs.SkillCDDecreasePercent);
  1394. for (int k = 0; k < mActiveSkills.Count; k++)
  1395. {
  1396. if (mActiveSkills[k].SkillID == new_gs.SkillID)
  1397. {
  1398. mActiveSkills[k].SkillDataChange(new_gs, mOwner);
  1399. break;
  1400. }
  1401. }
  1402. }
  1403. gs.SkillCDDecreasePercent = new_gs.SkillCDDecreasePercent;
  1404. }
  1405. }
  1406. }
  1407. /// <summary>
  1408. /// 清理技能.
  1409. /// </summary>
  1410. public void ClearSkill()
  1411. {
  1412. List<GameSkill> ret = new List<GameSkill>();
  1413. GameSkill g = null;
  1414. if (mSkillMap != null)
  1415. {
  1416. foreach (KeyValuePair<int, GameSkill> pair in mSkillMap)
  1417. {
  1418. g = new GameSkill();
  1419. g.SkillID = pair.Key;
  1420. g.SkillType = pair.Value.SkillType;
  1421. ret.Add(g);
  1422. }
  1423. RemoveSkill(ret);
  1424. }
  1425. }
  1426. public void Dispose()
  1427. {
  1428. ClearSkill();
  1429. mBaseSkill = null;
  1430. if (mSkillMap != null)
  1431. {
  1432. mSkillMap.Clear();
  1433. mSkillMap = null;
  1434. }
  1435. if (mActiveSkillTemplateMap != null)
  1436. {
  1437. mActiveSkillTemplateMap.Clear();
  1438. mActiveSkillTemplateMap = null;
  1439. }
  1440. if (mPassiveSkills != null)
  1441. {
  1442. mPassiveSkills.Clear();
  1443. mPassiveSkills = null;
  1444. }
  1445. mOwner = null;
  1446. }
  1447. #endregion
  1448. #region 特殊硬编码技能.
  1449. #endregion
  1450. }
  1451. /// <summary>
  1452. /// 技能状态信息.
  1453. /// </summary>
  1454. public class XmdsSkillStatusData
  1455. {
  1456. /// <summary>
  1457. /// 技能(技能ID,到期时间戳).
  1458. /// </summary>.
  1459. public HashMap<int, long> SkillTimestampMSMap = null;
  1460. }
  1461. //-----------------------职业天赋相关的接口-----------------------
  1462. public virtual IPlayerCache GetPlayerCache()
  1463. {
  1464. return this.mPlayerCache;
  1465. }
  1466. public virtual void SetPlayerCache(IPlayerCache cache)
  1467. {
  1468. this.mPlayerCache = cache;
  1469. }
  1470. public virtual void Talent__Add(int value)
  1471. {
  1472. if (this.mPlayerCache != null)
  1473. {
  1474. this.mPlayerCache.AddTalentValue(value);
  1475. }
  1476. }
  1477. public virtual bool Talent_Use(int value)
  1478. {
  1479. if (this.mPlayerCache != null)
  1480. {
  1481. return this.mPlayerCache.UseTalentValue(value);
  1482. }
  1483. return false;
  1484. }
  1485. public virtual int Talent_Value()
  1486. {
  1487. return mPlayerCache == null ? 0 : mPlayerCache.GetTalentValue();
  1488. }
  1489. public virtual int Talent_Lv()
  1490. {
  1491. return mPlayerCache == null ? 0 : mPlayerCache.GetTalentLv();
  1492. }
  1493. public virtual bool Talent_Refresh(bool notify = true)
  1494. {
  1495. if (this.mPlayerCache != null)
  1496. {
  1497. return this.mPlayerCache.Refresh(notify);
  1498. }
  1499. return false;
  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. }