GameRoom.Role.cs 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  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 readonly ManualResetEvent TalkingActionComplete = new(false);
  22. public readonly ManualResetEvent VoteActionComplete = new(false);
  23. protected int MessageId = -1;
  24. public abstract Roles RoleKey { get; }
  25. public virtual Task NightAction() { return Task.CompletedTask; }
  26. public virtual Task ApplyNightActionResult() { return Task.CompletedTask; }
  27. public async Task CancelNightActionResult(string message)
  28. {
  29. await Bot.EditMessageAsync(Player.ChatId, MessageId, strings.activity_blocked);
  30. NightTargetId = -1;
  31. MessageId = -1;
  32. Player.IsSpeaker = false;
  33. await Bot.SendWithMarkdown2(Player.ChatId, message);
  34. }
  35. public virtual Task SetNightTarget(long userId) { return Task.CompletedTask; }
  36. public virtual async Task Dispatch()
  37. {
  38. await Room.PlayersCh.SendExcept(Player.Id, $"{strings.to_player} {Player.NickName} {strings.issued_posthumous_minute}");
  39. await OneMinuteSpeak();
  40. await Kill();
  41. }
  42. public virtual async Task Kill()
  43. {
  44. if (Room.PlayersRole.ContainsKey(Roles.Hooker) &&
  45. Room.PlayersRole[Roles.Hooker].Count == 1 && !Room.IsDay)
  46. {
  47. var hooker = Room.PlayersRole[Roles.Hooker][0];
  48. if (hooker.CurrentRole.NightTargetId == Player.Id) await hooker.CurrentRole.Kill();
  49. else
  50. {
  51. Player.IsAlive = false;
  52. await Bot.SendWithMarkdown2(Player.ChatId, strings.you_died);
  53. }
  54. }
  55. else
  56. {
  57. Player.IsAlive = false;
  58. await Bot.SendWithMarkdown2(Player.ChatId, strings.you_died);
  59. }
  60. }
  61. protected Role(GameRoom room, Player player)
  62. {
  63. Room = room;
  64. Player = player;
  65. }
  66. public long GetNightTarget()
  67. {
  68. return NightTargetId;
  69. }
  70. public async Task OneMinuteSpeak()
  71. {
  72. TalkingActionComplete.Reset();
  73. await Bot.SendWithMarkdown2(Player.ChatId, $"{strings.your_turn}\n{strings.you_turn_say}", Keyboard.InGamePlayerMenuWithEndTurn);
  74. Player.IsSpeaker = true;
  75. var timer = new Timer(60 * 1000) {AutoReset = false};
  76. timer.Elapsed += (_, _) => TalkingActionComplete.Set();
  77. timer.Start();
  78. TalkingActionComplete.WaitOne();
  79. timer.Stop();
  80. await Bot.SendWithMarkdown2(Player.ChatId, strings.your_turn_ended, Keyboard.InGamePlayerMenu);
  81. Player.IsSpeaker = false;
  82. }
  83. public async Task VotingAction()
  84. {
  85. var voteTimer = new Timer(10 * 1000) {AutoReset = false};
  86. var alivePlayers = Room.Players.Values.Where(p => p.IsAlive).ToList();
  87. var message = await SendVotingList(alivePlayers, !Player.IsFirst);
  88. voteTimer.Elapsed += async (_, _) =>
  89. {
  90. await Bot.EditMessageAsync(Player.ChatId, message.MessageId, strings.time_out);
  91. if (Player.IsFirst)
  92. await Room.PutUpVote(Player.Id, Player.Id);
  93. else
  94. await Room.PlayersCh.SendExcept(Player.Id, $"{Player.NickName} {strings.didnt_put_anyone}");
  95. VoteActionComplete.Set();
  96. };
  97. if(Player.IsFirst) await Bot.SendWithMarkdown2(Player.Id, strings.user_not_choose);
  98. voteTimer.Start();
  99. VoteActionComplete.WaitOne();
  100. voteTimer.Stop();
  101. if(message!=null) await Bot.Get().DeleteMessageAsync(Player.ChatId, message.MessageId);
  102. }
  103. public async Task<Message> SendVotingList(List<Player> targets, bool skipButton = true)
  104. {
  105. VoteActionComplete.Reset();
  106. return await Bot.SendWithMarkdown2(Player.ChatId, $"{strings.put_up_vote}\n{strings.you_have_ten_seconds}",
  107. Keyboard.VoteKeyboard(targets, Player.Id, skipButton));
  108. }
  109. public async Task DefenceAction()
  110. {
  111. await Room.PlayersCh.SendExcept(Player.Id, $"{strings.now_defence} \\({Player.TurnOrder}\\) {Player.NickName}");
  112. await OneMinuteSpeak();
  113. }
  114. public static Role GetNewRoleInstance(Roles roleKey, GameRoom room, Player player)
  115. {
  116. return roleKey switch
  117. {
  118. Roles.All => new NoneRole(),
  119. Roles.None => new NoneRole(),
  120. Roles.Doctor => new DoctorRole(room, player),
  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. _ => throw new ArgumentOutOfRangeException(nameof(roleKey), roleKey, null)
  137. };
  138. }
  139. }
  140. }
  141. }