Compare commits
No commits in common. "main" and "experimental" have entirely different histories.
main
...
experiment
66 changed files with 842 additions and 98 deletions
5
.vscode/settings.json
vendored
5
.vscode/settings.json
vendored
|
|
@ -1,5 +0,0 @@
|
||||||
{
|
|
||||||
"cSpell.words": [
|
|
||||||
"potionchoice"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
fuzzywuzzy==0.18.0
|
|
||||||
10
roles.txt
10
roles.txt
|
|
@ -1,10 +0,0 @@
|
||||||
Wolf
|
|
||||||
Seer
|
|
||||||
WhiteWolf
|
|
||||||
Cupidon
|
|
||||||
Witch
|
|
||||||
Hunter
|
|
||||||
Corbeau
|
|
||||||
Stealer
|
|
||||||
Sorcier
|
|
||||||
Savior
|
|
||||||
2
.gitignore → werewoolf/.gitignore
vendored
2
.gitignore → werewoolf/.gitignore
vendored
|
|
@ -214,3 +214,5 @@ __marimo__/
|
||||||
|
|
||||||
# Streamlit
|
# Streamlit
|
||||||
.streamlit/secrets.toml
|
.streamlit/secrets.toml
|
||||||
|
# custom
|
||||||
|
voicesline/playersname
|
||||||
87
werewoolf/finger_count.py
Normal file
87
werewoolf/finger_count.py
Normal file
|
|
@ -0,0 +1,87 @@
|
||||||
|
# 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
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
log.setLevel(logging.DEBUG)
|
log.setLevel(logging.INFO)
|
||||||
formatter = logging.Formatter(
|
formatter = logging.Formatter(
|
||||||
"%(asctime)s \033[1m%(levelname)s\033[0m\033[0m %(message)s"
|
"%(asctime)s \033[1m%(levelname)s\033[0m\033[0m %(message)s"
|
||||||
)
|
)
|
||||||
|
|
@ -3,11 +3,19 @@ from typing import Dict, List, Optional
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
import sys
|
import sys
|
||||||
from logger import log
|
from logger import log
|
||||||
from fuzzywuzzy import process
|
from finger_count import *
|
||||||
|
from playsound import playsound
|
||||||
|
import wave
|
||||||
|
from piper import PiperVoice
|
||||||
|
import os
|
||||||
|
from art import *
|
||||||
|
from translation import *
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class Player:
|
class Player:
|
||||||
name: str
|
name: str
|
||||||
|
alias: str
|
||||||
role: str
|
role: str
|
||||||
alive: bool = True
|
alive: bool = True
|
||||||
protected: bool = False
|
protected: bool = False
|
||||||
|
|
@ -26,6 +34,8 @@ class Game:
|
||||||
|
|
||||||
# Used potions
|
# Used potions
|
||||||
self.used_potions: [list[str]] = []
|
self.used_potions: [list[str]] = []
|
||||||
|
# Language
|
||||||
|
self.language: str = "fr"
|
||||||
# -------------------------
|
# -------------------------
|
||||||
# setup / I/O
|
# setup / I/O
|
||||||
# -------------------------
|
# -------------------------
|
||||||
|
|
@ -36,7 +46,7 @@ class Game:
|
||||||
"""
|
"""
|
||||||
players_file = "players.txt"
|
players_file = "players.txt"
|
||||||
roles_file = "roles.txt"
|
roles_file = "roles.txt"
|
||||||
|
words_file = "randoms_words.txt"
|
||||||
log.info("Loading lists...")
|
log.info("Loading lists...")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|
@ -53,20 +63,29 @@ class Game:
|
||||||
log.critical("Roles file not found: %s", roles_file)
|
log.critical("Roles file not found: %s", roles_file)
|
||||||
return None
|
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!")
|
log.info("Load complete!")
|
||||||
|
|
||||||
return {"players": player_names, "roles": roles_list}
|
return {"players": player_names, "roles": roles_list, "alias": alias_list}
|
||||||
|
|
||||||
# -------------------------
|
# -------------------------
|
||||||
# player / role assignment
|
# player / role assignment
|
||||||
# -------------------------
|
# -------------------------
|
||||||
def give_roles_to_players(self, player_names: Optional[List[str]] = None,
|
def give_roles_to_players(self, player_names: Optional[List[str]] = None,
|
||||||
roles_list: Optional[List[str]] = None) -> None:
|
roles_list: Optional[List[str]] = None,
|
||||||
|
alias_list: Optional[List[str]] = None) -> None:
|
||||||
"""
|
"""
|
||||||
Assign a random role to each player. Accepts optional lists (returned by load_lists).
|
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.
|
If lists are not supplied, it will attempt to read files itself.
|
||||||
"""
|
"""
|
||||||
|
number = 0
|
||||||
if not player_names:
|
if not player_names:
|
||||||
log.info("Players are not initialized")
|
log.info("Players are not initialized")
|
||||||
return
|
return
|
||||||
|
|
@ -77,16 +96,59 @@ class Game:
|
||||||
log.error("Not enough roles for players (roles: %d, players: %d)",
|
log.error("Not enough roles for players (roles: %d, players: %d)",
|
||||||
len(roles_list), len(player_names))
|
len(roles_list), len(player_names))
|
||||||
return
|
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)
|
available_roles = list(roles_list)
|
||||||
random.shuffle(available_roles)
|
random.shuffle(available_roles)
|
||||||
|
available_alias = list(alias_list)
|
||||||
|
random.shuffle(alias_list)
|
||||||
|
|
||||||
# clear any existing players (safe to reassign)
|
# clear any existing players (safe to reassign)
|
||||||
self.players.clear()
|
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:
|
for name in player_names:
|
||||||
chosen_role = available_roles.pop()
|
chosen_role = available_roles.pop()
|
||||||
self.players[name] = Player(name=name, role=chosen_role)
|
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")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
log.debug("Assigned roles:")
|
log.debug("Assigned roles:")
|
||||||
for player in self.players.values():
|
for player in self.players.values():
|
||||||
|
|
@ -95,56 +157,90 @@ class Game:
|
||||||
# -------------------------
|
# -------------------------
|
||||||
# utilities
|
# 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]:
|
def select_someone(self, prompt: Optional[str] = None) -> Optional[str]:
|
||||||
"""
|
"""
|
||||||
Prompt the user to enter a player name until a valid one is entered.
|
Prompt the user to enter a player name until a valid one is entered.
|
||||||
Returns None on EOF/KeyboardInterrupt.
|
Returns None on EOF/KeyboardInterrupt.
|
||||||
"""
|
"""
|
||||||
prompt = prompt or "Enter the name of the player: "
|
prompt = prompt or "show_number"
|
||||||
|
#self.play_sound("prompts", prompt)
|
||||||
while True:
|
while True:
|
||||||
selected = input(prompt).strip()
|
selected = count_fingers()
|
||||||
|
|
||||||
# exact match
|
# exact match
|
||||||
if selected in self.players:
|
if selected in self.players:
|
||||||
return selected
|
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):
|
def choose_between(self, options):
|
||||||
#Prompt the user to choose between options until a valid one is entered
|
#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)])
|
||||||
options_available = ', '.join(map(str, options))
|
log.info(f"Choose between {numbered_options}:")
|
||||||
#Make a prompt with a list of options, accepting either a list or a tuple.
|
|
||||||
prompt = f"Choose between {options_available}: "
|
|
||||||
while True:
|
while True:
|
||||||
selected = input(prompt)
|
selected = count_fingers()
|
||||||
|
try:
|
||||||
if selected in options:
|
index = int(selected) - 1
|
||||||
return selected
|
if 0 <= index < len(options):
|
||||||
|
chosen_option = options[index]
|
||||||
# fuzzy matching
|
log.debug("You chose %s!", chosen_option)
|
||||||
match = process.extract(selected, options, limit=1)
|
return chosen_option
|
||||||
log.debug(match)
|
else:
|
||||||
if match:
|
log.warning("Invalid number entered.")
|
||||||
fuzz_option, fuzz_score = match[0][0], match[0][1] #options, score
|
except ValueError:
|
||||||
log.debug(fuzz_option)
|
log.warning("Invalid input. Please enter an option or number.")
|
||||||
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
|
# game actions
|
||||||
# -------------------------
|
# -------------------------
|
||||||
|
|
@ -156,7 +252,7 @@ class Game:
|
||||||
|
|
||||||
self.lovers = (player1, player2)
|
self.lovers = (player1, player2)
|
||||||
|
|
||||||
log.debug("Players now put in love: %s <-> %s", player1, player2)
|
log.debug("Players now put in love: %s <-> %s", self.players[player1], self.players[player2])
|
||||||
|
|
||||||
log.info("They are now bounded by love.")
|
log.info("They are now bounded by love.")
|
||||||
log.info("They wake up and reveal their role to each other.")
|
log.info("They wake up and reveal their role to each other.")
|
||||||
|
|
@ -220,21 +316,22 @@ class Game:
|
||||||
log.debug("%s -> role: %s, alive: %s, Protected: %s",
|
log.debug("%s -> role: %s, alive: %s, Protected: %s",
|
||||||
p.name, p.role, p.alive, p.protected)
|
p.name, p.role, p.alive, p.protected)
|
||||||
# lovers
|
# lovers
|
||||||
log.debug("Lovers: %s" % ",".join(self.lovers))
|
log.debug(f"Lovers: {self.lovers}")
|
||||||
|
|
||||||
def role(func):
|
def role(func):
|
||||||
"""Decorator for roles"""
|
"""Decorator for roles"""
|
||||||
def wrapper(*args, **kwargs):
|
def wrapper(self, *args, **kwargs):
|
||||||
# the role is the name of the function thats decorated
|
# the role is the name of the function thats decorated
|
||||||
role = func.__name__.capitalize()
|
role = func.__name__.capitalize()
|
||||||
log.info("%s wakes up." % role)
|
os.system('clear')
|
||||||
func(*args, **kwargs)
|
if role in self.get_remaining_roles():
|
||||||
log.info("%s goes back to sleep." % role)
|
self.play_sound("roles", role)
|
||||||
|
self.play_sound("prompts", "wakes")
|
||||||
# workaround to call status from the instance
|
func(self, *args, **kwargs)
|
||||||
# is it ok? no idea but i dont have self anyway
|
self.play_sound("roles", role)
|
||||||
instance = args[0]
|
self.play_sound("prompts", "sleep_again")
|
||||||
instance.status()
|
log.INFO("%s goes back to sleep." % role)
|
||||||
|
self.status()
|
||||||
|
|
||||||
return wrapper
|
return wrapper
|
||||||
|
|
||||||
|
|
@ -245,12 +342,12 @@ class Game:
|
||||||
@role
|
@role
|
||||||
def cupidon(self) -> None:
|
def cupidon(self) -> None:
|
||||||
"""Interactively pick two players to link by love."""
|
"""Interactively pick two players to link by love."""
|
||||||
log.info("Choose two people to be linked to death.")
|
self.play_sound("prompts", "linked_death")
|
||||||
log.info("Give me the first person that shall be bounded!")
|
self.play_sound("prompts", "first_bound")
|
||||||
p1 = self.select_someone()
|
p1 = self.select_someone()
|
||||||
if p1 is None:
|
if p1 is None:
|
||||||
return
|
return
|
||||||
log.info("What about the second one?")
|
self.play_sound("prompts", "second_bound")
|
||||||
p2 = self.select_someone()
|
p2 = self.select_someone()
|
||||||
if p2 is None:
|
if p2 is None:
|
||||||
return
|
return
|
||||||
|
|
@ -262,21 +359,23 @@ class Game:
|
||||||
@role
|
@role
|
||||||
def savior(self) -> None:
|
def savior(self) -> None:
|
||||||
"""Interactively choose someone to protect."""
|
"""Interactively choose someone to protect."""
|
||||||
log.info("Choose someone to protect.")
|
self.play_sound("prompts", "choose_protect")
|
||||||
protected = self.select_someone()
|
protected = self.select_someone()
|
||||||
if protected is None:
|
if protected is None:
|
||||||
return
|
return
|
||||||
|
|
||||||
self.players[protected].protected = True
|
self.players[protected].protected = True
|
||||||
log.debug("Protected: %s", protected)
|
log.debug("Protected: %s", protected)
|
||||||
|
|
||||||
@role
|
@role
|
||||||
def witch(self) -> None:
|
def witch(self) -> None:
|
||||||
"""Interactively choose to kill or revive someone"""
|
"""Interactively choose to kill or revive someone"""
|
||||||
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.")
|
self.play_sound("prompts", "potions_choice")
|
||||||
log.info("Players who might die are %s", ' '.join(map(str, self.dead_this_night)))
|
self.play_sound("prompts", "might_die")
|
||||||
|
for player in self.dead_this_night:
|
||||||
|
self.show_text(self.players[player].name)
|
||||||
if len(self.used_potions) >= 2:
|
if len(self.used_potions) >= 2:
|
||||||
log.info("You already used all of your potions. ")
|
self.show_text("Vous avez utilisé toutes vos potions. ")
|
||||||
|
time.sleep(5)
|
||||||
else:
|
else:
|
||||||
while True:
|
while True:
|
||||||
options = ("Death", "Revive", "Nothing")
|
options = ("Death", "Revive", "Nothing")
|
||||||
|
|
@ -288,9 +387,9 @@ class Game:
|
||||||
self.revive(player)
|
self.revive(player)
|
||||||
return
|
return
|
||||||
elif player not in self.dead_this_night and not self.players[player].alive:
|
elif player not in self.dead_this_night and not self.players[player].alive:
|
||||||
log.info("You cannot bring this person back to life because they have been buried.")
|
self.show_text("Tu ne peux pas faire revivre cette personne.")
|
||||||
elif self.players[player].alive:
|
elif self.players[player].alive:
|
||||||
log.info("This player is not dead.")
|
self.show_text("Cette personne n'est pas morte.")
|
||||||
else:
|
else:
|
||||||
log.info("Unknown error: Invalid player choice")
|
log.info("Unknown error: Invalid player choice")
|
||||||
return
|
return
|
||||||
|
|
@ -299,14 +398,15 @@ class Game:
|
||||||
if self.players[player].alive:
|
if self.players[player].alive:
|
||||||
self.used_potions.append("Death")
|
self.used_potions.append("Death")
|
||||||
self.kill(player)
|
self.kill(player)
|
||||||
|
time.sleep(1)
|
||||||
return
|
return
|
||||||
elif not self.players[player].alive:
|
elif not self.players[player].alive:
|
||||||
log.info("This player is already dead.")
|
self.show_text("Ce joueur est déjà mort.")
|
||||||
else:
|
else:
|
||||||
log.info("Unknown error: Invalid player choice")
|
log.info("Unknown error: Invalid player choice")
|
||||||
return
|
return
|
||||||
elif potionchoice == "Nothing":
|
elif potionchoice == "Nothing":
|
||||||
log.info("You are not doing anything tonight.")
|
self.show_text("Vous ne faites rien cette nuit.")
|
||||||
return
|
return
|
||||||
elif potionchoice in self.used_potions:
|
elif potionchoice in self.used_potions:
|
||||||
log.info("You already used this potion.")
|
log.info("You already used this potion.")
|
||||||
|
|
@ -315,7 +415,7 @@ class Game:
|
||||||
return
|
return
|
||||||
@role
|
@role
|
||||||
def werewolf(self) -> None:
|
def werewolf(self) -> None:
|
||||||
log.info("You will choose someone to kill.")
|
self.play_sound("prompts", "werewolf_choice")
|
||||||
player = self.select_someone()
|
player = self.select_someone()
|
||||||
self.kill(player)
|
self.kill(player)
|
||||||
|
|
||||||
|
|
@ -325,21 +425,56 @@ class Game:
|
||||||
while True:
|
while True:
|
||||||
player = self.select_someone()
|
player = self.select_someone()
|
||||||
if "Seer" == self.players[player].role:
|
if "Seer" == self.players[player].role:
|
||||||
log.info("You can't see your own role.")
|
self.show_text("You can't see your own role.")
|
||||||
else:
|
else:
|
||||||
log.info(f"{player} is a {self.players[player].role}")
|
self.show_text(self.players[player].role)
|
||||||
|
time.sleep(3)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@role
|
||||||
|
def hunter(self) -> None:
|
||||||
|
self.play_sound("prompts", "hunter")
|
||||||
|
player = self.select_someone()
|
||||||
|
self.kill(player)
|
||||||
|
|
||||||
# -------------------------
|
# -------------------------
|
||||||
# game flow
|
# game flow
|
||||||
# -------------------------
|
# -------------------------
|
||||||
def first_day_cycle(self) -> None:
|
def first_night_cycle(self) -> None:
|
||||||
log.info("All the villagers fall asleep.")
|
self.play_sound("prompts", "fall_asleep_all")
|
||||||
self.cupidon()
|
self.cupidon()
|
||||||
|
self.couple()
|
||||||
self.savior()
|
self.savior()
|
||||||
self.werewolf()
|
self.werewolf()
|
||||||
self.witch()
|
self.witch()
|
||||||
self.seer()
|
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()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -354,8 +489,8 @@ if __name__ == "__main__":
|
||||||
try:
|
try:
|
||||||
if loaded:
|
if loaded:
|
||||||
# start the game!
|
# start the game!
|
||||||
game.give_roles_to_players(loaded["players"], loaded["roles"])
|
game.give_roles_to_players(loaded["players"], loaded["roles"], loaded["alias"])
|
||||||
game.first_day_cycle()
|
game.first_night_cycle()
|
||||||
|
|
||||||
# CTRL+C
|
# CTRL+C
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
|
|
@ -1,10 +1,6 @@
|
||||||
Marie
|
Anavoi
|
||||||
Jeanne
|
|
||||||
Paul
|
|
||||||
Jean
|
Jean
|
||||||
Michel
|
Paul
|
||||||
Christophe
|
Christophe
|
||||||
Anne
|
Jeanne
|
||||||
Julien
|
Julien
|
||||||
Aurélie
|
|
||||||
Yoxu
|
|
||||||
11
werewoolf/randoms_words.txt
Normal file
11
werewoolf/randoms_words.txt
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
Abricot
|
||||||
|
Pomme
|
||||||
|
Fraise
|
||||||
|
Melon
|
||||||
|
Orange
|
||||||
|
Framboise
|
||||||
|
Cerise
|
||||||
|
Citron
|
||||||
|
Poire
|
||||||
|
Raisin
|
||||||
|
Prune
|
||||||
7
werewoolf/requirements.txt
Normal file
7
werewoolf/requirements.txt
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
fuzzywuzzy==0.18.0
|
||||||
|
opencv_python
|
||||||
|
mediapipe
|
||||||
|
piper-tts
|
||||||
|
playsound
|
||||||
|
art
|
||||||
|
pygobject
|
||||||
10
werewoolf/roles.txt
Normal file
10
werewoolf/roles.txt
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
Werewolf
|
||||||
|
Seer
|
||||||
|
Witch
|
||||||
|
Grandchild
|
||||||
|
Hunter
|
||||||
|
Werewolf
|
||||||
|
Werewolf
|
||||||
|
Villager
|
||||||
|
Cupidon
|
||||||
|
Villager
|
||||||
10
werewoolf/translation.py
Normal file
10
werewoolf/translation.py
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
FR = {
|
||||||
|
"Seer": "Voyante",
|
||||||
|
"Werewolf": "Loups-Garous",
|
||||||
|
"Witch": "Sorciere",
|
||||||
|
"Cupidon": "Cupidon",
|
||||||
|
"Savior": "Salvateur",
|
||||||
|
"Villager": "Villageois",
|
||||||
|
"Grandchild": "Petite-Fille",
|
||||||
|
"Hunter": "Chasseur"
|
||||||
|
}
|
||||||
BIN
werewoolf/voices/fr/fr_FR-tom-medium.onnx
Normal file
BIN
werewoolf/voices/fr/fr_FR-tom-medium.onnx
Normal file
Binary file not shown.
502
werewoolf/voices/fr/fr_FR-tom-medium.onnx.json
Normal file
502
werewoolf/voices/fr/fr_FR-tom-medium.onnx.json
Normal file
|
|
@ -0,0 +1,502 @@
|
||||||
|
{
|
||||||
|
"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"
|
||||||
|
}
|
||||||
BIN
werewoolf/voicesline/prompts/en/bound.wav
Normal file
BIN
werewoolf/voicesline/prompts/en/bound.wav
Normal file
Binary file not shown.
BIN
werewoolf/voicesline/prompts/en/choose_protect.wav
Normal file
BIN
werewoolf/voicesline/prompts/en/choose_protect.wav
Normal file
Binary file not shown.
BIN
werewoolf/voicesline/prompts/en/fall_asleep_all.wav
Normal file
BIN
werewoolf/voicesline/prompts/en/fall_asleep_all.wav
Normal file
Binary file not shown.
BIN
werewoolf/voicesline/prompts/en/first_bound.wav
Normal file
BIN
werewoolf/voicesline/prompts/en/first_bound.wav
Normal file
Binary file not shown.
BIN
werewoolf/voicesline/prompts/en/hunter.wav
Normal file
BIN
werewoolf/voicesline/prompts/en/hunter.wav
Normal file
Binary file not shown.
BIN
werewoolf/voicesline/prompts/en/linked_death.wav
Normal file
BIN
werewoolf/voicesline/prompts/en/linked_death.wav
Normal file
Binary file not shown.
BIN
werewoolf/voicesline/prompts/en/lovers.wav
Normal file
BIN
werewoolf/voicesline/prompts/en/lovers.wav
Normal file
Binary file not shown.
BIN
werewoolf/voicesline/prompts/en/might_die.wav
Normal file
BIN
werewoolf/voicesline/prompts/en/might_die.wav
Normal file
Binary file not shown.
BIN
werewoolf/voicesline/prompts/en/night_deaths.wav
Normal file
BIN
werewoolf/voicesline/prompts/en/night_deaths.wav
Normal file
Binary file not shown.
BIN
werewoolf/voicesline/prompts/en/now_show_number.wav
Normal file
BIN
werewoolf/voicesline/prompts/en/now_show_number.wav
Normal file
Binary file not shown.
BIN
werewoolf/voicesline/prompts/en/potions_choice.wav
Normal file
BIN
werewoolf/voicesline/prompts/en/potions_choice.wav
Normal file
Binary file not shown.
BIN
werewoolf/voicesline/prompts/en/reveal.wav
Normal file
BIN
werewoolf/voicesline/prompts/en/reveal.wav
Normal file
Binary file not shown.
BIN
werewoolf/voicesline/prompts/en/second_bound.wav
Normal file
BIN
werewoolf/voicesline/prompts/en/second_bound.wav
Normal file
Binary file not shown.
BIN
werewoolf/voicesline/prompts/en/sleep.wav
Normal file
BIN
werewoolf/voicesline/prompts/en/sleep.wav
Normal file
Binary file not shown.
BIN
werewoolf/voicesline/prompts/en/sleep_again.wav
Normal file
BIN
werewoolf/voicesline/prompts/en/sleep_again.wav
Normal file
Binary file not shown.
BIN
werewoolf/voicesline/prompts/en/village_vote.wav
Normal file
BIN
werewoolf/voicesline/prompts/en/village_vote.wav
Normal file
Binary file not shown.
BIN
werewoolf/voicesline/prompts/en/wake_up_all.wav
Normal file
BIN
werewoolf/voicesline/prompts/en/wake_up_all.wav
Normal file
Binary file not shown.
BIN
werewoolf/voicesline/prompts/en/wakes.wav
Normal file
BIN
werewoolf/voicesline/prompts/en/wakes.wav
Normal file
Binary file not shown.
BIN
werewoolf/voicesline/prompts/en/werewolf_choice.wav
Normal file
BIN
werewoolf/voicesline/prompts/en/werewolf_choice.wav
Normal file
Binary file not shown.
BIN
werewoolf/voicesline/prompts/fr/bound.wav
Normal file
BIN
werewoolf/voicesline/prompts/fr/bound.wav
Normal file
Binary file not shown.
BIN
werewoolf/voicesline/prompts/fr/cheater.wav
Normal file
BIN
werewoolf/voicesline/prompts/fr/cheater.wav
Normal file
Binary file not shown.
BIN
werewoolf/voicesline/prompts/fr/choose_protect.wav
Normal file
BIN
werewoolf/voicesline/prompts/fr/choose_protect.wav
Normal file
Binary file not shown.
BIN
werewoolf/voicesline/prompts/fr/fall_asleep_all.wav
Normal file
BIN
werewoolf/voicesline/prompts/fr/fall_asleep_all.wav
Normal file
Binary file not shown.
BIN
werewoolf/voicesline/prompts/fr/first_bound.wav
Normal file
BIN
werewoolf/voicesline/prompts/fr/first_bound.wav
Normal file
Binary file not shown.
BIN
werewoolf/voicesline/prompts/fr/first_wakes.wav
Normal file
BIN
werewoolf/voicesline/prompts/fr/first_wakes.wav
Normal file
Binary file not shown.
BIN
werewoolf/voicesline/prompts/fr/hunter.wav
Normal file
BIN
werewoolf/voicesline/prompts/fr/hunter.wav
Normal file
Binary file not shown.
BIN
werewoolf/voicesline/prompts/fr/linked_death.wav
Normal file
BIN
werewoolf/voicesline/prompts/fr/linked_death.wav
Normal file
Binary file not shown.
BIN
werewoolf/voicesline/prompts/fr/lovers.wav
Normal file
BIN
werewoolf/voicesline/prompts/fr/lovers.wav
Normal file
Binary file not shown.
BIN
werewoolf/voicesline/prompts/fr/might_die.wav
Normal file
BIN
werewoolf/voicesline/prompts/fr/might_die.wav
Normal file
Binary file not shown.
BIN
werewoolf/voicesline/prompts/fr/night_deaths.wav
Normal file
BIN
werewoolf/voicesline/prompts/fr/night_deaths.wav
Normal file
Binary file not shown.
BIN
werewoolf/voicesline/prompts/fr/now_show_number.wav
Normal file
BIN
werewoolf/voicesline/prompts/fr/now_show_number.wav
Normal file
Binary file not shown.
BIN
werewoolf/voicesline/prompts/fr/potions_choice.wav
Normal file
BIN
werewoolf/voicesline/prompts/fr/potions_choice.wav
Normal file
Binary file not shown.
BIN
werewoolf/voicesline/prompts/fr/reveal.wav
Normal file
BIN
werewoolf/voicesline/prompts/fr/reveal.wav
Normal file
Binary file not shown.
BIN
werewoolf/voicesline/prompts/fr/second_bound.wav
Normal file
BIN
werewoolf/voicesline/prompts/fr/second_bound.wav
Normal file
Binary file not shown.
BIN
werewoolf/voicesline/prompts/fr/sleep.wav
Normal file
BIN
werewoolf/voicesline/prompts/fr/sleep.wav
Normal file
Binary file not shown.
BIN
werewoolf/voicesline/prompts/fr/sleep_again.wav
Normal file
BIN
werewoolf/voicesline/prompts/fr/sleep_again.wav
Normal file
Binary file not shown.
BIN
werewoolf/voicesline/prompts/fr/village_vote.wav
Normal file
BIN
werewoolf/voicesline/prompts/fr/village_vote.wav
Normal file
Binary file not shown.
BIN
werewoolf/voicesline/prompts/fr/wake_up_all.wav
Normal file
BIN
werewoolf/voicesline/prompts/fr/wake_up_all.wav
Normal file
Binary file not shown.
BIN
werewoolf/voicesline/prompts/fr/wakes.wav
Normal file
BIN
werewoolf/voicesline/prompts/fr/wakes.wav
Normal file
Binary file not shown.
BIN
werewoolf/voicesline/prompts/fr/werewolf_choice.wav
Normal file
BIN
werewoolf/voicesline/prompts/fr/werewolf_choice.wav
Normal file
Binary file not shown.
BIN
werewoolf/voicesline/roles/en/Cupidon.wav
Normal file
BIN
werewoolf/voicesline/roles/en/Cupidon.wav
Normal file
Binary file not shown.
BIN
werewoolf/voicesline/roles/en/Hunter.wav
Normal file
BIN
werewoolf/voicesline/roles/en/Hunter.wav
Normal file
Binary file not shown.
BIN
werewoolf/voicesline/roles/en/Savior.wav
Normal file
BIN
werewoolf/voicesline/roles/en/Savior.wav
Normal file
Binary file not shown.
BIN
werewoolf/voicesline/roles/en/Seer.wav
Normal file
BIN
werewoolf/voicesline/roles/en/Seer.wav
Normal file
Binary file not shown.
BIN
werewoolf/voicesline/roles/en/Werewolf.wav
Normal file
BIN
werewoolf/voicesline/roles/en/Werewolf.wav
Normal file
Binary file not shown.
BIN
werewoolf/voicesline/roles/en/Witch.wav
Normal file
BIN
werewoolf/voicesline/roles/en/Witch.wav
Normal file
Binary file not shown.
BIN
werewoolf/voicesline/roles/fr/Cupidon.wav
Normal file
BIN
werewoolf/voicesline/roles/fr/Cupidon.wav
Normal file
Binary file not shown.
BIN
werewoolf/voicesline/roles/fr/Hunter.wav
Normal file
BIN
werewoolf/voicesline/roles/fr/Hunter.wav
Normal file
Binary file not shown.
BIN
werewoolf/voicesline/roles/fr/Savior.wav
Normal file
BIN
werewoolf/voicesline/roles/fr/Savior.wav
Normal file
Binary file not shown.
BIN
werewoolf/voicesline/roles/fr/Seer.wav
Normal file
BIN
werewoolf/voicesline/roles/fr/Seer.wav
Normal file
Binary file not shown.
BIN
werewoolf/voicesline/roles/fr/Werewolf.wav
Normal file
BIN
werewoolf/voicesline/roles/fr/Werewolf.wav
Normal file
Binary file not shown.
BIN
werewoolf/voicesline/roles/fr/Witch.wav
Normal file
BIN
werewoolf/voicesline/roles/fr/Witch.wav
Normal file
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue