HGHuangHuangComponentSystem.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. namespace ET.Server
  5. {
  6. [FriendOf(typeof (HGHuangHuangComponent))]
  7. public static class HGHuangHuangComponentSystem
  8. {
  9. [ObjectSystem]
  10. public class HGHuangHuangComponentAwakeSystem: AwakeSystem<HGHuangHuangComponent>
  11. {
  12. protected override void Awake(HGHuangHuangComponent self)
  13. {
  14. Room room = self.GetParent<Room>();
  15. if (room == null)
  16. {
  17. Log.Error($"黄冈晃晃主逻辑组件获取不到主实体...");
  18. return;
  19. }
  20. Log.Info($"创建黄冈晃晃主逻辑组件...");
  21. self.Flag = false;
  22. self.Time = 0;
  23. self.State = 0;
  24. self.Players = new Player[4];
  25. self.CurrentRound = 0;
  26. self.ZhuangPos = 0;
  27. self.Rand = new[] { 0, 0 };
  28. self.AdmitDefeatList = new List<long>();
  29. self.CanHuIds = new List<Player>();
  30. self.CanPgIds = new List<Player>();
  31. self.OperableList = new List<Player>();
  32. self.ClickHuIds = new List<Player>();
  33. self.CardList = new List<int>();
  34. self.UpdateTime = 0;
  35. // 初始化玩家
  36. int index = 0;
  37. foreach (Player player in room.GetAllPlayers().Values)
  38. {
  39. if (player != null)
  40. {
  41. self.Players[index] = player;
  42. index++;
  43. }
  44. }
  45. // 初始化牌库
  46. for (int i = 0; i < 4; i++)
  47. {
  48. foreach (int value in HGHuangHuangConst.Values)
  49. {
  50. self.CardList.Add(value);
  51. }
  52. RandomGenerator.Shuffle(self.CardList);
  53. }
  54. }
  55. }
  56. [ObjectSystem]
  57. public class HGHuangHuangComponentDestroySystem: DestroySystem<HGHuangHuangComponent>
  58. {
  59. protected override void Destroy(HGHuangHuangComponent self)
  60. {
  61. Log.Info($"销毁黄冈晃晃主逻辑组件...");
  62. }
  63. }
  64. [ObjectSystem]
  65. [FriendOf(typeof(Room))]
  66. public class HGHuangHuangComponentUpdateSystem : UpdateSystem<HGHuangHuangComponent>
  67. {
  68. protected override void Update(HGHuangHuangComponent self)
  69. {
  70. long timeNow = TimeHelper.ClientNow();
  71. // 每秒执行一次
  72. if (timeNow - self.UpdateTime <= 1000)
  73. {
  74. return;
  75. }
  76. self.UpdateTime = timeNow;
  77. Room room = self.GetParent<Room>();
  78. if (room == null)
  79. {
  80. Log.Error($"黄冈晃晃主逻辑组件获取不到主实体...");
  81. return;
  82. }
  83. switch (self.State)
  84. {
  85. case 0:
  86. // 等待状态
  87. Log.Debug($"检测: 黄冈晃晃-房间号:{room.RoomId}, 房间人数:{room.Players.Count}, 状态:检测是否可开局...");
  88. if (self.CheckReadyStart(room))
  89. {
  90. self.State = 1;
  91. self.Flag = false;
  92. self.Time = 0;
  93. }
  94. // 120秒未开始直接解散
  95. if (self.Time >= 120)
  96. {
  97. room.Dispose();
  98. }
  99. break;
  100. case 1:
  101. // 开局
  102. if (!self.Flag)
  103. {
  104. if (self.Time >= 3)
  105. {
  106. self.Start(room);
  107. self.Flag = true;
  108. self.Time = 0;
  109. Log.Debug($"检测: 黄冈晃晃-房间号:{room.RoomId}, 房间人数:{room.Players.Count}, 状态:开局...VS动画...");
  110. }
  111. }
  112. else
  113. {
  114. if (self.Time > 0)
  115. {
  116. self.State = 2;
  117. self.Flag = false;
  118. self.Time = 0;
  119. }
  120. }
  121. break;
  122. case 2:
  123. // 进行中
  124. if (!self.Flag)
  125. {
  126. self.Flag = true;
  127. self.Time = 0;
  128. // 摸牌
  129. self.DrawCard(room);
  130. }
  131. else
  132. {
  133. // 强制操作
  134. if (self.Time > 30)
  135. {
  136. }
  137. }
  138. break;
  139. case 3:
  140. // 已结束
  141. break;
  142. }
  143. self.Time++;
  144. }
  145. }
  146. /// <summary>
  147. /// 检测是否可开始 3秒倒计时开始
  148. /// </summary>
  149. /// <param name="self"></param>
  150. /// <param name="room"></param>
  151. /// <returns></returns>
  152. private static bool CheckReadyStart(this HGHuangHuangComponent self, Room room)
  153. {
  154. if (!room.IsStart() || self.State != 0)
  155. {
  156. return false;
  157. }
  158. // 通知客户端3秒倒计时
  159. foreach (Player player in room.GetAllPlayers().Values.Where(player => player != null))
  160. {
  161. MessageHelper.SendToClient(player, new G2C_ReadyStartPush(){ReadyStartTime = 3});
  162. }
  163. return true;
  164. }
  165. /// <summary>
  166. /// 发牌
  167. /// </summary>
  168. /// <param name="self"></param>
  169. /// <param name="room"></param>
  170. private static void SendCard(this HGHuangHuangComponent self, Room room)
  171. {
  172. foreach (Player player in room.GetAllPlayers().Values)
  173. {
  174. if (player == null)
  175. {
  176. continue;
  177. }
  178. for (int i = 0; i < 13; i++)
  179. {
  180. int card = self.CardList[0];
  181. player.RemainCards = CardHelper.Add(player.RemainCards, card);
  182. self.CardList.RemoveAt(0);
  183. }
  184. }
  185. }
  186. /// <summary>
  187. /// 游戏开局
  188. /// </summary>
  189. /// <param name="self"></param>
  190. /// <param name="room"></param>
  191. private static void Start(this HGHuangHuangComponent self, Room room)
  192. {
  193. self.CurrentRound += 1;
  194. // 摇骰子
  195. int rand1 = RandomGenerator.RandomNumber(1, 7);
  196. int rand2 = RandomGenerator.RandomNumber(1, 7);
  197. self.Rand = new[] { rand1, rand2 };
  198. // 定庄
  199. self.ZhuangPos = (rand1 + rand2) % 4;
  200. // 设置当前操作玩家
  201. self.CurrentPlayer = room.GetAllPlayers()[self.ZhuangPos];
  202. // 设置当前摸牌玩家
  203. self.DrawCardPlayer = room.GetAllPlayers()[self.ZhuangPos];
  204. // 发牌
  205. self.SendCard(room);
  206. // 广播
  207. foreach (Player player in room.GetAllPlayers().Values)
  208. {
  209. if (player == null)
  210. {
  211. continue;
  212. }
  213. player.State = 2;
  214. MessageHelper.SendToClient(player, new G2C_StartPush(){info = ProtoHelper.RoomToProto(room, player, null)});
  215. Log.Info($"游戏开局, 房间id={room.RoomId}, 玩家id={player.Id}, 玩家={player.Name}, 手牌信息={player.RemainCards}");
  216. }
  217. }
  218. /// <summary>
  219. /// 摸牌
  220. /// </summary>
  221. /// <param name="self"></param>
  222. /// <param name="room"></param>
  223. private static void DrawCard(this HGHuangHuangComponent self, Room room)
  224. {
  225. // 2个以上玩家认输或牌库没牌了直接结束
  226. if (self.AdmitDefeatList.Count > 2 || self.CardList.Count <= 0)
  227. {
  228. self.GameOver(room);
  229. return;
  230. }
  231. Player drawCardPlayer = self.DrawCardPlayer;
  232. if (drawCardPlayer == null)
  233. {
  234. Log.Error($"房间id={room.RoomId}, 摸牌玩家为空...");
  235. return;
  236. }
  237. // 摸牌
  238. int card = self.CardList[0];
  239. drawCardPlayer.RemainCards = CardHelper.Add(drawCardPlayer.RemainCards, card);
  240. self.CardList.RemoveAt(0);
  241. // 当前摸的牌
  242. self.DrawCard = card;
  243. // 吃,碰,杠,胡,过
  244. bool hasAct = false;
  245. // 检测摸牌人动作, 校验摸牌是否胡
  246. Struct.HuRes huRes = HGHuangHuangHelper.CheckHu(drawCardPlayer.RemainCards);
  247. if (huRes.Type != HGHuangHuangConst.HU_DEFAULT)
  248. {
  249. hasAct = true;
  250. drawCardPlayer.Act[3] = 1;
  251. self.CanHuIds.Add(drawCardPlayer);
  252. if (!self.OperableList.Contains(drawCardPlayer))
  253. {
  254. self.OperableList.Add(drawCardPlayer);
  255. }
  256. }
  257. // todo 玩家听牌状态不允许杠
  258. // 检测摸牌人动作, 校验摸牌是否杠
  259. List<Struct.Kezi> gang = HGHuangHuangHelper.IsDrawGang(drawCardPlayer);
  260. if (gang is { Count: > 0 })
  261. {
  262. hasAct = true;
  263. drawCardPlayer.Act[2] = 1;
  264. if (!self.OperableList.Contains(drawCardPlayer))
  265. {
  266. self.OperableList.Add(drawCardPlayer);
  267. }
  268. if (!self.CanPgIds.Contains(drawCardPlayer))
  269. {
  270. self.CanPgIds.Add(drawCardPlayer);
  271. }
  272. }
  273. // 过牌
  274. drawCardPlayer.Act[4] = hasAct? 1 : 0;
  275. if (drawCardPlayer.HuCards.Any(_card => _card > 0 && _card == self.DrawCard))
  276. {
  277. drawCardPlayer.Act[4] = 0;
  278. }
  279. // 推送摸牌广播
  280. foreach (Player player in room.GetAllPlayers().Values)
  281. {
  282. if (player == null)
  283. {
  284. continue;
  285. }
  286. MessageHelper.SendToClient(player, new G2C_DrawCardPush(){info = ProtoHelper.RoomToProto(room, player, drawCardPlayer)});
  287. Log.Info($"摸牌, 房间id={room.RoomId}, 玩家id={player.Id}, 玩家={player.Name}, 摸牌玩家={player.Id == drawCardPlayer.Id}, 手牌信息={player.RemainCards}, 摸的牌={card}");
  288. }
  289. }
  290. /// <summary>
  291. /// 结束
  292. /// </summary>
  293. /// <param name="self"></param>
  294. /// <param name="room"></param>
  295. private static void GameOver(this HGHuangHuangComponent self, Room room)
  296. {
  297. }
  298. }
  299. }