diff --git a/werewolf/Game.py b/werewolf/Game.py index cefb9e4..5d19dc5 100644 --- a/werewolf/Game.py +++ b/werewolf/Game.py @@ -113,11 +113,11 @@ class Game: return await self._notify(6) - asyncio.sleep(120) - # 2 minutes left - asyncio.sleep(90) - # 30 seconds left - asyncio.sleep(30) + asyncio.sleep(120) # 2 minutes + + asyncio.sleep(90) # 1.5 minutes + + asyncio.sleep(30) # .5 minutes await self._at_night_end() @@ -129,17 +129,20 @@ class Game: asyncio.sleep(15) await self._at_day_start() - async def _notify(self, event): + async def _notify(self, event, data=None): for i in range(10): tasks = [] role_order = [role for role in self.roles if role.action_list[event][1]==i] - for role in role_action: - tasks.append(asyncio.ensure_future(role.on_event(event)) + for role in role_order: + tasks.append(asyncio.ensure_future(role.on_event(event, data)) # self.loop.create_task(role.on_event(event)) self.loop.run_until_complete(asyncio.gather(*tasks)) # Run same-priority task simultaneously async def _generate_targets(self): + + async def register_channel(self, channel_id): + async def join(self, member: discord.Member, channel: discord.Channel): diff --git a/werewolf/Player.py b/werewolf/Player.py index 72b628f..56d4bda 100644 --- a/werewolf/Player.py +++ b/werewolf/Player.py @@ -10,7 +10,7 @@ class Player: """ def __init__(self, member: discord.Member): - self.user = member + self.member = member self.role = None self.id = None @@ -24,3 +24,6 @@ class Player: """ role.player = self self.role = role + + async def send_dm(self, message): + await self.member.send(message) # Lets do embeds later diff --git a/werewolf/Role.py b/werewolf/Role.py index d152b1e..7d272c7 100644 --- a/werewolf/Role.py +++ b/werewolf/Role.py @@ -33,6 +33,7 @@ class Role: 2. Group discussions and Pick targets _at_night_end + 0. No Action 1. Self actions (Veteran) 2. Target switching and role blocks (bus driver, witch, escort) 3. Protection / Preempt actions (bodyguard/framer) @@ -46,6 +47,11 @@ class Role: allignment = 0 # 1: Town, 2: Werewolf, 3: Neutral channel_id = "" # Empty for no private channel unique = False # Only one of this role per game + game_start_message=""" + Your role is **Default** + You win by testing the game + Lynch players during the day with `[p]ww lynch ` + """ action_list = [ (self._at_game_start, 0), # (Action, Priority) (self._at_day_start, 0), @@ -61,6 +67,7 @@ class Role: self.game = game self.player = None self.blocked = False + self.secret_channel = None self.properties = {} # Extra data for other roles (i.e. arsonist) async def on_event(self, event, data): @@ -90,30 +97,33 @@ class Role: async def _see_role(self, source=None): """ Interaction for investigative roles. - More common to be able to deceive these roles + More common to be able to deceive this action """ return "Role" async def _at_game_start(self, data=None): - pass + if self.channel_id: + self.properties["channel"] = await self.game.register_channel(self.channel_id) + + await self.player.send_dm(self.game_start_message) #Maybe embeds eventually async def _at_day_start(self, data=None): pass - async def _at_voted(self, target=None): + async def _at_voted(self, data=None): pass - async def _at_kill(self, target=None): + async def _at_kill(self, data=None): pass - async def _at_hang(self, target=None): + async def _at_hang(self, data=None): pass - async def _at_day_end(self): + async def _at_day_end(self, data=None): pass - async def _at_night_start(self): + async def _at_night_start(self, data=None): pass - async def _at_night_end(self): + async def _at_night_end(self, data=None): pass \ No newline at end of file diff --git a/werewolf/Roles/DefaultWerewolf.py b/werewolf/Roles/DefaultWerewolf.py index 9b5acfb..29c3890 100644 --- a/werewolf/Roles/DefaultWerewolf.py +++ b/werewolf/Roles/DefaultWerewolf.py @@ -4,15 +4,17 @@ import discord from datetime import datetime,timedelta -from . import Role +from cogs.werewolf.Role import Role + +from cogs.werewolf.VoteGroup import WolfVote class DefaultWerewolf(Role): - rand_choice = False # Determines if it can be picked as a random role (False for unusually disruptive roles) - category = [0] # List of enrolled categories (listed above) - allignment = 0 # 1: Town, 2: Werewolf, 3: Neutral - channel_id = "" # Empty for no private channel - unique = False # Only one of this role per game + rand_choice = True + category = [11, 15] + allignment = 2 # 1: Town, 2: Werewolf, 3: Neutral + channel_id = "werewolf" + unique = False action_list = [ (self._at_game_start, 0), # (Action, Priority) (self._at_day_start, 0), @@ -20,8 +22,8 @@ class DefaultWerewolf(Role): (self._at_kill, 0), (self._at_hang, 0), (self._at_day_end, 0), - (self._at_night_start, 0), - (self._at_night_end, 0) + (self._at_night_start, 2), + (self._at_night_end, 5) ] def __init__(self, game): @@ -30,57 +32,57 @@ class DefaultWerewolf(Role): 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 "Default" + return "Werewolf" async def _see_role(self, source=None): """ Interaction for investigative roles. More common to be able to deceive these roles """ - return "Role" + return "Werewolf" async def _at_game_start(self, data=None): - pass + 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): - pass + super()._at_day_start(data) + + async def _at_voted(self, data=None): + super()._at_voted(data) - async def _at_voted(self, target=None): - pass + async def _at_kill(self, data=None): + super()._at_kill(data) - async def _at_kill(self, target=None): - pass + async def _at_hang(self, data=None): + super()._at_hang(data) - async def _at_hang(self, target=None): - pass + async def _at_day_end(self, data=None): + super()._at_day_end(data) - async def _at_day_end(self): - pass + async def _at_night_start(self, data=None): + channel = self.game.channel_lock(self.channel_id, False) + # channel = await self.game.get_channel(self.channel_id) - async def _at_night_start(self): - pass + await self.game._generate_targets(channel) + super()._at_night_start(data) - async def _at_night_end(self): - pass \ No newline at end of file + async def _at_night_end(self, data=None): + await self.game.channel_lock(self.channel_id, True) + + try: + target = data["target"] + except: + # No target chosen, no kill + target = None + + if target: + await self.game.kill(target) + + super()._at_night_end(data) \ No newline at end of file diff --git a/werewolf/VoteGroup.py b/werewolf/VoteGroup.py new file mode 100644 index 0000000..f5cc94e --- /dev/null +++ b/werewolf/VoteGroup.py @@ -0,0 +1,62 @@ +import asyncio + +import discord + + +class SecretGroup: + """ + Base SecretGroup class for werewolf game + Handles secret channels and group decisions + Default handles Town lynch votes + """ + + allignment = 1 # 1: Town, 2: Werewolf, 3: Neutral + channel_id = "Town Square" + + 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, 0), + (self._at_night_end, 0) + ] + + def __init__(self, game): + self.game = game + self.channel = None + self.properties = {} # Extra data for other options + + 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): + + 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): + pass + + async def _at_night_end(self, data=None): + pass \ No newline at end of file