csharp/8720826/emud/src/Emprise.MudServer/JobHandlers/PlayerStatusHandler.cs

PlayerStatusHandler.cs
using Emprise.Domain.Core.Bus;
using Emprise.Domain.Core.Enums;
using Emprise.Domain.Core.Extensions;
using Emprise.Domain.Core.Interfaces;
using Emprise.Domain.Core.Interfaces.Ioc;
using Emprise.Domain.Core.Models;
using Emprise.Domain.Core.Queue.Models;
using Emprise.Domain.ItemDrop.Models;
using Emprise.Domain.ItemDrop.Services;
using Emprise.Domain.Npc.Ensaty;
using Emprise.Domain.Npc.Services;
using Emprise.Domain.Player.Ensaty;
using Emprise.Domain.Player.Services;
using Emprise.Domain.Room.Services;
using Emprise.Domain.Skill.Services;
using Emprise.Domain.Ware.Ensaty;
using Emprise.Domain.Ware.Services;
using Emprise.MudServer.Events;
using Emprise.MudServer.Models;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Diagnostics.Codeastysis;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Emprise.MudServer.Handles
{
    public interface IPlayerStatusHandler : IScoped
    {
        Task Execute(PlayerStatusModel model);
    }
    public clast PlayerStatusHandler : IPlayerStatusHandler
    {
        private readonly IMudProvider _mudProvider;
        private readonly IPlayerDomainService _playerDomainService;
        private readonly ILogger _logger;
        private readonly IRecurringQueue _recurringQueue;
        private readonly IMediatorHandler _bus;
        private readonly IMudOnlineProvider _mudOnlineProvider;
        private readonly IRoomItemDropDomainService  _roomItemDropDomainService;
        private readonly IItemDropDomainService  _itemDropDomainService;
        private readonly IItemDropRateDomainService  _itemDropRateDomainService;
        private readonly IWareDomainService _wareDomainService;
        private readonly IPlayerWareDomainService _playerWareDomainService;
        private readonly ISkillDomainService _skillDomainService;
        private readonly IPlayerSkillDomainService _playerSkillDomainService;
        private readonly INpcDomainService _npcDomainService;
        private readonly IRedisDb _redisDb;
        public PlayerStatusHandler(
            IMudProvider mudProvider, 
            IPlayerDomainService playerDomainService, 
            ILogger logger, 
            IRecurringQueue recurringQueue,
            IMudOnlineProvider mudOnlineProvider,
           IRoomItemDropDomainService roomItemDropDomainService,
           IItemDropDomainService itemDropDomainService,
           IItemDropRateDomainService itemDropRateDomainService,
           IWareDomainService wareDomainService,
           IPlayerWareDomainService playerWareDomainService,
           ISkillDomainService skillDomainService,
           IPlayerSkillDomainService playerSkillDomainService,
           INpcDomainService npcDomainService,
           IRedisDb redisDb,
            IMediatorHandler bus)
        {
            _mudProvider = mudProvider;
            _playerDomainService = playerDomainService;
            _logger = logger;
            _recurringQueue = recurringQueue;
            _bus = bus;
            _mudOnlineProvider = mudOnlineProvider;
            _roomItemDropDomainService = roomItemDropDomainService;
            _itemDropDomainService = itemDropDomainService;
            _itemDropRateDomainService = itemDropRateDomainService;
            _wareDomainService = wareDomainService;
            _playerWareDomainService = playerWareDomainService;
            _skillDomainService = skillDomainService;
            _playerSkillDomainService = playerSkillDomainService;
            _npcDomainService = npcDomainService;
            _redisDb = redisDb;
        }
        public async Task Execute(PlayerStatusModel model)
        {
            int playerId = model.PlayerId;
            var player = await _playerDomainService.Get(playerId);
            if (player == null)
            {
                return;
            }

            var online = await _mudOnlineProvider.GetPlayerOnline(playerId);
            if (online == null)
            {
                //玩家离线后,从队列删除,并且修改状态为空闲
                await _recurringQueue.Remove($"player_{playerId}");
                if (player.Status!= PlayerStatusEnum.空闲)
                {
                    player.Status = PlayerStatusEnum.空闲;
                    await _playerDomainService.Update(player);

                    await _bus.RaiseEvent(new PlayerStatusChangedEvent(player)).ConfigureAwait(false);
                }
                return;
            }

            if (player.Status!= model.Status)
            {
                await _recurringQueue.Remove($"player_{playerId}");
                return;
            }

            var remainingTime = await _recurringQueue.GetRemainingTime($"player_{playerId}");


            await _mudProvider.ShowRemainingTime(playerId, remainingTime);

            //TODO
            switch (model.Status)
            {
                case PlayerStatusEnum.伐木:
                case PlayerStatusEnum.挖矿:
                case PlayerStatusEnum.打猎:
                case PlayerStatusEnum.采药:
                case PlayerStatusEnum.钓鱼:
                case PlayerStatusEnum.打工:

                    await DoWork(player);
                    break;

                case PlayerStatusEnum.疗伤:
                    await Heal(player);
                    break;

                case PlayerStatusEnum.打坐:
                    await Muse(player);
                    break;

                case PlayerStatusEnum.切磋:
                    await Fighting(player, model.TargetType, model.TargetId);
                    break;

                case PlayerStatusEnum.战斗:
                    await Killing(player, model.TargetId);
                    break;



            }

          
        }


        private async Task DoWork(PlayerEnsaty player)
        {
            await _mudProvider.ShowMessage(player.Id, $"你正在{player.Status}。。。");
            WorkTypeEnum workType = WorkTypeEnum.伐木;
            switch (player.Status)
            {
                case PlayerStatusEnum.伐木:
                    workType = WorkTypeEnum.伐木;
                    break;
                case PlayerStatusEnum.挖矿:
                    workType = WorkTypeEnum.挖矿;
                    break;
                case PlayerStatusEnum.打猎:
                    workType = WorkTypeEnum.打猎;
                    break;
                case PlayerStatusEnum.采药:
                    workType = WorkTypeEnum.采药;
                    break;
                case PlayerStatusEnum.钓鱼:
                    workType = WorkTypeEnum.钓鱼;
                    break;
                case PlayerStatusEnum.打工:
                    workType = WorkTypeEnum.打工;
                    break;

                default:
                    return;
            }

            var ids = (await _roomItemDropDomainService.GetAll()).Where(x => x.RoomId == player.RoomId).Select(x=>x.ItemDropId).ToList();

            var itemDrop = (await _itemDropDomainService.GetAll()).Where(x => ids.Contains(x.Id)).FirstOrDefault(x => x.WorkType == workType);
            if (itemDrop == null)
            {
                return;
            }
           

            var itemDropRates = (await _itemDropRateDomainService.GetAll()).Where(x => x.ItemDropId == itemDrop.Id).ToList();
            if (itemDropRates?.Count == 0)
            {
                return;
            }

            var random = new Random();
            int maxWeight = 100;//掉落总权重
            var itemDropModels = new List();
            foreach (var itemDropRate in itemDropRates.OrderBy(x=>x.Order))
            {
                if (itemDropRate.Percent < random.Next(0, 100))
                {
                    continue;
                }

                int number = random.Next(Math.Min(itemDropRate.MinNumber, itemDropRate.MaxNumber), itemDropRate.MaxNumber + 1);
                if (number  0)
            {
                await _mudProvider.ShowMessage(player.Id, $"获得{ string.Join(",", dropContents)   }。");   
            }


        }


        /// 
        /// 疗伤,恢复体力
        /// 
        /// 
        /// 
        private async Task Heal(PlayerEnsaty player)
        {
            if (player.Hp >= player.MaxHp)
            {
                await _mudProvider.ShowMessage(player.Id, $"{player.Status}结束,你站了起来。。。");

                await StopAction(player);
            }
            else
            {
                Random random = new Random();
                int addHp = random.Next((player.MaxHp / 40) + 1, (player.MaxHp / 20) + 1);
                if (player.Hp + addHp > player.MaxHp)
                {
                    addHp = player.MaxHp - player.Hp;
                }
                player.Hp += addHp;

                await _mudProvider.ShowMessage(player.Id, $"你正在{player.Status}。。。");
                await _mudProvider.ShowMessage(player.Id, $"你感觉身体好多了,气血恢复 +{addHp}。。。");
                await _bus.RaiseEvent(new PlayerAttributeChangedEvent(player)).ConfigureAwait(false);
            }
         
        }

        /// 
        /// 打坐,恢复内力
        /// 
        /// 
        /// 
        private async Task Muse(PlayerEnsaty player)
        {
            if (player.Mp >= player.MaxMp)
            {
                await StopAction(player);
                await _mudProvider.ShowMessage(player.Id, $"{player.Status}结束,你站了起来。。。");
            }
            else
            {
                Random random = new Random();
                int addMp = random.Next((player.MaxMp / 40) + 1, (player.MaxMp / 20) + 1);
                if (player.Mp + addMp > player.MaxMp)
                {
                    addMp = player.MaxMp - player.Mp;
                }
                player.Mp += addMp;
                await _playerDomainService.Update(player);

                await _mudProvider.ShowMessage(player.Id, $"你正在{player.Status}。。。");
                await _mudProvider.ShowMessage(player.Id, $"你感觉精神好多了,内力恢复 +{addMp}。。。");
                await _bus.RaiseEvent(new PlayerAttributeChangedEvent(player)).ConfigureAwait(false);
            }
          
        }

        private async Task Fighting(PlayerEnsaty player, TargetTypeEnum? targetType, int targetId)
        {
            if (targetType == TargetTypeEnum.Npc)
            {
                var npc = await _npcDomainService.Get(targetId);
                if (npc == null)
                {
                    await StopAction(player);
                    return;
                }

                var npcFightingPlayerId = await _redisDb.StringGet(string.Format(RedisKey.NpcFighting, npc.Id));
                if (npcFightingPlayerId != player.Id)
                {
                    await StopAction(player);
                    return;
                }

                await _redisDb.StringSet(string.Format(RedisKey.NpcFighting, npc.Id), player.Id, DateTime.Now.AddSeconds(60));

                await FightingNpc(player, npc);
            }
            else if (targetType == TargetTypeEnum.玩家)
            {
                var target = await _playerDomainService.Get(targetId);
                if (target == null)
                {
                    await StopAction(player);
                    return;
                }

                await FightingPlayer(player, target);
            }
            else
            {
                await StopAction(player);
            }


          

        }

        private async Task FightingNpc(PlayerEnsaty player, NpcEnsaty npc)
        {
            var actionPoint = await _redisDb.StringGet(string.Format(RedisKey.ActionPoint, player.Id));
            if (actionPoint < 10)
            {
                actionPoint++;
            }

            Random random = new Random();

            actionPoint -= random.Next(0, 4);
            if (actionPoint