GameRoom.Role.cs 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  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. await Bot.SendWithMarkdown2(Player.ChatId, message);
  33. }
  34. public virtual Task SetNightTarget(long userId) { return Task.CompletedTask; }
  35. public virtual async Task Dispatch()
  36. {
  37. await Room.PlayersCh.SendExcept(Player.Id, $"{strings.to_player} {Player.NickName} {strings.issued_posthumous_minute}");
  38. await OneMinuteSpeak();
  39. await Player.Kill();
  40. }
  41. protected Role(GameRoom room, Player player)
  42. {
  43. Room = room;
  44. Player = player;
  45. }
  46. public long GetNightTarget()
  47. {
  48. return NightTargetId;
  49. }
  50. public async Task OneMinuteSpeak()
  51. {
  52. TalkingActionComplete.Reset();
  53. await Bot.SendWithMarkdown2(Player.ChatId, $"{strings.your_turn}\n{strings.you_turn_say}", Keyboard.InGamePlayerMenuWithEndTurn);
  54. Player.IsSpeaker = true;
  55. var timer = new Timer(60 * 1000) {AutoReset = false};
  56. timer.Elapsed += (_, _) => TalkingActionComplete.Set();
  57. timer.Start();
  58. TalkingActionComplete.WaitOne();
  59. timer.Stop();
  60. await Bot.SendWithMarkdown2(Player.ChatId, strings.your_turn_ended, Keyboard.InGamePlayerMenu);
  61. Player.IsSpeaker = false;
  62. }
  63. public async Task VotingAction()
  64. {
  65. var voteTimer = new Timer(10 * 1000) {AutoReset = false};
  66. var alivePlayers = Room.Players.Values.Where(p => p.IsAlive).ToList();
  67. var message = await SendVotingList(alivePlayers, !Player.IsFirst);
  68. voteTimer.Elapsed += async (_, _) =>
  69. {
  70. await Bot.EditMessageAsync(Player.ChatId, message.MessageId, strings.time_out);
  71. if (Player.IsFirst)
  72. await Room.PutUpVote(Player.Id, Player.Id);
  73. else
  74. await Room.PlayersCh.SendExcept(Player.Id, $"{Player.NickName} {strings.didnt_put_anyone}");
  75. VoteActionComplete.Set();
  76. };
  77. if(Player.IsFirst) await Bot.SendWithMarkdown2(Player.Id, strings.user_not_choose);
  78. voteTimer.Start();
  79. VoteActionComplete.WaitOne();
  80. voteTimer.Stop();
  81. if(message!=null) await Bot.Get().DeleteMessageAsync(Player.ChatId, message.MessageId);
  82. }
  83. public async Task<Message> SendVotingList(List<Player> targets, bool skipButton = true)
  84. {
  85. VoteActionComplete.Reset();
  86. return await Bot.SendWithMarkdown2(Player.ChatId, $"{strings.put_up_vote}\n{strings.you_have_ten_seconds}",
  87. Keyboard.VoteKeyboard(targets, Player.Id, skipButton));
  88. }
  89. public async Task DefenceAction()
  90. {
  91. await Room.PlayersCh.SendExcept(Player.Id, $"{strings.now_defence} {Player.NickName}");
  92. await OneMinuteSpeak();
  93. }
  94. public static Role GetNewRoleInstance(Roles roleKey, GameRoom room, Player player)
  95. {
  96. return roleKey switch
  97. {
  98. Roles.All => new NoneRole(),
  99. Roles.None => new NoneRole(),
  100. Roles.Doctor => new DoctorRole(room, player),
  101. Roles.Mafia => new MafiaRole(room, player),
  102. Roles.Don => new DonRole(room, player),
  103. Roles.Cop => new CopRole(room, player),
  104. Roles.Villager => new VillagerRole(room, player),
  105. Roles.Hooker => new HookerRole(room, player),
  106. Roles.Elder => new ElderRole(room, player),
  107. Roles.Werewolf => new WerewolfRole(room, player),
  108. Roles.Journalist => new JournalistRole(room, player),
  109. Roles.Detective => new DetectiveRole(room, player),
  110. Roles.Dame => new DameRole(room, player),
  111. Roles.Parasite => new ParasiteRole(room, player),
  112. Roles.Lawyer => new LawyerRole(room, player),
  113. Roles.Fool => new FoolRole(room, player),
  114. Roles.Necromancer => new NecromancerRole(room, player),
  115. Roles.Bodyguard => new BodyguardRole(room, player),
  116. _ => throw new ArgumentOutOfRangeException(nameof(roleKey), roleKey, null)
  117. };
  118. }
  119. }
  120. }
  121. }