HGHuangHuangComponentSystem.cs 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746
  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[room.MaxNum];
  25. self.CurrentRound = 0;
  26. self.ZhuangPos = 0;
  27. self.Rand = new[] { 0, 0 };
  28. self.GangType = -1;
  29. self.AdmitDefeatList = new List<long>();
  30. self.CanPgIds = new List<long>();
  31. self.CanHuIds = new List<long>();
  32. self.OperableList = new List<long>();
  33. self.ClickHuIds = new List<Player>();
  34. self.CardList = new List<int>();
  35. self.UpdateTime = 0;
  36. // 初始化牌库
  37. for (int i = 0; i < 4; i++)
  38. {
  39. foreach (int value in HGHuangHuangConst.Values)
  40. {
  41. self.CardList.Add(value);
  42. }
  43. RandomGenerator.Shuffle(self.CardList);
  44. }
  45. }
  46. }
  47. [ObjectSystem]
  48. public class HGHuangHuangComponentDestroySystem: DestroySystem<HGHuangHuangComponent>
  49. {
  50. protected override void Destroy(HGHuangHuangComponent self)
  51. {
  52. Log.Info($"销毁黄冈晃晃主逻辑组件...");
  53. }
  54. }
  55. [ObjectSystem]
  56. [FriendOf(typeof(Room))]
  57. public class HGHuangHuangComponentUpdateSystem : UpdateSystem<HGHuangHuangComponent>
  58. {
  59. protected override void Update(HGHuangHuangComponent self)
  60. {
  61. long timeNow = TimeHelper.ClientNow();
  62. // 每秒执行一次
  63. if (timeNow - self.UpdateTime <= 1000)
  64. {
  65. return;
  66. }
  67. self.UpdateTime = timeNow;
  68. Room room = self.GetParent<Room>();
  69. if (room == null)
  70. {
  71. Log.Error($"黄冈晃晃主逻辑组件获取不到主实体...");
  72. return;
  73. }
  74. switch (self.State)
  75. {
  76. case 0:
  77. // 等待状态
  78. Log.Debug($"检测: 黄冈晃晃-房间号:{room.RoomId}, 房间人数:{room.Players.Count}, 状态:检测是否可开局...");
  79. if (self.CheckReadyStart(room))
  80. {
  81. self.State = 1;
  82. self.Flag = false;
  83. self.Time = 0;
  84. }
  85. // 120秒未开始直接解散
  86. if (self.Time >= 120)
  87. {
  88. room.Dispose();
  89. }
  90. break;
  91. case 1:
  92. // 开局
  93. if (!self.Flag)
  94. {
  95. if (self.Time >= 3)
  96. {
  97. self.Start(room);
  98. self.Flag = true;
  99. self.Time = 0;
  100. Log.Debug($"检测: 黄冈晃晃-房间号:{room.RoomId}, 房间人数:{room.Players.Count}, 状态:开局...VS动画...");
  101. }
  102. }
  103. else
  104. {
  105. if (self.Time >= 4)
  106. {
  107. self.State = 2;
  108. self.Flag = false;
  109. self.Time = 0;
  110. }
  111. }
  112. break;
  113. case 2:
  114. // 进行中
  115. if (!self.Flag)
  116. {
  117. self.Flag = true;
  118. self.Time = 0;
  119. // 摸牌
  120. self.DrawCard(room);
  121. }
  122. else
  123. {
  124. // 强制操作
  125. if (self.Time >= 15)
  126. {
  127. if (self.OperableList != null && self.OperableList.Count > 0)
  128. {
  129. // 过
  130. }
  131. if (self.DrawCardPlayer.Id == self.CurrentPlayer.Id)
  132. {
  133. // 出牌
  134. self.DisCard(room, self.CurrentPlayer, 0, true);
  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.Where(player => player != null))
  173. {
  174. for (int i = 0; i < 13; i++)
  175. {
  176. int card = self.CardList[0];
  177. player.RemainCards = CardHelper.Add(player.RemainCards, card);
  178. self.CardList.RemoveAt(0);
  179. }
  180. }
  181. }
  182. /// <summary>
  183. /// 游戏开局
  184. /// </summary>
  185. /// <param name="self"></param>
  186. /// <param name="room"></param>
  187. private static void Start(this HGHuangHuangComponent self, Room room)
  188. {
  189. self.CurrentRound += 1;
  190. // 摇骰子
  191. int rand1 = RandomGenerator.RandomNumber(1, 7);
  192. int rand2 = RandomGenerator.RandomNumber(1, 7);
  193. self.Rand = new[] { rand1, rand2 };
  194. // 定庄
  195. // self.ZhuangPos = (rand1 + rand2) % 4;
  196. self.ZhuangPos = (rand1 + rand2) % room.MaxNum;
  197. // 设置当前操作玩家
  198. self.CurrentPlayer = self.Players[self.ZhuangPos];
  199. // 设置当前摸牌玩家
  200. self.DrawCardPlayer = self.Players[self.ZhuangPos];
  201. // 发牌
  202. self.SendCard(room);
  203. // 广播
  204. foreach (Player player in room.GetAllPlayers().Values.Where(player => player != null))
  205. {
  206. player.State = 2;
  207. MessageHelper.SendToClient(player, new G2C_StartPush(){info = ProtoHelper.RoomToProto(room, player, null)});
  208. Log.Info($"游戏开局, 房间id={room.RoomId}, 玩家id={player.Id}, 玩家={player.Name}, 手牌信息={player.RemainCards}");
  209. }
  210. }
  211. /// <summary>
  212. /// 摸牌
  213. /// </summary>
  214. /// <param name="self"></param>
  215. /// <param name="room"></param>
  216. private static void DrawCard(this HGHuangHuangComponent self, Room room)
  217. {
  218. // 2个以上玩家认输或牌库没牌了直接结束
  219. if (self.AdmitDefeatList.Count > 2 || self.CardList.Count <= 0)
  220. {
  221. self.GameOver(room);
  222. return;
  223. }
  224. Player drawCardPlayer = self.DrawCardPlayer;
  225. if (drawCardPlayer == null)
  226. {
  227. Log.Error($"房间id={room.RoomId}, 摸牌玩家为空...");
  228. return;
  229. }
  230. // 摸牌
  231. int card = self.CardList[0];
  232. drawCardPlayer.RemainCards = CardHelper.Add(drawCardPlayer.RemainCards, card);
  233. self.CardList.RemoveAt(0);
  234. // 当前摸的牌
  235. self.DrawCard = card;
  236. // 吃,碰,杠,胡,过
  237. bool hasAct = false;
  238. // 检测摸牌人动作, 校验摸牌是否胡
  239. Struct.HuRes huRes = HGHuangHuangHelper.CheckHu(drawCardPlayer.RemainCards);
  240. if (huRes.Type != HGHuangHuangConst.HU_DEFAULT)
  241. {
  242. hasAct = true;
  243. drawCardPlayer.Act[3] = 1;
  244. self.CanHuIds.Add(drawCardPlayer.Id);
  245. if (!self.OperableList.Contains(drawCardPlayer.Id))
  246. {
  247. self.OperableList.Add(drawCardPlayer.Id);
  248. }
  249. }
  250. // todo 玩家听牌状态不允许杠
  251. // 检测摸牌人动作, 校验摸牌是否杠
  252. List<Struct.Kezi> gang = HGHuangHuangHelper.IsDrawGang(drawCardPlayer);
  253. if (gang is { Count: > 0 })
  254. {
  255. hasAct = true;
  256. drawCardPlayer.Act[2] = 1;
  257. if (!self.OperableList.Contains(drawCardPlayer.Id))
  258. {
  259. self.OperableList.Add(drawCardPlayer.Id);
  260. }
  261. if (!self.CanPgIds.Contains(drawCardPlayer.Id))
  262. {
  263. self.CanPgIds.Add(drawCardPlayer.Id);
  264. }
  265. }
  266. // 过牌
  267. drawCardPlayer.Act[4] = hasAct? 1 : 0;
  268. if (drawCardPlayer.HuCards.Any(_card => _card > 0 && _card == self.DrawCard))
  269. {
  270. drawCardPlayer.Act[4] = 0;
  271. }
  272. // 推送摸牌广播
  273. foreach (Player player in room.GetAllPlayers().Values.Where(player => player != null))
  274. {
  275. MessageHelper.SendToClient(player, new G2C_DrawCardPush(){info = ProtoHelper.RoomToProto(room, player, drawCardPlayer)});
  276. Log.Info($"摸牌... 玩家ID:{player.Id}, 位置:{player.Pos}, 摸牌玩家:{player.Id == drawCardPlayer.Id}, 手牌大小:{player.RemainCards.Length}, 手牌信息:{string.Join(", ", player.RemainCards)}, 摸的牌:{card}");
  277. }
  278. }
  279. /// <summary>
  280. /// 出牌
  281. /// </summary>
  282. /// <param name="self"></param>
  283. /// <param name="room"></param>
  284. /// <param name="player"></param>
  285. /// <param name="card">出的牌(0.当前摸牌玩家自动出牌 -1.非当前摸牌玩家自动出牌 >0.玩家手动出牌)</param>
  286. /// <param name="flag">是否自动出牌</param>
  287. public static async void DisCard(this HGHuangHuangComponent self, Room room, Player player, int card, bool flag)
  288. {
  289. if (player == null)
  290. {
  291. Log.Error($"出牌错误,player is null.");
  292. return;
  293. }
  294. using (await CoroutineLockComponent.Instance.Wait(CoroutineLockType.PlayerOperation, player.Id))
  295. {
  296. if (self.CurrentPlayer.Id == player.Id && self.DrawCardPlayer.Id == player.Id)
  297. {
  298. Log.Info($"出牌... 玩家ID:{player.Id}, 位置:{player.Pos}, 手牌大小:{player.RemainCards.Length}, 手牌信息: {string.Join(", ", player.RemainCards)}");
  299. // 自动出牌
  300. if (flag)
  301. {
  302. if (self.PengPlayer != null && self.PengPlayer.Id == player.Id)
  303. {
  304. self.PengPlayer = null;
  305. int[] tmpCard = new int[player.RemainCards.Length];
  306. Array.Copy(player.RemainCards, 0, tmpCard, 0, player.RemainCards.Length);
  307. Array.Sort(tmpCard);
  308. card = tmpCard[^1];
  309. }
  310. else
  311. {
  312. card = player.RemainCards[^1];
  313. }
  314. // todo 真人托管状态
  315. }
  316. if (!player.RemainCards.Contains(card))
  317. {
  318. Log.Error($"出牌错误,玩家的牌不在手中...");
  319. return;
  320. }
  321. // 玩家出牌
  322. player.RemainCards = CardHelper.Remove(player.RemainCards, card);
  323. player.DisCards = CardHelper.Add(player.DisCards, card);
  324. player.DiscardCount += 1;
  325. self.DisCard = card;
  326. self.DisCardPlayer = player;
  327. self.PengPlayer = null;
  328. // 给出牌人广播
  329. MessageHelper.SendToClient(player, new G2C_DisCardPush(){info = ProtoHelper.RoomToProto(room, player, player)});
  330. self.CanHuIds.Clear();
  331. self.ClickHuIds.Clear();
  332. self.OperableList.Clear();
  333. self.CanPgIds.Clear();
  334. self.CleanUserAct();
  335. // 检测其它三家的动作
  336. int[] nextPos = room.GetSorcPos(player.Pos);
  337. foreach (int index in nextPos)
  338. {
  339. Player otherPlayer = self.Players[index];
  340. if (otherPlayer != null)
  341. {
  342. // 吃,碰,杠,胡,过
  343. int[] act = new int[5];
  344. List<Struct.Kezi> gangs = new List<Struct.Kezi>();
  345. List<Struct.Kezi> pengs = new List<Struct.Kezi>();
  346. List<Struct.Kezi> chis = new List<Struct.Kezi>();
  347. // todo 玩家听牌状态不允许有动作
  348. // 出牌是否杠
  349. gangs = HGHuangHuangHelper.IsDiscardGang(otherPlayer, card, player.Id);
  350. // 出牌是否碰
  351. pengs = HGHuangHuangHelper.IsDiscardPeng(otherPlayer, card, player.Id);
  352. // 出牌是否吃
  353. if (otherPlayer.Pos == nextPos[0])
  354. {
  355. chis = HGHuangHuangHelper.IsDiscardChi(otherPlayer, card, player.Id);
  356. }
  357. // 游戏中才会动作
  358. if (otherPlayer.State == 2)
  359. {
  360. bool hasAct = false;
  361. int[] tmpCards = new int[otherPlayer.RemainCards.Length];
  362. Array.Copy(otherPlayer.RemainCards, 0, tmpCards, 0, otherPlayer.RemainCards.Length);
  363. tmpCards = CardHelper.Add(tmpCards, card);
  364. // 校验胡牌
  365. Struct.HuRes huType = HGHuangHuangHelper.CheckHu(tmpCards);
  366. if (huType.Type != HGHuangHuangConst.HU_DEFAULT)
  367. {
  368. hasAct = true;
  369. act[3] = 1;
  370. // 放入可胡玩家列表
  371. if (!self.CanHuIds.Contains(otherPlayer.Id))
  372. {
  373. self.CanHuIds.Add(otherPlayer.Id);
  374. }
  375. // 加入可操作玩家list
  376. if (!self.OperableList.Contains(otherPlayer.Id))
  377. {
  378. self.OperableList.Add(otherPlayer.Id);
  379. }
  380. }
  381. // 是否杠
  382. if (gangs.Count > 0)
  383. {
  384. hasAct = true;
  385. act[2] = 1;
  386. }
  387. // 是否碰
  388. if (pengs.Count > 0)
  389. {
  390. hasAct = true;
  391. act[1] = 1;
  392. }
  393. // 是否吃
  394. if (chis.Count > 0)
  395. {
  396. hasAct = true;
  397. act[0] = 1;
  398. }
  399. // 是否过
  400. if (hasAct) {
  401. act[4] = 1;
  402. }
  403. if (act[2] == 1 || act[1] == 1) {
  404. // 加入可操作玩家list
  405. if (!self.OperableList.Contains(otherPlayer.Id)) {
  406. self.OperableList.Add(otherPlayer.Id);
  407. }
  408. // 加入可碰杠玩家集合
  409. if (!self.CanPgIds.Contains(otherPlayer.Id)) {
  410. self.CanPgIds.Add(otherPlayer.Id);
  411. }
  412. }
  413. // 设置玩家动作
  414. otherPlayer.Act = act;
  415. }
  416. // 广播其它三家
  417. MessageHelper.SendToClient(otherPlayer, new G2C_DisCardPush(){info = ProtoHelper.RoomToProto(room, otherPlayer, player)});
  418. }
  419. }
  420. if (self.CanHuIds.Count <= 0)
  421. {
  422. self.GangPlayer = null;
  423. }
  424. // 判断是否下家摸牌, 指定下家摸牌
  425. if (self.OperableList.Count == 0)
  426. {
  427. Player nextPlayer = null;
  428. foreach (int index in nextPos)
  429. {
  430. Player tempPlayer = self.Players[index];
  431. if (tempPlayer is { State: 2 } && tempPlayer.Id != player.Id)
  432. {
  433. nextPlayer = tempPlayer;
  434. break;
  435. }
  436. }
  437. // 有三家认输,就会有null
  438. if (nextPlayer == null)
  439. {
  440. self.GameOver(room);
  441. }
  442. else
  443. {
  444. // 设置摸牌玩家
  445. self.DrawCardPlayer = nextPlayer;
  446. // 设置操作玩家
  447. self.CurrentPlayer = nextPlayer;
  448. // 摸牌
  449. self.Flag = false;
  450. }
  451. }
  452. else
  453. {
  454. long id = 0;
  455. if (self.CanHuIds.Count > 0)
  456. {
  457. id = self.CanHuIds.First();
  458. } else if (self.CanPgIds.Count > 0)
  459. {
  460. id = self.CanPgIds.First();
  461. }
  462. else
  463. {
  464. id = self.OperableList.First();
  465. }
  466. Player tmpPlayer = room.GetPlayer(id);
  467. if (tmpPlayer != null)
  468. {
  469. self.CurrentPlayer = self.Players[tmpPlayer.Pos];
  470. }
  471. }
  472. }
  473. }
  474. }
  475. /// <summary>
  476. /// 玩家是否可以操作吃
  477. /// </summary>
  478. /// <param name="self"></param>
  479. /// <param name="player"></param>
  480. /// <returns></returns>
  481. private static bool IsCanChi(this HGHuangHuangComponent self, Player player)
  482. {
  483. if (self.ClickHuIds.Count > 0)
  484. {
  485. return false;
  486. }
  487. if (self.CanHuIds.Count > 1)
  488. {
  489. return false;
  490. }
  491. else
  492. {
  493. if (self.CanHuIds.Count == 1)
  494. {
  495. if (self.CanPgIds.Count > 0)
  496. {
  497. if (self.CanPgIds.Any(id => id > 0 && id != player.Id))
  498. {
  499. return false;
  500. }
  501. }
  502. return self.CanHuIds.Contains(player.Id);
  503. }
  504. else
  505. {
  506. if (self.CanPgIds.Count > 0)
  507. {
  508. return self.CanPgIds.Contains(player.Id);
  509. }
  510. else
  511. {
  512. return true;
  513. }
  514. }
  515. }
  516. }
  517. /// <summary>
  518. /// 玩家操作吃
  519. /// </summary>
  520. /// <param name="self"></param>
  521. /// <param name="room"></param>
  522. /// <param name="player"></param>
  523. /// <param name="card"></param>
  524. public static void Chi(this HGHuangHuangComponent self, Room room, Player player, int card)
  525. {
  526. if (self.IsCanChi(player))
  527. {
  528. return;
  529. }
  530. if (self.DisCard >= HGHuangHuangConst.DONG_FENG)
  531. {
  532. return;
  533. }
  534. // 删除出牌人打出的牌堆
  535. self.DisCardPlayer.DisCards = CardHelper.Remove(self.DisCardPlayer.DisCards, self.DisCard);
  536. // 吃牌玩家的手牌
  537. int[] temp = CardHelper.Add(player.RemainCards, self.DisCard);
  538. for (int i = 0; i < 3; i++)
  539. {
  540. temp = CardHelper.Remove(temp, card + i);
  541. }
  542. player.RemainCards = temp;
  543. // 刻子
  544. player.KeZi.Add(new Struct.Kezi((int)HGHuangHuangConst.KeziType.CHI, card, self.DisCardPlayer.Id));
  545. // 重置摸牌人
  546. self.DrawCardPlayer = player;
  547. self.PengPlayer = player;
  548. self.OperableList.Clear();
  549. // 重置时间和流程标记
  550. self.Time = 15;
  551. self.Flag = false;
  552. Log.Info($"玩家吃牌... 玩家ID:{player.Id}, 位置:{player.Pos}, 手牌大小:{player.RemainCards.Length}, 手牌信息:{string.Join(", ", player.RemainCards)}, 吃的牌:{card}");
  553. // 广播
  554. foreach (Player p in room.GetAllPlayers().Values.Where(p => p != null))
  555. {
  556. MessageHelper.SendToClient(p, new G2C_OperationPush(){info = ProtoHelper.RoomToProto(room, p, p)});
  557. }
  558. }
  559. /// <summary>
  560. /// 玩家是否可以操作碰
  561. /// </summary>
  562. /// <param name="self"></param>
  563. /// <param name="player"></param>
  564. /// <returns></returns>
  565. private static bool IsCanPengGang(this HGHuangHuangComponent self, Player player)
  566. {
  567. if (!self.CanPgIds.Contains(player.Id))
  568. {
  569. return false;
  570. }
  571. if (self.ClickHuIds.Count > 0)
  572. {
  573. return false;
  574. }
  575. return self.CanHuIds.Count switch
  576. {
  577. > 1 => false,
  578. 1 => self.CanHuIds.Contains(player.Id),
  579. _ => true
  580. };
  581. }
  582. /// <summary>
  583. /// 玩家操作碰
  584. /// </summary>
  585. /// <param name="self"></param>
  586. /// <param name="room"></param>
  587. /// <param name="player"></param>
  588. public static void Peng(this HGHuangHuangComponent self, Room room, Player player)
  589. {
  590. if (!self.IsCanPengGang(player))
  591. {
  592. return;
  593. }
  594. int num = CardHelper.CountCardNum(player.RemainCards, self.DisCard);
  595. if (num < 2)
  596. {
  597. return;
  598. }
  599. // 删除出牌人打出的牌堆
  600. int[] temp = CardHelper.Remove(self.DisCardPlayer.DisCards, self.DisCard);
  601. self.DisCardPlayer.DisCards = temp;
  602. // 碰牌玩家的手牌
  603. int[] remainCards = player.RemainCards;
  604. for (int i = 0; i < 2; i++)
  605. {
  606. remainCards = CardHelper.Remove(remainCards, self.DisCard);
  607. }
  608. player.RemainCards = remainCards;
  609. // 刻子
  610. player.KeZi.Add(new Struct.Kezi((int)HGHuangHuangConst.KeziType.PENG, self.DisCard, self.DisCardPlayer.Id));
  611. // 重置摸牌人
  612. self.DrawCardPlayer = player;
  613. self.PengPlayer = player;
  614. self.OperableList.Clear();
  615. // 重置时间和流程标记
  616. self.Time = 15;
  617. self.Flag = false;
  618. Log.Info($"玩家碰牌... 玩家ID:{player.Id}, 位置:{player.Pos}, 手牌大小:{player.RemainCards.Length}, 手牌信息:{string.Join(", ", player.RemainCards)}, 碰的牌:{self.DisCard}");
  619. // 广播
  620. foreach (Player p in room.GetAllPlayers().Values.Where(p => p != null))
  621. {
  622. MessageHelper.SendToClient(p, new G2C_OperationPush(){info = ProtoHelper.RoomToProto(room, p, player)});
  623. }
  624. }
  625. /// <summary>
  626. /// 玩家操作杠
  627. /// </summary>
  628. /// <param name="self"></param>
  629. /// <param name="room"></param>
  630. /// <param name="player"></param>
  631. /// <param name="card"></param>
  632. public static void Gang(this HGHuangHuangComponent self, Room room, Player player, int card)
  633. {
  634. }
  635. /// <summary>
  636. /// 玩家操作胡
  637. /// </summary>
  638. /// <param name="self"></param>
  639. /// <param name="room"></param>
  640. /// <param name="player"></param>
  641. public static void Hu(this HGHuangHuangComponent self, Room room, Player player)
  642. {
  643. }
  644. /// <summary>
  645. /// 玩家操作过
  646. /// </summary>
  647. /// <param name="self"></param>
  648. /// <param name="room"></param>
  649. /// <param name="player"></param>
  650. public static void Guo(this HGHuangHuangComponent self, Room room, Player player)
  651. {
  652. }
  653. /// <summary>
  654. /// 清空玩家可操作动作
  655. /// </summary>
  656. /// <param name="self"></param>
  657. private static void CleanUserAct(this HGHuangHuangComponent self) {
  658. foreach (Player player in self.Players)
  659. {
  660. if (player != null)
  661. {
  662. player.Act = new int[5];
  663. }
  664. }
  665. }
  666. /// <summary>
  667. /// 结束
  668. /// </summary>
  669. /// <param name="self"></param>
  670. /// <param name="room"></param>
  671. private static void GameOver(this HGHuangHuangComponent self, Room room)
  672. {
  673. }
  674. }
  675. }