Browse Source

增加玩家吃操作

johnclot69 10 months ago
parent
commit
f0cf47aa4e

+ 1 - 1
DotNet/Core/Core/Module/CoroutineLock/CoroutineLockType.cs

@@ -11,7 +11,7 @@ namespace ET
         public const int Resources = 6;
         public const int ResourcesLoader = 7;
 
-        public const int DisCard = 8;
+        public const int PlayerOperation = 8;           // 玩家操作出牌或吃碰杠胡过
 
         public const int Max = 100; // 这个必须最大
     }

+ 117 - 0
DotNet/Hotfix/Scenes/Game/Handler/C2G_OperationHandler.cs

@@ -0,0 +1,117 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace ET.Server
+{
+    /// <summary>
+    /// 玩家操作动作吃、碰、杠、胡、过
+    /// </summary>
+    [MessageHandler(SceneType.Game)]
+    public class C2G_OperationHandler : AMRpcHandler<C2G_Operation, G2C_Operation>
+    {
+        protected override async ETTask Run(Session session, C2G_Operation request, G2C_Operation response, Action reply)
+        {
+            Player player = session.GetComponent<SessionPlayerComponent>().GetMyPlayer();
+            if (player == null)
+            {
+                response.Error = ErrorCode.ERR_OperationError;
+                response.Message = "玩家不存在或离线...";
+                reply();
+                return;
+            }
+            
+            // 玩家是否进入房间
+            if (player.RoomId <= 0)
+            { 
+                response.Error = ErrorCode.ERR_OperationError;
+                response.Message = "玩家不在房间,不可操作...";
+                reply();
+                return;
+            }
+
+            Scene scene = session.DomainScene();
+            
+            // 房间是否能找到
+            Room room = scene.GetComponent<GameRoomComponent>().Get(player.RoomId);
+            if (room == null)
+            {
+                response.Error = ErrorCode.ERR_OperationError;
+                response.Message = "请求的房间不存在或已解散...";
+                reply();
+                return;
+            }
+            
+            // todo 玩家房间是否已开始, 后面这个判断要调整
+            // 房间状态
+            HGHuangHuangComponent hgHuangHuangComponent = room.GetComponent<HGHuangHuangComponent>();
+            if (hgHuangHuangComponent != null && hgHuangHuangComponent.State != 2)
+            {
+                response.Error = ErrorCode.ERR_OperationError;
+                response.Message = "房间不在游戏中,不可操作...";
+                reply();
+                return;
+            }
+            
+            // 玩家状态
+            if (player.State != 2)
+            {
+                response.Error = ErrorCode.ERR_OperationError;
+                response.Message = "玩家不在游戏中,不可操作...";
+                reply();
+                return;
+            }
+
+            if (request.OpType is < 0 or > 5)
+            {
+                response.Error = ErrorCode.ERR_ParameterError;
+                response.Message = "参数错误...";
+                reply();
+                return;
+            }
+            
+            if (request.Card <= 0 || !HGHuangHuangConst.Values.Contains(request.Card))
+            {
+                response.Error = ErrorCode.ERR_OperationError;
+                response.Message = "牌值错误...";
+                reply();
+                return;
+            }
+            
+            // 判断玩家是否可操作
+            if (!hgHuangHuangComponent.OperableList.Contains(player.Id))
+            {
+                response.Error = ErrorCode.ERR_OperationError;
+                response.Message = "不可操作...";
+                reply();
+                return;
+            }
+            
+            using (await CoroutineLockComponent.Instance.Wait(CoroutineLockType.PlayerOperation, player.Id))
+            {
+                switch (request.OpType)
+                {
+                    case 1:
+                        hgHuangHuangComponent.Chi(room, player, request.Card);
+                        break;
+                    case 2:
+                        hgHuangHuangComponent.Peng(room, player);
+                        break;
+                    case 3:
+                        hgHuangHuangComponent.Gang(room, player, request.Card);
+                        break;
+                    case 4:
+                        hgHuangHuangComponent.Hu(room, player);
+                        break;
+                    case 5:
+                        hgHuangHuangComponent.Guo(room, player);
+                        break;
+                }
+            }
+            
+            // 返回
+            reply();
+            await ETTask.CompletedTask;
+        }
+    }
+}

+ 156 - 14
DotNet/Hotfix/Scenes/Game/Room/HGHuangHuangComponentSystem.cs

@@ -31,10 +31,7 @@ namespace ET.Server
                 self.AdmitDefeatList = new List<long>();
                 self.CanHuIds = new List<Player>();
                 self.CanPgIds = new List<Player>();
-                self.OperableList = new List<Player>();
-                self.ClickHuIds = new List<Player>();
-                self.CanPgIds = new List<Player>();
-                self.OperableList = new List<Player>();
+                self.OperableList = new List<long>();
                 self.ClickHuIds = new List<Player>();
                 self.CardList = new List<int>();
                 self.UpdateTime = 0;
@@ -267,9 +264,9 @@ namespace ET.Server
                 hasAct = true;
                 drawCardPlayer.Act[3] = 1;
                 self.CanHuIds.Add(drawCardPlayer);
-                if (!self.OperableList.Contains(drawCardPlayer))
+                if (!self.OperableList.Contains(drawCardPlayer.Id))
                 {
-                    self.OperableList.Add(drawCardPlayer);
+                    self.OperableList.Add(drawCardPlayer.Id);
                 }
             }
             // todo 玩家听牌状态不允许杠
@@ -279,9 +276,9 @@ namespace ET.Server
             {
                 hasAct = true;
                 drawCardPlayer.Act[2] = 1;
-                if (!self.OperableList.Contains(drawCardPlayer))
+                if (!self.OperableList.Contains(drawCardPlayer.Id))
                 {
-                    self.OperableList.Add(drawCardPlayer);
+                    self.OperableList.Add(drawCardPlayer.Id);
                 }
                 if (!self.CanPgIds.Contains(drawCardPlayer))
                 {
@@ -318,7 +315,7 @@ namespace ET.Server
                 Log.Error($"出牌错误,player is null.");
                 return;
             }
-            using (await CoroutineLockComponent.Instance.Wait(CoroutineLockType.DisCard, player.Id))
+            using (await CoroutineLockComponent.Instance.Wait(CoroutineLockType.PlayerOperation, player.Id))
             {
                 if (self.CurrentPlayer.Id == player.Id && self.DrawCardPlayer.Id == player.Id)
                 {
@@ -409,9 +406,9 @@ namespace ET.Server
                                         self.CanHuIds.Add(otherPlayer);
                                     }
                                     // 加入可操作玩家list
-                                    if (!self.OperableList.Contains(otherPlayer))
+                                    if (!self.OperableList.Contains(otherPlayer.Id))
                                     {
-                                        self.OperableList.Add(otherPlayer);
+                                        self.OperableList.Add(otherPlayer.Id);
                                     }
                                 }
                                 // 是否杠
@@ -438,8 +435,8 @@ namespace ET.Server
                                 }
                                 if (act[2] == 1 || act[1] == 1) {
                                     // 加入可操作玩家list
-                                    if (!self.OperableList.Contains(otherPlayer)) {
-                                        self.OperableList.Add(otherPlayer);
+                                    if (!self.OperableList.Contains(otherPlayer.Id)) {
+                                        self.OperableList.Add(otherPlayer.Id);
                                     }
                                     // 加入可碰杠玩家集合
                                     if (!self.CanPgIds.Contains(otherPlayer)) {
@@ -498,13 +495,158 @@ namespace ET.Server
                         }
                         else
                         {
-                            self.CurrentPlayer = self.Players[self.OperableList.First().Pos];
+                            long id = self.OperableList.First();
+                            Player tmpPlayer = room.GetPlayer(id);
+                            if (tmpPlayer != null)
+                            {
+                                self.CurrentPlayer = self.Players[tmpPlayer.Pos];
+                            }
                         }
                     }
                 }
             }
         }
 
+        /// <summary>
+        /// 玩家是否可以操作吃
+        /// </summary>
+        /// <param name="self"></param>
+        /// <param name="player"></param>
+        /// <returns></returns>
+        private static bool IsCanChi(this HGHuangHuangComponent self, Player player)
+        {
+            if (self.ClickHuIds.Count > 0)
+            {
+                return false;
+            }
+
+            if (self.CanHuIds.Count > 1)
+            {
+                return false;
+            }
+            else
+            {
+                if (self.CanHuIds.Count == 1)
+                {
+                    if (self.CanPgIds.Count > 0)
+                    {
+                        if (self.CanPgIds.Any(p => p != null && p.Id != player.Id))
+                        {
+                            return false;
+                        }
+                    }
+
+                    return self.CanHuIds.Contains(player);
+                }
+                else
+                {
+                    if (self.CanPgIds.Count > 0)
+                    {
+                        return self.CanPgIds.Contains(player);
+                    }
+                    else
+                    {
+                        return true;
+                    }
+                }
+            }
+        }
+
+        /// <summary>
+        /// 玩家操作吃
+        /// </summary>
+        /// <param name="self"></param>
+        /// <param name="room"></param>
+        /// <param name="player"></param>
+        /// <param name="card"></param>
+        public static void Chi(this HGHuangHuangComponent self, Room room, Player player, int card)
+        {
+            if (self.IsCanChi(player))
+            {
+                return;
+            }
+
+            if (self.DisCard >= HGHuangHuangConst.DONG_FENG)
+            {
+                return;
+            }
+
+            // 删除出牌人打出的牌堆
+            self.DisCardPlayer.DisCards = CardHelper.Remove(self.DisCardPlayer.DisCards, self.DisCard);
+            // 吃牌玩家的手牌
+            int[] temp = CardHelper.Add(player.RemainCards, self.DisCard);
+            for (int i = 0; i < 3; i++)
+            {
+                temp = CardHelper.Remove(temp, card + i);
+            }
+
+            player.RemainCards = temp;
+            // 刻子
+            player.KeZi.Add(new Struct.Kezi((int)HGHuangHuangConst.KeziType.CHI, card, self.DisCardPlayer.Id));
+                
+            self.OperableList.Clear();
+            // 重置摸牌人
+            self.DrawCardPlayer = player;
+            self.PengPlayer = player;
+            
+            // 重置时间和流程标记
+            self.Time = 15;
+            self.Flag = false;
+            
+            Log.Info($"玩家吃牌... 玩家ID:{player.Id}, 位置:{player.Pos}, 手牌大小:{player.RemainCards.Length}, 手牌信息:{string.Join(", ", player.RemainCards)}, 吃的牌:{card}");
+            
+            // 广播
+            foreach (Player p in room.GetAllPlayers().Values.Where(p => p != null))
+            {
+                MessageHelper.SendToClient(p, new G2C_DrawCardPush(){info = ProtoHelper.RoomToProto(room, p, p)});
+            }
+        }
+        
+        /// <summary>
+        /// 玩家操作碰
+        /// </summary>
+        /// <param name="self"></param>
+        /// <param name="room"></param>
+        /// <param name="player"></param>
+        public static  void Peng(this HGHuangHuangComponent self, Room room, Player player)
+        {
+            
+        }
+        
+        /// <summary>
+        /// 玩家操作杠
+        /// </summary>
+        /// <param name="self"></param>
+        /// <param name="room"></param>
+        /// <param name="player"></param>
+        /// <param name="card"></param>
+        public static void Gang(this HGHuangHuangComponent self, Room room, Player player, int card)
+        {
+            
+        }
+        
+        /// <summary>
+        /// 玩家操作胡
+        /// </summary>
+        /// <param name="self"></param>
+        /// <param name="room"></param>
+        /// <param name="player"></param>
+        public static void Hu(this HGHuangHuangComponent self, Room room, Player player)
+        {
+            
+        }
+        
+        /// <summary>
+        /// 玩家操作过
+        /// </summary>
+        /// <param name="self"></param>
+        /// <param name="room"></param>
+        /// <param name="player"></param>
+        public static void Guo(this HGHuangHuangComponent self, Room room, Player player)
+        {
+            
+        }
+
         /// <summary>
         /// 清空玩家可操作动作
         /// </summary>

+ 12 - 1
DotNet/Hotfix/Scenes/Game/Room/RoomSystem.cs

@@ -104,7 +104,18 @@ namespace ET.Server
         {
             self.Players.Remove(playerId);
         }
-        
+
+        /// <summary>
+        /// 获取房间内玩家
+        /// </summary>
+        /// <param name="self"></param>
+        /// <param name="playerId"></param>
+        /// <returns></returns>
+        public static Player GetPlayer(this Room self, long playerId)
+        {
+            return self.Players.GetValueOrDefault(playerId);
+        }
+
         /// <summary>
         /// 是否玩家都已准备,可开始
         /// </summary>

+ 1 - 1
DotNet/Model/Scenes/Game/Room/HGHuangHuangComponent.cs

@@ -44,7 +44,7 @@ namespace ET.Server
         /** 可碰杠玩家集合 **/
         public List<Player> CanPgIds { get; set; }
         /** 可操作玩家集合 **/
-        public List<Player> OperableList { get; set; }
+        public List<long> OperableList { get; set; }
         /** 点击胡的玩家集合 **/
         public List<Player> ClickHuIds { get; set; }
         /** 牌库 **/