import datetime import discord import asyncio from funcs import logThis from enum import Enum minimumPlayers = 1 minimumPlayersWithAI = 5 class Team(Enum): Villager = 1 Werewolf = 2 class Role(): def __init__(self,team,isWerewolf=False,isSeer=False,isSorcerer=False): self.alive = True self.team = team self.isWerewolf = isWerewolf self.isSeer = isSeer self.isSorcerer = isSorcerer class VillagerRole(Role): def __init__(self): super().__init__(Team.Villager) class WerewolfRole(Role): def __init__(self): super.__init__(Team.Werewolf,isWerewolf=True) class SeerRole(Role): def __init__(self): super.__init__(Team.Villager,isSeer=True) class SorcererRole(Role): def __init__(self): super.__init__(Team.Werewolf,isSorcerer=True) class SorcererWerewolfRole(Role): def __init__(self): super.__init__(Team.Werewolf,isWerewolf=True,isSorcerer=True) class Werewolf(): def __init__(self,bot): self.bot = bot # Starts a game of werewolf def werewolfStart(self,channel:str): game = self.bot.database["werewolf games"].find_one({"_id":channel}) logThis("Trying to start a werewolf game in "+channel) if game == None: gameID = datetime.datetime.now().strftime('%Y%m%d%H%M%S') newGame = {"_id":channel,"users": {},"round":0,"turn":0,"turnOrder":[],"current message":None,"gameID":gameID} self.bot.database["werewolf games"].insert_one(newGame) return "Started a game of werewolf. Use \"!werewolf join\" to join the game", True else: logThis("There is already a werewolf game going on in "+channel) return "There's already a werewolf game going on in this channel. Try again in a few minutes.", False # Stops the game of werewolf def werewolfStop(self,channel:str): game = self.bot.database["werewolf games"].find_one({"_id":channel}) if game != None: self.bot.database["werewolf games"].delete_one({"_id":channel}) return "Ended the werewolf game" else: return "There's no game going on right now" def allotRoles(self,channel): game = self.bot.database["werewolf games"].find_one({"_id":channel}) players = len(game["users"]) async def werewolfLoop(self,ctx,round): logThis(f"Starting loop {round} of Werewolf game") channel = "#"+str(ctx.channel.id) if round == 0: await asyncio.sleep(90) game = self.bot.database["werewolf games"].find_one({"_id":channel}) if len(game["users"].keys()) >= minimumPlayers: while len(game["users"].keys()) < minimumPlayersWithAI: user = {"role": None} self.bot.database["werewolf games"].update_one({"_id":"#"+str(ctx.channel.id)}, {"$set":{"users."+self.bot.generator.nameGen()[:-1]+" (AI player)":user}}) game = self.bot.database["werewolf games"].find_one({"_id":channel}) if game["current message"] != None: await ctx.channel.fetch_message(game["current message"]).delete() users = "" for x, user in enumerate(list(game["users"].keys())): users += str(x+1)+") "+self.bot.funcs.getName(user)+"\n" em = discord.Embed(title="Game started with the following players:",description=users,colour=0x00FF00) oldMessage = await ctx.send(embed=em) self.bot.database["werewolf games"].update_one({"_id":channel},{"$set":{"current message":oldMessage.id}}) self.allotRoles(channel) self.bot.database["werewolf games"].update_one({"_id":channel},{"$inc":{"round":1}}) await self.werewolfLoop(ctx,round+1) else: ctx.send("Not enough players. Ending game.") self.werewolfStop("#"+str(ctx.channel.id)) else: await asyncio.sleep(30) async def werewolfJoin(self,ctx): currentGames = list(self.bot.database["werewolf games"].find({})) for game in currentGames: if "#"+str(ctx.message.author.id) in game["users"].keys(): return f"{ctx.message.author.display_name} is already in a werewolf game", False game = self.bot.database["werewolf games"].find_one({"_id":"#"+str(ctx.channel.id)}) if game["round"] == 0: user = {"role": None} self.bot.database["werewolf games"].update_one({"_id":"#"+str(ctx.channel.id)}, {"$set":{"users."+"#"+str(ctx.message.author.id):user}}) return "You joined the werewolf game", True else: return "It's too late to join", False async def parseWerewolf(self,ctx,content): if content == "start": response, started = self.werewolfStart("#"+str(ctx.channel.id)) await ctx.send(response) if started: await self.werewolfLoop(ctx,0) elif content == "stop": await ctx.send(self.werewolfStop("#"+str(ctx.channel.id))) elif content == "join": response, joined = await self.werewolfJoin(ctx) await ctx.send(response) if joined: game = self.bot.database["werewolf games"].find_one({"_id":"#"+str(ctx.channel.id)}) if game["current message"] != None: await ctx.channel.fetch_message(game["current message"]).delete() users = "" for x, user in enumerate(list(game["users"].keys())): users += str(x+1)+") "+self.bot.funcs.getName(user)+"\n" if len(list(game["users"].keys())) < minimumPlayers: users += f"You need at least {minimumPlayers} players to play werewolf." em = discord.Embed(title="Current Players",description=users,colour=0x00FF00) oldMessage = await ctx.send(embed=em) self.bot.database["werewolf games"].update_one({"_id":"#"+str(ctx.channel.id)},{"$set":{"current message":oldMessage.id}})