You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Fox-V3/werewolf/werewolf.py

177 lines
4.7 KiB

import asyncio
import discord
from discord.ext import commands
from redbot.core import Config
from werewolf.game import Game
class Werewolf:
"""
Base to host werewolf on a guild
"""
def __init__(self, bot):
self.bot = bot
self.config = Config.get_conf(self, identifier=87101114101119111108102, force_registration=True)
default_global = {}
default_guild = {
}
self.config.register_global(**default_global)
self.config.register_guild(**default_guild)
self.games = {} # Active games stored here, id is per guild
7 years ago
@commands.group()
async def ww(self, ctx: commands.Context):
"""
Base command for this cog. Check help for the commands list.
"""
if ctx.invoked_subcommand is None:
await ctx.send_help()
7 years ago
@commands.guild_only()
@ww.command()
7 years ago
async def new(self, ctx, game_code):
"""
7 years ago
Create and join a new game of Werewolf
"""
7 years ago
game = self._get_game(ctx.guild, game_code)
7 years ago
if not game:
await ctx.send("Failed to start a new game")
else:
await ctx.send("New game has started")
@commands.guild_only()
7 years ago
@ww.command()
async def join(self, ctx):
"""
Joins a game of Werewolf
"""
game = self._get_game(ctx.guild)
if not game:
await ctx.send("No game to join!\nCreate a new one with `[p]ww new`")
7 years ago
return
7 years ago
await game.join(ctx.author, ctx.channel)
7 years ago
@commands.guild_only()
@ww.command()
async def quit(self, ctx):
"""
Quit a game of Werewolf
"""
7 years ago
game = self._get_game(ctx.guild)
7 years ago
await game.quit(ctx.author, ctx.channel)
@commands.guild_only()
@ww.command()
async def start(self, ctx):
"""
Checks number of players and attempts to start the game
"""
7 years ago
game = self._get_game(ctx.guild)
if not game:
await ctx.send("No game running, cannot start")
await game.setup(ctx)
7 years ago
@commands.guild_only()
7 years ago
@ww.command()
async def stop(self, ctx):
"""
Stops the current game
"""
game = self._get_game(ctx.guild)
if not game:
await ctx.send("No game running, cannot stop")
game.game_over = True
@commands.guild_only()
7 years ago
@ww.command()
7 years ago
async def vote(self, ctx, id: int):
7 years ago
"""
Vote for a player by ID
"""
7 years ago
try:
id = int(id)
except:
id = None
if id is None:
await ctx.send("`id` must be an integer")
return
7 years ago
# if ctx.guild is None:
# # DM nonsense, find their game
# # If multiple games, panic
# for game in self.games.values():
# if await game.get_player_by_member(ctx.author):
# break #game = game
# else:
# await ctx.send("You're not part of any werewolf game")
# return
# else:
7 years ago
game = self._get_game(ctx.guild)
7 years ago
if game is None:
await ctx.send("No game running, cannot vote")
return
7 years ago
# Game handles response now
channel = ctx.channel
7 years ago
if channel == game.village_channel:
7 years ago
await game.vote(ctx.author, id, channel)
7 years ago
elif channel in (c["channel"] for c in game.p_channels.values()):
7 years ago
await game.vote(ctx.author, id, channel)
7 years ago
else:
await ctx.send("Nothing to vote for in this channel")
7 years ago
7 years ago
@ww.command()
async def choose(self, ctx, data):
"""
Arbitrary decision making
Handled by game+role
Can be received by DM
"""
7 years ago
7 years ago
if ctx.guild is not None:
await ctx.send("This action is only available in DM's")
return
# DM nonsense, find their game
# If multiple games, panic
for game in self.games.values():
if await game.get_player_by_member(ctx.author):
break # game = game
7 years ago
else:
await ctx.send("You're not part of any werewolf game")
return
await game.choose(ctx, data)
def _get_game(self, guild, game_code=None):
7 years ago
if guild is None:
# Private message, can't get guild
return None
7 years ago
if guild.id not in self.games:
7 years ago
if not game_code:
7 years ago
return None
self.games[guild.id] = Game(guild, game_code)
7 years ago
return self.games[guild.id]
async def _game_start(self, game):
await game.start()