Mad scientist fixes

Also stats fix
This commit is contained in:
Vgr E. Barry 2017-01-17 14:43:28 -05:00
parent 8c2124fb6a
commit bc63f2be4f
2 changed files with 82 additions and 91 deletions

View File

@ -5,78 +5,75 @@ from collections import defaultdict, deque
import src.settings as var import src.settings as var
from src.utilities import * from src.utilities import *
from src import debuglog, errlog, plog from src.functions import get_players, get_target
from src.decorators import cmd, event_listener from src import users, debuglog, errlog, plog
from src.decorators import command, event_listener
from src.messages import messages from src.messages import messages
from src.events import Event from src.events import Event
import botconfig import botconfig
KILLS = {} # type: Dict[str, str] KILLS = {} # type: Dict[users.User, users.User]
TARGETS = {} # type: Dict[str, Set[str]] TARGETS = {} # type: Dict[users.User, Set[users.User]]
@cmd("kill", chan=False, pm=True, playing=True, silenced=True, phases=("night",), roles=("dullahan",)) @command("kill", chan=False, pm=True, playing=True, silenced=True, phases=("night",), roles=("dullahan",))
def dullahan_kill(cli, nick, chan, rest): def dullahan_kill(var, wrapper, message):
"""Kill someone at night as a dullahan until everyone on your list is dead.""" """Kill someone at night as a dullahan until everyone on your list is dead."""
if not TARGETS[nick] & set(list_players()): if not TARGETS[wrapper.source] & set(get_players()):
pm(cli, nick, messages["dullahan_targets_dead"]) wrapper.pm(messages["dullahan_targets_dead"])
return return
victim = get_victim(cli, nick, re.split(" +",rest)[0], False) target = get_target(var, wrapper, re.split(" +", message)[0])
if not victim: if not target:
return return
if victim == nick: if target is wrapper.source:
pm(cli, nick, messages["no_suicide"]) wrapper.pm(messages["no_suicide"])
return return
orig = victim orig = target
evt = Event("targeted_command", {"target": victim, "misdirection": True, "exchange": True}) evt = Event("targeted_command", {"target": target.nick, "misdirection": True, "exchange": True})
evt.dispatch(cli, var, "kill", nick, victim, frozenset({"detrimental"})) evt.dispatch(wrapper.client, var, "kill", wrapper.source.nick, target.nick, frozenset({"detrimental"}))
if evt.prevent_default: if evt.prevent_default:
return return
victim = evt.data["target"] target = evt.data["target"]
KILLS[nick] = victim KILLS[wrapper.source] = target
msg = messages["wolf_target"].format(orig) wrapper.pm(messages["player"].format(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))) debuglog("{0} ({1}) KILL: {2} ({3})".format(wrapper.source, get_role(wrapper.source.nick), target, get_role(target.nick)))
chk_nightdone(cli) chk_nightdone(wrapper.client)
@cmd("retract", "r", chan=False, pm=True, playing=True, phases=("night",), roles=("dullahan",)) @command("retract", "r", chan=False, pm=True, playing=True, phases=("night",), roles=("dullahan",))
def dullahan_retract(cli, nick, chan, rest): def dullahan_retract(var, wrapper, message):
"""Removes a dullahan's kill selection.""" """Removes a dullahan's kill selection."""
if nick not in KILLS: if KILLS.pop(wrapper.source, None):
return wrapper.pm(messages["retracted_kill"])
if nick in KILLS:
del KILLS[nick]
pm(cli, nick, messages["retracted_kill"])
@event_listener("player_win") @event_listener("player_win")
def on_player_win(evt, var, user, role, winner, survived): def on_player_win(evt, var, user, role, winner, survived):
if role != "dullahan": if role != "dullahan":
return return
alive = set(list_players()) alive = set(get_players())
if user.nick in var.ENTRANCED: if user.nick in var.ENTRANCED:
alive -= var.ROLES["succubus"] alive.difference_update(users._get(x) for x in var.ROLES["succubus"]) # FIXME
if not TARGETS[user.nick] & alive: if not TARGETS[user] & alive:
evt.data["iwon"] = True evt.data["iwon"] = True
@event_listener("del_player") @event_listener("del_player")
def on_del_player(evt, cli, var, nick, nickrole, nicktpls, death_triggers): def on_del_player(evt, cli, var, nick, nickrole, nicktpls, death_triggers):
for h,v in list(KILLS.items()): for h, v in list(KILLS.items()):
if v == nick: if v.nick == nick:
pm(cli, h, messages["hunter_discard"]) h.send(messages["hunter_discard"])
del KILLS[h] del KILLS[h]
elif h == nick: elif h.nick == nick:
del KILLS[h] del KILLS[h]
if death_triggers and nickrole == "dullahan": if death_triggers and nickrole == "dullahan":
pl = evt.data["pl"] pl = evt.data["pl"]
targets = TARGETS[nick] & set(pl) targets = TARGETS[users._get(nick)].union(users._get(x) for x in pl) # FIXME
if targets: if targets:
target = random.choice(list(targets)) target = random.choice(list(targets)).nick
prots = deque(var.ACTIVE_PROTECTIONS[target]) prots = deque(var.ACTIVE_PROTECTIONS[target])
aevt = Event("assassinate", {"pl": evt.data["pl"]}, aevt = Event("assassinate", {"pl": evt.data["pl"]},
del_player=evt.params.del_player, del_player=evt.params.del_player,
@ -105,6 +102,15 @@ def on_del_player(evt, cli, var, nick, nickrole, nicktpls, death_triggers):
evt.params.del_player(cli, target, True, end_game=False, killer_role=nickrole, deadlist=evt.params.deadlist, original=evt.params.original, ismain=False) evt.params.del_player(cli, target, True, end_game=False, killer_role=nickrole, deadlist=evt.params.deadlist, original=evt.params.original, ismain=False)
evt.data["pl"] = evt.params.refresh_pl(pl) evt.data["pl"] = evt.params.refresh_pl(pl)
@event_listener("night_acted")
def on_acted(evt, cli, var, nick, sender):
if users._get(nick) in KILLS: # FIXME
evt.data["acted"] = True
@event_listener("get_special")
def on_get_special(evt, cli, var):
evt.data["special"].update(list_players(("dullahan",)))
@event_listener("rename_player") @event_listener("rename_player")
def on_rename(evt, cli, var, prefix, nick): def on_rename(evt, cli, var, prefix, nick):
kvp = [] kvp = []
@ -131,61 +137,45 @@ def on_rename(evt, cli, var, prefix, nick):
if prefix in TARGETS: if prefix in TARGETS:
del TARGETS[prefix] del TARGETS[prefix]
@event_listener("night_acted")
def on_acted(evt, cli, var, nick, sender):
if nick in KILLS:
evt.data["acted"] = True
@event_listener("get_special")
def on_get_special(evt, cli, var):
evt.data["special"].update(list_players(("dullahan",)))
@event_listener("transition_day", priority=2) @event_listener("transition_day", priority=2)
def on_transition_day(evt, cli, var): def on_transition_day(evt, cli, var):
for k, d in list(KILLS.items()): while KILLS:
evt.data["victims"].append(d) k, d = KILLS.popitem()
evt.data["onlybywolves"].discard(d) evt.data["victims"].append(d.nick)
evt.data["killers"][d].append(k) evt.data["onlybywolves"].discard(d.nick)
del KILLS[k] evt.data["killers"][d.nick].append(k.nick)
@event_listener("exchange_roles") @event_listener("exchange_roles")
def on_exchange(evt, cli, var, actor, nick, actor_role, nick_role): def on_exchange(evt, cli, var, actor, nick, actor_role, nick_role):
if actor in KILLS: for k in set(KILLS):
del KILLS[actor] if k.nick == actor or k.nick == nick:
if nick in KILLS: del KILLS[k]
del KILLS[nick]
if actor_role == "dullahan" and nick_role != "dullahan" and actor in TARGETS: for k in set(TARGETS):
TARGETS[nick] = TARGETS[actor] - {nick} if actor_role == "dullahan" and nick_role != "dullahan" and k.nick == actor:
del TARGETS[actor] TARGETS[users._get(nick)] = TARGETS.pop(k) - {users._get(nick)} # FIXME
elif nick_role == "dullahan" and actor_role != "dullahan" and nick in TARGETS: elif nick_role == "dullahan" and actor_role != "dullahan" and k.nick == nick:
TARGETS[actor] = TARGETS[nick] - {actor} TARGET[users._get(actor)] = TARGETS.pop(k) - {users._get(actor)} # FIXME
del TARGETS[nick]
@event_listener("chk_nightdone") @event_listener("chk_nightdone")
def on_chk_nightdone(evt, cli, var): def on_chk_nightdone(evt, cli, var):
spl = set(list_players()) spl = set(get_players())
evt.data["actedcount"] += len(KILLS) evt.data["actedcount"] += len(KILLS)
for p in var.ROLES["dullahan"]: for d, targets in TARGETS.items():
if TARGETS[p] & spl: if targets & spl:
evt.data["nightroles"].append(p) evt.data["nightroles"].append(d.nick)
@event_listener("transition_night_end", priority=2) @event_listener("transition_night_end", priority=2)
def on_transition_night_end(evt, cli, var): def on_transition_night_end(evt, cli, var):
for dullahan in var.ROLES["dullahan"]: for dullahan, targets in TARGETS.items():
targets = list(TARGETS[dullahan]) targets = (targets - var.DEAD)
for target in var.DEAD:
if target in targets:
targets.remove(target)
if not targets: # already all dead if not targets: # already all dead
pm(cli, dullahan, "{0} {1}".format(messages["dullahan_simple"], messages["dullahan_targets_dead"])) dullahan.send("{0} {1}".format(messages["dullahan_simple"], messages["dullahan_targets_dead"]))
continue continue
random.shuffle(targets) random.shuffle(targets)
if dullahan in var.PLAYERS and not is_user_simple(dullahan): dullahan.send(messages["dullahan_" + ("simple" if dullahan.prefers_simple() else "notify")])
pm(cli, dullahan, messages["dullahan_notify"])
else:
pm(cli, dullahan, messages["dullahan_simple"])
t = messages["dullahan_targets"] if var.FIRST_NIGHT else messages["dullahan_remaining_targets"] t = messages["dullahan_targets"] if var.FIRST_NIGHT else messages["dullahan_remaining_targets"]
pm(cli, dullahan, t + ", ".join(targets)) dullahan.send(t + ", ".join([t.nick for t in targets]))
@event_listener("role_assignment") @event_listener("role_assignment")
def on_role_assignment(evt, cli, var, gamemode, pl, restart): def on_role_assignment(evt, cli, var, gamemode, pl, restart):

View File

@ -1624,6 +1624,7 @@ def stats(cli, nick, chan, rest):
vb = "are" vb = "are"
for role in rs: for role in rs:
count = len(var.ROLES[role])
# only show actual roles # only show actual roles
if role in var.TEMPLATE_RESTRICTIONS.keys(): if role in var.TEMPLATE_RESTRICTIONS.keys():
continue continue
@ -2689,47 +2690,47 @@ def del_player(cli, nick, forced_death=False, devoice=True, end_game=True, death
if target2.nick in var.ROLES["blessed villager"]: if target2.nick in var.ROLES["blessed villager"]:
target2 = None target2 = None
if target1 in pl: if target1.nick in pl:
if target2 in pl and target1 != target2: if target2.nick in pl and target1 is not target2:
if var.ROLE_REVEAL in ("on", "team"): if var.ROLE_REVEAL in ("on", "team"):
r1 = get_reveal_role(target1) r1 = get_reveal_role(target1.nick)
an1 = "n" if r1.startswith(("a", "e", "i", "o", "u")) else "" an1 = "n" if r1.startswith(("a", "e", "i", "o", "u")) else ""
r2 = get_reveal_role(target2) r2 = get_reveal_role(target2.nick)
an2 = "n" if r2.startswith(("a", "e", "i", "o", "u")) else "" an2 = "n" if r2.startswith(("a", "e", "i", "o", "u")) else ""
tmsg = messages["mad_scientist_kill"].format(nick, target1, an1, r1, target2, an2, r2) tmsg = messages["mad_scientist_kill"].format(nick, target1, an1, r1, target2, an2, r2)
else: else:
tmsg = messages["mad_scientist_kill_no_reveal"].format(nick, target1, target2) tmsg = messages["mad_scientist_kill_no_reveal"].format(nick, target1, target2)
cli.msg(botconfig.CHANNEL, tmsg) cli.msg(botconfig.CHANNEL, tmsg)
debuglog(nick, "(mad scientist) KILL: {0} ({1}) - {2} ({3})".format(target1, get_role(target1), target2, get_role(target2))) debuglog(nick, "(mad scientist) KILL: {0} ({1}) - {2} ({3})".format(target1, get_role(target1.nick), target2, get_role(target2.nick)))
deadlist1 = copy.copy(deadlist) deadlist1 = copy.copy(deadlist)
deadlist1.append(target2) deadlist1.append(target2)
deadlist2 = copy.copy(deadlist) deadlist2 = copy.copy(deadlist)
deadlist2.append(target1) deadlist2.append(target1)
del_player(cli, target1, True, end_game = False, killer_role = "mad scientist", deadlist = deadlist1, original = original, ismain = False) del_player(cli, target1.nick, True, end_game = False, killer_role = "mad scientist", deadlist = deadlist1, original = original, ismain = False)
del_player(cli, target2, True, end_game = False, killer_role = "mad scientist", deadlist = deadlist2, original = original, ismain = False) del_player(cli, target2.nick, True, end_game = False, killer_role = "mad scientist", deadlist = deadlist2, original = original, ismain = False)
pl = refresh_pl(pl) pl = refresh_pl(pl)
else: else:
if var.ROLE_REVEAL in ("on", "team"): if var.ROLE_REVEAL in ("on", "team"):
r1 = get_reveal_role(target1) r1 = get_reveal_role(target1.nick)
an1 = "n" if r1.startswith(("a", "e", "i", "o", "u")) else "" an1 = "n" if r1.startswith(("a", "e", "i", "o", "u")) else ""
tmsg = messages["mad_scientist_kill_single"].format(nick, target1, an1, r1) tmsg = messages["mad_scientist_kill_single"].format(nick, target1, an1, r1)
else: else:
tmsg = messages["mad_scientist_kill_single_no_reveal"].format(nick, target1) tmsg = messages["mad_scientist_kill_single_no_reveal"].format(nick, target1)
cli.msg(botconfig.CHANNEL, tmsg) cli.msg(botconfig.CHANNEL, tmsg)
debuglog(nick, "(mad scientist) KILL: {0} ({1})".format(target1, get_role(target1))) debuglog(nick, "(mad scientist) KILL: {0} ({1})".format(target1, get_role(target1.nick)))
del_player(cli, target1, True, end_game = False, killer_role = "mad scientist", deadlist = deadlist, original = original, ismain = False) del_player(cli, target1.nick, True, end_game = False, killer_role = "mad scientist", deadlist = deadlist, original = original, ismain = False)
pl = refresh_pl(pl) pl = refresh_pl(pl)
else: else:
if target2 in pl: if target2.nick in pl:
if var.ROLE_REVEAL in ("on", "team"): if var.ROLE_REVEAL in ("on", "team"):
r2 = get_reveal_role(target2) r2 = get_reveal_role(target2.nick)
an2 = "n" if r2.startswith(("a", "e", "i", "o", "u")) else "" an2 = "n" if r2.startswith(("a", "e", "i", "o", "u")) else ""
tmsg = messages["mad_scientist_kill_single"].format(nick, target2, an2, r2) tmsg = messages["mad_scientist_kill_single"].format(nick, target2, an2, r2)
else: else:
tmsg = messages["mad_scientist_kill_single_no_reveal"].format(nick, target2) tmsg = messages["mad_scientist_kill_single_no_reveal"].format(nick, target2)
cli.msg(botconfig.CHANNEL, tmsg) cli.msg(botconfig.CHANNEL, tmsg)
debuglog(nick, "(mad scientist) KILL: {0} ({1})".format(target2, get_role(target2))) debuglog(nick, "(mad scientist) KILL: {0} ({1})".format(target2, get_role(target2.nick)))
del_player(cli, target2, True, end_game = False, killer_role = "mad scientist", deadlist = deadlist, original = original, ismain = False) del_player(cli, target2.nick, True, end_game = False, killer_role = "mad scientist", deadlist = deadlist, original = original, ismain = False)
pl = refresh_pl(pl) pl = refresh_pl(pl)
else: else:
tmsg = messages["mad_scientist_fail"].format(nick) tmsg = messages["mad_scientist_fail"].format(nick)
@ -5379,7 +5380,7 @@ def relay(var, wrapper, message):
return return
elif wrapper.source.nick not in wolves and var.RESTRICT_WOLFCHAT & var.RW_WOLVES_ONLY_CHAT: elif wrapper.source.nick not in wolves and var.RESTRICT_WOLFCHAT & var.RW_WOLVES_ONLY_CHAT:
return return
elif nick not in wolves and var.RESTRICT_WOLFCHAT & var.RW_REM_NON_WOLVES: elif wrapper.source.nick not in wolves and var.RESTRICT_WOLFCHAT & var.RW_REM_NON_WOLVES:
return return
badguys.remove(wrapper.source.nick) badguys.remove(wrapper.source.nick)