Implemented casting votes and ending the vote

This commit is contained in:
Elnath 2021-06-10 00:58:37 +02:00
parent 5f20403b9b
commit 19e2811823
2 changed files with 102 additions and 9 deletions

View File

@ -81,6 +81,14 @@ class Game:
def is_gm(self, user: discord.Member) -> bool: def is_gm(self, user: discord.Member) -> bool:
return self.get_gm_role() in user.roles return self.get_gm_role() in user.roles
@started_only
def get_player_role_id(self) -> int:
return self.config["player_role"]
@started_only
def get_player_role(self) -> discord.Role:
return self.guild.get_role(self.get_player_role_id())
@started_only @started_only
def get_game_category_id(self) -> int: def get_game_category_id(self) -> int:
return self.config["category"] return self.config["category"]
@ -89,6 +97,14 @@ class Game:
def get_game_category(self) -> discord.CategoryChannel: def get_game_category(self) -> discord.CategoryChannel:
return self.guild.get_channel(self.get_game_category_id()) return self.guild.get_channel(self.get_game_category_id())
@started_only
def get_announcements_channel_id(self) -> int:
return self.config["announce_chan"]
@started_only
def get_announcements_channel(self) -> discord.TextChannel:
return self.guild.get_channel(self.get_announcements_channel_id())
@started_only @started_only
def get_votes_channel_id(self) -> int: def get_votes_channel_id(self) -> int:
return self.config["votes_chan"] return self.config["votes_chan"]
@ -108,6 +124,16 @@ class Game:
vote_count[self.config["vote"][str(player_id)]] += 1 vote_count[self.config["vote"][str(player_id)]] += 1
return vote_count[True] > vote_count[False] return vote_count[True] > vote_count[False]
@started_only
def get_player_channel_id(self, player: Union[int, discord.Member]) -> int:
if isinstance(player, discord.Member):
player = player.id
return self.config["player_info"][str(player)]["channel"]
@started_only
def get_player_channel(self, player: Union[int, discord.Member]) -> discord.TextChannel:
return self.guild.get_channel(self.get_player_channel_id(player))
async def start(self, gm_role: discord.Role, player_role: discord.Role): async def start(self, gm_role: discord.Role, player_role: discord.Role):
if self.is_started(): if self.is_started():
raise ValueError("Game already started") raise ValueError("Game already started")
@ -193,6 +219,7 @@ class Game:
"Do you want to elect the following government?", "Do you want to elect the following government?",
f":crown: <@{president}> as president", f":crown: <@{president}> as president",
f":person_in_tuxedo: <@{chancellor}> as chancellor", f":person_in_tuxedo: <@{chancellor}> as chancellor",
"You can vote by typing `!ja` or `!nein` in your channel"
"", "",
] ]
for player_id in self.get_players_id(): for player_id in self.get_players_id():
@ -214,5 +241,28 @@ class Game:
else: else:
await (await self.get_votes_channel().fetch_message(self.config["vote"]["message"])).edit(content = message_content_str, allowed_mentions = discord.AllowedMentions.none()) await (await self.get_votes_channel().fetch_message(self.config["vote"]["message"])).edit(content = message_content_str, allowed_mentions = discord.AllowedMentions.none())
@vote_running
async def cast_vote(self, user: discord.Member, vote: Union[bool, None]):
logging.debug(f"[{self.guild.name}] Casting vote with value {vote} for user {user.display_name}")
self.config["vote"][str(user.id)] = vote
await self.update_vote_message()
self.save_function()
@vote_running
async def stop_vote(self):
logging.debug(f"[{self.guild.name}] Stopping the vote")
passed = self.is_vote_passing()
self.config["vote"]["revealed"] = True
await self.update_vote_message()
await self.get_votes_channel().send("**The vote has ended**")
announcement_content = [
f"{self.get_player_role().mention} the vote has ended!",
f"{':green_square:' if passed else ':red_square:'} The vote has **{'' if passed else 'not '}passed**"
]
if passed:
president = self.config["vote"]["president"]
chancellor = self.config["vote"]["chancellor"]
announcement_content.append(f"Congratulations to president <@{president}> and chancellor <@{chancellor}>!")
await self.get_announcements_channel().send("\n".join(announcement_content), allowed_mentions = discord.AllowedMentions(roles = True))
self.config["vote"] = None
self.save_function()

View File

@ -85,6 +85,15 @@ class SecretBot(commands.Cog):
await ctx.reply(f":dragon_face: You have no power here!") await ctx.reply(f":dragon_face: You have no power here!")
raise utils.CheckFailDoNotNotify raise utils.CheckFailDoNotNotify
async def check_is_administrator_or_gm(self, ctx: commands.Context):
"""
If the user that sent the command is not either an administrator of the server or a gm of the game, notify them and raise utils.CheckFailDoNotNotify.
"""
game = self.games_file[ctx.guild]
if not (utils.is_administrator(ctx.author) or (game.is_started() and game.is_gm(ctx.author))):
await ctx.reply(f":dragon_face: You have no power here!")
raise utils.CheckFailDoNotNotify
@commands.command(help = "See if I'm alive") @commands.command(help = "See if I'm alive")
async def ping(self, ctx: commands.Context): async def ping(self, ctx: commands.Context):
await ctx.reply(":ping_pong:", mention_author = True) await ctx.reply(":ping_pong:", mention_author = True)
@ -104,18 +113,17 @@ class SecretBot(commands.Cog):
async def delete_game(self, ctx: commands.Context): async def delete_game(self, ctx: commands.Context):
game = self.games_file[ctx.guild] game = self.games_file[ctx.guild]
if game.is_started(): if game.is_started():
if game.is_gm(ctx.author) or utils.is_administrator(ctx.author): await self.check_is_administrator_or_gm(ctx)
gm_role = game.get_gm_role() gm_role = game.get_gm_role()
await game.delete() await game.delete()
await ctx.guild.get_member(self.bot.user.id).remove_roles(gm_role) await ctx.guild.get_member(self.bot.user.id).remove_roles(gm_role)
await ctx.reply(":white_check_mark: Game deleted!") await ctx.reply(":white_check_mark: Game deleted!")
else:
await ctx.reply(f":dragon_face: You have no power here!")
else: else:
await ctx.reply(":x: Game is not running") await ctx.reply(":x: Game is not running")
@commands.command("StartVote") @commands.command("StartVote")
async def start_vote(self, ctx: commands.Context, president: discord.Member, chancellor: discord.Member): async def start_vote(self, ctx: commands.Context, president: discord.Member, chancellor: discord.Member):
await self.check_is_administrator_or_gm(ctx)
game = self.games_file[ctx.guild] game = self.games_file[ctx.guild]
if not game.is_started(): if not game.is_started():
await ctx.reply(":x: Game is not running") await ctx.reply(":x: Game is not running")
@ -126,6 +134,41 @@ class SecretBot(commands.Cog):
await game.start_vote(president, chancellor) await game.start_vote(president, chancellor)
await ctx.message.delete() await ctx.message.delete()
async def cast_vote(self, ctx: commands.Context, vote: bool):
game = self.games_file[ctx.guild]
if game.is_started() and game.is_vote_running():
if ctx.author.id in game.get_players_id():
if ctx.channel == game.get_player_channel(ctx.author):
await game.cast_vote(ctx.author, vote)
await ctx.reply(":pencil: Your vote has been registered. Thank you citizen.")
else:
await ctx.reply(":x: Please cast your vote in your dedicated channel.")
else:
await ctx.reply(":x: Only players can cast votes")
else:
await ctx.reply(":x: There isn't a vote running")
@commands.command("ja")
async def vote_yes(self, ctx: commands.Context):
await self.cast_vote(ctx, True)
@commands.command("nein")
async def vote_no(self, ctx: commands.Context):
await self.cast_vote(ctx, False)
@commands.command("StopTheCount")
async def stop_vote(self, ctx: commands.Context):
await self.check_is_administrator_or_gm(ctx)
game = self.games_file[ctx.guild]
if not game.is_started():
await ctx.reply(":x: Game is not running")
return
if not game.is_vote_running():
await ctx.reply(":x: No vote is running")
return
await game.stop_vote()
await ctx.message.delete()
if __name__ == '__main__': if __name__ == '__main__':
argparser = argparse.ArgumentParser(description = "Secret Hitler helper bot", formatter_class = argparse.ArgumentDefaultsHelpFormatter) argparser = argparse.ArgumentParser(description = "Secret Hitler helper bot", formatter_class = argparse.ArgumentDefaultsHelpFormatter)