diff --git a/src/gamemodes.py b/src/gamemodes.py index 51a9945..0f08d18 100644 --- a/src/gamemodes.py +++ b/src/gamemodes.py @@ -223,7 +223,7 @@ class VillagergameMode(GameMode): t = threading.Timer(abs(rand), transition_day, args=(cli,), kwargs={"gameid": gameid}) t.start() - def transition_day(self, evt, cli, var): + def transition_day(self, evt, var): # 30% chance we kill a safe, otherwise kill at random # when killing safes, go after seer, then harlot, then shaman self.delaying_night = False @@ -256,7 +256,7 @@ class VillagergameMode(GameMode): from src.roles import wolf wolf.KILLS[botconfig.NICK] = [tgt] - def on_retribution_kill(self, evt, cli, var, victim, orig_target): + def on_retribution_kill(self, evt, var, victim, orig_target): # There are no wolves for this totem to kill if orig_target == "@wolves": evt.data["target"] = None @@ -1130,11 +1130,13 @@ class SleepyMode(GameMode): if self.having_nightmare is not None: evt.data["actedcount"] = -1 - def nightmare_kill(self, evt, cli, var): + def nightmare_kill(self, evt, var): # if True, it means night ended before 1 minute - if self.having_nightmare is not None and self.having_nightmare is not True and self.having_nightmare in list_players(): - var.DYING.add(self.having_nightmare) - pm(cli, self.having_nightmare, messages["sleepy_nightmare_death"]) + if self.having_nightmare is not None and self.having_nightmare is not True: + user = users._get(self.having_nightmare) # FIXME + if user in get_players(): + var.DYING.add(user) + user.send(messages["sleepy_nightmare_death"]) def happy_fun_times(self, evt, var, user, mainrole, allroles, death_triggers): if death_triggers: diff --git a/src/roles/angel.py b/src/roles/angel.py index 901aca2..b89d7a6 100644 --- a/src/roles/angel.py +++ b/src/roles/angel.py @@ -117,43 +117,43 @@ def on_chk_nightdone(evt, var): evt.data["nightroles"].extend(get_players(("guardian angel", "bodyguard"))) @event_listener("transition_day", priority=4.2) -def on_transition_day(evt, cli, var): - pl = list_players() +def on_transition_day(evt, var): + pl = get_players() vs = set(evt.data["victims"]) for v in pl: if v in vs: if v in var.DYING: continue - for g in var.ROLES["guardian angel"]: - if GUARDED.get(g) == v: + for g in get_all_players(("guardian angel",)): + if GUARDED.get(g.nick) == v.nick: evt.data["numkills"][v] -= 1 if evt.data["numkills"][v] >= 0: evt.data["killers"][v].pop(0) if evt.data["numkills"][v] <= 0 and v not in evt.data["protected"]: evt.data["protected"][v] = "angel" elif evt.data["numkills"][v] <= 0: - var.ACTIVE_PROTECTIONS[v].append("angel") - for g in var.ROLES["bodyguard"]: - if GUARDED.get(g) == v: + var.ACTIVE_PROTECTIONS[v.nick].append("angel") + for g in get_all_players(("bodyguard",)): + if GUARDED.get(g.nick) == v.nick: evt.data["numkills"][v] -= 1 if evt.data["numkills"][v] >= 0: evt.data["killers"][v].pop(0) if evt.data["numkills"][v] <= 0 and v not in evt.data["protected"]: evt.data["protected"][v] = "bodyguard" elif evt.data["numkills"][v] <= 0: - var.ACTIVE_PROTECTIONS[v].append("bodyguard") + var.ACTIVE_PROTECTIONS[v.nick].append("bodyguard") else: for g in var.ROLES["guardian angel"]: - if GUARDED.get(g) == v: - var.ACTIVE_PROTECTIONS[v].append("angel") + if GUARDED.get(g) == v.nick: + var.ACTIVE_PROTECTIONS[v.nick].append("angel") for g in var.ROLES["bodyguard"]: - if GUARDED.get(g) == v: - var.ACTIVE_PROTECTIONS[v].append("bodyguard") + if GUARDED.get(g) == v.nick: + var.ACTIVE_PROTECTIONS[v.nick].append("bodyguard") @event_listener("fallen_angel_guard_break") -def on_fagb(evt, cli, var, victim, killer): - for g in var.ROLES["guardian angel"]: - if GUARDED.get(g) == victim: +def on_fagb(evt, var, user, killer): + for g in get_all_players(("guardian angel",)): + if GUARDED.get(g.nick) == user.nick: if random.random() < var.FALLEN_ANGEL_KILLS_GUARDIAN_ANGEL_CHANCE: if g in evt.data["protected"]: del evt.data["protected"][g] @@ -162,10 +162,10 @@ def on_fagb(evt, cli, var, victim, killer): evt.data["onlybywolves"].add(g) evt.data["victims"].append(g) evt.data["killers"][g].append(killer) - if g != victim: - pm(cli, g, messages["fallen_angel_success"].format(victim)) - for g in var.ROLES["bodyguard"]: - if GUARDED.get(g) == victim: + if g is not user: + g.send(messages["fallen_angel_success"].format(user)) + for g in get_all_players(("bodyguard",)): + if GUARDED.get(g.nick) == user.nick: if g in evt.data["protected"]: del evt.data["protected"][g] evt.data["bywolves"].add(g) @@ -173,19 +173,19 @@ def on_fagb(evt, cli, var, victim, killer): evt.data["onlybywolves"].add(g) evt.data["victims"].append(g) evt.data["killers"][g].append(killer) - if g != victim: - pm(cli, g, messages["fallen_angel_success"].format(victim)) + if g is not user: + g.send(messages["fallen_angel_success"].format(user)) @event_listener("transition_day_resolve", priority=2) -def on_transition_day_resolve(evt, cli, var, victim): +def on_transition_day_resolve(evt, var, victim): if evt.data["protected"].get(victim) == "angel": evt.data["message"].append(messages["angel_protection"].format(victim)) evt.data["novictmsg"] = False evt.stop_processing = True evt.prevent_default = True elif evt.data["protected"].get(victim) == "bodyguard": - for bodyguard in var.ROLES["bodyguard"]: - if GUARDED.get(bodyguard) == victim: + for bodyguard in get_all_players(("bodyguard",)): + if GUARDED.get(bodyguard.nick) == victim.nick: evt.data["dead"].append(bodyguard) evt.data["message"].append(messages["bodyguard_protection"].format(bodyguard)) evt.data["novictmsg"] = False @@ -194,9 +194,9 @@ def on_transition_day_resolve(evt, cli, var, victim): break @event_listener("transition_day_resolve_end") -def on_transition_day_resolve_end(evt, cli, var, victims): - for bodyguard in var.ROLES["bodyguard"]: - if GUARDED.get(bodyguard) in list_players(var.WOLF_ROLES) and bodyguard not in evt.data["dead"] and bodyguard not in evt.data["bitten"]: +def on_transition_day_resolve_end(evt, var, victims): + for bodyguard in get_all_players(("bodyguard",)): + if GUARDED.get(bodyguard.nick) in list_players(var.WOLF_ROLES) and bodyguard not in evt.data["dead"] and bodyguard not in evt.data["bitten"]: r = random.random() if r < var.BODYGUARD_DIES_CHANCE: evt.data["bywolves"].add(bodyguard) @@ -206,8 +206,8 @@ def on_transition_day_resolve_end(evt, cli, var, victims): else: # off and team evt.data["message"].append(messages["bodyguard_protection"].format(bodyguard)) evt.data["dead"].append(bodyguard) - for gangel in var.ROLES["guardian angel"]: - if GUARDED.get(gangel) in list_players(var.WOLF_ROLES) and gangel not in evt.data["dead"] and gangel not in evt.data["bitten"]: + for gangel in get_all_players(("guardian angel",)): + if GUARDED.get(gangel.nick) in list_players(var.WOLF_ROLES) and gangel not in evt.data["dead"] and gangel not in evt.data["bitten"]: r = random.random() if r < var.GUARDIAN_ANGEL_DIES_CHANCE: evt.data["bywolves"].add(gangel) diff --git a/src/roles/blessed.py b/src/roles/blessed.py index b713227..ce8eb5e 100644 --- a/src/roles/blessed.py +++ b/src/roles/blessed.py @@ -14,26 +14,26 @@ from src.messages import messages from src.events import Event @event_listener("transition_day", priority=4.3) -def on_transition_day(evt, cli, var): - pl = list_players() +def on_transition_day(evt, var): + pl = get_players() vs = set(evt.data["victims"]) for v in pl: if v in vs: if v in var.DYING: continue - if v in var.ROLES["blessed villager"]: + if v in get_all_players(("blessed villager",)): evt.data["numkills"][v] -= 1 if evt.data["numkills"][v] >= 0: evt.data["killers"][v].pop(0) if evt.data["numkills"][v] <= 0 and v not in evt.data["protected"]: evt.data["protected"][v] = "blessing" elif evt.data["numkills"][v] <= 0: - var.ACTIVE_PROTECTIONS[v].append("blessing") - elif v in var.ROLES["blessed villager"]: - var.ACTIVE_PROTECTIONS[v].append("blessing") + var.ACTIVE_PROTECTIONS[v.nick].append("blessing") + elif v in get_all_players(("blessed villager",)): + var.ACTIVE_PROTECTIONS[v.nick].append("blessing") @event_listener("transition_day_resolve", priority=2) -def on_transition_day_resolve(evt, cli, var, victim): +def on_transition_day_resolve(evt, var, victim): if evt.data["protected"].get(victim) == "blessing": # don't play any special message for a blessed target, this means in a game with priest and monster it's not really possible # for wolves to tell which is which. May want to change that in the future to be more obvious to wolves since there's not really @@ -58,9 +58,9 @@ def on_desperation(evt, cli, var, votee, target, prot): evt.stop_processing = True @event_listener("retribution_totem") -def on_retribution(evt, cli, var, victim, loser, prot): +def on_retribution(evt, var, victim, target, prot): if prot == "blessing": - var.ACTIVE_PROTECTIONS[target].remove("blessing") + var.ACTIVE_PROTECTIONS[target.nick].remove("blessing") evt.prevent_default = True evt.stop_processing = True diff --git a/src/roles/doomsayer.py b/src/roles/doomsayer.py index 11de485..f1ebd8c 100644 --- a/src/roles/doomsayer.py +++ b/src/roles/doomsayer.py @@ -3,7 +3,7 @@ import random import src.settings as var from src.utilities import * -from src import debuglog, errlog, plog +from src import users, debuglog, errlog, plog from src.functions import get_players, get_all_players from src.decorators import cmd, event_listener from src.messages import messages @@ -128,20 +128,25 @@ def on_get_voters(evt, var): evt.data["voters"].difference_update(SICK.values()) @event_listener("transition_day_begin") -def on_transition_day_begin(evt, cli, var): +def on_transition_day_begin(evt, var): for victim in SICK.values(): - pm(cli, victim, messages["player_sick"]) + user = users._get(victim) + user.queue_message(messages["player_sick"]) + if SICK: + user.send_messages() @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) +def on_transition_day(evt, var): + for k, v in list(KILLS.items()): + killer = users._get(k) # FIXME + victim = users._get(v) # FIXME + evt.data["victims"].append(victim) # even though doomsayer is a wolf, remove from onlybywolves since # that particular item indicates that they were the target of a wolf !kill. # If doomsayer doesn't remove this, roles such as harlot or monster will not # die if they are the target of a doomsayer !see that ends up killing the target. - evt.data["onlybywolves"].discard(d) - evt.data["killers"][d].append(k) + evt.data["onlybywolves"].discard(victim) + evt.data["killers"][victim].append(killer) @event_listener("begin_day") def on_begin_day(evt, var): diff --git a/src/roles/dullahan.py b/src/roles/dullahan.py index f7663d4..0aca578 100644 --- a/src/roles/dullahan.py +++ b/src/roles/dullahan.py @@ -134,12 +134,12 @@ def on_get_special(evt, var): evt.data["special"].update(get_players(("dullahan",))) @event_listener("transition_day", priority=2) -def on_transition_day(evt, cli, var): +def on_transition_day(evt, var): while KILLS: k, d = KILLS.popitem() - evt.data["victims"].append(d.nick) - evt.data["onlybywolves"].discard(d.nick) - evt.data["killers"][d.nick].append(k.nick) + evt.data["victims"].append(d) + evt.data["onlybywolves"].discard(d) + evt.data["killers"][d].append(k) @event_listener("exchange_roles") def on_exchange(evt, cli, var, actor, nick, actor_role, nick_role): diff --git a/src/roles/fallenangel.py b/src/roles/fallenangel.py index 7194a70..6fc1b48 100644 --- a/src/roles/fallenangel.py +++ b/src/roles/fallenangel.py @@ -7,16 +7,17 @@ from collections import defaultdict import botconfig import src.settings as var from src.utilities import * -from src import debuglog, errlog, plog +from src import users, debuglog, errlog, plog from src.decorators import cmd, event_listener +from src.functions import get_players, get_all_players from src.messages import messages from src.events import Event @event_listener("transition_day", priority=4.8) -def on_transition_day(evt, cli, var): +def on_transition_day(evt, var): # now that all protections are finished, add people back to onlybywolves # if they're down to 1 active kill and wolves were a valid killer - victims = set(list_players()) & set(evt.data["victims"]) - var.DYING + victims = set(get_players()) & set(evt.data["victims"]) - var.DYING for v in victims: if evt.data["numkills"][v] == 1 and v in evt.data["bywolves"]: evt.data["onlybywolves"].add(v) @@ -25,17 +26,17 @@ def on_transition_day(evt, cli, var): for p, t in list(evt.data["protected"].items()): if p in evt.data["bywolves"]: if p in evt.data["protected"]: - pm(cli, p, messages["fallen_angel_deprotect"]) + p.send(messages["fallen_angel_deprotect"]) # let other roles do special things when we bypass their guards - killer = random.choice(list(var.ROLES["fallen angel"])) + killer = random.choice(list(get_all_players(("fallen angel",)))) fevt = Event("fallen_angel_guard_break", evt.data) - fevt.dispatch(cli, var, p, killer) + fevt.dispatch(var, p, killer) if p in evt.data["protected"]: del evt.data["protected"][p] if p in var.ACTIVE_PROTECTIONS: - del var.ACTIVE_PROTECTIONS[p] + del var.ACTIVE_PROTECTIONS[p.nick] # mark kill as performed by a random FA # this is important as there may otherwise be no killers if every kill was blocked evt.data["killers"][p].append(killer) diff --git a/src/roles/harlot.py b/src/roles/harlot.py index e5516f1..2ec61d9 100644 --- a/src/roles/harlot.py +++ b/src/roles/harlot.py @@ -8,7 +8,7 @@ import botconfig import src.settings as var from src.utilities import * from src import channels, users, debuglog, errlog, plog -from src.functions import get_players, get_all_players +from src.functions import get_players, get_all_players, get_main_role from src.decorators import cmd, event_listener from src.messages import messages from src.events import Event @@ -59,16 +59,18 @@ def pass_cmd(cli, nick, chan, rest): chk_nightdone(cli) @event_listener("bite") -def on_bite(evt, cli, var, alpha, target): - if target not in var.ROLES["harlot"]: +def on_bite(evt, var, alpha, target): + if target.nick not in var.ROLES["harlot"] or target.nick not in VISITED: return - hvisit = VISITED.get(target) - if hvisit and get_role(hvisit) not in var.WOLFCHAT_ROLES and (hvisit not in evt.param.bywolves or hvisit in evt.param.protected): - evt.data["can_bite"] = False + hvisit = VISITED[target.nick] + if hvisit is not None: + visited = users._get(hvisit) # FIXME + if get_main_role(visited) not in var.WOLFCHAT_ROLES and (visited not in evt.params.bywolves or visited in evt.params.protected): + evt.data["can_bite"] = False @event_listener("transition_day_resolve", priority=1) -def on_transition_day_resolve(evt, cli, var, victim): - if victim in var.ROLES["harlot"] and VISITED.get(victim) and victim not in evt.data["dead"] and victim in evt.data["onlybywolves"]: +def on_transition_day_resolve(evt, var, victim): + if victim.nick in var.ROLES["harlot"] and VISITED.get(victim.nick) and victim not in evt.data["dead"] and victim in evt.data["onlybywolves"]: if victim not in evt.data["bitten"]: evt.data["message"].append(messages["target_not_home"]) evt.data["novictmsg"] = False @@ -76,23 +78,24 @@ def on_transition_day_resolve(evt, cli, var, victim): evt.prevent_default = True @event_listener("transition_day_resolve_end", priority=1) -def on_transition_day_resolve_end(evt, cli, var, victims): +def on_transition_day_resolve_end(evt, var, victims): for victim in victims + evt.data["bitten"]: - if victim in evt.data["dead"] and victim in VISITED.values() and (victim in evt.data["bywolves"] or victim in evt.data["bitten"]): + if victim in evt.data["dead"] and victim.nick in VISITED.values() and (victim in evt.data["bywolves"] or victim in evt.data["bitten"]): for hlt in VISITED: - if VISITED[hlt] == victim and hlt not in evt.data["bitten"] and hlt not in evt.data["dead"]: + user = users._get(hlt) # FIXME + if VISITED[hlt] == victim.nick and user not in evt.data["bitten"] and user not in evt.data["dead"]: if var.ROLE_REVEAL in ("on", "team"): evt.data["message"].append(messages["visited_victim"].format(hlt, get_reveal_role(hlt))) else: evt.data["message"].append(messages["visited_victim_noreveal"].format(hlt)) - evt.data["bywolves"].add(hlt) - evt.data["onlybywolves"].add(hlt) - evt.data["dead"].append(hlt) + evt.data["bywolves"].add(user) + evt.data["onlybywolves"].add(user) + evt.data["dead"].append(user) @event_listener("transition_day_resolve_end", priority=3) -def on_transition_day_resolve_end3(evt, cli, var, victims): - for harlot in var.ROLES["harlot"]: - if VISITED.get(harlot) in list_players(var.WOLF_ROLES) and harlot not in evt.data["dead"] and harlot not in evt.data["bitten"]: +def on_transition_day_resolve_end3(evt, var, victims): + for harlot in get_all_players(("harlot",)): + if VISITED.get(harlot.nick) in list_players(var.WOLF_ROLES) and harlot not in evt.data["dead"] and harlot not in evt.data["bitten"]: evt.data["message"].append(messages["harlot_visited_wolf"].format(harlot)) evt.data["bywolves"].add(harlot) evt.data["onlybywolves"].add(harlot) diff --git a/src/roles/hunter.py b/src/roles/hunter.py index 8e73b89..78cf22f 100644 --- a/src/roles/hunter.py +++ b/src/roles/hunter.py @@ -104,11 +104,11 @@ def on_get_special(evt, var): evt.data["special"].update(get_players(("hunter",))) @event_listener("transition_day", priority=2) -def on_transition_day(evt, cli, var): +def on_transition_day(evt, var): for k, d in list(KILLS.items()): - evt.data["victims"].append(d.nick) - evt.data["onlybywolves"].discard(d.nick) - evt.data["killers"][d.nick].append(k.nick) + evt.data["victims"].append(d) + evt.data["onlybywolves"].discard(d) + evt.data["killers"][d].append(k) # important, otherwise our del_player listener lets hunter kill again del KILLS[k] diff --git a/src/roles/shaman.py b/src/roles/shaman.py index 4dc8f00..3358f13 100644 --- a/src/roles/shaman.py +++ b/src/roles/shaman.py @@ -6,7 +6,7 @@ from collections import defaultdict, deque import botconfig import src.settings as var from src.utilities import * -from src import debuglog, errlog, plog, users +from src import debuglog, errlog, plog, users, channels from src.functions import get_players, get_main_role from src.decorators import cmd, event_listener from src.messages import messages @@ -305,27 +305,29 @@ def on_player_win(evt, var, user, rol, winner, survived): evt.data["iwon"] = True @event_listener("transition_day_begin", priority=4) -def on_transition_day_begin(evt, cli, var): +def on_transition_day_begin(evt, var): # Select random totem recipients if shamans didn't act - pl = list_players() - for shaman in list_players(var.TOTEM_ORDER): - if shaman not in SHAMANS and shaman not in var.SILENCED: + pl = get_players() + for shaman in get_players(var.TOTEM_ORDER): + if shaman.nick not in SHAMANS and shaman.nick not in var.SILENCED: ps = pl[:] - if LASTGIVEN.get(shaman) in ps: - ps.remove(LASTGIVEN.get(shaman)) + if shaman.nick in LASTGIVEN: + user = users._get(LASTGIVEN[shaman.nick]) # FIXME + if user in ps: + ps.remove(user) levt = Event("get_random_totem_targets", {"targets": ps}) - levt.dispatch(cli, var, shaman) + levt.dispatch(var, shaman) ps = levt.data["targets"] if ps: target = random.choice(ps) - totem.func(cli, shaman, shaman, target, messages["random_totem_prefix"]) # XXX: Old API + totem.func(target.client, shaman.nick, shaman.nick, target.nick, messages["random_totem_prefix"]) # XXX: Old API else: - LASTGIVEN[shaman] = None + LASTGIVEN[shaman.nick] = None elif shaman not in SHAMANS: - LASTGIVEN[shaman] = None + LASTGIVEN[shaman.nick] = None @event_listener("transition_day_begin", priority=6) -def on_transition_day_begin2(evt, cli, var): +def on_transition_day_begin2(evt, var): # Reset totem variables DEATH.clear() PROTECTION.clear() @@ -382,7 +384,8 @@ def on_transition_day_begin2(evt, cli, var): # other totem types possibly handled in an earlier event, # as such there is no else: clause here if target != victim: - pm(cli, shaman, messages["totem_retarget"].format(victim)) + user = users._get(shaman) # FIXME + user.send(messages["totem_retarget"].format(victim)) LASTGIVEN[shaman] = victim # In transition_day_end we report who was given totems based on havetotem. @@ -393,21 +396,23 @@ def on_transition_day_begin2(evt, cli, var): havetotem.extend(sorted(filter(None, LASTGIVEN.values()))) @event_listener("transition_day", priority=2) -def on_transition_day2(evt, cli, var): +def on_transition_day2(evt, var): for k, d in DEATH.items(): - evt.data["victims"].append(d) - evt.data["onlybywolves"].discard(d) - evt.data["killers"][d].append(k) + shaman = users._get(k) # FIXME + target = users._get(d) # FIXME + evt.data["victims"].append(target) + evt.data["onlybywolves"].discard(target) + evt.data["killers"][target].append(shaman) @event_listener("transition_day", priority=4.1) -def on_transition_day3(evt, cli, var): +def on_transition_day3(evt, var): # protection totems are applied first in default logic, however # we set priority=4.1 to allow other modes of protection # to pre-empt us if desired - pl = list_players() + pl = get_players() vs = set(evt.data["victims"]) for v in pl: - numtotems = PROTECTION.count(v) + numtotems = PROTECTION.count(v.nick) if v in vs: if v in var.DYING: continue @@ -419,22 +424,22 @@ def on_transition_day3(evt, cli, var): if numkills <= 0 and v not in evt.data["protected"]: evt.data["protected"][v] = "totem" elif numkills <= 0: - var.ACTIVE_PROTECTIONS[v].append("totem") + var.ACTIVE_PROTECTIONS[v.nick].append("totem") evt.data["numkills"][v] = numkills else: for i in range(0, numtotems): - var.ACTIVE_PROTECTIONS[v].append("totem") + var.ACTIVE_PROTECTIONS[v.nick].append("totem") @event_listener("fallen_angel_guard_break") -def on_fagb(evt, cli, var, victim, killer): +def on_fagb(evt, var, victim, killer): # we'll never end up killing a shaman who gave out protection, but delete the totem since # story-wise it gets demolished at night by the FA - while victim in havetotem: - havetotem.remove(victim) - brokentotem.add(victim) + while victim.nick in havetotem: + havetotem.remove(victim.nick) + brokentotem.add(victim.nick) @event_listener("transition_day_resolve", priority=2) -def on_transition_day_resolve2(evt, cli, var, victim): +def on_transition_day_resolve2(evt, var, victim): if evt.data["protected"].get(victim) == "totem": evt.data["message"].append(messages["totem_protection"].format(victim)) evt.data["novictmsg"] = False @@ -442,54 +447,54 @@ def on_transition_day_resolve2(evt, cli, var, victim): evt.prevent_default = True @event_listener("transition_day_resolve", priority=6) -def on_transition_day_resolve6(evt, cli, var, victim): +def on_transition_day_resolve6(evt, var, victim): # TODO: remove these checks once everything is split # right now they're needed because otherwise retribution may fire off when the target isn't actually dying # that will not be an issue once everything is using the event if evt.data["protected"].get(victim): return - if victim in var.ROLES["lycan"] and victim in evt.data["onlybywolves"] and victim not in var.IMMUNIZED: + if victim.nick in var.ROLES["lycan"] and victim in evt.data["onlybywolves"] and victim.nick not in var.IMMUNIZED: return # END checks to remove - if victim in RETRIBUTION: + if victim.nick in RETRIBUTION: killers = list(evt.data["killers"].get(victim, [])) loser = None while killers: loser = random.choice(killers) - if loser in evt.data["dead"] or victim == loser: + if loser in evt.data["dead"] or victim is loser: killers.remove(loser) continue break - if loser in evt.data["dead"] or victim == loser: + if loser in evt.data["dead"] or victim is loser: loser = None ret_evt = Event("retribution_kill", {"target": loser, "message": []}) - ret_evt.dispatch(cli, var, victim, loser) + ret_evt.dispatch(var, victim, loser) loser = ret_evt.data["target"] evt.data["message"].extend(ret_evt.data["message"]) - if loser in evt.data["dead"] or victim == loser: + if loser in evt.data["dead"] or victim is loser: loser = None if loser is not None: - prots = deque(var.ACTIVE_PROTECTIONS[loser]) + prots = deque(var.ACTIVE_PROTECTIONS[loser.nick]) while len(prots) > 0: # an event can read the current active protection and cancel the totem # if it cancels, it is responsible for removing the protection from var.ACTIVE_PROTECTIONS # so that it cannot be used again (if the protection is meant to be usable once-only) ret_evt = Event("retribution_totem", {"message": []}) - if not ret_evt.dispatch(cli, var, victim, loser, prots[0]): + if not ret_evt.dispatch(var, victim, loser, prots[0]): evt.data["message"].extend(ret_evt.data["message"]) return prots.popleft() evt.data["dead"].append(loser) if var.ROLE_REVEAL in ("on", "team"): - role = get_reveal_role(loser) + role = get_reveal_role(loser.nick) an = "n" if role.startswith(("a", "e", "i", "o", "u")) else "" evt.data["message"].append(messages["totem_death"].format(victim, loser, an, role)) else: evt.data["message"].append(messages["totem_death_no_reveal"].format(victim, loser)) @event_listener("transition_day_end", priority=1) -def on_transition_day_end(evt, cli, var): +def on_transition_day_end(evt, var): message = [] for player, tlist in itertools.groupby(havetotem): ntotems = len(list(tlist)) @@ -497,7 +502,7 @@ def on_transition_day_end(evt, cli, var): player, "ed" if player not in list_players() else "s", "a" if ntotems == 1 else "\u0002{0}\u0002".format(ntotems), "s" if ntotems > 1 else "")) for player in brokentotem: message.append(messages["totem_broken"].format(player)) - cli.msg(botconfig.CHANNEL, "\n".join(message)) + channels.Main.send("\n".join(message)) @event_listener("transition_night_end", priority=2.01) def on_transition_night_end(evt, var): @@ -513,7 +518,7 @@ def on_transition_night_end(evt, var): for shaman in get_players(var.TOTEM_ORDER): pl = ps[:] random.shuffle(pl) - if shaman.nick in LASTGIVEN: + if LASTGIVEN.get(shaman.nick): user = users._get(LASTGIVEN[shaman.nick]) # FIXME if user in pl: pl.remove(user) diff --git a/src/roles/succubus.py b/src/roles/succubus.py index 70c3c1d..327a7ec 100644 --- a/src/roles/succubus.py +++ b/src/roles/succubus.py @@ -90,9 +90,9 @@ def on_harlot_visit(evt, cli, var, nick, victim): ENTRANCED.add(nick) @event_listener("get_random_totem_targets") -def on_get_random_totem_targets(evt, cli, var, shaman): - if shaman in ENTRANCED: - for succubus in var.ROLES["succubus"]: +def on_get_random_totem_targets(evt, var, shaman): + if shaman.nick in ENTRANCED: + for succubus in get_all_players(("succubus",)): if succubus in evt.data["targets"]: evt.data["targets"].remove(succubus) @@ -221,8 +221,8 @@ def on_del_player(evt, var, user, mainrole, allroles, death_triggers): ENTRANCED_DYING.clear() @event_listener("transition_day_resolve", priority=1) -def on_transition_day_resolve(evt, cli, var, victim): - if victim in var.ROLES["succubus"] and VISITED.get(victim) and victim not in evt.data["dead"] and victim in evt.data["onlybywolves"]: +def on_transition_day_resolve(evt, var, victim): + if victim.nick in var.ROLES["succubus"] and VISITED.get(victim.nick) and victim not in evt.data["dead"] and victim in evt.data["onlybywolves"]: # TODO: check if this is necessary for succubus, it's to prevent a message playing if alpha bites # a harlot that is visiting a wolf, since the bite succeeds in that case. if victim not in evt.data["bitten"]: @@ -232,18 +232,19 @@ def on_transition_day_resolve(evt, cli, var, victim): evt.prevent_default = True @event_listener("transition_day_resolve_end", priority=1) -def on_transition_day_resolve_end(evt, cli, var, victims): +def on_transition_day_resolve_end(evt, var, victims): for victim in victims + evt.data["bitten"]: - if victim in evt.data["dead"] and victim in VISITED.values() and (victim in evt.data["bywolves"] or victim in evt.data["bitten"]): + if victim in evt.data["dead"] and victim.nick in VISITED.values() and (victim in evt.data["bywolves"] or victim in evt.data["bitten"]): for succ in VISITED: - if VISITED[succ] == victim and succ not in evt.data["bitten"] and succ not in evt.data["dead"]: + user = users._get(succ) # FIXME + if VISITED[succ] == victim.nick and user not in evt.data["bitten"] and user not in evt.data["dead"]: if var.ROLE_REVEAL in ("on", "team"): evt.data["message"].append(messages["visited_victim"].format(succ, get_reveal_role(succ))) else: evt.data["message"].append(messages["visited_victim_noreveal"].format(succ)) - evt.data["bywolves"].add(succ) - evt.data["onlybywolves"].add(succ) - evt.data["dead"].append(succ) + evt.data["bywolves"].add(user) + evt.data["onlybywolves"].add(user) + evt.data["dead"].append(user) @event_listener("night_acted") def on_night_acted(evt, var, user, actor): @@ -290,11 +291,12 @@ def on_begin_day(evt, var): ENTRANCED_DYING.clear() @event_listener("transition_day", priority=2) -def on_transition_day(evt, cli, var): +def on_transition_day(evt, var): for v in ENTRANCED_DYING: - var.DYING.add(v) # indicate that the death bypasses protections - evt.data["victims"].append(v) - evt.data["onlybywolves"].discard(v) + user = users._get(v) # FIXME + var.DYING.add(user) # indicate that the death bypasses protections + evt.data["victims"].append(user) + evt.data["onlybywolves"].discard(user) # we do not add to killers as retribution totem should not work on entranced not following succubus @event_listener("get_special") diff --git a/src/roles/vengefulghost.py b/src/roles/vengefulghost.py index a289c40..f9838a0 100644 --- a/src/roles/vengefulghost.py +++ b/src/roles/vengefulghost.py @@ -5,12 +5,12 @@ from collections import defaultdict import src.settings as var from src.utilities import * from src import channels, users, debuglog, errlog, plog -from src.functions import get_players +from src.functions import get_players, get_target, get_main_role from src.decorators import command, event_listener from src.messages import messages from src.events import Event -KILLS = {} # type: Dict[str, str] +KILLS = {} # type: Dict[users.User, users.User] GHOSTS = {} # type: Dict[users.User, str] # temporary holding variable, only non-empty during transition_day @@ -22,34 +22,34 @@ def vg_kill(var, wrapper, message): if GHOSTS[wrapper.source][0] == "!": return - victim = get_victim(wrapper.source.client, wrapper.source.nick, re.split(" +", message)[0], False) - if not victim: + target = get_target(var, wrapper, re.split(" +", message)[0]) + if not target: return - if victim == wrapper.source.nick: + if target is wrapper.source: wrapper.pm(messages["player_dead"]) return - wolves = list_players(var.WOLFTEAM_ROLES) - if GHOSTS[wrapper.source] == "wolves" and victim not in wolves: + wolves = get_players(var.WOLFTEAM_ROLES) + if GHOSTS[wrapper.source] == "wolves" and target not in wolves: wrapper.pm(messages["vengeful_ghost_wolf"]) return - elif GHOSTS[wrapper.source] == "villagers" and victim in wolves: + elif GHOSTS[wrapper.source] == "villagers" and target in wolves: wrapper.pm(messages["vengeful_ghost_villager"]) return - orig = victim - evt = Event("targeted_command", {"target": victim, "misdirection": True, "exchange": False}) - evt.dispatch(wrapper.source.client, var, "kill", wrapper.source.nick, victim, frozenset({"detrimental"})) + orig = target + evt = Event("targeted_command", {"target": target.nick, "misdirection": True, "exchange": False}) + evt.dispatch(wrapper.source.client, var, "kill", wrapper.source.nick, target.nick, frozenset({"detrimental"})) if evt.prevent_default: return - victim = evt.data["target"] + target = users._get(evt.data["target"]) # FIXME - KILLS[wrapper.source.nick] = victim + KILLS[wrapper.source] = target wrapper.pm(messages["player_kill"].format(orig)) - debuglog("{0} (vengeful ghost) KILL: {1} ({2})".format(wrapper.source.nick, victim, get_role(victim))) + debuglog("{0} (vengeful ghost) KILL: {1} ({2})".format(wrapper.source.nick, target, get_main_role(target))) chk_nightdone(wrapper.source.client) @command("retract", "r", chan=False, pm=True, playing=False, phases=("night",)) @@ -57,8 +57,8 @@ def vg_retract(var, wrapper, message): """Removes a vengeful ghost's kill selection.""" if wrapper.source not in GHOSTS: return - if wrapper.source.nick in KILLS: - del KILLS[wrapper.source.nick] + if wrapper.source in KILLS: + del KILLS[wrapper.source] wrapper.pm(messages["retracted_kill"]) @event_listener("get_participants") @@ -90,9 +90,9 @@ def on_player_win(evt, var, user, role, winner, survived): @event_listener("del_player", priority=6) def on_del_player(evt, var, user, nickrole, nicktpls, death_triggers): - for h,v in list(KILLS.items()): - if v == user.nick: - pm(user.client, h, messages["hunter_discard"]) + for h, v in list(KILLS.items()): + if user is v: + h.send(messages["hunter_discard"]) del KILLS[h] # extending VG to work with new teams can be done by registering a listener # at priority < 6, importing src.roles.vengefulghost, and setting @@ -105,28 +105,15 @@ def on_del_player(evt, var, user, nickrole, nicktpls, death_triggers): user.send(messages["vengeful_turn"].format(GHOSTS[user])) debuglog(user.nick, "(vengeful ghost) TRIGGER", GHOSTS[user]) -@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] - @event_listener("transition_day_begin", priority=6) -def on_transition_day_begin(evt, cli, var): +def on_transition_day_begin(evt, var): # select a random target for VG if they didn't kill - wolves = set(list_players(var.WOLFTEAM_ROLES)) - villagers = set(list_players()) - wolves + wolves = set(get_players(var.WOLFTEAM_ROLES)) + villagers = set(get_players()) - wolves for ghost, target in GHOSTS.items(): if target[0] == "!" or ghost.nick in var.SILENCED: continue - if ghost.nick not in KILLS: + if ghost not in KILLS: choice = set() if target == "wolves": choice = wolves.copy() @@ -136,39 +123,38 @@ def on_transition_day_begin(evt, cli, var): evt.dispatch(var, ghost, target) choice = evt.data["pl"] if choice: - KILLS[ghost.nick] = random.choice(list(choice)) + KILLS[ghost] = random.choice(list(choice)) @event_listener("transition_day", priority=2) -def on_transition_day(evt, cli, var): +def on_transition_day(evt, var): for k, d in KILLS.items(): evt.data["victims"].append(d) evt.data["onlybywolves"].discard(d) evt.data["killers"][d].append(k) @event_listener("transition_day", priority=3.01) -def on_transition_day3(evt, cli, var): +def on_transition_day3(evt, var): for k, d in list(KILLS.items()): - if GHOSTS[users._get(k)] == "villagers": + if GHOSTS[k] == "villagers": evt.data["killers"][d].remove(k) evt.data["killers"][d].insert(0, k) @event_listener("transition_day", priority=6.01) -def on_transition_day6(evt, cli, var): +def on_transition_day6(evt, var): for k, d in list(KILLS.items()): - if GHOSTS[users._get(k)] == "villagers" and k in evt.data["killers"][d]: + if GHOSTS[k] == "villagers" and k in evt.data["killers"][d]: evt.data["killers"][d].remove(k) evt.data["killers"][d].insert(0, k) # important, otherwise our del_player listener messages the vg del KILLS[k] -@event_listener("retribution_kill", priority=6) # FIXME: This function, and all of the event -def on_retribution_kill(evt, cli, var, victim, orig_target): - t = evt.data["target"] - user = users._get(t) - if user in GHOSTS: - drivenoff[user] = GHOSTS[user] - GHOSTS[user] = "!" + GHOSTS[user] - evt.data["message"].append(messages["totem_banish"].format(victim, t)) +@event_listener("retribution_kill", priority=6) +def on_retribution_kill(evt, var, victim, orig_target): + target = evt.data["target"] + if target in GHOSTS: + drivenoff[target] = GHOSTS[target] + GHOSTS[target] = "!" + GHOSTS[target] + evt.data["message"].append(messages["totem_banish"].format(victim, target)) evt.data["target"] = None @event_listener("get_participant_role") diff --git a/src/roles/vigilante.py b/src/roles/vigilante.py index 7270d5a..3f4b3a3 100644 --- a/src/roles/vigilante.py +++ b/src/roles/vigilante.py @@ -4,8 +4,8 @@ from collections import defaultdict import src.settings as var from src.utilities import * -from src import debuglog, errlog, plog -from src.functions import get_players, get_all_players +from src import users, debuglog, errlog, plog +from src.functions import get_players, get_all_players, get_main_role from src.decorators import cmd, event_listener from src.messages import messages from src.events import Event @@ -97,16 +97,18 @@ def on_get_special(evt, var): evt.data["special"].update(get_players(("vigilante",))) @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].append(k) +def on_transition_day(evt, var): + for k, v in list(KILLS.items()): + killer = users._get(k) # FIXME + victim = users._get(v) # FIXME + evt.data["victims"].append(victim) + evt.data["onlybywolves"].discard(victim) + evt.data["killers"][victim].append(killer) # 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) + if get_main_role(victim) not in var.WOLF_ROLES | var.WIN_STEALER_ROLES: + var.DYING.add(killer) @event_listener("exchange_roles") def on_exchange(evt, cli, var, actor, nick, actor_role, nick_role): diff --git a/src/roles/wildchild.py b/src/roles/wildchild.py index 365156b..551d2fb 100644 --- a/src/roles/wildchild.py +++ b/src/roles/wildchild.py @@ -130,16 +130,16 @@ def on_chk_nightdone(evt, var): evt.data["nightroles"].extend(get_all_players(("wild child",))) @event_listener("transition_day_begin") -def on_transition_day_begin(evt, cli, var): +def on_transition_day_begin(evt, var): if (not var.START_WITH_DAY or not var.FIRST_DAY) and var.FIRST_NIGHT: - for child in var.ROLES["wild child"]: - if child not in IDOLS: - pl = list_players() + for child in get_all_players(("wild child",)): + if child.nick not in IDOLS: + pl = get_players() pl.remove(child) if pl: target = random.choice(pl) - IDOLS[child] = target - pm(cli, child, messages["wild_child_random_idol"].format(target)) + IDOLS[child.nick] = target.nick + child.send(messages["wild_child_random_idol"].format(target)) @event_listener("transition_night_end", priority=2) def on_transition_night_end(evt, var): diff --git a/src/roles/wolf.py b/src/roles/wolf.py index 0d4b5e0..d2afc1e 100644 --- a/src/roles/wolf.py +++ b/src/roles/wolf.py @@ -4,7 +4,7 @@ from collections import defaultdict import src.settings as var from src.utilities import * -from src.functions import get_players, get_main_role, get_all_roles +from src.functions import get_players, get_all_players, get_main_role, get_all_roles from src import debuglog, errlog, plog, users from src.decorators import cmd, event_listener from src.messages import messages @@ -148,7 +148,7 @@ def on_get_special(evt, var): evt.data["special"].update(get_players(CAN_KILL)) @event_listener("transition_day", priority=1) -def on_transition_day(evt, cli, var): +def on_transition_day(evt, var): # figure out wolf target found = defaultdict(int) nevt = Event("wolf_numkills", {"numkills": 1}) @@ -173,31 +173,32 @@ def on_transition_day(evt, cli, var): dups.append(v) if maxc and dups: victim = random.choice(dups) - evt.data["victims"].append(victim) - evt.data["bywolves"].add(victim) - evt.data["onlybywolves"].add(victim) + user = users._get(victim) # FIXME + evt.data["victims"].append(user) + evt.data["bywolves"].add(user) + evt.data["onlybywolves"].add(user) # special key to let us know to randomly select a wolf in case of retribution totem - evt.data["killers"][victim].append("@wolves") + evt.data["killers"][user].append("@wolves") del found[victim] # this should be moved to an event in kill, where monster prefixes their nick with ! # and fallen angel subsequently removes the ! prefix # TODO: when monster is split off if len(var.ROLES["fallen angel"]) == 0: - for monster in var.ROLES["monster"]: + for monster in get_all_players(("monster",)): if monster in evt.data["victims"]: evt.data["victims"].remove(monster) evt.data["bywolves"].discard(monster) evt.data["onlybywolves"].discard(monster) @event_listener("transition_day", priority=3) -def on_transition_day3(evt, cli, var): +def on_transition_day3(evt, var): evt.data["numkills"] = {v: evt.data["victims"].count(v) for v in set(evt.data["victims"])} - on_transition_day6(evt, cli, var) + on_transition_day6(evt, var) @event_listener("transition_day", priority=6) -def on_transition_day6(evt, cli, var): - wolfteam = list_players(var.WOLFTEAM_ROLES) +def on_transition_day6(evt, var): + wolfteam = get_players(var.WOLFTEAM_ROLES) for victim, killers in list(evt.data["killers"].items()): k2 = [] kappend = [] @@ -215,10 +216,9 @@ def on_transition_day6(evt, cli, var): evt.data["killers"][victim] = k2 @event_listener("retribution_kill") -def on_retribution_kill(evt, cli, var, victim, orig_target): - t = evt.data["target"] - if t == "@wolves": - wolves = list_players(var.WOLF_ROLES) +def on_retribution_kill(evt, var, victim, orig_target): + if evt.data["target"] == "@wolves": + wolves = get_players(var.WOLF_ROLES) evt.data["target"] = random.choice(wolves) @event_listener("exchange_roles", priority=2) diff --git a/src/roles/wolfcub.py b/src/roles/wolfcub.py index ceaa628..232b94f 100644 --- a/src/roles/wolfcub.py +++ b/src/roles/wolfcub.py @@ -90,7 +90,7 @@ def on_reconfigure_stats(evt, cli, var, stats): stats["wolf cub"] = 0 @event_listener("transition_day_resolve_end") -def on_begin_day(evt, cli, var, victims): +def on_begin_day(evt, var, victims): global ANGRY_WOLVES ANGRY_WOLVES = False diff --git a/src/wolfgame.py b/src/wolfgame.py index 6e427b9..f6c550a 100644 --- a/src/wolfgame.py +++ b/src/wolfgame.py @@ -3044,7 +3044,7 @@ def rename_player(var, user, prefix): var.JESTERS, var.AMNESIACS, var.LYCANTHROPES, var.LUCKY, var.DISEASED, var.MISDIRECTED, var.EXCHANGED, var.IMMUNIZED, var.CURED_LYCANS, var.ALPHA_WOLVES, var.CURSED, var.CHARMERS, var.CHARMED, var.TOBECHARMED, - var.PRIESTS, var.CONSECRATING, var.DYING): + var.PRIESTS, var.CONSECRATING): if prefix in setvar: setvar.remove(prefix) setvar.add(nick) @@ -3366,9 +3366,9 @@ def transition_day(cli, gameid=0): chan = botconfig.CHANNEL event_begin = Event("transition_day_begin", {}) - event_begin.dispatch(cli, var) + event_begin.dispatch(var) - pl = list_players() + pl = get_players() if not var.START_WITH_DAY or not var.FIRST_DAY: if len(var.HEXED) < len(var.ROLES["hag"]): @@ -3381,20 +3381,20 @@ def transition_day(cli, gameid=0): if var.FIRST_NIGHT: # Select a random target for clone if they didn't choose someone - for clone in var.ROLES["clone"]: - if clone not in var.CLONED: + for clone in get_all_players(("clone",)): + if clone.nick not in var.CLONED: ps = pl[:] ps.remove(clone) if len(ps) > 0: target = random.choice(ps) - var.CLONED[clone] = target - pm(cli, clone, messages["random_clone"].format(target)) + var.CLONED[clone.nick] = target.nick + clone.send(messages["random_clone"].format(target)) - for mm in var.ROLES["matchmaker"]: - if mm not in var.MATCHMAKERS: + for mm in get_all_players(("matchmaker",)): + if mm.nick not in var.MATCHMAKERS: lovers = random.sample(pl, 2) - choose.func(cli, mm, mm, lovers[0] + " " + lovers[1], sendmsg=False) # XXX: Old API - pm(cli, mm, messages["random_matchmaker"]) + choose.func(mm.client, mm.nick, mm.nick, "{0[0]} {0[1]}".format(lovers), sendmsg=False) # XXX: Old API + mm.send(messages["random_matchmaker"]) # Reset daytime variables var.INVESTIGATED = set() @@ -3445,9 +3445,9 @@ def transition_day(cli, gameid=0): if ((target in var.HVISITED and var.HVISITED[target]) or (target in var.PRAYED and var.PRAYED[target][0] > 0) or target in var.CHARMERS or target in var.OBSERVED or target in var.HEXED or target in var.CURSED or evt.data["acted"]): - pm(cli, crow, messages["werecrow_success"].format(target)) + actor.send(messages["werecrow_success"].format(user)) else: - pm(cli, crow, messages["werecrow_failure"].format(target)) + actor.send(messages["werecrow_failure"].format(user)) if var.START_WITH_DAY and var.FIRST_DAY: # TODO: need to message everyone their roles and give a short thing saying "it's daytime" @@ -3482,7 +3482,7 @@ def transition_day(cli, gameid=0): "bitten": [], "numkills": {} # populated at priority 3 }) - evt.dispatch(cli, var) + evt.dispatch(var) victims = evt.data["victims"] killers = evt.data["killers"] bywolves = evt.data["bywolves"] @@ -3503,6 +3503,8 @@ def transition_day(cli, gameid=0): new_wolf = False if var.ALPHA_ENABLED: # check for bites for (alpha, target) in var.BITE_PREFERENCES.items(): + actor = users._get(alpha) # FIXME + user = users._get(target) # FIXME # bite is now separate but some people may try to double up still, if bitten person is # also being killed by wolves, make the kill not apply # note that we cannot bite visiting harlots unless they are visiting a wolf, @@ -3519,48 +3521,48 @@ def transition_day(cli, gameid=0): protected=protected, bitten=bitten, numkills=numkills) - bite_evt.dispatch(cli, var, alpha, target) + bite_evt.dispatch(var, actor, user) if bite_evt.data["can_bite"] and not bite_evt.data["kill"]: # mark them as bitten got_bit = True # if they were also being killed by wolves, undo that - if target in bywolves: - victims.remove(target) - bywolves.discard(target) - onlybywolves.discard(target) - killers[target].remove("@wolves") - if target not in victims: - victims_set.discard(target) + if user in bywolves: + victims.remove(user) + bywolves.discard(user) + onlybywolves.discard(user) + killers[user].remove("@wolves") + if user not in victims: + victims_set.discard(user) - if target in victims_set: + if user in victims_set: # bite was unsuccessful due to someone else killing them - var.ALPHA_WOLVES.remove(alpha) + var.ALPHA_WOLVES.remove(actor.nick) elif bite_evt.data["kill"]: # target immunized or a lycan, kill them instead and refund the bite - var.ALPHA_WOLVES.remove(alpha) - if var.ACTIVE_PROTECTIONS[target]: + var.ALPHA_WOLVES.remove(actor.nick) + if var.ACTIVE_PROTECTIONS[user.nick]: # target was protected - protected[target] = var.ACTIVE_PROTECTIONS[target].pop(0) - elif target in protected: - del protected[target] + protected[user] = var.ACTIVE_PROTECTIONS[user.nick].pop(0) + elif user in protected: + del protected[user] # add them as a kill even if protected so that protection message plays - if target not in victims: - onlybywolves.add(target) - killers[target].append(alpha) - victims.append(target) - victims_set.add(target) - bywolves.add(target) + if user not in victims: + onlybywolves.add(user) + killers[user].append(actor) + victims.append(user) + victims_set.add(user) + bywolves.add(user) elif got_bit: new_wolf = True - bitten.append(target) + bitten.append(user) else: # bite failed due to some other reason (namely harlot) - var.ALPHA_WOLVES.remove(alpha) + var.ALPHA_WOLVES.remove(actor.nick) - if alpha in var.ALPHA_WOLVES: - pm(cli, alpha, messages["alpha_bite_success"].format(target)) - else: - pm(cli, alpha, messages["alpha_bite_failure"].format(target)) + to_send = "alpha_bite_failure" + if actor.nick in var.ALPHA_WOLVES: + to_send = "alpha_bite_success" + actor.send(messages[to_send].format(user)) var.BITE_PREFERENCES = {} @@ -3576,9 +3578,9 @@ def transition_day(cli, gameid=0): for v in victims_set: if v in var.DYING: victims.append(v) - elif v in var.ROLES["bodyguard"] and angel.GUARDED.get(v) in victims_set: + elif v.nick in var.ROLES["bodyguard"] and v.nick in angel.GUARDED and users._get(angel.GUARDED[v.nick]) in victims_set: # FIXME vappend.append(v) - elif v in var.ROLES["harlot"] and harlot.VISITED.get(v) in victims_set: + elif v.nick in var.ROLES["harlot"] and v.nick in harlot.VISITED and users._get(harlot.VISITED[v.nick]) in victims_set: # FIXME vappend.append(v) else: victims.append(v) @@ -3592,18 +3594,18 @@ def transition_day(cli, gameid=0): continue prevlen = len(vappend) - for v in copy.copy(vappend): - if v in var.ROLES["bodyguard"] and angel.GUARDED.get(v) not in vappend: + for v in vappend[:]: + if v.nick in var.ROLES["bodyguard"] and users._get(angel.GUARDED.get(v.nick)) not in vappend: # FIXME vappend.remove(v) victims.append(v) - elif v in var.ROLES["harlot"] and harlot.VISITED.get(v) not in vappend: + elif v.nick in var.ROLES["harlot"] and users._get(harlot.VISITED.get(v.nick)) not in vappend: # FIXME vappend.remove(v) victims.append(v) # Select a random target for assassin that isn't already going to die if they didn't target - pl = list_players() - for ass in var.ROLES["assassin"]: - if ass not in var.TARGETED and ass not in var.SILENCED: + pl = get_players() + for ass in get_all_players(("assassin",)): + if ass.nick not in var.TARGETED and ass.nick not in var.SILENCED: ps = pl[:] ps.remove(ass) for victim in victims: @@ -3611,8 +3613,8 @@ def transition_day(cli, gameid=0): ps.remove(victim) if len(ps) > 0: target = random.choice(ps) - var.TARGETED[ass] = target - pm(cli, ass, messages["assassin_random"].format(target)) + var.TARGETED[ass.nick] = target.nick + ass.send(messages["assassin_random"].format(target)) message = [messages["sunrise"].format(min, sec)] @@ -3621,7 +3623,7 @@ def transition_day(cli, gameid=0): var.ALPHA_ENABLED = False dead = [] - vlist = copy.copy(victims) + vlist = victims[:] novictmsg = True if new_wolf: message.append(messages["new_wolf"]) @@ -3646,35 +3648,39 @@ def transition_day(cli, gameid=0): # In general, an event listener < 6 should both stop propagation and prevent default # Priority 6 listeners add additional stuff to the default action and should not prevent default for victim in vlist: - if not revt.dispatch(cli, var, victim): + if not revt.dispatch(var, victim): continue - if (victim in var.ROLES["lycan"] or victim in var.LYCANTHROPES) and victim in revt.data["onlybywolves"] and victim not in var.IMMUNIZED: - vrole = get_role(victim) + if (victim.nick in var.ROLES["lycan"] or victim.nick in var.LYCANTHROPES) and victim in revt.data["onlybywolves"] and victim.nick not in var.IMMUNIZED: + vrole = get_main_role(victim) if vrole not in var.WOLFCHAT_ROLES: revt.data["message"].append(messages["new_wolf"]) var.EXTRA_WOLVES += 1 - pm(cli, victim, messages["lycan_turn"]) - var.LYCAN_ROLES[victim] = vrole - change_role(users._get(victim), vrole, "wolf") # FIXME - var.ROLES["lycan"].discard(victim) # in the event lycan was a template, we want to ensure it gets purged - wolves = list_players(var.WOLFCHAT_ROLES) + victim.send(messages["lycan_turn"]) + var.LYCAN_ROLES[victim.nick] = vrole + change_role(victim, vrole, "wolf") + var.ROLES["lycan"].discard(victim.nick) # in the event lycan was a template, we want to ensure it gets purged + wolves = get_players(var.WOLFCHAT_ROLES) random.shuffle(wolves) wolves.remove(victim) # remove self from list - for i, wolf in enumerate(wolves): - pm(cli, wolf, messages["lycan_wc_notification"].format(victim)) - role = get_role(wolf) + to_send = [] + for wolf in wolves: + wolf.queue_message(messages["lycan_wc_notification"].format(victim)) + role = get_main_role(wolf) wevt = Event("wolflist", {"tags": set()}) - wevt.dispatch(cli, var, wolf, victim) + wevt.dispatch(cli, var, wolf.nick, victim.nick) tags = " ".join(wevt.data["tags"]) if tags: tags += " " - wolves[i] = "\u0002{0}\u0002 ({1}{2})".format(wolf, tags, role) + to_send.append("\u0002{0}\u0002 ({1}{2})".format(wolf, tags, role)) - pm(cli, victim, "Wolves: " + ", ".join(wolves)) + if wolves: + wolf.send_messages() + + victim.send("Wolves: " + ", ".join(to_send)) revt.data["novictmsg"] = False elif victim not in revt.data["dead"]: # not already dead via some other means if var.ROLE_REVEAL in ("on", "team"): - role = get_reveal_role(victim) + role = get_reveal_role(victim.nick) an = "n" if role.startswith(("a", "e", "i", "o", "u")) else "" revt.data["message"].append(messages["death"].format(victim, an, role)) else: @@ -3723,7 +3729,7 @@ def transition_day(cli, gameid=0): "protected": revt.data["protected"], "bitten": revt.data["bitten"] }) - revt2.dispatch(cli, var, victims) + revt2.dispatch(var, victims) message = revt2.data["message"] novictmsg = revt2.data["novictmsg"] dead = revt2.data["dead"] @@ -3734,32 +3740,31 @@ def transition_day(cli, gameid=0): bitten = revt2.data["bitten"] for victim in list(dead): - if victim in var.GUNNERS.keys() and var.GUNNERS[victim] > 0 and victim in bywolves: + if victim.nick in var.GUNNERS and var.GUNNERS[victim.nick] > 0 and victim in bywolves: if random.random() < var.GUNNER_KILLS_WOLF_AT_NIGHT_CHANCE: # pick a random wofl to be shot - woflset = {wolf for wolf in get_players(var.WOLF_ROLES) if wolf.nick not in dead} + woflset = {wolf for wolf in get_players(var.WOLF_ROLES) if wolf not in dead} # TODO: split into werekitten.py - woflset.difference_update(get_players(("werekitten",))) + woflset.difference_update(get_all_players(("werekitten",))) wolf_evt = Event("gunner_overnight_kill_wolflist", {"wolves": woflset}) wolf_evt.dispatch(var) woflset = wolf_evt.data["wolves"] if woflset: deadwolf = random.choice(tuple(woflset)) - deadwolf = deadwolf.nick # FIXME: remove when dead is converted to store users if var.ROLE_REVEAL in ("on", "team"): - message.append(messages["gunner_killed_wolf_overnight"].format(victim, deadwolf, get_reveal_role(deadwolf))) + message.append(messages["gunner_killed_wolf_overnight"].format(victim, deadwolf, get_reveal_role(deadwolf.nick))) else: message.append(messages["gunner_killed_wolf_overnight_no_reveal"].format(victim, deadwolf)) dead.append(deadwolf) - var.GUNNERS[victim] -= 1 # deduct the used bullet + var.GUNNERS[victim.nick] -= 1 # deduct the used bullet for victim in dead: - if victim in bywolves and victim in var.DISEASED: + if victim in bywolves and victim.nick in var.DISEASED: var.DISEASED_WOLVES = True - if var.WOLF_STEALS_GUN and victim in bywolves and victim in var.GUNNERS.keys() and var.GUNNERS[victim] > 0: + if var.WOLF_STEALS_GUN and victim in bywolves and victim.nick in var.GUNNERS and var.GUNNERS[victim.nick] > 0: # victim has bullets try: - looters = list_players(var.WOLFCHAT_ROLES) + looters = get_players(var.WOLFCHAT_ROLES) while len(looters) > 0: guntaker = random.choice(looters) # random looter if guntaker not in dead: @@ -3767,52 +3772,50 @@ def transition_day(cli, gameid=0): else: looters.remove(guntaker) if guntaker not in dead: - numbullets = var.GUNNERS[victim] - if guntaker not in var.GUNNERS: - var.GUNNERS[guntaker] = 0 - if guntaker not in var.ROLES["gunner"] and guntaker not in var.ROLES["sharpshooter"]: - var.ROLES["gunner"].add(guntaker) - var.GUNNERS[guntaker] += 1 # only transfer one bullet - mmsg = (messages["wolf_gunner"]) - mmsg = mmsg.format(victim) - pm(cli, guntaker, mmsg) + numbullets = var.GUNNERS[victim.nick] + if guntaker.nick not in var.GUNNERS: + var.GUNNERS[guntaker.nick] = 0 + if guntaker not in get_all_players(("gunner", "sharpshooter")): + var.ROLES["gunner"].add(guntaker.nick) + var.GUNNERS[guntaker.nick] += 1 # only transfer one bullet + guntaker.send(messages["wolf_gunner"].format(victim)) except IndexError: pass # no wolves to give gun to (they were all killed during night or something) - var.GUNNERS[victim] = 0 # just in case + var.GUNNERS[victim.nick] = 0 # just in case - cli.msg(chan, "\n".join(message)) + channels.Main.send("\n".join(message)) for chump in bitten: # turn all bitten people into wolves # short-circuit if they are already a wolf or are dying - chumprole = get_role(chump) + chumprole = get_main_role(chump) if chump in dead or chumprole in var.WOLF_ROLES: continue newrole = "wolf" if chumprole == "guardian angel": - pm(cli, chump, messages["fallen_angel_turn"]) + chump.send(messages["fallen_angel_turn"]) # fallen angels also automatically gain the assassin template if they don't already have it newrole = "fallen angel" - var.ROLES["assassin"].add(chump) - debuglog("{0} ({1}) TURNED FALLEN ANGEL".format(chump, chumprole)) + var.ROLES["assassin"].add(chump.nick) + debuglog("{0} (guardian angel) TURNED FALLEN ANGEL".format(chump)) elif chumprole in ("seer", "oracle", "augur"): - pm(cli, chump, messages["seer_turn"]) + chump.send(messages["seer_turn"]) newrole = "doomsayer" debuglog("{0} ({1}) TURNED DOOMSAYER".format(chump, chumprole)) elif chumprole in var.TOTEM_ORDER: - pm(cli, chump, messages["shaman_turn"]) + chump.send(messages["shaman_turn"]) newrole = "wolf shaman" debuglog("{0} ({1}) TURNED WOLF SHAMAN".format(chump, chumprole)) elif chumprole == "harlot": - pm(cli, chump, messages["harlot_turn"]) - debuglog("{0} ({1}) TURNED WOLF".format(chump, chumprole)) + chump.send(messages["harlot_turn"]) + debuglog("{0} (harlot) TURNED WOLF".format(chump)) else: - pm(cli, chump, messages["bitten_turn"]) + chump.send(messages["bitten_turn"]) debuglog("{0} ({1}) TURNED WOLF".format(chump, chumprole)) - var.BITTEN_ROLES[chump] = chumprole - change_role(users._get(chump), chumprole, newrole) # FIXME - relay_wolfchat_command(cli, chump, messages["wolfchat_new_member"].format(chump, newrole), var.WOLF_ROLES, is_wolf_command=True, is_kill_command=True) + var.BITTEN_ROLES[chump.nick] = chumprole + change_role(chump, chumprole, newrole) + relay_wolfchat_command(cli, chump.nick, messages["wolfchat_new_member"].format(chump, newrole), var.WOLF_ROLES, is_wolf_command=True, is_kill_command=True) killer_role = {} for deadperson in dead: @@ -3821,19 +3824,20 @@ def transition_day(cli, gameid=0): if killer == "@wolves": killer_role[deadperson] = "wolf" else: - killer_role[deadperson] = get_role(killer) + killer_role[deadperson] = get_main_role(killer) else: # no killers, so assume suicide - killer_role[deadperson] = get_role(deadperson) + killer_role[deadperson] = get_main_role(deadperson) + dead_nicks = [p.nick for p in dead] # FIXME: Update once del_player has been updated for deadperson in dead: # check if they have already been killed since del_player could do chain reactions and we want # to avoid sending duplicate messages. - if deadperson in list_players(): - del_player(cli, deadperson, end_game=False, killer_role=killer_role[deadperson], deadlist=dead, original=deadperson) + if deadperson in get_players(): + del_player(cli, deadperson.nick, end_game=False, killer_role=killer_role[deadperson], deadlist=dead_nicks, original=deadperson.nick) event_end = Event("transition_day_end", {"begin_day": begin_day}) - event_end.dispatch(cli, var) + event_end.dispatch(var) if chk_win(cli): # if after the last person is killed, one side wins, then actually end the game here return @@ -3841,7 +3845,7 @@ def transition_day(cli, gameid=0): event_end.data["begin_day"](cli) @event_listener("transition_day_resolve_end", priority=2) -def on_transition_day_resolve_end(evt, cli, var, victims): +def on_transition_day_resolve_end(evt, var, victims): if evt.data["novictmsg"] and len(evt.data["dead"]) == 0: evt.data["message"].append(random.choice(messages["no_victims"]) + messages["no_victims_append"])