Allow pipers to pass or change targets (#322)
Also adds some more info to revealroles. Some miscellaneous fixes included.
This commit is contained in:
parent
1d2ab6a2cc
commit
7d83dc4d8e
@ -415,6 +415,7 @@
|
||||
"warlock_pass": "You have chosen not to curse anyone tonight.",
|
||||
"warlock_pass_wolfchat": "\u0002{0}\u0002 has chosen not to curse anyone tonight.",
|
||||
"piper_pass": "You have chosen not to charm anyone tonight.",
|
||||
"piper_retract": "You have retracted your decision to charm.",
|
||||
"turncoat_already_turned": "You have changed sides yesterday night, and may not do so again tonight.",
|
||||
"turncoat_error": "Please specify which team you wish to side with, villagers or wolves.",
|
||||
"turncoat_success": "You are now siding with \u0002{0}\u0002.",
|
||||
@ -540,6 +541,8 @@
|
||||
"assassin_simple": "You are an \u0002assassin\u0002.",
|
||||
"piper_notify": "You are a \u0002piper\u0002. You can select up to two players to charm each night. The charmed players will know each other, but not who charmed them. You win when all other players are charmed. Use \"charm <nick1> and <nick2>\" to select the players to charm, or \"charm <nick>\" to charm just one player.",
|
||||
"piper_simple": "You are a \u0002piper\u0002.",
|
||||
"piper_revealroles_charmed": "\u0002charmed players\u0002: {0}",
|
||||
"piper_revealroles_charming": "charming {0}",
|
||||
"turncoat_notify": "You are a \u0002turncoat\u0002. You can change which team you're siding with every other night. Use \"side villagers\" or \"side wolves\" to select your team. ",
|
||||
"turncoat_current_team": "You are currently siding with \u0002{0}\u0002.",
|
||||
"turncoat_no_team": "If you die before selecting a side, you will not win.",
|
||||
|
@ -16,7 +16,7 @@ INVESTIGATED = UserSet()
|
||||
@command("id", chan=False, pm=True, playing=True, silenced=True, phases=("day",), roles=("detective",))
|
||||
def investigate(var, wrapper, message):
|
||||
"""Investigate a player to determine their exact role."""
|
||||
if wrapper.source in INVESTIGATED:
|
||||
if wrapper.source in INVESTIGATED:
|
||||
wrapper.send(messages["already_investigated"])
|
||||
return
|
||||
|
||||
@ -38,7 +38,7 @@ def investigate(var, wrapper, message):
|
||||
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 = var.WOLFCHAT_ROLES
|
||||
|
@ -44,6 +44,7 @@ def dullahan_retract(var, wrapper, message):
|
||||
"""Removes a dullahan's kill selection."""
|
||||
if KILLS.pop(wrapper.source, None):
|
||||
wrapper.pm(messages["retracted_kill"])
|
||||
debuglog("{0} (dullahan) RETRACT".format(wrapper.source))
|
||||
|
||||
@event_listener("player_win")
|
||||
def on_player_win(evt, var, user, role, winner, survived):
|
||||
@ -129,7 +130,7 @@ def on_exchange(evt, var, actor, target, actor_role, target_role):
|
||||
if actor_role == "dullahan" and target_role != "dullahan" and k is actor:
|
||||
TARGETS[target] = TARGETS.pop(k) - {target}
|
||||
elif target_role == "dullahan" and actor_role != "dullahan" and k is target:
|
||||
TARGET[actor] = TARGETS.pop(k) - {actor}
|
||||
TARGETS[actor] = TARGETS.pop(k) - {actor}
|
||||
|
||||
@event_listener("chk_nightdone")
|
||||
def on_chk_nightdone(evt, var):
|
||||
@ -205,7 +206,7 @@ def on_revealroles_role(evt, var, user, role):
|
||||
for target in TARGETS[user]:
|
||||
if target.nick in var.DEAD:
|
||||
targets.remove(target)
|
||||
if targets:
|
||||
if targets:
|
||||
evt.data["special_case"].append(messages["dullahan_to_kill"].format(", ".join(t.nick for t in targets)))
|
||||
else:
|
||||
evt.data["special_case"].append(messages["dullahan_all_dead"])
|
||||
|
@ -45,10 +45,13 @@ def hunter_retract(var, wrapper, message):
|
||||
"""Removes a hunter's kill selection."""
|
||||
if wrapper.source not in KILLS and wrapper.source not in PASSED:
|
||||
return
|
||||
KILLS.pop(wrapper.source, None)
|
||||
|
||||
del KILLS[:wrapper.source:]
|
||||
HUNTERS.discard(wrapper.source)
|
||||
PASSED.discard(wrapper.source)
|
||||
|
||||
wrapper.pm(messages["retracted_kill"])
|
||||
debuglog("{0} (hunter) RETRACT".format(wrapper.source))
|
||||
|
||||
@command("pass", chan=False, pm=True, playing=True, silenced=True, phases=("night",), roles=("hunter",))
|
||||
def hunter_pass(var, wrapper, message):
|
||||
@ -56,7 +59,8 @@ def hunter_pass(var, wrapper, message):
|
||||
if wrapper.source in HUNTERS and wrapper.source not in KILLS:
|
||||
wrapper.pm(messages["hunter_already_killed"])
|
||||
return
|
||||
KILLS.pop(wrapper.source, None)
|
||||
|
||||
del KILLS[:wrapper.source:]
|
||||
HUNTERS.discard(wrapper.source)
|
||||
PASSED.add(wrapper.source)
|
||||
wrapper.pm(messages["hunter_pass"])
|
||||
|
@ -46,7 +46,6 @@ def _get_targets(var, pl, user):
|
||||
|
||||
return (target1, target2)
|
||||
|
||||
|
||||
@event_listener("del_player")
|
||||
def on_del_player(evt, var, user, mainrole, allroles, death_triggers):
|
||||
if not death_triggers or "mad scientist" not in allroles:
|
||||
|
@ -15,10 +15,11 @@ from src.events import Event
|
||||
|
||||
TOBECHARMED = UserDict() # type: Dict[users.User, Set[users.User]]
|
||||
CHARMED = UserSet() # type: Set[users.User]
|
||||
PASSED = UserSet() # type: Set[users.User]
|
||||
|
||||
@command("charm", chan=False, pm=True, playing=True, silenced=True, phases=("night",), roles=("piper",))
|
||||
def charm(var, wrapper, message):
|
||||
"""Charm a player, slowly leading to your win!"""
|
||||
"""Charm a player or two, slowly leading to your win!"""
|
||||
pieces = re.split(" +", message)
|
||||
target1 = pieces[0]
|
||||
if len(pieces) > 1:
|
||||
@ -75,6 +76,7 @@ def charm(var, wrapper, message):
|
||||
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,
|
||||
@ -85,6 +87,25 @@ def charm(var, wrapper, message):
|
||||
debuglog("{0} (piper) CHARM {1} ({2})".format(wrapper.source, target1, get_main_role(target1)))
|
||||
wrapper.send(messages["charm_success"].format(orig1))
|
||||
|
||||
@command("pass", chan=False, pm=True, playing=True, silenced=True, phases=("night",), roles=("piper",))
|
||||
def pass_cmd(var, wrapper, message):
|
||||
"""Do not charm anyone tonight."""
|
||||
del TOBECHARMED[:wrapper.source:]
|
||||
PASSED.add(wrapper.source)
|
||||
|
||||
wrapper.send(messages["piper_pass"])
|
||||
debuglog("{0} (piper) PASS".format(wrapper.source))
|
||||
|
||||
@command("retract", "r", chan=False, pm=True, playing=True, silenced=True, phases=("night",), roles=("piper",))
|
||||
def retract(var, wrapper, message):
|
||||
"""Remove your decision to charm people."""
|
||||
if wrapper.source in TOBECHARMED or wrapper.source in PASSED:
|
||||
del TOBECHARMED[:wrapper.source:]
|
||||
PASSED.discard(wrapper.source)
|
||||
|
||||
wrapper.send(messages["piper_retract"])
|
||||
debuglog("{0} (piper) RETRACT".format(wrapper.source))
|
||||
|
||||
@event_listener("chk_win", priority=2)
|
||||
def on_chk_win(evt, var, rolemap, mainroles, lpl, lwolves, lrealwolves):
|
||||
# lpl doesn't included wounded/sick people or consecrating priests
|
||||
@ -113,9 +134,7 @@ def on_player_win(evt, var, player, mainrole, winner, survived):
|
||||
@event_listener("del_player")
|
||||
def on_del_player(evt, var, player, mainrole, allroles, death_triggers):
|
||||
CHARMED.discard(player)
|
||||
x = TOBECHARMED.pop(player, None)
|
||||
if x is not None:
|
||||
x.clear()
|
||||
del TOBECHARMED[:player:]
|
||||
|
||||
@event_listener("transition_day_begin")
|
||||
def on_transition_day_begin(evt, var):
|
||||
@ -157,10 +176,11 @@ def on_transition_day_begin(evt, var):
|
||||
|
||||
CHARMED.update(tocharm)
|
||||
TOBECHARMED.clear()
|
||||
PASSED.clear()
|
||||
|
||||
@event_listener("chk_nightdone")
|
||||
def on_chk_nightdone(evt, var):
|
||||
evt.data["actedcount"] += len(TOBECHARMED.keys())
|
||||
evt.data["actedcount"] += len(TOBECHARMED) + len(PASSED)
|
||||
evt.data["nightroles"].extend(get_all_players(("piper",)))
|
||||
|
||||
@event_listener("transition_night_end", priority=2)
|
||||
@ -180,8 +200,14 @@ def on_exchange(evt, var, actor, target, actor_role, target_role):
|
||||
# if we're shifting piper around, ensure that the new piper isn't charmed
|
||||
if actor_role == "piper":
|
||||
CHARMED.discard(target)
|
||||
if target_role != "piper":
|
||||
del TOBECHARMED[:actor:]
|
||||
PASSED.discard(actor)
|
||||
if target_role == "piper":
|
||||
CHARMED.discard(actor)
|
||||
if actor_role != "piper":
|
||||
del TOBECHARMED[:target:]
|
||||
PASSED.discard(target)
|
||||
|
||||
@event_listener("get_special")
|
||||
def on_get_special(evt, var):
|
||||
@ -196,10 +222,19 @@ def on_acted(evt, var, target, spy):
|
||||
def on_reset(evt, var):
|
||||
CHARMED.clear()
|
||||
TOBECHARMED.clear()
|
||||
PASSED.clear()
|
||||
|
||||
@event_listener("revealroles")
|
||||
def on_revealroles(evt, var, wrapper):
|
||||
if CHARMED:
|
||||
evt.data["output"].append("\u0002charmed players\u0002: {0}".format(", ".join(p.nick for p in CHARMED)))
|
||||
nicks = ", ".join(p.nick for p in CHARMED)
|
||||
evt.data["output"].append(messages["piper_revealroles_charmed"].format(nicks))
|
||||
|
||||
@event_listener("revealroles_role")
|
||||
def on_revealroles_role(evt, var, user, role):
|
||||
players = TOBECHARMED.get(user)
|
||||
if players:
|
||||
nicks = ", ".join(p.nick for p in players)
|
||||
evt.data["special_case"].append(messages["piper_revealroles_charming"].format(nicks))
|
||||
|
||||
# vim: set sw=4 expandtab:
|
||||
|
@ -49,16 +49,18 @@ def vg_kill(var, wrapper, message):
|
||||
|
||||
wrapper.pm(messages["player_kill"].format(orig))
|
||||
|
||||
debuglog("{0} (vengeful ghost) KILL: {1} ({2})".format(wrapper.source.nick, target, get_main_role(target)))
|
||||
debuglog("{0} (vengeful ghost) KILL: {1} ({2})".format(wrapper.source, target, get_main_role(target)))
|
||||
|
||||
@command("retract", "r", chan=False, pm=True, playing=False, phases=("night",))
|
||||
def vg_retract(var, wrapper, message):
|
||||
"""Removes a vengeful ghost's kill selection."""
|
||||
if wrapper.source not in GHOSTS:
|
||||
return
|
||||
|
||||
if wrapper.source in KILLS:
|
||||
del KILLS[wrapper.source]
|
||||
wrapper.pm(messages["retracted_kill"])
|
||||
debuglog("{0} (vengeful ghost) RETRACT".format(wrapper.source))
|
||||
|
||||
@event_listener("get_participants")
|
||||
def on_get_participants(evt, var):
|
||||
|
@ -30,7 +30,6 @@ def vigilante_kill(var, wrapper, message):
|
||||
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)))
|
||||
|
||||
@command("retract", "r", chan=False, pm=True, playing=True, phases=("night",), roles=("vigilante",))
|
||||
@ -39,14 +38,16 @@ def vigilante_retract(var, wrapper, message):
|
||||
if wrapper.source not in KILLS and wrapper.source not in PASSED:
|
||||
return
|
||||
|
||||
KILLS.pop(wrapper.source, None)
|
||||
del KILLS[:wrapper.source:]
|
||||
PASSED.discard(wrapper.source)
|
||||
|
||||
wrapper.send(messages["retracted_kill"])
|
||||
debuglog("{0} (vigilante) RETRACT".format(wrapper.source))
|
||||
|
||||
@command("pass", chan=False, pm=True, playing=True, silenced=True, phases=("night",), roles=("vigilante",))
|
||||
def vigilante_pass(var, wrapper, message):
|
||||
"""Do not kill anyone tonight as a vigilante."""
|
||||
KILLS.pop(wrapper.source, None)
|
||||
del KILLS[:wrapper.source:]
|
||||
PASSED.add(wrapper.source)
|
||||
wrapper.send(messages["hunter_pass"])
|
||||
|
||||
@ -55,7 +56,7 @@ def vigilante_pass(var, wrapper, message):
|
||||
@event_listener("del_player")
|
||||
def on_del_player(evt, var, user, mainrole, allroles, death_triggers):
|
||||
PASSED.discard(user)
|
||||
KILLS.pop(user, None)
|
||||
del KILLS[:user:]
|
||||
for vigilante, target in list(KILLS.items()):
|
||||
if target is user:
|
||||
vigilante.send(messages["hunter_discard"])
|
||||
@ -84,8 +85,8 @@ def on_transition_day(evt, var):
|
||||
|
||||
@event_listener("exchange_roles")
|
||||
def on_exchange(evt, var, actor, target, actor_role, target_role):
|
||||
KILLS.pop(actor, None)
|
||||
KILLS.pop(target, None)
|
||||
del KILLS[:actor:]
|
||||
del KILLS[:target:]
|
||||
PASSED.discard(actor)
|
||||
PASSED.discard(target)
|
||||
|
||||
|
@ -62,7 +62,7 @@ def wolf_kill(cli, nick, chan, rest):
|
||||
victim = get_victim(cli, nick, victim, False)
|
||||
if not victim:
|
||||
return
|
||||
|
||||
|
||||
if victim == nick:
|
||||
pm(cli, nick, messages["no_suicide"])
|
||||
return
|
||||
|
Loading…
Reference in New Issue
Block a user