Compare commits
9 Commits
266b2fe81f
...
812ae8a990
Author | SHA1 | Date |
---|---|---|
Bibin Muttappillil | 812ae8a990 | |
Bibin Muttappillil | e7b37217f9 | |
Bibin Muttappillil | 54f8eaf4c2 | |
Bibin Muttappillil | 13064a3af0 | |
Bibin Muttappillil | b85c20b65a | |
Bibin Muttappillil | eff057da8c | |
Bibin Muttappillil | 9cdc8d742c | |
Bibin Muttappillil | a4652642d1 | |
Bibin Muttappillil | ec446785ee |
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,62 @@
|
|||
import discord
|
||||
from discord.ext import commands
|
||||
|
||||
|
||||
class Developer(commands.Cog):
|
||||
"""This class is intended only for the developer, mainly for testing purposes"""
|
||||
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
|
||||
@commands.Cog.listener()
|
||||
async def on_ready(self):
|
||||
await self.bot.change_presence(status=discord.Status.online, activity=discord.Game('One Night Ultimate Werewolf'))
|
||||
print('We have logged in as {0.user}'.format(self.bot))
|
||||
|
||||
async def is_dev(ctx):
|
||||
if ctx.author.id == 461892912821698562:
|
||||
return True
|
||||
await ctx.send("This command is not for you!")
|
||||
return False
|
||||
|
||||
@commands.command()
|
||||
async def hello(self, ctx):
|
||||
await ctx.send(f"Hello {ctx.message.author.name} :wave:")
|
||||
|
||||
@commands.group(name="gg")
|
||||
async def group(self, ctx):
|
||||
pass
|
||||
|
||||
@group.command()
|
||||
@commands.check(is_dev)
|
||||
async def ping(self, ctx):
|
||||
await ctx.send("pong")
|
||||
|
||||
@commands.command()
|
||||
@commands.check(is_dev)
|
||||
async def logout(self, ctx):
|
||||
await self.bot.logout()
|
||||
|
||||
@commands.command()
|
||||
@commands.check(is_dev)
|
||||
async def debug(self, ctx, *args):
|
||||
embed = discord.Embed(title=f"Village won!", color=0x00ffff)
|
||||
won_emoji = ":trophy:"
|
||||
dead_emoji = ":test:"
|
||||
tab = "\t"
|
||||
space = "<:space:705863033871663185>"
|
||||
embed.add_field(name=str("Name"), value=f"{won_emoji}{space}{dead_emoji}{space}{space}{3}:ballot_box:{tab}role: werewolf{tab}(was: drunk){tab}:point_right: someone", inline=False)
|
||||
await ctx.send(embed=embed)
|
||||
await ctx.send(":test::skull:")
|
||||
|
||||
for emoji in ctx.guild.emojis:
|
||||
await ctx.send(emoji)
|
||||
print(emoji.id)
|
||||
|
||||
@debug.error
|
||||
async def debug_error(self, ctx, error):
|
||||
await ctx.send(error)
|
||||
|
||||
|
||||
def setup(bot):
|
||||
bot.add_cog(Developer(bot))
|
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,20 @@
|
|||
from abc import ABC
|
||||
|
||||
|
||||
class Game(ABC):
|
||||
|
||||
@classmethod
|
||||
def name(cls):
|
||||
return "Game"
|
||||
|
||||
def __init__(self, bot, channel):
|
||||
self.bot = bot
|
||||
self.channel = channel
|
||||
self.running = False
|
||||
self.player_list = []
|
||||
|
||||
async def round(self):
|
||||
pass
|
||||
|
||||
async def set_players(self):
|
||||
pass
|
|
@ -0,0 +1,78 @@
|
|||
"""Has a single class: Game_cog"""
|
||||
|
||||
# standard library imports
|
||||
from typing import Dict, Type
|
||||
|
||||
# discord imports
|
||||
import discord
|
||||
|
||||
# local imports
|
||||
from ..send_message import Send_message
|
||||
from .game import Game
|
||||
|
||||
|
||||
class Game_cog(Send_message):
|
||||
"""This (abstract) class is are common function for the Game Cog's (setup-game, pre-game, in-game), mainly has checker functions"""
|
||||
|
||||
def __init__(self, bot, game_cls: Type[Game]):
|
||||
self.bot = bot
|
||||
self.game_cls = game_cls
|
||||
self.game_instances = Dict[discord.TextChannel, self.game_cls]
|
||||
|
||||
async def setup_check(self, ctx):
|
||||
if ctx.channel not in self.game_instances:
|
||||
await self.send_wrong(ctx, f"The channel is not setup yet.")
|
||||
return ctx.channel in self.game_instances
|
||||
|
||||
async def not_running_check(self, ctx):
|
||||
if self.game_instances[ctx.channel].running:
|
||||
await self.send_wrong(ctx, "Sorry! A game is already running")
|
||||
return not self.game_instances[ctx.channel].running
|
||||
|
||||
async def running_check(self, ctx):
|
||||
if not self.game_instances[ctx.channel].running:
|
||||
await self.send_wrong(ctx, "No game is running")
|
||||
return self.game_instances[ctx.channel].running
|
||||
|
||||
async def setup(self, ctx):
|
||||
"""This function creates an game instance for this channel"""
|
||||
if ctx.channel in self.game_instances:
|
||||
await self.send_wrong(ctx, f"A game '{self.game_cls.name()}' is already setup in this channel")
|
||||
else:
|
||||
self.game_instances[ctx.channel] = self.game_cls(self.bot, ctx.channel)
|
||||
await self.send_friendly(ctx, f"This channel can now play: {self.game_cls.name()}")
|
||||
|
||||
async def reset(self, ctx):
|
||||
"""This function deletes the game instance for this channel"""
|
||||
if self.setup_check(ctx):
|
||||
del self.game_instances[ctx.channel]
|
||||
|
||||
# TODO: better info message
|
||||
async def info(self, ctx):
|
||||
"""Send information about the subcommands for the game"""
|
||||
embed = discord.Embed(title="How to play?", description="You will need to set up the game and its information in a channel and start the game there. Afterwards the player mainly interact with the bot in DM.", color=0x00ffff)
|
||||
embed.set_author(name=f"With this bot you can play {self.game_cls.name()}")
|
||||
# embed.set_thumbnail(url="https://images-na.ssl-images-amazon.com/images/I/717GrDtFKCL._AC_SL1000_.jpg")
|
||||
embed.add_field(name="$w game setup", value="Make this channel playable.", inline=False)
|
||||
embed.add_field(name="$w game players", value="Set mentioned users as players", inline=False)
|
||||
embed.add_field(name="$w game roles", value="Set the roles to play with", inline=False)
|
||||
embed.add_field(name="$w game start", value="Play one round", inline=False)
|
||||
embed.set_footer(text="Have fun!")
|
||||
await ctx.send(embed=embed)
|
||||
|
||||
async def pre_game_check(self, ctx):
|
||||
return self.setup_check(ctx) and self.not_running_check(ctx)
|
||||
|
||||
async def players(self, ctx):
|
||||
await self.game_instances[ctx.channel].set_players(ctx.message)
|
||||
|
||||
async def start(self, ctx):
|
||||
self.game_instances[ctx.channel].game = self.bot.loop.create_task(self.game_instances[ctx.channel].round())
|
||||
await self.game_instances[ctx.channel].game
|
||||
|
||||
async def in_game_check(self, ctx):
|
||||
return self.setup_check(ctx) and self.running_check(ctx)
|
||||
|
||||
async def stop(self, ctx):
|
||||
self.game_instances[ctx.channel].game.cancel()
|
||||
await self.send_friendly(ctx, "Game canceled")
|
|
@ -1,33 +1,30 @@
|
|||
"""Has a single class: Player"""
|
||||
|
||||
# discord imports
|
||||
import discord
|
||||
|
||||
|
||||
class Player:
|
||||
"""This (abstract) class is a template for player objects for games"""
|
||||
|
||||
@staticmethod
|
||||
async def make(member, game):
|
||||
p = Player()
|
||||
@classmethod
|
||||
async def make(cls, member, game):
|
||||
p = cls()
|
||||
p.member = member
|
||||
p.dm = member.dm_channel or await member.create_dm()
|
||||
p.game = game
|
||||
return p
|
||||
|
||||
def setRole(self, role):
|
||||
self.day_role = self.night_role = role
|
||||
|
||||
def reset(self):
|
||||
self.tally = 0
|
||||
self.won = self.dead = False
|
||||
|
||||
def name(self):
|
||||
return self.member.name
|
||||
|
||||
def __str__(self):
|
||||
return self.name()
|
||||
|
||||
def swap(self, player_B):
|
||||
self.day_role, player_B.day_role = player_B.day_role, self.day_role
|
||||
def reset(self):
|
||||
pass
|
||||
|
||||
def other(self):
|
||||
def other_players(self):
|
||||
return [p for p in self.game.player_list if p != self]
|
||||
|
||||
async def send_normal(self, message):
|
||||
|
@ -45,21 +42,24 @@ class Player:
|
|||
async def send_info(self, message):
|
||||
await self.send_embed(message, 0x00ffff)
|
||||
|
||||
# TODO: refactor this function to make it understandable
|
||||
async def ask_choice(self, question, options):
|
||||
text = f"{question}\n" + f"{'='*len(question)}\n\n" + '\n'.join(f"[{str(i)}]({str(options[i])})" for i in range(len(options)))
|
||||
await self.dm.send(f"```md\n{text}```")
|
||||
|
||||
# TODO: Basic Converters (https://discordpy.readthedocs.io/en/latest/ext/commands/commands.html#basic-converters)
|
||||
def check_num(self, choice, N):
|
||||
if not choice.isdigit():
|
||||
raise ValueError(f"Your choice {choice} is not a number")
|
||||
if not 0 <= int(choice) < N:
|
||||
raise ValueError(f"Your choice {choice} is not in range 0 - {N-1}")
|
||||
|
||||
# TODO: seems hacky, figure out a nicer way
|
||||
async def receive_choice(self, options, n_ans=1):
|
||||
while True:
|
||||
def check(choice):
|
||||
return choice.channel == self.dm and choice.author == self.member
|
||||
choice = (await self.game.bot.wait_for('message', timeout=30.0, check=check)).content.split()
|
||||
choice = (await self.game.bot.wait_for('message', check=check)).content.split()
|
||||
|
||||
if not len(choice) == n_ans:
|
||||
await self.send_wrong(f"Please give {n_ans} numbers not {len(choice)}")
|
||||
|
@ -77,21 +77,3 @@ class Player:
|
|||
async def get_choice(self, question, options):
|
||||
await self.ask_choice(question, options)
|
||||
return (await self.receive_choice(options))[0]
|
||||
|
||||
async def get_double_choice(self, question, options):
|
||||
await self.ask_choice(question, options)
|
||||
return await self.receive_choice(options, 2)
|
||||
|
||||
async def cast_vote(self, question, options):
|
||||
self.vote = options[await self.get_choice(question, options)]
|
||||
|
||||
async def ready_to_vote(self):
|
||||
def check(msg):
|
||||
return msg.channel == self.dm and msg.author == self.member and msg.content.casefold() == "vote"
|
||||
await self.game.bot.wait_for('message', check=check)
|
||||
await self.send_confirmation("You are ready to vote")
|
||||
|
||||
|
||||
class No_player(Player):
|
||||
def name(self):
|
||||
return "no one"
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,54 @@
|
|||
"""Has a single class: Werewolf_Cog"""
|
||||
|
||||
# discord imports
|
||||
from discord.ext import commands
|
||||
|
||||
# local imports
|
||||
from ..game_cog import Game_cog
|
||||
from .game import Werewolf_game
|
||||
|
||||
|
||||
class Werewolf_cog(Game_cog, commands.Cog):
|
||||
"""This singleton class is a Discord Cog for the interaction in the werewolf game"""
|
||||
|
||||
@commands.group(invoke_without_command=True)
|
||||
async def werewolf(self, ctx):
|
||||
# TODO: isn't there a better way to have a default subcommand? Maybe invoke super().info()?
|
||||
await ctx.invoke(self.bot.get_command('werewolf info'))
|
||||
|
||||
@werewolf.command()
|
||||
async def info(self, ctx):
|
||||
"""Send information about the subcommands for the game"""
|
||||
await super().info(ctx, Werewolf_game)
|
||||
|
||||
@werewolf.command()
|
||||
async def setup(self, ctx):
|
||||
"""This function creates an game instance for this channel"""
|
||||
await super().setup(ctx, Werewolf_game)
|
||||
|
||||
@werewolf.command()
|
||||
async def reset(self, ctx):
|
||||
"""This function deletes the game instance for this channel"""
|
||||
await super().reset(ctx)
|
||||
|
||||
@werewolf.command()
|
||||
@commands.check(Game_cog.pre_game_check)
|
||||
async def players(self, ctx):
|
||||
"""registers all mentioned players for the game"""
|
||||
await super().players(ctx)
|
||||
|
||||
@werewolf.command()
|
||||
@commands.check(Game_cog.pre_game_check)
|
||||
async def start(self, ctx):
|
||||
"""starts a round of werewolf"""
|
||||
await super().start(ctx)
|
||||
|
||||
@werewolf.command()
|
||||
@commands.check(Game_cog.in_game_check)
|
||||
async def stop(self, ctx):
|
||||
"""aborts the current round of werewolf"""
|
||||
await super().stop(ctx)
|
||||
|
||||
|
||||
def setup(bot):
|
||||
bot.add_cog(Werewolf_cog(bot, Werewolf_game))
|
|
@ -2,11 +2,15 @@ from random import shuffle
|
|||
import time
|
||||
import asyncio
|
||||
import discord
|
||||
from werewolf_roles import Role, Doppelganger, Werewolf, Minion, Mason, Seer, Robber, Troublemaker, Drunk, Insomniac, Tanner, Hunter, No_role
|
||||
from werewolf_players import Player, No_player
|
||||
from .roles import Role, Doppelganger, Werewolf, Minion, Mason, Seer, Robber, Troublemaker, Drunk, Insomniac, Tanner, Hunter, No_role
|
||||
from .players import Player, No_player
|
||||
|
||||
|
||||
class Game:
|
||||
class Werewolf_game:
|
||||
|
||||
@classmethod
|
||||
def name(cls):
|
||||
return "One Night Ultimate Werewolf"
|
||||
|
||||
def __init__(self, bot, channel):
|
||||
self.running = False
|
||||
|
@ -14,7 +18,7 @@ class Game:
|
|||
self.channel = channel
|
||||
self.player_list = []
|
||||
self.role_list = []
|
||||
self.discussion_time = 300 # seconds
|
||||
self.discussion_time = 301 # seconds
|
||||
|
||||
async def send(self, message):
|
||||
await self.channel.send(embed=discord.Embed(description=message, color=0x00ffff))
|
||||
|
@ -69,6 +73,7 @@ class Game:
|
|||
await self.for_all_player(lambda p: p.send_info(f"Your role: **{p.night_role.name()}**"))
|
||||
|
||||
async def night_phases(self):
|
||||
# TODO: implement waiting if role in middle
|
||||
await asyncio.gather(*[self.role[r].query() for r in [Doppelganger, Seer, Robber, Troublemaker, Drunk]]) # slow
|
||||
await self.role[Doppelganger].send_copy_info()
|
||||
await self.role[Doppelganger].simulate() # slow
|
|
@ -0,0 +1,39 @@
|
|||
import discord
|
||||
|
||||
"""Has a single class: Werewolf_player"""
|
||||
|
||||
# local import
|
||||
from .player import Player
|
||||
|
||||
|
||||
class Werewolf_player(Player):
|
||||
"""This class is for simulating non-role-specific werewolf players"""
|
||||
|
||||
def set_role(self, role):
|
||||
self.day_role = self.night_role = role
|
||||
|
||||
def reset(self):
|
||||
self.tally = 0
|
||||
self.won = self.dead = False
|
||||
|
||||
def swap(self, player_B):
|
||||
self.day_role, player_B.day_role = player_B.day_role, self.day_role
|
||||
|
||||
async def get_double_choice(self, question, options):
|
||||
await self.ask_choice(question, options)
|
||||
return await self.receive_choice(options, 2)
|
||||
|
||||
async def cast_vote(self, question, options):
|
||||
self.vote = options[await self.get_choice(question, options)]
|
||||
|
||||
async def ready_to_vote(self):
|
||||
def check(msg):
|
||||
return msg.channel == self.dm and msg.author == self.member and msg.content.casefold() == "vote"
|
||||
await self.game.bot.wait_for('message', check=check)
|
||||
await self.send_confirmation("You are ready to vote")
|
||||
|
||||
|
||||
# TODO: this seems hacky, find another approach
|
||||
class No_player(Werewolf_player):
|
||||
def name(self):
|
||||
return "no one"
|
|
@ -1,6 +1,6 @@
|
|||
import functools
|
||||
from fuzzywuzzy import fuzz
|
||||
from werewolf_players import No_player
|
||||
from .players import No_player
|
||||
|
||||
|
||||
class Role:
|
||||
|
@ -45,28 +45,33 @@ class Doppelganger(Role):
|
|||
@Role.no_player
|
||||
async def send_copy_info(self):
|
||||
self.copy_role = type(self.player.other()[self.choice].day_role)
|
||||
await self.send_info(f"You copied: {self.copy_role}")
|
||||
await self.player.send_info(f"You copied: {self.copy_role.name()}")
|
||||
|
||||
@Role.no_player
|
||||
async def simulate(self):
|
||||
if self.copy_role in [Werewolf, Mason]:
|
||||
self.copy_role.add_yourself(self)
|
||||
if self.copy_role == Werewolf:
|
||||
await self.copy_role.phase(self)
|
||||
if self.copy_role in [Mason, Minion]:
|
||||
await self.copy_role.send_info(self)
|
||||
|
||||
if self.copy_role in [Seer, Robber, Troublemaker, Drunk]:
|
||||
elif self.copy_role in [Seer, Robber, Troublemaker, Drunk]:
|
||||
await self.copy_role.query(self)
|
||||
if self.copy_role in [Robber, Troublemaker, Drunk]:
|
||||
self.copy_role.simulate(self)
|
||||
await self.copy_role.simulate(self)
|
||||
if self.copy_role in [Seer, Robber]:
|
||||
await self.copy_role.send_info(self)
|
||||
|
||||
@Role.no_player
|
||||
async def phase(self):
|
||||
if self.copy_role == Werewolf:
|
||||
await self.copy_role.phase(self)
|
||||
|
||||
@Role.no_player
|
||||
async def send_info(self):
|
||||
if self.copy_role in [Mason, Minion]:
|
||||
await self.copy_role.send_info(self)
|
||||
|
||||
@Role.no_player
|
||||
async def insomniac(self):
|
||||
if self.copy_role == Insomniac:
|
||||
self.copy_role.send_info(self)
|
||||
await self.copy_role.send_info(self)
|
||||
|
||||
def is_role(self, cls):
|
||||
return self.copy_role == cls
|
||||
|
@ -113,10 +118,10 @@ class Seer(Role):
|
|||
@Role.no_player
|
||||
async def send_info(self):
|
||||
if self.choice < len(self.player.other()):
|
||||
await self.player.send_info(self.player.other()[self.choice].night_role)
|
||||
await self.player.send_info(f"You saw: {self.player.other()[self.choice].night_role.name()}")
|
||||
else:
|
||||
a, b = [(0, 1), (1, 2), (0, 2)][self.choice - len(self.player.other())]
|
||||
await self.player.send_info(f"{self.game.middle_card[a]} {self.game.middle_card[b]}")
|
||||
await self.player.send_info(f"You saw: {self.game.middle_card[a]} {self.game.middle_card[b]}")
|
||||
|
||||
|
||||
class Robber(Role):
|
||||
|
@ -130,7 +135,7 @@ class Robber(Role):
|
|||
|
||||
@Role.no_player
|
||||
async def send_info(self):
|
||||
await self.player.send_info(f"You robbed: {self.player.day_role}")
|
||||
await self.player.send_info(f"You robbed: {self.player.day_role.name()}")
|
||||
|
||||
|
||||
class Troublemaker(Role):
|
||||
|
@ -156,7 +161,7 @@ class Drunk(Role):
|
|||
class Insomniac(Role):
|
||||
@Role.no_player
|
||||
async def send_info(self):
|
||||
await self.player.send_info(f"You are: {self.player.day_role}")
|
||||
await self.player.send_info(f"You are: {self.player.day_role.name()}")
|
||||
|
||||
|
||||
class Villager(Role):
|
|
@ -0,0 +1,18 @@
|
|||
# discord import
|
||||
import discord
|
||||
|
||||
|
||||
class Send_message:
|
||||
"""This (abstract) class for sending formatted messages"""
|
||||
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
|
||||
async def send_embed(self, ctx, desc, color):
|
||||
await ctx.send(embed=discord.Embed(description=desc, color=color))
|
||||
|
||||
async def send_friendly(self, ctx, desc):
|
||||
await self.send_embed(ctx, desc, 0x00ff00)
|
||||
|
||||
async def send_wrong(self, ctx, desc):
|
||||
await self.send_embed(ctx, desc, 0xff8000)
|
|
@ -1,107 +1,43 @@
|
|||
"""
|
||||
This is the main module of the Discord Bot
|
||||
|
||||
Mainly loads the Cog's and starts the bot
|
||||
"""
|
||||
|
||||
__version__ = '0.3'
|
||||
__author__ = 'Bibin Muttappillil'
|
||||
|
||||
# standard library imports
|
||||
import os
|
||||
from dotenv import load_dotenv
|
||||
import functools
|
||||
import asyncio
|
||||
import discord
|
||||
|
||||
# discord imports
|
||||
from discord.ext import commands
|
||||
from werewolf_game import Game as Werewolf_Game
|
||||
|
||||
|
||||
# Token stuff
|
||||
load_dotenv()
|
||||
TOKEN = os.getenv('DISCORD_TOKEN')
|
||||
if TOKEN is None:
|
||||
print("Missing discord token!")
|
||||
exit(1)
|
||||
|
||||
bot = commands.Bot(command_prefix=commands.when_mentioned_or('$w '))
|
||||
|
||||
PREFIX = '$w '
|
||||
bot = commands.Bot(command_prefix=commands.when_mentioned_or(PREFIX))
|
||||
bot.remove_command('help')
|
||||
|
||||
|
||||
@bot.event
|
||||
async def on_ready():
|
||||
await bot.change_presence(status=discord.Status.online, activity=discord.Game('One Night Ultimate Werewolf'))
|
||||
print('We have logged in as {0.user}'.format(bot))
|
||||
bot.load_extension('package.developer')
|
||||
bot.load_extension('package.games.werewolf.cog')
|
||||
|
||||
|
||||
@bot.command()
|
||||
async def help(ctx):
|
||||
embed = discord.Embed(title="How to play?", description="You will need to set up the game and its information in a channel and start the game there. Afterwards the player mainly interact with the bot in DM.", color=0x00ffff)
|
||||
embed.set_author(name="With this bot you can play One Night Ultimate Werewolf")
|
||||
# embed.set_thumbnail(url="https://images-na.ssl-images-amazon.com/images/I/717GrDtFKCL._AC_SL1000_.jpg")
|
||||
embed.add_field(name="$w game setup", value="Make this channel playable.", inline=False)
|
||||
embed.add_field(name="$w game players", value="Set mentioned users as players", inline=False)
|
||||
embed.add_field(name="$w game roles", value="Set the roles to play with", inline=False)
|
||||
embed.add_field(name="$w game start", value="Play one round", inline=False)
|
||||
embed.set_footer(text="Have fun!")
|
||||
await ctx.send(embed=embed)
|
||||
@commands.is_owner()
|
||||
async def reload(ctx, extension):
|
||||
bot.reload_extension(f'package.{extension}')
|
||||
|
||||
|
||||
async def send_embed(ctx, desc, color):
|
||||
await ctx.send(embed=discord.Embed(description=desc, color=color))
|
||||
|
||||
|
||||
async def send_friendly(ctx, desc):
|
||||
await send_embed(ctx, desc, 0x00ff00)
|
||||
|
||||
|
||||
async def send_wrong(ctx, desc):
|
||||
await send_embed(ctx, desc, 0xff8000)
|
||||
|
||||
|
||||
# game commands
|
||||
|
||||
game_instances = {}
|
||||
|
||||
|
||||
@bot.group()
|
||||
async def game(ctx):
|
||||
if ctx.invoked_subcommand is None:
|
||||
await send_wrong(ctx, 'Invalid sub command passed...')
|
||||
|
||||
|
||||
@game.command()
|
||||
async def setup(ctx):
|
||||
if ctx.channel in game_instances:
|
||||
await send_wrong(ctx, "Game already setup in this channel")
|
||||
else:
|
||||
game_instances[ctx.channel] = Werewolf_Game(bot, ctx.channel)
|
||||
await send_friendly(ctx, "This channel can now play Werewolf")
|
||||
|
||||
|
||||
def channel_setup(command):
|
||||
@functools.wraps(command)
|
||||
async def wrapper(ctx, *args, **kwargs):
|
||||
if ctx.channel not in game_instances:
|
||||
await send_wrong(ctx, f"No game setup yet. Use {PREFIX}game setup")
|
||||
else:
|
||||
await command(ctx, *args, **kwargs)
|
||||
return wrapper
|
||||
|
||||
|
||||
def game_not_running(command):
|
||||
@functools.wraps(command)
|
||||
@channel_setup
|
||||
async def wrapper(ctx, *args, **kwargs):
|
||||
if game_instances[ctx.channel].running:
|
||||
await send_wrong(ctx, "Sorry! A game is already running")
|
||||
else:
|
||||
await command(ctx, *args, **kwargs)
|
||||
return wrapper
|
||||
|
||||
|
||||
def game_running(command):
|
||||
@functools.wraps(command)
|
||||
@channel_setup
|
||||
async def wrapper(ctx, *args, **kwargs):
|
||||
if not game_instances[ctx.channel].running:
|
||||
await send_wrong(ctx, "No game is running")
|
||||
else:
|
||||
await command(ctx, *args, **kwargs)
|
||||
return wrapper
|
||||
|
||||
# checker annotations
|
||||
# TODO: replace with discord.py error handling?
|
||||
|
||||
'''
|
||||
def error_handling(command):
|
||||
@functools.wraps(command)
|
||||
async def wrapper(ctx, *args, **kwargs):
|
||||
|
@ -112,30 +48,11 @@ def error_handling(command):
|
|||
except asyncio.TimeoutError:
|
||||
await send_wrong(ctx, "Error: I got bored waiting for your input")
|
||||
return wrapper
|
||||
'''
|
||||
|
||||
'''
|
||||
|
||||
@game.command()
|
||||
@game_not_running
|
||||
@error_handling
|
||||
async def start(ctx):
|
||||
game_instances[ctx.channel].game = bot.loop.create_task(game_instances[ctx.channel].round())
|
||||
await game_instances[ctx.channel].game
|
||||
|
||||
|
||||
@game.command()
|
||||
@game_running
|
||||
@channel_setup
|
||||
async def stop(ctx):
|
||||
game_instances[ctx.channel].game.cancel()
|
||||
await send_friendly(ctx, "Game canceled")
|
||||
|
||||
|
||||
@game.command()
|
||||
@game_not_running
|
||||
@error_handling
|
||||
async def players(ctx):
|
||||
await game_instances[ctx.channel].set_players(ctx.message)
|
||||
|
||||
# TODO: (specifig game) werewolf COG
|
||||
|
||||
@game.command()
|
||||
@game_not_running
|
||||
|
@ -156,45 +73,6 @@ async def minutes(ctx, i):
|
|||
@error_handling
|
||||
async def time(ctx):
|
||||
await send_friendly(ctx, game_instances[ctx.channel].remaining_time_string())
|
||||
|
||||
|
||||
# smaller commands
|
||||
|
||||
@bot.command()
|
||||
async def hello(ctx):
|
||||
await send_friendly(ctx, f"Hello {ctx.message.author.name} :wave:")
|
||||
|
||||
|
||||
@bot.command()
|
||||
async def ping(ctx):
|
||||
print("pong")
|
||||
await send_friendly(ctx, "pong")
|
||||
|
||||
|
||||
# developer commands
|
||||
|
||||
def developer(command):
|
||||
@functools.wraps(command)
|
||||
async def wrapper(ctx, *args, **kwargs):
|
||||
DEV_ID = 461892912821698562
|
||||
if ctx.author.id == DEV_ID:
|
||||
await command(ctx, *args, **kwargs)
|
||||
else:
|
||||
await send_wrong(ctx, "This command is not for you!")
|
||||
return wrapper
|
||||
|
||||
|
||||
@bot.command()
|
||||
@developer
|
||||
async def logout(ctx):
|
||||
await bot.logout()
|
||||
|
||||
|
||||
@bot.command()
|
||||
@developer
|
||||
async def debug(ctx, *args):
|
||||
print("DEBUG")
|
||||
print(ctx.args)
|
||||
print(ctx.kwargs)
|
||||
'''
|
||||
|
||||
bot.run(TOKEN)
|
||||
|
|
Loading…
Reference in New Issue