def on_update_stats3(evt, var, player, mainrole, revealrole, allroles): # if this is a night death and we know for sure that wolves (and only wolves) # killed, then that kill cannot be traitor as long as they're in wolfchat. wolfchat = get_wolfchat_roles(var) if evt.params.reason != "night_death": # a chained death, someone dying during day, or someone idling out # either way, traitor can die here return if "traitor" not in wolfchat: # wolves can kill traitor normally in this configuration return if "traitor" not in evt.data["possible"]: # not under consideration return if mainrole == "traitor": # definitely dying, so we shouldn't remove them from consideration # this may lead to info leaks, but info leaks are better than !stats just entirely breaking return if in_misdirection_scope(var, Wolf, as_actor=True) or in_misdirection_scope(var, All - wolfchat, as_target=True): # luck/misdirection totems are in play, a wolf kill could have bounced to traitor anyway return if var.PHASE == "day" and var.GAMEPHASE == "night": mevt = Event("get_role_metadata", {}) mevt.dispatch(var, "night_kills") nonwolf = 0 total = 0 for role, num in mevt.data.items(): if role != "wolf": nonwolf += num total += num if nonwolf == 0: evt.data["possible"].discard("traitor") return
def on_reconfigure_stats(evt, var, roleset, reason): from src.roles.helper.wolves import get_wolfchat_roles if reason != "howl" or not LYCANTHROPES or not SCOPE: return evt2 = Event("get_role_metadata", {}) evt2.dispatch(var, "lycanthropy_role") roles = {} wolfchat = get_wolfchat_roles(var) for role, count in roleset.items(): if role in wolfchat or count == 0 or role not in SCOPE: continue if role in evt2.data and "role" in evt2.data[role]: roles[role] = evt2.data[role]["role"] else: roles[role] = "wolf" if roles and roleset in evt.data["new"]: evt.data["new"].remove(roleset) for role, new_role in roles.items(): rs = roleset.copy() rs[role] -= 1 rs[new_role] = rs.get(new_role, 0) + 1 evt.data["new"].append(rs)
def on_reconfigure_stats(evt, var, roleset, reason): from src.roles.helper.wolves import get_wolfchat_roles if reason != "howl" or not SCOPE: return evt2 = Event("get_role_metadata", {}) evt2.dispatch(var, "lycanthropy_role") roles = {} wolfchat = get_wolfchat_roles(var) for role, count in roleset.items(): if role in wolfchat or count == 0 or role not in SCOPE: continue if role in evt2.data and "role" in evt2.data[role]: roles[role] = evt2.data[role]["role"] else: roles[role] = "wolf" if roles and roleset in evt.data["new"]: evt.data["new"].remove(roleset) for role, new_role in roles.items(): rs = roleset.copy() rs[role] -= 1 rs[new_role] = rs.get(new_role, 0) + 1 evt.data["new"].append(rs)
def on_begin_day(evt, var): wroles = get_wolfchat_roles(var) for warlock, target in CURSED.items(): if get_main_role(target) not in wroles: var.ROLES["cursed villager"].add(target) CURSED.clear() PASSED.clear()
def on_revealroles_role(evt, var, user, role): if role == "wild child" and user not in get_players( get_wolfchat_roles(var)): if user in IDOLS: evt.data["special_case"].append( messages["wild_child_revealroles_picked"].format(IDOLS[user])) else: evt.data["special_case"].append( messages["wild_child_revealroles_no_idol"])
def on_transition_night_end(evt, var): wolves = get_players(get_wolfchat_roles(var)) for child in get_all_players(("wild child", )): if child in wolves: continue if child.prefers_simple(): child.send(messages["wild_child_simple"]) else: child.send(messages["wild_child_notify"])
def on_transition_night_end(evt, var): wolves = get_players(get_wolfchat_roles(var)) for child in get_all_players(("wild child",)): if child in wolves: continue if child.prefers_simple(): child.send(messages["wild_child_simple"]) else: child.send(messages["wild_child_notify"])
def investigate(var, wrapper, message): """Investigate a player to determine their exact role.""" if wrapper.source in INVESTIGATED: wrapper.send(messages["already_investigated"]) return target = get_target(var, wrapper, re.split(" +", message)[0], not_self_message="no_investigate_self") if target is None: return target = try_misdirection(var, wrapper.source, target) if try_exchange(var, wrapper.source, target): return targrole = get_main_role(target) evt = Event("investigate", {"role": targrole}) evt.dispatch(var, wrapper.source, target) targrole = evt.data["role"] INVESTIGATED.add(wrapper.source) wrapper.send(messages["investigate_success"].format(target, targrole)) debuglog("{0} (detective) ID: {1} ({2})".format(wrapper.source, target, targrole)) if random.random( ) < var.DETECTIVE_REVEALED_CHANCE: # a 2/5 chance (changeable in settings) # The detective's identity is compromised! wolves = get_all_players(get_wolfchat_roles(var)) if wolves: for wolf in wolves: wolf.queue_message(messages["detective_reveal"].format( wrapper.source)) wolf.send_messages() debuglog("{0} (detective) PAPER DROP".format(wrapper.source))
def on_myrole(evt, var, user): if user in IDOLS and user not in get_players(get_wolfchat_roles(var)): evt.data["messages"].append(messages["wild_child_idol"].format( IDOLS[user]))
def on_myrole(evt, var, user): if user in IDOLS and user not in get_players(get_wolfchat_roles(var)): evt.data["messages"].append(messages["wild_child_idol"].format(IDOLS[user]))
def on_revealroles_role(evt, var, user, role): if role == "wild child" and user not in get_players(get_wolfchat_roles(var)): if user in IDOLS: evt.data["special_case"].append(messages["wild_child_revealroles_picked"].format(IDOLS[user])) else: evt.data["special_case"].append(messages["wild_child_revealroles_no_idol"])