diff --git a/messages/en.json b/messages/en.json index 34fd650..ca6a4bf 100644 --- a/messages/en.json +++ b/messages/en.json @@ -309,9 +309,19 @@ "role_swap": "You have exchanged roles with someone! You are now a \u0002{0}\u0002.", "clone_target": "You are cloning \u0002{0}\u0002.", "shaman_totem": "You have a \u0002{0}\u0002 totem.", - "mystic_info": "There {0} \u0002{1}\u0002 evil villager{2} still alive.", "players_exchanged_roles": "\u0002{0}\u0002 and \u0002{1}\u0002 have exchanged roles!", - "wolf_mystic_info": "There {0} \u0002{1}\u0002 special villager{2} still alive.", + "mystic_info_singular": "There is \u00021\u0002 evil villager still alive.", + "mystic_info_plural": "There are \u0002{0}\u0002 evil villagers still alive.", + "mystic_info_night_singular": "There was \u00021\u0002 evil villager alive at the beginning of the night.", + "mystic_info_night_plural": "There were \u0002{0}\u0002 evil villagers alive at the beginning of the night.", + "mystic_info_day_singular": "There was \u00021\u0002 evil villager alive at the beginning of last night.", + "mystic_info_day_plural": "There were \u0002{0}\u0002 evil villagers alive at the beginning of last night.", + "wolf_mystic_info_singular": "There is \u00021\u0002 special villager still alive.", + "wolf_mystic_info_plural": "There are \u0002{0}\u0002 special villagers still alive.", + "wolf_mystic_info_night_singular": "There was \u00021\u0002 special villager alive at the beginning of the night.", + "wolf_mystic_info_night_plural": "There were \u0002{0}\u0002 special villagers alive at the beginning of the night.", + "wolf_mystic_info_day_singular": "There was \u00021\u0002 special villager alive at the beginning of last night.", + "wolf_mystic_info_day_plural": "There were \u0002{0}\u0002 special villagers alive at the beginning of last night.", "ill_wolves": "You are feeling ill tonight, and are unable to kill anyone.", "angry_wolves": "You are \u0002angry\u0002 tonight, and may kill two targets by using \"kill and \".", "wolf_bite": "You may use \"bite \" tonight in order to turn that person into a wolf.", diff --git a/src/roles/_mystic_helper.py b/src/roles/_mystic_helper.py new file mode 100644 index 0000000..005659b --- /dev/null +++ b/src/roles/_mystic_helper.py @@ -0,0 +1,66 @@ +import re +import random + +from src.utilities import * +from src import users, channels, debuglog, errlog, plog +from src.functions import get_players, get_all_players +from src.decorators import cmd, event_listener +from src.containers import UserList, UserSet, UserDict, DefaultUserDict +from src.messages import messages +from src.events import Event + +def setup_variables(rolename, *, send_role, types): + LAST_COUNT = UserDict() # type: Dict[users.User, int] + + role = rolename.replace(" ", "_") + + @event_listener("transition_night_end") + def on_transition_night_end(evt, var): + villagers = set(get_players(("priest", "prophet", "matchmaker", "doctor"))) + win_stealers = set(get_players(("fool", "monster", "demoniac"))) + neutrals = set(get_players(("turncoat", "clone", "jester"))) + + special_evt = Event("get_special", {"villagers": villagers, "wolves": set(), "win_stealers": win_stealers, "neutrals": neutrals}) + special_evt.dispatch(var) + + targets = set() + for name in types: + targets.update(special_evt.data[name]) + + count = len(targets) + key = "{0}_info_{1}".format(role, ("singular" if count == 1 else "plural")) + + for mystic in get_all_players((rolename,)): + LAST_COUNT[mystic] = count + if send_role: + to_send = "{0}_{1}".format(role, ("simple" if mystic.prefers_simple() else "notify")) + mystic.send(messages[to_send]) + mystic.send(messages[key].format(count)) + + @event_listener("exchange_roles") + def on_exchange_roles(evt, var, actor, target, actor_role, target_role): + if actor_role == rolename and target_role != rolename: + count = LAST_COUNT.pop(actor) + LAST_COUNT[target] = count + key = "{0}_info_{1}_{2}".format(role, var.PHASE, ("singular" if count == 1 else "plural")) + evt.data["target_messages"].append(messages[key].format(count)) + + if target_role == rolename and actor_role != rolename: + count = LAST_COUNT.pop(target) + LAST_COUNT[actor] = count + key = "{0}_info_{1}_{2}".format(role, var.PHASE, ("singular" if count == 1 else "plural")) + evt.data["actor_messages"].append(messages[key].format(count)) + + @event_listener("reset") + def on_reset(evt, var): + LAST_COUNT.clear() + + @event_listener("myrole") + def on_myrole(evt, var, user): + if user in get_all_players((rolename,)): + key = "{0}_info_{1}_{2}".format(role, var.PHASE, ("singular" if LAST_COUNT[user] == 1 else "plural")) + evt.data["messages"].append(messages[key].format(LAST_COUNT[user])) + + return LAST_COUNT + +# vim: set sw=4 expandtab: diff --git a/src/roles/_seer_helper.py b/src/roles/_seer_helper.py index 19729ba..d3e194c 100644 --- a/src/roles/_seer_helper.py +++ b/src/roles/_seer_helper.py @@ -24,7 +24,7 @@ def setup_variables(rolename): @event_listener("get_special") def on_get_special(evt, var): - evt.data["special"].update(get_players((rolename,))) + evt.data["villagers"].update(get_players((rolename,))) @event_listener("exchange_roles") def on_exchange(evt, var, actor, target, actor_role, target_role): diff --git a/src/roles/_shaman_helper.py b/src/roles/_shaman_helper.py index 4cdd15a..b4e039d 100644 --- a/src/roles/_shaman_helper.py +++ b/src/roles/_shaman_helper.py @@ -133,10 +133,6 @@ def setup_variables(rolename, *, knows_totem, get_tags): if user in SHAMANS: evt.data["acted"] = True - @event_listener("get_special") - def on_get_special(evt, var): - evt.data["special"].update(get_players((rolename,))) - @event_listener("chk_nightdone") def on_chk_nightdone(evt, var): evt.data["actedcount"] += len(SHAMANS) diff --git a/src/roles/angel.py b/src/roles/angel.py index 735f170..de4baa7 100644 --- a/src/roles/angel.py +++ b/src/roles/angel.py @@ -99,7 +99,7 @@ def on_acted(evt, var, user, actor): @event_listener("get_special") def on_get_special(evt, var): - evt.data["special"].update(get_players(("guardian angel", "bodyguard"))) + evt.data["villagers"].update(get_players(("guardian angel", "bodyguard"))) @event_listener("exchange_roles") def on_exchange(evt, var, actor, target, actor_role, target_role): diff --git a/src/roles/crazedshaman.py b/src/roles/crazedshaman.py index 93dfab8..95b4a76 100644 --- a/src/roles/crazedshaman.py +++ b/src/roles/crazedshaman.py @@ -95,4 +95,8 @@ def on_transition_night_end(evt, var): shaman.send(messages["shaman_notify"].format("crazed shaman", "random ")) shaman.send("Players: " + ", ".join(p.nick for p in pl)) +@event_listener("get_special") +def on_get_special(evt, var): + evt.data["neutrals"].update(get_players(("crazed shaman",))) + # vim: set sw=4 expandtab: diff --git a/src/roles/detective.py b/src/roles/detective.py index c1b7cc3..4a4245b 100644 --- a/src/roles/detective.py +++ b/src/roles/detective.py @@ -62,7 +62,7 @@ def on_del_player(evt, var, user, mainrole, allroles, death_triggers): @event_listener("get_special") def on_get_special(evt, var): - evt.data["special"].update(get_players(("detective",))) + evt.data["villagers"].update(get_players(("detective",))) @event_listener("exchange_roles") def on_exchange(evt, var, actor, target, actor_role, target_role): diff --git a/src/roles/doomsayer.py b/src/roles/doomsayer.py index f23f407..6c74be3 100644 --- a/src/roles/doomsayer.py +++ b/src/roles/doomsayer.py @@ -82,10 +82,6 @@ def on_doctor_immunize(evt, var, doctor, target): del SICK[n] evt.data["message"] = "not_sick" -@event_listener("get_special") -def on_get_special(evt, var): - evt.data["special"].update(get_players(("doomsayer",))) - @event_listener("chk_nightdone") def on_chk_nightdone(evt, var): evt.data["actedcount"] += len(SEEN) diff --git a/src/roles/dullahan.py b/src/roles/dullahan.py index e0d3083..95fe71b 100644 --- a/src/roles/dullahan.py +++ b/src/roles/dullahan.py @@ -109,7 +109,7 @@ def on_acted(evt, var, user, actor): @event_listener("get_special") def on_get_special(evt, var): - evt.data["special"].update(get_players(("dullahan",))) + evt.data["neutrals"].update(get_players(("dullahan",))) @event_listener("transition_day", priority=2) def on_transition_day(evt, var): diff --git a/src/roles/harlot.py b/src/roles/harlot.py index c9d33cc..bb9fffb 100644 --- a/src/roles/harlot.py +++ b/src/roles/harlot.py @@ -136,7 +136,7 @@ def on_begin_day(evt, var): @event_listener("get_special") def on_get_special(evt, var): - evt.data["special"].update(get_players(("harlot",))) + evt.data["villagers"].update(get_players(("harlot",))) @event_listener("del_player") def on_del_player(evt, var, user, mainrole, allroles, death_triggers): diff --git a/src/roles/hunter.py b/src/roles/hunter.py index 05ee034..4157c0a 100644 --- a/src/roles/hunter.py +++ b/src/roles/hunter.py @@ -81,7 +81,7 @@ def on_acted(evt, var, user, actor): @event_listener("get_special") def on_get_special(evt, var): - evt.data["special"].update(get_players(("hunter",))) + evt.data["villagers"].update(get_players(("hunter",))) @event_listener("transition_day", priority=2) def on_transition_day(evt, var): diff --git a/src/roles/investigator.py b/src/roles/investigator.py index c7d410c..ea7c965 100644 --- a/src/roles/investigator.py +++ b/src/roles/investigator.py @@ -98,7 +98,7 @@ def on_del_player(evt, var, user, mainrole, allroles, death_triggers): @event_listener("get_special") def on_get_special(evt, var): - evt.data["special"].update(get_players(("investigator",))) + evt.data["villagers"].update(get_players(("investigator",))) @event_listener("exchange_roles") def on_exchange(evt, var, actor, target, actor_role, target_role): diff --git a/src/roles/mystic.py b/src/roles/mystic.py index 37df9ad..f6f2232 100644 --- a/src/roles/mystic.py +++ b/src/roles/mystic.py @@ -9,64 +9,13 @@ from src.containers import UserList, UserSet, UserDict, DefaultUserDict from src.messages import messages from src.events import Event -@event_listener("exchange_roles") -def on_exchange(evt, var, actor, target, actor_role, target_role): - if actor_role not in ("mystic", "wolf mystic") and target_role not in ("mystic", "wolf mystic"): - return +from src.roles._mystic_helper import setup_variables - special = set(get_players(("harlot", "priest", "prophet", "matchmaker", - "doctor", "hag", "sorcerer", "turncoat", "clone"))) - evt2 = Event("get_special", {"special": special}) - evt2.dispatch(var) - pl = set(get_players()) - wolves = set(get_players(var.WOLFTEAM_ROLES)) - neutral = set(get_players(var.TRUE_NEUTRAL_ROLES)) - special = evt2.data["special"] - - if target_role == "wolf mystic" and actor_role != "wolf mystic": - # # of special villagers = # of players - # of villagers - # of wolves - # of neutrals - numvills = len(special & (pl - wolves - neutral)) - evt.data["actor_messages"].append(messages["wolf_mystic_info"].format("are" if numvills != 1 else "is", numvills, "s" if numvills != 1 else "")) - elif target_role == "mystic" and actor_role != "mystic": - numevil = len(wolves) - evt.data["actor_messages"].append(messages["mystic_info"].format("are" if numevil != 1 else "is", numevil, "s" if numevil != 1 else "")) - - if actor_role == "wolf mystic" and target_role != "wolf mystic": - # # of special villagers = # of players - # of villagers - # of wolves - # of neutrals - numvills = len(special & (pl - wolves - neutral)) - evt.data["target_messages"].append(messages["wolf_mystic_info"].format("are" if numvills != 1 else "is", numvills, "s" if numvills != 1 else "")) - elif actor_role == "mystic" and target_role != "mystic": - numevil = len(wolves) - evt.data["target_messages"].append(messages["mystic_info"].format("are" if numevil != 1 else "is", numevil, "s" if numevil != 1 else "")) - -@event_listener("transition_night_end", priority=2.01) -def on_transition_night_end(evt, var): - # init with all roles that haven't been split yet - special = set(get_players(("harlot", "priest", "prophet", "matchmaker", - "doctor", "hag", "sorcerer", "turncoat", "clone"))) - evt2 = Event("get_special", {"special": special}) - evt2.dispatch(var) - pl = set(get_players()) - wolves = set(get_players(var.WOLFTEAM_ROLES)) - neutral = set(get_players(var.TRUE_NEUTRAL_ROLES)) - special = evt2.data["special"] - - for wolf in get_all_players(("wolf mystic",)): - # if adding this info to !myrole, you will need to save off this count so that they can't get updated info until the next night - # # of special villagers = # of players - # of villagers - # of wolves - # of neutrals - numvills = len(special & (pl - wolves - neutral)) - wolf.send(messages["wolf_mystic_info"].format("are" if numvills != 1 else "is", numvills, "s" if numvills != 1 else "")) - for mystic in get_all_players(("mystic",)): - to_send = "mystic_notify" - if mystic.prefers_simple(): - to_send = "mystic_simple" - # if adding this info to !myrole, you will need to save off this count so that they can't get updated info until the next night - numevil = len(wolves) - mystic.send(messages[to_send], messages["mystic_info"].format("are" if numevil != 1 else "is", numevil, "s" if numevil != 1 else ""), sep="\n") +LAST_COUNT = setup_variables("mystic", send_role=True, types=("wolves",)) @event_listener("get_special") def on_get_special(evt, var): # mystics count as special even though they don't have any commands - evt.data["special"].update(get_players(("mystic",))) + evt.data["villagers"].update(get_players(("mystic",))) # vim: set sw=4 expandtab: diff --git a/src/roles/piper.py b/src/roles/piper.py index 944148b..11f039c 100644 --- a/src/roles/piper.py +++ b/src/roles/piper.py @@ -185,7 +185,7 @@ def on_exchange(evt, var, actor, target, actor_role, target_role): @event_listener("get_special") def on_get_special(evt, var): - evt.data["special"].update(get_players(("piper",))) + evt.data["win_stealers"].update(get_players(("piper",))) @event_listener("night_acted") def on_acted(evt, var, target, spy): diff --git a/src/roles/shaman.py b/src/roles/shaman.py index 1b6ae2b..a5ab0d3 100644 --- a/src/roles/shaman.py +++ b/src/roles/shaman.py @@ -98,4 +98,8 @@ def on_transition_night_end(evt, var): shaman.send(tmsg) shaman.send("Players: " + ", ".join(p.nick for p in pl)) +@event_listener("get_special") +def on_get_special(evt, var): + evt.data["villagers"].update(get_players(("shaman",))) + # vim: set sw=4 expandtab: diff --git a/src/roles/succubus.py b/src/roles/succubus.py index 2c6c7a9..7e4de7b 100644 --- a/src/roles/succubus.py +++ b/src/roles/succubus.py @@ -300,7 +300,7 @@ def on_transition_day(evt, var): @event_listener("get_special") def on_get_special(evt, var): - evt.data["special"].update(get_players(("succubus",))) + evt.data["win_stealers"].update(get_players(("succubus",))) @event_listener("vg_kill") def on_vg_kill(evt, var, ghost, target): diff --git a/src/roles/vigilante.py b/src/roles/vigilante.py index 9cffa7e..5cac890 100644 --- a/src/roles/vigilante.py +++ b/src/roles/vigilante.py @@ -68,7 +68,7 @@ def on_acted(evt, var, target, spy): @event_listener("get_special") def on_get_special(evt, var): - evt.data["special"].update(get_players(("vigilante",))) + evt.data["villagers"].update(get_players(("vigilante",))) @event_listener("transition_day", priority=2) def on_transition_day(evt, var): diff --git a/src/roles/wolf.py b/src/roles/wolf.py index 7aa5097..4bbedf8 100644 --- a/src/roles/wolf.py +++ b/src/roles/wolf.py @@ -150,7 +150,7 @@ def on_acted(evt, var, user, actor): @event_listener("get_special") def on_get_special(evt, var): - evt.data["special"].update(get_players(CAN_KILL)) + evt.data["wolves"].update(get_players(var.WOLFCHAT_ROLES)) @event_listener("transition_day", priority=1) def on_transition_day(evt, var): diff --git a/src/roles/wolfmystic.py b/src/roles/wolfmystic.py new file mode 100644 index 0000000..426b6f9 --- /dev/null +++ b/src/roles/wolfmystic.py @@ -0,0 +1,18 @@ +import re +import random + +from src.utilities import * +from src import users, channels, debuglog, errlog, plog +from src.functions import get_players, get_all_players +from src.decorators import cmd, event_listener +from src.containers import UserList, UserSet, UserDict, DefaultUserDict +from src.messages import messages +from src.events import Event + +from src.roles._mystic_helper import setup_variables + +LAST_COUNT = setup_variables("wolf mystic", send_role=False, types=("villagers", "win_stealers")) + +# No need for get_special, as wolf.py does it for us (for now) + +# vim: set sw=4 expandtab: