@ -12,14 +12,23 @@ class Game:
"""
Base class to run a single game of Werewolf
"""
default_secret_channel = {
" channel " : None ,
" players " : [ ] ,
" votegroup " : None
}
def __new__ ( cls , game_code ) :
game_code = [ " DefaultWerewolf " , " Villager " , " Villager " " ]
return Game ( game_code )
def __init__ ( self , game_code ) :
self . roles = [ ]
def __init__ ( self , g uild, g ame_code) :
self . guild = guild
self . game_code = game_code
self . roles = [ ]
if self . game_code :
self . get_roles ( )
@ -30,9 +39,11 @@ class Game:
self . game_over = False
self . can_vote = False
self . channel_category = None
self . village_channel = None
self . secret_channels = { }
self . vote_groups = [ ]
self . p_channels = { }
self . vote_groups = { }
self . loop = asyncio . get_event_loop ( )
@ -48,16 +59,51 @@ class Game:
4. Start game
"""
if len ( self . players ) != self . roles :
ctx . send ( " Player s does not match roles , cannot start" )
ctx . send ( " Player count does not match role count , cannot start" )
return False
overwrite = {
self . guild . default_role : discord . PermissionOverwrite ( read_messages = False ) ,
self . guild . me : discord . PermissionOverwrite ( read_messages = True )
}
self . channel_category = await self . guild . create_category ( " ww-game " , overwrites = overwrite , reason = " New game of werewolf " )
for player in self . players :
overwrite [ player . member ] = discord . PermissionOverwrite ( read_messages = True )
self . village_channel = await self . guild . create_text_channel ( " Village Square " , overwrites = overwrite , reason = " New game of werewolf " , category = self . channel_category )
# Assuming everything worked so far
await self . _at_day_start ( ) # This will queue channels and votegroups to be made
for channel_id in self . p_channels :
overwrite = {
self . guild . default_role : discord . PermissionOverwrite ( read_messages = False ) ,
self . guild . me : discord . PermissionOverwrite ( read_messages = True )
}
for member in self . p_channels [ channel_id ] [ " players " ] :
overwrite [ member ] = discord . PermissionOverwrite ( read_messages = True )
channel = await self . guild . create_text_channel ( channel_id , overwrites = overwrite , reason = " Werewolf secret channel " , category = self . channel_category )
self . p_channels [ channel_id ] [ " channel " ] = channel
if self . p_channels [ channel_id ] [ " votegroup " ] is not None :
vote_group = self . p_channels [ channel_id ] [ " votegroup " ] ( self , channel )
await vote_group . register_player ( )
self . vote_groups [ channel_id ] = self . p_channels [ channel_id ] [ " votegroup " ] ( self , channel )
############START Notify structure############
async def _cycle ( self ) :
"""
Each event calls the next event
_at_start ( )
_at_day_start ( )
_at_voted ( )
_at_kill ( )
@ -65,17 +111,17 @@ class Game:
_at_night_begin ( )
_at_night_end ( )
and repeat with _at_ morning _start( ) again
and repeat with _at_ day _start( ) again
"""
await self . _at_ start( ) :
await self . _at_ day_ start( ) :
async def _at_game_start ( self ) : # ID 0
if self . game_over :
return
await self . _notify( 0 )
await self . village_channel. send ( " Game is starting, please wait for setup to complete " )
asyncio . sleep ( 6 0)
await self . _at_day_start ( )
await self . _notify ( 0)
async def _at_day_start ( self ) : # ID 1
if self . game_over :
@ -90,17 +136,20 @@ class Game:
async def _at_voted ( self , target ) : # ID 2
if self . game_over :
return
await self . _notify ( 2 , target )
data = { " player " : target }
await self . _notify ( 2 , data )
async def _at_kill ( self , target ) : # ID 3
if self . game_over :
return
await self . _notify ( 3 , target )
data = { " player " : target }
await self . _notify ( 3 , data )
async def _at_hang ( self , target ) : # ID 4
if self . game_over :
return
await self . _notify ( 4 , target )
data = { " player " : target }
await self . _notify ( 4 , data )
async def _at_day_end ( self ) : # ID 5
if self . game_over :
@ -142,7 +191,7 @@ class Game:
for role in role_order :
tasks . append ( asyncio . ensure_future ( role . on_event ( event , data ) )
# VoteGroup priorities
vote_order = [ votes for votes in self . vote_groups if votes . action_list [ event ] [ 1 ] == i ]
vote_order = [ votes for votes in self . vote_groups . values ( ) if votes . action_list [ event ] [ 1 ] == i ]
for vote_group in vote_order :
tasks . append ( asyncio . ensure_future ( vote_group . on_event ( event , data ) )
@ -163,17 +212,22 @@ class Game:
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 , player , votegroup = None ) :
"""
Queue a channel to be created by game_start
"""
if channel_id not in self . p_channels :
self . p_channels [ channel_id ] = self . default_secret_channel . copy ( )
async def register_channel ( self , channel_id , votegroup = None ) :
# Create channel, set permissions, register votegroup
if channel_id not in self . secret_channels :
await asyncio . sleep ( 1 )
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 ) )
self . p_channels [ channel_id ] [ " players " ] . append ( player )
if votegroup :
self . p_channels [ channel_id ] [ " votegroup " ] = votegroup
async def join ( self , member : discord . Member , channel : discord . Channel ) :
"""
Have a member join a game
@ -201,13 +255,6 @@ class Game:
if self . started :
await self . kill ( )
if member in self . players :
return " {} is already in the game! " . format ( member . mention )
self . started . append ( member )
channel . send ( " {} has been added to the game, total players is ** {} ** " . format ( member . mention , len ( self . players ) ) )
async def vote ( self , author , id , channel ) :
"""
@ -222,15 +269,14 @@ class Game:
if not player . alive :
channel . send ( " Corpses can ' t vote " )
return
if channel in self . secret_channels . values ( ) :
if channel == self . village_channel :
if not self . can_vote :
channel . send ( " Voting is not allowed right now " )
return
if channel in self . p_channels . values ( ) :
try :
target = self . players [ id ]
except IndexError :
@ -244,6 +290,7 @@ class Game:
"""
Attempt to kill a target
Source allows admin override
Be sure to remove permissions appropriately
"""
async def get_roles ( self , game_code = None ) :