Add vigilante
This commit is contained in:
parent
ac2f28e6ed
commit
67f698a701
@ -38,7 +38,6 @@ def hunter_kill(cli, nick, chan, rest):
|
|||||||
pm(cli, nick, messages["player"].format(msg))
|
pm(cli, nick, messages["player"].format(msg))
|
||||||
|
|
||||||
debuglog("{0} ({1}) KILL: {2} ({3})".format(nick, get_role(nick), victim, get_role(victim)))
|
debuglog("{0} ({1}) KILL: {2} ({3})".format(nick, get_role(nick), victim, get_role(victim)))
|
||||||
|
|
||||||
chk_nightdone(cli)
|
chk_nightdone(cli)
|
||||||
|
|
||||||
@cmd("retract", "r", chan=False, pm=True, playing=True, phases=("night",), roles=("hunter",))
|
@cmd("retract", "r", chan=False, pm=True, playing=True, phases=("night",), roles=("hunter",))
|
||||||
@ -64,6 +63,9 @@ def hunter_pass(cli, nick, chan, rest):
|
|||||||
PASSED.add(nick)
|
PASSED.add(nick)
|
||||||
pm(cli, nick, messages["hunter_pass"])
|
pm(cli, nick, messages["hunter_pass"])
|
||||||
|
|
||||||
|
debuglog("{0} ({1}) PASS".format(nick, get_role(nick)))
|
||||||
|
chk_nightdone(cli)
|
||||||
|
|
||||||
@event_listener("del_player")
|
@event_listener("del_player")
|
||||||
def on_del_player(evt, cli, var, nick, nickrole, nicktpls, lynched, end_game, death_triggers, killer_role, deadlist, original, ismain, refresh_pl):
|
def on_del_player(evt, cli, var, nick, nickrole, nicktpls, lynched, end_game, death_triggers, killer_role, deadlist, original, ismain, refresh_pl):
|
||||||
for h,v in list(KILLS.items()):
|
for h,v in list(KILLS.items()):
|
||||||
|
140
src/roles/vigilante.py
Normal file
140
src/roles/vigilante.py
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
import re
|
||||||
|
import random
|
||||||
|
from collections import defaultdict
|
||||||
|
|
||||||
|
import src.settings as var
|
||||||
|
from src.utilities import *
|
||||||
|
from src import debuglog, errlog, plog
|
||||||
|
from src.decorators import cmd, event_listener
|
||||||
|
from src.messages import messages
|
||||||
|
from src.events import Event
|
||||||
|
|
||||||
|
KILLS = {} # type: Dict[str, str]
|
||||||
|
PASSED = set()
|
||||||
|
|
||||||
|
@cmd("kill", chan=False, pm=True, playing=True, silenced=True, phases=("night",), roles=("vigilante",))
|
||||||
|
def vigilante_kill(cli, nick, chan, rest):
|
||||||
|
"""Kill someone at night, but you die too if they aren't a wolf or win stealer!"""
|
||||||
|
victim = get_victim(cli, nick, re.split(" +",rest)[0], False)
|
||||||
|
if not victim:
|
||||||
|
return
|
||||||
|
|
||||||
|
orig = victim
|
||||||
|
evt = Event("targeted_command", {"target": victim, "misdirection": True, "exchange": True})
|
||||||
|
evt.dispatch(cli, var, "kill", nick, victim, frozenset({"detrimental"}))
|
||||||
|
if evt.prevent_default:
|
||||||
|
return
|
||||||
|
victim = evt.data["target"]
|
||||||
|
|
||||||
|
KILLS[nick] = victim
|
||||||
|
PASSED.discard(nick)
|
||||||
|
|
||||||
|
msg = messages["wolf_target"].format(orig)
|
||||||
|
pm(cli, nick, messages["player"].format(msg))
|
||||||
|
|
||||||
|
debuglog("{0} ({1}) KILL: {2} ({3})".format(nick, get_role(nick), victim, get_role(victim)))
|
||||||
|
|
||||||
|
chk_nightdone(cli)
|
||||||
|
|
||||||
|
@cmd("retract", "r", chan=False, pm=True, playing=True, phases=("night",), roles=("vigilante",))
|
||||||
|
def vigilante_retract(cli, nick, chan, rest):
|
||||||
|
"""Removes a vigilante's kill selection."""
|
||||||
|
if nick not in KILLS and nick not in PASSED:
|
||||||
|
return
|
||||||
|
if nick in KILLS:
|
||||||
|
del KILLS[nick]
|
||||||
|
PASSED.discard(nick)
|
||||||
|
pm(cli, nick, messages["retracted_kill"])
|
||||||
|
|
||||||
|
@cmd("pass", chan=False, pm=True, playing=True, silenced=True, phases=("night",), roles=("vigilante",))
|
||||||
|
def vigilante_pass(cli, nick, chan, rest):
|
||||||
|
"""Do not kill anyone tonight as a vigilante."""
|
||||||
|
if nick in KILLS:
|
||||||
|
del KILLS[nick]
|
||||||
|
PASSED.add(nick)
|
||||||
|
pm(cli, nick, messages["hunter_pass"])
|
||||||
|
|
||||||
|
debuglog("{0} ({1}) PASS".format(nick, get_role(nick)))
|
||||||
|
chk_nightdone(cli)
|
||||||
|
|
||||||
|
@event_listener("del_player")
|
||||||
|
def on_del_player(evt, cli, var, nick, nickrole, nicktpls, lynched, end_game, death_triggers, killer_role, deadlist, original, ismain, refresh_pl):
|
||||||
|
for h,v in list(KILLS.items()):
|
||||||
|
if v == nick:
|
||||||
|
PASSED.discard(h)
|
||||||
|
pm(cli, h, messages["hunter_discard"])
|
||||||
|
del KILLS[h]
|
||||||
|
elif h == nick:
|
||||||
|
del KILLS[h]
|
||||||
|
|
||||||
|
@event_listener("rename_player")
|
||||||
|
def on_rename(evt, cli, var, prefix, nick):
|
||||||
|
kvp = []
|
||||||
|
for a,b in KILLS.items():
|
||||||
|
if a == prefix:
|
||||||
|
a = nick
|
||||||
|
if b == prefix:
|
||||||
|
b = nick
|
||||||
|
kvp.append((a,b))
|
||||||
|
KILLS.update(kvp)
|
||||||
|
if prefix in KILLS:
|
||||||
|
del KILLS[prefix]
|
||||||
|
if prefix in PASSED:
|
||||||
|
PASSED.discard(prefix)
|
||||||
|
PASSED.add(nick)
|
||||||
|
|
||||||
|
@event_listener("acted")
|
||||||
|
def on_acted(evt, cli, var, nick, sender):
|
||||||
|
if nick in KILLS:
|
||||||
|
evt.data["acted"] = True
|
||||||
|
|
||||||
|
@event_listener("transition_day", priority=2)
|
||||||
|
def on_transition_day(evt, cli, var):
|
||||||
|
for k, d in list(KILLS.items()):
|
||||||
|
evt.data["victims"].append(d)
|
||||||
|
evt.data["onlybywolves"].discard(d)
|
||||||
|
evt.data["killers"][d] = k
|
||||||
|
# important, otherwise our del_player listener lets hunter kill again
|
||||||
|
del KILLS[k]
|
||||||
|
|
||||||
|
if get_role(d) not in var.WOLF_ROLES | var.WIN_STEALER_ROLES:
|
||||||
|
var.DYING.add(k)
|
||||||
|
|
||||||
|
@event_listener("exchange_roles")
|
||||||
|
def on_exchange(evt, cli, var, actor, nick, actor_role, nick_role):
|
||||||
|
if actor in KILLS:
|
||||||
|
del KILLS[actor]
|
||||||
|
if nick in KILLS:
|
||||||
|
del KILLS[nick]
|
||||||
|
PASSED.discard(actor)
|
||||||
|
PASSED.discard(nick)
|
||||||
|
|
||||||
|
@event_listener("chk_nightdone")
|
||||||
|
def on_chk_nightdone(evt, cli, var):
|
||||||
|
evt.data["actedcount"] += len(KILLS) + len(PASSED)
|
||||||
|
evt.data["nightroles"].extend(get_roles("vigilante"))
|
||||||
|
|
||||||
|
@event_listener("transition_night_end", priority=2)
|
||||||
|
def on_transition_night_end(evt, cli, var):
|
||||||
|
ps = list_players()
|
||||||
|
for vigilante in var.ROLES["vigilante"]:
|
||||||
|
pl = ps[:]
|
||||||
|
random.shuffle(pl)
|
||||||
|
pl.remove(vigilante)
|
||||||
|
if vigilante in var.PLAYERS and not is_user_simple(vigilante):
|
||||||
|
pm(cli, vigilante, messages["vigilante_notify"])
|
||||||
|
else:
|
||||||
|
pm(cli, vigilante, messages["vigilante_simple"])
|
||||||
|
pm(cli, vigilante, "Players: " + ", ".join(pl))
|
||||||
|
|
||||||
|
@event_listener("begin_day")
|
||||||
|
def on_begin_day(evt, cli, var):
|
||||||
|
KILLS.clear()
|
||||||
|
PASSED.clear()
|
||||||
|
|
||||||
|
@event_listener("reset")
|
||||||
|
def on_reset(evt, var):
|
||||||
|
KILLS.clear()
|
||||||
|
PASSED.clear()
|
||||||
|
|
||||||
|
# vim: set sw=4 expandtab:
|
@ -282,6 +282,8 @@ SEEN_DEFAULT = frozenset({"traitor", "hag", "sorcerer", "time lord", "villager",
|
|||||||
HIDDEN_VILLAGERS = frozenset({"time lord"})
|
HIDDEN_VILLAGERS = frozenset({"time lord"})
|
||||||
# These roles are notified that they are the default role. They also win alongside the default role barring other role-specific win conds.
|
# These roles are notified that they are the default role. They also win alongside the default role barring other role-specific win conds.
|
||||||
HIDDEN_ROLES = frozenset({"vengeful ghost", "amnesiac"})
|
HIDDEN_ROLES = frozenset({"vengeful ghost", "amnesiac"})
|
||||||
|
# These roles are win stealers, and are valid kills for vigilante
|
||||||
|
WIN_STEALER_ROLES = frozenset({"monster", "succubus", "demoniac", "piper", "fool"})
|
||||||
|
|
||||||
# these totems are beneficial for the *receiving* person, but can be detrimental to someone else acting on the receiver!
|
# these totems are beneficial for the *receiving* person, but can be detrimental to someone else acting on the receiver!
|
||||||
BENEFICIAL_TOTEMS = frozenset({"protection", "revealing", "desperation", "influence", "luck", "pestilence", "retribution"})
|
BENEFICIAL_TOTEMS = frozenset({"protection", "revealing", "desperation", "influence", "luck", "pestilence", "retribution"})
|
||||||
|
@ -3826,7 +3826,7 @@ def begin_day(cli):
|
|||||||
|
|
||||||
# Reset nighttime variables
|
# Reset nighttime variables
|
||||||
var.GAMEPHASE = "day"
|
var.GAMEPHASE = "day"
|
||||||
var.OTHER_KILLS = {} # other kill victims (vigilante/vengeful ghost)
|
var.OTHER_KILLS = {} # other kill victims (dullahan/vengeful ghost)
|
||||||
var.KILLER = "" # nickname of who chose the victim
|
var.KILLER = "" # nickname of who chose the victim
|
||||||
var.SEEN = set() # set of doomsayers that have had visions
|
var.SEEN = set() # set of doomsayers that have had visions
|
||||||
var.HEXED = set() # set of hags that have silenced others
|
var.HEXED = set() # set of hags that have silenced others
|
||||||
@ -4133,9 +4133,6 @@ def transition_day(cli, gameid=0):
|
|||||||
killers[d].append(k)
|
killers[d].append(k)
|
||||||
if var.VENGEFUL_GHOSTS.get(k) == "villagers":
|
if var.VENGEFUL_GHOSTS.get(k) == "villagers":
|
||||||
wolfghostvictims.append(d)
|
wolfghostvictims.append(d)
|
||||||
if k in var.ROLES["vigilante"]:
|
|
||||||
if get_role(d) not in var.WOLF_ROLES | {"monster", "succubus", "demoniac", "piper", "fool"}:
|
|
||||||
var.DYING.add(k)
|
|
||||||
|
|
||||||
for v in var.ENTRANCED_DYING:
|
for v in var.ENTRANCED_DYING:
|
||||||
var.DYING.add(v)
|
var.DYING.add(v)
|
||||||
@ -4672,7 +4669,7 @@ def chk_nightdone(cli):
|
|||||||
|
|
||||||
nightroles = get_roles("harlot", "succubus", "bodyguard", "guardian angel",
|
nightroles = get_roles("harlot", "succubus", "bodyguard", "guardian angel",
|
||||||
"sorcerer", "hag", "shaman", "crazed shaman",
|
"sorcerer", "hag", "shaman", "crazed shaman",
|
||||||
"warlock", "piper", "vigilante", "doomsayer",
|
"warlock", "piper", "doomsayer",
|
||||||
"prophet", "wolf shaman")
|
"prophet", "wolf shaman")
|
||||||
|
|
||||||
for ghost, against in var.VENGEFUL_GHOSTS.items():
|
for ghost, against in var.VENGEFUL_GHOSTS.items():
|
||||||
@ -5331,7 +5328,7 @@ def kill(cli, nick, chan, rest):
|
|||||||
role = get_role(nick)
|
role = get_role(nick)
|
||||||
except KeyError:
|
except KeyError:
|
||||||
role = None
|
role = None
|
||||||
if role not in {"dullahan", "vigilante"} and nick not in var.VENGEFUL_GHOSTS.keys():
|
if role != "dullahan" and nick not in var.VENGEFUL_GHOSTS.keys():
|
||||||
return
|
return
|
||||||
if nick in var.VENGEFUL_GHOSTS.keys() and var.VENGEFUL_GHOSTS[nick][0] == "!":
|
if nick in var.VENGEFUL_GHOSTS.keys() and var.VENGEFUL_GHOSTS[nick][0] == "!":
|
||||||
# ghost was driven away by retribution
|
# ghost was driven away by retribution
|
||||||
@ -5885,7 +5882,7 @@ def bite_cmd(cli, nick, chan, rest):
|
|||||||
chk_nightdone(cli)
|
chk_nightdone(cli)
|
||||||
|
|
||||||
@cmd("pass", chan=False, pm=True, playing=True, phases=("night",),
|
@cmd("pass", chan=False, pm=True, playing=True, phases=("night",),
|
||||||
roles=("harlot", "bodyguard", "guardian angel", "turncoat", "warlock", "piper", "succubus", "vigilante"))
|
roles=("harlot", "bodyguard", "guardian angel", "turncoat", "warlock", "piper", "succubus"))
|
||||||
def pass_cmd(cli, nick, chan, rest):
|
def pass_cmd(cli, nick, chan, rest):
|
||||||
"""Decline to use your special power for that night."""
|
"""Decline to use your special power for that night."""
|
||||||
nickrole = get_role(nick)
|
nickrole = get_role(nick)
|
||||||
@ -5941,11 +5938,6 @@ def pass_cmd(cli, nick, chan, rest):
|
|||||||
return
|
return
|
||||||
pm(cli, nick, )
|
pm(cli, nick, )
|
||||||
var.PASSED.add(nick)
|
var.PASSED.add(nick)
|
||||||
elif nickrole == "vigilante":
|
|
||||||
if nick in var.OTHER_KILLS:
|
|
||||||
del var.OTHER_KILLS[nick]
|
|
||||||
pm(cli, nick, messages["hunter_pass"])
|
|
||||||
var.PASSED.add(nick)
|
|
||||||
|
|
||||||
debuglog("{0} ({1}) PASS".format(nick, get_role(nick)))
|
debuglog("{0} ({1}) PASS".format(nick, get_role(nick)))
|
||||||
chk_nightdone(cli)
|
chk_nightdone(cli)
|
||||||
@ -6705,16 +6697,6 @@ def transition_night(cli):
|
|||||||
pm(cli, succubus, messages["succubus_simple"])
|
pm(cli, succubus, messages["succubus_simple"])
|
||||||
pm(cli, succubus, "Players: " + ", ".join(("{0} ({1})".format(x, get_role(x)) if x in var.ROLES["succubus"] else x for x in pl)))
|
pm(cli, succubus, "Players: " + ", ".join(("{0} ({1})".format(x, get_role(x)) if x in var.ROLES["succubus"] else x for x in pl)))
|
||||||
|
|
||||||
for vigilante in var.ROLES["vigilante"]:
|
|
||||||
pl = ps[:]
|
|
||||||
random.shuffle(pl)
|
|
||||||
pl.remove(vigilante)
|
|
||||||
if vigilante in var.PLAYERS and not is_user_simple(vigilante):
|
|
||||||
pm(cli, vigilante, messages["vigilante_notify"])
|
|
||||||
else:
|
|
||||||
pm(cli, vigilante, messages["vigilante_simple"])
|
|
||||||
pm(cli, vigilante, "Players: " + ", ".join(pl))
|
|
||||||
|
|
||||||
for ms in var.ROLES["mad scientist"]:
|
for ms in var.ROLES["mad scientist"]:
|
||||||
pl = ps[:]
|
pl = ps[:]
|
||||||
index = var.ALL_PLAYERS.index(ms)
|
index = var.ALL_PLAYERS.index(ms)
|
||||||
|
Loading…
Reference in New Issue
Block a user