GameRoom.Role.cs 6.8 KB

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