def hunter_kill(var, wrapper, message): """Kill someone once per game.""" if wrapper.source in HUNTERS and wrapper.source not in KILLS: wrapper.pm(messages["hunter_already_killed"]) return target = get_target(var, wrapper, re.split(" +", message)[0], not_self_message="no_suicide") if not target: return orig = target target = try_misdirection(var, wrapper.source, target) if try_exchange(var, wrapper.source, target): return KILLS[wrapper.source] = target HUNTERS.add(wrapper.source) PASSED.discard(wrapper.source) wrapper.pm(messages["player_kill"].format(orig)) debuglog("{0} (hunter) KILL: {1} ({2})".format(wrapper.source, target, get_main_role(target)))
def immunize(var, wrapper, message): """Immunize a player, preventing them from turning into a wolf.""" if not DOCTORS[wrapper.source]: wrapper.pm(messages["doctor_fail"]) return target = get_target(var, wrapper, re.split(" +", message)[0], allow_self=True) if not target: return target = try_misdirection(var, wrapper.source, target) if try_exchange(var, wrapper.source, target): return doctor_evt = Event("doctor_immunize", {"message": "villager_immunized"}) doctor_evt.dispatch(var, wrapper.source, target) wrapper.pm(messages["doctor_success"].format(target)) target.send(messages["immunization_success"].format(messages[doctor_evt.data["message"]])) IMMUNIZED.add(target) DOCTORS[wrapper.source] -= 1 remove_lycanthropy(var, target) remove_disease(var, target) debuglog("{0} (doctor) IMMUNIZE: {1} ({2})".format(wrapper.source, target, get_main_role(target)))
def see(var, wrapper, message): """Use your paranormal senses to determine a player's doom.""" if wrapper.source in SEEN: wrapper.send(messages["seer_fail"]) return target = get_target(var, wrapper, re.split(" +", message)[0], not_self_message="no_see_self") if not target: return if is_known_wolf_ally(var, wrapper.source, target): wrapper.send(messages["no_see_wolf"]) return target = try_misdirection(var, wrapper.source, target) if try_exchange(var, wrapper.source, target): return targrole = get_main_role(target) mode, mapping = random.choice(_mappings) wrapper.send(messages["doomsayer_{0}".format(mode)].format(target)) mapping[wrapper.source] = target debuglog("{0} (doomsayer) SEE: {1} ({2}) - {3}".format(wrapper.source, target, targrole, mode.upper())) relay_wolfchat_command(wrapper.client, wrapper.source.nick, messages["doomsayer_wolfchat"].format(wrapper.source, target), ("doomsayer",), is_wolf_command=True) SEEN.add(wrapper.source)
def hvisit(var, wrapper, message): """Visit a player. You will die if you visit a wolf or a target of the wolves.""" if VISITED.get(wrapper.source): wrapper.pm(messages["harlot_already_visited"].format(VISITED[wrapper.source])) return target = get_target(var, wrapper, re.split(" +", message)[0], not_self_message="harlot_not_self") if not target: return target = try_misdirection(var, wrapper.source, target) if try_exchange(var, wrapper.source, target): return vrole = get_main_role(target) VISITED[wrapper.source] = target PASSED.discard(wrapper.source) wrapper.pm(messages["harlot_success"].format(target)) if target is not wrapper.source: target.send(messages["harlot_success"].format(wrapper.source)) revt = Event("harlot_visit", {}) revt.dispatch(var, wrapper.source, target) debuglog("{0} (harlot) VISIT: {1} ({2})".format(wrapper.source, target, vrole))
def observe(var, wrapper, message): """Turn a player into a wolf!""" if not ENABLED: wrapper.pm(messages["alpha_no_bite"]) return if wrapper.source in ALPHAS: wrapper.pm(messages["alpha_already_bit"]) return target = get_target(var, wrapper, re.split(" +", message)[0]) if not target: return if is_known_wolf_ally(var, wrapper.source, target): wrapper.pm(messages["alpha_no_bite_wolf"]) return orig = target target = try_misdirection(var, wrapper.source, target) if try_exchange(var, wrapper.source, target): return BITTEN[wrapper.source] = target wrapper.pm(messages["alpha_bite_target"].format(orig)) send_wolfchat_message(var, wrapper.source, messages["alpha_bite_wolfchat"].format( wrapper.source, target), {"alpha wolf"}, role="alpha wolf", command="bite") debuglog("{0} (alpha wolf) BITE: {1} ({2})".format(wrapper.source, target, get_main_role(target)))
def observe(var, wrapper, message): """Observe a player to obtain various information.""" target = get_target(var, wrapper, re.split(" +", message)[0], not_self_message="no_observe_self") if not target: return if wrapper.source in OBSERVED: wrapper.pm(messages["already_observed"]) return if is_known_wolf_ally(var, wrapper.source, target): wrapper.pm(messages["no_observe_wolf"]) return target = try_misdirection(var, wrapper.source, target) if try_exchange(var, wrapper.source, target): return OBSERVED.add(wrapper.source) targrole = get_main_role(target) if targrole == "amnesiac": from src.roles.amnesiac import ROLES as amn_roles targrole = amn_roles[target] key = "sorcerer_fail" if targrole in Spy: key = "sorcerer_success" wrapper.pm(messages[key].format(target, targrole)) send_wolfchat_message(var, wrapper.source, messages["sorcerer_success_wolfchat"].format(wrapper.source, target), {"sorcerer"}, role="sorcerer", command="observe") debuglog("{0} (sorcerer) OBSERVE: {1} ({2})".format(wrapper.source, target, targrole))
def dullahan_kill(var, wrapper, message): """Kill someone at night as a dullahan until everyone on your list is dead.""" if not TARGETS[wrapper.source] & set(get_players()): wrapper.pm(messages["dullahan_targets_dead"]) return target = get_target(var, wrapper, re.split(" +", message)[0], not_self_message="no_suicide") if not target: return orig = target target = try_misdirection(var, wrapper.source, target) if try_exchange(var, wrapper.source, target): return target = evt.data["target"] KILLS[wrapper.source] = target wrapper.pm(messages["player_kill"].format(orig)) debuglog("{0} (dullahan) KILL: {1} ({2})".format(wrapper.source, target, get_main_role(target)))
def hex_cmd(var, wrapper, message): """Hex someone, preventing them from acting the next day and night.""" if wrapper.source in HEXED: wrapper.pm(messages["already_hexed"]) return target = get_target(var, wrapper, re.split(" +", message)[0]) if not target: return if LASTHEXED.get(wrapper.source) is target: wrapper.pm(messages["no_multiple_hex"].format(target)) return target = try_misdirection(var, wrapper.source, target) if try_exchange(var, wrapper.source, target): return if is_known_wolf_ally(var, wrapper.source, target): wrapper.pm(messages["no_hex_wolf"]) return HEXED[wrapper.source] = target wrapper.pm(messages["hex_success"].format(target)) send_wolfchat_message(var, wrapper.source, messages["hex_success_wolfchat"].format(wrapper.source, target), {"hag"}, role="hag", command="hex") debuglog("{0} (hag) HEX: {1} ({2})".format(wrapper.source, target, get_main_role(target)))
def curse(var, wrapper, message): target = get_target(var, wrapper, re.split(" +", message)[0]) if not target: return if target in get_all_players(("cursed villager",)): wrapper.pm(messages["target_already_cursed"].format(target)) return # There may actually be valid strategy in cursing other wolfteam members, # but for now it is not allowed. If someone seems suspicious and shows as # villager across multiple nights, safes can use that as a tell that the # person is likely wolf-aligned. if is_known_wolf_ally(var, wrapper.source, target): wrapper.pm(messages["no_curse_wolf"]) return orig = target target = try_misdirection(var, wrapper.source, target) if try_exchange(var, wrapper.source, target): return CURSED[wrapper.source] = target PASSED.discard(wrapper.source) wrapper.pm(messages["curse_success"].format(orig)) send_wolfchat_message(var, wrapper.source, messages["curse_success_wolfchat"].format(wrapper.source, orig), {"warlock"}, role="warlock", command="curse") debuglog("{0} (warlock) CURSE: {1} ({2})".format(wrapper.source, target, get_main_role(target)))
def immunize(var, wrapper, message): """Immunize a player, preventing them from turning into a wolf.""" if not DOCTORS[wrapper.source]: wrapper.pm(messages["doctor_fail"]) return target = get_target(var, wrapper, re.split(" +", message)[0], allow_self=True) if not target: return target = try_misdirection(var, wrapper.source, target) if try_exchange(var, wrapper.source, target): return doctor_evt = Event("doctor_immunize", {"message": "villager_immunized"}) doctor_evt.dispatch(var, wrapper.source, target) wrapper.pm(messages["doctor_success"].format(target)) target.send(messages["immunization_success"].format( messages[doctor_evt.data["message"]])) IMMUNIZED.add(target) DOCTORS[wrapper.source] -= 1 remove_lycanthropy(var, target) remove_disease(var, target) debuglog("{0} (doctor) IMMUNIZE: {1} ({2})".format(wrapper.source, target, get_main_role(target)))
def curse(var, wrapper, message): target = get_target(var, wrapper, re.split(" +", message)[0]) if not target: return if target in get_all_players(("cursed villager", )): wrapper.pm(messages["target_already_cursed"].format(target)) return # There may actually be valid strategy in cursing other wolfteam members, # but for now it is not allowed. If someone seems suspicious and shows as # villager across multiple nights, safes can use that as a tell that the # person is likely wolf-aligned. if is_known_wolf_ally(var, wrapper.source, target): wrapper.pm(messages["no_curse_wolf"]) return orig = target target = try_misdirection(var, wrapper.source, target) if try_exchange(var, wrapper.source, target): return CURSED[wrapper.source] = target PASSED.discard(wrapper.source) wrapper.pm(messages["curse_success"].format(orig)) send_wolfchat_message(var, wrapper.source, messages["curse_success_wolfchat"].format( wrapper.source, orig), {"warlock"}, role="warlock", command="curse") debuglog("{0} (warlock) CURSE: {1} ({2})".format(wrapper.source, target, get_main_role(target)))
def vg_kill(var, wrapper, message): """Take revenge on someone each night after you die.""" if GHOSTS[wrapper.source][0] == "!": return target = get_target(var, wrapper, re.split(" +", message)[0]) if not target: return if target is wrapper.source: wrapper.pm(messages["player_dead"]) return wolves = get_players(Wolfteam) if GHOSTS[wrapper.source] == "wolves" and target not in wolves: wrapper.pm(messages["vengeful_ghost_wolf"]) return elif GHOSTS[wrapper.source] == "villagers" and target in wolves: wrapper.pm(messages["vengeful_ghost_villager"]) return orig = target target = try_misdirection(var, wrapper.source, target) KILLS[wrapper.source] = target wrapper.pm(messages["player_kill"].format(orig)) debuglog("{0} (vengeful ghost) KILL: {1} ({2})".format(wrapper.source, target, get_main_role(target)))
def see(var, wrapper, message): """Use your paranormal powers to determine the role or alignment of a player.""" if wrapper.source in SEEN: wrapper.send(messages["seer_fail"]) return target = get_target(var, wrapper, re.split(" +", message)[0], not_self_message="no_see_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) trole = targrole # keep a copy for logging evt = Event("investigate", {"role": targrole}) evt.dispatch(var, wrapper.source, target) targrole = evt.data["role"] aura = "blue" if targrole in Wolfteam: aura = "red" elif targrole in Neutral: aura = "grey" wrapper.send(messages["augur_success"].format(target, aura)) debuglog("{0} (augur) SEE: {1} ({2}) as {3} ({4} aura)".format(wrapper.source, target, trole, targrole, aura)) SEEN.add(wrapper.source)
def observe(var, wrapper, message): """Observe a player to obtain various information.""" target = get_target(var, wrapper, re.split(" +", message)[0], not_self_message="no_observe_self") if not target: return if wrapper.source in OBSERVED: wrapper.pm(messages["already_observed"]) return if is_known_wolf_ally(var, wrapper.source, target): wrapper.pm(messages["no_observe_wolf"]) return target = try_misdirection(var, wrapper.source, target) if try_exchange(var, wrapper.source, target): return OBSERVED.add(wrapper.source) targrole = get_main_role(target) if targrole == "amnesiac": from src.roles.amnesiac import ROLES as amn_roles targrole = amn_roles[target] an = "" key = "sorcerer_fail" if targrole in Spy: if targrole.startswith(("a", "e", "i", "o", "u")): an = "n" key = "sorcerer_success" wrapper.pm(messages[key].format(target, an, targrole)) send_wolfchat_message(var, wrapper.source, messages["sorcerer_success_wolfchat"].format(wrapper.source, target), {"sorcerer"}, role="sorcerer", command="observe") debuglog("{0} (sorcerer) OBSERVE: {1} ({2})".format(wrapper.source, target, targrole))
def hvisit(var, wrapper, message): """Entrance a player, converting them to your team.""" if VISITED.get(wrapper.source): wrapper.send(messages["succubus_already_visited"].format(VISITED[wrapper.source])) return target = get_target(var, wrapper, re.split(" +", message)[0], not_self_message="succubus_not_self") if not target: return target = try_misdirection(var, wrapper.source, target) if try_exchange(var, wrapper.source, target): return VISITED[wrapper.source] = target PASSED.discard(wrapper.source) if target not in get_all_players(("succubus",)): ENTRANCED.add(target) wrapper.send(messages["succubus_target_success"].format(target)) else: wrapper.send(messages["harlot_success"].format(target)) if wrapper.source is not target: if target not in get_all_players(("succubus",)): target.send(messages["notify_succubus_target"].format(wrapper.source)) else: target.send(messages["harlot_success"].format(wrapper.source)) revt = Event("succubus_visit", {}) revt.dispatch(var, wrapper.source, target) debuglog("{0} (succubus) VISIT: {1} ({2})".format(wrapper.source, target, get_main_role(target)))
def guard(var, wrapper, message): """Guard a player, preventing them from being killed that night.""" if wrapper.source in GUARDED: wrapper.pm(messages["already_protecting"]) return target = get_target(var, wrapper, re.split(" +", message)[0], allow_self=var.GUARDIAN_ANGEL_CAN_GUARD_SELF, not_self_message="cannot_guard_self") if not target: return if LASTGUARDED.get(wrapper.source) is target: wrapper.pm(messages["guardian_target_another"].format(target)) return target = try_misdirection(var, wrapper.source, target) if try_exchange(var, wrapper.source, target): return add_protection(var, target, wrapper.source, "guardian angel") GUARDED[wrapper.source] = target LASTGUARDED[wrapper.source] = target if wrapper.source is target: wrapper.pm(messages["guardian_guard_self"]) else: wrapper.pm(messages["protecting_target"].format(target)) target.send(messages["target_protected"]) debuglog("{0} (guardian angel) GUARD: {1} ({2})".format(wrapper.source, target, get_main_role(target)))
def see(var, wrapper, message): """Use your paranormal powers to determine the role or alignment of a player.""" if wrapper.source in SEEN: wrapper.send(messages["seer_fail"]) return target = get_target(var, wrapper, re.split(" +", message)[0], not_self_message="no_see_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) trole = targrole # keep a copy for logging evt = Event("investigate", {"role": targrole}) evt.dispatch(var, wrapper.source, target) targrole = evt.data["role"] aura = "blue" if targrole in Wolfteam: aura = "red" elif targrole in Neutral: aura = "grey" wrapper.send(messages["augur_success"].format(target, aura)) debuglog("{0} (augur) SEE: {1} ({2}) as {3} ({4} aura)".format( wrapper.source, target, trole, targrole, aura)) SEEN.add(wrapper.source)
def hvisit(var, wrapper, message): """Visit a player. You will die if you visit a wolf or a target of the wolves.""" if VISITED.get(wrapper.source): wrapper.pm(messages["harlot_already_visited"].format( VISITED[wrapper.source])) return if wrapper.source in FORCE_PASSED: wrapper.pm(messages["already_being_visited"]) return target = get_target(var, wrapper, re.split(" +", message)[0], not_self_message="harlot_not_self") if not target: return target = try_misdirection(var, wrapper.source, target) if try_exchange(var, wrapper.source, target): return vrole = get_main_role(target) VISITED[wrapper.source] = target PASSED.discard(wrapper.source) wrapper.pm(messages["harlot_success"].format(target)) if target is not wrapper.source: target.send(messages["harlot_success"].format(wrapper.source)) revt = Event("visit", {}) revt.dispatch(var, "harlot", wrapper.source, target) debuglog("{0} (harlot) VISIT: {1} ({2})".format(wrapper.source, target, vrole))
def observe(var, wrapper, message): """Observe a player to see whether they are able to act at night.""" if wrapper.source in OBSERVED: wrapper.pm(messages["werecrow_already_observing"].format( OBSERVED[wrapper.source])) return target = get_target(var, wrapper, re.split(" +", message)[0], not_self_message="werecrow_no_observe_self") if not target: return if is_known_wolf_ally(var, wrapper.source, target): wrapper.pm(messages["werecrow_no_target_wolf"]) return orig = target target = try_misdirection(var, wrapper.source, target) if try_exchange(var, wrapper.source, target): return OBSERVED[wrapper.source] = target wrapper.pm(messages["werecrow_observe_success"].format(orig)) send_wolfchat_message(var, wrapper.source, messages["wolfchat_observe"].format( wrapper.source, target), {"werecrow"}, role="werecrow", command="observe") debuglog("{0} (werecrow) OBSERVE: {1} ({2})".format( wrapper.source, target, get_main_role(target)))
def hex_cmd(var, wrapper, message): """Hex someone, preventing them from acting the next day and night.""" if wrapper.source in HEXED: wrapper.pm(messages["already_hexed"]) return target = get_target(var, wrapper, re.split(" +", message)[0]) if not target: return if LASTHEXED.get(wrapper.source) is target: wrapper.pm(messages["no_multiple_hex"].format(target)) return target = try_misdirection(var, wrapper.source, target) if try_exchange(var, wrapper.source, target): return if is_known_wolf_ally(var, wrapper.source, target): wrapper.pm(messages["no_hex_wolf"]) return HEXED[wrapper.source] = target wrapper.pm(messages["hex_success"].format(target)) send_wolfchat_message(var, wrapper.source, messages["hex_success_wolfchat"].format( wrapper.source, target), {"hag"}, role="hag", command="hex") debuglog("{0} (hag) HEX: {1} ({2})".format(wrapper.source, target, get_main_role(target)))
def guard(var, wrapper, message): """Guard a player, preventing them from being killed that night.""" if wrapper.source in GUARDED: wrapper.pm(messages["already_protecting"]) return target = get_target(var, wrapper, re.split(" +", message)[0], allow_self=var.GUARDIAN_ANGEL_CAN_GUARD_SELF, not_self_message="cannot_guard_self") if not target: return if LASTGUARDED.get(wrapper.source) is target: wrapper.pm(messages["guardian_target_another"].format(target)) return target = try_misdirection(var, wrapper.source, target) if try_exchange(var, wrapper.source, target): return add_protection(var, target, wrapper.source, "guardian angel") GUARDED[wrapper.source] = target LASTGUARDED[wrapper.source] = target if wrapper.source is target: wrapper.pm(messages["guardian_guard_self"]) else: wrapper.pm(messages["protecting_target"].format(target)) target.send(messages["target_protected"]) debuglog("{0} (guardian angel) GUARD: {1} ({2})".format( wrapper.source, target, get_main_role(target)))
def wolf_kill(var, wrapper, message): """Kill one or more players as a wolf.""" # verify this user can actually kill if not get_all_roles(wrapper.source) & Wolf & Killer: return pieces = re.split(" +", message) targets = [] orig = [] nevt = Event("wolf_numkills", {"numkills": 1, "message": ""}) nevt.dispatch(var) num_kills = nevt.data["numkills"] if not num_kills: if nevt.data["message"]: wrapper.pm(messages[nevt.data["message"]]) return if len(pieces) < num_kills: wrapper.pm(messages["wolf_must_target_multiple"]) return for targ in pieces[:num_kills]: target = get_target(var, wrapper, targ, not_self_message="no_suicide") if target is None: return if is_known_wolf_ally(var, wrapper.source, target): wrapper.pm(messages["wolf_no_target_wolf"]) return if target in orig: wrapper.pm(messages["wolf_must_target_multiple"]) return orig.append(target) target = try_misdirection(var, wrapper.source, target) if try_exchange(var, wrapper.source, target): return targets.append(target) KILLS[wrapper.source] = UserList(targets) if len(orig) > 1: wrapper.pm(messages["player_kill_multiple"].format(orig)) msg = messages["wolfchat_kill_multiple"].format(wrapper.source, orig) debuglog("{0} KILL: {1} ({3}) and {2} ({4})".format(wrapper.source, targets[0], targets[1], get_main_role(targets[0]), get_main_role(targets[1]))) else: wrapper.pm(messages["player_kill"].format(orig[0])) msg = messages["wolfchat_kill"].format(wrapper.source, orig[0]) debuglog("{0} KILL: {1} ({2})".format(wrapper.source, targets[0], get_main_role(targets[0]))) send_wolfchat_message(var, wrapper.source, msg, Wolf, role="wolf", command="kill")
def wolf_kill(var, wrapper, message): """Kill one or more players as a wolf.""" pieces = re.split(" +", message) targets = [] orig = [] nevt = Event("wolf_numkills", {"numkills": 1, "message": ""}) nevt.dispatch(var) num_kills = nevt.data["numkills"] if not num_kills: if nevt.data["message"]: wrapper.pm(messages[nevt.data["message"]]) return if len(pieces) < num_kills: wrapper.pm(messages["wolf_must_target_multiple"]) return for targ in pieces[:num_kills]: target = get_target(var, wrapper, targ, not_self_message="no_suicide") if target is None: return if is_known_wolf_ally(var, wrapper.source, target): wrapper.pm(messages["wolf_no_target_wolf"]) return if target in orig: wrapper.pm(messages["wolf_must_target_multiple"]) return orig.append(target) target = try_misdirection(var, wrapper.source, target) if try_exchange(var, wrapper.source, target): return targets.append(target) KILLS[wrapper.source] = UserList(targets) if len(orig) > 1: # TODO: Expand this so we can support arbitrarily many kills (instead of just one or two) wrapper.pm(messages["player_kill_multiple"].format(*orig)) msg = messages["wolfchat_kill_multiple"].format(wrapper.source, *orig) debuglog("{0} ({1}) KILL: {2} ({4}) and {3} ({5})".format(wrapper.source, rolename, *targets, get_main_role(targets[0]), get_main_role(targets[1]))) else: wrapper.pm(messages["player_kill"].format(orig[0])) msg = messages["wolfchat_kill"].format(wrapper.source, orig[0]) debuglog("{0} ({1}) KILL: {2} ({3})".format(wrapper.source, rolename, targets[0], get_main_role(targets[0]))) send_wolfchat_message(var, wrapper.source, msg, Wolf, role=rolename, command="kill")
def vigilante_kill(var, wrapper, message): """Kill someone at night, but you die too if they aren't a wolf or win stealer!""" target = get_target(var, wrapper, re.split(" +", message)[0], not_self_message="no_suicide") orig = target target = try_misdirection(var, wrapper.source, target) if try_exchange(var, wrapper.source, target): return KILLS[wrapper.source] = target PASSED.discard(wrapper.source) wrapper.send(messages["player_kill"].format(orig)) debuglog("{0} (vigilante) KILL: {1} ({2})".format(wrapper.source, target, get_main_role(target)))
def see(var, wrapper, message): """Use your paranormal powers to determine the role or alignment of a player.""" if wrapper.source in SEEN: wrapper.send(messages["seer_fail"]) return target = get_target(var, wrapper, re.split(" +", message)[0], not_self_message="no_see_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) trole = targrole # keep a copy for logging for i in range(2): # need to go through loop twice iswolf = False if targrole in Cursed: targrole = "wolf" iswolf = True elif targrole in Safe | Innocent: targrole = var.HIDDEN_ROLE elif targrole in Wolf: targrole = "wolf" iswolf = True else: targrole = var.HIDDEN_ROLE if i: break evt = Event("see", {"role": targrole}) evt.dispatch(var, wrapper.source, target) targrole = evt.data["role"] wrapper.send(messages["oracle_success"].format( target, "" if iswolf else "\u0002not\u0002 ", "\u0002" if iswolf else "")) debuglog("{0} (oracle) SEE: {1} ({2}) (Wolf: {3})".format( wrapper.source, target, trole, str(iswolf))) SEEN.add(wrapper.source)
def give_totem(var, wrapper, target, prefix, role, msg): """Give a totem to a player. Return the value of SHAMANS[user].""" orig_target = target orig_role = get_main_role(orig_target) target = try_misdirection(var, wrapper.source, target) if try_exchange(var, wrapper.source, target): return targrole = get_main_role(target) wrapper.send(messages["shaman_success"].format(prefix, msg, orig_target)) debuglog("{0} ({1}) TOTEM: {2} ({3}) as {4} ({5})".format( wrapper.source, role, target, targrole, orig_target, orig_role)) return UserList((target, orig_target))
def give_totem(var, wrapper, target, totem, *, key, role) -> Optional[Tuple[users.User, users.User]]: """Give a totem to a player.""" orig_target = target orig_role = get_main_role(orig_target) target = try_misdirection(var, wrapper.source, target) if try_exchange(var, wrapper.source, target): return targrole = get_main_role(target) # keys: shaman_success_night_known, shaman_success_random_known, shaman_success_night_unknown, shaman_success_random_unknown wrapper.send(messages[key].format(orig_target, totem)) debuglog("{0} ({1}) TOTEM: {2} ({3}) as {4} ({5}): {6}".format(wrapper.source, role, target, targrole, orig_target, orig_role, totem)) return target, orig_target
def bless(var, wrapper, message): """Bless a player, preventing them from being killed for the remainder of the game.""" if wrapper.source in PRIESTS: wrapper.pm(messages["already_blessed"]) return target = get_target(var, wrapper, re.split(" +", message)[0], not_self_message="no_bless_self") if not target: return target = try_misdirection(var, wrapper.source, target) if try_exchange(var, wrapper.source, target): return PRIESTS.add(wrapper.source) var.ROLES["blessed villager"].add(target) wrapper.pm(messages["blessed_success"].format(target)) target.send(messages["blessed_notify_target"]) debuglog("{0} (priest) BLESS: {1} ({2})".format(wrapper.source, target, get_main_role(target)))
def dullahan_kill(var, wrapper, message): """Kill someone at night as a dullahan until everyone on your list is dead.""" if not TARGETS[wrapper.source] & set(get_players()): wrapper.pm(messages["dullahan_targets_dead"]) return target = get_target(var, wrapper, re.split(" +", message)[0], not_self_message="no_suicide") if not target: return orig = target target = try_misdirection(var, wrapper.source, target) if try_exchange(var, wrapper.source, target): return KILLS[wrapper.source] = target wrapper.pm(messages["player_kill"].format(orig)) debuglog("{0} (dullahan) KILL: {1} ({2})".format(wrapper.source, target, get_main_role(target)))
def target(var, wrapper, message): """Pick a player as your target, killing them if you die.""" if wrapper.source in PREV_ACTED: wrapper.send(messages["assassin_already_targeted"]) return target = get_target(var, wrapper, re.split(" +", message)[0]) if not target: return orig = target target = try_misdirection(var, wrapper.source, target) if try_exchange(var, wrapper.source, target): return TARGETED[wrapper.source] = target wrapper.send(messages["assassin_target_success"].format(orig)) debuglog("{0} (assassin) TARGET: {1} ({2})".format(wrapper.source, target, get_main_role(target)))
def see(var, wrapper, message): """Use your paranormal powers to determine the role or alignment of a player.""" if wrapper.source in SEEN: wrapper.send(messages["seer_fail"]) return target = get_target(var, wrapper, re.split(" +", message)[0], not_self_message="no_see_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) trole = targrole # keep a copy for logging for i in range(2): # need to go through loop twice iswolf = False if targrole in Cursed: targrole = "wolf" iswolf = True elif targrole in Safe | Innocent: targrole = var.HIDDEN_ROLE elif targrole in Wolf: targrole = "wolf" iswolf = True else: targrole = var.HIDDEN_ROLE if i: break evt = Event("see", {"role": targrole}) evt.dispatch(var, wrapper.source, target) targrole = evt.data["role"] wrapper.send(messages["oracle_success"].format(target, "" if iswolf else "\u0002not\u0002 ", "\u0002" if iswolf else "")) debuglog("{0} (oracle) SEE: {1} ({2}) (Wolf: {3})".format(wrapper.source, target, trole, str(iswolf))) SEEN.add(wrapper.source)
def guard(var, wrapper, message): """Guard a player, preventing them from being killed that night.""" if wrapper.source in GUARDED: wrapper.pm(messages["already_protecting"]) return target = get_target(var, wrapper, re.split(" +", message)[0], not_self_message="cannot_guard_self") if not target: return target = try_misdirection(var, wrapper.source, target) if try_exchange(var, wrapper.source, target): return add_protection(var, target, wrapper.source, "bodyguard") GUARDED[wrapper.source] = target wrapper.pm(messages["protecting_target"].format(target)) target.send(messages["target_protected"]) debuglog("{0} (bodyguard) GUARD: {1} ({2})".format(wrapper.source, target, get_main_role(target)))
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 (should be changeable in settings) # The detective's identity is compromised! wcroles = Wolfchat if var.RESTRICT_WOLFCHAT & var.RW_REM_NON_WOLVES: if var.RESTRICT_WOLFCHAT & var.RW_TRAITOR_NON_WOLF: wcroles = Wolf else: wcroles = Wolf | {"traitor"} wolves = get_all_players(wcroles) 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 see(var, wrapper, message): """Use your paranormal powers to determine the role or alignment of a player.""" if wrapper.source in SEEN: wrapper.send(messages["seer_fail"]) return target = get_target(var, wrapper, re.split(" +", message)[0], not_self_message="no_see_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) trole = targrole # keep a copy for logging if targrole in Cursed: targrole = "wolf" elif targrole in Safe: pass # Keep the same role elif targrole in Innocent: targrole = var.HIDDEN_ROLE elif targrole in (Neutral - Win_Stealer - Team_Switcher): pass # Keep the same role elif targrole in Wolf: targrole = "wolf" else: targrole = var.HIDDEN_ROLE evt = Event("see", {"role": targrole}) evt.dispatch(var, wrapper.source, target) targrole = evt.data["role"] wrapper.send(messages["seer_success"].format(target, targrole)) debuglog("{0} (seer) SEE: {1} ({2}) as {3}".format(wrapper.source, target, trole, targrole)) SEEN.add(wrapper.source)
def observe(var, wrapper, message): """Turn a player into a wolf!""" if not ENABLED: wrapper.pm(messages["alpha_no_bite"]) return if wrapper.source in ALPHAS: wrapper.pm(messages["alpha_already_bit"]) return target = get_target(var, wrapper, re.split(" +", message)[0]) if not target: return if is_known_wolf_ally(var, wrapper.source, target): wrapper.pm(messages["alpha_no_bite_wolf"]) return orig = target target = try_misdirection(var, wrapper.source, target) if try_exchange(var, wrapper.source, target): return BITTEN[wrapper.source] = target wrapper.pm(messages["alpha_bite_target"].format(orig)) send_wolfchat_message(var, wrapper.source, messages["alpha_bite_wolfchat"].format(wrapper.source, target), {"alpha wolf"}, role="alpha wolf", command="bite") debuglog("{0} (alpha wolf) BITE: {1} ({2})".format(wrapper.source, target, get_main_role(target)))
def see(var, wrapper, message): """Use your paranormal powers to determine the role or alignment of a player.""" if wrapper.source in SEEN: wrapper.send(messages["seer_fail"]) return target = get_target(var, wrapper, re.split(" +", message)[0], not_self_message="no_see_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) trole = targrole # keep a copy for logging if targrole in Cursed: targrole = "wolf" elif targrole in Safe | Innocent: targrole = var.HIDDEN_ROLE elif targrole in Wolf: targrole = "wolf" evt = Event("see", {"role": targrole}) evt.dispatch(var, wrapper.source, target) targrole = evt.data["role"] to_send = "oracle_success_not_wolf" if targrole == "wolf": to_send = "oracle_success_wolf" wrapper.send(messages[to_send].format(target)) debuglog("{0} (oracle) SEE: {1} ({2}) (Wolf: {3})".format(wrapper.source, target, trole, "True" if targrole == "wolf" else "False")) SEEN.add(wrapper.source)
def see(var, wrapper, message): """Use your paranormal powers to determine the role or alignment of a player.""" if wrapper.source in SEEN: wrapper.send(messages["seer_fail"]) return target = get_target(var, wrapper, re.split(" +", message)[0], not_self_message="no_see_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) trole = targrole # keep a copy for logging if targrole in Cursed: targrole = "wolf" elif targrole in Safe: pass # Keep the same role elif targrole in Innocent: targrole = var.HIDDEN_ROLE elif targrole in Wolf: targrole = "wolf" else: targrole = var.HIDDEN_ROLE evt = Event("see", {"role": targrole}) evt.dispatch(var, wrapper.source, target) targrole = evt.data["role"] wrapper.send(messages["seer_success"].format(target, targrole)) debuglog("{0} (seer) SEE: {1} ({2}) as {3}".format(wrapper.source, target, trole, targrole)) SEEN.add(wrapper.source)
def investigate(var, wrapper, message): """Investigate two players to determine their relationship to each other.""" if wrapper.source in INVESTIGATED: wrapper.pm(messages["already_investigated"]) return pieces = re.split(" +", message) if len(pieces) == 1: wrapper.pm(messages["investigator_help"]) return target1 = pieces[0] target2 = pieces[1] if target2.lower() == "and" and len(pieces) > 2: target2 = pieces[2] target1 = get_target(var, wrapper, target1, not_self_message="no_investigate_self") target2 = get_target(var, wrapper, target2, not_self_message="no_investigate_self") if not target1 or not target2: return elif target1 is target2: wrapper.pm(messages["investigator_help"]) return target1 = try_misdirection(var, wrapper.source, target1) target2 = try_misdirection(var, wrapper.source, target2) if try_exchange(var, wrapper.source, target1) or try_exchange( var, wrapper.source, target2): return t1role = get_main_role(target1) t2role = get_main_role(target2) evt = Event("investigate", {"role": t1role}) evt.dispatch(var, wrapper.source, target1) t1role = evt.data["role"] evt = Event("investigate", {"role": t2role}) evt.dispatch(var, wrapper.source, target2) t2role = evt.data["role"] # FIXME: make a standardized way of getting team affiliation, and make # augur and investigator both use it (and make it events-aware so other # teams can be added more easily) if t1role in Wolfteam: t1role = "red" elif t1role in Neutral: t1role = "grey" else: t1role = "blue" if t2role in Wolfteam: t2role = "red" elif t2role in Neutral: t2role = "grey" else: t2role = "blue" evt = Event("get_team_affiliation", {"same": (t1role == t2role)}) evt.dispatch(evt, target1, target2) if evt.data["same"]: wrapper.pm(messages["investigator_results_same"].format( target1, target2)) else: wrapper.pm(messages["investigator_results_different"].format( target1, target2)) 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 evt.data["same"] else "different"))
def investigate(var, wrapper, message): """Investigate two players to determine their relationship to each other.""" if wrapper.source in INVESTIGATED: wrapper.pm(messages["already_investigated"]) return pieces = re.split(" +", message) if len(pieces) == 1: wrapper.pm(messages["investigator_help"]) return target1 = pieces[0] target2 = pieces[1] if target2.lower() == "and" and len(pieces) > 2: target2 = pieces[2] target1 = get_target(var, wrapper, target1, not_self_message="no_investigate_self") target2 = get_target(var, wrapper, target2, not_self_message="no_investigate_self") if not target1 or not target2: return elif target1 is target2: wrapper.pm(messages["investigator_help"]) return target1 = try_misdirection(var, wrapper.source, target1) target2 = try_misdirection(var, wrapper.source, target2) if try_exchange(var, wrapper.source, target1) or try_exchange(var, wrapper.source, target2): return t1role = get_main_role(target1) t2role = get_main_role(target2) evt = Event("investigate", {"role": t1role}) evt.dispatch(var, wrapper.source, target1) t1role = evt.data["role"] evt = Event("investigate", {"role": t2role}) evt.dispatch(var, wrapper.source, target2) t2role = evt.data["role"] # FIXME: make a standardized way of getting team affiliation, and make # augur and investigator both use it (and make it events-aware so other # teams can be added more easily) if t1role in Wolfteam: t1role = "red" elif t1role in Neutral: t1role = "grey" else: t1role = "blue" if t2role in Wolfteam: t2role = "red" elif t2role in Neutral: t2role = "grey" else: t2role = "blue" evt = Event("get_team_affiliation", {"same": (t1role == t2role)}) evt.dispatch(evt, target1, target2) if evt.data["same"]: wrapper.pm(messages["investigator_results_same"].format(target1, target2)) else: wrapper.pm(messages["investigator_results_different"].format(target1, target2)) 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 evt.data["same"] else "different"))
def shoot(var, wrapper, message): """Use this to fire off a bullet at someone in the day if you have bullets.""" if not GUNNERS[wrapper.source]: wrapper.pm(messages["no_bullets"]) return target = get_target(var, wrapper, re.split(" +", message)[0], not_self_message="gunner_target_self") if not target: return target = try_misdirection(var, wrapper.source, target) if try_exchange(var, wrapper.source, target): return GUNNERS[wrapper.source] -= 1 gun_evt = Event("gun_chances", {"hit": 0, "miss": 0, "headshot": 0}) gun_evt.dispatch(var, wrapper.source, rolename) rand = random.random() # need to save it shoot_evt = Event("gun_shoot", {"hit": rand <= gun_evt.data["hit"], "kill": random.random() <= gun_evt.data["headshot"]}) shoot_evt.dispatch(var, wrapper.source, target) realrole = get_main_role(target) targrole = get_reveal_role(target) if shoot_evt.data["hit"]: wrapper.send(messages["shoot_success"].format(wrapper.source, target)) an = "n" if targrole.startswith(("a", "e", "i", "o", "u")) else "" if realrole in Wolf: if var.ROLE_REVEAL == "on": wrapper.send(messages["gunner_victim_wolf_death"].format(target, an, targrole)) else: # off and team wrapper.send(messages["gunner_victim_wolf_death_no_reveal"].format(target)) add_dying(var, target, killer_role=get_main_role(wrapper.source), reason="gunner_victim") if kill_players(var): return elif shoot_evt.data["kill"]: accident = "accidentally " if gun_evt.data["headshot"] == 1: # would always headshot accident = "" wrapper.send(messages["gunner_victim_villager_death"].format(target, accident)) if var.ROLE_REVEAL in ("on", "team"): wrapper.send(messages["gunner_victim_role"].format(an, targrole)) add_dying(var, target, killer_role=get_main_role(wrapper.source), reason="gunner_victim") if kill_players(var): return else: wrapper.send(messages["gunner_victim_injured"].format(target)) add_absent(var, target, "wounded") from src.votes import chk_decision from src.wolfgame import chk_win if not chk_win(): # game didn't immediately end due to injury, see if we should force through a vote chk_decision(var) elif rand <= gun_evt.data["hit"] + gun_evt.data["miss"]: wrapper.send(messages["gunner_miss"].format(wrapper.source)) else: # BOOM! your gun explodes, you're dead if var.ROLE_REVEAL in ("on", "team"): wrapper.send(messages["gunner_suicide"].format(wrapper.source, get_reveal_role(wrapper.source))) else: wrapper.send(messages["gunner_suicide_no_reveal"].format(wrapper.source)) add_dying(var, wrapper.source, killer_role="villager", reason="gunner_suicide") # blame explosion on villager's shoddy gun construction or something kill_players(var)
def shoot(var, wrapper, message): """Use this to fire off a bullet at someone in the day if you have bullets.""" if not GUNNERS[wrapper.source]: wrapper.pm(messages["no_bullets"]) return target = get_target(var, wrapper, re.split(" +", message)[0], not_self_message="gunner_target_self") if not target: return target = try_misdirection(var, wrapper.source, target) if try_exchange(var, wrapper.source, target): return GUNNERS[wrapper.source] -= 1 gun_evt = Event("gun_chances", {"hit": 0, "miss": 0, "headshot": 0}) gun_evt.dispatch(var, wrapper.source, rolename) rand = random.random() # need to save it shoot_evt = Event("gun_shoot", {"hit": rand <= gun_evt.data["hit"], "kill": random.random() <= gun_evt.data["headshot"]}) shoot_evt.dispatch(var, wrapper.source, target) realrole = get_main_role(target) targrole = get_reveal_role(target) if shoot_evt.data["hit"]: wrapper.send(messages["shoot_success"].format(wrapper.source, target)) an = "n" if targrole.startswith(("a", "e", "i", "o", "u")) else "" if realrole in Wolf: if var.ROLE_REVEAL == "on": wrapper.send(messages["gunner_victim_wolf_death"].format(target, an, targrole)) else: # off and team wrapper.send(messages["gunner_victim_wolf_death_no_reveal"].format(target)) add_dying(var, target, killer_role=get_main_role(wrapper.source), reason="gunner_victim") if kill_players(var): return elif shoot_evt.data["kill"]: accident = "accidentally " if gun_evt.data["headshot"] == 1: # would always headshot accident = "" wrapper.send(messages["gunner_victim_villager_death"].format(target, accident)) if var.ROLE_REVEAL in ("on", "team"): wrapper.send(messages["gunner_victim_role"].format(an, targrole)) add_dying(var, target, killer_role=get_main_role(wrapper.source), reason="gunner_victim") if kill_players(var): return else: wrapper.send(messages["gunner_victim_injured"].format(target)) add_absent(var, target, "wounded") from src.wolfgame import chk_decision, chk_win chk_decision() chk_win() elif rand <= gun_evt.data["hit"] + gun_evt.data["miss"]: wrapper.send(messages["gunner_miss"].format(wrapper.source)) else: # BOOM! your gun explodes, you're dead if var.ROLE_REVEAL in ("on", "team"): wrapper.send(messages["gunner_suicide"].format(wrapper.source, get_reveal_role(wrapper.source))) else: wrapper.send(messages["gunner_suicide_no_reveal"].format(wrapper.source)) add_dying(var, wrapper.source, killer_role="villager", reason="gunner_suicide") # blame explosion on villager's shoddy gun construction or something kill_players(var)
def charm(var, wrapper, message): """Charm a player or two, slowly leading to your win!""" pieces = re.split(" +", message) target1 = pieces[0] if len(pieces) > 1: if len(pieces) > 2 and pieces[1].lower() == "and": target2 = pieces[2] else: target2 = pieces[1] else: target2 = None target1 = get_target(var, wrapper, target1) if not target1: return if target2 is not None: target2 = get_target(var, wrapper, target2) if not target2: return orig1 = target1 orig2 = target2 target1 = try_misdirection(var, wrapper.source, target1) if target2 is not None: target2 = try_misdirection(var, wrapper.source, target2) if try_exchange(var, wrapper.source, target1) or try_exchange(var, wrapper.source, target2): return # Do these checks based on original targets, so piper doesn't know to change due to misdirection/luck totem if orig1 is orig2: wrapper.send(messages["must_charm_multiple"]) return if orig1 in CHARMED and orig2 in CHARMED: wrapper.send(messages["targets_already_charmed"].format(orig1, orig2)) return elif orig1 in CHARMED: wrapper.send(messages["target_already_charmed"].format(orig1)) return elif orig2 in CHARMED: wrapper.send(messages["target_already_charmed"].format(orig2)) return if wrapper.source in TOBECHARMED: TOBECHARMED[wrapper.source].clear() else: TOBECHARMED[wrapper.source] = UserSet() TOBECHARMED[wrapper.source].update({target1, target2} - {None}) PASSED.discard(wrapper.source) if orig2: debuglog("{0} (piper) CHARM {1} ({2}) && {3} ({4})".format(wrapper.source, target1, get_main_role(target1), target2, get_main_role(target2))) wrapper.send(messages["charm_multiple_success"].format(orig1, orig2)) else: debuglog("{0} (piper) CHARM {1} ({2})".format(wrapper.source, target1, get_main_role(target1))) wrapper.send(messages["charm_success"].format(orig1))
def wolf_kill(var, wrapper, message): """Kill one or more players as a wolf.""" pieces = re.split(" +", message) targets = [] orig = [] nevt = Event("wolf_numkills", {"numkills": 1, "message": ""}) nevt.dispatch(var) num_kills = nevt.data["numkills"] if not num_kills: if nevt.data["message"]: wrapper.pm(messages[nevt.data["message"]]) return if len(pieces) < num_kills: wrapper.pm(messages["wolf_must_target_multiple"]) return for targ in pieces[:num_kills]: target = get_target(var, wrapper, targ, not_self_message="no_suicide") if target is None: return if is_known_wolf_ally(var, wrapper.source, target): wrapper.pm(messages["wolf_no_target_wolf"]) return if target in orig: wrapper.pm(messages["wolf_must_target_multiple"]) return orig.append(target) target = try_misdirection(var, wrapper.source, target) if try_exchange(var, wrapper.source, target): return targets.append(target) KILLS[wrapper.source] = UserList(targets) if len(orig) > 1: # TODO: Expand this so we can support arbitrarily many kills (instead of just one or two) wrapper.pm(messages["player_kill_multiple"].format(*orig)) msg = messages["wolfchat_kill_multiple"].format( wrapper.source, *orig) debuglog("{0} ({1}) KILL: {2} ({4}) and {3} ({5})".format( wrapper.source, rolename, *targets, get_main_role(targets[0]), get_main_role(targets[1]))) else: wrapper.pm(messages["player_kill"].format(orig[0])) msg = messages["wolfchat_kill"].format(wrapper.source, orig[0]) debuglog("{0} ({1}) KILL: {2} ({3})".format( wrapper.source, rolename, targets[0], get_main_role(targets[0]))) send_wolfchat_message(var, wrapper.source, msg, Wolf, role=rolename, command="kill")
def charm(var, wrapper, message): """Charm a player or two, slowly leading to your win!""" pieces = re.split(" +", message) target1 = pieces[0] if len(pieces) > 1: if len(pieces) > 2 and pieces[1].lower() == "and": target2 = pieces[2] else: target2 = pieces[1] else: target2 = None target1 = get_target(var, wrapper, target1) if not target1: return if target2 is not None: target2 = get_target(var, wrapper, target2) if not target2: return orig1 = target1 orig2 = target2 target1 = try_misdirection(var, wrapper.source, target1) if target2 is not None: target2 = try_misdirection(var, wrapper.source, target2) if try_exchange(var, wrapper.source, target1) or try_exchange( var, wrapper.source, target2): return # Do these checks based on original targets, so piper doesn't know to change due to misdirection/luck totem if orig1 is orig2: wrapper.send(messages["must_charm_multiple"]) return if orig1 in CHARMED and orig2 in CHARMED: wrapper.send(messages["targets_already_charmed"].format(orig1, orig2)) return elif orig1 in CHARMED: wrapper.send(messages["target_already_charmed"].format(orig1)) return elif orig2 in CHARMED: wrapper.send(messages["target_already_charmed"].format(orig2)) return if wrapper.source in TOBECHARMED: TOBECHARMED[wrapper.source].clear() else: TOBECHARMED[wrapper.source] = UserSet() TOBECHARMED[wrapper.source].update({target1, target2} - {None}) PASSED.discard(wrapper.source) if orig2: debuglog("{0} (piper) CHARM {1} ({2}) && {3} ({4})".format( wrapper.source, target1, get_main_role(target1), target2, get_main_role(target2))) wrapper.send(messages["charm_multiple_success"].format(orig1, orig2)) else: debuglog("{0} (piper) CHARM {1} ({2})".format(wrapper.source, target1, get_main_role(target1))) wrapper.send(messages["charm_success"].format(orig1))