Split and convert matchmaker
This commit is contained in:
parent
84d25330b2
commit
35bcda40dc
@ -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}.",
|
||||
|
@ -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
|
||||
|
@ -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")))
|
||||
|
||||
|
@ -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
257
src/roles/matchmaker.py
Normal 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:
|
@ -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):
|
||||
|
202
src/wolfgame.py
202
src/wolfgame.py
@ -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)))
|
||||
|
Loading…
Reference in New Issue
Block a user