Boss.cs 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading;
  6. using System.Threading.Tasks;
  7. using System.Threading.Channels;
  8. using pb = global::Google.Protobuf;
  9. namespace BossServer.server
  10. {
  11. /// <summary>
  12. /// Boss对象
  13. /// </summary>
  14. class Boss
  15. {
  16. /// <summary>
  17. /// 当前血量
  18. /// </summary>
  19. public volatile int Hp;
  20. /// <summary>
  21. /// 最大血量
  22. /// </summary>
  23. public readonly int MaxHp;
  24. public int CountDownSecs;
  25. /// <summary>
  26. /// boss ZoneID
  27. /// </summary>
  28. public int ZoneId;
  29. /// <summary>
  30. /// boss id (大小boss,现在只有1,2)
  31. /// </summary>
  32. public int Id;
  33. /// <summary>
  34. /// 唯一id
  35. /// </summary>
  36. public string UID => $"{ZoneId}-{Id}";
  37. public Dictionary<int, Peer> Peers;
  38. public Channel<int> DamageQueue;
  39. private Action<Boss> _Settle;
  40. private readonly Timer timer;
  41. /// <summary>
  42. /// 倒计时模块
  43. /// </summary>
  44. /// <param name="stateObject"></param>
  45. private void OnTimer(object stateObject)
  46. {
  47. CountDownSecs--;
  48. }
  49. /// <summary>
  50. /// 战斗结束
  51. /// </summary>
  52. public bool Ended { get; private set; } = false;
  53. public Boss(int id, int zoneid, int maxHp, Action<Boss> Settle)
  54. {
  55. this.Id = id;
  56. this.ZoneId = zoneid;
  57. this.Hp = this.MaxHp = maxHp;
  58. this.CountDownSecs = Config.Ins.CountDownTimes;
  59. var roomName = Room.Instance.Name ?? "Room";
  60. var redis_key = MemKey_Game.BossFight_Damage_byDateHour_zset(Convert.ToInt32(ZoneId), Id, roomName);
  61. var rdb = Redis.Ins.GetDatabase(0);
  62. rdb.KeyDelete(redis_key);
  63. this.Peers = new Dictionary<int, Peer>();
  64. this.DamageQueue = Channel.CreateBounded<int>(100);
  65. this._Settle = Settle;
  66. var t = Task.Run(Damage);
  67. this.timer = new Timer(OnTimer, null, 0, 1000); // 1秒1次
  68. var end = Task.Delay(TimeSpan.FromSeconds(Config.Ins.CountDownTimes)).ContinueWith(t => // 10分钟结束战斗
  69. {
  70. this.Settle();
  71. });
  72. }
  73. private async Task<int> Damage()
  74. {
  75. while (Hp > 0)
  76. {
  77. var damage = await DamageQueue.Reader.ReadAsync();
  78. Hp += damage;
  79. if (Hp < 0)
  80. {
  81. Hp = 0;
  82. }
  83. CheckHp();
  84. }
  85. return 0;
  86. }
  87. public void CheckHp()
  88. {
  89. if (Hp > 0)
  90. {
  91. BroadUpdate();
  92. }
  93. else
  94. {
  95. Settle();
  96. }
  97. }
  98. private void Settle()
  99. {
  100. if (!this.Ended)
  101. {
  102. this.Ended = true;
  103. this.CountDownSecs = Config.Ins.CountDownTimes;
  104. BroadGameOver();
  105. this?._Settle(this);
  106. }
  107. }
  108. private void BroadGameOver()
  109. {
  110. Console.WriteLine("游戏结束1");
  111. this.Broadcast(TargetType.All, eProtocalCommand.ScGameOver, new SCGameOver() { BossHp = this.Hp, CountDown = this.CountDownSecs });
  112. this.Peers.Values.ToList().ForEach(p => p.Close());
  113. }
  114. private void BroadUpdate()
  115. {
  116. this.Broadcast(TargetType.All, eProtocalCommand.ScUpdateProperties, new SCUpdateProperties() { BossMaxHp = this.MaxHp, BossHp = this.Hp, CountDown = this.CountDownSecs });
  117. }
  118. /// <summary>
  119. /// 广播消息
  120. /// </summary>
  121. /// <param name="targetType"></param>
  122. /// <param name="msgType"></param>
  123. /// <param name="msg"></param>
  124. private void Broadcast(TargetType targetType, eProtocalCommand msgType, pb::IMessage msg)
  125. {
  126. switch (targetType)
  127. {
  128. case TargetType.All:
  129. this.Peers.Values.ToList().ForEach(p => p.SendEvent(msgType, msg));
  130. break;
  131. case TargetType.Others:
  132. break;
  133. }
  134. }
  135. }
  136. }