def try_exchange(var, actor, target): """Check if an exchange is happening. Return True if the exchange occurs.""" if actor is target or target not in EXCHANGE: return False EXCHANGE.remove(target) role = get_main_role(actor) target_role = get_main_role(target) actor_role = change_role(var, actor, role, target_role, inherit_from=target) target_role = change_role(var, target, target_role, role, inherit_from=actor) if actor_role == target_role: # swap state of two players with the same role evt = Event("swap_role_state", { "actor_messages": [], "target_messages": [] }) evt.dispatch(var, actor, target, actor_role) actor.send(*evt.data["actor_messages"]) target.send(*evt.data["target_messages"]) return True
def happy_fun_times(self, evt, var, player, all_roles, death_triggers): if death_triggers and evt.params.main_role == "priest": channels.Main.send(messages["sleepy_priest_death"]) turn_chance = 3 / 4 mapping = { "seer": "doomsayer", "harlot": "succubus", "cultist": "demoniac" } for old, new in mapping.items(): turn = [ p for p in get_players((old, )) if random.random() < turn_chance ] for t in turn: # messages: sleepy_doomsayer_turn, sleepy_succubus_turn, sleepy_demoniac_turn change_role(var, t, old, new, message="sleepy_{0}_turn".format(new)) newstats = set() for rs in var.ROLE_STATS: d = Counter(dict(rs)) newstats.add(rs) if old in d and d[old] >= 1: d[old] -= 1 d[new] += 1 newstats.add(frozenset(d.items())) var.ROLE_STATS = frozenset(newstats)
def on_revealing_totem(evt, var, user, role): if role not in _get_blacklist(var) and not var.HIDDEN_AMNESIAC and var.ORIGINAL_ROLES["amnesiac"]: global STATS_FLAG STATS_FLAG = True if role == "amnesiac": user.send(messages["amnesia_clear"].format(ROLES[user])) change_role(var, user, "amnesiac", ROLES[user])
def on_transition_day_resolve_end(evt, var, victims): evt2 = Event("get_role_metadata", {}) evt2.dispatch(var, "lycanthropy_role") for victim in victims: if victim in LYCANTHROPES and evt.data["killers"][victim] == ["@wolves"] and victim in evt.data["dead"]: vrole = get_main_role(victim) if vrole not in Wolf: new_role = "wolf" prefix = LYCANTHROPES[victim] if vrole in evt2.data: if "role" in evt2.data[vrole]: new_role = evt2.data[vrole]["role"] if "prefix" in evt2.data[vrole]: prefix = evt2.data[vrole]["prefix"] for sec_role in evt2.data[vrole].get("secondary_roles", ()): var.ROLES[sec_role].add(victim) to_send = "{0}_{1}".format(sec_role.replace(" ", "_"), "simple" if victim.prefers_simple() else "notify") victim.send(messages[to_send]) # FIXME: Not every role has proper message keys, such as shamans change_role(var, victim, vrole, new_role, message=prefix + "_turn") evt.data["howl"] += 1 evt.data["novictmsg"] = False evt.data["dead"].remove(victim) evt.data["killers"][victim].remove("@wolves") del evt.data["message"][victim] debuglog("{0} ({1}) TURN {2}".format(victim, vrole, new_role))
def on_revealing_totem(evt, var, user, role): if role not in _get_blacklist( var ) and not var.HIDDEN_AMNESIAC and var.ORIGINAL_ROLES["amnesiac"]: global STATS_FLAG STATS_FLAG = True if role == "amnesiac": user.send(messages["amnesia_clear"].format(ROLES[user])) change_role(var, user, "amnesiac", ROLES[user])
def on_revealing_totem(evt, var, votee): if evt.data["role"] not in _get_blacklist( var) and not var.HIDDEN_AMNESIAC and len( var.ORIGINAL_ROLES["amnesiac"]): global STATS_FLAG STATS_FLAG = True if evt.data["role"] == "amnesiac": votee.send(messages["totem_amnesia_clear"]) change_role(var, votee, "amnesiac", ROLES[votee])
def maybe_make_wendigo(self, var, player): from src.roles import vengefulghost num_wendigos = len(vengefulghost.GHOSTS) num_wolf_shamans = len(get_players(("wolf shaman", ))) if num_wendigos < num_wolf_shamans: change_role(var, player, get_main_role(player), "vengeful ghost", message=None)
def on_del_player(evt, var, player, all_roles, death_triggers): del IDOLS[:player:] if not death_triggers: return for child in get_all_players(("wild child",)): if IDOLS.get(child) is player: # Change their main role to wolf change_role(var, child, get_main_role(child), "wolf", message="wild_child_idol_died") var.ROLES["wild child"].add(child)
def on_lynch(self, evt, var, votee, voters): if get_main_role(votee) not in Wolfteam: # if there are less VGs than alive wolf shamans, they become a wendigo as well from src.roles import vengefulghost num_wendigos = len(vengefulghost.GHOSTS) num_wolf_shamans = len(get_players(("wolf shaman", ))) if num_wendigos < num_wolf_shamans: change_role(var, votee, get_main_role(votee), "vengeful ghost", message=None)
def on_del_player(evt, var, player, all_roles, death_triggers): del IDOLS[:player:] if not death_triggers: return for child in get_all_players(("wild child", )): if IDOLS.get(child) is player: # Change their main role to wolf change_role(var, child, get_main_role(child), "wolf", message="wild_child_idol_died") var.ROLES["wild child"].add(child)
def on_swap_role_state(evt, var, actor, target, role): if role == "wild child": IDOLS[actor], IDOLS[target] = IDOLS[target], IDOLS[actor] if IDOLS[actor] in get_players(): evt.data["actor_messages"].append(messages["wild_child_idol"].format(IDOLS[actor])) else: # The King is dead, long live the King! change_role(var, actor, "wild child", "wolf", message="wild_child_idol_died") var.ROLES["wild child"].add(actor) if IDOLS[target] in get_players(): evt.data["target_messages"].append(messages["wild_child_idol"].format(IDOLS[target])) else: change_role(var, target, "wild child", "wolf", message="wild_child_idol_died") var.ROLES["wild child"].add(target)
def on_del_player(evt, var, player, all_roles, death_triggers): # clone happens regardless of death_triggers being true or not if var.PHASE not in var.GAME_PHASES: return clones = get_all_players(("clone", )) mainrole = evt.params.main_role for clone in clones: if clone in CLONED: target = CLONED[clone] if player is target: # clone is cloning target, so clone becomes target's role # clone does NOT get any of target's templates (gunner/assassin/etc.) del CLONED[clone] mainrole = change_role(var, clone, "clone", mainrole, inherit_from=target) # if a clone is cloning a clone, clone who the old clone cloned if mainrole == "clone" and player in CLONED: if CLONED[player] is clone: clone.send(messages["forever_aclone"].format(player)) else: CLONED[clone] = CLONED[player] clone.send(messages["clone_success"].format( CLONED[clone])) debuglog("{0} (clone) CLONE: {1} ({2})".format( clone, CLONED[clone], get_main_role(CLONED[clone]))) debuglog("{0} (clone) CLONE DEAD PLAYER: {1} ({2})".format( clone, target, mainrole)) del CLONED[:player:]
def on_del_player(evt, var, user, mainrole, allroles, death_triggers): if var.PHASE not in var.GAME_PHASES: return for child in get_all_players(("wild child", )): if child in evt.params.deadlist or IDOLS.get( child) not in evt.params.deadlist: continue # Change their main role to wolf WILD_CHILDREN.add(child) change_role(var, child, get_main_role(child), "wolf", message="wild_child_idol_died") var.ROLES["wild child"].discard(child)
def on_transition_night_begin(evt, var): global STATS_FLAG if var.NIGHT_COUNT == var.AMNESIAC_NIGHTS: amnesiacs = get_all_players(("amnesiac",)) if amnesiacs and not var.HIDDEN_AMNESIAC: STATS_FLAG = True for amn in amnesiacs: role = change_role(var, amn, "amnesiac", ROLES[amn], message="amnesia_clear") debuglog("{0} REMEMBER: {1}".format(amn, role))
def try_exchange(var, actor, target): """Check if an exchange is happening. Return True if the exchange occurs.""" if actor is target or target not in EXCHANGE: return False EXCHANGE.remove(target) role = get_main_role(actor) target_role = get_main_role(target) actor_role = change_role(var, actor, role, target_role, inherit_from=target) target_role = change_role(var, target, target_role, role, inherit_from=actor) if actor_role == target_role: # swap state of two players with the same role evt = Event("swap_role_state", {"actor_messages": [], "target_messages": []}) evt.dispatch(var, actor, target, actor_role) actor.send(*evt.data["actor_messages"]) target.send(*evt.data["target_messages"]) return True
def happy_fun_times(self, evt, var, player, all_roles, death_triggers): if death_triggers: if evt.params.main_role == "priest": turn_chance = 3 / 4 seers = [ p for p in get_players(("seer", )) if random.random() < turn_chance ] harlots = [ p for p in get_players(("harlot", )) if random.random() < turn_chance ] cultists = [ p for p in get_players(("cultist", )) if random.random() < turn_chance ] channels.Main.send(messages["sleepy_priest_death"]) for seer in seers: change_role(var, seer, "seer", "doomsayer", message="sleepy_doomsayer_turn") for harlot in harlots: change_role(var, harlot, "harlot", "succubus", message="sleepy_succubus_turn") for cultist in cultists: change_role(var, cultist, "cultist", "demoniac", message="sleepy_demoniac_turn")
def on_transition_day_begin(self, evt, var): from src.roles import vengefulghost num_wendigos = len(vengefulghost.GHOSTS) num_wolf_shamans = len(get_players(("wolf shaman", ))) ps = get_players() for p in ps: if get_main_role(p) in Wolfteam: continue # wolf shamans can't starve if self.totem_tracking[p] > 0: # if sustenance totem made it through, fully feed player self.hunger_levels[p] = 0 elif self.totem_tracking[p] < 0: # if hunger totem made it through, fast-track player to starvation if self.hunger_levels[p] < 3: self.hunger_levels[p] = 3 # apply natural hunger self.hunger_levels[p] += 1 if self.hunger_levels[p] >= 5: # if they hit 5, they die of starvation # if there are less VGs than alive wolf shamans, they become a wendigo as well if num_wendigos < num_wolf_shamans: num_wendigos += 1 change_role(var, p, get_main_role(p), "vengeful ghost", message=None) add_dying(var, p, killer_role="villager", reason="boreal_starvation") elif self.hunger_levels[p] >= 3: # if they are at 3 or 4, alert them that they are hungry p.send(messages["boreal_hungry"]) self.totem_tracking.clear()
def on_transition_night_begin(evt, var): global STATS_FLAG if var.NIGHT_COUNT == var.AMNESIAC_NIGHTS: amnesiacs = get_all_players(("amnesiac", )) if amnesiacs and not var.HIDDEN_AMNESIAC: STATS_FLAG = True for amn in amnesiacs: role = change_role(var, amn, "amnesiac", ROLES[amn], message="amnesia_clear") debuglog("{0} REMEMBER: {1}".format(amn, role))
def on_swap_role_state(evt, var, actor, target, role): if role == "wild child": IDOLS[actor], IDOLS[target] = IDOLS[target], IDOLS[actor] if IDOLS[actor] in get_players(): evt.data["actor_messages"].append( messages["wild_child_idol"].format(IDOLS[actor])) else: # The King is dead, long live the King! change_role(var, actor, "wild child", "wolf", message="wild_child_idol_died") var.ROLES["wild child"].add(actor) if IDOLS[target] in get_players(): evt.data["target_messages"].append( messages["wild_child_idol"].format(IDOLS[target])) else: change_role(var, target, "wild child", "wolf", message="wild_child_idol_died") var.ROLES["wild child"].add(target)