fight-fixes
bobloy 7 years ago
commit 70a5583d56

@ -22,10 +22,12 @@ class Game:
} }
morning_messages = [ morning_messages = [
"**The sun rises on the village..**", "**The sun rises on day {} in the village..**",
"**Morning has arrived..**" "**Morning has arrived on day {}..**"
] ]
day_vote_count = 3
# def __new__(cls, guild, game_code): # def __new__(cls, guild, game_code):
# game_code = ["VanillaWerewolf", "Villager", "Villager"] # game_code = ["VanillaWerewolf", "Villager", "Villager"]
@ -47,6 +49,9 @@ class Game:
self.can_vote = False self.can_vote = False
self.used_votes = 0 self.used_votes = 0
self.day_time = False
self.day_count = 0
self.channel_category = None self.channel_category = None
self.village_channel = None self.village_channel = None
@ -153,10 +158,13 @@ class Game:
if self.game_over: if self.game_over:
return return
embed=discord.Embed(title=random.choice(self.morning_messages)) self.day_count += 1
embed=discord.Embed(title=random.choice(self.morning_messages.format(self.day_count)))
for result in self.night_results: for result in self.night_results:
embed.add_field(name=result, value="________", inline=False) embed.add_field(name=result, value="________", inline=False)
self.day_time = True
self.night_results = [] # Clear for next day self.night_results = [] # Clear for next day
await self.village_channel.send(embed=embed) await self.village_channel.send(embed=embed)
@ -174,7 +182,9 @@ class Game:
await self.village_channel.send(embed=discord.Embed(title="**Two minutes of daylight remain...**")) await self.village_channel.send(embed=discord.Embed(title="**Two minutes of daylight remain...**"))
await asyncio.sleep(120) # 4 minute days await asyncio.sleep(120) # 4 minute days
if not self.can_vote or self.game_over: # Need a loop here to wait for trial to end
if not self.can_vote or not self.day_time or self.game_over:
return return
await self._at_day_end() await self._at_day_end()
@ -187,14 +197,14 @@ class Game:
self.used_votes += 1 self.used_votes += 1
await self.all_but_perms(self.village_channel, target) await self.speech_perms(self.village_channel, target.member)
await self.village_channel.send("**{} will be put to trial and has 30 seconds to defend themselves**".format(target.mention)) await self.village_channel.send("**{} will be put to trial and has 30 seconds to defend themselves**".format(target.mention))
await asyncio.sleep(30) await asyncio.sleep(30)
await self.village_channel.set_permissions(target, read_messages=True) await self.speech_perms(self.village_channel, target.member, undo=True)
message = await self.village_channel.send("Everyone will now vote whether to lynch {}\n👍 to save, 👎 to lynch\n*Majority rules, no-lynch on ties, vote for both or neither to abstain, 15 seconds to vote*".format(target.mention)) message = await self.village_channel.send("Everyone will now vote whether to lynch {}\n👍 to save, 👎 to lynch\n*Majority rules, no-lynch on ties, vote both or neither to abstain, 15 seconds to vote*".format(target.mention))
await self.village_channel.add_reaction("👍") await self.village_channel.add_reaction("👍")
await self.village_channel.add_reaction("👎") await self.village_channel.add_reaction("👎")
@ -218,11 +228,17 @@ class Game:
if len(down_votes) > len(up_votes): if len(down_votes) > len(up_votes):
await self.village_channel.send("**Voted to lynch {}!**".format(target.mention)) await self.village_channel.send("**Voted to lynch {}!**".format(target.mention))
await self.kill(target) await self.lynch(target)
self.can_vote = False self.can_vote = False
elif self.used_votes >= 3: else:
self.can_vote = False await self.village_channel.send("**{} has been spared!**".format(target.mention))
if self.used_votes >= self.day_vote_count:
await self.village_channel.send("**All votes have been used! Day is now over!**")
self.can_vote = False
else:
await self.village_channel.send("**{}**/**{}** of today's votes have been used!\nNominate carefully..".format(self.used_votes, self.day_vote_count))
if not self.can_vote: if not self.can_vote:
await self._at_day_end() await self._at_day_end()
@ -247,6 +263,7 @@ class Game:
self.can_vote = False self.can_vote = False
self.day_vote = {} self.day_vote = {}
self.vote_totals = {} self.vote_totals = {}
self.day_time = False
await self.night_perms(self.village_channel) await self.night_perms(self.village_channel)
@ -353,7 +370,7 @@ class Game:
return "You're not in a game!" return "You're not in a game!"
if self.started: if self.started:
await self.kill(member) await self._quit(player)
await channel.send("{} has left the game".format(member.mention)) await channel.send("{} has left the game".format(member.mention))
else: else:
self.players = [player for player in self.players if player.member != member] self.players = [player for player in self.players if player.member != member]
@ -384,6 +401,16 @@ class Game:
await player.choose(ctx, data) await player.choose(ctx, data)
async def visit(self, target_id, source):
"""
Night visit target_id
Returns a target for role information (i.e. Seer)
"""
target = await self.get_night_target(target_id, source)
await target.role.visit(source)
await self._at_visit(target, source)
return target
async def vote(self, author, id, channel): async def vote(self, author, id, channel):
@ -443,6 +470,7 @@ class Game:
self.vote_totals[id] += 1 self.vote_totals[id] += 1
required_votes = len([player for player in self.players if player.alive]) // 7 + 2 required_votes = len([player for player in self.players if player.alive]) // 7 + 2
if self.vote_totals[id] < required_votes: if self.vote_totals[id] < required_votes:
await self.village_channel.send("{} has voted to put {} to trial. {} more votes needed".format(author.mention, target.member.mention, required_votes - self.vote_totals[id])) await self.village_channel.send("{} has voted to put {} to trial. {} more votes needed".format(author.mention, target.member.mention, required_votes - self.vote_totals[id]))
else: else:
@ -452,7 +480,22 @@ class Game:
async def eval_results(self, target, source=None, method = None): async def eval_results(self, target, source=None, method = None):
return "{} was found dead".format(target.member.display_name) if method is not None:
out = "**{ID}** - " + method
return out.format(ID=target.id, target=target.member.display_name)
else:
return "**{ID}** - {} was found dead".format(ID=target.id, target=target.member.display_name)
async def _quit(self, player):
"""
Have player quit the game
"""
player.alive = False
await self._at_kill(player)
player.alive = False # Do not allow resurrection
await self.dead_perms(player.member)
# Add a punishment system for quitting games later
async def kill(self, target_id, source=None, method: str=None): async def kill(self, target_id, source=None, method: str=None):
""" """
@ -461,18 +504,25 @@ class Game:
Be sure to remove permissions appropriately Be sure to remove permissions appropriately
Important to finish execution before triggering notify Important to finish execution before triggering notify
""" """
target = await self.get_night_target(target_id, source)
if source is None:
target = self.players[target_id]
elif self.day_time:
target = self.get_day_target(target_id, source)
else:
target = await self.get_night_target(target_id, source)
if source is not None: if source is not None:
if source.blocked: if source.blocked:
# Do nothing if blocked, blocker handles text # Do nothing if blocked, blocker handles text
return return
else:
if not target.protected: if not target.protected:
target.alive = False target.alive = False
await target.kill(source)
await self._at_kill(target) await self._at_kill(target)
if not target.alive: # Still dead after notifying if not target.alive: # Still dead after notifying
self.night_results.append(await self.eval_results(target, source, method)) if not self.day_time:
self.night_results.append(await self.eval_results(target, source, method))
await self.dead_perms(target.member) await self.dead_perms(target.member)
else: else:
target.protected = False target.protected = False
@ -530,7 +580,6 @@ class Game:
async def dead_perms(self, channel, member): async def dead_perms(self, channel, member):
await channel.set_permissions(member, read_messages=True, send_message=False, add_reactions=False) await channel.set_permissions(member, read_messages=True, send_message=False, add_reactions=False)
async def night_perms(self, channel): async def night_perms(self, channel):
await channel.set_permissions(self.guild.default_role, read_messages=False, send_messages=False) await channel.set_permissions(self.guild.default_role, read_messages=False, send_messages=False)
@ -539,7 +588,6 @@ class Game:
async def speech_perms(self, channel, member, undo=False): async def speech_perms(self, channel, member, undo=False):
if undo: if undo:
await channel.set_permissions(self.guild.default_role, read_messages=False)
await channel.set_permissions(member, read_messages=True) await channel.set_permissions(member, read_messages=True)
else: else:
await channel.set_permissions(self.guild.default_role, read_messages=False, send_messages=False) await channel.set_permissions(self.guild.default_role, read_messages=False, send_messages=False)
@ -556,4 +604,4 @@ class Game:
async def _end_game(self): async def _end_game(self):
#ToDo #ToDo
pass pass

@ -17,6 +17,7 @@ class Player:
self.alive = True self.alive = True
self.muted = False self.muted = False
self.protected = False self.protected = False
self.mention = self.member.mention
async def assign_role(self, role): async def assign_role(self, role):
""" """

@ -40,7 +40,7 @@ class Role:
rand_choice = False # Determines if it can be picked as a random role (False for unusually disruptive roles) 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) category = [0] # List of enrolled categories (listed above)
allignment = 0 # 1: Town, 2: Werewolf, 3: Neutral alignment = 0 # 1: Town, 2: Werewolf, 3: Neutral
channel_id = "" # Empty for no private channel channel_id = "" # Empty for no private channel
unique = False # Only one of this role per game unique = False # Only one of this role per game
game_start_message= ( game_start_message= (
@ -74,7 +74,7 @@ class Role:
await self.action_list[event][0](data) await self.action_list[event][0](data)
async def assign_player(self, player): async def assign_player(self, player):
""" """
Give this role a player Give this role a player
@ -84,14 +84,29 @@ class Role:
player.role = self player.role = self
self.player = player self.player = player
async def _get_role(self, source=None): async def get_alignment(self, source=None):
"""
Interaction for powerful access of alignment
(Village, Werewolf, Other)
Unlikely to be able to deceive this
"""
return self.alignment
async def see_alignment(self, source=None):
"""
Interaction for investigative roles attempting
to see alignment (Village, Werewolf Other)
"""
return "Other"
async def get_role(self, source=None):
""" """
Interaction for powerful access of role Interaction for powerful access of role
Unlikely to be able to deceive this Unlikely to be able to deceive this
""" """
return "Default" return "Default"
async def _see_role(self, source=None): async def see_role(self, source=None):
""" """
Interaction for investigative roles. Interaction for investigative roles.
More common to be able to deceive this action More common to be able to deceive this action
@ -128,6 +143,14 @@ class Role:
async def _at_visit(self, data=None): async def _at_visit(self, data=None):
pass pass
async def kill(self, source):
"""
Called when someone is trying to kill you!
Can you do anything about it?
self.alive is now set to False, set to True to stay alive
"""
pass
async def visit(self, source): async def visit(self, source):
""" """
Called whenever a night action targets you Called whenever a night action targets you

@ -6,7 +6,7 @@ class Seer(Role):
rand_choice = False # Determines if it can be picked as a random role (False for unusually disruptive roles) rand_choice = False # Determines if it can be picked as a random role (False for unusually disruptive roles)
category = [1,2] # List of enrolled categories (listed above) category = [1,2] # List of enrolled categories (listed above)
allignment = 1 # 1: Town, 2: Werewolf, 3: Neutral alignment = 1 # 1: Town, 2: Werewolf, 3: Neutral
channel_id = "" # Empty for no private channel channel_id = "" # Empty for no private channel
unique = False # Only one of this role per game unique = False # Only one of this role per game
game_start_message=( game_start_message=(
@ -50,7 +50,21 @@ class Seer(Role):
# player.role = self # player.role = self
# self.player = player # self.player = player
# async def get_alignment(self, source=None):
# """
# Interaction for power access of team (Village, Werewolf, Other)
# Unlikely to be able to deceive this
# """
# return self.alignment
async def see_alignment(self, source=None):
"""
Interaction for investigative roles attempting
to see team (Village, Werewolf Other)
"""
return "Village"
async def _get_role(self, source=None): async def _get_role(self, source=None):
""" """
Interaction for powerful access of role Interaction for powerful access of role
@ -85,17 +99,44 @@ class Seer(Role):
async def _at_night_start(self): async def _at_night_start(self):
await self.game.generate_targets(self.player.member) await self.game.generate_targets(self.player.member)
await self.player.member.send("{}\n**Pick a target to see tonight**\n") await self.player.send_dm("{}\n**Pick a target to see tonight**\n")
async def _at_night_end(self): async def _at_night_end(self):
target = await self.game.visit(self.see_target)
alignment = await target.see_alignment(self.player)
if alignment == "Werewolf":
out = "Your insight reveals this player to be a **Werewolf!**"
else:
out = "You fail to find anything suspicious about this player..."
await self.player.send_dm(out)
# async def _at_visit(self, data=None):
# pass
# async def kill(self, source):
# """
# Called when someone is trying to kill you!
# Can you do anything about it?
# self.alive is now set to False, set to True to stay alive
# """
# pass
# async def visit(self, source):
# """
# Called whenever a night action targets you
# Source is the player who visited you
# """
# pass
async def choose(self, ctx, data): async def choose(self, ctx, data):
"""Handle night actions""" """Handle night actions"""
id = int(data) id = int(data)
try: try:
target = game.players[id] target = self.game.players[id]
except IndexError: except IndexError:
target = None target = None

@ -9,7 +9,7 @@ class VanillaWerewolf(Role):
rand_choice = True rand_choice = True
category = [11, 15] category = [11, 15]
allignment = 2 # 1: Town, 2: Werewolf, 3: Neutral alignment = 2 # 1: Town, 2: Werewolf, 3: Neutral
channel_id = "werewolves" channel_id = "werewolves"
unique = False unique = False
game_start_message = ( game_start_message = (
@ -53,6 +53,20 @@ class VanillaWerewolf(Role):
# player.role = self # player.role = self
# self.player = player # self.player = player
# async def get_alignment(self, source=None):
# """
# Interaction for power access of team (Village, Werewolf, Other)
# Unlikely to be able to deceive this
# """
# return self.alignment
async def see_alignment(self, source=None):
"""
Interaction for investigative roles attempting
to see team (Village, Werewolf Other)
"""
return "Werewolf"
async def _get_role(self, source=None): async def _get_role(self, source=None):
""" """
Interaction for powerful access of role Interaction for powerful access of role
@ -97,7 +111,15 @@ class VanillaWerewolf(Role):
# async def _at_visit(self, data=None): # async def _at_visit(self, data=None):
# pass # pass
# async def kill(self, source):
# """
# Called when someone is trying to kill you!
# Can you do anything about it?
# self.alive is now set to False, set to True to stay alive
# """
# pass
# async def visit(self, source): # async def visit(self, source):
# """ # """
# Called whenever a night action targets you # Called whenever a night action targets you

@ -6,7 +6,7 @@ class Villager(Role):
rand_choice = False # Determines if it can be picked as a random role (False for unusually disruptive roles) rand_choice = False # Determines if it can be picked as a random role (False for unusually disruptive roles)
category = [1] # List of enrolled categories (listed above) category = [1] # List of enrolled categories (listed above)
allignment = 1 # 1: Town, 2: Werewolf, 3: Neutral alignment = 1 # 1: Town, 2: Werewolf, 3: Neutral
channel_id = "" # Empty for no private channel channel_id = "" # Empty for no private channel
unique = False # Only one of this role per game unique = False # Only one of this role per game
game_start_message=( game_start_message=(
@ -50,7 +50,21 @@ class Villager(Role):
# player.role = self # player.role = self
# self.player = player # self.player = player
# async def get_alignment(self, source=None):
# """
# Interaction for power access of team (Village, Werewolf, Other)
# Unlikely to be able to deceive this
# """
# return self.alignment
async def see_alignment(self, source=None):
"""
Interaction for investigative roles attempting
to see team (Village, Werewolf Other)
"""
return "Village"
async def _get_role(self, source=None): async def _get_role(self, source=None):
""" """
Interaction for powerful access of role Interaction for powerful access of role
@ -91,7 +105,15 @@ class Villager(Role):
# async def _at_visit(self, data=None): # async def _at_visit(self, data=None):
# pass # pass
# async def kill(self, source):
# """
# Called when someone is trying to kill you!
# Can you do anything about it?
# self.alive is now set to False, set to True to stay alive
# """
# pass
# async def visit(self, source): # async def visit(self, source):
# """ # """
# Called whenever a night action targets you # Called whenever a night action targets you

@ -11,7 +11,7 @@ class VoteGroup:
Handles secret channels and group decisions Handles secret channels and group decisions
""" """
allignment = 0 # 1: Town, 2: Werewolf, 3: Neutral alignment = 0 # 1: Town, 2: Werewolf, 3: Neutral
channel_id = "" channel_id = ""
def __init__(self, game, channel): def __init__(self, game, channel):
@ -63,7 +63,7 @@ class VoteGroup:
async def _at_night_start(self, data=None): async def _at_night_start(self, data=None):
if self.channel is None: if self.channel is None:
return return
await self.game.generate_targets(self.channel) await self.game.generate_targets(self.channel)
async def _at_night_end(self, data=None): async def _at_night_end(self, data=None):
@ -80,6 +80,9 @@ class VoteGroup:
# Do what you voted on # Do what you voted on
pass pass
async def _at_visit(self, data=None):
pass
async def register_players(self, *players): async def register_players(self, *players):
""" """
Extend players by passed list Extend players by passed list

@ -11,7 +11,7 @@ class WolfVote(VoteGroup):
Werewolf implementation of base VoteGroup class Werewolf implementation of base VoteGroup class
""" """
allignment = 2 # 1: Town, 2: Werewolf, 3: Neutral alignment = 2 # 1: Town, 2: Werewolf, 3: Neutral
channel_id = "werewolves" channel_id = "werewolves"
kill_messages = [ kill_messages = [
@ -35,7 +35,8 @@ class WolfVote(VoteGroup):
(self._at_hang, 0), (self._at_hang, 0),
(self._at_day_end, 0), (self._at_day_end, 0),
(self._at_night_start, 2), (self._at_night_start, 2),
(self._at_night_end, 5) # Kill priority (self._at_night_end, 5), # Kill priority
(self._at_visit, 0)
] ]
# async def on_event(self, event, data): # async def on_event(self, event, data):

Loading…
Cancel
Save