123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162 |
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading;
- using System.Threading.Tasks;
- using System.Threading.Channels;
- using pb = global::Google.Protobuf;
- namespace BossServer.server
- {
- /// <summary>
- /// Boss对象
- /// </summary>
- class Boss
- {
- /// <summary>
- /// 当前血量
- /// </summary>
- public volatile int Hp;
- /// <summary>
- /// 最大血量
- /// </summary>
- public readonly int MaxHp;
- public int CountDownSecs;
- /// <summary>
- /// boss ZoneID
- /// </summary>
- public int ZoneId;
- /// <summary>
- /// boss id (大小boss,现在只有1,2)
- /// </summary>
- public int Id;
- /// <summary>
- /// 唯一id
- /// </summary>
- public string UID => $"{ZoneId}-{Id}";
- public Dictionary<int, Peer> Peers;
- public Channel<int> DamageQueue;
- private Action<Boss> _Settle;
- private readonly Timer timer;
- /// <summary>
- /// 倒计时模块
- /// </summary>
- /// <param name="stateObject"></param>
- private void OnTimer(object stateObject)
- {
- CountDownSecs--;
- }
- /// <summary>
- /// 战斗结束
- /// </summary>
- public bool Ended { get; private set; } = false;
- public Boss(int id, int zoneid, int maxHp, Action<Boss> Settle)
- {
- this.Id = id;
- this.ZoneId = zoneid;
- this.Hp = this.MaxHp = maxHp;
- this.CountDownSecs = Config.Ins.CountDownTimes;
- var roomName = Room.Instance.Name ?? "Room";
- var redis_key = MemKey_Game.BossFight_Damage_byDateHour_zset(Convert.ToInt32(ZoneId), Id, roomName);
- var rdb = Redis.Ins.GetDatabase(0);
- rdb.KeyDelete(redis_key);
- this.Peers = new Dictionary<int, Peer>();
- this.DamageQueue = Channel.CreateBounded<int>(100);
- this._Settle = Settle;
- var t = Task.Run(Damage);
- this.timer = new Timer(OnTimer, null, 0, 1000); // 1秒1次
- var end = Task.Delay(TimeSpan.FromSeconds(Config.Ins.CountDownTimes)).ContinueWith(t => // 10分钟结束战斗
- {
- this.Settle();
- });
- }
- private async Task<int> Damage()
- {
- while (Hp > 0)
- {
- var damage = await DamageQueue.Reader.ReadAsync();
- Hp += damage;
- if (Hp < 0)
- {
- Hp = 0;
- }
- CheckHp();
- }
- return 0;
- }
- public void CheckHp()
- {
- if (Hp > 0)
- {
- BroadUpdate();
- }
- else
- {
- Settle();
- }
- }
- private void Settle()
- {
- if (!this.Ended)
- {
- this.Ended = true;
- this.CountDownSecs = Config.Ins.CountDownTimes;
- BroadGameOver();
- this?._Settle(this);
- }
- }
- private void BroadGameOver()
- {
- Console.WriteLine("游戏结束1");
- this.Broadcast(TargetType.All, eProtocalCommand.ScGameOver, new SCGameOver() { BossHp = this.Hp, CountDown = this.CountDownSecs });
- this.Peers.Values.ToList().ForEach(p => p.Close());
- }
- private void BroadUpdate()
- {
- this.Broadcast(TargetType.All, eProtocalCommand.ScUpdateProperties, new SCUpdateProperties() { BossMaxHp = this.MaxHp, BossHp = this.Hp, CountDown = this.CountDownSecs });
- }
- /// <summary>
- /// 广播消息
- /// </summary>
- /// <param name="targetType"></param>
- /// <param name="msgType"></param>
- /// <param name="msg"></param>
- private void Broadcast(TargetType targetType, eProtocalCommand msgType, pb::IMessage msg)
- {
- switch (targetType)
- {
- case TargetType.All:
- this.Peers.Values.ToList().ForEach(p => p.SendEvent(msgType, msg));
- break;
- case TargetType.Others:
- break;
- }
- }
- }
- }
|