From 220a2a8d7f20d12c36d508482200107678957c8d Mon Sep 17 00:00:00 2001 From: Ryan Schmidt Date: Tue, 26 Nov 2024 19:15:12 -0700 Subject: [PATCH] Unbreak some things The mode should actually work now. --- messages/en.json | 7 +++++++ src/gamemodes/pactbreaker.py | 29 +++++++++++++++++++++++++---- 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/messages/en.json b/messages/en.json index 683f28ba..dc21afe7 100644 --- a/messages/en.json +++ b/messages/en.json @@ -1451,6 +1451,10 @@ "pactbreaker_villager_notify": "You are {=villager!role:article} {=villager!role:bold}. It is your job to either re-establish the pact with the {=wolf!role:plural} by killing the {=vigilante!role:plural} and {=vampire!role:plural} or to help the {=vigilante!role:plural} end the threat the {=wolf!role:plural} and {=vampire!role:plural} cause.\n{=pactbreaker_notify!message}", "pactbreaker_notify": "You may visit another player's house by using \"{=visit!command} \"; you can also visit the {=forest!command:bold}, {=square!command:bold}, or {=graveyard!command:bold}. Visiting allows you to collect evidence about other players. Alternatively, you can stay home by using \"{=pass!command}\" to make it harder for other players to collect evidence about you.", "pactbreaker_clue_notify": "You have {0:bold} clue {=token,tokens:plural({0})}. You may spend all of your clue tokens during the day (minimum 2) by using \"{=id!command} \" in PM to gain evidence on someone.", + "pactbreaker_info_clues": "You have {0:bold} clue {=token,tokens:plural({0})}.", + "pactbreaker_info_evidence": "You have collected evidence on the following people: {0:join}", + "pactbreaker_info_evidence_entry": "{0} ({1!role})", + "pactbreaker_info_no_evidence": "You have not collected evidence on anyone.", "pactbreaker_visiting_forest": "You have chosen to visit the forest tonight.", "pactbreaker_visiting_square": "You have chosen to visit the village square tonight.", "pactbreaker_visiting_graveyard": "You have chosen to visit the graveyard tonight.", @@ -1463,6 +1467,9 @@ "pactbreaker_forest_empty": "Your search of the forest last night did not turn up any useful evidence.", "pactbreaker_square_share": "You compared notes with other people in the village square last night and gained a useful clue towards someone's identity!", "pactbreaker_square_evidence": "Examining {0:@} while they are in the stocks leads you to the conclusion that they are {1!role:article} {1!role:bold}!", + "pactbreaker_square_witness_wolf": "While in the square last night, you witnessed a werewolf leap out of the shadows and maul {0} while they helplessly watched from the stocks. You feel like the scene may provide a useful clue towards someone's identity!", + "pactbreaker_square_witness_vigilante": "While in the square last night, you witnessed a cloked figure step in front of stocks and shoot {0} with a crossbow before swiftly fleeing the scene. You feel like the scene may provide a useful clue towards someone's identity!", + "pactbreaker_square_witness_vampire": "While in the square last night, you notice {0} hanging limply from the stocks. Upon closer investigation, there are bite marks on their neck. You feel like the scene may provide a useful clue towards someone's identity!", "pactbreaker_square_empty": "Your search of the village square last night did not turn up any useful evidence.", "pactbreaker_graveyard_clue": "While searching the graveyard last night, you gained a useful clue towards someone's identity!", "pactbreaker_graveyard_empty": "Your search of the graveyard last night did not turn up any useful evidence.", diff --git a/src/gamemodes/pactbreaker.py b/src/gamemodes/pactbreaker.py index c973d9ac..e42ab52e 100644 --- a/src/gamemodes/pactbreaker.py +++ b/src/gamemodes/pactbreaker.py @@ -65,6 +65,7 @@ def __init__(self, arg=""): "abstain": EventListener(self.on_abstain), "lynch_immunity": EventListener(self.on_lynch_immunity), "del_player": EventListener(self.on_del_player), + "myrole": EventListener(self.on_myrole), } self.MESSAGE_OVERRIDES = { @@ -161,6 +162,8 @@ def on_del_player(self, evt: Event, var: GameState, player, all_roles, death_tri del self.killing[:player:] del self.voted[:player:] del self.visit_count[:player:] + self.clue_pool += self.clue_tokens[player] + del self.clue_tokens[player] for attacker, victim in list(self.killing.items()): if victim is player: NIGHT_IDLE_EXEMPT.add(attacker) @@ -192,6 +195,19 @@ def on_send_role(self, evt: Event, var: GameState): ps.remove(player) player.send(messages["players_list"].format(ps)) + def on_myrole(self, evt: Event, var: GameState, player: User): + player.send(messages["pactbreaker_info_clues"].format(self.clue_tokens[player])) + if not self.collected_evidence[player] and not self.stale_evidence[player]: + player.send(messages["pactbreaker_info_no_evidence"]) + else: + entries = [] + for target in self.collected_evidence[player]: + entries.append(messages["pactbreaker_info_evidence_entry"].format(target, get_main_role(var, target))) + for target in self.stale_evidence[player]: + if target not in self.collected_evidence[player]: + entries.append(messages["pactbreaker_info_evidence_entry"].format(target, "vigilante")) + player.send(messages["pactbreaker_info_evidence"].format(sorted(entries))) + def on_chk_nightdone(self, evt: Event, var: GameState): evt.data["acted"].clear() evt.data["nightroles"].clear() @@ -324,11 +340,11 @@ def on_night_kills(self, evt: Event, var: GameState): i = 0 # for hunted card messaging and forest evidence all_wolves = set(get_players(var, ("wolf",))) - wolves = list(visitors - all_wolves) + wolves = list(visitors & all_wolves) random.shuffle(wolves) # for bites all_vamps = set(get_players(var, ("vampire",))) - vamps = list(visitors - all_vamps) + vamps = list(visitors & all_vamps) random.shuffle(vamps) # ensure that clue tokens are randomly distributed in case there are not enough by randomizing visitor list vl = list(visitors) @@ -368,7 +384,7 @@ def on_night_kills(self, evt: Event, var: GameState): if location is VillageSquare and witness and self.clue_pool > 0: self.clue_pool -= 1 self.clue_tokens[visitor] += 1 - visitor.send(messages["pactbreaker_square_witness"].format(witness)) + visitor.send(messages[f"pactbreaker_square_witness_{witness}"].format(self.in_stocks)) if "share" in cards: # has to be handled after everyone finishes drawing shares.append(visitor) @@ -480,7 +496,7 @@ def on_night_death_message(self, evt: Event, var: GameState, victim: User, kille killer.send(messages["pactbreaker_shooter_stocks"].format(victim, victim_role)) else: # shouldn't happen; indicates a bug in the mode - raise RuntimeError("Unknown night death situation") + raise RuntimeError(f"Unknown night death situation ({killer_role}/{victim_role}/{location.name})") def on_transition_day_resolve(self, evt: Event, var: GameState, dead: set[User], killers: dict[User, User | str]): # check for players meant to kill someone but got their kill pre-empted by someone else @@ -501,6 +517,11 @@ def on_begin_day(self, evt: Event, var: GameState): # if someone was locked up last night, ensure they can't be locked up again tonight if self.last_voted is not None: add_lynch_immunity(var, self.last_voted, "pactbreaker") + # alert people about clue tokens they have + for player, amount in self.clue_tokens.items(): + if amount == 0: + continue + player.send(messages["pactbreaker_clue_notify"].format(amount)) def on_lynch(self, evt: Event, var: GameState, votee: User, voters: Iterable[User]): self.last_voted = votee