diff --git a/werewolf/Game.py b/werewolf/Game.py index 68d5211..7c91037 100644 --- a/werewolf/Game.py +++ b/werewolf/Game.py @@ -51,9 +51,7 @@ class Game: ctx.send("Players does not match roles, cannot start") return False - - - + ############START Notify structure############ async def _cycle(self): """ Each event calls the next event @@ -151,7 +149,9 @@ class Game: # self.loop.create_task(role.on_event(event)) self.loop.run_until_complete(asyncio.gather(*tasks)) # Run same-priority task simultaneously - + + ############END Notify structure############ + async def generate_targets(self, channel): embed=discord.Embed(title="Remaining Players") for i in range(len(self.players)): @@ -160,23 +160,31 @@ class Game: status="" else: status="*Dead*" - embed.add_field(name="ID# **{}**".format(i), value="{} {}".format(status, player.member.display_name, inline=True) + embed.add_field(name="ID# **{}**".format(i), value="{} {}".format(status, player.member.display_name), inline=True) return await channel.send(embed=embed) - + async def register_channel(self, channel_id, votegroup = None): + # Create channel, set permissions, register votegroup + if channel_id not in self.secret_channels: + - + async def register_vote_group(self, channel_id, votegroup = None): + # Register channel and assign passed votegroup to it + if channel_id not in self.secret_channels: + await self.register_channel(channel_id, votegroup(self)) async def join(self, member: discord.Member, channel: discord.Channel): """ Have a member join a game """ if self.started: - return "**Game has already started!**" + await channel.send("**Game has already started!**") + return if member in self.players: - return "{} is already in the game!".format(member.mention) + await channel.send("{} is already in the game!".format(member.mention)) + return self.started.append(member) @@ -232,8 +240,12 @@ class Game: channel.send("Not a valid target") return + async def kill(self, target, source=None, method: str=None): + """ + Attempt to kill a target + Source allows admin override + """ - async def get_roles(self, game_code=None): if game_code: self.game_code=game_code diff --git a/werewolf/Roles/DefaultWerewolf.py b/werewolf/Roles/DefaultWerewolf.py deleted file mode 100644 index e05da2a..0000000 --- a/werewolf/Roles/DefaultWerewolf.py +++ /dev/null @@ -1,73 +0,0 @@ -import asyncio - -import discord - -from datetime import datetime,timedelta - -from cogs.werewolf.Role import Role - -from cogs.werewolf.VoteGroup import WolfVote - -class DefaultWerewolf(Role): - - rand_choice = True - category = [11, 15] - allignment = 2 # 1: Town, 2: Werewolf, 3: Neutral - channel_id = "werewolves" - unique = False - action_list = [ - (self._at_game_start, 0), # (Action, Priority) - (self._at_day_start, 0), - (self._at_voted, 0), - (self._at_kill, 0), - (self._at_hang, 0), - (self._at_day_end, 0), - (self._at_night_start, 2), - (self._at_night_end, 5) - ] - - def __init__(self, game): - self.game = game - self.player = None - self.blocked = False - self.properties = {} # Extra data for other roles (i.e. arsonist) - - async def _get_role(self, source=None): - """ - Interaction for powerful access of role - Unlikely to be able to deceive this - """ - return "Werewolf" - - async def _see_role(self, source=None): - """ - Interaction for investigative roles. - More common to be able to deceive these roles - """ - return "Werewolf" - - async def _at_game_start(self, data=None): - await self.game.register_vote_group(WolfVote(self.game), self.channel_id) - - super()._at_game_start(data) - - async def _at_day_start(self, data=None): - super()._at_day_start(data) - - async def _at_voted(self, data=None): - super()._at_voted(data) - - async def _at_kill(self, data=None): - super()._at_kill(data) - - async def _at_hang(self, data=None): - super()._at_hang(data) - - async def _at_day_end(self, data=None): - super()._at_day_end(data) - - async def _at_night_start(self, data=None): - super()._at_night_start(data) - - async def _at_night_end(self, data=None): - super()._at_night_end(data) \ No newline at end of file diff --git a/werewolf/Roles/VanillaWerewolf.py b/werewolf/Roles/VanillaWerewolf.py new file mode 100644 index 0000000..404a5a2 --- /dev/null +++ b/werewolf/Roles/VanillaWerewolf.py @@ -0,0 +1,96 @@ +import asyncio + +import discord + +from datetime import datetime,timedelta + +from cogs.werewolf.Role import Role + +from cogs.werewolf.votegroups.wolfvote import WolfVote + +class VanillaWerewolf(Role): + + rand_choice = True + category = [11, 15] + allignment = 2 # 1: Town, 2: Werewolf, 3: Neutral + channel_id = "werewolves" + unique = False + game_start_message=""" + Your role is **Werewolf** + You win by killing everyone else in the village + Lynch players during the day with `[p]ww lynch ` + Vote to kill players at night with `[p]ww vote ` + """ + action_list = [ + (self._at_game_start, 0), # (Action, Priority) + (self._at_day_start, 0), + (self._at_voted, 0), + (self._at_kill, 0), + (self._at_hang, 0), + (self._at_day_end, 0), + (self._at_night_start, 2), + (self._at_night_end, 5) + ] + + def __init__(self, game): + self.game = game + self.player = None + self.blocked = False + self.properties = {} # Extra data for other roles (i.e. arsonist) + + # async def on_event(self, event, data): + # """ + # See Game class for event guide + # """ + + # await action_list[event][0](data) + + + # async def assign_player(self, player): + # """ + # Give this role a player + # Can be used after the game has started (Cult, Mason, other role swap) + # """ + + # player.role = self + # self.player = player + + async def _get_role(self, source=None): + """ + Interaction for powerful access of role + Unlikely to be able to deceive this + """ + return "Werewolf" + + async def _see_role(self, source=None): + """ + Interaction for investigative roles. + More common to be able to deceive these roles + """ + return "Werewolf" + + async def _at_game_start(self, data=None): + # super()._at_game_start(data) # Registers channel + + await self.game.register_vote_group(self.channel_id, WolfVote) + + # async def _at_day_start(self, data=None): + # super()._at_day_start(data) + + # async def _at_voted(self, data=None): + # super()._at_voted(data) + + # async def _at_kill(self, data=None): + # super()._at_kill(data) + + # async def _at_hang(self, data=None): + # super()._at_hang(data) + + # async def _at_day_end(self, data=None): + # super()._at_day_end(data) + + # async def _at_night_start(self, data=None): + # super()._at_night_start(data) + + # async def _at_night_end(self, data=None): + # super()._at_night_end(data) \ No newline at end of file diff --git a/werewolf/VoteGroup.py b/werewolf/VoteGroup.py index b3833eb..f35b29e 100644 --- a/werewolf/VoteGroup.py +++ b/werewolf/VoteGroup.py @@ -2,16 +2,17 @@ import asyncio import discord +import random + class VoteGroup: """ Base VoteGroup class for werewolf game Handles secret channels and group decisions - Default handles wolf kill vote """ - allignment = 2 # 1: Town, 2: Werewolf, 3: Neutral - channel_id = "werewolves" + allignment = 0 # 1: Town, 2: Werewolf, 3: Neutral + channel_id = "" action_list = [ (self._at_game_start, 0), # (Action, Priority) @@ -21,30 +22,31 @@ class VoteGroup: (self._at_hang, 0), (self._at_day_end, 0), (self._at_night_start, 2), - (self._at_night_end, 5) + (self._at_night_end, 0) ] - vote_emojis = - - def __init__(self, game): + + def __init__(self, game, members): self.game = game + self.members = members self.channel = None + self.vote_results = {} self.properties = {} # Extra data for other options - self.vote_message = None + async def on_event(self, event, data): """ See Game class for event guide """ - + await action_list[event][0](data) - async def _at_game_start(self, data=None): if self.channel_id: self.channel = await self.game.register_channel(self.channel_id) async def _at_day_start(self, data=None): + pass async def _at_voted(self, data=None): pass @@ -62,10 +64,38 @@ class VoteGroup: if self.channel is None: return - self.vote_message = await self.game.generate_targets(self.channel) - - + await self.game.generate_targets(self.channel) async def _at_night_end(self, data=None): if self.channel is None: - return \ No newline at end of file + return + + target = None + vote_list = list(self.vote_results.values()) + + if vote_list: + target = max(set(vote_list), key=vote_list.count) + + if target: + # Do what you voted on + pass + + async def register_member(self, member): + """ + Add a member to member list + """ + self.members.append(member) + + async def remove_member(self, member): + """ + Remove a member from member list + """ + if member in self.members: + self.members.remove(member) + + async def vote(self, author, id): + """ + Receive vote from game + """ + + self.vote_results[author.id] = id \ No newline at end of file diff --git a/werewolf/VoteGroups/WolfVote.py b/werewolf/VoteGroups/WolfVote.py new file mode 100644 index 0000000..7a57df5 --- /dev/null +++ b/werewolf/VoteGroups/WolfVote.py @@ -0,0 +1,96 @@ +import asyncio + +import discord + +import random + +from cogs.werewolf.votegroup import VoteGroup + +class WolfVote(VoteGroup): + """ + Werewolf implementation of base VoteGroup class + """ + + allignment = 2 # 1: Town, 2: Werewolf, 3: Neutral + channel_id = "werewolves" + + action_list = [ + (self._at_game_start, 0), # (Action, Priority) + (self._at_day_start, 0), + (self._at_voted, 0), + (self._at_kill, 0), + (self._at_hang, 0), + (self._at_day_end, 0), + (self._at_night_start, 2), + (self._at_night_end, 5) # Kill priority + ] + + + kill_messages = [ + "{target} was attacked by wolves", + "{target} was found torn to shreds"] + + def __init__(self, game, members): + self.game = game + self.members = members + self.channel = None + self.vote_results = {} + self.properties = {} # Extra data for other options + self.killer = None # Added killer + + + # async def on_event(self, event, data): + # """ + # See Game class for event guide + # """ + + # await action_list[event][0](data) + + # async def _at_game_start(self, data=None): + # if self.channel_id: + # self.channel = await self.game.register_channel(self.channel_id) + + # async def _at_day_start(self, data=None): + # pass + + # async def _at_voted(self, data=None): + # pass + + # async def _at_kill(self, data=None): + # pass + + # async def _at_hang(self, data=None): + # pass + + # async def _at_day_end(self, data=None): + # pass + + async def _at_night_start(self, data=None): + if self.channel is None: + return + + await self.game.generate_targets(self.channel) + + self.killer = random.choice(self.members) + + await channel.send("{} has been selected as tonight's killer") + + async def _at_night_end(self, data=None): + if self.channel is None: + return + + target = None + vote_list = list(self.vote_results.values()) + + if vote_list: + target = max(set(vote_list), key=vote_list.count) + + if target and self.killer: + await self.game.kill(target, self.killer, random.choice(self.kill_messages)) + + # async def vote(self, author, id): + # """ + # Receive vote from game + # """ + + # self.vote_results[author.id] = id \ No newline at end of file diff --git a/werewolf/info.json b/werewolf/info.json index a87fb10..2f58d46 100644 --- a/werewolf/info.json +++ b/werewolf/info.json @@ -6,5 +6,5 @@ "install_msg" : "Thank you for installing Werewolf! Use [p]wwset to run inital setup", "requirements" : [], "short" : "Werewolf Game", - "tags" : ["fun", "game", "bobloy"] + "tags" : ["mafia", "werewolf", "party", "fun", "game", "bobloy"] } \ No newline at end of file