Compare commits
No commits in common. "812ae8a9907f9c90d9f624e7ad423d52c4677a39" and "266b2fe81f935b7bce085690cce90000ea473251" have entirely different histories.
812ae8a990
...
266b2fe81f
18 changed files with 198 additions and 339 deletions
Binary file not shown.
Binary file not shown.
|
|
@ -1,62 +0,0 @@
|
|||
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.
|
|
@ -1,20 +0,0 @@
|
|||
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
|
||||
|
|
@ -1,78 +0,0 @@
|
|||
"""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")
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -1,54 +0,0 @@
|
|||
"""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))
|
||||
|
|
@ -1,39 +0,0 @@
|
|||
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,18 +0,0 @@
|
|||
# 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,43 +1,107 @@
|
|||
"""
|
||||
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
|
||||
|
||||
# discord imports
|
||||
import functools
|
||||
import asyncio
|
||||
import discord
|
||||
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 '))
|
||||
|
||||
bot.load_extension('package.developer')
|
||||
bot.load_extension('package.games.werewolf.cog')
|
||||
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.command()
|
||||
@commands.is_owner()
|
||||
async def reload(ctx, extension):
|
||||
bot.reload_extension(f'package.{extension}')
|
||||
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)
|
||||
|
||||
|
||||
# checker annotations
|
||||
# TODO: replace with discord.py error handling?
|
||||
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
|
||||
|
||||
|
||||
'''
|
||||
def error_handling(command):
|
||||
@functools.wraps(command)
|
||||
async def wrapper(ctx, *args, **kwargs):
|
||||
|
|
@ -48,11 +112,30 @@ def error_handling(command):
|
|||
except asyncio.TimeoutError:
|
||||
await send_wrong(ctx, "Error: I got bored waiting for your input")
|
||||
return wrapper
|
||||
'''
|
||||
|
||||
'''
|
||||
|
||||
# TODO: (specifig game) werewolf COG
|
||||
@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)
|
||||
|
||||
|
||||
@game.command()
|
||||
@game_not_running
|
||||
|
|
@ -73,6 +156,45 @@ 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)
|
||||
|
|
|
|||
|
|
@ -2,15 +2,11 @@ from random import shuffle
|
|||
import time
|
||||
import asyncio
|
||||
import discord
|
||||
from .roles import Role, Doppelganger, Werewolf, Minion, Mason, Seer, Robber, Troublemaker, Drunk, Insomniac, Tanner, Hunter, No_role
|
||||
from .players import Player, No_player
|
||||
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
|
||||
|
||||
|
||||
class Werewolf_game:
|
||||
|
||||
@classmethod
|
||||
def name(cls):
|
||||
return "One Night Ultimate Werewolf"
|
||||
class Game:
|
||||
|
||||
def __init__(self, bot, channel):
|
||||
self.running = False
|
||||
|
|
@ -18,7 +14,7 @@ class Werewolf_game:
|
|||
self.channel = channel
|
||||
self.player_list = []
|
||||
self.role_list = []
|
||||
self.discussion_time = 301 # seconds
|
||||
self.discussion_time = 300 # seconds
|
||||
|
||||
async def send(self, message):
|
||||
await self.channel.send(embed=discord.Embed(description=message, color=0x00ffff))
|
||||
|
|
@ -73,7 +69,6 @@ class Werewolf_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
|
||||
|
|
@ -1,30 +1,33 @@
|
|||
"""Has a single class: Player"""
|
||||
|
||||
# discord imports
|
||||
import discord
|
||||
|
||||
|
||||
class Player:
|
||||
"""This (abstract) class is a template for player objects for games"""
|
||||
|
||||
@classmethod
|
||||
async def make(cls, member, game):
|
||||
p = cls()
|
||||
@staticmethod
|
||||
async def make(member, game):
|
||||
p = Player()
|
||||
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 reset(self):
|
||||
pass
|
||||
def swap(self, player_B):
|
||||
self.day_role, player_B.day_role = player_B.day_role, self.day_role
|
||||
|
||||
def other_players(self):
|
||||
def other(self):
|
||||
return [p for p in self.game.player_list if p != self]
|
||||
|
||||
async def send_normal(self, message):
|
||||
|
|
@ -42,24 +45,21 @@ 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', check=check)).content.split()
|
||||
choice = (await self.game.bot.wait_for('message', timeout=30.0, check=check)).content.split()
|
||||
|
||||
if not len(choice) == n_ans:
|
||||
await self.send_wrong(f"Please give {n_ans} numbers not {len(choice)}")
|
||||
|
|
@ -77,3 +77,21 @@ 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"
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
import functools
|
||||
from fuzzywuzzy import fuzz
|
||||
from .players import No_player
|
||||
from werewolf_players import No_player
|
||||
|
||||
|
||||
class Role:
|
||||
|
|
@ -45,33 +45,28 @@ 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.player.send_info(f"You copied: {self.copy_role.name()}")
|
||||
await self.send_info(f"You copied: {self.copy_role}")
|
||||
|
||||
@Role.no_player
|
||||
async def simulate(self):
|
||||
if self.copy_role in [Werewolf, Mason]:
|
||||
self.copy_role.add_yourself(self)
|
||||
elif self.copy_role in [Seer, Robber, Troublemaker, Drunk]:
|
||||
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]:
|
||||
await self.copy_role.query(self)
|
||||
if self.copy_role in [Robber, Troublemaker, Drunk]:
|
||||
await self.copy_role.simulate(self)
|
||||
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:
|
||||
await self.copy_role.send_info(self)
|
||||
self.copy_role.send_info(self)
|
||||
|
||||
def is_role(self, cls):
|
||||
return self.copy_role == cls
|
||||
|
|
@ -118,10 +113,10 @@ class Seer(Role):
|
|||
@Role.no_player
|
||||
async def send_info(self):
|
||||
if self.choice < len(self.player.other()):
|
||||
await self.player.send_info(f"You saw: {self.player.other()[self.choice].night_role.name()}")
|
||||
await self.player.send_info(self.player.other()[self.choice].night_role)
|
||||
else:
|
||||
a, b = [(0, 1), (1, 2), (0, 2)][self.choice - len(self.player.other())]
|
||||
await self.player.send_info(f"You saw: {self.game.middle_card[a]} {self.game.middle_card[b]}")
|
||||
await self.player.send_info(f"{self.game.middle_card[a]} {self.game.middle_card[b]}")
|
||||
|
||||
|
||||
class Robber(Role):
|
||||
|
|
@ -135,7 +130,7 @@ class Robber(Role):
|
|||
|
||||
@Role.no_player
|
||||
async def send_info(self):
|
||||
await self.player.send_info(f"You robbed: {self.player.day_role.name()}")
|
||||
await self.player.send_info(f"You robbed: {self.player.day_role}")
|
||||
|
||||
|
||||
class Troublemaker(Role):
|
||||
|
|
@ -161,7 +156,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.name()}")
|
||||
await self.player.send_info(f"You are: {self.player.day_role}")
|
||||
|
||||
|
||||
class Villager(Role):
|
||||
Loading…
Add table
Add a link
Reference in a new issue