Convert wild child (#338)

* Start conversion of wild child.

* Remove redundant silenced=False.

* Inline random idol selection.

* Use get_players() instead of get_all_players().

* Remove botconfig import.

* Fix checks.

* Remove wild child from wolves when notifying.

* Update listeners.
This commit is contained in:
Ammon Smith 2018-05-26 20:58:59 -07:00 committed by Em Barry
parent afa9a04077
commit e54a3f7672
2 changed files with 78 additions and 89 deletions

View File

@ -225,7 +225,9 @@
"wild_child_success": "You have picked {0} to be 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_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.", "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_revealroles_picked": "picked {0} as idol",
"wild_child_revealroles_no_idol": "no idol picked yet",
"wild_child_idol_died": "Your idol has died, and you are now a \u0002wolf\u0002!",
"wild_child_idol": "Your idol is \u0002{0}\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.",

View File

@ -1,83 +1,67 @@
import random
import re import re
import random
import itertools
import math
from collections import defaultdict
import src.settings as var
from src.utilities import * from src.utilities import *
from src import users, channels, debuglog, errlog, plog from src import channels, users, debuglog, errlog, plog
from src.functions import get_players, get_all_players, get_main_role from src.functions import get_players, get_all_players, get_main_role, get_reveal_role, get_target
from src.decorators import cmd, event_listener from src.decorators import command, event_listener
from src.containers import UserList, UserSet, UserDict, DefaultUserDict from src.containers import UserList, UserSet, UserDict, DefaultUserDict
from src.messages import messages from src.messages import messages
from src.events import Event from src.events import Event
WILD_CHILDREN = set() WILD_CHILDREN = UserSet()
IDOLS = {} IDOLS = UserDict()
@cmd("choose", chan=False, pm=True, playing=True, phases=("night",), roles=("wild child",)) @command("choose", chan=False, pm=True, playing=True, phases=("night",), roles=("wild child",))
def choose_idol(cli, nick, chan, rest): def choose_idol(var, wrapper, message):
"""Pick your idol, if they die, you'll become a wolf!""" """Pick your idol, if they die, you'll become a wolf!"""
if not var.FIRST_NIGHT: if not var.FIRST_NIGHT:
return return
if nick in IDOLS: if wrapper.source in IDOLS:
pm(cli, nick, messages["wild_child_already_picked"]) wrapper.pm(messages["wild_child_already_picked"])
return return
victim = get_victim(cli, nick, re.split(" +", rest)[0], False) idol = get_target(var, wrapper, re.split(" +", message)[0])
if not victim: if not idol:
return return
if nick == victim: IDOLS[wrapper.source] = idol
pm(cli, nick, messages["no_target_self"]) wrapper.send(messages["wild_child_success"].format(idol))
return debuglog("{0} (wild child) IDOLIZE: {1} ({2})".format(wrapper.source, idol, get_main_role(idol)))
IDOLS[nick] = victim
pm(cli, nick, messages["wild_child_success"].format(victim))
debuglog("{0} (wild child) IDOLIZE: {1} ({2})".format(nick, victim, get_role(victim)))
@event_listener("see") @event_listener("see")
def on_see(evt, var, seer, target): def on_see(evt, var, seer, target):
if target.nick in WILD_CHILDREN: if target in WILD_CHILDREN:
evt.data["role"] = "wild child" evt.data["role"] = "wild child"
@event_listener("rename_player")
def on_rename(evt, var, prefix, nick):
if prefix in WILD_CHILDREN:
WILD_CHILDREN.remove(prefix)
WILD_CHILDREN.add(nick)
for (wildchild, idol) in IDOLS.items():
if wildchild == prefix:
IDOLS[nick] = IDOLS[wildchild]
del IDOLS[wildchild]
elif idol == prefix:
IDOLS[wildchild] = nick
@event_listener("exchange_roles") @event_listener("exchange_roles")
def on_exchange(evt, var, actor, target, actor_role, target_role): def on_exchange(evt, var, actor, target, actor_role, target_role):
if actor_role == "wolf" and actor.nick in WILD_CHILDREN and target.nick not in WILD_CHILDREN: if actor_role == "wolf" and actor in WILD_CHILDREN and target not in WILD_CHILDREN:
WILD_CHILDREN.discard(actor.nick) WILD_CHILDREN.discard(actor)
WILD_CHILDREN.add(target.nick) WILD_CHILDREN.add(target)
elif actor_role == "wild child": elif actor_role == "wild child":
if target_role == "wild child": if target_role == "wild child":
IDOLS[actor.nick], IDOLS[target.nick] = IDOLS[target.nick], IDOLS[actor.nick] IDOLS[actor], IDOLS[target] = IDOLS[target], IDOLS[actor]
evt.data["actor_messages"].append(messages["wild_child_idol"].format(IDOLS[actor.nick])) evt.data["actor_messages"].append(messages["wild_child_idol"].format(IDOLS[actor]))
evt.data["target_messages"].append(messages["wild_child_idol"].format(IDOLS[target.nick])) evt.data["target_messages"].append(messages["wild_child_idol"].format(IDOLS[target]))
else: else:
IDOLS[target.nick] = IDOLS.pop(actor.nick) IDOLS[target] = IDOLS.pop(actor)
evt.data["target_messages"].append(messages["wild_child_idol"].format(IDOLS[target.nick])) evt.data["target_messages"].append(messages["wild_child_idol"].format(IDOLS[target]))
if target_role == "wolf" and target.nick in WILD_CHILDREN and actor.nick not in WILD_CHILDREN: if target_role == "wolf" and target in WILD_CHILDREN and actor not in WILD_CHILDREN:
WILD_CHILDREN.discard(target.nick) WILD_CHILDREN.discard(target)
WILD_CHILDREN.add(actor.nick) WILD_CHILDREN.add(actor)
elif target_role == "wild child" and actor_role != "wild child": elif target_role == "wild child" and actor_role != "wild child":
# if they're both wild children, already swapped idols above # if they're both wild children, already swapped idols above
IDOLS[actor.nick] = IDOLS.pop(target.nick) IDOLS[actor] = IDOLS.pop(target)
evt.data["actor_messages"].append(messages["wild_child_idol"].format(IDOLS[actor.nick])) evt.data["actor_messages"].append(messages["wild_child_idol"].format(IDOLS[actor]))
@event_listener("myrole") @event_listener("myrole")
def on_myrole(evt, var, user): def on_myrole(evt, var, user):
if user.nick in IDOLS: if user in IDOLS:
evt.data["messages"].append(messages["wild_child_idol"].format(IDOLS[user.nick])) evt.data["messages"].append(messages["wild_child_idol"].format(IDOLS[user]))
@event_listener("del_player") @event_listener("del_player")
def on_del_player(evt, var, user, mainrole, allroles, death_triggers): def on_del_player(evt, var, user, mainrole, allroles, death_triggers):
@ -85,41 +69,42 @@ def on_del_player(evt, var, user, mainrole, allroles, death_triggers):
return return
for child in get_all_players(("wild child",)): for child in get_all_players(("wild child",)):
if child.nick not in IDOLS or child in evt.params.deadlist or users._get(IDOLS[child.nick]) not in evt.params.deadlist: # FIXME if child in evt.params.deadlist or IDOLS.get(child) not in evt.params.deadlist:
continue continue
# change their main role to wolf, even if wild child was a template # Change their main role to wolf
child.send(messages["idol_died"]) child.send(messages["wild_child_idol_died"])
WILD_CHILDREN.add(child.nick) WILD_CHILDREN.add(child)
change_role(child, get_main_role(child), "wolf") change_role(child, get_main_role(child), "wolf")
var.ROLES["wild child"].discard(child) var.ROLES["wild child"].discard(child)
wcroles = var.WOLFCHAT_ROLES
if var.RESTRICT_WOLFCHAT & var.RW_REM_NON_WOLVES: if var.RESTRICT_WOLFCHAT & var.RW_REM_NON_WOLVES:
if var.RESTRICT_WOLFCHAT & var.RW_TRAITOR_NON_WOLF: if var.RESTRICT_WOLFCHAT & var.RW_TRAITOR_NON_WOLF:
wcroles = var.WOLF_ROLES wcroles = var.WOLF_ROLES
else: else:
wcroles = var.WOLF_ROLES | {"traitor"} wcroles = var.WOLF_ROLES | {"traitor"}
wolves = get_players(wcroles)
wolves.remove(child)
if wolves:
for wolf in wolves:
wolf.queue_message(messages["wild_child_as_wolf"].format(child))
wolf.send_messages()
if var.PHASE == "day":
random.shuffle(wolves)
new = []
for i, wolf in enumerate(wolves):
wolfroles = get_main_role(wolf)
cursed = ""
if wolf in get_all_players(("cursed villager",)):
cursed = "cursed "
new.append("\u0002{0}\u0002 ({1}{2})".format(wolf, cursed, wolfroles))
if new: wolves = get_players(wcroles)
child.send(messages["wolves_list"].format(", ".join(new))) wolves.remove(child)
else: if wolves:
child.send(messages["no_other_wolves"]) for wolf in wolves:
wolf.queue_message(messages["wild_child_as_wolf"].format(child))
wolf.send_messages()
# Send wolf list
if var.PHASE == "day":
random.shuffle(wolves)
names = []
cursed_list = get_all_players(("cursed villager",))
for i, wolf in enumerate(wolves):
role = get_main_role(wolf)
cursed = "cursed " if wolf in cursed_list else ""
names.append("\u0002{0}\u0002 ({1}{2})".format(wolf, cursed, role))
if names:
child.send(messages["wolves_list"].format(", ".join(names)))
else:
child.send(messages["no_other_wolves"])
@event_listener("chk_nightdone") @event_listener("chk_nightdone")
def on_chk_nightdone(evt, var): def on_chk_nightdone(evt, var):
@ -131,33 +116,35 @@ def on_chk_nightdone(evt, var):
def on_transition_day_begin(evt, var): def on_transition_day_begin(evt, var):
if (not var.START_WITH_DAY or not var.FIRST_DAY) and var.FIRST_NIGHT: if (not var.START_WITH_DAY or not var.FIRST_DAY) and var.FIRST_NIGHT:
for child in get_all_players(("wild child",)): for child in get_all_players(("wild child",)):
if child.nick not in IDOLS: if child not in IDOLS:
pl = get_players() players = get_players()
pl.remove(child) players.remove(child)
if pl: if players:
target = random.choice(pl) idol = random.choice(players)
IDOLS[child.nick] = target.nick IDOLS[child] = idol
child.send(messages["wild_child_random_idol"].format(target)) child.send(messages["wild_child_random_idol"].format(idol))
idol_role = get_main_role(idol)
debuglog("{0} (wild child) IDOLIZE RANDOM: {1} ({2})".format(child, idol, idol_role))
@event_listener("transition_night_end", priority=2) @event_listener("transition_night_end", priority=2)
def on_transition_night_end(evt, var): def on_transition_night_end(evt, var):
for child in get_all_players(("wild child",)): for child in get_all_players(("wild child",)):
to_send = "child_notify"
if child.prefers_simple(): if child.prefers_simple():
to_send = "child_simple" child.send(messages["child_simple"])
child.send(messages[to_send]) else:
child.send(messages["child_notify"])
@event_listener("revealroles_role") @event_listener("revealroles_role")
def on_revealroles_role(evt, var, user, role): def on_revealroles_role(evt, var, user, role):
if role == "wild child": if role == "wild child":
if user.nick in IDOLS: if user in IDOLS:
evt.data["special_case"].append("picked {0} as idol".format(IDOLS[user.nick])) evt.data["special_case"].append(messages["wild_child_revealroles_picked"].format(IDOLS[user]))
else: else:
evt.data["special_case"].append("no idol picked yet") evt.data["special_case"].append(messages["wild_child_revealroles_no_idol"])
@event_listener("get_reveal_role") @event_listener("get_reveal_role")
def on_get_reveal_role(evt, var, user): def on_get_reveal_role(evt, var, user):
if user.nick in WILD_CHILDREN: if user in WILD_CHILDREN:
evt.data["role"] = "wild child" evt.data["role"] = "wild child"
@event_listener("reset") @event_listener("reset")