Draw and enact policies for legislative step
This commit is contained in:
parent
fa28e10f27
commit
4e825e10ce
|
|
@ -1,13 +1,20 @@
|
||||||
import logging
|
import logging
|
||||||
|
import random
|
||||||
from typing import Dict, Callable, List, Union
|
from typing import Dict, Callable, List, Union
|
||||||
from functools import wraps
|
from functools import wraps
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
|
from enum import Enum
|
||||||
|
|
||||||
import discord
|
import discord
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class Policy(Enum):
|
||||||
|
LIBERAL = "L"
|
||||||
|
FASCIST = "F"
|
||||||
|
|
||||||
|
|
||||||
def game_started(func):
|
def game_started(func):
|
||||||
"""
|
"""
|
||||||
Decorator for *methods* of Game that need the game to be started.
|
Decorator for *methods* of Game that need the game to be started.
|
||||||
|
|
@ -113,6 +120,14 @@ class Game:
|
||||||
def get_votes_channel(self) -> discord.TextChannel:
|
def get_votes_channel(self) -> discord.TextChannel:
|
||||||
return self.guild.get_channel(self.get_votes_channel_id())
|
return self.guild.get_channel(self.get_votes_channel_id())
|
||||||
|
|
||||||
|
@game_started
|
||||||
|
def get_gm_channel_id(self) -> int:
|
||||||
|
return self.config["admin_chan"]
|
||||||
|
|
||||||
|
@game_started
|
||||||
|
def get_gm_channel(self) -> discord.TextChannel:
|
||||||
|
return self.guild.get_channel(self.get_gm_channel_id())
|
||||||
|
|
||||||
@game_started
|
@game_started
|
||||||
def is_vote_running(self) -> bool:
|
def is_vote_running(self) -> bool:
|
||||||
return self.config["vote"] is not None
|
return self.config["vote"] is not None
|
||||||
|
|
@ -143,6 +158,11 @@ class Game:
|
||||||
self.config["players"] = [member.id for member in player_role.members]
|
self.config["players"] = [member.id for member in player_role.members]
|
||||||
self.config["player_info"] = {str(player): {} for player in self.config["players"]}
|
self.config["player_info"] = {str(player): {} for player in self.config["players"]}
|
||||||
self.config["vote"] = None
|
self.config["vote"] = None
|
||||||
|
self.config["deck"] = [Policy.FASCIST.value] * 11 + [Policy.LIBERAL.value] * 6
|
||||||
|
random.shuffle(self.config["deck"])
|
||||||
|
self.config["discard"] = []
|
||||||
|
self.config["drawn"] = None
|
||||||
|
self.config["enacted"] = []
|
||||||
|
|
||||||
permissions = {
|
permissions = {
|
||||||
self.guild.default_role: discord.PermissionOverwrite(send_messages = False),
|
self.guild.default_role: discord.PermissionOverwrite(send_messages = False),
|
||||||
|
|
@ -266,3 +286,28 @@ class Game:
|
||||||
await self.get_announcements_channel().send("\n".join(announcement_content), allowed_mentions = discord.AllowedMentions(roles = True))
|
await self.get_announcements_channel().send("\n".join(announcement_content), allowed_mentions = discord.AllowedMentions(roles = True))
|
||||||
self.config["vote"] = None
|
self.config["vote"] = None
|
||||||
self.save_function()
|
self.save_function()
|
||||||
|
|
||||||
|
@game_started
|
||||||
|
async def draw_policies(self) -> List[Policy]:
|
||||||
|
self.config["drawn"] = [self.config["deck"].pop() for _ in range(3)]
|
||||||
|
self.save_function()
|
||||||
|
return [Policy(p) for p in self.config["drawn"]]
|
||||||
|
|
||||||
|
async def enact_drawn_policy(self, index: int):
|
||||||
|
if self.config["drawn"] is None:
|
||||||
|
raise RuntimeError("Can only enact a policy when they have been drawn")
|
||||||
|
if not (0 <= index < len(self.config["drawn"])):
|
||||||
|
raise IndexError(f"Expected policy index between 0 and {len(self.config['drawn'])}, got {index}")
|
||||||
|
for i, policy_str in enumerate(self.config["drawn"]):
|
||||||
|
if i == index:
|
||||||
|
self.config["enacted"].append(policy_str)
|
||||||
|
else:
|
||||||
|
self.config["discard"].append(policy_str)
|
||||||
|
self.config["drawn"] = None
|
||||||
|
if len(self.config["deck"]) < 3:
|
||||||
|
self.config["deck"].extend(self.config["discard"])
|
||||||
|
self.config["discard"] = []
|
||||||
|
random.shuffle(self.config["deck"])
|
||||||
|
self.save_function()
|
||||||
|
enacted = Policy(self.config["enacted"][-1])
|
||||||
|
await self.get_announcements_channel().send(f"{self.get_player_role().mention} A **{enacted.name}** policy has been enacted!")
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1,2 @@
|
||||||
from .Game import Game
|
from .Game import Game, Policy
|
||||||
from .GamesFile import GamesFile
|
from .GamesFile import GamesFile
|
||||||
|
|
|
||||||
28
SecretBot.py
28
SecretBot.py
|
|
@ -9,7 +9,7 @@ import discord.utils
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
|
|
||||||
import utils
|
import utils
|
||||||
from GameFiles import Game, GamesFile
|
from GameFiles import Game, GamesFile, Policy
|
||||||
|
|
||||||
logger = logging.getLogger("SecretBot")
|
logger = logging.getLogger("SecretBot")
|
||||||
|
|
||||||
|
|
@ -174,6 +174,32 @@ class SecretBot(commands.Cog):
|
||||||
await game.stop_vote()
|
await game.stop_vote()
|
||||||
await ctx.message.delete()
|
await ctx.message.delete()
|
||||||
|
|
||||||
|
@commands.command("Legislate")
|
||||||
|
async def draw_policies(self, ctx: commands.Context):
|
||||||
|
game = await self.get_running_game_or_error_message(ctx)
|
||||||
|
await self.check_is_administrator_or_gm(ctx)
|
||||||
|
if ctx.channel != game.get_gm_channel():
|
||||||
|
await ctx.reply(":warning: You should do this in your own channel!")
|
||||||
|
return
|
||||||
|
policies = await game.draw_policies()
|
||||||
|
message_content = [
|
||||||
|
"The following policies have been drawn:",
|
||||||
|
" ".join([f"{num + 1}) {':blue_square:' if policy == Policy.LIBERAL else ':red_square:'} " for num, policy in enumerate(policies)]),
|
||||||
|
"Send them to the president and chancellor and type `!Enact <number>` to enact one of them when you are finished"
|
||||||
|
]
|
||||||
|
await ctx.reply("\n".join(message_content))
|
||||||
|
|
||||||
|
@commands.command("Enact")
|
||||||
|
async def enact_drawn_policy(self, ctx: commands.Context, policy_number: int):
|
||||||
|
game = await self.get_running_game_or_error_message(ctx)
|
||||||
|
await self.check_is_administrator_or_gm(ctx)
|
||||||
|
if ctx.channel != game.get_gm_channel():
|
||||||
|
await ctx.reply(":warning: You should do this in your own channel!")
|
||||||
|
return
|
||||||
|
policy_number = policy_number - 1
|
||||||
|
await game.enact_drawn_policy(policy_number)
|
||||||
|
await ctx.reply(":white_check_mark: Done")
|
||||||
|
|
||||||
|
|
||||||
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)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue