diff --git a/src/__pycache__/werewolf_game.cpython-37.pyc b/src/__pycache__/werewolf_game.cpython-37.pyc index e8e5524..dd64ba7 100644 Binary files a/src/__pycache__/werewolf_game.cpython-37.pyc and b/src/__pycache__/werewolf_game.cpython-37.pyc differ diff --git a/src/__pycache__/werewolf_players.cpython-37.pyc b/src/__pycache__/werewolf_players.cpython-37.pyc index bdcf3df..3c10399 100644 Binary files a/src/__pycache__/werewolf_players.cpython-37.pyc and b/src/__pycache__/werewolf_players.cpython-37.pyc differ diff --git a/src/__pycache__/werewolf_roles.cpython-37.pyc b/src/__pycache__/werewolf_roles.cpython-37.pyc index 121e3a5..58720c5 100644 Binary files a/src/__pycache__/werewolf_roles.cpython-37.pyc and b/src/__pycache__/werewolf_roles.cpython-37.pyc differ diff --git a/src/werewolf_bot.py b/src/werewolf_bot.py index c52ab07..c61c82e 100644 --- a/src/werewolf_bot.py +++ b/src/werewolf_bot.py @@ -1,8 +1,9 @@ import os -import discord -import asyncio from dotenv import load_dotenv - +import functools +import asyncio +import discord +from discord.ext import commands from werewolf_game import Game as Werewolf_Game @@ -12,54 +13,74 @@ if TOKEN is None: print("Missing discord token!") exit(1) -bot = discord.Client() +bot = commands.Bot(command_prefix=commands.when_mentioned_or('$werewolf ')) + @bot.event async def on_ready(): + await bot.change_presence(status=discord.Status.idle, activity=discord.Game('One Night Ultimate Werewolf')) print('We have logged in as {0.user}'.format(bot)) - -async def hello(message): - print("Hello") - await message.channel.send('Hello!:regional_indicator_a:') - - print(message.mentions) - @bot.event async def on_message(message): - - global running - if message.author == bot.user: return + await bot.process_commands(message) - if message.content.startswith('$hello'): - await hello(message) +@bot.group(help="werewolf game", description="Prefix for the One Night Ultimate Werewolf commands.") +async def game(ctx): + if ctx.invoked_subcommand is None: + await bot.say('Invalid sub command passed...') + + +@game.command(help="start werewolf game", description="Start One Night Ultimate Werewolf game.") +async def start(ctx): + if werewolf_game.running: + await ctx.message.channel.send("Sorry! A game is already running") return + werewolf_game.running = True + werewolf_game.set_channel(ctx.message.channel) - if message.content.startswith('$logout'): - await bot.logout() - return + await werewolf_game.game() - if message.content.startswith('$werewolf'): - - # start (only one instance running) - - if werewolf_game.running: - await message.channel.send("Sorry! A game is already running") - return - - werewolf_game.running = True - werewolf_game.set_channel(message.channel) +@bot.command(help="greets you", description="This just says hello back to the message author.") +async def hello(ctx): + await ctx.message.channel.send(f"Hello {ctx.message.author.name} :wave:") - await werewolf_game.game() +@bot.command(help="test bot responsiveness", description="This is a debug function to see if the bot listens to a command.") +async def ping(ctx): + print("pong") + await ctx.send("pong") + + +def developer(command): + @functools.wraps(command) + async def wrapper(ctx): + DEV_ID = 461892912821698562 + if ctx.message.author.id == DEV_ID: + await command(ctx) + else: + await ctx.send("This command is not for you!") + return wrapper + + +@bot.command(help="not for you", description="Shut down the bot.") +@developer +async def logout(ctx): + await bot.logout() + + +@bot.command(help="debug") +@developer +async def debug(ctx): + print("DEBUG") + print(ctx.message.author.id) - return werewolf_game = Werewolf_Game(bot) bot.run(TOKEN) diff --git a/src/werewolf_game.py b/src/werewolf_game.py index b01a931..e9e5d81 100644 --- a/src/werewolf_game.py +++ b/src/werewolf_game.py @@ -1,8 +1,9 @@ from random import shuffle import asyncio -from werewolf_roles import Role, Doppelganger, Werewolf, Minion, Mason, Seer, Robber, Troublemaker, Drunk, Insomniac, Villiager, Tanner, Hunter, No_role +from werewolf_roles import Role, Werewolf, Minion, Tanner, Hunter from werewolf_players import Player, No_player + class Game: def __init__(self, bot): @@ -11,26 +12,22 @@ class Game: self.player_list = [] self.role_list = Role.role_set - def set_channel(self, channel): self.channel = channel - async def send(self, message): await self.channel.send(message) - async def receive(self, command): def check(msg): return msg.channel == self.channel and msg.content.startswith(command) - return await self.bot.wait_for('message', check = check) + return await self.bot.wait_for('message', check=check) def setup(self): self.werewolf_list = [] self.mason_list = [] - async def set_players(self): await self.send("Who is playing?") @@ -47,7 +44,6 @@ class Game: # send confirmation await self.send("Players: " + ", ".join(p.name() for p in self.player_list)) - async def set_roles(self): await self.send("With which roles do you want to play?") msg = await self.receive('$roles') @@ -69,7 +65,6 @@ class Game: # send confirmation await self.send("Roles: " + ", ".join(r.name() for r in self.role_list)) - def distribute_roles(self): shuffle(self.role_list) for i in range(len(self.player_list)): @@ -77,21 +72,20 @@ class Game: self.role_list[i].setPlayer(self.player_list[i]) self.middle_card = self.role_list[-3:] - self.active_role = sorted(self.role_list[:-3], key = lambda x: x.order) #necessary? - + self.active_role = sorted(self.role_list[:-3], key=lambda x: x.order) async def start_night(self): - await asyncio.gather( *[p.send("The night has begun") for p in self.player_list] ) + await asyncio.gather(*[p.send("The night has begun") for p in self.player_list]) async def send_role(self): - await asyncio.gather( *[p.send("Your role: " + p.night_role.name()) for p in self.player_list] ) + await asyncio.gather(*[p.send("Your role: " + p.night_role.name()) for p in self.player_list]) async def night_phases(self): - await asyncio.gather( *[r.phase1() for r in self.active_role] ) - await asyncio.gather( *[r.phase2() for r in self.active_role] ) - await asyncio.gather( *[r.phase3() for r in self.active_role] ) - await asyncio.gather( *[r.phase4() for r in self.active_role] ) - await asyncio.gather( *[r.phase5() for r in self.active_role] ) + await asyncio.gather(*[r.phase1() for r in self.active_role]) + await asyncio.gather(*[r.phase2() for r in self.active_role]) + await asyncio.gather(*[r.phase3() for r in self.active_role]) + await asyncio.gather(*[r.phase4() for r in self.active_role]) + await asyncio.gather(*[r.phase5() for r in self.active_role]) async def start_day(self): await self.send("The day has started") @@ -102,7 +96,7 @@ class Game: await self.receive('$vote') await self.send("Vote in DM") - await asyncio.gather( *[p.cast_vote(options) for p in self.player_list] ) + await asyncio.gather(*[p.cast_vote(options) for p in self.player_list]) await self.send("Votes\n\n" + '\n'.join(str(p) + " :arrow_right: " + str(p.vote) for p in self.player_list)) @@ -187,7 +181,6 @@ class Game: def end(self): self.running = False - async def game(self): try: @@ -202,7 +195,7 @@ class Game: await self.night_phases() await self.start_day() - #discussion timer + # discussion timer options = self.player_list + [No_player(self)] await self.vote(options) diff --git a/src/werewolf_players.py b/src/werewolf_players.py index 9086772..2d88af0 100644 --- a/src/werewolf_players.py +++ b/src/werewolf_players.py @@ -1,3 +1,6 @@ +from werewolf_roles import No_role + + class Player: @staticmethod @@ -8,9 +11,8 @@ class Player: p.game = game return p - @staticmethod - def swap(player_A, player_B): - player_A.day_role, player_B.day_role = player_B.day_role, player_A.day_role + def swap(self, player_B): + self.day_role, player_B.day_role = player_B.day_role, self.day_role def setRole(self, role): self.night_role = role @@ -29,13 +31,13 @@ class Player: await self.dm.send(message) async def ask_choice(self, options): - await self.send('\n'.join( "(" + str(i) + ") " + str(options[i]) for i in range(len(options)) )) + await self.send('\n'.join("(" + str(i) + ") " + str(options[i]) for i in range(len(options)))) async def receive_choice(self, options): def check(choice): - return choice.channel == self.dm and choice.content.isdigit() and 0 <= int(choice.content) < len(options) + return choice.channel == self.dm and choice.content.isdigit() and 0 <= int(choice.content) < len(options) - return int((await self.game.bot.wait_for('message', timeout=30.0, check = check)).content) + return int((await self.game.bot.wait_for('message', timeout=30.0, check=check)).content) async def get_choice(self, options): await self.ask_choice(options) @@ -44,6 +46,7 @@ class Player: async def cast_vote(self, options): self.vote = options[await self.get_choice(options)] + class No_player(Player): def __init__(self): diff --git a/src/werewolf_roles.py b/src/werewolf_roles.py index 8d108cd..5185634 100644 --- a/src/werewolf_roles.py +++ b/src/werewolf_roles.py @@ -7,19 +7,19 @@ class Role: def setPlayer(self, player): self.player = player - async def phase1(self): # query stuff + doppelganger simulation + async def phase1(self): # query stuff + doppelganger simulation pass - async def phase2(self): # werewolf stuff + seer info + async def phase2(self): # werewolf stuff + seer info pass - async def phase3(self): # robber simulation & info + async def phase3(self): # robber simulation & info pass - async def phase4(self): # troublemaker simulation + async def phase4(self): # troublemaker simulation pass - async def phase5(self): # mostly sending info + drunk simulation + async def phase5(self): # mostly sending info + drunk simulation pass @staticmethod @@ -35,9 +35,11 @@ class Role: def __str__(self): return self.name() + class Doppelganger(Role): order = 1 + class Werewolf(Role): order = 2 @@ -107,9 +109,10 @@ class Robber(Role): self.choice = await self.player.get_choice(self.player.other()) async def phase3(self): - Player.swap(self.player, self.player.other()[self.choice]) + self.player.swap(self.player.other()[self.choice]) await self.player.send("You robbed: " + str(self.player.day_role)) + class Troublemaker(Role): order = 7 @@ -119,10 +122,11 @@ class Troublemaker(Role): self.B = await self.player.get_choice(self.player.other()) async def phase4(self): - Player.swap(self.player.other()[self.A], self.player.other()[self.B]) + self.player.other()[self.A].swap(self.player.other()[self.B]) # receive conformation await self.player.send("Received " + str(self.A) + " " + str(self.B)) + class Drunk(Role): order = 8 @@ -132,25 +136,31 @@ class Drunk(Role): async def phase5(self): self.player.day_role, self.game.middle_card[self.choice] = self.game.middle_card[self.choice], self.player.day_role - #receive conformation + # receive conformation await self.player.send("Received " + str(self.choice)) + class Insomniac(Role): order = 9 async def phase5(self): await self.player.send("You are now: " + str(self.player.day_role)) + class Villiager(Role): order = 10 + class Tanner(Role): order = 11 + class Hunter(Role): order = 12 + class No_role(Role): order = 1000 -Role.role_set = [Doppelganger, Werewolf, Minion, Mason, Seer, Robber, Troublemaker, Drunk, Insomniac, Villiager, Tanner, Hunter] \ No newline at end of file + +Role.role_set = [Doppelganger, Werewolf, Minion, Mason, Seer, Robber, Troublemaker, Drunk, Insomniac, Villiager, Tanner, Hunter]