diff --git a/werewolf/builder.py b/werewolf/builder.py index b6a52df..1648b45 100644 --- a/werewolf/builder.py +++ b/werewolf/builder.py @@ -17,7 +17,7 @@ from redbot.core.utils.menus import menu, prev_page, next_page, close_menu ROLE_LIST = sorted([Villager, Seer, VanillaWerewolf], key=lambda x: x.alignment) -ALIGNMENT_COLORS = [0x008000, 0xff0000, 0xc0c0c0] +ALIGNMENT_COLORS = [0x008000, 0xFF0000, 0xC0C0C0] TOWN_ROLES = [(idx, role) for idx, role in enumerate(ROLE_LIST) if role.alignment == 1] WW_ROLES = [(idx, role) for idx, role in enumerate(ROLE_LIST) if role.alignment == 2] OTHER_ROLES = [(idx, role) for idx, role in enumerate(ROLE_LIST) if role.alignment not in [0, 1]] @@ -26,21 +26,38 @@ ROLE_PAGES = [] PAGE_GROUPS = [0] ROLE_CATEGORIES = { - 1: "Random", 2: "Investigative", 3: "Protective", 4: "Government", - 5: "Killing", 6: "Power (Special night action)", - 11: "Random", 12: "Deception", 15: "Killing", 16: "Support", - 21: "Benign", 22: "Evil", 23: "Killing"} + 1: "Random", + 2: "Investigative", + 3: "Protective", + 4: "Government", + 5: "Killing", + 6: "Power (Special night action)", + 11: "Random", + 12: "Deception", + 15: "Killing", + 16: "Support", + 21: "Benign", + 22: "Evil", + 23: "Killing", +} CATEGORY_COUNT = [] def role_embed(idx, role, color): - embed = discord.Embed(title="**{}** - {}".format(idx, str(role.__name__)), description=role.game_start_message, - color=color) - embed.add_field(name='Alignment', value=['Town', 'Werewolf', 'Neutral'][role.alignment - 1], inline=True) - embed.add_field(name='Multiples Allowed', value=str(not role.unique), inline=True) - embed.add_field(name='Role Type', value=", ".join(ROLE_CATEGORIES[x] for x in role.category), inline=True) - embed.add_field(name='Random Option', value=str(role.rand_choice), inline=True) + embed = discord.Embed( + title="**{}** - {}".format(idx, str(role.__name__)), + description=role.game_start_message, + color=color, + ) + embed.add_field( + name="Alignment", value=["Town", "Werewolf", "Neutral"][role.alignment - 1], inline=True + ) + embed.add_field(name="Multiples Allowed", value=str(not role.unique), inline=True) + embed.add_field( + name="Role Type", value=", ".join(ROLE_CATEGORIES[x] for x in role.category), inline=True + ) + embed.add_field(name="Random Option", value=str(role.rand_choice), inline=True) return embed @@ -60,7 +77,11 @@ def setup(): PAGE_GROUPS.append(len(ROLE_PAGES) - 1) for k, v in ROLE_CATEGORIES.items(): if 0 < k <= 6: - ROLE_PAGES.append(discord.Embed(title="RANDOM:Town Role", description="Town {}".format(v), color=0x008000)) + ROLE_PAGES.append( + discord.Embed( + title="RANDOM:Town Role", description="Town {}".format(v), color=0x008000 + ) + ) CATEGORY_COUNT.append(k) # Random WW Roles @@ -69,7 +90,12 @@ def setup(): for k, v in ROLE_CATEGORIES.items(): if 10 < k <= 16: ROLE_PAGES.append( - discord.Embed(title="RANDOM:Werewolf Role", description="Werewolf {}".format(v), color=0xff0000)) + discord.Embed( + title="RANDOM:Werewolf Role", + description="Werewolf {}".format(v), + color=0xFF0000, + ) + ) CATEGORY_COUNT.append(k) # Random Neutral Roles if len(ROLE_PAGES) - 1 not in PAGE_GROUPS: @@ -77,7 +103,10 @@ def setup(): for k, v in ROLE_CATEGORIES.items(): if 20 < k <= 26: ROLE_PAGES.append( - discord.Embed(title="RANDOM:Neutral Role", description="Neutral {}".format(v), color=0xc0c0c0)) + discord.Embed( + title="RANDOM:Neutral Role", description="Neutral {}".format(v), color=0xC0C0C0 + ) + ) CATEGORY_COUNT.append(k) @@ -187,9 +216,15 @@ async def encode(roles, rand_roles): return out_code -async def next_group(ctx: commands.Context, pages: list, - controls: dict, message: discord.Message, page: int, - timeout: float, emoji: str): +async def next_group( + ctx: commands.Context, + pages: list, + controls: dict, + message: discord.Message, + page: int, + timeout: float, + emoji: str, +): perms = message.channel.permissions_for(ctx.me) if perms.manage_messages: # Can manage messages, so remove react try: @@ -203,13 +238,18 @@ async def next_group(ctx: commands.Context, pages: list, else: page = PAGE_GROUPS[page] - return await menu(ctx, pages, controls, message=message, - page=page, timeout=timeout) + return await menu(ctx, pages, controls, message=message, page=page, timeout=timeout) -async def prev_group(ctx: commands.Context, pages: list, - controls: dict, message: discord.Message, page: int, - timeout: float, emoji: str): +async def prev_group( + ctx: commands.Context, + pages: list, + controls: dict, + message: discord.Message, + page: int, + timeout: float, + emoji: str, +): perms = message.channel.permissions_for(ctx.me) if perms.manage_messages: # Can manage messages, so remove react try: @@ -218,18 +258,23 @@ async def prev_group(ctx: commands.Context, pages: list, pass page = PAGE_GROUPS[bisect.bisect_left(PAGE_GROUPS, page) - 1] - return await menu(ctx, pages, controls, message=message, - page=page, timeout=timeout) + return await menu(ctx, pages, controls, message=message, page=page, timeout=timeout) def role_from_alignment(alignment): - return [role_embed(idx, role, ALIGNMENT_COLORS[role.alignment - 1]) - for idx, role in enumerate(ROLE_LIST) if alignment == role.alignment] + return [ + role_embed(idx, role, ALIGNMENT_COLORS[role.alignment - 1]) + for idx, role in enumerate(ROLE_LIST) + if alignment == role.alignment + ] def role_from_category(category): - return [role_embed(idx, role, ALIGNMENT_COLORS[role.alignment - 1]) - for idx, role in enumerate(ROLE_LIST) if category in role.category] + return [ + role_embed(idx, role, ALIGNMENT_COLORS[role.alignment - 1]) + for idx, role in enumerate(ROLE_LIST) + if category in role.category + ] def role_from_id(idx): @@ -242,8 +287,11 @@ def role_from_id(idx): def role_from_name(name: str): - return [role_embed(idx, role, ALIGNMENT_COLORS[role.alignment - 1]) - for idx, role in enumerate(ROLE_LIST) if name in role.__name__] + return [ + role_embed(idx, role, ALIGNMENT_COLORS[role.alignment - 1]) + for idx, role in enumerate(ROLE_LIST) + if name in role.__name__ + ] def say_role_list(code_list, rand_roles): @@ -268,7 +316,6 @@ def say_role_list(code_list, rand_roles): class GameBuilder: - def __init__(self): self.code = [] self.rand_roles = [] @@ -276,13 +323,13 @@ class GameBuilder: async def build_game(self, ctx: commands.Context): new_controls = { - '⏪': prev_group, + "⏪": prev_group, "⬅": prev_page, - '☑': self.select_page, + "☑": self.select_page, "➡": next_page, - '⏩': next_group, - '📇': self.list_roles, - "❌": close_menu + "⏩": next_group, + "📇": self.list_roles, + "❌": close_menu, } await ctx.send("Browse through roles and add the ones you want using the check mark") @@ -292,9 +339,16 @@ class GameBuilder: out = await encode(self.code, self.rand_roles) return out - async def list_roles(self, ctx: commands.Context, pages: list, - controls: dict, message: discord.Message, page: int, - timeout: float, emoji: str): + async def list_roles( + self, + ctx: commands.Context, + pages: list, + controls: dict, + message: discord.Message, + page: int, + timeout: float, + emoji: str, + ): perms = message.channel.permissions_for(ctx.me) if perms.manage_messages: # Can manage messages, so remove react try: @@ -304,12 +358,18 @@ class GameBuilder: await ctx.send(embed=say_role_list(self.code, self.rand_roles)) - return await menu(ctx, pages, controls, message=message, - page=page, timeout=timeout) - - async def select_page(self, ctx: commands.Context, pages: list, - controls: dict, message: discord.Message, page: int, - timeout: float, emoji: str): + return await menu(ctx, pages, controls, message=message, page=page, timeout=timeout) + + async def select_page( + self, + ctx: commands.Context, + pages: list, + controls: dict, + message: discord.Message, + page: int, + timeout: float, + emoji: str, + ): perms = message.channel.permissions_for(ctx.me) if perms.manage_messages: # Can manage messages, so remove react try: @@ -322,5 +382,4 @@ class GameBuilder: else: self.code.append(page) - return await menu(ctx, pages, controls, message=message, - page=page, timeout=timeout) + return await menu(ctx, pages, controls, message=message, page=page, timeout=timeout) diff --git a/werewolf/game.py b/werewolf/game.py index a31518f..95807a1 100644 --- a/werewolf/game.py +++ b/werewolf/game.py @@ -15,6 +15,7 @@ class Game: """ Base class to run a single game of Werewolf """ + vote_groups: Dict[str, VoteGroup] roles: List[Role] players: List[Player] @@ -22,19 +23,25 @@ class Game: default_secret_channel = { "channel": None, "players": [], - "votegroup": None # uninitialized VoteGroup + "votegroup": None, # uninitialized VoteGroup } morning_messages = [ "**The sun rises on day {} in the village..**", - "**Morning has arrived on day {}..**" + "**Morning has arrived on day {}..**", ] day_vote_count = 3 - def __init__(self, guild: discord.Guild, role: discord.Role = None, - category: discord.CategoryChannel = None, village: discord.TextChannel = None, - log_channel: discord.TextChannel = None, game_code=None): + def __init__( + self, + guild: discord.Guild, + role: discord.Role = None, + category: discord.CategoryChannel = None, + village: discord.TextChannel = None, + log_channel: discord.TextChannel = None, + game_code=None, + ): self.guild = guild self.game_code = game_code @@ -97,22 +104,28 @@ class Game: await self.get_roles(ctx) if len(self.players) != len(self.roles): - await ctx.maybe_send_embed("Player count does not match role count, cannot start\n" - "Currently **{} / {}**\n" - "Use `{}ww code` to pick a new game" - "".format(len(self.players), len(self.roles), ctx.prefix)) + await ctx.maybe_send_embed( + "Player count does not match role count, cannot start\n" + "Currently **{} / {}**\n" + "Use `{}ww code` to pick a new game" + "".format(len(self.players), len(self.roles), ctx.prefix) + ) self.roles = [] return False if self.game_role is None: try: - self.game_role = await ctx.guild.create_role(name="WW Players", - hoist=True, - mentionable=True, - reason="(BOT) Werewolf game role") + self.game_role = await ctx.guild.create_role( + name="WW Players", + hoist=True, + mentionable=True, + reason="(BOT) Werewolf game role", + ) self.to_delete.add(self.game_role) except (discord.Forbidden, discord.HTTPException): - await ctx.maybe_send_embed("Game role not configured and unable to generate one, cannot start") + await ctx.maybe_send_embed( + "Game role not configured and unable to generate one, cannot start" + ) self.roles = [] return False try: @@ -120,24 +133,33 @@ class Game: await player.member.add_roles(*[self.game_role]) except discord.Forbidden: await ctx.send( - "Unable to add role **{}**\nBot is missing `manage_roles` permissions".format(self.game_role.name)) + "Unable to add role **{}**\nBot is missing `manage_roles` permissions".format( + self.game_role.name + ) + ) return False await self.assign_roles() # Create category and channel with individual overwrites overwrite = { - self.guild.default_role: discord.PermissionOverwrite(read_messages=True, send_messages=False, - add_reactions=False), - self.guild.me: discord.PermissionOverwrite(read_messages=True, send_messages=True, add_reactions=True, - manage_messages=True, manage_channels=True, - manage_roles=True), - self.game_role: discord.PermissionOverwrite(read_messages=True, send_messages=True) + self.guild.default_role: discord.PermissionOverwrite( + read_messages=True, send_messages=False, add_reactions=False + ), + self.guild.me: discord.PermissionOverwrite( + read_messages=True, + send_messages=True, + add_reactions=True, + manage_messages=True, + manage_channels=True, + manage_roles=True, + ), + self.game_role: discord.PermissionOverwrite(read_messages=True, send_messages=True), } if self.channel_category is None: - self.channel_category = await self.guild.create_category("Werewolf Game", - overwrites=overwrite, - reason="(BOT) New game of werewolf") + self.channel_category = await self.guild.create_category( + "Werewolf Game", overwrites=overwrite, reason="(BOT) New game of werewolf" + ) else: # No need to modify categories pass # await self.channel_category.edit(name="🔴 Werewolf Game (ACTIVE)", reason="(BOT) New game of werewolf") @@ -147,20 +169,26 @@ class Game: # reason="(BOT) New game of werewolf") if self.village_channel is None: try: - self.village_channel = await self.guild.create_text_channel("🔵Werewolf", - overwrites=overwrite, - reason="(BOT) New game of werewolf", - category=self.channel_category) + self.village_channel = await self.guild.create_text_channel( + "🔵Werewolf", + overwrites=overwrite, + reason="(BOT) New game of werewolf", + category=self.channel_category, + ) except discord.Forbidden: - await ctx.send("Unable to create Game Channel and none was provided\n" - "Grant Bot appropriate permissions or assign a game_channel") + await ctx.send( + "Unable to create Game Channel and none was provided\n" + "Grant Bot appropriate permissions or assign a game_channel" + ) return False else: self.save_perms[self.village_channel] = self.village_channel.overwrites try: - await self.village_channel.edit(name="🔵Werewolf", - category=self.channel_category, - reason="(BOT) New game of werewolf") + await self.village_channel.edit( + name="🔵Werewolf", + category=self.channel_category, + reason="(BOT) New game of werewolf", + ) except discord.Forbidden as e: print("Unable to rename Game Channel") print(e) @@ -170,12 +198,14 @@ class Game: for target, ow in overwrite.items(): curr = self.village_channel.overwrites_for(target) curr.update(**{perm: value for perm, value in ow}) - await self.village_channel.set_permissions(target=target, - overwrite=curr, - reason="(BOT) New game of werewolf") + await self.village_channel.set_permissions( + target=target, overwrite=curr, reason="(BOT) New game of werewolf" + ) except discord.Forbidden: - await ctx.send("Unable to edit Game Channel permissions\n" - "Grant Bot appropriate permissions to manage permissions") + await ctx.send( + "Unable to edit Game Channel permissions\n" + "Grant Bot appropriate permissions to manage permissions" + ) return self.started = True # Assuming everything worked so far @@ -186,18 +216,25 @@ class Game: print("Channel id: " + channel_id) overwrite = { self.guild.default_role: discord.PermissionOverwrite(read_messages=False), - self.guild.me: discord.PermissionOverwrite(read_messages=True, send_messages=True, add_reactions=True, - manage_messages=True, manage_channels=True, - manage_roles=True) + self.guild.me: discord.PermissionOverwrite( + read_messages=True, + send_messages=True, + add_reactions=True, + manage_messages=True, + manage_channels=True, + manage_roles=True, + ), } for player in self.p_channels[channel_id]["players"]: overwrite[player.member] = discord.PermissionOverwrite(read_messages=True) - channel = await self.guild.create_text_channel(channel_id, - overwrites=overwrite, - reason="(BOT) WW game secret channel", - category=self.channel_category) + channel = await self.guild.create_text_channel( + channel_id, + overwrites=overwrite, + reason="(BOT) WW game secret channel", + category=self.channel_category, + ) self.p_channels[channel_id]["channel"] = channel @@ -216,8 +253,8 @@ class Game: async def _cycle(self): """ Each event calls the next event - - + + _at_day_start() _at_voted() @@ -225,7 +262,7 @@ class Game: _at_day_end() _at_night_begin() _at_night_end() - + and repeat with _at_day_start() again """ await self._at_day_start() @@ -237,7 +274,8 @@ class Game: return await self.village_channel.send( - embed=discord.Embed(title="Game is starting, please wait for setup to complete")) + embed=discord.Embed(title="Game is starting, please wait for setup to complete") + ) await self._notify(0) @@ -271,7 +309,9 @@ class Game: await asyncio.sleep(24) # 4 minute days FixMe to 120 later if check(): return - await self.village_channel.send(embed=discord.Embed(title="**Two minutes of daylight remain...**")) + await self.village_channel.send( + embed=discord.Embed(title="**Two minutes of daylight remain...**") + ) await asyncio.sleep(24) # 4 minute days FixMe to 120 later # Need a loop here to wait for trial to end (can_vote?) @@ -295,7 +335,10 @@ class Game: await self.speech_perms(self.village_channel, target.member) # Only target can talk await self.village_channel.send( - "**{} will be put to trial and has 30 seconds to defend themselves**".format(target.mention)) + "**{} will be put to trial and has 30 seconds to defend themselves**".format( + target.mention + ) + ) await asyncio.sleep(30) @@ -305,7 +348,8 @@ class Game: "Everyone will now vote whether to lynch {}\n" "👍 to save, 👎 to lynch\n" "*Majority rules, no-lynch on ties, " - "vote both or neither to abstain, 15 seconds to vote*".format(target.mention)) + "vote both or neither to abstain, 15 seconds to vote*".format(target.mention) + ) await message.add_reaction("👍") await message.add_reaction("👎") @@ -317,9 +361,9 @@ class Game: down_votes = sum(p for p in reaction_list if p.emoji == "👎" and not p.me) if down_votes > up_votes: - embed = discord.Embed(title="Vote Results", color=0xff0000) + embed = discord.Embed(title="Vote Results", color=0xFF0000) else: - embed = discord.Embed(title="Vote Results", color=0x80ff80) + embed = discord.Embed(title="Vote Results", color=0x80FF80) embed.add_field(name="👎", value="**{}**".format(up_votes), inline=True) embed.add_field(name="👍", value="**{}**".format(down_votes), inline=True) @@ -339,7 +383,8 @@ class Game: else: await self.village_channel.send( "**{}**/**{}** of today's votes have been used!\n" - "Nominate carefully..".format(self.used_votes, self.day_vote_count)) + "Nominate carefully..".format(self.used_votes, self.day_vote_count) + ) self.ongoing_vote = False @@ -373,7 +418,9 @@ class Game: await self.night_perms(self.village_channel) - await self.village_channel.send(embed=discord.Embed(title="**The sun sets on the village...**")) + await self.village_channel.send( + embed=discord.Embed(title="**The sun sets on the village...**") + ) await self._notify(5) await asyncio.sleep(5) @@ -385,9 +432,13 @@ class Game: await self._notify(6) await asyncio.sleep(12) # 2 minutes FixMe to 120 later - await self.village_channel.send(embed=discord.Embed(title="**Two minutes of night remain...**")) + await self.village_channel.send( + embed=discord.Embed(title="**Two minutes of night remain...**") + ) await asyncio.sleep(9) # 1.5 minutes FixMe to 90 later - await self.village_channel.send(embed=discord.Embed(title="**Thirty seconds until sunrise...**")) + await self.village_channel.send( + embed=discord.Embed(title="**Thirty seconds until sunrise...**") + ) await asyncio.sleep(3) # .5 minutes FixMe to 3 Later await self._at_night_end() @@ -413,10 +464,12 @@ class Game: role_order = [role for role in self.roles if role.action_list[event][1] == i] for role in role_order: tasks.append(asyncio.ensure_future(role.on_event(event, data), loop=self.loop)) - # VoteGroup priorities + # VoteGroup priorities vote_order = [vg for vg in self.vote_groups.values() if vg.action_list[event][1] == i] for vote_group in vote_order: - tasks.append(asyncio.ensure_future(vote_group.on_event(event, data), loop=self.loop)) + tasks.append( + asyncio.ensure_future(vote_group.on_event(event, data), loop=self.loop) + ) if tasks: await asyncio.gather(*tasks) # Run same-priority task simultaneously @@ -432,13 +485,17 @@ class Game: else: status = "*[Dead]*-" if with_roles or not player.alive: - embed.add_field(name="ID# **{}**".format(i), - value="{}{}-{}".format(status, player.member.display_name, str(player.role)), - inline=True) + embed.add_field( + name="ID# **{}**".format(i), + value="{}{}-{}".format(status, player.member.display_name, str(player.role)), + inline=True, + ) else: - embed.add_field(name="ID# **{}**".format(i), - value="{}{}".format(status, player.member.display_name), - inline=True) + embed.add_field( + name="ID# **{}**".format(i), + value="{}{}".format(status, player.member.display_name), + inline=True, + ) return await channel.send(embed=embed) @@ -479,10 +536,15 @@ class Game: await member.add_roles(*[self.game_role]) except discord.Forbidden: await channel.send( - "Unable to add role **{}**\nBot is missing `manage_roles` permissions".format(self.game_role.name)) + "Unable to add role **{}**\nBot is missing `manage_roles` permissions".format( + self.game_role.name + ) + ) - await channel.send("{} has been added to the game, " - "total players is **{}**".format(member.mention, len(self.players))) + await channel.send( + "{} has been added to the game, " + "total players is **{}**".format(member.mention, len(self.players)) + ) async def quit(self, member: discord.Member, channel: discord.TextChannel = None): """ @@ -499,7 +561,11 @@ class Game: else: self.players = [player for player in self.players if player.member != member] await member.remove_roles(*[self.game_role]) - await channel.send("{} chickened out, player count is now **{}**".format(member.mention, len(self.players))) + await channel.send( + "{} chickened out, player count is now **{}**".format( + member.mention, len(self.players) + ) + ) async def choose(self, ctx, data): """ @@ -598,14 +664,20 @@ class Game: required_votes = len([player for player in self.players if player.alive]) // 7 + 2 if self.vote_totals[target_id] < required_votes: - await self.village_channel.send("" - "{} has voted to put {} to trial. " - "{} more votes needed".format(author.mention, - target.member.mention, - required_votes - self.vote_totals[target_id])) + await self.village_channel.send( + "" + "{} has voted to put {} to trial. " + "{} more votes needed".format( + author.mention, + target.member.mention, + required_votes - self.vote_totals[target_id], + ) + ) else: self.vote_totals[target_id] = 0 - self.day_vote = {k: v for k, v in self.day_vote.items() if v != target_id} # Remove votes for this id + self.day_vote = { + k: v for k, v in self.day_vote.items() if v != target_id + } # Remove votes for this id await self._at_voted(target) async def eval_results(self, target, source=None, method=None): @@ -613,9 +685,9 @@ class Game: out = "**{ID}** - " + method return out.format(ID=target.id, target=target.member.display_name) else: - return "**{ID}** - {target} the {role} was found dead".format(ID=target.id, - target=target.member.display_name, - role=await target.role.get_role()) + return "**{ID}** - {target} the {role} was found dead".format( + ID=target.id, target=target.member.display_name, role=await target.role.get_role() + ) async def _quit(self, player): """ @@ -748,7 +820,9 @@ class Game: alive_players = [player for player in self.players if player.alive] if len(alive_players) <= 0: - await self.village_channel.send(embed=discord.Embed(title="**Everyone is dead! Game Over!**")) + await self.village_channel.send( + embed=discord.Embed(title="**Everyone is dead! Game Over!**") + ) self.game_over = True elif len(alive_players) == 1: self.game_over = True @@ -780,17 +854,19 @@ class Game: async def _announce_winners(self, winnerlist): await self.village_channel.send(self.game_role.mention) - embed = discord.Embed(title='Game Over', description='The Following Players have won!') + embed = discord.Embed(title="Game Over", description="The Following Players have won!") for player in winnerlist: embed.add_field(name=player.member.display_name, value=str(player.role), inline=True) - embed.set_thumbnail(url='https://emojipedia-us.s3.amazonaws.com/thumbs/160/twitter/134/trophy_1f3c6.png') + embed.set_thumbnail( + url="https://emojipedia-us.s3.amazonaws.com/thumbs/160/twitter/134/trophy_1f3c6.png" + ) await self.village_channel.send(embed=embed) await self.generate_targets(self.village_channel, True) async def _end_game(self): # Remove game_role access for potential archiving for now - reason = '(BOT) End of WW game' + reason = "(BOT) End of WW game" for obj in self.to_delete: print(obj) await obj.delete(reason=reason) @@ -798,8 +874,12 @@ class Game: try: await self.village_channel.edit(reason=reason, name="Werewolf") for target, overwrites in self.save_perms[self.village_channel]: - await self.village_channel.set_permissions(target, overwrite=overwrites, reason=reason) - await self.village_channel.set_permissions(self.game_role, overwrite=None, reason=reason) + await self.village_channel.set_permissions( + target, overwrite=overwrites, reason=reason + ) + await self.village_channel.set_permissions( + self.game_role, overwrite=None, reason=reason + ) except (discord.HTTPException, discord.NotFound, discord.errors.NotFound): pass diff --git a/werewolf/role.py b/werewolf/role.py index 3e4124d..af2d38b 100644 --- a/werewolf/role.py +++ b/werewolf/role.py @@ -1,31 +1,31 @@ class Role: """ Base Role class for werewolf game - + Category enrollment guide as follows (category property): Town: 1: Random, 2: Investigative, 3: Protective, 4: Government, 5: Killing, 6: Power (Special night action) - + Werewolf: 11: Random, 12: Deception, 15: Killing, 16: Support - + Neutral: 21: Benign, 22: Evil, 23: Killing - - + + Example category: category = [1, 5, 6] Could be Veteran category = [1, 5] Could be Bodyguard category = [11, 16] Could be Werewolf Silencer - - + + Action guide as follows (on_event function): _at_night_start 0. No Action 1. Detain actions (Jailer/Kidnapper) 2. Group discussions and choose targets - + _at_night_end 0. No Action 1. Self actions (Veteran) @@ -68,7 +68,7 @@ class Role: (self._at_day_end, 0), (self._at_night_start, 0), (self._at_night_end, 0), - (self._at_visit, 0) + (self._at_visit, 0), ] def __repr__(self): diff --git a/werewolf/votegroup.py b/werewolf/votegroup.py index bf07c8c..a754247 100644 --- a/werewolf/votegroup.py +++ b/werewolf/votegroup.py @@ -23,7 +23,7 @@ class VoteGroup: (self._at_day_end, 0), (self._at_night_start, 2), (self._at_night_end, 0), - (self._at_visit, 0) + (self._at_visit, 0), ] async def on_event(self, event, data):