Statistic.cs 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using CommonLang;
  5. using CommonAI.ZoneServer;
  6. using CommonLang.IO;
  7. namespace CommonAI.Zone.Instance.Helper
  8. {
  9. public abstract class IUnitStatistic
  10. {
  11. public InstanceUnit Owner { get; private set; }
  12. public IUnitStatistic(InstanceUnit owner)
  13. {
  14. this.Owner = owner;
  15. }
  16. /// <summary>
  17. /// 转存可序列化协议对象
  18. /// </summary>
  19. /// <returns></returns>
  20. public virtual UnitStatisticData ToUnitStatisticData()
  21. {
  22. var ret = new UnitStatisticData();
  23. ret.ObjectID = Owner.ID;
  24. ret.DeadCount = this.DeadCount;
  25. ret.KillUnitCount = this.KillUnitCount;
  26. ret.KillPlayerCount = this.KillPlayerCount;
  27. ret.SelfDamage = this.SelfDamage;
  28. ret.TotalDamage = this.TotalDamage;
  29. ret.PlayerDamage = this.PlayerDamage;
  30. ret.TotalHealing = this.TotalHealing;
  31. ret.PlayerHealing = this.PlayerHealing;
  32. return ret;
  33. }
  34. public abstract void Reset();
  35. //------------------------------------------------------------------------------------
  36. /// <summary>
  37. /// 死亡次数
  38. /// </summary>
  39. public abstract int DeadCount { get; }
  40. /// <summary>
  41. /// 总共杀死玩家数量
  42. /// </summary>
  43. public abstract int KillPlayerCount { get; }
  44. /// <summary>
  45. /// 总共杀死单位数量
  46. /// </summary>
  47. public abstract int KillUnitCount { get; }
  48. /// <summary>
  49. /// 承受伤害
  50. /// </summary>
  51. public abstract long SelfDamage { get; }
  52. /// <summary>
  53. /// 对所有单位输出的总伤害
  54. /// </summary>
  55. public abstract long TotalDamage { get; }
  56. /// <summary>
  57. /// 对玩家输出的总伤害
  58. /// </summary>
  59. public abstract long PlayerDamage { get; }
  60. /// <summary>
  61. /// 对所有单位输出的总治疗量
  62. /// </summary>
  63. public abstract long TotalHealing { get; }
  64. /// <summary>
  65. /// 对玩家输出的总治疗量
  66. /// </summary>
  67. public abstract long PlayerHealing { get; }
  68. /// <summary>
  69. /// 连斩信息
  70. /// </summary>
  71. public abstract long preKillTime { get; set; }
  72. public abstract short continueKills { get; set; }
  73. /// <summary>
  74. /// 总共杀死特定类型单位数量
  75. /// </summary>
  76. /// <param name="type"></param>
  77. public abstract int GetKillUnitCount(UnitInfo.UnitType type);
  78. //------------------------------------------------------------------------------------
  79. /// <summary>
  80. /// 当自己死亡
  81. /// </summary>
  82. /// <param name="killer"></param>
  83. public abstract void onDead(InstanceUnit killer);
  84. /// <summary>
  85. /// 干掉别人
  86. /// </summary>
  87. /// <param name="target"></param>
  88. public abstract void onKill(InstanceUnit target);
  89. /// <summary>
  90. /// 当受到伤害
  91. /// </summary>
  92. /// <param name="attacker"></param>
  93. /// <param name="reduceHP"></param>
  94. public abstract void onDamage(InstanceUnit attacker, int reduceHP);
  95. /// <summary>
  96. /// 当造成伤害
  97. /// </summary>
  98. /// <param name="target"></param>
  99. /// <param name="reduceHP"></param>
  100. public abstract void onAttack(InstanceUnit target, int reduceHP);
  101. /// <summary>
  102. /// 当使用道具
  103. /// </summary>
  104. /// <param name="item"></param>
  105. public abstract void onUseItem(ItemTemplate item);
  106. //------------------------------------------------------------------------------------
  107. internal void LogDamage(IUnitStatistic attacker, int reduceHP)
  108. {
  109. if (reduceHP > 0 && this.Owner.CurrentHP < reduceHP)
  110. {
  111. reduceHP = this.Owner.CurrentHP;
  112. }
  113. if (reduceHP < 0 && this.Owner.MaxHP - this.Owner.CurrentHP < -reduceHP)
  114. {
  115. reduceHP = this.Owner.CurrentHP - this.Owner.MaxHP;
  116. }
  117. this.onDamage(attacker.Owner, reduceHP);
  118. attacker.onAttack(this.Owner, reduceHP);
  119. }
  120. internal void LogDead(IUnitStatistic attacker)
  121. {
  122. this.onDead(attacker.Owner);
  123. attacker.onKill(this.Owner);
  124. }
  125. internal void LogUseItem(ItemTemplate item)
  126. {
  127. this.onUseItem(item);
  128. }
  129. //------------------------------------------------------------------------------------
  130. }
  131. //------------------------------------------------------------------------------------
  132. public class UnitStatistic : IUnitStatistic
  133. {
  134. private int m_DeadCount = 0;
  135. private int m_KillPlayerCount = 0;
  136. private int m_KillUnitCount = 0;
  137. private long m_SelfDamage = 0;
  138. private long m_TotalDamage = 0;
  139. private long m_PlayerDamage = 0;
  140. private long m_TotalHealing = 0;
  141. private long m_PlayerHealing = 0;
  142. //联展信息
  143. private long m_preKillTime = 0;
  144. private short m_continueKills = 0;
  145. private Dictionary<UnitInfo.UnitType, int> m_KillUnitCountMap = new Dictionary<UnitInfo.UnitType, int>();
  146. public UnitStatistic(InstanceUnit owner) : base(owner)
  147. {
  148. }
  149. public override void Reset()
  150. {
  151. this.m_DeadCount = 0;
  152. this.m_KillPlayerCount = 0;
  153. this.m_KillUnitCount = 0;
  154. this.m_SelfDamage = 0;
  155. this.m_TotalDamage = 0;
  156. this.m_PlayerDamage = 0;
  157. this.m_TotalHealing = 0;
  158. this.m_PlayerHealing = 0;
  159. //联展信息
  160. this.m_preKillTime = 0;
  161. this.m_continueKills = 0;
  162. this.m_KillUnitCountMap.Clear();
  163. }
  164. public override int DeadCount { get { return m_DeadCount; } }
  165. public override int KillPlayerCount { get { return m_KillPlayerCount; } }
  166. public override int KillUnitCount { get { return m_KillUnitCount; } }
  167. public override long SelfDamage { get { return m_SelfDamage; } }
  168. public override long TotalDamage { get { return m_TotalDamage; } }
  169. public override long PlayerDamage { get { return m_PlayerDamage; } }
  170. public override long TotalHealing { get { return m_TotalHealing; } }
  171. public override long PlayerHealing { get { return m_PlayerHealing; } }
  172. /// <summary>
  173. /// 连斩信息
  174. /// </summary>
  175. public override long preKillTime { get { return m_preKillTime; } set { m_preKillTime = value; } }
  176. public override short continueKills { get { return m_continueKills; } set { m_continueKills = value; } }
  177. public override int GetKillUnitCount(UnitInfo.UnitType type)
  178. {
  179. int ret = 0;
  180. if (m_KillUnitCountMap.TryGetValue(type, out ret))
  181. return ret;
  182. return 0;
  183. }
  184. public override void onDead(InstanceUnit killer)
  185. {
  186. this.m_DeadCount += 1;
  187. }
  188. public override void onKill(InstanceUnit target)
  189. {
  190. this.m_KillUnitCount += 1;
  191. if (target.IsPlayer) { this.m_KillPlayerCount += 1; }
  192. int count = 0;
  193. if (this.m_KillUnitCountMap.TryGetValue(target.Info.UType, out count))
  194. {
  195. count += 1;
  196. this.m_KillUnitCountMap[target.Info.UType] = count;
  197. }
  198. else
  199. {
  200. this.m_KillUnitCountMap.Add(target.Info.UType, 1);
  201. }
  202. }
  203. public override void onDamage(InstanceUnit attacker, int reduceHP)
  204. {
  205. if (reduceHP > 0)
  206. {
  207. this.m_SelfDamage += reduceHP;
  208. }
  209. }
  210. public override void onAttack(InstanceUnit target, int reduceHP)
  211. {
  212. if (reduceHP > 0)
  213. {
  214. this.m_TotalDamage += reduceHP;
  215. if (target.IsPlayer)
  216. {
  217. this.m_PlayerDamage += reduceHP;
  218. }
  219. }
  220. else
  221. {
  222. this.m_TotalHealing += -reduceHP;
  223. if (target.IsPlayer)
  224. {
  225. this.m_PlayerHealing += -reduceHP;
  226. }
  227. }
  228. }
  229. public override void onUseItem(ItemTemplate item)
  230. {
  231. }
  232. }
  233. //
  234. // public class UnitStatistic
  235. // {
  236. // public readonly InstanceUnit Owner;
  237. //
  238. // private int mTotalTakeMoney = 0;
  239. //
  240. // //自身受到的伤害.
  241. // private long mSelfDamage;
  242. // //对怪物输出的伤害.
  243. // private long mMonsterDamage;
  244. // //对玩家输出伤害.
  245. // private long mPlayerDamage;
  246. //
  247. // //治疗回复血量.
  248. // private long mSelfHealing;
  249. // //怪物造成的治疗量.
  250. // private long mMonsterHealing;
  251. // //玩家造成的治疗量.
  252. // private long mPlayerHealing;
  253. //
  254. //
  255. // private int mDeadCount;
  256. // private int mKillPlayerCount;
  257. // private int mKillUnitCount;
  258. //
  259. // private HashMap<UnitInfo.UnitType, int> mKillUnitCountMap = new HashMap<UnitInfo.UnitType, int>();
  260. //
  261. // private List<int> mKilledEllitMonsters = new List<int>();
  262. //
  263. // private List<int> mUseItems = new List<int>();
  264. //
  265. // public UnitStatistic(InstanceUnit owner)
  266. // {
  267. // Owner = owner;
  268. // }
  269. //
  270. // protected internal virtual void onDead()
  271. // {
  272. // mDeadCount += 1;
  273. // }
  274. //
  275. // protected internal virtual void onHitAttack(InstanceUnit self, InstanceUnit sender, int reduceHP)
  276. // {
  277. // //伤害.
  278. // if (reduceHP > 0)
  279. // {
  280. // mSelfDamage += reduceHP;
  281. // if (self is InstancePlayer)
  282. // {
  283. // sender.Statistic.mOutPlayerDamage += reduceHP;
  284. // }
  285. // else
  286. // {
  287. // sender.Statistic.mOutMonsterDamage += reduceHP;
  288. // }
  289. // }
  290. // else if (reduceHP < 0)//治疗量.
  291. // {
  292. // mSelfHealingPerSecond += -reduceHP;
  293. // if (self is InstancePlayer)
  294. // {
  295. // sender.Statistic.mOutPlayerHealingPerSecond += -reduceHP;
  296. // }
  297. // else
  298. // {
  299. // sender.Statistic.mOutMonsterHealingPerSecond += -reduceHP;
  300. // }
  301. // }
  302. // else
  303. // {
  304. // return;
  305. // }
  306. //
  307. // if (self.IsDead)
  308. // {
  309. // sender.Statistic.addKillUnit(self);
  310. //
  311. // sender.Statistic.mTotalTakeMoney += self.Info.DropMoney;
  312. // }
  313. // }
  314. //
  315. // protected internal virtual void onUseItem(InstanceUnit self, ItemTemplate item)
  316. // {
  317. // mUseItems.Add(item.ID);
  318. // }
  319. //
  320. //
  321. //
  322. //
  323. // private void addKillUnit(InstanceUnit unit)
  324. // {
  325. // mKillUnitCount += 1;
  326. //
  327. // if (unit is InstancePlayer)
  328. // {
  329. // mKillPlayerCount += 1;
  330. // }
  331. // else if (unit.Info.IsElite)
  332. // {
  333. // mKilledEllitMonsters.Add(unit.Info.ID);
  334. // }
  335. //
  336. // UnitInfo.UnitType type = unit.Info.UType;
  337. // if (!mKillUnitCountMap.ContainsKey(type))
  338. // {
  339. // mKillUnitCountMap[type] = 1;
  340. // }
  341. // else
  342. // {
  343. // mKillUnitCountMap[type] = (mKillUnitCountMap[type] + 1);
  344. // }
  345. // }
  346. //
  347. //
  348. //
  349. // /// <summary>
  350. // /// 获取的金币数量
  351. // /// </summary>
  352. // public int TotalTakeMoney
  353. // {
  354. // get
  355. // {
  356. // return mTotalTakeMoney;
  357. // }
  358. // }
  359. //
  360. //
  361. // /// <summary>
  362. // /// 死亡次数
  363. // /// </summary>
  364. // public int DeadCount
  365. // {
  366. // get
  367. // {
  368. // return mDeadCount;
  369. // }
  370. // }
  371. //
  372. // /// <summary>
  373. // /// 承受伤害
  374. // /// </summary>
  375. // public long SelfDamage
  376. // {
  377. // get
  378. // {
  379. // return mSelfDamage;
  380. // }
  381. // }
  382. //
  383. // /// <summary>
  384. // /// 使用的所有道具 编辑器道具ID[]
  385. // /// </summary>
  386. // public int[] UseItems
  387. // {
  388. // get
  389. // {
  390. // return mUseItems.ToArray();
  391. // }
  392. // }
  393. //
  394. // /// <summary>
  395. // /// 总共杀死玩家数量
  396. // /// </summary>
  397. // public int KillPlayerCount
  398. // {
  399. // get
  400. // {
  401. // return mKillPlayerCount;
  402. // }
  403. // }
  404. //
  405. // public int KillUnitCount
  406. // {
  407. // get
  408. // {
  409. // return mKillUnitCount;
  410. // }
  411. // }
  412. //
  413. // /// <summary>
  414. // /// 杀死精英怪物 编辑器单位ID[]
  415. // /// </summary>
  416. // public int[] KilledEllitMonsters
  417. // {
  418. // get
  419. // {
  420. // return mKilledEllitMonsters.ToArray();
  421. // }
  422. // }
  423. //
  424. // /// <summary>
  425. // /// 对怪物造成的总伤害
  426. // /// </summary>
  427. // public long MonsterDamage
  428. // {
  429. // get
  430. // {
  431. // return mOutMonsterDamage;
  432. // }
  433. // }
  434. //
  435. // /// <summary>
  436. // /// 对玩家造成的总伤害
  437. // /// </summary>
  438. // public long PlayerDamage
  439. // {
  440. // get
  441. // {
  442. // return mOutPlayerDamage;
  443. // }
  444. // }
  445. // //治疗回复血量.
  446. // public long SelfHealingPerSecond
  447. // {
  448. // get
  449. // {
  450. // return mSelfHealingPerSecond;
  451. // }
  452. // }
  453. // //玩家造成的治疗量.
  454. // public long PlayerHealingPerSecond
  455. // {
  456. // get
  457. // {
  458. // return mOutPlayerHealingPerSecond;
  459. // }
  460. // }
  461. // //怪物造成的治疗量.
  462. // public long MonsterHealingPerSecond
  463. // {
  464. // get
  465. // {
  466. // return mOutMonsterHealingPerSecond;
  467. // }
  468. // }
  469. //
  470. // /// <summary>
  471. // /// 总共杀死怪物数量
  472. // /// </summary>
  473. // public int GetKillUnitCount(UnitInfo.UnitType type)
  474. // {
  475. // if (mKillUnitCountMap.ContainsKey(type))
  476. // {
  477. // return mKillUnitCountMap[type];
  478. // }
  479. // return 0;
  480. // }
  481. //
  482. // public UnitStatisticData ToUnitStatisticData()
  483. // {
  484. // var rst = new UnitStatisticData();
  485. // rst.ObjectID = Owner.ID;
  486. // rst.DeadCount = this.DeadCount;
  487. // rst.ItemTemplates = this.UseItems;
  488. // rst.KillUnitCount = this.KillUnitCount;
  489. // rst.KillEnemyCount = this.GetKillUnitCount(UnitInfo.UnitType.TYPE_MONSTER);
  490. // rst.KillNeutralityCount = this.GetKillUnitCount(UnitInfo.UnitType.TYPE_NEUTRALITY);
  491. // rst.KillBuildingCount = this.GetKillUnitCount(UnitInfo.UnitType.TYPE_BUILDING);
  492. // rst.KillPlayerCount = this.KillPlayerCount;
  493. // rst.MonsterDamage = this.MonsterDamage;
  494. // rst.PlayerDamage = this.PlayerDamage;
  495. // rst.SelfDamage = this.SelfDamage;
  496. // rst.TotalTakeMoney = this.TotalTakeMoney;
  497. // rst.KilledEllitMonsters = this.KilledEllitMonsters;
  498. // if (Owner is InstancePlayer)
  499. // {
  500. // // 统计杀死玩家 //
  501. // rst.KillPlayers = (Owner as InstancePlayer).KilledPlayersID;
  502. //
  503. // }
  504. // return rst;
  505. // }
  506. //
  507. // public RoomFinishInfoB2R.PlayerResult ToUnitStatisticDataServer()
  508. // {
  509. // RoomFinishInfoB2R.PlayerResult rst = new RoomFinishInfoB2R.PlayerResult();
  510. // rst.ZoneObjectID = Owner.ID;
  511. // rst.Force = Owner.Force;
  512. // rst.DeadCount = this.DeadCount;
  513. // rst.ItemTemplates = this.UseItems;
  514. // rst.KillUnitCount = this.KillUnitCount;
  515. // rst.KillEnemyCount = this.GetKillUnitCount(UnitInfo.UnitType.TYPE_MONSTER);
  516. // rst.KillNeutralityCount = this.GetKillUnitCount(UnitInfo.UnitType.TYPE_NEUTRALITY);
  517. // rst.KillBuildingCount = this.GetKillUnitCount(UnitInfo.UnitType.TYPE_BUILDING);
  518. // rst.KillPlayerCount = this.KillPlayerCount;
  519. // rst.MonsterDamage = this.MonsterDamage;
  520. // rst.PlayerDamage = this.PlayerDamage;
  521. // rst.SelfDamage = this.SelfDamage;
  522. // rst.TotalTakeMoney = this.TotalTakeMoney;
  523. // rst.KilledEllitMonsters = this.KilledEllitMonsters;
  524. // // 统计杀死玩家 //
  525. // if (Owner is InstancePlayer)
  526. // {
  527. // var p = Owner as InstancePlayer;
  528. // rst.KillPlayers = p.KilledPlayersID;
  529. // rst.PlayerUUID = p.PlayerUUID;
  530. // }
  531. // return rst;
  532. // }
  533. // public void FromUnitStatisticDataServer(RoomFinishInfoB2R.PlayerResult rst)
  534. // {
  535. // this.mDeadCount = rst.DeadCount;
  536. // this.mUseItems = new List<int>(rst.ItemTemplates);
  537. // this.mKillUnitCount = rst.KillUnitCount;
  538. // this.mKillUnitCountMap.Put(UnitInfo.UnitType.TYPE_MONSTER, rst.KillEnemyCount);
  539. // this.mKillUnitCountMap.Put(UnitInfo.UnitType.TYPE_NEUTRALITY, rst.KillNeutralityCount);
  540. // this.mKillUnitCountMap.Put(UnitInfo.UnitType.TYPE_BUILDING, rst.KillBuildingCount);
  541. // this.mKillPlayerCount = rst.KillPlayerCount;
  542. // this.mOutMonsterDamage = rst.MonsterDamage;
  543. // this.mOutPlayerDamage = rst.PlayerDamage;
  544. // this.mSelfDamage = rst.SelfDamage;
  545. // this.mTotalTakeMoney = rst.TotalTakeMoney;
  546. // this.mKilledEllitMonsters = new List<int>(rst.KilledEllitMonsters);
  547. // // 统计杀死玩家 //
  548. // if (Owner is InstancePlayer)
  549. // {
  550. // var p = Owner as InstancePlayer;
  551. // foreach (var uuid in rst.KillPlayers)
  552. // {
  553. // p.PutKillPlayer(uuid);
  554. // }
  555. // }
  556. // }
  557. // }
  558. }