123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205 |
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Threading;
- using System.Threading.Tasks;
- using MafiaTelegramBot.Game.GameRoles;
- using MafiaTelegramBot.Resources;
- using Timer = System.Timers.Timer;
- namespace MafiaTelegramBot.Game.GameRooms
- {
- public partial class GameRoom
- {
- public abstract class Role
- {
- protected readonly GameRoom Room;
- protected readonly Player Player;
- public readonly Dictionary<long, string> KnownRoles = new();
- protected long NightTargetId = -1;
- public long MafiaTargetId = -1;
- public abstract int ColorRole
- {
- get;
- set;
- }
-
- public readonly ManualResetEvent TalkingActionComplete = new(false);
- public readonly ManualResetEvent VoteActionComplete = new(false);
- protected int MessageId = -1;
- protected int MafiaMessageId = -1;
- protected List<Player> NightTargetList = null;
- public abstract Roles RoleKey { get; }
- public abstract int RankingCost { get; }
-
- public virtual Task NightAction() { return Task.CompletedTask; }
- public virtual Task SetMafiaTarget(long userId) { return Task.CompletedTask; }
- public virtual Task ApplyNightActionResult() { return Task.CompletedTask; }
- public virtual Task SetNightTarget(long userId) { return Task.CompletedTask; }
- public virtual async Task CancelNightActionResult(string message)
- {
- if (MessageId != -1)
- {
- await Room.PlayersMessageChannel.EditTo(Player.Id, MessageId, strings.activity_blocked);
- NightTargetId = -2;
- }
- if (MafiaMessageId != -1)
- {
- Player.IsSpeaker = false;
- await Room.PlayersMessageChannel.EditTo(Player.Id, MafiaMessageId, strings.activity_blocked);
- MafiaTargetId = -2;
- }
- await Room.PlayersMessageChannel.SendTo(Player.ChatId, message);
- }
- public virtual async Task<string> IsWon()
- {
- return await Task.Run(() => "");
- }
- public virtual async Task Dispatch()
- {
- if (Room.PlayersRole.ContainsKey(Roles.Hooker)
- && Room.PlayersRole[Roles.Hooker].Count == 1
- && Room.PlayersRole[Roles.Hooker][0].CurrentRole.NightTargetId == Player.Id)
- {
- await Room.PlayersMessageChannel.SendExcept(Player.Id, $"{strings.villagers_want_dispatch} {Player.NickName}, {strings.player_not_died_he_has_alibi}");
- }
- else
- {
- if (!Player.IsBlocked)
- {
- await Room.PlayersMessageChannel.SendExcept(Player.Id, $"{strings.to_player} {Player.NickName} {strings.issued_posthumous_minute}");
- await Room.PlayersMessageChannel.SendTo(Player.ChatId, strings.you_will_be_dispatched);
- await SpeakAction(enableTimer: true);
- }
- await Kill();
- await Room.PlayersMessageChannel.Send($"({Player.TurnOrder}) {Player.NickName} {strings.dispatched}");
- if(RoleKey == Roles.Cop) Player.FoolRoleAchievementEvent();
- }
- }
- public virtual async Task Kill()
- {
- Player.IsAlive = false;
- if (Room.PlayersRole.ContainsKey(Roles.Parasite)
- && Room.PlayersRole[Roles.Parasite].Count == 1
- && ((ParasiteRole) Room.PlayersRole[Roles.Parasite][0].CurrentRole).ParentId == Player.Id)
- {
- await Room.PlayersRole[Roles.Parasite][0].CurrentRole.Kill();
- if(Room.IsDay) await Room.PlayersMessageChannel.Send($"{strings.for_unknown_reasons_died} {Room.PlayersRole[Roles.Parasite][0].NickName}");
- await Room.PlayersMessageChannel.SendTo(Room.PlayersRole[Roles.Parasite][0].Id,
- strings.your_carrier_player_has_died);
- }
- }
- protected async Task SetRandomNightTarget()
- {
- var inGamePlayers = NightTargetList.Where(p => Room.Players.ContainsKey(p.Id)).ToArray();
- if (inGamePlayers.Length == 0)
- {
- NightTargetId = -1;
- await Room.PlayersMessageChannel.EditTo(Player.Id, MessageId, strings.nothing_to_choose);
- }
- else
- {
- NightTargetId = NightTargetList[Utilities.Rnd.Next(NightTargetList.Count)].Id;
- await Room.PlayersMessageChannel.EditTo(Player.Id, MessageId,
- $"{strings.automatically_choosed_target} {Room.Players[NightTargetId].NickName}");
- }
- }
- protected Role(GameRoom room, Player player)
- {
- Room = room;
- Player = player;
- }
- public async Task SpeakAction(int interval = Constants.SPEAK_INTERVAL, bool enableTimer = false)
- {
- await Room.PlayersMessageChannel.SendTo(Player.ChatId, $"{strings.your_turn}", Keyboard.InGamePlayerMenuWithEndTurn);
- Player.IsSpeaker = true;
- var timer = new Timer(interval) {AutoReset = false};
- timer.Elapsed += (_, _) => TalkingActionComplete.Set();
- if (Room.TimerEnabled || enableTimer) timer.Start();
- TalkingActionComplete.WaitOne();
- if (Room.TimerEnabled || enableTimer) timer.Stop();
- TalkingActionComplete.Reset();
- await Room.PlayersMessageChannel.SendTo(Player.ChatId, strings.your_turn_ended, Keyboard.InGamePlayerMenu);
- Player.IsSpeaker = false;
- }
- public async Task VotingAction(bool isFirst = false)
- {
- var voteTimer = new Timer(Constants.PUT_UP_VOTE_INTERVAL) {AutoReset = false};
- var alivePlayers = Room.Players.Values.Where(p => p.IsAlive).Except(Room._voteUpList).ToList();
- var message = await Room.PlayersMessageChannel.SendTo(Player.ChatId,
- $"{strings.put_up_vote}\n{strings.you_have_twenty_seconds}{(isFirst ? "\n" + strings.user_not_choose : "")}",
- Keyboard.VoteKeyboard(alivePlayers, Player.Id, !isFirst));
- voteTimer.Elapsed += async (_, _) =>
- {
- if (isFirst) await Room.PutUpVote(Player.Id, Player.Id, message.MessageId);
- else await Room.PutUpVote(Player.Id, 0, message.MessageId);
- VoteActionComplete.Set();
- };
- voteTimer.Start();
- VoteActionComplete.WaitOne();
- voteTimer.Stop();
- VoteActionComplete.Reset();
- }
- private int _votingMessageId;
- private List<Player> _votingTargetsList;
- public async Task VotingAction(List<Player> targets)
- {
- _votingMessageId = (await Room.PlayersMessageChannel.SendTo(Player.Id, strings.you_have_ten_seconds_to_vote,
- Keyboard.VoteKeyboard(targets, Player.Id, false, Callback.VoteToKill))).MessageId;
- _votingTargetsList = targets;
- }
- public async Task RandomVoting()
- {
- var players = _votingTargetsList.Where(p => Room.Players.ContainsKey(p.Id)).ToArray();
- if(players.Length == 0) await Room.PlayersMessageChannel.EditTo(Player.Id, _votingMessageId, strings.nothing_to_choose);
- else
- {
- var randomPlayer = players[Utilities.Rnd.Next(players.Length)];
- await Room.PutUpVote(Player.Id, randomPlayer.Id, toKill: true);
- await Room.PlayersMessageChannel.EditTo(Player.Id, _votingMessageId, $"{strings.automatically_vote} ({randomPlayer.TurnOrder}) {randomPlayer.NickName}");
- }
- }
- public async Task DefenceAction()
- {
- await Room.PlayersMessageChannel.SendExcept(Player.Id, $"{strings.now_defence} ({Player.TurnOrder}) {Player.NickName}");
- await Room.PlayersMessageChannel.SendTo(Player.ChatId, strings.you_have_eigty_seconds_to_defence);
- await SpeakAction(Constants.DEFENCE_INTERVAL);
- }
- public static Role GetNewRoleInstance(Roles roleKey, GameRoom room, Player player)
- {
- return roleKey switch
- {
- Roles.All => new NoneRole(),
- Roles.None => new NoneRole(),
- Roles.Mafia => new MafiaRole(room, player),
- Roles.Don => new DonRole(room, player),
- Roles.Cop => new CopRole(room, player),
- Roles.Villager => new VillagerRole(room, player),
- Roles.Hooker => new HookerRole(room, player),
- Roles.Elder => new ElderRole(room, player),
- Roles.Werewolf => new WerewolfRole(room, player),
- Roles.Journalist => new JournalistRole(room, player),
- Roles.Detective => new DetectiveRole(room, player),
- Roles.Dame => new DameRole(room, player),
- Roles.Lawyer => new LawyerRole(room, player),
- Roles.Fool => new FoolRole(room, player),
- Roles.Necromancer => new NecromancerRole(room, player),
- Roles.Bodyguard => new BodyguardRole(room, player),
- Roles.Doctor => new DoctorRole(room, player),
- Roles.Parasite => new ParasiteRole(room, player),
- _ => throw new ArgumentOutOfRangeException(nameof(roleKey), roleKey, null)
- };
- }
- }
- }
- }
|