GameRoom.Role.cs 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Threading;
  5. using System.Threading.Tasks;
  6. using MafiaTelegramBot.Game.GameRoles;
  7. using MafiaTelegramBot.Models;
  8. using MafiaTelegramBot.Resources;
  9. using Telegram.Bot.Types;
  10. using Timer = System.Timers.Timer;
  11. namespace MafiaTelegramBot.Game.GameRooms
  12. {
  13. public partial class GameRoom
  14. {
  15. public abstract class Role
  16. {
  17. protected readonly GameRoom Room;
  18. protected readonly Player Player;
  19. public readonly List<Player> KnownRoles = new();
  20. protected long NightTargetId = -1;
  21. public long MafiaTargetId = -1;
  22. public readonly ManualResetEvent TalkingActionComplete = new(false);
  23. public readonly ManualResetEvent VoteActionComplete = new(false);
  24. protected int MessageId = -1;
  25. protected int MafiaMessageId = -1;
  26. public abstract Roles RoleKey { get; }
  27. public virtual Task NightAction() { return Task.CompletedTask; }
  28. public virtual Task SetMafiaTarget(long userId) { return Task.CompletedTask; }
  29. public virtual Task ApplyNightActionResult() { return Task.CompletedTask; }
  30. public virtual Task SetNightTarget(long userId) { return Task.CompletedTask; }
  31. public async Task CancelNightActionResult(string message)
  32. {
  33. if (MessageId != -1)
  34. {
  35. await Room.PlayersCh.EditTo(Player.Id, MessageId, strings.activity_blocked);
  36. NightTargetId = -1;
  37. }
  38. if (MafiaMessageId != -1)
  39. {
  40. Player.IsSpeaker = false;
  41. await Room.PlayersCh.EditTo(Player.Id, MafiaMessageId, strings.activity_blocked);
  42. MafiaTargetId = -1;
  43. }
  44. await Room.PlayersCh.SendTo(Player.ChatId, message);
  45. }
  46. public virtual async Task Dispatch()
  47. {
  48. if (Room.PlayersRole.ContainsKey(Roles.Hooker)
  49. && Room.PlayersRole[Roles.Hooker].Count == 1
  50. && Room.PlayersRole[Roles.Hooker][0].CurrentRole.NightTargetId == Player.Id)
  51. {
  52. await Room.PlayersCh.SendExcept(Player.Id, $"{strings.villagers_want_dispatch} {Player.NickName}, {strings.player_not_died_he_has_alibi}");
  53. }
  54. else
  55. {
  56. await Room.PlayersCh.SendExcept(Player.Id, $"{strings.to_player} {Player.NickName} {strings.issued_posthumous_minute}");
  57. await Room.PlayersCh.SendTo(Player.ChatId, strings.you_will_be_dispatched);
  58. await SpeakAction(enableTimer: true);
  59. await Kill();
  60. }
  61. }
  62. public virtual async Task Kill()
  63. {
  64. if (Room.PlayersRole.ContainsKey(Roles.Hooker)
  65. && Room.PlayersRole[Roles.Hooker].Count == 1
  66. && Room.PlayersRole[Roles.Hooker][0].CurrentRole.NightTargetId == Player.Id
  67. && !Room.IsDay)
  68. await Room.PlayersRole[Roles.Hooker][0].CurrentRole.Kill();
  69. else Player.IsAlive = false;
  70. }
  71. protected Role(GameRoom room, Player player)
  72. {
  73. Room = room;
  74. Player = player;
  75. }
  76. public async Task SpeakAction(int seconds = 60, bool enableTimer = false)
  77. {
  78. TalkingActionComplete.Reset();
  79. await Room.PlayersCh.SendTo(Player.ChatId, $"{strings.your_turn}", Keyboard.InGamePlayerMenuWithEndTurn);
  80. Player.IsSpeaker = true;
  81. var timer = new Timer(seconds * 1000) {AutoReset = false};
  82. timer.Elapsed += (_, _) => TalkingActionComplete.Set();
  83. if (Room.TimerEnabled || enableTimer) timer.Start();
  84. TalkingActionComplete.WaitOne();
  85. if (Room.TimerEnabled || enableTimer) timer.Stop();
  86. await Room.PlayersCh.SendTo(Player.ChatId, strings.your_turn_ended, Keyboard.InGamePlayerMenu);
  87. Player.IsSpeaker = false;
  88. }
  89. public async Task VotingAction()
  90. {
  91. var voteTimer = new Timer(10 * 1000) {AutoReset = false};
  92. var alivePlayers = Room.Players.Values.Where(p => p.IsAlive).Except(Room.VoteUpList).ToList();
  93. var message = await Room.PlayersCh.SendTo(Player.ChatId,
  94. $"{strings.put_up_vote}\n{strings.you_have_ten_seconds}",
  95. Keyboard.VoteKeyboard(alivePlayers, Player.Id, !Player.IsFirst));
  96. voteTimer.Elapsed += async (_, _) =>
  97. {
  98. Console.WriteLine("this");
  99. if (Player.IsFirst) await Room.PutUpVote(Player.Id, Player.Id, message.MessageId);
  100. else await Room.PutUpVote(Player.Id, 0, message.MessageId);
  101. VoteActionComplete.Set();
  102. };
  103. if(Player.IsFirst) await Room.PlayersCh.SendTo(Player.Id, strings.user_not_choose);
  104. voteTimer.Start();
  105. VoteActionComplete.WaitOne();
  106. VoteActionComplete.Reset();
  107. voteTimer.Stop();
  108. }
  109. public async Task DefenceAction()
  110. {
  111. await Room.PlayersCh.SendExcept(Player.Id, $"{strings.now_defence} ({Player.TurnOrder}) {Player.NickName}");
  112. await Room.PlayersCh.SendTo(Player.ChatId, strings.you_have_eigty_seconds_to_defence);
  113. await SpeakAction(90);
  114. }
  115. public static Role GetNewRoleInstance(Roles roleKey, GameRoom room, Player player)
  116. {
  117. return roleKey switch
  118. {
  119. Roles.All => new NoneRole(),
  120. Roles.None => new NoneRole(),
  121. Roles.Mafia => new MafiaRole(room, player),
  122. Roles.Don => new DonRole(room, player),
  123. Roles.Cop => new CopRole(room, player),
  124. Roles.Villager => new VillagerRole(room, player),
  125. Roles.Hooker => new HookerRole(room, player),
  126. Roles.Elder => new ElderRole(room, player),
  127. Roles.Werewolf => new WerewolfRole(room, player),
  128. Roles.Journalist => new JournalistRole(room, player),
  129. Roles.Detective => new DetectiveRole(room, player),
  130. Roles.Dame => new DameRole(room, player),
  131. Roles.Parasite => new ParasiteRole(room, player),
  132. Roles.Lawyer => new LawyerRole(room, player),
  133. Roles.Fool => new FoolRole(room, player),
  134. Roles.Necromancer => new NecromancerRole(room, player),
  135. Roles.Bodyguard => new BodyguardRole(room, player),
  136. Roles.Doctor => new DoctorRole(room, player),
  137. _ => throw new ArgumentOutOfRangeException(nameof(roleKey), roleKey, null)
  138. };
  139. }
  140. }
  141. }
  142. }