XmdsVirtual.cs 75 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464
  1. using CommonAI.Zone;
  2. using CommonAI.Zone.Helper;
  3. using CommonAI.Zone.Instance;
  4. using CommonAI.Zone.Formula;
  5. using CommonLang;
  6. using CommonLang.Log;
  7. using System.Collections.Generic;
  8. using XmdsCommon.Message;
  9. using XmdsCommon.Plugin;
  10. using XmdsCommonServer.Plugin.XmdsSkillTemplate.Skills;
  11. using CommonAI.Zone.ZoneEditor;
  12. using System.Diagnostics;
  13. using XmdsCommonServer.Plugin.Units;
  14. using XmdsCommonServer.Plugin.XmdsSkillTemplate.DamageCalculator;
  15. using XmdsCommonServer.XLS.Data;
  16. using System;
  17. using XmdsCommonServer.Plugin.Scene;
  18. using CommonLang.Vector;
  19. using CommonLang.Concurrent;
  20. using CommonAI.Data;
  21. using static CommonAI.Zone.Instance.InstanceUnit;
  22. using CommonAI.data;
  23. using XmdsCommonServer.Plugin.Base;
  24. using XmdsCommonSkill.Plugin.CardSkill;
  25. namespace XmdsCommonServer.Plugin
  26. {
  27. /// <summary>
  28. /// FileName: XmdsVirtualUnit.cs
  29. /// </summary>
  30. public partial class XmdsVirtual : XmdsCommon.Plugin.VirtualUnitBase
  31. {
  32. private static AtomicInteger s_alloc_object_count = new AtomicInteger(0);
  33. /// <summary>
  34. /// 分配实例数量
  35. /// </summary>
  36. public static int AllocCount { get { return s_alloc_object_count.Value; } }
  37. #region Log.
  38. public static Logger log = LoggerFactory.GetDefLogger();
  39. public static void FormatLog(string txt, params object[] args)
  40. {
  41. if (args != null) { log.Debug(string.Format(txt, args)); }
  42. else { log.Debug(txt); }
  43. }
  44. public static void FormatLog(uint level, string txt, params object[] args)
  45. {
  46. if (args != null)
  47. {
  48. switch (level)
  49. {
  50. case LoggerLevel.ERROR:
  51. log.Error(string.Format(txt, args));
  52. break;
  53. case LoggerLevel.WARNNING:
  54. log.Warn(string.Format(txt, args));
  55. break;
  56. default:
  57. log.Debug(string.Format(txt, args));
  58. break;
  59. }
  60. }
  61. else
  62. {
  63. switch (level)
  64. {
  65. case LoggerLevel.ERROR:
  66. log.Error(txt);
  67. break;
  68. case LoggerLevel.WARNNING:
  69. log.Warn(txt);
  70. break;
  71. default:
  72. log.Debug(txt);
  73. break;
  74. }
  75. }
  76. }
  77. #endregion
  78. #region 战斗状态恢复配置.
  79. //血量恢复时间和系数,目前战中和非战中恢复速度一致.
  80. //HP回复频率.
  81. public static readonly int Coefficient_HPRebornTime = 5000;
  82. //战斗中HP回复系数.
  83. public static readonly float Coefficient_CombatHPReborn = 1f;
  84. #endregion
  85. readonly public UnitInfo mInfo;
  86. readonly public InstanceUnit mUnit;
  87. readonly public XmdsUnitProperties mProp;
  88. readonly public XmdsHateSystem mHateSystem;
  89. //是否完成初始化技能.
  90. protected bool mFinishSkillInit = false;
  91. public XmdsUnitProp MirrorProp;
  92. //脱战计时器.
  93. private TimeExpire<int> mOutOfCombatTime = null;
  94. //血量回复计时器.
  95. private TimeInterval<int> mHPRebornTimer = null;
  96. //定力值回复计时器.
  97. private TimeInterval<int> mMPRebornTimer = null;
  98. //出生点坐标.
  99. protected float mBirthPosX;
  100. protected float mBirthPosY;
  101. //坐骑状态.
  102. private bool mIsMounted = false;
  103. //是否在战斗状态.
  104. private BattleStatus mInCombatState = BattleStatus.None;
  105. //游戏服场景配置.
  106. public XmdsServerSceneData ServerSceneData = null;
  107. //隐身时队友是否可见.
  108. protected bool mTeamMemberVisible = true;
  109. public virtual bool TeamMemberVisible { get { return mTeamMemberVisible; } set { mTeamMemberVisible = value; } }
  110. //是否无敌.
  111. public bool IsInvincible { get; set; }
  112. //虚无状态无视技能.
  113. public bool NothingnessIgnoreSkill { get; set; }
  114. //虚无状态无视Buff效果.
  115. public bool NothingnessIgnoreBuff { get; set; }
  116. //虚无状态无视所有效果.
  117. public bool NothingnessIgnoreAll { get; set; }
  118. //恢复MP状态,不可打断
  119. public int mRecoverMPLeftTimes;
  120. //PVP触发的玩家id
  121. public string mPvpTriggerPlayerId;
  122. //战斗状态变更通知.
  123. public delegate void OnCombatChangeEvent(BattleStatus status);
  124. public event OnCombatChangeEvent OnHandleCombatChangeEvent
  125. {
  126. add { event_OnHandleCombatChangeEvent += value; }
  127. remove { event_OnHandleCombatChangeEvent -= value; }
  128. }
  129. protected event OnCombatChangeEvent event_OnHandleCombatChangeEvent;
  130. #region 属性变更.
  131. //操作指令申请计数.
  132. private int mPropChangeOperationCount = 0;
  133. //操作指令合集.
  134. private HashMap<int, PropChangeOperation> mPropChangeMap = new HashMap<int, PropChangeOperation>();
  135. protected PlayerBattlePropChangeEventB2C mBattlePropChangeEvt = null;
  136. private int mVirtualInventorySize = 0;
  137. #endregion
  138. #region 战斗状态变更原因.
  139. public const byte COMBATSTATE_CHANGE_REASON_DORESET = 1;
  140. #endregion
  141. public XmdsVirtual(InstanceUnit unit)
  142. {
  143. s_alloc_object_count++;
  144. mUnit = unit;
  145. mInfo = unit.Info;
  146. mProp = unit.Info.Properties as XmdsUnitProperties;
  147. mHateSystem = new XmdsHateSystem(this);
  148. }
  149. ~XmdsVirtual() { s_alloc_object_count--; }
  150. public void OnInit(InstanceUnit unit, bool pointLv)
  151. {
  152. UnitInfo info = unit.Info;
  153. FormatLog("- 初始化单位 : {0} - {0} ", unit.ID, unit.Name);
  154. Stopwatch sw = Stopwatch.StartNew();
  155. try
  156. {
  157. //出生点坐标.
  158. mBirthPosX = mUnit.X;
  159. mBirthPosY = mUnit.Y;
  160. //背包格子数.
  161. mVirtualInventorySize = mProp.ServerData.Prop.CurInventorySize;
  162. //非玩家,速度配置0
  163. if (mInfo.UType != UnitInfo.UnitType.TYPE_PLAYER && mProp.ServerData.Prop.MoveSpeed == 0)
  164. {
  165. mProp.ServerData.Prop.MoveSpeed = mInfo.MoveSpeedSEC;
  166. }
  167. //当前场景类型.
  168. InitSceneInfo();
  169. //子类初始化.
  170. Init(pointLv);
  171. //基础信息初始化.
  172. InitBaseData(mProp.ServerData.Prop);
  173. //坐骑信息记录.
  174. CheckMountStatus(mProp.ServerData.AvatarList);
  175. if (this.mCardModule == null)
  176. {
  177. this.CreateCreateCardModule();
  178. }
  179. //初始化技能信息.
  180. InitSkillInfo(mProp.ServerData);
  181. //脱战计时器初始化.
  182. InitOutOfCombatTime();
  183. //初始化HP恢复计时器.
  184. InitRebornTimer();
  185. //(最后执行)同步给客户度信息.
  186. SyncClientData();
  187. //施放技能监听.
  188. mUnit.OnLaunchSkill += OnLaunchSkillHandler;
  189. //技能新增监听.
  190. mUnit.OnSkillAdded += OnSkillAddHandler;
  191. //技能移除监听.
  192. mUnit.OnSkillRemoved += OnSkillRemoveHandler;
  193. //技能变更监听.
  194. mUnit.OnStateChanged += OnStateChangedHandler;
  195. //物品时候时触发.
  196. mUnit.OnUseItem += MUnit_OnUseItem;
  197. mUnit.OnSkillHitTarget += OnSkillHitTargetHandler;
  198. }
  199. catch(Exception e)
  200. {
  201. log.Error("单位初始化异常:" + unit.Info.ID + ", " + e);
  202. }
  203. finally
  204. {
  205. sw.Stop();
  206. if (sw.ElapsedMilliseconds > 10)
  207. {
  208. FormatLog("XmdsVirtual create overload , stopwatch time {0} > 10ms", sw.ElapsedMilliseconds);
  209. }
  210. }
  211. }
  212. private void MUnit_OnUseItem(InstanceUnit obj, ItemTemplate item, InstanceUnit item_creater)
  213. {
  214. BattleFunction battleFuntion = BattleFunction.GetInstance();
  215. if (item != null && battleFuntion != null)
  216. {
  217. int id = (item.Properties as XmdsItemProperties).TriggerFunctionID;
  218. if (id != 0)
  219. {
  220. battleFuntion.TriggrBattleFunction(id, this, this);
  221. }
  222. }
  223. }
  224. public void OnDispose(InstanceUnit owner)
  225. {
  226. if(this.mUnit != null)
  227. {
  228. //施放技能监听.
  229. mUnit.OnLaunchSkill -= OnLaunchSkillHandler;
  230. //技能新增监听.
  231. mUnit.OnSkillAdded -= OnSkillAddHandler;
  232. //技能移除监听.
  233. mUnit.OnSkillRemoved -= OnSkillRemoveHandler;
  234. //技能变更监听.
  235. mUnit.OnStateChanged -= OnStateChangedHandler;
  236. //物品时候时触发.
  237. mUnit.OnUseItem -= MUnit_OnUseItem;
  238. mUnit.OnSkillHitTarget -= OnSkillHitTargetHandler;
  239. }
  240. Dispose();
  241. }
  242. /// <summary>
  243. /// 供子类重铸.
  244. /// </summary>
  245. protected virtual void Init(bool pointLv) { }
  246. public bool IsFinishSkillInit()
  247. {
  248. return mFinishSkillInit;
  249. }
  250. #region 常用API.
  251. protected virtual void SyncClientData()
  252. {
  253. //推属性变更计算.
  254. UnitPropRefresh();
  255. //第一次将全部属性推给客户端.
  256. SyncBattlePropsFields(PlayerBattlePropChangeEventB2C.MASK_ALL);
  257. }
  258. public int GetUnitLv()
  259. {
  260. if (this.mProp.ServerData.BaseInfo.UnitLv == 0)
  261. {
  262. return 1;
  263. }
  264. return this.mProp.ServerData.BaseInfo.UnitLv;
  265. }
  266. public int GetStateLv()
  267. {
  268. return this.mProp.ServerData.BaseInfo.StateLv;
  269. }
  270. // 神器id
  271. public int GetArtifactIndex()
  272. {
  273. return ((XmdsUnitProp)mProp.ServerData.Prop).ArtifactIndex;
  274. }
  275. //获得神器克制id
  276. public bool IsArtifactRestrain(UnitFateType fateType)
  277. {
  278. return ((int)fateType-1) == (((XmdsUnitProp)mProp.ServerData.Prop).ArtifactIndex + 1) % 5;
  279. }
  280. //是否有神器
  281. public bool IsHasArtifact()
  282. {
  283. return ((XmdsUnitProp)mProp.ServerData.Prop).ArtifactIndex != (int)ArtifactType.None;
  284. }
  285. //神器背饰id
  286. public int GetArtifactDefenceIndex()
  287. {
  288. return ((XmdsUnitProp)mProp.ServerData.Prop).ArtifactDefenceIndex;
  289. }
  290. protected void InitBaseInfo(XmdsUnitBaseInfo baseInfo)
  291. {
  292. //同步等级信息.
  293. mProp.ServerData.BaseInfo = baseInfo;
  294. this.mUnit.Level = mProp.ServerData.BaseInfo.UnitLv;
  295. }
  296. public HateSystem GetHateSystem()
  297. {
  298. return mHateSystem;
  299. }
  300. /// <summary>
  301. /// 获得攻击目标.
  302. /// </summary>
  303. /// <returns></returns>
  304. public virtual InstanceUnit GetAtkTarget(InstanceUnit target)
  305. {
  306. var unit_prop = target.Virtual as XmdsVirtual;
  307. return DispatchGetAtkUnitEvent(unit_prop).mUnit;
  308. }
  309. /// <summary>
  310. /// 物品触发单位加血效果.
  311. /// </summary>
  312. /// <param name="hp"></param>
  313. public int AddHPByItem(int hp)
  314. {
  315. int v = hp;
  316. this.mUnit.ReduceHP(-v, null, false, null);
  317. return v;
  318. }
  319. /// <summary>
  320. /// 女武神能量变更.
  321. /// </summary>
  322. /// <param name="value"></param>
  323. public void AddEnergyByItem(int value)
  324. {
  325. }
  326. /// <summary>
  327. /// 通知单位接收跳字事件.
  328. /// </summary>
  329. /// <param name="objID"></param>
  330. /// <param name="value"></param>
  331. public void SendHPChangeMessage(uint objID, int value)
  332. {
  333. BattleHintNumberB2C evt = new BattleHintNumberB2C();
  334. evt.Value = -value;
  335. evt.State = (byte)UnitHitEventState.Normal;
  336. evt.TargetObjID = this.mUnit.ID;
  337. this.mUnit.queueEvent(evt);
  338. }
  339. /// <summary>
  340. /// 通知单位接收能量变更跳字事件.
  341. /// </summary>
  342. /// <param name="objID"></param>
  343. /// <param name="value"></param>
  344. public void SendMPChangeMessage(uint objID, int value)
  345. {
  346. BattleHintNumberB2C evt = new BattleHintNumberB2C();
  347. evt.Value = -value;
  348. evt.State = (byte)UnitHitEventState.MP;
  349. evt.TargetObjID = this.mUnit.ID;
  350. this.mUnit.queueEvent(evt);
  351. }
  352. public void SendBattleHintNumberB2C(int Value, UnitHitEventState type, uint targetId = 0)
  353. {
  354. BattleHintNumberB2C evt = new BattleHintNumberB2C();
  355. evt.Value = Value;
  356. evt.State = (byte)type;
  357. evt.TargetObjID = targetId == 0 ? this.mUnit.ID : targetId;
  358. this.mUnit.queueEvent(evt);
  359. }
  360. /// <summary>
  361. /// 加血.
  362. /// </summary>
  363. /// <param name="hp">血量</param>
  364. /// <param name="sender">加血者</param>
  365. /// <param name="sendMsg">是否发送协议</param>
  366. public void AddHP(int hp, InstanceUnit sender = null, bool sendMsg = true, DamageSource dmgSrc = DamageSource.Def)
  367. {
  368. this.mUnit.ReduceHP(-hp, sender, sendMsg, null, false, dmgSrc);
  369. }
  370. public void AddHP(int hp, InstanceUnit sender, DamageSource dmgSrc)
  371. {
  372. this.mUnit.ReduceHP(-hp, sender, true, null, false, dmgSrc);
  373. }
  374. /// <summary>
  375. /// 加能量.
  376. /// </summary>
  377. /// <param name="mp"></param>
  378. /// <param name="sendMsg">是否发送协议</param>
  379. public void AddMP(int mp, InstanceUnit sender, bool sendMsg = true, bool force = false, AttackSource source = null)
  380. {
  381. this.mUnit.AddMP(mp, sender, force, false, source);
  382. }
  383. public void AddMP(int mp, InstanceUnit sender, AttackSource source)
  384. {
  385. this.mUnit.AddMP(mp, sender, true, false, source);
  386. }
  387. public bool IsCanReduceMP(bool force)
  388. {
  389. return force || mRecoverMPLeftTimes <= 0;
  390. }
  391. /// <summary>
  392. /// 获得角色原始属性.
  393. /// </summary>
  394. /// <returns></returns>
  395. public XmdsUnitProp GetOriginProp()
  396. {
  397. return mProp.ServerData.Prop;
  398. }
  399. /// <summary>
  400. /// 判断一定概率是否触发概率单位为万分比:填写1000表示百分之10.
  401. /// </summary>
  402. /// <param name="percent"></param>
  403. /// <returns></returns>
  404. public bool RandomPercent(int percent)
  405. {
  406. return XmdsDamageCalculator.IsInRandomRange(percent,
  407. this.mUnit.RandomN, (int)XmdsDamageCalculator.PERER);
  408. }
  409. protected virtual void Dispose()
  410. {
  411. DestorySkill();
  412. mOutOfCombatTime = null;
  413. mHPRebornTimer = null;
  414. mMPRebornTimer = null;
  415. OnHealEventHandle = null;
  416. event_OnCombatStateChangeHandle = null;
  417. event_OnHandleCombatChangeEvent = null;
  418. mBattlePropChangeEvt = null;
  419. if(this.mCardModule != null)
  420. {
  421. this.mCardModule.Dispose();
  422. }
  423. ClearRegistEvent();
  424. mHateSystem.Dispose();
  425. }
  426. /// <summary>
  427. /// 是否在异常状态内.
  428. /// </summary>
  429. /// <returns></returns>
  430. public bool IsInDebuffStatus()
  431. {
  432. bool ret = false;
  433. if (this.mUnit.IsStun || this.mUnit.IsSilent)
  434. {
  435. ret = true;
  436. }
  437. //取当前所有BUFF,判断如果有隐身BUFF立即解除该BUFF.
  438. using (var buffList = ListObjectPool<InstanceUnit.BuffState>.AllocAutoRelease())
  439. {
  440. this.mUnit.GetAllBuffStatus(buffList);
  441. if (buffList != null && buffList.Count > 0)
  442. {
  443. for (int i = 0; i < buffList.Count; i++)
  444. {
  445. if (XmdsInstanceUtils.IsControlBuff(buffList[i].Data))
  446. {
  447. return true;
  448. }
  449. }
  450. }
  451. }
  452. return ret;
  453. }
  454. //移除控制buff
  455. public void RemoveControlBuff()
  456. {
  457. //取当前所有BUFF,判断如果有隐身BUFF立即解除该BUFF.
  458. using (var buffList = ListObjectPool<InstanceUnit.BuffState>.AllocAutoRelease())
  459. {
  460. //InstanceUnit.BuffState bfs = null;
  461. //XmdsBuffProperties prop = null;
  462. //BuffTemplate bt = null;
  463. this.mUnit.GetAllBuffStatus(buffList);
  464. if (buffList == null || buffList.Count <= 0)
  465. {
  466. return;
  467. }
  468. for (int i = 0; i < buffList.Count; i++)
  469. {
  470. if (XmdsInstanceUtils.IsControlBuff(buffList[i].Data))
  471. {
  472. this.mUnit.removeBuff(buffList[i].Data.ID);
  473. }
  474. }
  475. }
  476. }
  477. protected bool IsBusy()
  478. {
  479. bool ret = false;
  480. if (this.mUnit.CurrentState != null &&
  481. (this.mUnit.CurrentState is InstanceUnit.StateSkill))// ||
  482. //(this.mUnit.CurrentState is InstanceUnit.StatePickObject))
  483. {
  484. ret = true;
  485. }
  486. return ret;
  487. }
  488. /// <summary>
  489. /// 向战斗服发送提示信息.
  490. /// </summary>
  491. /// <param name="msg"></param>
  492. public void SendMsgToClient(string msg)
  493. {
  494. if (msg != null)
  495. {
  496. ShowTipsEventB2C evt = new ShowTipsEventB2C();
  497. evt.Msg = msg;
  498. this.mUnit.queueEvent(evt);
  499. }
  500. }
  501. //单独给玩家发送消息,非广播
  502. public void SendMsgToPlayer(ObjectEvent evt, bool force = false)
  503. {
  504. this.mUnit.queueEvent(evt, force);
  505. }
  506. /// <summary>
  507. /// 获取当前可用背包格子数量.
  508. /// </summary>
  509. /// <returns></returns>
  510. public int GetInventorySize()
  511. {
  512. if (mProp != null)
  513. {
  514. return mProp.ServerData.Prop.CurInventorySize;
  515. }
  516. return 0;
  517. }
  518. public void SetInventorySize(int size)
  519. {
  520. if (mProp != null)
  521. {
  522. mProp.ServerData.Prop.CurInventorySize = size;
  523. VirtualInventorySize = size;
  524. }
  525. }
  526. public int VirtualInventorySize
  527. {
  528. get { return mVirtualInventorySize; }
  529. set { mVirtualInventorySize = value; }
  530. }
  531. /// <summary>
  532. /// 组队背包格子数.
  533. /// </summary>
  534. /// <returns></returns>
  535. public int GetTeamInventorySize()
  536. {
  537. if (mProp != null)
  538. {
  539. return mProp.ServerData.Prop.CurTeamInventorySize;
  540. }
  541. return 0;
  542. }
  543. public bool ContainBuff(bool isDebuff)
  544. {
  545. using (var buffList = ListObjectPool<InstanceUnit.BuffState>.AllocAutoRelease())
  546. {
  547. InstanceUnit.BuffState bfs = null;
  548. XmdsBuffProperties prop = null;
  549. BuffTemplate bt = null;
  550. this.mUnit.GetAllBuffStatus(buffList);
  551. if (buffList != null && buffList.Count > 0)
  552. {
  553. for (int i = 0; i < buffList.Count; i++)
  554. {
  555. bfs = buffList[i];
  556. bt = bfs.Data;
  557. prop = bt.Properties as XmdsBuffProperties;
  558. if (prop.Dispelled == false) { continue; }
  559. if (bt.IsHarmful == isDebuff)
  560. {
  561. return true;
  562. }
  563. }
  564. }
  565. }
  566. return false;
  567. }
  568. /// <summary>
  569. /// 记录同步可视数据.
  570. /// 战斗服数据大致分为两块,一部分用作战斗计算使用,另一部分用作同步客户端表现相关信息,
  571. /// 当表现信息变更时,需要将数据同步给syncInfo,底层每次调用时时直接拿syncInfo来推送.
  572. /// </summary>
  573. protected void SyncPlayerVisibleData()
  574. {
  575. if (this.mUnit.VisibleInfo is PlayerVisibleDataB2C)
  576. {
  577. PlayerVisibleDataB2C pvd = this.mUnit.VisibleInfo as PlayerVisibleDataB2C;
  578. pvd.AvatarList = this.mProp.ServerData.AvatarList;
  579. pvd.BaseInfo = this.mProp.ServerData.BaseInfo;
  580. pvd.UnitPKInfo = this.mProp.ServerData.UnitPKInfo;
  581. pvd.UnitSceneInfo = this.mProp.ServerData.UnitSceneInfo;
  582. }
  583. }
  584. /// <summary>
  585. /// 当前场景信息初始化记录.
  586. /// </summary>
  587. protected virtual void InitSceneInfo()
  588. {
  589. EditorScene es = mUnit.Parent as EditorScene;
  590. XmdsSceneProperties zp = es.Data.Properties as XmdsSceneProperties;
  591. ServerSceneData = zp.ServerSceneData;
  592. }
  593. protected bool CalPKValue(XmdsVirtual target)
  594. {
  595. //特殊规则,跨服场景,击杀非本服玩家.
  596. if (this.mUnit.GetSceneType() >= CommonAI.Data.SceneType.CROSS_SERVER_NEW)
  597. {
  598. XmdsVirtual_Player r = target.GetPlayerUnit();
  599. if (r != null && this.GetServerID() != r.GetServerID())
  600. {
  601. return false;
  602. }
  603. }
  604. return ServerSceneData.CalPKValue;
  605. }
  606. public virtual PKMode GetCurPKMode()
  607. {
  608. if (mProp.ServerData.UnitPKInfo != null)
  609. {
  610. return mProp.ServerData.UnitPKInfo.CurPKMode;
  611. }
  612. return PKMode.Peace;
  613. }
  614. /// <summary>
  615. /// 获得当前PK等级(判断是否为红名).
  616. /// </summary>
  617. /// <returns></returns>
  618. public virtual PKLevel GetCurPKLevel()
  619. {
  620. PKLevel ret = PKLevel.White;
  621. if (mProp != null && mProp.ServerData.UnitPKInfo != null)
  622. {
  623. ret = mProp.ServerData.UnitPKInfo.CurPKLevel;
  624. }
  625. return ret;
  626. }
  627. /// <summary>
  628. /// 服ID.
  629. /// </summary>
  630. /// <returns></returns>
  631. public virtual int GetServerID()
  632. {
  633. int ret = 0;
  634. if (this.mProp.ServerData != null && this.mProp.ServerData.BaseInfo != null)
  635. {
  636. ret = this.mProp.ServerData.BaseInfo.ServerID;
  637. }
  638. return ret;
  639. }
  640. /// <summary>
  641. /// 获得公会ID.
  642. /// </summary>
  643. /// <returns></returns>
  644. public virtual string GetGuildID()
  645. {
  646. string ret = null;
  647. if (this.mProp.ServerData != null && this.mProp.ServerData.BaseInfo != null)
  648. {
  649. ret = this.mProp.ServerData.BaseInfo.GuildID;
  650. }
  651. return ret;
  652. }
  653. /// <summary>
  654. /// 获得阵营ID
  655. /// </summary>
  656. /// <returns></returns>
  657. public virtual int GetForceID()
  658. {
  659. return this.mUnit.Force;
  660. }
  661. /// <summary>
  662. /// 获得单位ID(玩家返回UUID).
  663. /// </summary>
  664. /// <returns></returns>
  665. public virtual string GetPlayerUUID()
  666. {
  667. return mUnit.ID.ToString();
  668. }
  669. /// <summary>
  670. /// 重置功能,血量、buff、状态、技能全部变为初始状态.
  671. /// </summary>
  672. public void Reset()
  673. {
  674. //脱战.
  675. SetCombatState(BattleStatus.None, 1);
  676. //BUFF.
  677. this.mUnit.clearBuffs();
  678. //技能CD.
  679. this.mUnit.ClearAllSkillCD();
  680. //坐骑状态.
  681. this.TakeOffMount();
  682. //回血重置.
  683. if (mHPRebornTimer != null)
  684. {
  685. mHPRebornTimer.Reset();
  686. }
  687. if(mMPRebornTimer != null)
  688. {
  689. mMPRebornTimer.Reset();
  690. }
  691. this.mUnit.startRebirth();
  692. this.mUnit.CurrentHP = this.mUnit.MaxHP;
  693. this.mUnit.CurrentMP = this.mUnit.MaxMP;
  694. }
  695. /// <summary>
  696. /// 获取当前强度类型
  697. /// </summary>
  698. /// <returns></returns>
  699. public string GetCurSceneType()
  700. {
  701. return ServerSceneData.SceneHard;
  702. }
  703. /// <summary>
  704. /// 获取当前场景类型
  705. /// </summary>
  706. /// <returns></returns>
  707. public CommonAI.XmdsConstConfig.AreaType CurAreaType()
  708. {
  709. return ServerSceneData.CurAreaType;
  710. }
  711. protected virtual void OnHeal(XmdsVirtual attcker, int value, ref AtkResult result)
  712. {
  713. if (OnHealEventHandle != null)
  714. {
  715. OnHealEventHandle.Invoke(attcker, this, value, ref result);
  716. }
  717. }
  718. public void SendBattleFloatTipsEventB2C(BattleFloatTipsEventB2C evt)
  719. {
  720. if (evt != null)
  721. {
  722. this.mUnit.queueEvent(evt);
  723. }
  724. }
  725. public void SendBubbleTipsEventB2C(string msg)
  726. {
  727. if (!string.IsNullOrEmpty(msg))
  728. {
  729. var evt = new BubbleTipsEventB2C();
  730. evt.Msg = msg;
  731. this.mUnit.queueEvent(evt);
  732. }
  733. }
  734. /// <summary>
  735. /// 能否使用物品.
  736. /// </summary>
  737. /// <returns></returns>
  738. public bool CanUseItem()
  739. {
  740. bool ret = true;
  741. ret = (!this.mUnit.IsSilent);
  742. return ret;
  743. }
  744. /// <summary>
  745. /// 同步归属权信息.
  746. /// </summary>
  747. /// <param name="name"></param>
  748. /// <param name="protype"></param>
  749. public virtual void SyncHeirsInfo(string name, int hpPercent, CommonAI.Data.XmdsUnitPro protype)
  750. {
  751. }
  752. /// <summary>
  753. /// 是否可被攻击.
  754. /// </summary>
  755. public virtual bool IsAttackable(XmdsVirtual attacker)
  756. {
  757. return true;
  758. }
  759. public virtual int GetVirtualTemplateID()
  760. {
  761. return mInfo.TemplateID;
  762. }
  763. /// <summary>
  764. /// 治愈效果,满血、满蓝.
  765. /// </summary>
  766. public virtual void DoCure()
  767. {
  768. this.AddHP(this.mUnit.MaxHP, null, false);
  769. this.AddMP(this.mUnit.MaxMP, null, false, true);
  770. }
  771. public bool SkillAutoLaunchTest(InstanceUnit.SkillState ss)
  772. {
  773. bool ret = false;
  774. UnitSkill us = XmdsBattleSkill.GetUnitSkill(ss.Data.ID); ;
  775. if (us != null)
  776. {
  777. ret = us.SkillAutoLaunchTest(ss, this);
  778. }
  779. return ret;
  780. }
  781. #endregion
  782. #region 基础事件.
  783. /// <summary>
  784. /// 角色本身的初始化.
  785. /// </summary>
  786. /// <param name="unit"></param>
  787. private void Unit_OnActivated(InstanceUnit unit)
  788. {
  789. mUnit.OnActivated -= Unit_OnActivated;
  790. }
  791. //主动移除技能.
  792. public GameSkill RemoveSkill(int skillID)
  793. {
  794. GameSkill skillData = this.SkillHelper.GetGameSkill(skillID);
  795. if (skillData == null)
  796. {
  797. return null;
  798. }
  799. if (skillData.SkillType == XmdsSkillType.passive || skillData.SkillType == XmdsSkillType.petGivePassive)
  800. {
  801. this.SkillHelper.RemovePassiveSkill(skillID);
  802. return null;
  803. }
  804. else
  805. {
  806. SkillState skillState = this.mUnit.getSkillState(skillID);
  807. this.SkillHelper.RemoveActiveSkill(skillID);
  808. return skillData;
  809. }
  810. }
  811. #endregion
  812. #region 安全区域
  813. private bool mIsInSafeArea = false;
  814. /// <summary>
  815. /// 是否在安全区域
  816. /// </summary>
  817. public bool IsInSafeArea(){ return mIsInSafeArea; }
  818. //跟新战斗区域状态
  819. private void UpdateAreaState(int intervalMS)
  820. {
  821. //var sa = mUnit.Parent.GetArea(mUnit.X, mUnit.Y);
  822. var sa = mUnit.CurrentArea;
  823. if (sa != null && sa.CurrentMapNodeValue == XmdsMapBlock.BLOCK_VALUE_SAFE)
  824. {
  825. this.mIsInSafeArea = true;
  826. }
  827. else
  828. {
  829. this.mIsInSafeArea = false;
  830. }
  831. }
  832. #endregion
  833. #region 战斗状态.
  834. /// <summary>
  835. /// 是否在战斗状态.
  836. /// </summary>
  837. public BattleStatus CombatState
  838. {
  839. get { return mInCombatState; }
  840. }
  841. public virtual void SetCombatState(BattleStatus value, byte reason = 0, String pvpTriggerPlayerId = "")
  842. {
  843. // 只有在空闲状态才允许设置技能展示状态
  844. if (value == BattleStatus.ReadyBattle && mInCombatState != BattleStatus.None)
  845. {
  846. return;
  847. }
  848. if (value != BattleStatus.None && mOutOfCombatTime != null)
  849. {
  850. mOutOfCombatTime.Reset();
  851. }
  852. if (mInCombatState != value)
  853. {
  854. if (value == BattleStatus.None)
  855. {
  856. if (JudgeChangeCombatStateChange(value, reason))
  857. {
  858. mInCombatState = value;
  859. CombatStateConnect(value, reason);
  860. OnCombatStateChange(mInCombatState);
  861. //单位脱战了
  862. this.mUnit.Parent.cb_unitOutBattleCallBack(this.mUnit);
  863. }
  864. }
  865. else if (value > mInCombatState)//战斗状态等级不同.
  866. {
  867. if (JudgeChangeCombatStateChange(value, reason))
  868. {
  869. mInCombatState = value;
  870. CombatStateConnect(value, reason);
  871. OnCombatStateChange(mInCombatState);
  872. }
  873. }
  874. }
  875. if(mInCombatState == BattleStatus.PVP)
  876. {
  877. this.mPvpTriggerPlayerId = pvpTriggerPlayerId;
  878. }
  879. }
  880. public bool IsInPVP()
  881. {
  882. return mInCombatState == BattleStatus.PVP ? true : false;
  883. }
  884. public bool IsInPVE()
  885. {
  886. return mInCombatState == BattleStatus.PVE ? true : false;
  887. }
  888. public BattleStatus GetBattleStatus()
  889. {
  890. return mInCombatState;
  891. }
  892. //坐骑状态变更.
  893. public bool IsMounted
  894. {
  895. set { mIsMounted = value; }
  896. get { return mIsMounted; }
  897. }
  898. private void CheckMountStatus(List<XmdsAvatarInfo> list)
  899. {
  900. if (list != null)
  901. {
  902. for (int i = 0; i < list.Count; i++)
  903. {
  904. if (list[i].PartTag == XmdsAvatarInfo.XmdsAvatar.Ride_Equipment)
  905. {
  906. if (!string.IsNullOrEmpty(list[i].FileName))
  907. {
  908. //有坐骑信息.
  909. IsMounted = true;
  910. break;
  911. }
  912. }
  913. }
  914. }
  915. }
  916. //状态改变时候触发.
  917. protected virtual void OnCombatStateChange(BattleStatus status)
  918. {
  919. //脱战时,清空仇恨列表.
  920. if (status == BattleStatus.None && this.mUnit.IsDead() == false)
  921. {
  922. mHateSystem.Clear();
  923. if (event_OnCombatStateChangeHandle != null)
  924. {
  925. event_OnCombatStateChangeHandle.Invoke(this, false);
  926. }
  927. FormatLog("{0}脱离战斗", mInfo.Name);
  928. }
  929. //状态变更时,需要同步告知客户端做响应表现.
  930. if (status != BattleStatus.None)
  931. {
  932. FormatLog("{0}进入战斗", mInfo.Name);
  933. }
  934. SyncUnitCombatState(status);
  935. if (event_OnHandleCombatChangeEvent != null)
  936. {
  937. event_OnHandleCombatChangeEvent.Invoke(status);
  938. }
  939. var scene = (mUnit.Parent as XmdsServerScene);
  940. scene.callback_OnCombatStateChange(this.mUnit, status);
  941. }
  942. protected virtual bool JudgeChangeCombatStateChange(BattleStatus status, byte reason)
  943. {
  944. bool ret = true;
  945. //默认为0,特殊情况不为0.
  946. if (reason != 0)
  947. {
  948. ret = true;
  949. }
  950. else
  951. {
  952. if (status == BattleStatus.None)
  953. {
  954. //表示单位一旦开始追击不会退出战斗状态.
  955. if (this.mUnit.Info.GuardRangeLimit == 0)
  956. {
  957. return false;
  958. }
  959. }
  960. }
  961. return ret;
  962. }
  963. protected virtual void ChangeCombatStateFromAtk(XmdsVirtual target)
  964. {
  965. var s = (this.IsPlayerUnit() && target.IsPlayerUnit()) ? BattleStatus.PVP : BattleStatus.PVE;
  966. SetCombatState(s, 0, target.mUnit.PlayerUUID);
  967. }
  968. protected virtual void CombatStateConnect(BattleStatus status, byte reason)
  969. {
  970. }
  971. public virtual void OnHitOthter(XmdsVirtual target)
  972. {
  973. }
  974. private void SyncUnitCombatState(BattleStatus status)
  975. {
  976. //改走通用字段.
  977. //mUnit.queueEvent(new CombatStateChangeEvent(mUnit.ID, status));
  978. //Dummy_0用来同步战斗状态.
  979. mUnit.Dummy_0 = (byte)status;
  980. }
  981. //脱战计时器.
  982. private void InitOutOfCombatTime()
  983. {
  984. if (mProp.IsUseCombatTimeCount == true)
  985. {
  986. if (this.mUnit.IsMonster)
  987. {
  988. mOutOfCombatTime = new TimeExpire<int>(XmdsConfig.Instance.OUTOF_BATTLE_MONSTER);
  989. }
  990. else
  991. {
  992. mOutOfCombatTime = new TimeExpire<int>(XmdsConfig.Instance.OUTOF_BATTLE_PLAYER);
  993. }
  994. }
  995. }
  996. //更新脱战计时.
  997. private void UpdateOutOfCombatTime(int time)
  998. {
  999. if (mInCombatState != BattleStatus.None && mOutOfCombatTime != null && mOutOfCombatTime.Update(time))
  1000. {
  1001. SetCombatState(BattleStatus.None);
  1002. }
  1003. }
  1004. #endregion
  1005. #region 基础信息.
  1006. protected void InitBaseData(XmdsUnitProp data)
  1007. {
  1008. //复制原始单位数据.
  1009. MirrorProp = (XmdsUnitProp)data.Clone();
  1010. this.mUnit.SetMaxHP(data.MaxHP, true);
  1011. if (data.HP >= 0)
  1012. {
  1013. this.mUnit.CurrentHP = data.HP;
  1014. }
  1015. this.mUnit.MaxMP = data.ShieldValue;
  1016. this.mUnit.CurrentMP = data.ShieldValue;
  1017. SycSkillCdReduce();
  1018. SycControledTimeReduce();
  1019. SycMoveSpeed();
  1020. SycAttackSpeed();
  1021. }
  1022. public void SycMoveSpeed()
  1023. {
  1024. this.mUnit.SetMoveSpeed(this.MirrorProp.MoveSpeed);
  1025. }
  1026. private void SycAttackSpeed()
  1027. {
  1028. this.mUnit.SetAttackSpeed(this.MirrorProp.AttackSpeed);
  1029. }
  1030. private void SycMaxHP()
  1031. {
  1032. mUnit.SetMaxHP(this.MirrorProp.MaxHP, true);
  1033. }
  1034. private void SycSkillCdReduce()
  1035. {
  1036. mUnit.SetSkillCdReduce(this.MirrorProp.SkillCD);
  1037. }
  1038. private void SycControledTimeReduce()
  1039. {
  1040. mUnit.SetControledTimeReduce(this.MirrorProp.CtrlTimeReduce);
  1041. }
  1042. #endregion
  1043. #region 血量回复.
  1044. private void InitRebornTimer()
  1045. {
  1046. if (mHPRebornTimer == null)
  1047. {
  1048. mHPRebornTimer = new TimeInterval<int>(Coefficient_HPRebornTime);
  1049. mHPRebornTimer.FirstTimeEnable = false;
  1050. }
  1051. if(mMPRebornTimer == null)
  1052. {
  1053. mMPRebornTimer = new TimeInterval< int > (GlobalData.SHIELD_RECOVER_INTERVAL);
  1054. mMPRebornTimer.FirstTimeEnable = false;
  1055. }
  1056. }
  1057. private void UpdateHPReborn(int intervalMS)
  1058. {
  1059. try
  1060. {
  1061. if (MirrorProp.HPReborn > 0 && this.mUnit.CurrentHP < this.mUnit.MaxHP && mHPRebornTimer != null && !this.mUnit.IsDead())
  1062. {
  1063. if (mHPRebornTimer.Update(intervalMS))
  1064. {
  1065. if (mInCombatState != BattleStatus.None)
  1066. {
  1067. int v = CUtils.CastInt(MirrorProp.MaxHPReborn * Coefficient_CombatHPReborn);
  1068. this.mUnit.AddHP(v, null);
  1069. }
  1070. else
  1071. {
  1072. this.mUnit.AddHP(MirrorProp.MaxHPReborn, null);
  1073. }
  1074. }
  1075. }
  1076. }
  1077. catch(Exception e)
  1078. {
  1079. log.Error("UpdateHPReborn catch : " + this.mUnit.Info.ID + ", IsActive: " + this.mUnit.IsActive +
  1080. ", " + (mMPRebornTimer == null ? "timer null" : "OK") + ", " + e);
  1081. }
  1082. }
  1083. private void UpdateMPReborn(int intervalMS)
  1084. {
  1085. try
  1086. {
  1087. if(this.mRecoverMPLeftTimes > 0 && mMPRebornTimer != null && mMPRebornTimer.Update(intervalMS))
  1088. {
  1089. int addMP = 0;
  1090. if(--this.mRecoverMPLeftTimes == 0)
  1091. {
  1092. addMP = this.mUnit.MaxMP - this.mUnit.CurrentMP;
  1093. }
  1094. else
  1095. {
  1096. addMP = this.mUnit.MaxMP / GlobalData.SHIELD_RECOVER_TIME;
  1097. }
  1098. this.AddMP(addMP, null);
  1099. }
  1100. }
  1101. catch (Exception e)
  1102. {
  1103. log.Error("UpdateMPReborn catch : " + this.mUnit.Info.ID + ", IsActive: " + this.mUnit.IsActive +
  1104. ", " + (mMPRebornTimer == null ? "timer null" : "OK") + ", " + e);
  1105. }
  1106. }
  1107. public void StartRecoverMP(bool reset = false)
  1108. {
  1109. if (reset)
  1110. {
  1111. this.mRecoverMPLeftTimes = 0;
  1112. }
  1113. else
  1114. {
  1115. this.mRecoverMPLeftTimes = GlobalData.SHIELD_RECOVER_TIME;
  1116. }
  1117. }
  1118. #endregion
  1119. #region Formula调用.
  1120. public void OnUnitRemoved() { }
  1121. public virtual int OnHit(XmdsVirtual attacker, AttackSource source)
  1122. {
  1123. AtkResult result = new AtkResult();
  1124. //无敌直接免疫打击效果.
  1125. if ((this.IsInvincible == true) && source.FromExpectTarget == SkillTemplate.CastTarget.Enemy)
  1126. {
  1127. attacker.OnHitOthter(this);
  1128. //无敌时仇恨减为1.
  1129. attacker.mHateSystem.SetHateInfo(this.mUnit.ID, 1);
  1130. //攻击者进度战斗状态.
  1131. attacker.ChangeCombatStateFromAtk(this);
  1132. mHateSystem.OnHitted(attacker, this, 0, ref result);
  1133. source.OutIsDamage = false;
  1134. source.OutClientState = (int)UnitHitEventState.Immunity;
  1135. return 0;
  1136. }
  1137. #region 特殊状态判断.
  1138. if (this.NothingnessIgnoreBuff)
  1139. {
  1140. if (source.FromBuffState != null)
  1141. {
  1142. return 0;
  1143. }
  1144. }
  1145. if (this.NothingnessIgnoreSkill)
  1146. {
  1147. if (source.FromSkillState != null || source.FromSpellUnit != null)
  1148. {
  1149. return 0;
  1150. }
  1151. }
  1152. if (this.NothingnessIgnoreAll)
  1153. {
  1154. return 0;
  1155. }
  1156. #endregion
  1157. int damage = this.On_hit_unit_vs_unit(attacker, this, source, ref result);
  1158. if (damage < 0)
  1159. {
  1160. OnHeal(attacker, -damage, ref result);
  1161. //加血.
  1162. if (attacker.CombatState != BattleStatus.None) { SetCombatState(attacker.CombatState); }
  1163. }
  1164. else if(this.mUnit.ID != attacker.mUnit.ID)//自己对自己作用的不算
  1165. {
  1166. if (damage == 0 && source.OutClientState != (int)UnitHitEventState.Dodge)//增益、负面效果.
  1167. {
  1168. if (source.FromExpectTarget == SkillTemplate.CastTarget.Enemy)//负面效果.
  1169. {
  1170. attacker.OnHitOthter(this);
  1171. //攻击者进度战斗状态.
  1172. attacker.ChangeCombatStateFromAtk(this);
  1173. mHateSystem.OnHitted(attacker, this, damage, ref result);
  1174. var v = (this.IsPlayerUnit() && attacker.IsPlayerUnit()) ? BattleStatus.PVP : BattleStatus.PVE;
  1175. //单位被攻击,且从PVE状态转为PVP状态,
  1176. if (v == BattleStatus.PVP && CombatState != BattleStatus.PVP)
  1177. {
  1178. UnderAttackCheck(attacker);
  1179. }
  1180. SetCombatState(v, 0, attacker.mUnit.PlayerUUID);
  1181. //坐骑状态下检查受击影响.
  1182. MountOnHitCheck(attacker);
  1183. //判断异常状态(击倒击飞).
  1184. {
  1185. MountOnHit(source);
  1186. }
  1187. }
  1188. else //增益效果.
  1189. {
  1190. if (this != attacker)
  1191. {
  1192. //施术者或受攻击者双方互相影响.
  1193. if (this.CombatState != BattleStatus.None)
  1194. {
  1195. attacker.SetCombatState(this.CombatState);
  1196. }
  1197. if (attacker.CombatState != BattleStatus.None)
  1198. {
  1199. SetCombatState(attacker.CombatState);
  1200. }
  1201. }
  1202. }
  1203. }
  1204. else
  1205. {
  1206. attacker.OnHitOthter(this);
  1207. //致命一击时候死亡状态不设置.
  1208. if (this.mUnit.CurrentHP - damage > 0)
  1209. {
  1210. var s = (this.IsPlayerUnit() && attacker.IsPlayerUnit()) ? BattleStatus.PVP : BattleStatus.PVE;
  1211. //单位被攻击,且从PVE状态转为PVP状态,
  1212. if (s == BattleStatus.PVP && CombatState != BattleStatus.PVP)
  1213. {
  1214. UnderAttackCheck(attacker);
  1215. }
  1216. SetCombatState(s, 0, attacker.mUnit.PlayerUUID);
  1217. }
  1218. //攻击者进度战斗状态.
  1219. attacker.ChangeCombatStateFromAtk(this);
  1220. //仇恨值计算.
  1221. attacker.DispatchCalThreatValueEvent(this, source, ref result);
  1222. mHateSystem.OnHitted(attacker, this, damage, ref result);
  1223. //坐骑状态下检查受击影响.
  1224. MountOnHitCheck(attacker);
  1225. //判断异常状态(击倒击飞).
  1226. {
  1227. MountOnHit(source);
  1228. }
  1229. //扣除定力
  1230. if (this.mUnit.MaxMP > 0 && result.breakShieldValue > 0)
  1231. {
  1232. this.AddMP(-result.breakShieldValue, attacker.mUnit, source);
  1233. }
  1234. }
  1235. }
  1236. //if (damage == 0)
  1237. //{
  1238. // source.OutIsDamage = false;
  1239. //}
  1240. return damage;
  1241. }
  1242. public virtual void OnUnitDead(XmdsVirtual killer)
  1243. {
  1244. //坐骑状态设置为false.
  1245. TakeOffMount();
  1246. //脱战.
  1247. SetCombatState(BattleStatus.None, 1);
  1248. if (mHateSystem != null)
  1249. {
  1250. mHateSystem.Clear();
  1251. }
  1252. }
  1253. public virtual void OnKillUnit(XmdsVirtual dead)
  1254. {
  1255. }
  1256. /// <summary>
  1257. /// 是否属于玩家.
  1258. /// </summary>
  1259. /// <returns></returns>
  1260. public virtual bool IsPlayerUnit()
  1261. {
  1262. return false;
  1263. }
  1264. /// <summary>
  1265. /// 获取对应玩家单位.
  1266. /// </summary>
  1267. /// <returns></returns>
  1268. public virtual XmdsVirtual_Player GetPlayerUnit()
  1269. {
  1270. return null;
  1271. }
  1272. public void OnHandleNetMessage(ObjectAction action)
  1273. {
  1274. }
  1275. public void OnTriggerStart(InstanceUnit.TriggerState trigger, XmdsVirtual target)
  1276. {
  1277. }
  1278. public virtual void OnUpdateTriggerSkill(int intervalMS, bool slowRefresh)
  1279. {
  1280. // 区域刷新 //
  1281. UpdateAreaState(intervalMS);
  1282. //同步战斗属性协议.
  1283. UpdateBattlePropsChangeEvt();
  1284. //慢刷新,不必要每一帧都刷新
  1285. if (slowRefresh)
  1286. {
  1287. int slowInterval = intervalMS * GlobalData.ZONE_UPDATE_SLOW;
  1288. //计算是否脱战.
  1289. UpdateOutOfCombatTime(slowInterval);
  1290. //HP回复.
  1291. UpdateHPReborn(slowInterval);
  1292. UpdateMPReborn(slowInterval);
  1293. //仇恨系统刷新.
  1294. UpdateHateSystem(slowInterval);
  1295. }
  1296. //技能刷新.
  1297. UpdateSkillHelper(intervalMS, slowRefresh);
  1298. if (this.mCardModule != null)
  1299. {
  1300. this.mCardModule.Update(intervalMS, slowRefresh);
  1301. }
  1302. }
  1303. public void OnBuffBegin(InstanceUnit.BuffState state, XmdsVirtual sender)
  1304. {
  1305. BuffTemplate template = state.Data;
  1306. XmdsBuffProperties prop = template.Properties as XmdsBuffProperties;
  1307. List<XmdsBuffVirtual> list = null;
  1308. if (state.Tag != null)
  1309. {
  1310. list = state.Tag as List<XmdsBuffVirtual>;
  1311. }
  1312. //异常BUFF对坐骑状态有影响.
  1313. MountOnBuffBegin(template);
  1314. if (list != null)
  1315. {
  1316. for (int i = 0; i < list.Count; i++)
  1317. {
  1318. UnitBuff ub = list[i] as UnitBuff;
  1319. ub.BuffBegin(this, sender, state);
  1320. }
  1321. }
  1322. DispatchBuffEvent(state, BuffEventType.Begin, null);
  1323. }
  1324. public void OnBuffUpdate(InstanceUnit.BuffState state, int time)
  1325. {
  1326. BuffTemplate template = state.Data;
  1327. List<XmdsBuffVirtual> list = null;
  1328. if (state.Tag != null)
  1329. {
  1330. list = state.Tag as List<XmdsBuffVirtual>;
  1331. }
  1332. if (list != null && list.Count != 0)
  1333. {
  1334. int count = 0;
  1335. for (int i = 0; i < list.Count; i++)
  1336. {
  1337. UnitBuff ub = list[i] as UnitBuff;
  1338. ub.BuffUpdate(this, state);
  1339. if (ub.IsInvaild())
  1340. {
  1341. count++;
  1342. }
  1343. }
  1344. if (count == list.Count)//当前BUFF所有能力都已失效,主动移出该BUFF.
  1345. {
  1346. this.mUnit.removeBuff(template.ID);
  1347. }
  1348. }
  1349. }
  1350. public void OnBuffEnd(InstanceUnit.BuffState state, string result, bool replace)
  1351. {
  1352. BuffTemplate template = state.Data;
  1353. XmdsBuffProperties prop = template.Properties as XmdsBuffProperties;
  1354. List<XmdsBuffVirtual> list = null;
  1355. if (state.Tag != null)
  1356. {
  1357. list = state.Tag as List<XmdsBuffVirtual>;
  1358. }
  1359. if (list != null)
  1360. {
  1361. for (int i = 0; i < list.Count; i++)
  1362. {
  1363. UnitBuff ub = list[i] as UnitBuff;
  1364. ub.BuffEnd(this, state, replace);
  1365. }
  1366. }
  1367. DispatchBuffEvent(state, BuffEventType.End, result);
  1368. }
  1369. #endregion
  1370. #region 属性能力重算.
  1371. /// <summary>
  1372. /// 刷新属性.
  1373. /// </summary>
  1374. protected void UnitPropRefresh(XmdsUnitProp prop = null)
  1375. {
  1376. if (prop == null)
  1377. {
  1378. XmdsUnitProp zup = GetOriginProp();
  1379. this.MirrorProp = zup.Clone() as XmdsUnitProp;
  1380. }
  1381. else
  1382. {
  1383. this.MirrorProp = prop;
  1384. }
  1385. foreach (KeyValuePair<int, PropChangeOperation> kvp in mPropChangeMap)
  1386. {
  1387. ChangeProp(kvp.Value);
  1388. }
  1389. int srcHP = this.MirrorProp.MaxHP;
  1390. // 更新虚拟属性,只影响数值,不计入显示和战力计算(也不在面板上显示)
  1391. if(this.mProp.ServerData.PropExt != null && this.mUnit.IsPlayer)
  1392. {
  1393. this.MirrorProp.AddTo(this.mProp.ServerData.PropExt);
  1394. }
  1395. SycMaxHP();
  1396. SycSkillCdReduce();
  1397. SycControledTimeReduce();
  1398. SycMoveSpeed();
  1399. SycAttackSpeed();
  1400. //隐藏属性导致玩家血量变了,同步最大血量ext
  1401. if(this.MirrorProp.MaxHP != srcHP)
  1402. {
  1403. SyncBattlePropsFields(UnitAttributeType.SetMaxHP);
  1404. }
  1405. }
  1406. private void ChangeProp(PropChangeOperation opt)
  1407. {
  1408. XmdsUnitProp zup = GetOriginProp();
  1409. switch (opt.Type)
  1410. {
  1411. case UnitAttributeType.Defence:
  1412. if (opt.OpType == PropChangeOperation.OperateType.Percent)
  1413. {
  1414. this.MirrorProp.DefencePer += opt.Value;
  1415. }
  1416. else
  1417. {
  1418. this.MirrorProp.BaseDefence += opt.Value;
  1419. }
  1420. //攻击异常日志
  1421. if (this.MirrorProp.Defence > this.GetOriginProp().Defence * 5)
  1422. {
  1423. this.PrintAttrErrorInfo(opt.Type, this.MirrorProp.Defence, this.GetOriginProp().Defence);
  1424. }
  1425. break;
  1426. case UnitAttributeType.CritRate:
  1427. this.MirrorProp.CritRate += opt.Value;
  1428. break;
  1429. case UnitAttributeType.MaxHP:
  1430. if (opt.OpType == PropChangeOperation.OperateType.Percent)
  1431. {
  1432. this.MirrorProp.HPPer += opt.Value;
  1433. }
  1434. else
  1435. {
  1436. this.MirrorProp.BaseMaxHP += opt.Value;
  1437. }
  1438. mUnit.SetMaxHP(this.MirrorProp.MaxHP, true);
  1439. //攻击异常日志
  1440. if (this.MirrorProp.MaxHP > this.GetOriginProp().MaxHP * 3)
  1441. {
  1442. this.PrintAttrErrorInfo(opt.Type, this.MirrorProp.MaxHP, this.GetOriginProp().MaxHP);
  1443. }
  1444. break;
  1445. case UnitAttributeType.Attack:
  1446. if (opt.OpType == PropChangeOperation.OperateType.Percent)
  1447. {
  1448. this.MirrorProp.AttackPer += opt.Value;
  1449. }
  1450. else
  1451. {
  1452. this.MirrorProp.BaseAttack += opt.Value;
  1453. }
  1454. //攻击异常日志
  1455. if (this.MirrorProp.MaxAttack > this.GetOriginProp().MaxAttack * 3)
  1456. {
  1457. this.PrintAttrErrorInfo(opt.Type, this.MirrorProp.MaxAttack, this.GetOriginProp().MaxAttack);
  1458. }
  1459. break;
  1460. case UnitAttributeType.HealedEffect:
  1461. this.MirrorProp.HealedEffect += opt.Value;
  1462. break;
  1463. case UnitAttributeType.HealEffect:
  1464. this.MirrorProp.HealEffect += opt.Value;
  1465. break;
  1466. case UnitAttributeType.PlayerDamageReduce:
  1467. this.MirrorProp.PlayerDamageReduce += opt.Value;
  1468. // 免伤异常日志
  1469. if(this.MirrorProp.PlayerDamageReduce > 10000)
  1470. {
  1471. this.PrintAttrErrorInfo(opt.Type, this.MirrorProp.PlayerDamageReduce, opt.Value);
  1472. }
  1473. break;
  1474. case UnitAttributeType.MoveSpeed:
  1475. this.MirrorProp.MoveSpeed += GetOpValueFloat(zup.MoveSpeed, opt.Value, opt.OpType);
  1476. this.MirrorProp.VelocityAddition += opt.Value;
  1477. break;
  1478. case UnitAttributeType.PickupRange:
  1479. this.MirrorProp.pickupRange += GetOpValue(zup.pickupRange, opt.Value, opt.OpType);
  1480. break;
  1481. case UnitAttributeType.AttackSpeed:
  1482. this.MirrorProp.AttackSpeed += GetOpValue(zup.AttackSpeed, opt.Value, opt.OpType);
  1483. break;
  1484. case UnitAttributeType.SkillLanuchSpeed:
  1485. this.MirrorProp.SkillCD += GetOpValue(zup.SkillCD, opt.Value, opt.OpType);
  1486. break;
  1487. case UnitAttributeType.ControlTimeReduce:
  1488. this.MirrorProp.CtrlTimeReduce += opt.Value;
  1489. break;
  1490. case UnitAttributeType.SkillDamage:
  1491. this.MirrorProp.SkillDamageAdd += opt.Value;
  1492. break;
  1493. case UnitAttributeType.IngoreDefence:
  1494. if (opt.OpType == PropChangeOperation.OperateType.Percent)
  1495. {
  1496. this.MirrorProp.IgnoreDefensePer += opt.Value;
  1497. }
  1498. else
  1499. {
  1500. this.MirrorProp.BaseIgnoreDefense += opt.Value;
  1501. }
  1502. break;
  1503. case UnitAttributeType.SkillLeech:
  1504. this.MirrorProp.ActiveAtkLeech += opt.Value;
  1505. break;
  1506. case UnitAttributeType.CritDamage:
  1507. this.MirrorProp.CritDamage += opt.Value;
  1508. break;
  1509. case UnitAttributeType.PlayerDamageAdd:
  1510. this.MirrorProp.PlayerDamageAdd += opt.Value;
  1511. // 伤害增加异常日志
  1512. if (this.MirrorProp.PlayerDamageAdd > 10000)
  1513. {
  1514. this.PrintAttrErrorInfo(opt.Type, this.MirrorProp.PlayerDamageAdd, opt.Value);
  1515. }
  1516. break;
  1517. case UnitAttributeType.MonsterDamageAdd:
  1518. this.MirrorProp.monsterDamageAdd += opt.Value;
  1519. break;
  1520. case UnitAttributeType.MonsterDamageReduce:
  1521. this.MirrorProp.monsterDamageReduce += opt.Value;
  1522. break;
  1523. case UnitAttributeType.AllDmgAdd:
  1524. this.MirrorProp.AllDmgAdd += opt.Value;
  1525. // 伤害增加异常日志
  1526. if (this.MirrorProp.AllDmgAdd > 10000)
  1527. {
  1528. this.PrintAttrErrorInfo(opt.Type, this.MirrorProp.AllDmgAdd, opt.Value);
  1529. }
  1530. break;
  1531. case UnitAttributeType.AllDmgReduce:
  1532. this.MirrorProp.AllDmgReduce += opt.Value;
  1533. // 伤害增加异常日志
  1534. if (this.MirrorProp.AllDmgReduce > 13000)
  1535. {
  1536. this.PrintAttrErrorInfo(opt.Type, this.MirrorProp.AllDmgReduce, opt.Value);
  1537. }
  1538. break;
  1539. case UnitAttributeType.SetMaxHP:
  1540. this.MirrorProp.BaseMaxHP = opt.Value;
  1541. break;
  1542. case UnitAttributeType.CritRate_NormalAtk:
  1543. this.MirrorProp.NormalAtkCriteRate += opt.Value;
  1544. break;
  1545. case UnitAttributeType.HPRecover:
  1546. if (opt.OpType == PropChangeOperation.OperateType.Percent)
  1547. {
  1548. this.MirrorProp.HPRecoverPer += opt.Value;
  1549. }
  1550. else
  1551. {
  1552. this.MirrorProp.HPReborn += opt.Value;
  1553. }
  1554. break;
  1555. case UnitAttributeType.EAttack_Gold:
  1556. this.MirrorProp.ArtifactAttack[(int)ArtifactType.Gold] += opt.Value;
  1557. break;
  1558. case UnitAttributeType.EAttack_Wood:
  1559. this.MirrorProp.ArtifactAttack[(int)ArtifactType.Wood] += opt.Value;
  1560. break;
  1561. case UnitAttributeType.EAttack_Water:
  1562. this.MirrorProp.ArtifactAttack[(int)ArtifactType.Water] += opt.Value;
  1563. break;
  1564. case UnitAttributeType.EAttack_Fire:
  1565. this.MirrorProp.ArtifactAttack[(int)ArtifactType.Fire] += opt.Value;
  1566. break;
  1567. case UnitAttributeType.EAttack_Soil:
  1568. this.MirrorProp.ArtifactAttack[(int)ArtifactType.Soil] += opt.Value;
  1569. break;
  1570. case UnitAttributeType.EDefence_Gold:
  1571. this.MirrorProp.ArtifactDefense[(int)ArtifactType.Gold] += opt.Value;
  1572. break;
  1573. case UnitAttributeType.EDefence_Wood:
  1574. this.MirrorProp.ArtifactDefense[(int)ArtifactType.Wood] += opt.Value;
  1575. break;
  1576. case UnitAttributeType.EDefence_Water:
  1577. this.MirrorProp.ArtifactDefense[(int)ArtifactType.Water] += opt.Value;
  1578. break;
  1579. case UnitAttributeType.EDefence_Fire:
  1580. this.MirrorProp.ArtifactDefense[(int)ArtifactType.Fire] += opt.Value;
  1581. break;
  1582. case UnitAttributeType.EDefence_Soil:
  1583. this.MirrorProp.ArtifactDefense[(int)ArtifactType.Soil] += opt.Value;
  1584. break;
  1585. case UnitAttributeType.ToBoss_CriteRate:
  1586. this.MirrorProp.ToBossCritRate += opt.Value;
  1587. break;
  1588. case UnitAttributeType.ToBoss_CriteDamage:
  1589. this.MirrorProp.ToBossCritDamage += opt.Value;
  1590. break;
  1591. case UnitAttributeType.MonsterRestraint_1:
  1592. this.MirrorProp.MonsterRestraint[(int)UnitFateType.One - 1] += opt.Value;
  1593. break;
  1594. case UnitAttributeType.MonsterRestraint_2:
  1595. this.MirrorProp.MonsterRestraint[(int)UnitFateType.Two - 1] += opt.Value;
  1596. break;
  1597. case UnitAttributeType.MonsterRestraint_3:
  1598. this.MirrorProp.MonsterRestraint[(int)UnitFateType.Three - 1] += opt.Value;
  1599. break;
  1600. case UnitAttributeType.MonsterRestraint_4:
  1601. this.MirrorProp.MonsterRestraint[(int)UnitFateType.Four - 1] += opt.Value;
  1602. break;
  1603. case UnitAttributeType.MonsterRestraint_5:
  1604. this.MirrorProp.MonsterRestraint[(int)UnitFateType.Five - 1] += opt.Value;
  1605. break;
  1606. default:
  1607. break;
  1608. }
  1609. }
  1610. private void PrintAttrErrorInfo(UnitAttributeType Type, int value1, int value2)
  1611. {
  1612. #if JSG_DMG_LOG
  1613. try
  1614. {
  1615. string stackInfo = new StackTrace().ToString();
  1616. XmdsVirtual.FormatLog(LoggerLevel.ERROR, "属性异常异常 : UID:{0}, {1}, {2}, {3}, {4}", this.mUnit.PlayerUUID, Type, value1, value2, stackInfo);
  1617. }
  1618. catch(Exception e)
  1619. {
  1620. XmdsVirtual.FormatLog(LoggerLevel.ERROR, "PrintAttrErrorInfo异常:" + Type + ", " + value1 + ", " + value2 + ", " + e);
  1621. }
  1622. #endif
  1623. }
  1624. private int GetOpValue(float UnitProp, float changeValue, PropChangeOperation.OperateType type)
  1625. {
  1626. float ret = 0;
  1627. if (type == PropChangeOperation.OperateType.Percent)
  1628. {
  1629. ret = UnitProp * (changeValue / XmdsDamageCalculator.PERER);
  1630. }
  1631. else
  1632. {
  1633. ret = changeValue;
  1634. }
  1635. return CUtils.CastInt(ret);
  1636. }
  1637. private float GetOpValueFloat(float UnitProp, float changeValue, PropChangeOperation.OperateType type)
  1638. {
  1639. float ret = 0;
  1640. if (type == PropChangeOperation.OperateType.Percent)
  1641. {
  1642. ret = UnitProp * (changeValue / XmdsDamageCalculator.PERER);
  1643. }
  1644. else
  1645. {
  1646. ret = changeValue;
  1647. }
  1648. return ret;
  1649. }
  1650. public PropChangeOperation CreatePropChangeOpertation()
  1651. {
  1652. return new PropChangeOperation();
  1653. }
  1654. /** 被动改变数值 */
  1655. public void ChangeMaxHP(int addValues)
  1656. {
  1657. mProp.ServerData.Prop.BaseMaxHP += addValues;
  1658. mUnit.SetMaxHP(this.MirrorProp.MaxHP, true);
  1659. }
  1660. /** 被动改变攻击,除非死亡,否则不清除属性 */
  1661. public void ChangeAttack(int addValues)
  1662. {
  1663. mProp.ServerData.Prop.BaseAttack += addValues;
  1664. UnitPropRefresh();
  1665. }
  1666. /** 被动改变防御,除非死亡,否则不清除属性 */
  1667. public void ChangeDefence(int addValues)
  1668. {
  1669. mProp.ServerData.Prop.BaseDefence += addValues;
  1670. UnitPropRefresh();
  1671. }
  1672. /** 被动改变攻速,除非死亡,否则不清除属性 */
  1673. public void ChangeAtkSpeed(int addValues)
  1674. {
  1675. mProp.ServerData.Prop.AttackSpeed += addValues;
  1676. UnitPropRefresh();
  1677. }
  1678. /** 被动改变暴击伤害,除非死亡,否则不清除属性 */
  1679. public void ChangeCriteDamage(int addValues)
  1680. {
  1681. mProp.ServerData.Prop.CritDamage += addValues;
  1682. UnitPropRefresh();
  1683. }
  1684. /** 被动改变暴击率,除非死亡,否则不清除属性 */
  1685. public void ChangeCriteRate(int addValues)
  1686. {
  1687. mProp.ServerData.Prop.CritRate += addValues;
  1688. UnitPropRefresh();
  1689. }
  1690. /// <summary>
  1691. /// 插入一条属性变更操作指令,返回id用来删除.
  1692. /// </summary>
  1693. /// <returns></returns>
  1694. public int AddPropChangeOperation(PropChangeOperation opt)
  1695. {
  1696. int ret = 0;
  1697. mPropChangeOperationCount++;
  1698. ret = mPropChangeOperationCount;
  1699. mPropChangeMap.Add(ret, opt);
  1700. //立刻生效计算.
  1701. UnitPropRefresh();
  1702. SyncBattlePropsFields(opt.Type);
  1703. return ret;
  1704. }
  1705. public bool UpdatePropChangeOperation(int OpID, PropChangeOperation opt)
  1706. {
  1707. if (mPropChangeMap.ContainsKey(OpID))
  1708. {
  1709. mPropChangeMap[OpID] = opt;
  1710. //立刻生效计算.
  1711. UnitPropRefresh();
  1712. SyncBattlePropsFields(opt.Type);
  1713. return true;
  1714. }
  1715. return false;
  1716. }
  1717. /// <summary>
  1718. ///删除属性变更操作指令.
  1719. /// </summary>
  1720. public void RemovePropChangeOperation(int id)
  1721. {
  1722. PropChangeOperation opt;
  1723. if (mPropChangeMap != null && mPropChangeMap.TryGetValue(id, out opt))
  1724. {
  1725. mPropChangeMap.Remove(id);
  1726. SyncBattlePropsFields(opt.Type);
  1727. UnitPropRefresh();
  1728. }
  1729. else
  1730. {
  1731. FormatLog("RemovePropChangeOperation Error");
  1732. }
  1733. }
  1734. /// <summary>
  1735. /// 操作指令.
  1736. /// </summary>
  1737. public struct PropChangeOperation
  1738. {
  1739. /// <summary>
  1740. /// 操作属性.
  1741. /// </summary>
  1742. public UnitAttributeType Type;
  1743. /// <summary>
  1744. /// 操作值.
  1745. /// </summary>
  1746. public int Value;
  1747. /// <summary>
  1748. /// 操作类型.
  1749. /// </summary>
  1750. public OperateType OpType;
  1751. /// <summary>
  1752. /// 操作类型:值加减,百分比,
  1753. /// </summary>
  1754. public enum OperateType : byte
  1755. {
  1756. Value,
  1757. Percent,
  1758. }
  1759. }
  1760. /// <summary>
  1761. /// 操作标识.
  1762. /// </summary>
  1763. public enum UnitAttributeType : Byte
  1764. {
  1765. None, //无.
  1766. MoveSpeed, //速度.
  1767. Defence, //防御.
  1768. Attack, //最大攻击
  1769. /**attention, 这里存在坑,之前增伤,减伤被改成玩家后,后来有需要所有的增伤,减伤,有新加了一个奇怪的东西。 容易混淆*/
  1770. PlayerDamageAdd, // 伤害加成(玩家之间)
  1771. PlayerDamageReduce, // 伤害减免(被改成玩家之间)
  1772. MonsterDamageAdd, // 怪物(妖兽)伤害增加
  1773. MonsterDamageReduce, // 怪物(妖兽)免伤
  1774. AllDmgReduce, // 所有伤害减免
  1775. AllDmgAdd, // 单位增伤,IncAllDamage改成玩家之间导致新增一个奇怪所有增伤属性
  1776. HealEffect, //治疗效果.
  1777. HealedEffect, //受治疗效果.
  1778. MaxHP, //生命上限.
  1779. CritRate, //暴击率
  1780. PickupRange, //拾取距离
  1781. AttackSpeed, //攻速, 普攻冷却缩减
  1782. SkillLanuchSpeed, //技能冷却缩减
  1783. ControlTimeReduce, //控制时间改变,韧性
  1784. SkillDamage, //技能伤害
  1785. IngoreDefence, //无视防御
  1786. SkillLeech, //技能吸血
  1787. CritDamage, //暴击伤害
  1788. SetMaxHP, //设置最大血量
  1789. CritRate_NormalAtk, //普攻暴击率(为实现技能效果加的)
  1790. HPRecover, //生命恢复效果
  1791. EAttack_Gold,
  1792. EAttack_Wood,
  1793. EAttack_Water,
  1794. EAttack_Fire,
  1795. EAttack_Soil,
  1796. EDefence_Gold,
  1797. EDefence_Wood,
  1798. EDefence_Water,
  1799. EDefence_Fire,
  1800. EDefence_Soil,
  1801. ToBoss_CriteRate,
  1802. ToBoss_CriteDamage,
  1803. MonsterRestraint_1, // 命格克制
  1804. MonsterRestraint_2,
  1805. MonsterRestraint_3,
  1806. MonsterRestraint_4,
  1807. MonsterRestraint_5,
  1808. }
  1809. // 数值上限
  1810. public class GamePropLimit
  1811. {
  1812. public const int AttackSpeed_Down = -5000; // 攻速下限
  1813. public const int AttackSpeed_Up = 25000; // 攻速上限
  1814. public const int MoveSpeed = 4000; // 移速
  1815. public const int SkillLaunchSpeed = 5000; // 冷却缩减
  1816. public const int DamageRemit = 5000; // 伤害减免
  1817. public const int CtrlTimeReduce = 5000; // 韧性
  1818. public const int SkillDamageAdd = 5000; // 技能伤害增幅
  1819. public const int HealthAddition = 5000; // 治疗增幅
  1820. public const int CtrlAddition = 5000; // 控制增幅
  1821. }
  1822. /// <summary>
  1823. /// 同步客户端.
  1824. /// </summary>
  1825. private void UpdateBattlePropsChangeEvt()
  1826. {
  1827. if (mBattlePropChangeEvt != null)
  1828. {
  1829. GenBattlePropsFields(mBattlePropChangeEvt);
  1830. SendBattlePropsChangeEvt(mBattlePropChangeEvt);
  1831. mBattlePropChangeEvt = null;
  1832. }
  1833. }
  1834. private ulong GetBattlePropFieldsMask(UnitAttributeType type)
  1835. {
  1836. ulong mask = 0;
  1837. switch (type)
  1838. {
  1839. case UnitAttributeType.MaxHP:
  1840. mask = PlayerBattlePropChangeEventB2C.MASK_MAX_HP;
  1841. break;
  1842. case UnitAttributeType.MoveSpeed:
  1843. mask = PlayerBattlePropChangeEventB2C.MASK_MOVE_SPEED | PlayerBattlePropChangeEventB2C.MASK_MOVE_SPEED_ADDITION;
  1844. break;
  1845. case UnitAttributeType.Attack:
  1846. mask = PlayerBattlePropChangeEventB2C.MASK_ATTACK;
  1847. break;
  1848. case UnitAttributeType.IngoreDefence:
  1849. mask = PlayerBattlePropChangeEventB2C.MASK_IGNORE_DEFENSE_PER;
  1850. break;
  1851. case UnitAttributeType.Defence:
  1852. mask = PlayerBattlePropChangeEventB2C.MASK_DEF;
  1853. break;
  1854. case UnitAttributeType.CritRate:
  1855. mask = PlayerBattlePropChangeEventB2C.MASK_CRIT_RATE;
  1856. break;
  1857. case UnitAttributeType.CritDamage:
  1858. mask = PlayerBattlePropChangeEventB2C.MASK_CRIT_DAMAGE;
  1859. break;
  1860. case UnitAttributeType.PlayerDamageReduce:
  1861. mask = PlayerBattlePropChangeEventB2C.MASK_ALL_DAMAGE_REDUCE;
  1862. break;
  1863. case UnitAttributeType.HealEffect:
  1864. mask = PlayerBattlePropChangeEventB2C.MASK_HEALEFFECT;
  1865. break;
  1866. case UnitAttributeType.HealedEffect:
  1867. mask = PlayerBattlePropChangeEventB2C.MASK_HEALEDEFFECT;
  1868. break;
  1869. case UnitAttributeType.AttackSpeed:
  1870. mask = PlayerBattlePropChangeEventB2C.MASK_ATTACK_SPEED;
  1871. break;
  1872. case UnitAttributeType.SkillLanuchSpeed:
  1873. mask = PlayerBattlePropChangeEventB2C.MASK_SKILL_CD;
  1874. break;
  1875. case UnitAttributeType.ControlTimeReduce:
  1876. mask = PlayerBattlePropChangeEventB2C.MASK_CTRLTIME_REDUCE;
  1877. break;
  1878. case UnitAttributeType.SkillDamage:
  1879. mask = PlayerBattlePropChangeEventB2C.MASK_SKILLDAMAGE;
  1880. break;
  1881. case UnitAttributeType.PlayerDamageAdd:
  1882. mask = PlayerBattlePropChangeEventB2C.MASK_INCALLDAMAGE;
  1883. break;
  1884. case UnitAttributeType.SetMaxHP:
  1885. mask = PlayerBattlePropChangeEventB2C.MASK_MAX_HP_EXT;
  1886. break;
  1887. case UnitAttributeType.SkillLeech:
  1888. mask = PlayerBattlePropChangeEventB2C.MASK_ACTIVE_ATK_LEECH;
  1889. break;
  1890. case UnitAttributeType.HPRecover:
  1891. mask = PlayerBattlePropChangeEventB2C.MASK_HP_REBORN;
  1892. break;
  1893. case UnitAttributeType.EAttack_Gold:
  1894. mask = PlayerBattlePropChangeEventB2C.MASK_GOLD_ATTACK;
  1895. break;
  1896. case UnitAttributeType.EAttack_Wood:
  1897. mask = PlayerBattlePropChangeEventB2C.MASK_WOOD_ATTACK;
  1898. break;
  1899. case UnitAttributeType.EAttack_Water:
  1900. mask = PlayerBattlePropChangeEventB2C.MASK_WATER_ATTACK;
  1901. break;
  1902. case UnitAttributeType.EAttack_Fire:
  1903. mask = PlayerBattlePropChangeEventB2C.MASK_FIRE_ATTACK;
  1904. break;
  1905. case UnitAttributeType.EAttack_Soil:
  1906. mask = PlayerBattlePropChangeEventB2C.MASK_SOIL_ATTACK;
  1907. break;
  1908. case UnitAttributeType.EDefence_Gold:
  1909. mask = PlayerBattlePropChangeEventB2C.MASK_GOLD_DEFENSE;
  1910. break;
  1911. case UnitAttributeType.EDefence_Wood:
  1912. mask = PlayerBattlePropChangeEventB2C.MASK_WOOD_DEFENSE;
  1913. break;
  1914. case UnitAttributeType.EDefence_Water:
  1915. mask = PlayerBattlePropChangeEventB2C.MASK_WATER_DEFENSE;
  1916. break;
  1917. case UnitAttributeType.EDefence_Fire:
  1918. mask = PlayerBattlePropChangeEventB2C.MASK_FIRE_DEFENSE;
  1919. break;
  1920. case UnitAttributeType.EDefence_Soil:
  1921. mask = PlayerBattlePropChangeEventB2C.MASK_SOIL_DEFENSE;
  1922. break;
  1923. case UnitAttributeType.ToBoss_CriteRate:
  1924. mask = PlayerBattlePropChangeEventB2C.MASK_TOBOSS_CRIT_RATE;
  1925. break;
  1926. case UnitAttributeType.ToBoss_CriteDamage:
  1927. mask = PlayerBattlePropChangeEventB2C.MASK_TOBOSS_CRIT_DAMAGE;
  1928. break;
  1929. case UnitAttributeType.MonsterRestraint_1:
  1930. mask = PlayerBattlePropChangeEventB2C.MASK_MONSTER_RESTRAINT_1;
  1931. break;
  1932. case UnitAttributeType.MonsterRestraint_2:
  1933. mask = PlayerBattlePropChangeEventB2C.MASK_MONSTER_RESTRAINT_2;
  1934. break;
  1935. case UnitAttributeType.MonsterRestraint_3:
  1936. mask = PlayerBattlePropChangeEventB2C.MASK_MONSTER_RESTRAINT_3;
  1937. break;
  1938. case UnitAttributeType.MonsterRestraint_4:
  1939. mask = PlayerBattlePropChangeEventB2C.MASK_MONSTER_RESTRAINT_4;
  1940. break;
  1941. case UnitAttributeType.MonsterRestraint_5:
  1942. mask = PlayerBattlePropChangeEventB2C.MASK_MONSTER_RESTRAINT_5;
  1943. break;
  1944. //case UnitAttributeType.
  1945. //mask = PlayerBattlePropChangeEventB2C.MASK_BREAK_SHIELD;
  1946. //break;
  1947. default:
  1948. break;
  1949. }
  1950. return mask;
  1951. }
  1952. private void SyncBattlePropsFields(UnitAttributeType type)
  1953. {
  1954. ulong mask = GetBattlePropFieldsMask(type);
  1955. SyncBattlePropsFields(mask);
  1956. }
  1957. public virtual void SyncBattlePropsFields(ulong mask)
  1958. {
  1959. //该功能实现转移至player.
  1960. //donothing.
  1961. }
  1962. private void GenBattlePropsFields(PlayerBattlePropChangeEventB2C evt)
  1963. {
  1964. XmdsUnitProp UseProp = this.MirrorProp; //this.GetOriginProp();
  1965. evt.MaxHP = UseProp.MaxHP;
  1966. evt.MoveSpeed = UseProp.MoveSpeed;
  1967. evt.HPReborn = UseProp.HPReborn;
  1968. //同步Attribute
  1969. evt.HPPer = UseProp.HPPer;
  1970. evt.Attack = UseProp.MaxAttack;
  1971. evt.AttackPer = UseProp.AttackPer;
  1972. evt.Def = UseProp.Defence;
  1973. evt.DefPer = UseProp.DefencePer;
  1974. evt.IgnoreDefensePer = UseProp.IgnoreDefensePer;
  1975. evt.CritRate = UseProp.CritRate;
  1976. evt.ResCritRate = UseProp.ResCritRate;
  1977. evt.CritDamage = UseProp.CritDamage;
  1978. evt.IncAllDamage = UseProp.PlayerDamageAdd;
  1979. evt.AllDamageReduce = UseProp.PlayerDamageReduce;
  1980. evt.CtrlTimeReduce = UseProp.CtrlTimeReduce;
  1981. evt.SkillCD = UseProp.SkillCD;
  1982. evt.HealEffect = UseProp.HealEffect;
  1983. evt.HealedEffect = UseProp.HealedEffect;
  1984. evt.SkillDamage = UseProp.SkillDamageAdd;
  1985. evt.AttackSpeed = UseProp.AttackSpeed;
  1986. evt.ControlUp = UseProp.ControlUp;
  1987. evt.GoldAttack = UseProp.ArtifactAttack[(int)ArtifactType.Gold];
  1988. evt.WoodAttack = UseProp.ArtifactAttack[(int)ArtifactType.Wood];
  1989. evt.WaterAttack = UseProp.ArtifactAttack[(int)ArtifactType.Water];
  1990. evt.FireAttack = UseProp.ArtifactAttack[(int)ArtifactType.Fire];
  1991. evt.SoilAttack = UseProp.ArtifactAttack[(int)ArtifactType.Soil];
  1992. evt.GoldDefense = UseProp.ArtifactDefense[(int)ArtifactType.Gold];
  1993. evt.WoodDefense = UseProp.ArtifactDefense[(int)ArtifactType.Wood];
  1994. evt.WaterDefense = UseProp.ArtifactDefense[(int)ArtifactType.Water];
  1995. evt.FireDefense = UseProp.ArtifactDefense[(int)ArtifactType.Fire];
  1996. evt.SoilDefense = UseProp.ArtifactDefense[(int)ArtifactType.Soil];
  1997. evt.ToBossCritRate = UseProp.ToBossCritRate;
  1998. evt.ToBossCritDamage = UseProp.ToBossCritDamage;
  1999. evt.GoldRestraint = UseProp.ArtifactRestraint[(int)ArtifactType.Gold];
  2000. evt.WoodRestraint = UseProp.ArtifactRestraint[(int)ArtifactType.Wood];
  2001. evt.WaterRestraint = UseProp.ArtifactRestraint[(int)ArtifactType.Water];
  2002. evt.FireRestraint = UseProp.ArtifactRestraint[(int)ArtifactType.Fire];
  2003. evt.SoilRestraint = UseProp.ArtifactRestraint[(int)ArtifactType.Soil];
  2004. evt.GoldResist = UseProp.ArtifactResist[(int)ArtifactType.Gold];
  2005. evt.WoodResist = UseProp.ArtifactResist[(int)ArtifactType.Wood];
  2006. evt.WaterResist = UseProp.ArtifactResist[(int)ArtifactType.Water];
  2007. evt.FireResist = UseProp.ArtifactResist[(int)ArtifactType.Fire];
  2008. evt.SoilResist = UseProp.ArtifactResist[(int)ArtifactType.Soil];
  2009. evt.PvpKillValue = UseProp.KillValuePer;
  2010. evt.YaoQiLevel = UseProp.YaoQiLevel;
  2011. evt.NormalAtkLeech = UseProp.NormalAtkLeech;
  2012. evt.ActiveAtkLeech = UseProp.ActiveAtkLeech;
  2013. evt.ArtifactMainPer = UseProp.ArtifactMainPer;
  2014. evt.FieldBossDamageAdd = UseProp.monsterDamageAdd;
  2015. evt.MaxHPExt = this.MirrorProp.MaxHP;
  2016. evt.DungeonMonsterDamageAdd = UseProp.monsterDamageReduce;
  2017. evt.MoveSpeedAddition = UseProp.VelocityAddition;
  2018. for(int i = 0; i < (int)UnitFateType.Five; i++)
  2019. {
  2020. evt.MonsterRestraint[i] = UseProp.MonsterRestraint[i];
  2021. }
  2022. //// 猎妖属性
  2023. evt.monsterAtk = UseProp.monsterAtk;
  2024. evt.monsterDef = UseProp.monsterDef;
  2025. evt.monsterAtkPer = UseProp.monsterAtkPer;
  2026. evt.monsterDefPer = UseProp.monsterDefPer;
  2027. }
  2028. private void UpdateHateSystem(int intervalMS)
  2029. {
  2030. if (mHateSystem != null)
  2031. {
  2032. //定期去除仇恨对象.
  2033. mHateSystem.Update(intervalMS);
  2034. }
  2035. }
  2036. private void SendBattlePropsChangeEvt(PlayerBattlePropChangeEventB2C evt)
  2037. {
  2038. this.mUnit.queueEvent(evt);
  2039. }
  2040. private void UnderAttackCheck(XmdsVirtual attacker)
  2041. {
  2042. //单位被攻击,且从PVE状态转为PVP状态,
  2043. if (this is XmdsVirtual_Player)
  2044. {
  2045. var atk = attacker.GetPlayerUnit();
  2046. if (atk != null)
  2047. {
  2048. UnderAttackNotifyB2C evt = new UnderAttackNotifyB2C();
  2049. evt.AttackerID = atk.mUnit.ID;
  2050. evt.AttackerInfo = atk.mProp.ServerData.BaseInfo;
  2051. this.mUnit.queueEvent(evt);
  2052. }
  2053. }
  2054. }
  2055. public bool IsAllies(CommonAI.Zone.Formula.IVirtualUnit target, bool includeSelf = true, bool onlyForTeam = false)
  2056. {
  2057. XmdsVirtual unit = target as XmdsVirtual;
  2058. if (unit == null)
  2059. {
  2060. return false;
  2061. }
  2062. return IsMember(unit, this.GetCurPKMode(), includeSelf, onlyForTeam);
  2063. }
  2064. public virtual int GetMaType() { return -1; }
  2065. public virtual bool IsLvRepress() { return false; }
  2066. public virtual bool IsBoss() { return false; }
  2067. public virtual void doEvent(JSGCustomOpType value) {}
  2068. public virtual uint GetMasterID() { return 0; }
  2069. public virtual InstanceUnit GetMasterUnit() { return null; }
  2070. public virtual InstanceUnit GetPetUnit()
  2071. {
  2072. return null;
  2073. }
  2074. /// <summary>
  2075. /// 下坐骑.
  2076. /// </summary>
  2077. public virtual void TakeOffMount()
  2078. {
  2079. if (mIsMounted == true)
  2080. {
  2081. SyncMountStatus(false);
  2082. }
  2083. }
  2084. public int GetHealedEffect()
  2085. {
  2086. return this.MirrorProp.HealedEffect;
  2087. }
  2088. public int GetHealEffect()
  2089. {
  2090. return this.MirrorProp.HealEffect;
  2091. }
  2092. /** 获得单位职业 */
  2093. public XmdsUnitPro GetUnitPro()
  2094. {
  2095. return this.mProp.ServerData.BaseInfo.ProType;
  2096. }
  2097. //性别: 0-男,1-女
  2098. public int GetUnitSex()
  2099. {
  2100. return this.mProp.ServerData.BaseInfo.sex;
  2101. }
  2102. /** 获得宠物天赋加成 */
  2103. public virtual int GetPetTalentAddition(UnitFateType type)
  2104. {
  2105. return ((XmdsUnitProp)mProp.ServerData.Prop).fateValue;
  2106. }
  2107. public UnitFateType GetUnitFateType()
  2108. {
  2109. return ((XmdsUnitProp)mProp.ServerData.Prop).fateType;
  2110. }
  2111. #endregion
  2112. }
  2113. }