Run, Forrest, Run!

This commit is contained in:
Vgr E. Barry 2016-04-09 16:57:11 -04:00
parent 4d03ed03cf
commit 7b2cc43a50
3 changed files with 108 additions and 13 deletions

View File

@ -186,7 +186,7 @@
"forever_aclone": "It appears that \u0002{0}\u0002 was cloning you, so you are now stuck as a clone forever. How sad.", "forever_aclone": "It appears that \u0002{0}\u0002 was cloning you, so you are now stuck as a clone forever. How sad.",
"clone_success": "You will now be cloning \u0002{0}\u0002 if they die.", "clone_success": "You will now be cloning \u0002{0}\u0002 if they die.",
"clone_wolf": "\u0002{0}\u0002 cloned \u0002{1}\u0002 and has now become a wolf!", "clone_wolf": "\u0002{0}\u0002 cloned \u0002{1}\u0002 and has now become a wolf!",
"no_other_wolves": "There are no other wolves", "no_other_wolves": "There are no other wolves.",
"lover_suicide": "Saddened by the loss of their lover, \u0002{0}\u0002, a{1} \u0002{2}\u0002, commits suicide.", "lover_suicide": "Saddened by the loss of their lover, \u0002{0}\u0002, a{1} \u0002{2}\u0002, commits suicide.",
"lover_suicide_no_reveal": "Saddened by the loss of their lover, \u0002{0}\u0002 commits suicide.", "lover_suicide_no_reveal": "Saddened by the loss of their lover, \u0002{0}\u0002 commits suicide.",
"assassin_fail_totem": "Before dying, \u0002{0}\u0002 quickly attempts to slit \u0002{1}\u0002's throat; however, {1}'s totem emits a brilliant flash of light, causing the attempt to miss.", "assassin_fail_totem": "Before dying, \u0002{0}\u0002 quickly attempts to slit \u0002{1}\u0002's throat; however, {1}'s totem emits a brilliant flash of light, causing the attempt to miss.",
@ -203,6 +203,12 @@
"mad_scientist_kill_single_no_reveal": "\u0002{0}\u0002 throws a potent chemical concoction into the crowd. \u0002{1}\u0002 gets hit by the chemicals and dies.", "mad_scientist_kill_single_no_reveal": "\u0002{0}\u0002 throws a potent chemical concoction into the crowd. \u0002{1}\u0002 gets hit by the chemicals and dies.",
"mad_scientist_fail": "\u0002{0}\u0002 throws a potent chemical concoction into the crowd. Thankfully, nobody seems to have gotten hit.", "mad_scientist_fail": "\u0002{0}\u0002 throws a potent chemical concoction into the crowd. Thankfully, nobody seems to have gotten hit.",
"hunter_discard": "Your target has died, so you may now pick a new one.", "hunter_discard": "Your target has died, so you may now pick a new one.",
"wild_child_already_picked": "You have already picked your idol for this game.",
"wild_child_success": "You have picked {0} to be your idol for this game.",
"wild_child_as_wolf": "\u0002{0}\u0002's idol has died, and is now a \u0002wolf\u0002!",
"wild_child_random_idol": "Upon waking up, the first person you see is \u0002{0}\u0002, and they become your idol.",
"idol_died": "Your idol has died, and you are now a \u0002wolf\u0002!",
"wild_child_idol": "Your idol is \u0002{0}\u0002.",
"idle_death": "\u0002{0}\u0002 didn't get out of bed for a very long time and has been found dead. The survivors bury the \u0002{1}\u0002's body.", "idle_death": "\u0002{0}\u0002 didn't get out of bed for a very long time and has been found dead. The survivors bury the \u0002{1}\u0002's body.",
"idle_death_no_reveal": "\u0002{0}\u0002 didn't get out of bed for a very long time and has been found dead.", "idle_death_no_reveal": "\u0002{0}\u0002 didn't get out of bed for a very long time and has been found dead.",
"channel_idle_warning": "{0}: \u0002You have been idling for a while. Please say something soon or you might be declared dead.\u0002", "channel_idle_warning": "{0}: \u0002You have been idling for a while. Please say something soon or you might be declared dead.\u0002",
@ -511,6 +517,8 @@
"monster_simple": "You are a \u0002monster\u0002.", "monster_simple": "You are a \u0002monster\u0002.",
"lycan_notify": "You are a \u0002lycan\u0002. You are currently on the side of the villagers, but will turn into a wolf instead of dying if you are targeted by the wolves during the night.", "lycan_notify": "You are a \u0002lycan\u0002. You are currently on the side of the villagers, but will turn into a wolf instead of dying if you are targeted by the wolves during the night.",
"lycan_simple": "You are a \u0002lycan\u0002.", "lycan_simple": "You are a \u0002lycan\u0002.",
"child_notify": "You are a \u0002wild child\u0002. You must pick an idol with \"choose <nick>\", and you will become a wolf if your idol dies. You are a villager as long as your idol is alive.",
"child_simple": "You are a \u0002wild child\u0002.",
"vengeful_ghost_notify": "You are a \u0002vengeful ghost\u0002, sworn to take revenge on the {0} that you believe killed you. You must kill one of them with \"kill <nick>\" tonight. If you do not, one of them will be selected at random.", "vengeful_ghost_notify": "You are a \u0002vengeful ghost\u0002, sworn to take revenge on the {0} that you believe killed you. You must kill one of them with \"kill <nick>\" tonight. If you do not, one of them will be selected at random.",
"vengeful_ghost_simple": "You are a \u0002vengeful ghost\u0002.", "vengeful_ghost_simple": "You are a \u0002vengeful ghost\u0002.",
"drunken_assassin_notification": "You are an \u0002assassin\u0002. In your drunken stupor you have selected \u0002{0}\u0002 as your target.", "drunken_assassin_notification": "You are an \u0002assassin\u0002. In your drunken stupor you have selected \u0002{0}\u0002 as your target.",

View File

@ -245,6 +245,7 @@ ROLE_GUIDE = OrderedDict([ # This is order-sensitive - many parts of the code re
("turncoat" , ( 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 )), ("turncoat" , ( 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 )),
("clone" , ( 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 )), ("clone" , ( 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 )),
("lycan" , ( 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 )), ("lycan" , ( 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 )),
("wild child" , ( 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 )),
("vengeful ghost" , ( 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 )), ("vengeful ghost" , ( 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 )),
("succubus" , ( 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 )), ("succubus" , ( 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 )),
("demoniac" , ( 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 )), ("demoniac" , ( 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 )),
@ -269,7 +270,7 @@ WOLFTEAM_ROLES = WOLFCHAT_ROLES | {"minion", "cultist"}
# These roles either steal away wins or can otherwise win with any team # These roles either steal away wins or can otherwise win with any team
TRUE_NEUTRAL_ROLES = frozenset({"crazed shaman", "fool", "jester", "monster", "clone", "piper", "turncoat", "succubus", "demoniac", "dullahan"}) TRUE_NEUTRAL_ROLES = frozenset({"crazed shaman", "fool", "jester", "monster", "clone", "piper", "turncoat", "succubus", "demoniac", "dullahan"})
# These are the roles that will NOT be used for when amnesiac turns, everything else is fair game! (var.DEFAULT_ROLE is also added if not in this set) # These are the roles that will NOT be used for when amnesiac turns, everything else is fair game! (var.DEFAULT_ROLE is also added if not in this set)
AMNESIAC_BLACKLIST = frozenset({"monster", "demoniac", "minion", "matchmaker", "clone", "doctor", "villager", "cultist", "piper", "dullahan"}) AMNESIAC_BLACKLIST = frozenset({"monster", "demoniac", "minion", "matchmaker", "clone", "doctor", "villager", "cultist", "piper", "dullahan", "wild child"})
# These roles are seen as wolf by the seer/oracle # These roles are seen as wolf by the seer/oracle
SEEN_WOLF = WOLF_ROLES | {"monster", "mad scientist", "succubus"} SEEN_WOLF = WOLF_ROLES | {"monster", "mad scientist", "succubus"}
# These are seen as the default role (or villager) when seen by seer (this overrides SEEN_WOLF) # These are seen as the default role (or villager) when seen by seer (this overrides SEEN_WOLF)
@ -283,10 +284,10 @@ BENEFICIAL_TOTEMS = frozenset({"protection", "revealing", "desperation", "influe
# NB: if you want a template to apply to everyone, list it here but make the restrictions an empty set. Templates not listed here are considered full roles instead # NB: if you want a template to apply to everyone, list it here but make the restrictions an empty set. Templates not listed here are considered full roles instead
TEMPLATE_RESTRICTIONS = OrderedDict([ TEMPLATE_RESTRICTIONS = OrderedDict([
("cursed villager" , SEEN_WOLF | {"seer", "oracle", "fool", "jester", "priest"}), ("cursed villager" , SEEN_WOLF | {"seer", "oracle", "fool", "jester", "priest"}),
("gunner" , WOLFTEAM_ROLES | {"fool", "lycan", "jester", "priest"}), ("gunner" , WOLFTEAM_ROLES | {"fool", "lycan", "jester", "priest", "wild child"}),
("sharpshooter" , frozenset()), # the above gets automatically added to the set. this set is the list of roles that can be gunner but not sharpshooter ("sharpshooter" , frozenset()), # the above gets automatically added to the set. this set is the list of roles that can be gunner but not sharpshooter
("mayor" , frozenset({"fool", "jester", "monster"})), ("mayor" , frozenset({"fool", "jester", "monster"})),
("assassin" , WOLF_ROLES | {"traitor", "seer", "augur", "oracle", "harlot", "detective", "bodyguard", "guardian angel", "lycan", "priest"}), ("assassin" , WOLF_ROLES | {"traitor", "seer", "augur", "oracle", "harlot", "detective", "bodyguard", "guardian angel", "lycan", "priest", "wild child"}),
("bureaucrat" , frozenset()), ("bureaucrat" , frozenset()),
("blessed villager" , frozenset(ROLE_GUIDE.keys()) - {"villager", "blessed villager", "mayor", "bureaucrat"}), ("blessed villager" , frozenset(ROLE_GUIDE.keys()) - {"villager", "blessed villager", "mayor", "bureaucrat"}),
]) ])
@ -403,7 +404,8 @@ def plural(role, count=2):
bits[-1] = {"person": "people", bits[-1] = {"person": "people",
"wolf": "wolves", "wolf": "wolves",
"has": "have", "has": "have",
"succubus": "succubi"}.get(bits[-1], bits[-1] + "s") "succubus": "succubi",
"child": "children"}.get(bits[-1], bits[-1] + "s")
return " ".join(bits) return " ".join(bits)
def list_players(roles = None): def list_players(roles = None):
@ -440,6 +442,8 @@ def get_reveal_role(nick):
role = "amnesiac" role = "amnesiac"
elif HIDDEN_CLONE and nick in ORIGINAL_ROLES["clone"]: elif HIDDEN_CLONE and nick in ORIGINAL_ROLES["clone"]:
role = "clone" role = "clone"
elif nick in WILD_CHILDREN:
role = "wild child"
else: else:
role = get_role(nick) role = get_role(nick)

View File

@ -416,6 +416,7 @@ def reset():
var.START_VOTES = set() # list of players who have voted to !start var.START_VOTES = set() # list of players who have voted to !start
var.LOVERS = {} # need to be here for purposes of random var.LOVERS = {} # need to be here for purposes of random
var.ENTRANCED = set() var.ENTRANCED = set()
var.WILD_CHILDREN = set()
reset_settings() reset_settings()
@ -2917,6 +2918,31 @@ def del_player(cli, nick, forced_death=False, devoice=True, end_game=True, death
if nickrole == "clone" and nick in var.CLONED: if nickrole == "clone" and nick in var.CLONED:
del var.CLONED[nick] del var.CLONED[nick]
for child in var.ROLES["wild child"].copy():
if child in var.IDOLS and child not in deadlist:
if var.IDOLS[child] in deadlist:
pm(cli, child, messages["idol_died"])
var.WILD_CHILDREN.add(child)
var.ROLES["wild child"].remove(child)
var.ROLES["wolf"].add(child)
var.FINAL_ROLES[child] = "wolf"
wolves = var.list_players(var.WOLFCHAT_ROLES)
wolves.remove(child)
mass_privmsg(cli, wolves, messages["wild_child_as_wolf"].format(child))
if var.PHASE == "day":
random.shuffle(wolves)
for i, wolf in enumerate(wolves):
wolfroles = var.get_role(wolf)
cursed = ""
if wolf in var.ROLES["cursed villager"]:
cursed = "cursed "
wolves[i] = "\u0002{0}\u0002 ({1}{2})".format(wolf, cursed, wolfroles)
if wolves:
pm(cli, child, "Wolves: " + ", ".join(wolves))
else:
pm(cli, child, messages["no_other_wolves"])
if death_triggers and var.PHASE in var.GAME_PHASES: if death_triggers and var.PHASE in var.GAME_PHASES:
if nick in var.LOVERS: if nick in var.LOVERS:
others = var.LOVERS[nick].copy() others = var.LOVERS[nick].copy()
@ -3594,7 +3620,7 @@ def rename_player(cli, prefix, nick):
if prefix in dictvar.keys(): if prefix in dictvar.keys():
del dictvar[prefix] del dictvar[prefix]
for dictvar in (var.VENGEFUL_GHOSTS, var.TOTEMS, var.FINAL_ROLES, var.BITTEN, var.GUNNERS, var.TURNCOATS, for dictvar in (var.VENGEFUL_GHOSTS, var.TOTEMS, var.FINAL_ROLES, var.BITTEN, var.GUNNERS, var.TURNCOATS,
var.DOCTORS, var.BITTEN_ROLES, var.LYCAN_ROLES, var.AMNESIAC_ROLES): var.DOCTORS, var.BITTEN_ROLES, var.LYCAN_ROLES, var.AMNESIAC_ROLES, var.IDOLS):
if prefix in dictvar.keys(): if prefix in dictvar.keys():
dictvar[nick] = dictvar.pop(prefix) dictvar[nick] = dictvar.pop(prefix)
# Looks like {'jacob2': ['5'], '7': ['3']} # Looks like {'jacob2': ['5'], '7': ['3']}
@ -3640,7 +3666,7 @@ def rename_player(cli, prefix, nick):
var.DISEASED, var.TOBEDISEASED, var.RETRIBUTION, var.MISDIRECTED, var.TOBEMISDIRECTED, var.DISEASED, var.TOBEDISEASED, var.RETRIBUTION, var.MISDIRECTED, var.TOBEMISDIRECTED,
var.EXCHANGED, var.IMMUNIZED, var.CURED_LYCANS, var.ALPHA_WOLVES, var.CURSED, var.CHARMERS, var.EXCHANGED, var.IMMUNIZED, var.CURED_LYCANS, var.ALPHA_WOLVES, var.CURSED, var.CHARMERS,
var.CHARMED, var.TOBECHARMED, var.PRIESTS, var.CONSECRATING, var.ENTRANCED_DYING, var.DYING, var.CHARMED, var.TOBECHARMED, var.PRIESTS, var.CONSECRATING, var.ENTRANCED_DYING, var.DYING,
var.DECEIVED): var.DECEIVED, var.WILD_CHILDREN):
if prefix in setvar: if prefix in setvar:
setvar.remove(prefix) setvar.remove(prefix)
setvar.add(nick) setvar.add(nick)
@ -4019,6 +4045,15 @@ def transition_day(cli, gameid=0):
choose.func(cli, mm, mm, lovers[0] + " " + lovers[1], sendmsg=False) choose.func(cli, mm, mm, lovers[0] + " " + lovers[1], sendmsg=False)
pm(cli, mm, messages["random_matchmaker"]) pm(cli, mm, messages["random_matchmaker"])
for child in var.ROLES["wild child"]:
if child not in var.IDOLS:
ps = pl[:]
pl.remove(child)
if ps:
target = random.choice(ps)
var.IDOLS[child] = target
pm(cli, child, messages["wild_child_random_idol"].format(target))
# Reset daytime variables # Reset daytime variables
var.INVESTIGATED = set() var.INVESTIGATED = set()
@ -4752,8 +4787,8 @@ def chk_nightdone(cli):
nightroles.append(p) nightroles.append(p)
if var.FIRST_NIGHT: if var.FIRST_NIGHT:
actedcount += len(var.MATCHMAKERS | var.CLONED.keys()) actedcount += len(var.MATCHMAKERS | var.CLONED.keys() | var.IDOLS.keys())
nightroles.extend(get_roles("matchmaker", "clone")) nightroles.extend(get_roles("matchmaker", "clone", "wild child"))
if var.DISEASED_WOLVES: if var.DISEASED_WOLVES:
nightroles = [p for p in nightroles if p not in var.list_players(var.WOLF_ROLES - {"wolf cub", "werecrow", "doomsayer"})] nightroles = [p for p in nightroles if p not in var.list_players(var.WOLF_ROLES - {"wolf cub", "werecrow", "doomsayer"})]
@ -5003,6 +5038,7 @@ def check_exchange(cli, actor, nick):
elif actor_role in var.WOLF_ROLES - {"werecrow", "wolf cub", "alpha wolf"}: elif actor_role in var.WOLF_ROLES - {"werecrow", "wolf cub", "alpha wolf"}:
if actor in var.KILLS: if actor in var.KILLS:
del var.KILLS[actor] del var.KILLS[actor]
var.WILD_CHILDREN.discard(actor)
elif actor_role == "hunter": elif actor_role == "hunter":
if actor in var.OTHER_KILLS: if actor in var.OTHER_KILLS:
del var.OTHER_KILLS[actor] del var.OTHER_KILLS[actor]
@ -5024,6 +5060,8 @@ def check_exchange(cli, actor, nick):
del var.HVISITED[actor] del var.HVISITED[actor]
elif actor_role in ("seer", "oracle", "augur"): elif actor_role in ("seer", "oracle", "augur"):
var.SEEN.discard(actor) var.SEEN.discard(actor)
elif actor_role == "wild child": # would that ever happen?
var.IDOLS[nick] = var.IDOLS.pop(actor)
elif actor_role == "hag": elif actor_role == "hag":
if actor in var.LASTHEXED: if actor in var.LASTHEXED:
if var.LASTHEXED[actor] in var.TOBESILENCED and actor in var.HEXED: if var.LASTHEXED[actor] in var.TOBESILENCED and actor in var.HEXED:
@ -5067,6 +5105,7 @@ def check_exchange(cli, actor, nick):
elif nick_role in var.WOLF_ROLES - {"werecrow", "wolf cub", "alpha wolf"}: elif nick_role in var.WOLF_ROLES - {"werecrow", "wolf cub", "alpha wolf"}:
if nick in var.KILLS: if nick in var.KILLS:
del var.KILLS[nick] del var.KILLS[nick]
var.WILD_CHILDREN.discard(nick)
elif nick_role == "hunter": elif nick_role == "hunter":
if nick in var.OTHER_KILLS: if nick in var.OTHER_KILLS:
del var.OTHER_KILLS[nick] del var.OTHER_KILLS[nick]
@ -5088,6 +5127,8 @@ def check_exchange(cli, actor, nick):
del var.HVISITED[nick] del var.HVISITED[nick]
elif nick_role in ("seer", "oracle", "augur"): elif nick_role in ("seer", "oracle", "augur"):
var.SEEN.discard(nick) var.SEEN.discard(nick)
elif nick_role == "wild child":
var.IDOLS[actor] = var.IDOLS.pop(nick)
elif nick_role == "hag": elif nick_role == "hag":
if nick in var.LASTHEXED: if nick in var.LASTHEXED:
if var.LASTHEXED[nick] in var.TOBESILENCED and nick in var.HEXED: if var.LASTHEXED[nick] in var.TOBESILENCED and nick in var.HEXED:
@ -5161,6 +5202,8 @@ def check_exchange(cli, actor, nick):
if nick_role == "clone": if nick_role == "clone":
pm(cli, actor, messages["clone_target"].format(nick_target)) pm(cli, actor, messages["clone_target"].format(nick_target))
elif nick_role == "wild child":
pm(cli, actor, messages["wild_child_idol"].format(var.IDOLS[actor]))
elif nick_role in var.TOTEM_ORDER: elif nick_role in var.TOTEM_ORDER:
if nick_role == "shaman": if nick_role == "shaman":
pm(cli, actor, messages["shaman_totem"].format(nick_totem)) pm(cli, actor, messages["shaman_totem"].format(nick_totem))
@ -5203,6 +5246,8 @@ def check_exchange(cli, actor, nick):
if actor_role == "clone": if actor_role == "clone":
pm(cli, nick, messages["clone_target"].format(actor_target)) pm(cli, nick, messages["clone_target"].format(actor_target))
elif actor_role == "wild child":
pm(cli, nick, messages["wild_child_idol"].format(var.IDOLS[nick]))
elif actor_role in var.TOTEM_ORDER: elif actor_role in var.TOTEM_ORDER:
if actor_role == "shaman": if actor_role == "shaman":
pm(cli, nick, messages["shaman_totem"].format(actor_totem)) pm(cli, nick, messages["shaman_totem"].format(actor_totem))
@ -5917,7 +5962,9 @@ def see(cli, nick, chan, rest):
victimrole = var.get_role(victim) victimrole = var.get_role(victim)
vrole = victimrole # keep a copy for logging vrole = victimrole # keep a copy for logging
if role == "seer": if role == "seer":
if (victimrole in var.SEEN_WOLF and victimrole not in var.SEEN_DEFAULT) or victim in var.ROLES["cursed villager"]: if victim in var.WILD_CHILDREN:
victimrole = "wild child"
elif (victimrole in var.SEEN_WOLF and victimrole not in var.SEEN_DEFAULT) or victim in var.ROLES["cursed villager"]:
victimrole = "wolf" victimrole = "wolf"
elif victimrole in var.SEEN_DEFAULT: elif victimrole in var.SEEN_DEFAULT:
victimrole = var.DEFAULT_ROLE victimrole = var.DEFAULT_ROLE
@ -6214,8 +6261,9 @@ def change_sides(cli, nick, chan, rest, sendmsg=True):
debuglog("{0} ({1}) SIDE {2}".format(nick, var.get_role(nick), team)) debuglog("{0} ({1}) SIDE {2}".format(nick, var.get_role(nick), team))
chk_nightdone(cli) chk_nightdone(cli)
@cmd("choose", "match", chan=False, pm=True, playing=True, phases=("night",), roles=("matchmaker",)) @cmd("choose", chan=False, pm=True, playing=True, phases=("night",), roles=("matchmaker",))
def choose(cli, nick, chan, rest, sendmsg=True): @cmd("match", chan=False, pm=True, playing=True, phases=("night",), roles=("matchmaker",))
def choose_lovers(cli, nick, chan, rest, sendmsg=True):
"""Select two players to fall in love. You may select yourself as one of the lovers.""" """Select two players to fall in love. You may select yourself as one of the lovers."""
if not var.FIRST_NIGHT: if not var.FIRST_NIGHT:
return return
@ -6484,6 +6532,29 @@ def charm(cli, nick, chan, rest):
chk_nightdone(cli) chk_nightdone(cli)
@cmd("choose", chan=False, pm=True, playing=True, phases=("night",), roles=("wild child",))
def choose_idol(cli, nick, chan, rest):
"""Pick your idol, if they die, you'll become a wolf!"""
if not var.FIRST_NIGHT:
return
if nick in var.IDOLS:
pm(cli, nick, messages["wild_child_already_picked"])
return
victim = get_victim(cli, nick, re.split(" +", rest)[0], False)
if not victim:
return
if nick == victim:
pm(cli, nick, messages["no_target_self"])
return
var.IDOLS[nick] = victim
pm(cli, nick, messages["wild_child_success"].format(victim))
debuglog("{0} ({1}) IDOLIZE: {2} ({3})".format(nick, var.get_role(nick), victim, var.get_role(victim)))
chk_nightdone(cli)
@hook("featurelist") # For multiple targets with PRIVMSG @hook("featurelist") # For multiple targets with PRIVMSG
def getfeatures(cli, nick, *rest): def getfeatures(cli, nick, *rest):
for r in rest: for r in rest:
@ -7152,10 +7223,16 @@ def transition_night(cli):
for lycan in var.ROLES["lycan"]: for lycan in var.ROLES["lycan"]:
if lycan in var.PLAYERS and not is_user_simple(lycan): if lycan in var.PLAYERS and not is_user_simple(lycan):
pm(cli, lycan, (messages["lycan_notify"])) pm(cli, lycan, messages["lycan_notify"])
else: else:
pm(cli, lycan, messages["lycan_simple"]) pm(cli, lycan, messages["lycan_simple"])
for child in var.ROLES["wild child"]:
if child in var.PLAYERS and not is_user_simple(child):
pm(cli, child, messages["child_notify"])
else:
pm(cli, child, messages["child_simple"])
for v_ghost, who in var.VENGEFUL_GHOSTS.items(): for v_ghost, who in var.VENGEFUL_GHOSTS.items():
if who[0] == "!": if who[0] == "!":
continue continue
@ -7579,6 +7656,7 @@ def start(cli, nick, chan, forced = False, restart = ""):
var.SICK = set() var.SICK = set()
var.DULLAHAN_TARGETS = {} var.DULLAHAN_TARGETS = {}
var.DECEIVED = set() var.DECEIVED = set()
var.IDOLS = {}
var.DEADCHAT_PLAYERS = set() var.DEADCHAT_PLAYERS = set()
var.SPECTATING_WOLFCHAT = set() var.SPECTATING_WOLFCHAT = set()
@ -9121,6 +9199,11 @@ if botconfig.DEBUG_MODE or botconfig.ALLOWED_NORMAL_MODE_COMMANDS:
special_case.append("need to kill {0}".format(", ".join(var.DULLAHAN_TARGETS[nickname] - var.DEAD))) special_case.append("need to kill {0}".format(", ".join(var.DULLAHAN_TARGETS[nickname] - var.DEAD)))
else: else:
special_case.append("All targets dead") special_case.append("All targets dead")
elif role == "wild child":
if nickname in var.IDOLS:
special_case.append("picked {0} as idol".format(var.IDOLS[nickname]))
else:
special_case.append("no idol picked yet")
if nickname not in var.ORIGINAL_ROLES[role] and role not in var.TEMPLATE_RESTRICTIONS: if nickname not in var.ORIGINAL_ROLES[role] and role not in var.TEMPLATE_RESTRICTIONS:
for old_role in var.role_order(): # order doesn't matter here, but oh well for old_role in var.role_order(): # order doesn't matter here, but oh well
if nickname in var.ORIGINAL_ROLES[old_role] and nickname not in var.ROLES[old_role]: if nickname in var.ORIGINAL_ROLES[old_role] and nickname not in var.ROLES[old_role]: