diff --git a/werewoolf/.gitignore b/.gitignore similarity index 99% rename from werewoolf/.gitignore rename to .gitignore index 773fe78..5290d13 100644 --- a/werewoolf/.gitignore +++ b/.gitignore @@ -214,5 +214,3 @@ __marimo__/ # Streamlit .streamlit/secrets.toml -# custom -voicesline/playersname \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..0455c60 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "cSpell.words": [ + "potionchoice" + ] +} \ No newline at end of file diff --git a/werewoolf/logger.py b/logger.py similarity index 96% rename from werewoolf/logger.py rename to logger.py index 3262df6..3d65862 100644 --- a/werewoolf/logger.py +++ b/logger.py @@ -1,7 +1,7 @@ import logging log = logging.getLogger(__name__) -log.setLevel(logging.INFO) +log.setLevel(logging.DEBUG) formatter = logging.Formatter( "%(asctime)s \033[1m%(levelname)s\033[0m\033[0m %(message)s" ) diff --git a/werewoolf/main.py b/main.py similarity index 53% rename from werewoolf/main.py rename to main.py index 548c507..d79119b 100644 --- a/werewoolf/main.py +++ b/main.py @@ -3,19 +3,11 @@ from typing import Dict, List, Optional from dataclasses import dataclass import sys from logger import log -from finger_count import * -from playsound import playsound -import wave -from piper import PiperVoice -import os -from art import * -from translation import * - +from fuzzywuzzy import process @dataclass class Player: name: str - alias: str role: str alive: bool = True protected: bool = False @@ -34,8 +26,6 @@ class Game: # Used potions self.used_potions: [list[str]] = [] - # Language - self.language: str = "fr" # ------------------------- # setup / I/O # ------------------------- @@ -46,7 +36,7 @@ class Game: """ players_file = "players.txt" roles_file = "roles.txt" - words_file = "randoms_words.txt" + log.info("Loading lists...") try: @@ -63,29 +53,20 @@ class Game: log.critical("Roles file not found: %s", roles_file) return None - try: - with open(words_file, "r", encoding="utf-8") as rf: - alias_list = [line.strip() for line in rf if line.strip()] - except FileNotFoundError: - log.critical("Roles file not found: %s", words_file) - return None - - log.info("Load complete!") - return {"players": player_names, "roles": roles_list, "alias": alias_list} + return {"players": player_names, "roles": roles_list} # ------------------------- # player / role assignment # ------------------------- def give_roles_to_players(self, player_names: Optional[List[str]] = None, - roles_list: Optional[List[str]] = None, - alias_list: Optional[List[str]] = None) -> None: + roles_list: Optional[List[str]] = None) -> None: """ Assign a random role to each player. Accepts optional lists (returned by load_lists). If lists are not supplied, it will attempt to read files itself. """ - number = 0 + if not player_names: log.info("Players are not initialized") return @@ -96,59 +77,16 @@ class Game: log.error("Not enough roles for players (roles: %d, players: %d)", len(roles_list), len(player_names)) return - if len(alias_list) < len(player_names): - log.error("Not enough randoms words for players (words: %d, players: %d)", - len(alias_list), len(player_names)) - return available_roles = list(roles_list) random.shuffle(available_roles) - available_alias = list(alias_list) - random.shuffle(alias_list) # clear any existing players (safe to reassign) self.players.clear() - # clear any player name audio - if not os.path.exists("./voicesline/playersname"): - os.makedirs("./voicesline/playersname") - for filename in os.listdir("./voicesline/playersname"): - file_path = os.path.join("./voicesline/playersname", filename) - # Check if it is a file (not a subdirectory) - if os.path.isfile(file_path): - os.remove(file_path) # Remove the file - for filename in os.listdir("./voicesline/alias"): - file_path = os.path.join("./voicesline/alias", filename) - # Check if it is a file (not a subdirectory) - if os.path.isfile(file_path): - os.remove(file_path) # Remove the file - if self.language == "fr": - voice = PiperVoice.load("./voices/fr/fr_FR-tom-medium.onnx") - elif self.language == "en": - voice = PiperVoice.load("./voices/en/en_GB-alan-medium.onnx") - else: - log.info("Unknow language") + for name in player_names: chosen_role = available_roles.pop() - chosen_alias = available_alias.pop() - with wave.open(f"./voicesline/playersname/{name}.wav", "wb") as wav_file: - voice.synthesize_wav(name, wav_file) - with wave.open(f"./voicesline/alias/{chosen_alias}.wav", "wb") as wav_file: - voice.synthesize_wav(chosen_alias, wav_file) - number += 1 - self.players[number] = Player(name=name, role=chosen_role, alias=chosen_alias) - self.play_sound("players", name.capitalize()) - self.play_sound("prompts", "first_wakes") - if name == "Dan": - self.play_sound("prompts", "cheater") - self.show_text(chosen_role) - self.show_text(chosen_alias) - time.sleep(3) - os.system('clear') - self.play_sound("players", name.capitalize()) - self.play_sound("prompts", "sleep_again") - - - + self.players[name] = Player(name=name, role=chosen_role) log.debug("Assigned roles:") for player in self.players.values(): @@ -157,90 +95,56 @@ class Game: # ------------------------- # utilities # ------------------------- - def clear_data(self) -> None: - for player in self.players: - self.players[player].protected = False - - - def couple(self) -> None: - os.system('clear') - self.play_sound("prompts", "lovers") - log.debug(self.lovers) - for player in self.lovers: - log.info(self.players[player].alias) - self.play_sound("alias", self.players[player].alias) - self.show_text(self.players[player].role) - time.sleep(10) - - def show_text(self, text: str) -> None: - if self.language == "fr": - if text in FR: - Art=text2art(FR.get(text)) - print(Art) - else: - Art=text2art(text) - print(Art) - if self.language == "en": - Art=text2art(text) - print(Art) - - def get_remaining_roles(self) -> List[str]: - remaining_roles = [] - for player in self.players: - if self.players[player].alive: - remaining_roles.append(self.players[player].role) - log.DEBUG(remaining_roles) - return remaining_roles - - def number_2_name(self, player_number: int): - player_name = self.players[player_number].name - return player_name - - def play_sound(self, type, soundinfo) -> None: - if type == "prompts": - f = f"./voicesline/prompts/{self.language}/{soundinfo}.wav" - elif type == "roles": - f = f"./voicesline/roles/{self.language}/{soundinfo}.wav" - elif type == "players": - f = f"./voicesline/playersname/{soundinfo}.wav" - elif type == "alias": - f = f"./voicesline/alias/{soundinfo}.wav" - else: - log.debug("An error occurred") - return - time.sleep(0.2) - playsound(f) - def select_someone(self, prompt: Optional[str] = None) -> Optional[str]: """ Prompt the user to enter a player name until a valid one is entered. Returns None on EOF/KeyboardInterrupt. """ - prompt = prompt or "show_number" - #self.play_sound("prompts", prompt) + prompt = prompt or "Enter the name of the player: " while True: - selected = count_fingers() + selected = input(prompt).strip() # exact match if selected in self.players: return selected + # fuzzy matching + match = process.extract(selected, self.players, limit=1) + log.debug(match) + if match: + fuzz_player, fuzz_score = match[0][0], match[0][1] # player name, score + log.debug(fuzz_player) + log.debug(fuzz_score) + if fuzz_score >= 60: + log.info("You meant %s!", fuzz_player.name) + log.debug("Fuzz score: %s" % fuzz_score) + return fuzz_player.name + def choose_between(self, options): #Prompt the user to choose between options until a valid one is entered - numbered_options = " ".join([f"{i+1}: {option}" for i, option in enumerate(options)]) - log.info(f"Choose between {numbered_options}:") + + options_available = ', '.join(map(str, options)) + #Make a prompt with a list of options, accepting either a list or a tuple. + prompt = f"Choose between {options_available}: " while True: - selected = count_fingers() - try: - index = int(selected) - 1 - if 0 <= index < len(options): - chosen_option = options[index] - log.debug("You chose %s!", chosen_option) - return chosen_option - else: - log.warning("Invalid number entered.") - except ValueError: - log.warning("Invalid input. Please enter an option or number.") + selected = input(prompt) + + if selected in options: + return selected + + # fuzzy matching + match = process.extract(selected, options, limit=1) + log.debug(match) + if match: + fuzz_option, fuzz_score = match[0][0], match[0][1] #options, score + log.debug(fuzz_option) + log.debug(fuzz_score) + if fuzz_score >= 60: + log.info("You meant %s!", fuzz_option) + log.debug("Fuzz score: %s" % fuzz_score) + return fuzz_option + + # ------------------------- # game actions # ------------------------- @@ -252,7 +156,7 @@ class Game: self.lovers = (player1, player2) - log.debug("Players now put in love: %s <-> %s", self.players[player1], self.players[player2]) + log.debug("Players now put in love: %s <-> %s", player1, player2) log.info("They are now bounded by love.") log.info("They wake up and reveal their role to each other.") @@ -316,22 +220,21 @@ class Game: log.debug("%s -> role: %s, alive: %s, Protected: %s", p.name, p.role, p.alive, p.protected) # lovers - log.debug(f"Lovers: {self.lovers}") + log.debug("Lovers: %s" % ",".join(self.lovers)) def role(func): """Decorator for roles""" - def wrapper(self, *args, **kwargs): + def wrapper(*args, **kwargs): # the role is the name of the function thats decorated role = func.__name__.capitalize() - os.system('clear') - if role in self.get_remaining_roles(): - self.play_sound("roles", role) - self.play_sound("prompts", "wakes") - func(self, *args, **kwargs) - self.play_sound("roles", role) - self.play_sound("prompts", "sleep_again") - log.INFO("%s goes back to sleep." % role) - self.status() + log.info("%s wakes up." % role) + func(*args, **kwargs) + log.info("%s goes back to sleep." % role) + + # workaround to call status from the instance + # is it ok? no idea but i dont have self anyway + instance = args[0] + instance.status() return wrapper @@ -342,12 +245,12 @@ class Game: @role def cupidon(self) -> None: """Interactively pick two players to link by love.""" - self.play_sound("prompts", "linked_death") - self.play_sound("prompts", "first_bound") + log.info("Choose two people to be linked to death.") + log.info("Give me the first person that shall be bounded!") p1 = self.select_someone() if p1 is None: return - self.play_sound("prompts", "second_bound") + log.info("What about the second one?") p2 = self.select_someone() if p2 is None: return @@ -359,23 +262,21 @@ class Game: @role def savior(self) -> None: """Interactively choose someone to protect.""" - self.play_sound("prompts", "choose_protect") + log.info("Choose someone to protect.") protected = self.select_someone() if protected is None: - return + return + self.players[protected].protected = True log.debug("Protected: %s", protected) @role def witch(self) -> None: """Interactively choose to kill or revive someone""" - self.play_sound("prompts", "potions_choice") - self.play_sound("prompts", "might_die") - for player in self.dead_this_night: - self.show_text(self.players[player].name) + log.info("With the Revive Potion, you can revive someone, and with the Death Potion, you can kill someone. You can only use each potion once, and you can also choose to do nothing.") + log.info("Players who might die are %s", ' '.join(map(str, self.dead_this_night))) if len(self.used_potions) >= 2: - self.show_text("Vous avez utilisé toutes vos potions. ") - time.sleep(5) + log.info("You already used all of your potions. ") else: while True: options = ("Death", "Revive", "Nothing") @@ -387,9 +288,9 @@ class Game: self.revive(player) return elif player not in self.dead_this_night and not self.players[player].alive: - self.show_text("Tu ne peux pas faire revivre cette personne.") + log.info("You cannot bring this person back to life because they have been buried.") elif self.players[player].alive: - self.show_text("Cette personne n'est pas morte.") + log.info("This player is not dead.") else: log.info("Unknown error: Invalid player choice") return @@ -398,15 +299,14 @@ class Game: if self.players[player].alive: self.used_potions.append("Death") self.kill(player) - time.sleep(1) return elif not self.players[player].alive: - self.show_text("Ce joueur est déjà mort.") + log.info("This player is already dead.") else: log.info("Unknown error: Invalid player choice") return elif potionchoice == "Nothing": - self.show_text("Vous ne faites rien cette nuit.") + log.info("You are not doing anything tonight.") return elif potionchoice in self.used_potions: log.info("You already used this potion.") @@ -415,7 +315,7 @@ class Game: return @role def werewolf(self) -> None: - self.play_sound("prompts", "werewolf_choice") + log.info("You will choose someone to kill.") player = self.select_someone() self.kill(player) @@ -425,56 +325,21 @@ class Game: while True: player = self.select_someone() if "Seer" == self.players[player].role: - self.show_text("You can't see your own role.") + log.info("You can't see your own role.") else: - self.show_text(self.players[player].role) - time.sleep(3) + log.info(f"{player} is a {self.players[player].role}") return - - @role - def hunter(self) -> None: - self.play_sound("prompts", "hunter") - player = self.select_someone() - self.kill(player) - # ------------------------- # game flow # ------------------------- - def first_night_cycle(self) -> None: - self.play_sound("prompts", "fall_asleep_all") + def first_day_cycle(self) -> None: + log.info("All the villagers fall asleep.") self.cupidon() - self.couple() self.savior() self.werewolf() self.witch() self.seer() - self.day() - def night(self) -> None: - self.dead_this_night = [] - self.play_sound("prompts", "fall_asleep_all") - self.savior() - self.werewolf() - self.witch() - self.seer() - self.day() - - def day(self) -> None: - self.play_sound("prompts", "wake_up_all") - self.play_sound("prompts", "night_deaths") - for player in self.dead_this_night: - self.play_sound("players", self.number_2_name(player)) - for player in self.dead_this_night: - if self.players[player].role == "Hunter": - self.hunter() - self.play_sound("prompts", "village_vote") - while True: - if count_fingers(stable_duration=4) == 6: - break - self.play_sound("prompts", "now_show_number") - player = self.select_someone() - self.kill(player) - self.night() @@ -489,8 +354,8 @@ if __name__ == "__main__": try: if loaded: # start the game! - game.give_roles_to_players(loaded["players"], loaded["roles"], loaded["alias"]) - game.first_night_cycle() + game.give_roles_to_players(loaded["players"], loaded["roles"]) + game.first_day_cycle() # CTRL+C except KeyboardInterrupt: diff --git a/werewoolf/players.txt b/players.txt similarity index 53% rename from werewoolf/players.txt rename to players.txt index f11ae93..e0f4762 100644 --- a/werewoolf/players.txt +++ b/players.txt @@ -1,6 +1,10 @@ -Anavoi -Jean -Paul -Christophe +Marie Jeanne +Paul +Jean +Michel +Christophe +Anne Julien +Aurélie +Yoxu \ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..516af7e --- /dev/null +++ b/requirements.txt @@ -0,0 +1 @@ +fuzzywuzzy==0.18.0 \ No newline at end of file diff --git a/roles.txt b/roles.txt new file mode 100644 index 0000000..0f7f30e --- /dev/null +++ b/roles.txt @@ -0,0 +1,10 @@ +Wolf +Seer +WhiteWolf +Cupidon +Witch +Hunter +Corbeau +Stealer +Sorcier +Savior \ No newline at end of file diff --git a/werewoolf/finger_count.py b/werewoolf/finger_count.py deleted file mode 100644 index 8694571..0000000 --- a/werewoolf/finger_count.py +++ /dev/null @@ -1,87 +0,0 @@ -# code inspiration from https://www.geekering.com/categories/computer-vision/marcellacavalcanti/hand-tracking-and-finger-counting-in-python-with-mediapipe/ because i dont know how to use mediapipe - -import cv2 -import mediapipe as mp -import time - -mp_drawing = mp.solutions.drawing_utils -mp_drawing_styles = mp.solutions.drawing_styles -mp_hands = mp.solutions.hands - -def count_fingers(stable_duration=2): - previous_finger_count = -1 # Initialize to an invalid count - stable_start_time = None # To track when the count became stable - cap = cv2.VideoCapture(0) - with mp_hands.Hands( - model_complexity=0, - min_detection_confidence=0.5, - min_tracking_confidence=0.5) as hands: - - while cap.isOpened(): - success, image = cap.read() - if not success: - print("Ignoring empty camera frame.") - continue - - image.flags.writeable = False - image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) - results = hands.process(image) - - image.flags.writeable = True - image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR) - - fingerCount = 0 # Reset fingerCount for each frame - - if results.multi_hand_landmarks: - for hand_landmarks in results.multi_hand_landmarks: - handIndex = results.multi_hand_landmarks.index(hand_landmarks) - handLabel = results.multi_handedness[handIndex].classification[0].label - - handLandmarks = [] - for landmarks in hand_landmarks.landmark: - handLandmarks.append([landmarks.x, landmarks.y]) - - # Count fingers - if handLabel == "Left" and handLandmarks[4][0] > handLandmarks[3][0]: - fingerCount += 1 - elif handLabel == "Right" and handLandmarks[4][0] < handLandmarks[3][0]: - fingerCount += 1 - - if handLandmarks[8][1] < handLandmarks[6][1]: # Index finger - fingerCount += 1 - if handLandmarks[12][1] < handLandmarks[10][1]: # Middle finger - fingerCount += 1 - if handLandmarks[16][1] < handLandmarks[14][1]: # Ring finger - fingerCount += 1 - if handLandmarks[20][1] < handLandmarks[18][1]: # Pinky - fingerCount += 1 - - # Draw hand landmarks - mp_drawing.draw_landmarks( - image, - hand_landmarks, - mp_hands.HAND_CONNECTIONS, - mp_drawing_styles.get_default_hand_landmarks_style(), - mp_drawing_styles.get_default_hand_connections_style()) - - # Display finger count - cv2.putText(image, str(fingerCount), (50, 450), cv2.FONT_HERSHEY_SIMPLEX, 3, (255, 0, 0), 10) - #Display image - cv2.imshow('Finger Count', image) - - # Check if the finger count is stable - if fingerCount == previous_finger_count and fingerCount != 0: - if stable_start_time is None: - stable_start_time = time.time() # Start the timer - elif time.time() - stable_start_time >= stable_duration and fingerCount != 0: - cap.release() - cv2.destroyAllWindows() - return fingerCount # Return the stable finger count - else: - stable_start_time = None # Reset the timer if the count changes - - previous_finger_count = fingerCount # Update the previous count - if cv2.waitKey(5) & 0xFF == 27: - break - - return None # Return None if the loop ends without a stable count diff --git a/werewoolf/randoms_words.txt b/werewoolf/randoms_words.txt deleted file mode 100644 index 7ce4242..0000000 --- a/werewoolf/randoms_words.txt +++ /dev/null @@ -1,11 +0,0 @@ -Abricot -Pomme -Fraise -Melon -Orange -Framboise -Cerise -Citron -Poire -Raisin -Prune \ No newline at end of file diff --git a/werewoolf/requirements.txt b/werewoolf/requirements.txt deleted file mode 100644 index c638c1a..0000000 --- a/werewoolf/requirements.txt +++ /dev/null @@ -1,7 +0,0 @@ -fuzzywuzzy==0.18.0 -opencv_python -mediapipe -piper-tts -playsound -art -pygobject \ No newline at end of file diff --git a/werewoolf/roles.txt b/werewoolf/roles.txt deleted file mode 100644 index fcc099d..0000000 --- a/werewoolf/roles.txt +++ /dev/null @@ -1,10 +0,0 @@ -Werewolf -Seer -Witch -Grandchild -Hunter -Werewolf -Werewolf -Villager -Cupidon -Villager \ No newline at end of file diff --git a/werewoolf/translation.py b/werewoolf/translation.py deleted file mode 100644 index d94f467..0000000 --- a/werewoolf/translation.py +++ /dev/null @@ -1,10 +0,0 @@ -FR = { - "Seer": "Voyante", - "Werewolf": "Loups-Garous", - "Witch": "Sorciere", - "Cupidon": "Cupidon", - "Savior": "Salvateur", - "Villager": "Villageois", - "Grandchild": "Petite-Fille", - "Hunter": "Chasseur" -} \ No newline at end of file diff --git a/werewoolf/voices/fr/fr_FR-tom-medium.onnx b/werewoolf/voices/fr/fr_FR-tom-medium.onnx deleted file mode 100644 index 880e3e8..0000000 Binary files a/werewoolf/voices/fr/fr_FR-tom-medium.onnx and /dev/null differ diff --git a/werewoolf/voices/fr/fr_FR-tom-medium.onnx.json b/werewoolf/voices/fr/fr_FR-tom-medium.onnx.json deleted file mode 100644 index 526f2bd..0000000 --- a/werewoolf/voices/fr/fr_FR-tom-medium.onnx.json +++ /dev/null @@ -1,502 +0,0 @@ -{ - "dataset": "tom", - "audio": { - "sample_rate": 44100, - "quality": "medium" - }, - "espeak": { - "voice": "fr" - }, - "language": { - "code": "fr_FR", - "family": "fr", - "region": "FR", - "name_native": "Français", - "name_english": "French", - "country_english": "France" - }, - "inference": { - "noise_scale": 0.667, - "length_scale": 1, - "noise_w": 0.8 - }, - "phoneme_type": "espeak", - "phoneme_map": {}, - "phoneme_id_map": { - " ": [ - 3 - ], - "!": [ - 4 - ], - "\"": [ - 150 - ], - "#": [ - 149 - ], - "$": [ - 2 - ], - "'": [ - 5 - ], - "(": [ - 6 - ], - ")": [ - 7 - ], - ",": [ - 8 - ], - "-": [ - 9 - ], - ".": [ - 10 - ], - "0": [ - 130 - ], - "1": [ - 131 - ], - "2": [ - 132 - ], - "3": [ - 133 - ], - "4": [ - 134 - ], - "5": [ - 135 - ], - "6": [ - 136 - ], - "7": [ - 137 - ], - "8": [ - 138 - ], - "9": [ - 139 - ], - ":": [ - 11 - ], - ";": [ - 12 - ], - "?": [ - 13 - ], - "X": [ - 156 - ], - "^": [ - 1 - ], - "_": [ - 0 - ], - "a": [ - 14 - ], - "b": [ - 15 - ], - "c": [ - 16 - ], - "d": [ - 17 - ], - "e": [ - 18 - ], - "f": [ - 19 - ], - "g": [ - 154 - ], - "h": [ - 20 - ], - "i": [ - 21 - ], - "j": [ - 22 - ], - "k": [ - 23 - ], - "l": [ - 24 - ], - "m": [ - 25 - ], - "n": [ - 26 - ], - "o": [ - 27 - ], - "p": [ - 28 - ], - "q": [ - 29 - ], - "r": [ - 30 - ], - "s": [ - 31 - ], - "t": [ - 32 - ], - "u": [ - 33 - ], - "v": [ - 34 - ], - "w": [ - 35 - ], - "x": [ - 36 - ], - "y": [ - 37 - ], - "z": [ - 38 - ], - "æ": [ - 39 - ], - "ç": [ - 40 - ], - "ð": [ - 41 - ], - "ø": [ - 42 - ], - "ħ": [ - 43 - ], - "ŋ": [ - 44 - ], - "œ": [ - 45 - ], - "ǀ": [ - 46 - ], - "ǁ": [ - 47 - ], - "ǂ": [ - 48 - ], - "ǃ": [ - 49 - ], - "ɐ": [ - 50 - ], - "ɑ": [ - 51 - ], - "ɒ": [ - 52 - ], - "ɓ": [ - 53 - ], - "ɔ": [ - 54 - ], - "ɕ": [ - 55 - ], - "ɖ": [ - 56 - ], - "ɗ": [ - 57 - ], - "ɘ": [ - 58 - ], - "ə": [ - 59 - ], - "ɚ": [ - 60 - ], - "ɛ": [ - 61 - ], - "ɜ": [ - 62 - ], - "ɞ": [ - 63 - ], - "ɟ": [ - 64 - ], - "ɠ": [ - 65 - ], - "ɡ": [ - 66 - ], - "ɢ": [ - 67 - ], - "ɣ": [ - 68 - ], - "ɤ": [ - 69 - ], - "ɥ": [ - 70 - ], - "ɦ": [ - 71 - ], - "ɧ": [ - 72 - ], - "ɨ": [ - 73 - ], - "ɪ": [ - 74 - ], - "ɫ": [ - 75 - ], - "ɬ": [ - 76 - ], - "ɭ": [ - 77 - ], - "ɮ": [ - 78 - ], - "ɯ": [ - 79 - ], - "ɰ": [ - 80 - ], - "ɱ": [ - 81 - ], - "ɲ": [ - 82 - ], - "ɳ": [ - 83 - ], - "ɴ": [ - 84 - ], - "ɵ": [ - 85 - ], - "ɶ": [ - 86 - ], - "ɸ": [ - 87 - ], - "ɹ": [ - 88 - ], - "ɺ": [ - 89 - ], - "ɻ": [ - 90 - ], - "ɽ": [ - 91 - ], - "ɾ": [ - 92 - ], - "ʀ": [ - 93 - ], - "ʁ": [ - 94 - ], - "ʂ": [ - 95 - ], - "ʃ": [ - 96 - ], - "ʄ": [ - 97 - ], - "ʈ": [ - 98 - ], - "ʉ": [ - 99 - ], - "ʊ": [ - 100 - ], - "ʋ": [ - 101 - ], - "ʌ": [ - 102 - ], - "ʍ": [ - 103 - ], - "ʎ": [ - 104 - ], - "ʏ": [ - 105 - ], - "ʐ": [ - 106 - ], - "ʑ": [ - 107 - ], - "ʒ": [ - 108 - ], - "ʔ": [ - 109 - ], - "ʕ": [ - 110 - ], - "ʘ": [ - 111 - ], - "ʙ": [ - 112 - ], - "ʛ": [ - 113 - ], - "ʜ": [ - 114 - ], - "ʝ": [ - 115 - ], - "ʟ": [ - 116 - ], - "ʡ": [ - 117 - ], - "ʢ": [ - 118 - ], - "ʦ": [ - 155 - ], - "ʰ": [ - 145 - ], - "ʲ": [ - 119 - ], - "ˈ": [ - 120 - ], - "ˌ": [ - 121 - ], - "ː": [ - 122 - ], - "ˑ": [ - 123 - ], - "˞": [ - 124 - ], - "ˤ": [ - 146 - ], - "̃": [ - 141 - ], - "̧": [ - 140 - ], - "̩": [ - 144 - ], - "̪": [ - 142 - ], - "̯": [ - 143 - ], - "̺": [ - 152 - ], - "̻": [ - 153 - ], - "β": [ - 125 - ], - "ε": [ - 147 - ], - "θ": [ - 126 - ], - "χ": [ - 127 - ], - "ᵻ": [ - 128 - ], - "↑": [ - 151 - ], - "↓": [ - 148 - ], - "ⱱ": [ - 129 - ] - }, - "num_symbols": 256, - "num_speakers": 1, - "speaker_id_map": {}, - "piper_version": "1.0.0" -} diff --git a/werewoolf/voicesline/prompts/en/bound.wav b/werewoolf/voicesline/prompts/en/bound.wav deleted file mode 100644 index a8f3134..0000000 Binary files a/werewoolf/voicesline/prompts/en/bound.wav and /dev/null differ diff --git a/werewoolf/voicesline/prompts/en/choose_protect.wav b/werewoolf/voicesline/prompts/en/choose_protect.wav deleted file mode 100644 index fc97449..0000000 Binary files a/werewoolf/voicesline/prompts/en/choose_protect.wav and /dev/null differ diff --git a/werewoolf/voicesline/prompts/en/fall_asleep_all.wav b/werewoolf/voicesline/prompts/en/fall_asleep_all.wav deleted file mode 100644 index 56d2905..0000000 Binary files a/werewoolf/voicesline/prompts/en/fall_asleep_all.wav and /dev/null differ diff --git a/werewoolf/voicesline/prompts/en/first_bound.wav b/werewoolf/voicesline/prompts/en/first_bound.wav deleted file mode 100644 index bc697cf..0000000 Binary files a/werewoolf/voicesline/prompts/en/first_bound.wav and /dev/null differ diff --git a/werewoolf/voicesline/prompts/en/hunter.wav b/werewoolf/voicesline/prompts/en/hunter.wav deleted file mode 100644 index 80bb54c..0000000 Binary files a/werewoolf/voicesline/prompts/en/hunter.wav and /dev/null differ diff --git a/werewoolf/voicesline/prompts/en/linked_death.wav b/werewoolf/voicesline/prompts/en/linked_death.wav deleted file mode 100644 index d50a0ed..0000000 Binary files a/werewoolf/voicesline/prompts/en/linked_death.wav and /dev/null differ diff --git a/werewoolf/voicesline/prompts/en/lovers.wav b/werewoolf/voicesline/prompts/en/lovers.wav deleted file mode 100644 index 2d1e3d1..0000000 Binary files a/werewoolf/voicesline/prompts/en/lovers.wav and /dev/null differ diff --git a/werewoolf/voicesline/prompts/en/might_die.wav b/werewoolf/voicesline/prompts/en/might_die.wav deleted file mode 100644 index a0d9c1f..0000000 Binary files a/werewoolf/voicesline/prompts/en/might_die.wav and /dev/null differ diff --git a/werewoolf/voicesline/prompts/en/night_deaths.wav b/werewoolf/voicesline/prompts/en/night_deaths.wav deleted file mode 100644 index 57b0028..0000000 Binary files a/werewoolf/voicesline/prompts/en/night_deaths.wav and /dev/null differ diff --git a/werewoolf/voicesline/prompts/en/now_show_number.wav b/werewoolf/voicesline/prompts/en/now_show_number.wav deleted file mode 100644 index 9b66c8d..0000000 Binary files a/werewoolf/voicesline/prompts/en/now_show_number.wav and /dev/null differ diff --git a/werewoolf/voicesline/prompts/en/potions_choice.wav b/werewoolf/voicesline/prompts/en/potions_choice.wav deleted file mode 100644 index 571acf2..0000000 Binary files a/werewoolf/voicesline/prompts/en/potions_choice.wav and /dev/null differ diff --git a/werewoolf/voicesline/prompts/en/reveal.wav b/werewoolf/voicesline/prompts/en/reveal.wav deleted file mode 100644 index fcb8b25..0000000 Binary files a/werewoolf/voicesline/prompts/en/reveal.wav and /dev/null differ diff --git a/werewoolf/voicesline/prompts/en/second_bound.wav b/werewoolf/voicesline/prompts/en/second_bound.wav deleted file mode 100644 index 782ed53..0000000 Binary files a/werewoolf/voicesline/prompts/en/second_bound.wav and /dev/null differ diff --git a/werewoolf/voicesline/prompts/en/sleep.wav b/werewoolf/voicesline/prompts/en/sleep.wav deleted file mode 100644 index c4d2032..0000000 Binary files a/werewoolf/voicesline/prompts/en/sleep.wav and /dev/null differ diff --git a/werewoolf/voicesline/prompts/en/sleep_again.wav b/werewoolf/voicesline/prompts/en/sleep_again.wav deleted file mode 100644 index 24696af..0000000 Binary files a/werewoolf/voicesline/prompts/en/sleep_again.wav and /dev/null differ diff --git a/werewoolf/voicesline/prompts/en/village_vote.wav b/werewoolf/voicesline/prompts/en/village_vote.wav deleted file mode 100644 index 821695f..0000000 Binary files a/werewoolf/voicesline/prompts/en/village_vote.wav and /dev/null differ diff --git a/werewoolf/voicesline/prompts/en/wake_up_all.wav b/werewoolf/voicesline/prompts/en/wake_up_all.wav deleted file mode 100644 index 4eb3caa..0000000 Binary files a/werewoolf/voicesline/prompts/en/wake_up_all.wav and /dev/null differ diff --git a/werewoolf/voicesline/prompts/en/wakes.wav b/werewoolf/voicesline/prompts/en/wakes.wav deleted file mode 100644 index e8f5aa3..0000000 Binary files a/werewoolf/voicesline/prompts/en/wakes.wav and /dev/null differ diff --git a/werewoolf/voicesline/prompts/en/werewolf_choice.wav b/werewoolf/voicesline/prompts/en/werewolf_choice.wav deleted file mode 100644 index 7beba37..0000000 Binary files a/werewoolf/voicesline/prompts/en/werewolf_choice.wav and /dev/null differ diff --git a/werewoolf/voicesline/prompts/fr/bound.wav b/werewoolf/voicesline/prompts/fr/bound.wav deleted file mode 100644 index 0957a70..0000000 Binary files a/werewoolf/voicesline/prompts/fr/bound.wav and /dev/null differ diff --git a/werewoolf/voicesline/prompts/fr/cheater.wav b/werewoolf/voicesline/prompts/fr/cheater.wav deleted file mode 100644 index 334dfdb..0000000 Binary files a/werewoolf/voicesline/prompts/fr/cheater.wav and /dev/null differ diff --git a/werewoolf/voicesline/prompts/fr/choose_protect.wav b/werewoolf/voicesline/prompts/fr/choose_protect.wav deleted file mode 100644 index 6b006fa..0000000 Binary files a/werewoolf/voicesline/prompts/fr/choose_protect.wav and /dev/null differ diff --git a/werewoolf/voicesline/prompts/fr/fall_asleep_all.wav b/werewoolf/voicesline/prompts/fr/fall_asleep_all.wav deleted file mode 100644 index 8d65031..0000000 Binary files a/werewoolf/voicesline/prompts/fr/fall_asleep_all.wav and /dev/null differ diff --git a/werewoolf/voicesline/prompts/fr/first_bound.wav b/werewoolf/voicesline/prompts/fr/first_bound.wav deleted file mode 100644 index 31b3c10..0000000 Binary files a/werewoolf/voicesline/prompts/fr/first_bound.wav and /dev/null differ diff --git a/werewoolf/voicesline/prompts/fr/first_wakes.wav b/werewoolf/voicesline/prompts/fr/first_wakes.wav deleted file mode 100644 index e49ce3b..0000000 Binary files a/werewoolf/voicesline/prompts/fr/first_wakes.wav and /dev/null differ diff --git a/werewoolf/voicesline/prompts/fr/hunter.wav b/werewoolf/voicesline/prompts/fr/hunter.wav deleted file mode 100644 index 3188118..0000000 Binary files a/werewoolf/voicesline/prompts/fr/hunter.wav and /dev/null differ diff --git a/werewoolf/voicesline/prompts/fr/linked_death.wav b/werewoolf/voicesline/prompts/fr/linked_death.wav deleted file mode 100644 index 028e07f..0000000 Binary files a/werewoolf/voicesline/prompts/fr/linked_death.wav and /dev/null differ diff --git a/werewoolf/voicesline/prompts/fr/lovers.wav b/werewoolf/voicesline/prompts/fr/lovers.wav deleted file mode 100644 index e5cc0f6..0000000 Binary files a/werewoolf/voicesline/prompts/fr/lovers.wav and /dev/null differ diff --git a/werewoolf/voicesline/prompts/fr/might_die.wav b/werewoolf/voicesline/prompts/fr/might_die.wav deleted file mode 100644 index 022b8d8..0000000 Binary files a/werewoolf/voicesline/prompts/fr/might_die.wav and /dev/null differ diff --git a/werewoolf/voicesline/prompts/fr/night_deaths.wav b/werewoolf/voicesline/prompts/fr/night_deaths.wav deleted file mode 100644 index 5800794..0000000 Binary files a/werewoolf/voicesline/prompts/fr/night_deaths.wav and /dev/null differ diff --git a/werewoolf/voicesline/prompts/fr/now_show_number.wav b/werewoolf/voicesline/prompts/fr/now_show_number.wav deleted file mode 100644 index cd97fe1..0000000 Binary files a/werewoolf/voicesline/prompts/fr/now_show_number.wav and /dev/null differ diff --git a/werewoolf/voicesline/prompts/fr/potions_choice.wav b/werewoolf/voicesline/prompts/fr/potions_choice.wav deleted file mode 100644 index aaeba83..0000000 Binary files a/werewoolf/voicesline/prompts/fr/potions_choice.wav and /dev/null differ diff --git a/werewoolf/voicesline/prompts/fr/reveal.wav b/werewoolf/voicesline/prompts/fr/reveal.wav deleted file mode 100644 index a9345f7..0000000 Binary files a/werewoolf/voicesline/prompts/fr/reveal.wav and /dev/null differ diff --git a/werewoolf/voicesline/prompts/fr/second_bound.wav b/werewoolf/voicesline/prompts/fr/second_bound.wav deleted file mode 100644 index 781eca7..0000000 Binary files a/werewoolf/voicesline/prompts/fr/second_bound.wav and /dev/null differ diff --git a/werewoolf/voicesline/prompts/fr/sleep.wav b/werewoolf/voicesline/prompts/fr/sleep.wav deleted file mode 100644 index 6e31abe..0000000 Binary files a/werewoolf/voicesline/prompts/fr/sleep.wav and /dev/null differ diff --git a/werewoolf/voicesline/prompts/fr/sleep_again.wav b/werewoolf/voicesline/prompts/fr/sleep_again.wav deleted file mode 100644 index b3da3ac..0000000 Binary files a/werewoolf/voicesline/prompts/fr/sleep_again.wav and /dev/null differ diff --git a/werewoolf/voicesline/prompts/fr/village_vote.wav b/werewoolf/voicesline/prompts/fr/village_vote.wav deleted file mode 100644 index 875fa71..0000000 Binary files a/werewoolf/voicesline/prompts/fr/village_vote.wav and /dev/null differ diff --git a/werewoolf/voicesline/prompts/fr/wake_up_all.wav b/werewoolf/voicesline/prompts/fr/wake_up_all.wav deleted file mode 100644 index b3b5504..0000000 Binary files a/werewoolf/voicesline/prompts/fr/wake_up_all.wav and /dev/null differ diff --git a/werewoolf/voicesline/prompts/fr/wakes.wav b/werewoolf/voicesline/prompts/fr/wakes.wav deleted file mode 100644 index 92bd902..0000000 Binary files a/werewoolf/voicesline/prompts/fr/wakes.wav and /dev/null differ diff --git a/werewoolf/voicesline/prompts/fr/werewolf_choice.wav b/werewoolf/voicesline/prompts/fr/werewolf_choice.wav deleted file mode 100644 index d0d460a..0000000 Binary files a/werewoolf/voicesline/prompts/fr/werewolf_choice.wav and /dev/null differ diff --git a/werewoolf/voicesline/roles/en/Cupidon.wav b/werewoolf/voicesline/roles/en/Cupidon.wav deleted file mode 100644 index 1c9b15c..0000000 Binary files a/werewoolf/voicesline/roles/en/Cupidon.wav and /dev/null differ diff --git a/werewoolf/voicesline/roles/en/Hunter.wav b/werewoolf/voicesline/roles/en/Hunter.wav deleted file mode 100644 index 0bd6d49..0000000 Binary files a/werewoolf/voicesline/roles/en/Hunter.wav and /dev/null differ diff --git a/werewoolf/voicesline/roles/en/Savior.wav b/werewoolf/voicesline/roles/en/Savior.wav deleted file mode 100644 index 577c354..0000000 Binary files a/werewoolf/voicesline/roles/en/Savior.wav and /dev/null differ diff --git a/werewoolf/voicesline/roles/en/Seer.wav b/werewoolf/voicesline/roles/en/Seer.wav deleted file mode 100644 index 150f33a..0000000 Binary files a/werewoolf/voicesline/roles/en/Seer.wav and /dev/null differ diff --git a/werewoolf/voicesline/roles/en/Werewolf.wav b/werewoolf/voicesline/roles/en/Werewolf.wav deleted file mode 100644 index 1b08b7f..0000000 Binary files a/werewoolf/voicesline/roles/en/Werewolf.wav and /dev/null differ diff --git a/werewoolf/voicesline/roles/en/Witch.wav b/werewoolf/voicesline/roles/en/Witch.wav deleted file mode 100644 index e980847..0000000 Binary files a/werewoolf/voicesline/roles/en/Witch.wav and /dev/null differ diff --git a/werewoolf/voicesline/roles/fr/Cupidon.wav b/werewoolf/voicesline/roles/fr/Cupidon.wav deleted file mode 100644 index 37dfd77..0000000 Binary files a/werewoolf/voicesline/roles/fr/Cupidon.wav and /dev/null differ diff --git a/werewoolf/voicesline/roles/fr/Hunter.wav b/werewoolf/voicesline/roles/fr/Hunter.wav deleted file mode 100644 index bc7d2b0..0000000 Binary files a/werewoolf/voicesline/roles/fr/Hunter.wav and /dev/null differ diff --git a/werewoolf/voicesline/roles/fr/Savior.wav b/werewoolf/voicesline/roles/fr/Savior.wav deleted file mode 100644 index 5715ef4..0000000 Binary files a/werewoolf/voicesline/roles/fr/Savior.wav and /dev/null differ diff --git a/werewoolf/voicesline/roles/fr/Seer.wav b/werewoolf/voicesline/roles/fr/Seer.wav deleted file mode 100644 index 1e0a07c..0000000 Binary files a/werewoolf/voicesline/roles/fr/Seer.wav and /dev/null differ diff --git a/werewoolf/voicesline/roles/fr/Werewolf.wav b/werewoolf/voicesline/roles/fr/Werewolf.wav deleted file mode 100644 index e098cf8..0000000 Binary files a/werewoolf/voicesline/roles/fr/Werewolf.wav and /dev/null differ diff --git a/werewoolf/voicesline/roles/fr/Witch.wav b/werewoolf/voicesline/roles/fr/Witch.wav deleted file mode 100644 index 4ac115f..0000000 Binary files a/werewoolf/voicesline/roles/fr/Witch.wav and /dev/null differ