Split and convert matchmaker

This commit is contained in:
Vgr E. Barry 2018-04-30 14:51:42 -04:00
parent 84d25330b2
commit 35bcda40dc
7 changed files with 270 additions and 239 deletions

View File

@ -790,7 +790,7 @@
"assassin_role_info": "You are an \u0002assassin\u0002{0}.",
"assassin_targeting": " and targeting {0}",
"bitten_info": "You were bitten by an alpha wolf and have \u0002{0} night{1}\u0002 until your transformation.",
"matched_info": "You are \u0002in love\u0002 with ",
"matched_info": "You are \u0002in love\u0002 with",
"no_command_in_channel": "You cannot use this command in channel right now",
"no_such_role": "No such role: {0}",
"ambiguous_role": "Ambiguous role. Possible matches are: {0}.",

View File

@ -24,39 +24,6 @@ def game_mode(name, minp, maxp, likelihood = 0):
reset_roles = lambda i: OrderedDict([(role, (0,) * len(i)) for role in var.ROLE_GUIDE])
def get_lovers():
lovers = []
pl = list_players()
for lover in var.LOVERS:
done = None
for i, lset in enumerate(lovers):
if lover in pl and lover in lset:
if done is not None: # plot twist! two clusters turn out to be linked!
done.update(lset)
for lvr in var.LOVERS[lover]:
if lvr in pl:
done.add(lvr)
lset.clear()
continue
for lvr in var.LOVERS[lover]:
if lvr in pl:
lset.add(lvr)
done = lset
if done is None and lover in pl:
lovers.append(set())
lovers[-1].add(lover)
for lvr in var.LOVERS[lover]:
if lvr in pl:
lovers[-1].add(lvr)
while set() in lovers:
lovers.remove(set())
return lovers
class GameMode:
def __init__(self, arg=""):
if not arg:
@ -111,6 +78,7 @@ class GameMode:
winner = evt.data["winner"]
if winner is not None and winner.startswith("@"):
return # fool won, lovers can't win even if they would
from src.roles.matchmaker import get_lovers
all_lovers = get_lovers()
if len(all_lovers) != 1:
return # we need exactly one cluster alive for this to trigger

View File

@ -16,7 +16,7 @@ def setup_variables(rolename, *, send_role, types):
@event_listener("transition_night_end")
def on_transition_night_end(evt, var):
villagers = set(get_players(("priest", "prophet", "matchmaker", "doctor")))
villagers = set(get_players(("priest", "prophet", "doctor")))
win_stealers = set(get_players(("fool", "monster", "demoniac")))
neutrals = set(get_players(("turncoat", "clone", "jester")))

View File

@ -77,12 +77,10 @@ def investigate(var, wrapper, message):
else:
t2role = "blue"
same = t1role == t2role
# FIXME: split into matchmaker once that is split and make this an event
if target2.nick in var.LOVERS.get(target1.nick, set()):
same = True
evt = Event("get_team_affiliation", {"same": (t1role == t2role)})
evt.dispatch(evt, target1, target2)
if same:
if evt.data["same"]:
wrapper.pm(messages["investigator_results_same"].format(target1, target2))
else:
wrapper.pm(messages["investigator_results_different"].format(target1, target2))
@ -90,7 +88,7 @@ def investigate(var, wrapper, message):
INVESTIGATED.add(wrapper.source)
debuglog("{0} (investigator) ID: {1} ({2}) and {3} ({4}) as {5}".format(
wrapper.source, target1, get_main_role(target1), target2, get_main_role(target2),
"same" if same else "different"))
"same" if evt.data["same"] else "different"))
@event_listener("del_player")
def on_del_player(evt, var, user, mainrole, allroles, death_triggers):

257
src/roles/matchmaker.py Normal file
View File

@ -0,0 +1,257 @@
import re
import random
import itertools
import math
from collections import defaultdict
import botconfig
from src.utilities import *
from src import channels, users, debuglog, errlog, plog
from src.functions import get_players, get_all_players, get_main_role, get_reveal_role, get_target
from src.decorators import command, event_listener
from src.containers import UserList, UserSet, UserDict, DefaultUserDict
from src.messages import messages
from src.events import Event
MATCHMAKERS = UserSet() # type: Set[users.User]
LOVERS = UserDict() # type: Dict[users.User, Set[users.User]]
def _set_lovers(target1, target2):
if target1 in LOVERS:
LOVERS[target1].add(target2)
else:
LOVERS[target1] = UserSet({target2})
if target2 in LOVERS:
LOVERS[target2].add(target1)
else:
LOVERS[target2] = UserSet({target1})
t1_msg = "matchmaker_target_notify"
if target1.prefers_simple():
t1_msg += "_simple"
t2_msg = "matchmaker_target_notify"
if target2.prefers_simple():
t2_msg += "_simple"
target1.send(messages[t1_msg].format(target2))
target2.send(messages[t2_msg].format(target1))
def get_lovers():
lovers = []
pl = get_players()
for lover in LOVERS:
done = None
for i, lset in enumerate(lovers):
if lover in pl and lover in lset:
if done is not None: # plot twist! two clusters turn out to be linked!
done.update(lset)
for lvr in LOVERS[lover]:
if lvr in pl:
done.add(lvr)
lset.clear()
continue
for lvr in LOVERS[lover]:
if lvr in pl:
lset.add(lvr)
done = lset
if done is None and lover in pl:
lovers.append(set())
lovers[-1].add(lover)
for lvr in LOVERS[lover]:
if lvr in pl:
lovers[-1].add(lvr)
while set() in lovers:
lovers.remove(set())
return lovers
@command("match", "choose", chan=False, pm=True, playing=True, phases=("night",), roles=("matchmaker",))
def choose(var, wrapper, message):
"""Select two players to fall in love. You may select yourself as one of the lovers."""
if not var.FIRST_NIGHT:
return
if wrapper.source in MATCHMAKERS:
wrapper.send(messages["already_matched"])
return
pieces = re.split(" +", message)
victim1 = pieces[0]
if len(pieces) > 1:
if len(pieces) > 2 and pieces[1].lower() == "and":
victim2 = pieces[2]
else:
victim2 = pieces[1]
else:
victim2 = None
target1 = get_target(var, wrapper, victim1, allow_self=True)
target2 = get_target(var, wrapper, victim2, allow_self=True)
if not target1 or not target2:
return
if target1 is target2:
wrapper.send(messages["match_different_people"])
return
MATCHMAKERS.add(wrapper.source)
_set_lovers(target1, target2)
wrapper.send(messages["matchmaker_success"].format(target1, target2))
debuglog("{0} (matchmaker) MATCH: {1} ({2}) WITH {3} ({4})".format(wrapper.source, target1, get_main_role(target1), target2, get_main_role(target2)))
@event_listener("transition_day_begin")
def on_transition_day_begin(evt, var):
pl = get_players()
for mm in get_all_players(("matchmaker",)):
if mm not in MATCHMAKERS:
lovers = random.sample(pl, 2)
MATCHMAKERS.add(mm)
_set_lovers(*lovers)
mm.send(messages["random_matchmaker"])
@event_listener("transition_night_end")
def on_transition_night_end(evt, var):
if var.FIRST_NIGHT or var.ALWAYS_PM_ROLE:
ps = get_players()
for mm in get_all_players(("matchmaker",)):
pl = ps[:]
random.shuffle(pl)
if mm.prefers_simple():
mm.send(messages["matchmaker_simple"])
else:
mm.send(messages["matchmaker_notify"])
mm.send("Players: " + ", ".join(p.nick for p in pl))
@event_listener("del_player")
def on_del_player(evt, var, player, mainrole, allroles, death_triggers):
if death_triggers and player in LOVERS:
lovers = set(LOVERS[player])
for lover in lovers:
if lover not in evt.data["pl"]:
continue # already died somehow
if var.ROLE_REVEAL in ("on", "team"):
role = get_reveal_role(lover)
an = "n" if role.startswith(("a", "e", "i", "o", "u")) else ""
message = messages["lover_suicide"].format(lover, an, role)
else:
message = messages["lover_suicide_no_reveal"].format(lover)
channels.Main.send(message)
debuglog("{0} ({1}) LOVE SUICIDE: {2} ({3})".format(lover, get_main_role(lover), player, mainrole))
evt.params.del_player(lover, end_game=False, killer_role=evt.params.killer_role, deadlist=evt.params.deadlist, original=evt.params.original, ismain=False)
evt.data["pl"] = evt.params.refresh_pl(evt.data["pl"])
@event_listener("game_end_messages")
def on_game_end_messages(evt, var):
done = {}
lovers = []
for lover1, lset in LOVERS.items():
for lover2 in lset:
# check if already said the pairing
if (lover1 in done and lover2 in done[lover1]) or (lover2 in done and lover1 in done[lover2]):
continue
lovers.append("\u0002{0}\u0002/\u0002{1}\u0002".format(lover1, lover2))
if lover1 in done:
done[lover1].append(lover2)
else:
done[lover1] = [lover2]
if len(lovers) == 1 or len(lovers) == 2:
evt.data["messages"].append("The lovers were {0}.".format(" and ".join(lovers)))
elif len(lovers) > 2:
evt.data["messages"].append("The lovers were {0}, and {1}".format(", ".join(lovers[0:-1]), lovers[-1]))
@event_listener("player_win")
def on_player_win(evt, var, player, role, winner, survived):
if player in LOVERS:
evt.data["special"].append("lover")
if winner == "lovers" and player in LOVERS:
evt.data["iwon"] = True
elif player in LOVERS and survived and LOVERS[player].intersection(get_players()):
for lvr in LOVERS[player]:
if lvr not in get_players():
# cannot win with dead lover (lover idled out)
continue
lover_role = get_main_role(lvr)
if not winner.startswith("@") and singular(winner) not in var.WIN_STEALER_ROLES:
evt.data["iwon"] = True
break
elif winner.startswith("@") and winner == "@" + lvr.nick and var.LOVER_WINS_WITH_FOOL:
evt.data["iwon"] = True
break
elif singular(winner) in var.WIN_STEALER_ROLES and lover_role == singular(winner):
evt.data["iwon"] = True
break
@event_listener("chk_nightdone")
def on_chk_nightdone(evt, var):
evt.data["actedcount"] += len(MATCHMAKERS)
evt.data["nightroles"].extend(get_all_players(("matchmaker",)))
@event_listener("get_special")
def on_get_special(evt, var):
evt.data["villagers"].update(get_all_players(("matchmaker",)))
@event_listener("get_team_affiliation")
def on_get_team_affiliation(evt, var, target1, target2):
if target1 in LOVERS and target2 in LOVERS:
for lset in get_lovers():
if target1 in lset and target2 in lset:
evt.data["same"] = True
break
@event_listener("myrole")
def on_myrole(evt, var, user):
# Remind lovers of each other
if user in get_players() and user in LOVERS:
msg = [messages["matched_info"]]
lovers = sorted(LOVERS[user])
if len(lovers) == 1:
message.append(lovers[0])
elif len(lovers) == 2:
message.extend((lovers[0], "and", lovers[1]))
else:
message.extend((", ".join(lovers[:-1]) + ",", "and", lovers[-1]))
evt.data["messages"].append(" ".join(msg) + ".")
@event_listener("revealroles")
def on_revealroles(evt, var, wrapper):
# print out lovers
pl = get_players()
done = {}
lovers = []
for lover1, lset in LOVERS.items():
if lover1 not in pl:
continue
for lover2 in lset:
# check if already said the pairing
if (lover1 in done and lover2 in done[lover1]) or (lover2 in done and lover1 in done[lover2]):
continue
if lover2 not in pl:
continue
lovers.append("{0}/{1}".format(lover1, lover2))
if lover1 in done:
done[lover1].append(lover2)
else:
done[lover1] = [lover2]
if len(lovers) == 1 or len(lovers) == 2:
evt.data["output"].append("\u0002lovers\u0002: {0}".format(" and ".join(lovers)))
elif len(lovers) > 2:
evt.data["output"].append("\u0002lovers\u0002: {0}, and {1}".format(", ".join(lovers[0:-1]), lovers[-1]))
@event_listener("reset")
def on_reset(evt, var):
MATCHMAKERS.clear()
LOVERS.clear()
# vim: set sw=4 expandtab:

View File

@ -128,8 +128,6 @@ def on_player_win(evt, var, player, mainrole, winner, survived):
if mainrole == "piper":
evt.data["won"] = True
# TODO: add code here (or maybe a sep event?) to let lovers win alongside piper
# Right now that's still in wolfgame.py, but should be moved here once mm is split
@event_listener("del_player")
def on_del_player(evt, var, player, mainrole, allroles, death_triggers):

View File

@ -322,7 +322,6 @@ def reset():
var.FGAMED = False
var.GAMEMODE_VOTES = {} #list of players who have used !game
var.START_VOTES.clear() # list of players who have voted to !start
var.LOVERS = {} # need to be here for purposes of random
var.ROLE_STATS = frozenset() # type: FrozenSet[FrozenSet[Tuple[str, int]]]
var.ROLE_SETS = [] # type: List[Tuple[Counter[str], int]]
var.VOTES.clear()
@ -2041,22 +2040,8 @@ def stop_game(var, winner="", abort=False, additional_winners=None, log=True):
message = ""
count = 0
if not abort:
done = {}
lovers = []
for lover1, llist in var.ORIGINAL_LOVERS.items():
for lover2 in llist:
# check if already said the pairing
if (lover1 in done and lover2 in done[lover1]) or (lover2 in done and lover1 in done[lover2]):
continue
lovers.append("\u0002{0}\u0002/\u0002{1}\u0002".format(lover1, lover2))
if lover1 in done:
done[lover1].append(lover2)
else:
done[lover1] = [lover2]
if len(lovers) == 1 or len(lovers) == 2:
roles_msg.append("The lovers were {0}.".format(" and ".join(lovers)))
elif len(lovers) > 2:
roles_msg.append("The lovers were {0}, and {1}".format(", ".join(lovers[0:-1]), lovers[-1]))
evt = Event("game_end_messages", {"messages": roles_msg})
evt.dispatch(var)
channels.Main.send(*roles_msg)
@ -2091,8 +2076,6 @@ def stop_game(var, winner="", abort=False, additional_winners=None, log=True):
pentry["mainrole"] = rol
pentry["allroles"] = allroles[plr]
if splr in var.LOVERS:
pentry["special"].append("lover")
won = False
iwon = False
@ -2136,31 +2119,6 @@ def stop_game(var, winner="", abort=False, additional_winners=None, log=True):
iwon = False
elif rol == "fool" and "@" + splr == winner:
iwon = True
elif winner != "lovers" and splr in var.LOVERS and plr in survived and len([x for x in var.LOVERS[splr] if users._get(x) in survived]) > 0: # FIXME
for lvr in var.LOVERS[splr]:
lvuser = users._get(lvr) # FIXME
if lvuser not in survived:
# cannot win with dead lover (if splr in survived and lvr is not, that means lvr idled out)
continue
lvrrol = mainroles[lvuser]
if not winner.startswith("@") and singular(winner) not in var.WIN_STEALER_ROLES:
iwon = True
break
elif winner.startswith("@") and winner == "@" + lvr and var.LOVER_WINS_WITH_FOOL:
iwon = True
break
elif winner == "monsters" and lvrrol == "monster":
iwon = True
break
elif winner == "demoniacs" and lvrrol == "demoniac":
iwon = True
break
# TODO: split this into piper.py once matchmaker is split
elif winner == "pipers" and lvrrol == "piper":
iwon = True
break
elif rol == "monster" and plr in survived and winner == "monsters":
iwon = True
elif rol == "demoniac" and plr in survived and winner == "demoniacs":
@ -2451,28 +2409,6 @@ def del_player(player, *, devoice=True, end_game=True, death_triggers=True, kill
if mainrole == "clone" and player.nick in var.CLONED:
del var.CLONED[player.nick]
if death_triggers and var.PHASE in var.GAME_PHASES:
if player.nick in var.LOVERS:
lovers = var.LOVERS[player.nick].copy()
var.LOVERS[player.nick].clear()
for lovernick in lovers:
lover = users._get(lovernick) # FIXME
if lover not in pl:
continue # already died somehow
if player.nick not in var.LOVERS[lover.nick]:
continue
var.LOVERS[lover.nick].remove(player.nick)
if var.ROLE_REVEAL in ("on", "team"):
role = get_reveal_role(lover)
an = "n" if role.startswith(("a", "e", "i", "o", "u")) else ""
message = messages["lover_suicide"].format(lover, an, role)
else:
message = messages["lover_suicide_no_reveal"].format(lover)
channels.Main.send(message)
debuglog("{0} ({1}) LOVE SUICIDE: {2} ({3})".format(lover, get_main_role(lover), player, mainrole))
del_player(lover, end_game=False, killer_role=killer_role, deadlist=deadlist, original=original, ismain=False)
pl = refresh_pl(pl)
pl = refresh_pl(pl)
# i herd u liek parameters
evt_death_triggers = death_triggers and var.PHASE in var.GAME_PHASES
@ -2566,7 +2502,7 @@ def del_player(player, *, devoice=True, end_game=True, death_triggers=True, kill
# remove players from night variables
# the dicts are handled above, these are the lists of who has acted which is used to determine whether night should end
# if these aren't cleared properly night may end prematurely
for x in (var.PASSED, var.HEXED, var.MATCHMAKERS, var.CURSED):
for x in (var.PASSED, var.HEXED, var.CURSED):
x.discard(player.nick)
if var.PHASE == "day" and ret:
if player in var.VOTES:
@ -2893,21 +2829,6 @@ def rename_player(var, user, prefix):
# defaultdict(list), where keys are nicks and items in list do not matter
if prefix in var.ACTIVE_PROTECTIONS.keys():
var.ACTIVE_PROTECTIONS[nick] = var.ACTIVE_PROTECTIONS.pop(prefix)
# Looks like {'6': {'jacob3'}, 'jacob3': {'6'}}
for dictvar in (var.LOVERS, var.ORIGINAL_LOVERS):
kvp = []
for a,b in dictvar.items():
nl = set()
for n in b:
if n == prefix:
n = nick
nl.add(n)
if a == prefix:
a = nick
kvp.append((a,nl))
dictvar.update(kvp)
if prefix in dictvar.keys():
del dictvar[prefix]
for idx, tup in enumerate(var.EXCHANGED_ROLES):
a, b = tup
if a == prefix:
@ -2915,7 +2836,7 @@ def rename_player(var, user, prefix):
if b == prefix:
b = nick
var.EXCHANGED_ROLES[idx] = (a, b)
for setvar in (var.HEXED, var.SILENCED, var.MATCHMAKERS, var.PASSED,
for setvar in (var.HEXED, var.SILENCED, var.PASSED,
var.JESTERS, var.LYCANTHROPES, var.LUCKY, var.DISEASED,
var.MISDIRECTED, var.EXCHANGED, var.IMMUNIZED, var.CURED_LYCANS,
var.ALPHA_WOLVES, var.CURSED, var.PRIESTS):
@ -3215,12 +3136,6 @@ def transition_day(gameid=0):
var.CLONED[clone.nick] = target.nick
clone.send(messages["random_clone"].format(target))
for mm in get_all_players(("matchmaker",)):
if mm.nick not in var.MATCHMAKERS:
lovers = random.sample(pl, 2)
choose.func(mm.client, mm.nick, mm.nick, "{0[0]} {0[1]}".format(lovers), sendmsg=False) # XXX: Old API
mm.send(messages["random_matchmaker"])
# Reset daytime variables
var.WOUNDED.clear()
var.NO_LYNCH.clear()
@ -3624,8 +3539,8 @@ def chk_nightdone():
actedcount += 1
if var.FIRST_NIGHT:
actedcount += len(var.MATCHMAKERS | var.CLONED.keys())
nightroles.extend(get_all_players(("matchmaker", "clone")))
actedcount += len(var.CLONED.keys())
nightroles.extend(get_all_players(("clone",)))
if var.ALPHA_ENABLED:
# alphas both kill and bite if they're activated at night, so add them into the counts
@ -4419,69 +4334,6 @@ def change_sides(cli, nick, chan, rest, sendmsg=True):
var.TURNCOATS[nick] = (team, var.NIGHT_COUNT)
debuglog("{0} ({1}) SIDE {2}".format(nick, get_role(nick), team))
@cmd("choose", chan=False, pm=True, playing=True, phases=("night",), roles=("matchmaker",))
@cmd("match", chan=False, pm=True, playing=True, phases=("night",), roles=("matchmaker",))
def choose(cli, nick, chan, rest, sendmsg=True): # XXX: transition_day also needs updating alongside this one
"""Select two players to fall in love. You may select yourself as one of the lovers."""
if not var.FIRST_NIGHT:
return
if nick in var.MATCHMAKERS:
pm(cli, nick, messages["already_matched"])
return
# no var.SILENCED check for night 1 only roles; silence should only apply for the night after
# but just in case, it also sucks if the one night you're allowed to act is when you are
# silenced, so we ignore it here anyway.
pieces = re.split(" +",rest)
victim = pieces[0]
if len(pieces) > 1:
if len(pieces) > 2 and pieces[1].lower() == "and":
victim2 = pieces[2]
else:
victim2 = pieces[1]
else:
victim2 = None
victim = get_victim(cli, nick, victim, False, True)
if not victim:
return
victim2 = get_victim(cli, nick, victim2, False, True)
if not victim2:
return
if victim == victim2:
pm(cli, nick, messages["match_different_people"])
return
var.MATCHMAKERS.add(nick)
if victim in var.LOVERS:
var.LOVERS[victim].add(victim2)
var.ORIGINAL_LOVERS[victim].add(victim2)
else:
var.LOVERS[victim] = {victim2}
var.ORIGINAL_LOVERS[victim] = {victim2}
if victim2 in var.LOVERS:
var.LOVERS[victim2].add(victim)
var.ORIGINAL_LOVERS[victim2].add(victim)
else:
var.LOVERS[victim2] = {victim}
var.ORIGINAL_LOVERS[victim2] = {victim}
if sendmsg:
pm(cli, nick, messages["matchmaker_success"].format(victim, victim2))
if victim in var.PLAYERS and not is_user_simple(victim):
pm(cli, victim, messages["matchmaker_target_notify"].format(victim2))
else:
pm(cli, victim, messages["matchmaker_target_notify_simple"].format(victim2))
if victim2 in var.PLAYERS and not is_user_simple(victim2):
pm(cli, victim2, messages["matchmaker_target_notify"].format(victim))
else:
pm(cli, victim2, messages["matchmaker_target_notify_simple"].format(victim))
debuglog("{0} ({1}) MATCH: {2} ({3}) + {4} ({5})".format(nick, get_role(nick), victim, get_role(victim), victim2, get_role(victim2)))
@cmd("hex", chan=False, pm=True, playing=True, silenced=True, phases=("night",), roles=("hag",))
def hex_target(cli, nick, chan, rest):
"""Hex someone, preventing them from acting the next day and night."""
@ -4917,15 +4769,6 @@ def transition_night():
priest.send(messages["priest_notify"])
if var.FIRST_NIGHT or var.ALWAYS_PM_ROLE:
for mm in get_all_players(("matchmaker",)):
pl = ps[:]
random.shuffle(pl)
if mm.prefers_simple():
mm.send(messages["matchmaker_simple"])
else:
mm.send(messages["matchmaker_notify"])
mm.send("Players: " + ", ".join(p.nick for p in pl))
for clone in get_all_players(("clone",)):
pl = ps[:]
random.shuffle(pl)
@ -5189,7 +5032,6 @@ def start(cli, nick, chan, forced = False, restart = ""):
var.OBSERVED = {}
var.CLONED = {}
var.LASTHEXED = {}
var.MATCHMAKERS = set()
var.SILENCED = set()
var.TOBESILENCED = set()
var.JESTERS = set()
@ -5198,7 +5040,6 @@ def start(cli, nick, chan, forced = False, restart = ""):
var.DISEASED_WOLVES = False
var.TRAITOR_TURNED = False
var.FINAL_ROLES = {}
var.ORIGINAL_LOVERS = {}
var.LYCANTHROPES = set()
var.LUCKY = set()
var.DISEASED = set()
@ -6072,19 +5913,6 @@ def myrole(var, wrapper, message): # FIXME: Need to fix !swap once this gets con
if "prophet" in var.TEMPLATE_RESTRICTIONS and wrapper.source in var.ROLES["prophet"]:
wrapper.pm(messages["prophet_simple"])
# Remind lovers of each other
if wrapper.source in ps and wrapper.source.nick in var.LOVERS:
message = messages["matched_info"]
lovers = sorted(list(set(var.LOVERS[wrapper.source.nick])))
if len(lovers) == 1:
message += lovers[0]
elif len(lovers) == 2:
message += lovers[0] + " and " + lovers[1]
else:
message += ", ".join(lovers[:-1]) + ", and " + lovers[-1]
message += "."
wrapper.pm(message)
@command("aftergame", "faftergame", flag="D", pm=True)
def aftergame(var, wrapper, message):
"""Schedule a command to be run after the current game."""
@ -6570,24 +6398,6 @@ def revealroles(var, wrapper, message):
output.append("\u0002{0}\u0002: {1}".format(role, ", ".join(out)))
# print out lovers too
done = {}
lovers = []
for lover1, llist in var.LOVERS.items():
for lover2 in llist:
# check if already said the pairing
if (lover1 in done and lover2 in done[lover1]) or (lover2 in done and lover1 in done[lover2]):
continue
lovers.append("{0}/{1}".format(lover1, lover2))
if lover1 in done:
done[lover1].append(lover2)
else:
done[lover1] = [lover2]
if len(lovers) == 1 or len(lovers) == 2:
output.append("\u0002lovers\u0002: {0}".format(" and ".join(lovers)))
elif len(lovers) > 2:
output.append("\u0002lovers\u0002: {0}, and {1}".format(", ".join(lovers[0:-1]), lovers[-1]))
#show who got immunized
if var.IMMUNIZED:
output.append("\u0002immunized\u0002: {0}".format(", ".join(var.IMMUNIZED)))