import random
import time
from colorama import init, Fore, Style

# Initialize colorama for colored console output
init()

class Item:
    def __init__(self, nom, rarete, valeur, type_objet="général", stats=None, durabilite=None):
        self.nom = nom
        self.rarete = rarete
        self.valeur = valeur
        self.type_objet = type_objet
        self.stats = stats
        self.durabilite = durabilite
        self.durabilite_max = durabilite

    def __str__(self):
        details = f"{Fore.GREEN}{self.nom}{Style.RESET_ALL} (Rareté: {self.rarete}, Valeur: {self.valeur} pièces)"
        if self.type_objet == "arme":
            details += f" - Dégâts: {self.stats[0]}-{self.stats[1]}, Durabilité: {self.durabilite}/{self.durabilite_max}"
        elif self.type_objet == "armure":
            details += f" - Protection: {self.stats}%, Durabilité: {self.durabilite}/{self.durabilite_max}"
        elif self.type_objet == "nourriture":
            details += f" - Restauration de nourriture: {self.stats} points"
        elif self.type_objet == "boisson":
            details += f" - Restauration de soif: {self.stats} points"
        elif self.type_objet == "appat":
            details += f" - Rareté des poissons: {self.rarete}"
        return details

class Joueur:
    def __init__(self, nom):
        self.nom = nom
        self.niveau = 1
        self.niveau_max = 100
        self.force = 10
        self.sante = 100
        self.experience = 0
        self.experience_max = 100
        self.sante_max = 100
        self.nourriture = 100
        self.nourriture_max = 100
        self.soif = 100
        self.soif_max = 100
        self.argent = 1000
        self.inventaire = []
        self.armure = None
        self.arme = None
        self.paralyse = False
        self.poison = False
        self.buff_force = 1.0
        self.regen_par_combat = 0
        self.combats_restants_force = 0
        self.combats_restants_regen = 0
        self.quetes = []

    def attaquer(self, monstre):
        if self.poison:
            self.subir_poison()
        if self.paralyse:
            self.soigner_paralyse()
            if self.paralyse:
                print(f"{Fore.RED}{self.nom} est paralysé et ne peut pas attaquer !{Style.RESET_ALL}")
                return
        if self.arme:
            degats = random.randint(*self.arme.stats)
            chance_critique = 0.23
            if random.random() < chance_critique:
                degats *= 2
                print(f"{Fore.YELLOW}Coup critique !{Style.RESET_ALL}")
            self.arme.durabilite -= 0.5
            if self.arme.durabilite <= 0:
                print(f"{Fore.RED}{self.arme.nom} est cassée !{Style.RESET_ALL}")
                self.arme = None
        else:
            degats = random.randint(5, 10) + self.force

        degats = int(degats * self.buff_force)
        monstre.sante -= degats
        print(f"{Fore.CYAN}{self.nom} attaque {monstre.nom} pour {degats} dégâts !{Style.RESET_ALL}")

        if self.combats_restants_force > 0:
            self.combats_restants_force -= 1
            if self.combats_restants_force == 0:
                self.buff_force = 1.0
                print(f"{Fore.BLUE}Le buff de force de {self.nom} a expiré.{Style.RESET_ALL}")

        if self.combats_restants_regen > 0:
            self.sante += self.regen_par_combat
            if self.sante > self.sante_max:
                self.sante = self.sante_max
            print(f"{Fore.GREEN}{self.nom} régénère {self.regen_par_combat} points de santé.{Style.RESET_ALL}")
            self.combats_restants_regen -= 1

        if monstre.sante <= 0:
            self.verifier_quetes(monstre)

    def utiliser_objet(self, choix):
        if 0 <= choix < len(self.inventaire):
            item = self.inventaire.pop(choix)
            if item.nom == "Potion de Soin":
                self.sante += 50
                if self.sante > self.sante_max:
                    self.sante = self.sante_max
                print(f"{Fore.GREEN}{self.nom} utilise une {item.nom} et récupère 50 points de santé.{Style.RESET_ALL}")
            elif item.nom == "Potion de Force":
                self.buff_force = 1.14
                self.combats_restants_force = 10
                print(f"{Fore.YELLOW}{self.nom} utilise une {item.nom}, ses dégâts augmentent de 14% pour 10 combats.{Style.RESET_ALL}")
            elif item.nom == "Potion de Régénération":
                self.regen_par_combat = 20
                self.combats_restants_regen = 10
                print(f"{Fore.GREEN}{self.nom} utilise une {item.nom}, régénère 20 points de santé par combat pour 10 combats.{Style.RESET_ALL}")
            elif item.nom == "Anti-Para":
                self.paralyse = False
                print(f"{Fore.BLUE}{self.nom} utilise un {item.nom} et guérit de la paralysie.{Style.RESET_ALL}")
            elif item.nom == "Antidote":
                self.poison = False
                print(f"{Fore.BLUE}{self.nom} utilise un {item.nom} et guérit du poison.{Style.RESET_ALL}")
            elif item.nom == "Eau":
                self.boire(item.stats)
            elif item.type_objet == "nourriture":
                self.manger(item.stats)
            self.verifier_quetes(item=item)

    def est_vivant(self):
        return self.sante > 0

    def ajouter_objet(self, loot):
        if isinstance(loot, list):
            for item in loot:
                self.inventaire.append(item)
                print(f"{Fore.GREEN}{self.nom} a obtenu un nouvel objet : {item}{Style.RESET_ALL}")
                self.verifier_quetes(item=item)
        else:
            self.inventaire.append(loot)
            print(f"{Fore.GREEN}{self.nom} a obtenu un nouvel objet : {loot}{Style.RESET_ALL}")
            self.verifier_quetes(item=loot)

    def afficher_stats(self):
        print(f"\n{Fore.MAGENTA}╔════ Stats de {self.nom} ════╗{Style.RESET_ALL}")
        print(f"║ Niveau: {self.niveau} | Santé: {self.sante}/{self.sante_max} | Force: {self.force}")
        print(f"║ Expérience: {self.experience}/{self.experience_max}")
        print(f"║ Nourriture: {self.nourriture}/{self.nourriture_max} | Soif: {self.soif}/{self.soif_max}")
        print(f"║ Argent: {self.argent} pièces")
        if self.arme:
            print(f"║ Arme équipée: {self.arme}")
        if self.armure:
            print(f"║ Armure équipée: {self.armure}")
        print(f"╚═════════════════════════════╝{Style.RESET_ALL}")

    def voir_inventaire(self):
        if self.inventaire:
            print(f"\n{Fore.MAGENTA}╔════ Filtres Inventaire ════╗{Style.RESET_ALL}")
            print("║ 1. Tous     2. Armes")
            print("║ 3. Armures  4. Nourriture")
            print(f"║ 5. Boissons 6. Appâts{Style.RESET_ALL}")
            filtre = input("Choisissez un filtre (1-6) : ")

            filtered = {
                '1': self.inventaire,
                '2': [i for i in self.inventaire if i.type_objet == "arme"],
                '3': [i for i in self.inventaire if i.type_objet == "armure"],
                '4': [i for i in self.inventaire if i.type_objet == "nourriture"],
                '5': [i for i in self.inventaire if i.type_objet == "boisson"],
                '6': [i for i in self.inventaire if i.type_objet == "appat"]
            }.get(filtre, self.inventaire)

            print(f"\n{Fore.MAGENTA}╔════ Inventaire ({len(filtered)} objets) ════╗{Style.RESET_ALL}")
            for i, item in enumerate(filtered):
                print(f"║ {i+1}. {item}")
            print(f"╚══════════════════════════════════╝{Style.RESET_ALL}")
            try:
                item_choix = int(input("\nChoisissez un objet à utiliser ou équiper (ou 0 pour quitter) : ")) - 1
                if item_choix >= 0:
                    item = self.inventaire[item_choix]
                    if item.type_objet in ["arme", "armure"]:
                        self.equiper_objet(item_choix)
                    else:
                        self.utiliser_objet(item_choix)
            except ValueError:
                print(f"{Fore.RED}Entrée invalide.{Style.RESET_ALL}")
        else:
            print(f"{Fore.RED}{self.nom} n'a aucun objet dans son inventaire.{Style.RESET_ALL}")

    def soigner_paralyse(self):
        for item in self.inventaire:
            if item.nom == "Anti-Para" and self.paralyse:
                self.paralyse = False
                print(f"{Fore.BLUE}{self.nom} a utilisé automatiquement l'{item.nom} pour guérir de la paralysie.{Style.RESET_ALL}")
                self.inventaire.remove(item)
                break

    def manger(self, points):
        self.nourriture = min(self.nourriture_max, self.nourriture + points)
        print(f"{Fore.GREEN}{self.nom} a mangé. Nourriture actuelle : {self.nourriture}/{self.nourriture_max}.{Style.RESET_ALL}")
        self.verifier_quetes(item=Item("Nourriture", "Commun", 0, "nourriture"))

    def boire(self, points):
        self.soif = min(self.soif_max, self.soif + points)
        print(f"{Fore.GREEN}{self.nom} a bu. Soif actuelle : {self.soif}/{self.soif_max}.{Style.RESET_ALL}")

    def equiper_objet(self, choix):
        if 0 <= choix < len(self.inventaire):
            item = self.inventaire.pop(choix)
            if item.type_objet == "arme":
                self.arme = item
                print(f"{Fore.YELLOW}{self.nom} a équipé l'arme : {item.nom}{Style.RESET_ALL}")
            elif item.type_objet == "armure":
                self.armure = item
                print(f"{Fore.YELLOW}{self.nom} a équipé l'armure : {item.nom}{Style.RESET_ALL}")
            else:
                print(f"{Fore.RED}{item.nom} n'est ni une arme ni une armure.{Style.RESET_ALL}")
                self.inventaire.append(item)
        else:
            print(f"{Fore.RED}Objet invalide.{Style.RESET_ALL}")

    def verifier_niveau(self):
        if self.experience >= self.experience_max:
            self.niveau += 1
            if self.niveau >= 100:
                self.experience_max = 100000
                print(f"{Fore.YELLOW}{self.nom} a atteint le niveau maximum de 100.{Style.RESET_ALL}")
            else:
                self.experience -= self.experience_max
                self.experience_max += 25
                self.force += 1
                self.sante_max += 5
                self.sante = self.sante_max
                print(f"\n{Fore.YELLOW}{self.nom} est monté au niveau {self.niveau} ! Force et santé augmentées !{Style.RESET_ALL}")

            if self.niveau % 10 == 0:
                print(f"{Fore.MAGENTA}Un nouveau boss est disponible au niveau {self.niveau} !{Style.RESET_ALL}")

    def voir_inventaire2(self):
        if self.inventaire:
            print(f"\n{Fore.MAGENTA}╔════ Inventaire de {self.nom} ════╗{Style.RESET_ALL}")
            for i, item in enumerate(self.inventaire):
                print(f"║ {i+1}. {item}")
            print(f"╚══════════════════════════════════╝{Style.RESET_ALL}")

    def subir_poison(self):
        if self.poison:
            degats_poison = 5
            self.sante -= degats_poison
            print(f"{Fore.RED}{self.nom} subit {degats_poison} dégâts à cause du poison !{Style.RESET_ALL}")
            if self.sante <= 0:
                print(f"{Fore.RED}{self.nom} est mort à cause du poison !{Style.RESET_ALL}")
                self.sante = 0

    def ajouter_quete(self, quete):
        if len(self.quetes) < 5:
            self.quetes.append(quete)
            print(f"{Fore.CYAN}Nouvelle quête ajoutée : {quete.nom}{Style.RESET_ALL}")
        else:
            print(f"{Fore.RED}Vous avez déjà 5 quêtes actives !{Style.RESET_ALL}")

    def verifier_quetes(self, monstre=None, item=None):
        for quete in self.quetes[:]:
            if quete.type == "tuer" and monstre and quete.cible == monstre.nom:
                quete.progression += 1
                print(f"{Fore.CYAN}Quête '{quete.nom}' : {quete.progression}/{quete.quantite} {quete.cible} tués.{Style.RESET_ALL}")
                if quete.progression >= quete.quantite:
                    quete.completer(self)
                    self.quetes.remove(quete)
            elif quete.type == "collecter" and item and quete.cible == item.nom:
                quete.progression += 1
                print(f"{Fore.CYAN}Quête '{quete.nom}' : {quete.progression}/{quete.quantite} {quete.cible} collectés.{Style.RESET_ALL}")
                if quete.progression >= quete.quantite:
                    quete.completer(self)
                    self.quetes.remove(quete)
            elif quete.type == "pecher" and item and item.type_objet == "nourriture":
                quete.progression += 1
                print(f"{Fore.CYAN}Quête '{quete.nom}' : {quete.progression}/{quete.quantite} poissons pêchés.{Style.RESET_ALL}")
                if quete.progression >= quete.quantite:
                    quete.completer(self)
                    self.quetes.remove(quete)
            elif quete.type == "manger" and item and item.type_objet == "nourriture":
                quete.progression += 1
                print(f"{Fore.CYAN}Quête '{quete.nom}' : {quete.progression}/{quete.quantite} nourriture mangée.{Style.RESET_ALL}")
                if quete.progression >= quete.quantite:
                    quete.completer(self)
                    self.quetes.remove(quete)
            elif quete.type == "depenser" and item:
                quete.progression += item.valeur
                print(f"{Fore.CYAN}Quête '{quete.nom}' : {quete.progression}/{quete.quantite} pièces dépensées.{Style.RESET_ALL}")
                if quete.progression >= quete.quantite:
                    quete.completer(self)
                    self.quetes.remove(quete)
            elif quete.type == "crafter" and item and item.nom == quete.cible:
                quete.progression += 1
                print(f"{Fore.CYAN}Quête '{quete.nom}' : {quete.progression}/{quete.quantite} {quete.cible} craftés.{Style.RESET_ALL}")
                if quete.progression >= quete.quantite:
                    quete.completer(self)
                    self.quetes.remove(quete)

    def craft_objet(self, recette):
        for item_nom in recette["ingredients"]:
            if not any(item.nom == item_nom for item in self.inventaire):
                print(f"{Fore.RED}Vous n'avez pas assez de {item_nom}.{Style.RESET_ALL}")
                return
        for item_nom in recette["ingredients"]:
            for item in self.inventaire:
                if item.nom == item_nom:
                    self.inventaire.remove(item)
                    break
        self.ajouter_objet(recette["resultat"])
        print(f"{Fore.YELLOW}Vous avez crafté : {recette['resultat'].nom}{Style.RESET_ALL}")

    def reparer_equipement(self):
        reparables = []
        if self.arme and self.arme.durabilite < self.arme.durabilite_max:
            reparables.append(self.arme)
        if self.armure and self.armure.durabilite < self.armure.durabilite_max:
            reparables.append(self.armure)
        for item in self.inventaire:
            if item.type_objet in ["arme", "armure"] and item.durabilite < item.durabilite_max:
                reparables.append(item)

        if not reparables:
            print(f"{Fore.RED}Aucun équipement à réparer.{Style.RESET_ALL}")
            return

        print(f"\n{Fore.MAGENTA}╔════ Réparer Équipement ════╗{Style.RESET_ALL}")
        for i, item in enumerate(reparables):
            cout = int((item.durabilite_max - item.durabilite) * 10)
            print(f"║ {i+1}. {item.nom} (Durabilité: {item.durabilite}/{item.durabilite_max}, Coût: {cout} pièces)")
        print(f"╚════════════════════════════╝{Style.RESET_ALL}")

        try:
            choix = int(input("\nChoisissez un équipement à réparer (ou 0 pour quitter) : ")) - 1
            if choix == -1:
                return
            if 0 <= choix < len(reparables):
                item = reparables[choix]
                cout = int((item.durabilite_max - item.durabilite) * 10)
                if self.argent >= cout:
                    self.argent -= cout
                    item.durabilite = item.durabilite_max
                    print(f"{Fore.GREEN}{item.nom} a été réparé pour {cout} pièces.{Style.RESET_ALL}")
                    self.verifier_quetes(item=Item("Réparation", "Commun", cout, "depenser"))
                else:
                    print(f"{Fore.RED}Vous n'avez pas assez d'argent !{Style.RESET_ALL}")
            else:
                print(f"{Fore.RED}Choix invalide.{Style.RESET_ALL}")
        except ValueError:
            print(f"{Fore.RED}Entrée invalide.{Style.RESET_ALL}")

class Monstre:
    def __init__(self, nom, force, sante, loot, peut_paralyser=False, peut_poison=False):
        self.nom = nom
        self.force = force
        self.sante = sante
        self.loot = loot
        self.peut_paralyser = peut_paralyser
        self.peut_poison = peut_poison

    def attaquer(self, joueur):
        degats = random.randint(5, self.force)
        if joueur.armure:
            protection = joueur.armure.stats / 100
            degats *= (1 - protection)
            degats = round(degats)
            joueur.armure.durabilite -= 0.5
            if joueur.armure.durabilite <= 0:
                print(f"{Fore.RED}L'armure {joueur.armure.nom} est détruite !{Style.RESET_ALL}")
                joueur.armure = None
        joueur.sante -= int(degats)
        print(f"{Fore.RED}{self.nom} attaque {joueur.nom} pour {degats} dégâts !{Style.RESET_ALL}")

        if self.peut_paralyser and random.random() < 0.2:
            joueur.paralyse = True
            print(f"{Fore.RED}{self.nom} a paralysé {joueur.nom} !{Style.RESET_ALL}")

        if not joueur.poison and self.peut_poison and random.random() < 0.9:
            joueur.poison = True
            print(f"{Fore.RED}{self.nom} a empoisonné {joueur.nom} !{Style.RESET_ALL}")

    def est_vivant(self):
        return self.sante > 0

class Boss:
    def __init__(self, nom, sante, force, loot, niveau_requis, peut_paralyser=False, peut_poison=False):
        self.nom = nom
        self.sante = sante
        self.sante_max = sante
        self.force = force
        self.loot = loot
        self.niveau_requis = niveau_requis
        self.peut_paralyser = peut_paralyser
        self.peut_poison = peut_poison
        self.vaincu = False

    def est_vivant(self):
        return self.sante > 0

    def attaquer(self, joueur):
        degats = self.force
        if joueur.armure:
            protection = joueur.armure.stats / 100
            degats *= (1 - protection)
            degats = round(degats)
        joueur.sante -= degats
        print(f"{Fore.RED}{self.nom} attaque {joueur.nom} et inflige {degats} points de dégâts !{Style.RESET_ALL}")

    def reset_stats(self, multiplicateur=1):
        self.force += multiplicateur
        self.sante = self.sante_max
        self.sante_max += 5 * multiplicateur
        self.vaincu = False

class Quete:
    def __init__(self, nom, type, cible, quantite, recompense):
        self.nom = nom
        self.type = type
        self.cible = cible
        self.quantite = quantite
        self.recompense = recompense
        self.progression = 0

    def completer(self, joueur):
        print(f"{Fore.YELLOW}Quête '{self.nom}' complétée !{Style.RESET_ALL}")
        if "argent" in self.recompense:
            joueur.argent += self.recompense["argent"]
            print(f"{Fore.GREEN}Récompense : {self.recompense['argent']} pièces.{Style.RESET_ALL}")
        if "experience" in self.recompense:
            joueur.experience += self.recompense["experience"]
            print(f"{Fore.GREEN}Récompense : {self.recompense['experience']} expérience.{Style.RESET_ALL}")
        if "item" in self.recompense:
            joueur.ajouter_objet(self.recompense["item"])
            print(f"{Fore.GREEN}Récompense : {self.recompense['item'].nom}.{Style.RESET_ALL}")
        joueur.verifier_niveau()

probabilites_rarete = {
    "Commun": 63.69,
    "Rare": 30,
    "Épique": 5,
    "Légendaire": 1,
    "Mythique": 0.1,
    "Immortel": 0.01
}

def generer_loot(possibles_items, quantite=1):
    loots = []
    for _ in range(quantite):
        total_prob = sum(probabilites_rarete[item.rarete] for item in possibles_items)
        tirage = random.uniform(0, total_prob)
        cumul = 0.0
        for item in possibles_items:
            cumul += probabilites_rarete[item.rarete]
            if tirage <= cumul:
                loots.append(item)
                break
    return loots

# Updated loot tables with unique items per monster
loot_gobelin = [
    Item("Épée de Gobelin", "Rare", 50, "arme", (7, 12), durabilite=10),
    Item("Masse Gobeline", "Commun", 50, "arme", (6, 11), durabilite=15),
    Item("Dague de Gobelin", "Rare", 50, "arme", (8, 13), durabilite=5),
    Item("Armure Gobeline", "Commun", 100, "armure", 5, durabilite=10),
    Item("Cotte Gobeline", "Rare", 30, "armure", 15, durabilite=5),
    Item("Casque de Gobelin", "Commun", 100, "armure", 2, durabilite=15),
    Item("Baie Sauvage", "Commun", 5, "nourriture", 10),
    Item("Bière de Gobelin", "Commun", 10, "boisson", 15),
    Item("Dent de Gobelin", "Commun", 10),
    Item("Peau de Gobelin", "Rare", 12),
    Item("Griffe de Gobelin", "Épique", 15)
]
loot_orc = [
    Item("Hache Orque", "Commun", 100, "arme", (10, 15), durabilite=20),
    Item("Marteau Orque", "Commun", 100, "arme", (12, 18), durabilite=18),
    Item("Cimeterre Orque", "Rare", 100, "arme", (15, 20), durabilite=15),
    Item("Plastron Orque", "Rare", 200, "armure", 10, durabilite=25),
    Item("Bouclier Orque", "Commun", 150, "armure", 5, durabilite=20),
    Item("Jambières Orques", "Commun", 150, "armure", 7, durabilite=20),
    Item("Viande d'Orc", "Commun", 15, "nourriture", 20),
    Item("Hydromel Orque", "Rare", 25, "boisson", 30),
    Item("Tête d'Orc", "Commun", 10),
    Item("Os d'Orc", "Rare", 12),
    Item("Oreille d'Orc", "Épique", 15)
]
loot_esprit = [
    Item("Lame Fantomatique", "Épique", 350, "arme", (25, 35), durabilite=20),
    Item("Faux Éthérée", "Légendaire", 400, "arme", (30, 40), durabilite=25),
    Item("Bâton d'Esprit", "Rare", 300, "arme", (20, 30), durabilite=20),
    Item("Voile Fantomatique", "Épique", 450, "armure", 15, durabilite=30),
    Item("Cape d'Esprit", "Rare", 350, "armure", 10, durabilite=25),
    Item("Cuirasse Éthérée", "Légendaire", 400, "armure", 18, durabilite=30),
    Item("Nectar Spectral", "Rare", 40, "nourriture", 25),
    Item("Liqueur des Limbes", "Épique", 60, "boisson", 40),
    Item("Essence d'Esprit", "Rare", 25),
    Item("Cœur d'Esprit", "Commun", 20),
    Item("Éclat d'Esprit", "Épique", 30)
]
loot_dragon = [
    Item("Griffes Draconiques", "Mythique", 1000, "arme", (80, 100), durabilite=50),
    Item("Queue Draconique", "Légendaire", 900, "arme", (70, 90), durabilite=45),
    Item("Dard Draconique", "Légendaire", 850, "arme", (60, 85), durabilite=40),
    Item("Écailles Draconiques", "Mythique", 1200, "armure", 40, durabilite=60),
    Item("Plastron Draconique", "Légendaire", 1100, "armure", 35, durabilite=55),
    Item("Heaume Draconique", "Légendaire", 1000, "armure", 30, durabilite=50),
    Item("Steak de Dragon", "Épique", 200, "nourriture", 50),
    Item("Sang de Dragon", "Légendaire", 300, "boisson", 60),
    Item("Aile Draconique", "Épique", 100),
    Item("Cœur Draconique", "Rare", 90),
    Item("Dent Draconique", "Commun", 80)
]
loot_loup = [
    Item("Crocs de Loup", "Épique", 350, "arme", (25, 35), durabilite=20),
    Item("Griffes de Loup", "Légendaire", 400, "arme", (30, 40), durabilite=25),
    Item("Griffe de Loup", "Rare", 300, "arme", (20, 30), durabilite=20),
    Item("Pelage de Loup", "Épique", 450, "armure", 15, durabilite=30),
    Item("Cuir de Loup", "Rare", 350, "armure", 10, durabilite=25),
    Item("Casque de Loup", "Légendaire", 400, "armure", 18, durabilite=30),
    Item("Ragoût de Loup", "Commun", 30, "nourriture", 20),
    Item("Lait de Louve", "Rare", 45, "boisson", 25),
    Item("Essence de Loup", "Rare", 25),
    Item("Cœur de Loup", "Commun", 20),
    Item("Griffe Lupine", "Épique", 30)
]
loot_wyverne = [
    Item("Lance de Wyverne", "Mythique", 1000, "arme", (80, 120), durabilite=50),
    Item("Serres de Wyverne", "Légendaire", 950, "arme", (75, 110), durabilite=50),
    Item("Queue de Wyverne", "Légendaire", 900, "arme", (70, 100), durabilite=45),
    Item("Plastron de Wyverne", "Légendaire", 1100, "armure", 35, durabilite=60),
    Item("Heaume de Wyverne", "Légendaire", 1000, "armure", 30, durabilite=55),
    Item("Ailes de Wyverne", "Mythique", 1050, "armure", 40, durabilite=65),
    Item("Écaille de Wyverne", "Rare", 50),
    Item("Dent de Wyverne", "Commun", 45),
    Item("Cœur de Wyverne", "Épique", 60)
]
loot_araignee = [
    Item("Dard d'Araignée", "Épique", 500, "arme", (30, 45), durabilite=35),
    Item("Mâchoires d'Araignée", "Légendaire", 450, "arme", (35, 50), durabilite=30),
    Item("Lance d'Araignée", "Épique", 400, "arme", (25, 40), durabilite=25),
    Item("Carapace d'Araignée", "Légendaire", 600, "armure", 20, durabilite=40),
    Item("Chitine d'Araignée", "Épique", 550, "armure", 15, durabilite=35),
    Item("Bottes d'Araignée", "Épique", 500, "armure", 10, durabilite=30),
    Item("Venin d'Araignée", "Épique", 30),
    Item("Pattes d'Araignée", "Commun", 25),
    Item("Œil d'Araignée", "Rare", 30)
]
loot_zombie = [
    Item("Épée Zombie", "Rare", 300, "arme", (20, 30), durabilite=20),
    Item("Marteau Zombie", "Épique", 350, "arme", (25, 35), durabilite=25),
    Item("Griffe Zombie", "Rare", 250, "arme", (15, 25), durabilite=15),
    Item("Armure Zombie", "Épique", 400, "armure", 18, durabilite=30),
    Item("Cuirasse Zombie", "Rare", 300, "armure", 12, durabilite=25),
    Item("Gantelets Zombie", "Rare", 350, "armure", 10, durabilite=20),
    Item("Mâchoire Zombie", "Épique", 25),
    Item("Peau Zombie", "Rare", 20),
    Item("Main Zombie", "Commun", 15)
]
loot_troll = [
    Item("Massue Troll", "Rare", 300, "arme", (20, 30), durabilite=25),
    Item("Bâton Troll", "Rare", 300, "arme", (18, 28), durabilite=20),
    Item("Hache Troll", "Épique", 350, "arme", (25, 35), durabilite=20),
    Item("Plastron Troll", "Épique", 400, "armure", 15, durabilite=35),
    Item("Casque Troll", "Rare", 350, "armure", 10, durabilite=30),
    Item("Gantelets Troll", "Rare", 350, "armure", 12, durabilite=30),
    Item("Doigt de Troll", "Rare", 25),
    Item("Peau de Troll", "Commun", 20),
    Item("Œil de Troll", "Épique", 30)
]
loot_squelette = [
    Item("Épée Squelettique", "Épique", 350, "arme", (25, 35), durabilite=20),
    Item("Arc Squelettique", "Rare", 350, "arme", (20, 30), durabilite=25),
    Item("Lance Squelettique", "Rare", 300, "arme", (15, 25), durabilite=15),
    Item("Armure d'Os", "Épique", 400, "armure", 18, durabilite=30),
    Item("Cuirasse Squelettique", "Rare", 350, "armure", 12, durabilite=25),
    Item("Bouclier Squelettique", "Rare", 300, "armure", 8, durabilite=20),
    Item("Crâne Squelettique", "Épique", 25),
    Item("Côte Squelettique", "Rare", 20),
    Item("Vertèbre Squelettique", "Commun", 20)
]
loot_golem = [
    Item("Poing de Golem", "Légendaire", 600, "arme", (40, 55), durabilite=40),
    Item("Mâchoire de Golem", "Épique", 550, "arme", (35, 50), durabilite=35),
    Item("Massue de Golem", "Épique", 500, "arme", (30, 45), durabilite=30),
    Item("Cuirasse de Golem", "Légendaire", 700, "armure", 25, durabilite=45),
    Item("Jambières de Golem", "Épique", 650, "armure", 18, durabilite=40),
    Item("Casque de Golem", "Épique", 600, "armure", 12, durabilite=35),
    Item("Cœur de Golem", "Épique", 40),
    Item("Fragment de Golem", "Rare", 35),
    Item("Mains de Golem", "Commun", 30)
]
loot_lezard = [
    Item("Griffe de Lézard", "Commun", 150, "arme", (10, 15), durabilite=15),
    Item("Queue de Lézard", "Commun", 100, "arme", (5, 10), durabilite=10),
    Item("Dard de Lézard", "Rare", 200, "arme", (12, 18), durabilite=20),
    Item("Cuir de Lézard", "Rare", 250, "armure", 7, durabilite=20),
    Item("Écailles de Lézard", "Commun", 200, "armure", 5, durabilite=15),
    Item("Jambières de Lézard", "Commun", 150, "armure", 4, durabilite=15),
    Item("Griffe Lézard", "Épique", 15),
    Item("Peau Lézard", "Rare", 12),
    Item("Dent Lézard", "Commun", 10)
]
loot_minotaure = [
    Item("Hache Minotaure", "Légendaire", 850, "arme", (65, 85), durabilite=50),
    Item("Marteau Minotaure", "Légendaire", 900, "arme", (70, 90), durabilite=55),
    Item("Faux Minotaure", "Épique", 800, "arme", (60, 80), durabilite=45),
    Item("Armure Minotaure", "Légendaire", 950, "armure", 35, durabilite=60),
    Item("Casque Minotaure", "Épique", 850, "armure", 25, durabilite=50),
    Item("Bouclier Minotaure", "Légendaire", 900, "armure", 32, durabilite=55),
    Item("Corne Minotaure", "Épique", 50),
    Item("Cœur Minotaure", "Rare", 40),
    Item("Sabot Minotaure", "Commun", 35)
]
loot_cerbere = [
    Item("Crocs Cerbère", "Mythique", 1200, "arme", (90, 110), durabilite=60),
    Item("Griffes Cerbère", "Légendaire", 1100, "arme", (80, 100), durabilite=55),
    Item("Lance Cerbère", "Légendaire", 1050, "arme", (75, 95), durabilite=50),
    Item("Plastron Cerbère", "Mythique", 1300, "armure", 40, durabilite=70),
    Item("Cape Cerbère", "Légendaire", 1200, "armure", 35, durabilite=65),
    Item("Heaume Cerbère", "Légendaire", 1150, "armure", 30, durabilite=60),
    Item("Flamme Cerbère", "Épique", 100),
    Item("Cœur Cerbère", "Rare", 90),
    Item("Griffe Cerbère", "Commun", 80)
]
loot_slime = [
    Item("Lame Slime", "Épique", 550, "arme", (35, 50), durabilite=30),
    Item("Bâton Slime", "Rare", 500, "arme", (30, 45), durabilite=25),
    Item("Marteau Slime", "Légendaire", 600, "arme", (40, 55), durabilite=35),
    Item("Voile Slime", "Légendaire", 650, "armure", 20, durabilite=40),
    Item("Cape Slime", "Épique", 550, "armure", 15, durabilite=30),
    Item("Gantelets Slime", "Rare", 500, "armure", 12, durabilite=25),
    Item("Essence Slime", "Rare", 35),
    Item("Fragment Slime", "Commun", 30),
    Item("Cristaux Slime", "Épique", 40)
]
loot_kraken = [
    Item("Trident Kraken", "Mythique", 1100, "arme", (80, 120), durabilite=50),
    Item("Harpon Kraken", "Légendaire", 950, "arme", (70, 100), durabilite=45),
    Item("Lame Kraken", "Épique", 800, "arme", (60, 90), durabilite=40),
    Item("Armure Kraken", "Légendaire", 1000, "armure", 35, durabilite=55),
    Item("Cape Kraken", "Épique", 900, "armure", 30, durabilite=50),
    Item("Heaume Kraken", "Épique", 850, "armure", 25, durabilite=45),
    Item("Perle Kraken", "Épique", 60),
    Item("Tentacule Kraken", "Rare", 50),
    Item("Encre Kraken", "Commun", 40)
]
loot_griffon = [
    Item("Griffe Griffon", "Légendaire", 900, "arme", (65, 95), durabilite=50),
    Item("Lame Griffon", "Épique", 800, "arme", (60, 85), durabilite=45),
    Item("Arc Griffon", "Légendaire", 850, "arme", (55, 80), durabilite=40),
    Item("Ailes Griffon", "Mythique", 1100, "armure", 40, durabilite=60),
    Item("Plastron Griffon", "Légendaire", 1000, "armure", 35, durabilite=55),
    Item("Casque Griffon", "Épique", 900, "armure", 30, durabilite=50),
    Item("Plume Griffon", "Épique", 55),
    Item("Œil Griffon", "Rare", 45),
    Item("Serre Griffon", "Commun", 35)
]
loot_hydre = [
    Item("Lame Hydre", "Mythique", 1300, "arme", (90, 130), durabilite=60),
    Item("Dard Hydre", "Légendaire", 1200, "arme", (80, 110), durabilite=55),
    Item("Fléau Hydre", "Épique", 1100, "arme", (70, 100), durabilite=50),
    Item("Écailles Hydre", "Mythique", 1400, "armure", 40, durabilite=70),
    Item("Cape Hydre", "Légendaire", 1300, "armure", 35, durabilite=65),
    Item("Heaume Hydre", "Épique", 1200, "armure", 30, durabilite=60),
    Item("Cœur Hydre", "Épique", 80),
    Item("Venin Hydre", "Rare", 70),
    Item("Griffe Hydre", "Commun", 60)
]
loot_spectre = [
    Item("Faux Spectrale", "Légendaire", 800, "arme", (60, 90), durabilite=50),
    Item("Bâton Spectral", "Épique", 700, "arme", (50, 80), durabilite=45),
    Item("Dague Spectrale", "Rare", 600, "arme", (40, 70), durabilite=40),
    Item("Voile Spectral", "Légendaire", 900, "armure", 35, durabilite=55),
    Item("Cape Spectrale", "Épique", 800, "armure", 30, durabilite=50),
    Item("Cuirasse Spectrale", "Rare", 700, "armure", 25, durabilite=45),
    Item("Essence Spectrale", "Épique", 50),
    Item("Cendres Spectrales", "Rare", 40),
    Item("Fragment Spectral", "Commun", 30)
]
loot_basilic = [
    Item("Regard Basilic", "Mythique", 1400, "arme", (100, 140), durabilite=60),
    Item("Griffe Basilic", "Légendaire", 1300, "arme", (90, 120), durabilite=55),
    Item("Dard Basilic", "Épique", 1200, "arme", (80, 110), durabilite=50),
    Item("Écailles Basilic", "Mythique", 1500, "armure", 40, durabilite=70),
    Item("Cape Basilic", "Légendaire", 1400, "armure", 35, durabilite=65),
    Item("Heaume Basilic", "Épique", 1300, "armure", 30, durabilite=60),
    Item("Œil Basilic", "Épique", 90),
    Item("Peau Basilic", "Rare", 80),
    Item("Dent Basilic", "Commun", 70)
]
loot_boss1 = [
    Item("Bâton Arachnide", "Légendaire", 1500, "arme", (55, 85), durabilite=50),
    Item("Cape de Toile", "Épique", 1200, "armure", 25, durabilite=40),
    Item("Venin Arachnide", "Rare", 100)
]
loot_boss2 = [
    Item("Épée Royale", "Légendaire", 2200, "arme", (20, 30), durabilite=60),
    Item("Couronne d'Os", "Épique", 1500, "armure", 20, durabilite=50),
    Item("Os Sacré", "Rare", 120)
]
loot_boss3 = [
    Item("Marteau de Chef", "Légendaire", 2500, "arme", (25, 35), durabilite=70),
    Item("Plastron de Chef", "Épique", 1800, "armure", 30, durabilite=60),
    Item("Trophée Orque", "Rare", 150)
]
loot_boss4 = [
    Item("Armure de Dragon", "Légendaire", 3000, "armure", 35, durabilite=80),
    Item("Lame de Dragon", "Épique", 2000, "arme", (30, 40), durabilite=70),
    Item("Écaille Noire", "Rare", 180)
]
loot_boss5 = [
    Item("Lame d'Ombre", "Légendaire", 3500, "arme", (30, 40), durabilite=90),
    Item("Cape d'Ombre", "Épique", 2500, "armure", 30, durabilite=80),
    Item("Essence Ténébreuse", "Rare", 200)
]
loot_boss6 = [
    Item("Maillet Titan", "Légendaire", 5000, "arme", (35, 45), durabilite=100),
    Item("Bouclier Titan", "Épique", 3000, "armure", 35, durabilite=80),
    Item("Cœur Titan", "Rare", 200)
]
loot_boss7 = [
    Item("Trident Abyssal", "Mythique", 6000, "arme", (40, 50), durabilite=110),
    Item("Cape Abyssale", "Légendaire", 3500, "armure", 38, durabilite=90),
    Item("Perle Abyssale", "Épique", 250)
]
loot_boss8 = [
    Item("Arc Céleste", "Mythique", 7000, "arme", (45, 55), durabilite=120),
    Item("Ailes Célestes", "Légendaire", 4000, "armure", 40, durabilite=100),
    Item("Plume Céleste", "Épique", 300)
]
loot_boss9 = [
    Item("Faux d'Hydre", "Mythique", 8000, "arme", (50, 60), durabilite=130),
    Item("Écailles d'Hydre", "Légendaire", 4500, "armure", 40, durabilite=110),
    Item("Venin d'Hydre", "Épique", 350)
]
loot_boss10 = [
    Item("Regard Éternel", "Immortel", 10000, "arme", (60, 80), durabilite=150),
    Item("Armure Éternelle", "Mythique", 6000, "armure", 40, durabilite=120),
    Item("Œil Éternel", "Épique", 400)
]
loot_abyssal_serpent = [
    Item("Écaille Serpentine", "Épique", 200),
    Item("Dague Abyssale", "Légendaire", 1000, "arme", (50, 70), durabilite=40),
    Item("Cape Serpentine", "Épique", 800, "armure", 25, durabilite=50)
]
loot_coral_behemoth = [
    Item("Corail Vivant", "Épique", 250),
    Item("Marteau Corallien", "Légendaire", 1200, "arme", (60, 80), durabilite=45),
    Item("Plastron Corallien", "Épique", 900, "armure", 30, durabilite=55)
]

# Fish loot table
loot_poissons = [
    Item("Sardine", "Commun", 10, "nourriture", 10),
    Item("Hareng", "Commun", 12, "nourriture", 12),
    Item("Maquereau", "Commun", 15, "nourriture", 15),
    Item("Truite", "Rare", 30, "nourriture", 20),
    Item("Saumon", "Rare", 40, "nourriture", 25),
    Item("Anguille", "Rare", 50, "nourriture", 30),
    Item("Thon", "Épique", 100, "nourriture", 40),
    Item("Espadon", "Épique", 150, "nourriture", 50),
    Item("Requin", "Légendaire", 300, "nourriture", 60),
    Item("Poisson Abyssal", "Mythique", 1000, "nourriture", 80),
    Item("Légende des Mers", "Immortel", 5000, "nourriture", 100),
    Item("Bar", "Commun", 10, "nourriture", 10),
    Item("Anchois", "Commun", 10, "nourriture", 10),
    Item("Morue", "Commun", 10, "nourriture", 10),
    Item("Carpe", "Commun", 10, "nourriture", 10),
    Item("Perche", "Commun", 10, "nourriture", 10),
    Item("Tanche", "Commun", 10, "nourriture", 10),
    Item("Goujon", "Commun", 10, "nourriture", 10),
    Item("Éperlan", "Commun", 10, "nourriture", 10),
    Item("Lotte", "Commun", 10, "nourriture", 10),
    Item("Vairon", "Commun", 10, "nourriture", 10),
    Item("Ablette", "Commun", 10, "nourriture", 10),
    Item("Chevesne", "Commun", 10, "nourriture", 10),
    Item("Rotengle", "Commun", 10, "nourriture", 10),
    Item("Brème", "Commun", 10, "nourriture", 10),
    Item("Gardons", "Commun", 10, "nourriture", 10),
    Item("Ide", "Commun", 10, "nourriture", 10),
    Item("Vandoise", "Commun", 10, "nourriture", 10),
    Item("Hotu", "Commun", 10, "nourriture", 10),
    Item("Barbeau", "Commun", 10, "nourriture", 10),
    Item("Omble", "Commun", 10, "nourriture", 10),
    Item("Flet", "Commun", 10, "nourriture", 10),
    Item("Limande", "Commun", 10, "nourriture", 10),
    Item("Plie", "Commun", 10, "nourriture", 10),
    Item("Sole", "Commun", 10, "nourriture", 10),
    Item("Turbot", "Commun", 10, "nourriture", 10),
    Item("Merlan", "Commun", 10, "nourriture", 10),
    Item("Lieu", "Commun", 10, "nourriture", 10),
    Item("Églefin", "Commun", 10, "nourriture", 10),
    Item("Congre", "Commun", 10, "nourriture", 10),
    Item("Mulet", "Commun", 10, "nourriture", 10),
    Item("Orphie", "Commun", 10, "nourriture", 10),
    Item("Chinchard", "Commun", 10, "nourriture", 10),
    Item("Sprat", "Commun", 10, "nourriture", 10),
    Item("Aiguille", "Commun", 10, "nourriture", 10),
    Item("Silure", "Rare", 30, "nourriture", 20),
    Item("Brochet", "Rare", 30, "nourriture", 20),
    Item("Sandre", "Rare", 30, "nourriture", 20),
    Item("Black Bass", "Rare", 30, "nourriture", 20),
    Item("Esturgeon", "Rare", 30, "nourriture", 20),
    Item("Alose", "Rare", 30, "nourriture", 20),
    Item("Lamproie", "Rare", 30, "nourriture", 20),
    Item("Féra", "Rare", 30, "nourriture", 20),
    Item("Corégone", "Rare", 30, "nourriture", 20),
    Item("Omble Chevalier", "Rare", 30, "nourriture", 20),
    Item("Grondin", "Rare", 30, "nourriture", 20),
    Item("Vive", "Rare", 30, "nourriture", 20),
    Item("Roussette", "Rare", 30, "nourriture", 20),
    Item("Mérou", "Rare", 30, "nourriture", 20),
    Item("Pagre", "Rare", 30, "nourriture", 20),
    Item("Dorade", "Rare", 30, "nourriture", 20),
    Item("Sar", "Rare", 30, "nourriture", 20),
    Item("Loup de Mer", "Rare", 30, "nourriture", 20),
    Item("Muge", "Rare", 30, "nourriture", 20),
    Item("Marbré", "Rare", 30, "nourriture", 20),
    Item("Coryphène", "Épique", 100, "nourriture", 40),
    Item("Barracuda", "Épique", 100, "nourriture", 40),
    Item("Wahoo", "Épique", 100, "nourriture", 40),
    Item("Mahi-Mahi", "Épique", 100, "nourriture", 40),
    Item("Voilier", "Épique", 100, "nourriture", 40),
    Item("Marlin", "Épique", 100, "nourriture", 40),
    Item("Poisson-Lune", "Épique", 100, "nourriture", 40),
    Item("Requin-Marteau", "Épique", 100, "nourriture", 40),
    Item("Requin-Tigre", "Épique", 100, "nourriture", 40),
    Item("Poisson-Scie", "Légendaire", 300, "nourriture", 60),
    Item("Requin-Baleine", "Légendaire", 300, "nourriture", 60),
    Item("Manta", "Légendaire", 300, "nourriture", 60),
    Item("Mégalodon", "Légendaire", 300, "nourriture", 60)
]

# Monsters
monstres = {
    "Gobelin": Monstre("Gobelin", 10, 20, loot_gobelin, peut_poison=True),
    "Orc": Monstre("Orc", 15, 30, loot_orc),
    "Esprit": Monstre("Esprit", 20, 40, loot_esprit, peut_paralyser=True),
    "Dragon": Monstre("Dragon", 50, 100, loot_dragon, peut_poison=True),
    "Loup Fantôme": Monstre("Loup Fantôme", 25, 50, loot_loup, peut_paralyser=True),
    "Wyverne": Monstre("Wyverne", 45, 90, loot_wyverne, peut_poison=True),
    "Araignée Géante": Monstre("Araignée Géante", 30, 60, loot_araignee, peut_poison=True),
    "Zombie": Monstre("Zombie", 20, 50, loot_zombie, peut_poison=True),
    "Troll": Monstre("Troll", 25, 70, loot_troll),
    "Squelette": Monstre("Squelette", 15, 40, loot_squelette),
    "Golem": Monstre("Golem", 35, 80, loot_golem),
    "Lézard de Lave": Monstre("Lézard de Lave", 20, 50, loot_lezard, peut_poison=True),
    "Minotaure": Monstre("Minotaure", 40, 90, loot_minotaure),
    "Cerbère": Monstre("Cerbère", 50, 100, loot_cerbere, peut_poison=True),
    "Slime Spectral": Monstre("Slime Spectral", 30, 60, loot_slime, peut_paralyser=True),
    "Kraken": Monstre("Kraken", 45, 90, loot_kraken, peut_poison=True),
    "Griffon": Monstre("Griffon", 40, 80, loot_griffon),
    "Hydre": Monstre("Hydre", 50, 100, loot_hydre, peut_poison=True),
    "Spectre": Monstre("Spectre", 35, 70, loot_spectre, peut_paralyser=True),
    "Basilic": Monstre("Basilic", 45, 90, loot_basilic, peut_paralyser=True)
}

# Fishable monsters
monstres_peche = {
    "Serpent Abyssal": Monstre("Serpent Abyssal", 50, 100, loot_abyssal_serpent, peut_poison=True),
    "Béhémoth Corallien": Monstre("Béhémoth Corallien", 60, 120, loot_coral_behemoth)
}


# Donjons
donjons = [
    ("Forêt Maudite", ["Gobelin", "Orc", "Loup Fantôme"], 1),
    ("Cimetière Hanté", ["Esprit", "Zombie", "Squelette"], 10),
    ("Montagne de Feu", ["Dragon", "Wyverne", "Lézard de Lave"], 20),
    ("Caverne de Cristal", ["Troll", "Golem", "Minotaure"], 30),
    ("Abysse Infernal", ["Cerbère", "Slime Spectral", "Kraken"], 40),
    ("Plaine Céleste", ["Griffon", "Spectre"], 50),
    ("Marais Empoisonné", ["Hydre", "Basilic"], 60)
]

# Quests
quetes_disponibles = [
    Quete("Tuer des Gobelins", "tuer", "Gobelin", 5, {"argent": 100, "experience": 50}),
    Quete("Éliminer des Orcs", "tuer", "Orc", 4, {"argent": 150, "experience": 75}),
    Quete("Chasser des Loups Fantômes", "tuer", "Loup Fantôme", 3, {"argent": 200, "experience": 100}),
    Quete("Vaincre des Dragons", "tuer", "Dragon", 2, {"argent": 500, "experience": 250}),
    Quete("Détruire des Hydres", "tuer", "Hydre", 2, {"argent": 600, "experience": 300}),
    Quete("Collecter des Dents de Gobelin", "collecter", "Dent de Gobelin", 10, {"argent": 200, "experience": 100}),
    Quete("Rassembler des Écailles Draconiques", "collecter", "Écaille Draconique", 5, {"argent": 500, "experience": 250}),
    Quete("Obtenir des Flammes Cerbère", "collecter", "Flamme Cerbère", 3, {"argent": 600, "experience": 300}),
    Quete("Pêcher des Poissons", "pecher", None, 10, {"argent": 200, "experience": 100}),
    Quete("Pêcher un Requin", "pecher", "Requin", 3, {"argent": 500, "experience": 250}),
    Quete("Manger de la Nourriture", "manger", None, 5, {"argent": 100, "experience": 50}),
    Quete("Manger un Requin", "manger", "Requin", 2, {"argent": 300, "experience": 150}),
    Quete("Dépenser de l'Argent", "depenser", None, 1000, {"argent": 200, "experience": 100}),
    Quete("Dépenser Beaucoup", "depenser", None, 5000, {"argent": 1000, "experience": 500}),
    Quete("Crafter une Épée de Gobelin", "crafter", "Épée de Gobelin", 1, {"argent": 150, "experience": 75}),
    Quete("Crafter une Armure Gobeline", "crafter", "Armure Gobeline", 1, {"argent": 200, "experience": 100}),
    Quete("Crafter un Appât Rare", "crafter", "Appât Rare", 2, {"argent": 300, "experience": 150}),
    Quete("Tuer des Squelettes", "tuer", "Squelette", 5, {"argent": 150, "experience": 75}),
    Quete("Collecter des Crânes Squelettiques", "collecter", "Crâne Squelettique", 5, {"argent": 200, "experience": 100}),
    Quete("Pêcher un Poisson Abyssal", "pecher", "Poisson Abyssal", 1, {"argent": 1000, "experience": 500}),
    Quete("Crafter une Lame Fantomatique", "crafter", "Lame Fantomatique", 1, {"argent": 500, "experience": 250}),
    Quete("Buveur professionnel", "collecter", "Lait", 3, {"argent": 200, "item": Item("Coupe en Or", "Épique", 500)})
]

# Crafting recipes
recettes = [
    {"nom": "Épée de Gobelin", "ingredients": ["Dent de Gobelin", "Peau de Gobelin"], "resultat": Item("Épée de Gobelin", "Rare", 50, "arme", (7, 12), durabilite=10)},
    {"nom": "Armure Gobeline", "ingredients": ["Peau de Gobelin", "Peau de Gobelin"], "resultat": Item("Armure Gobeline", "Commun", 100, "armure", 5, durabilite=10)},
    {"nom": "Appât Rare", "ingredients": ["Dent de Gobelin", "Os d'Orc"], "resultat": Item("Appât Rare", "Rare", 50, "appat")},
    {"nom": "Lame Fantomatique", "ingredients": ["Essence d'Esprit", "Cœur d'Esprit"], "resultat": Item("Lame Fantomatique", "Épique", 350, "arme", (25, 35), durabilite=20)},
    {"nom": "Cape d'Esprit", "ingredients": ["Essence d'Esprit", "Essence d'Esprit"], "resultat": Item("Cape d'Esprit", "Rare", 350, "armure", 10, durabilite=25)},
    {"nom": "Appât Épique", "ingredients": ["Venin d'Araignée", "Essence Slime"], "resultat": Item("Appât Épique", "Épique", 100, "appat")},
    {"nom": "Griffes Draconiques", "ingredients": ["Écaille Draconique", "Cœur Draconique"], "resultat": Item("Griffes Draconiques", "Mythique", 1000, "arme", (80, 100), durabilite=50)},
    {"nom": "Plastron Draconique", "ingredients": ["Écaille Draconique", "Écaille Draconique"], "resultat": Item("Plastron Draconique", "Légendaire", 1100, "armure", 35, durabilite=55)},
    {"nom": "Appât Légendaire", "ingredients": ["Perle Kraken", "Flamme Cerbère"], "resultat": Item("Appât Légendaire", "Légendaire", 200, "appat")},
    {"nom": "Trident Kraken", "ingredients": ["Perle Kraken", "Tentacule Kraken"], "resultat": Item("Trident Kraken", "Mythique", 1100, "arme", (80, 120), durabilite=50)},
    {"nom": "Jus de Baies", "ingredients": ["Baie Sauvage", "Eau"], "resultat": Item("Jus de Baies", "Commun", 30, "boisson", 25)}
]

def assigner_quetes(joueur):
    if len(joueur.quetes) < 5:
        quetes_possibles = [q for q in quetes_disponibles if q not in joueur.quetes]
        quetes_a_ajouter = min(5 - len(joueur.quetes), len(quetes_possibles))
        nouvelles_quetes = random.sample(quetes_possibles, quetes_a_ajouter)
        for quete in nouvelles_quetes:
            quete_modifiee = Quete(
                quete.nom,
                quete.type,
                quete.cible,
                quete.quantite + (joueur.niveau // 10) * 2 if quete.type == "tuer" else quete.quantite,
                quete.recompense
            )
            joueur.ajouter_quete(quete_modifiee)

def vendre_objets(joueur):
    while True:
        joueur.voir_inventaire2()
        try:
            choix = int(input("\nChoisissez un objet à vendre (ou 0 pour quitter) : ")) - 1
            if choix == -1:
                break
            if 0 <= choix < len(joueur.inventaire):
                item = joueur.inventaire.pop(choix)
                joueur.argent += item.valeur
                print(f"{Fore.GREEN}{item.nom} vendu pour {item.valeur} pièces. Argent total : {joueur.argent}.{Style.RESET_ALL}")
                joueur.verifier_quetes(item=Item("Vente", "Commun", item.valeur, "depenser"))
            else:
                print(f"{Fore.RED}Choix invalide.{Style.RESET_ALL}")
        except ValueError:
            print(f"{Fore.RED}Entrée invalide.{Style.RESET_ALL}")

def donjon(joueur):
    print(f"\n{Fore.MAGENTA}╔════ Donjons Disponibles ════╗{Style.RESET_ALL}")
    for i, (nom, _, niveau_requis) in enumerate(donjons):
        print(f"║ {i+1}. {nom} (Niveau requis: {niveau_requis})")
    print(f"╚═════════════════════════════╝{Style.RESET_ALL}")

    try:
        choix = int(input("\nChoisissez un donjon (ou 0 pour quitter) : ")) - 1
        if choix == -1:
            return
        if 0 <= choix < len(donjons):
            nom, monstres_possibles, niveau_requis = donjons[choix]
            if joueur.niveau < niveau_requis:
                print(f"{Fore.RED}Niveau insuffisant ! Niveau requis : {niveau_requis}.{Style.RESET_ALL}")
                return

            nb_monstres = random.randint(1, 3)
            monstres_selectionnes = [monstres[monstre_nom] for monstre_nom in random.choices(monstres_possibles, k=nb_monstres)]
            print(f"\n{Fore.YELLOW}Vous entrez dans {nom} et rencontrez {nb_monstres} monstre(s) !{Style.RESET_ALL}")
            for i, monstre in enumerate(monstres_selectionnes):
                print(f"Monstre {i+1}: {monstre.nom} (Santé: {monstre.sante}, Force: {monstre.force})")

            while any(m.est_vivant() for m in monstres_selectionnes) and joueur.est_vivant():
                print(f"\n{Fore.CYAN}Votre santé: {joueur.sante}/{joueur.sante_max}{Style.RESET_ALL}")
                for i, m in enumerate(monstres_selectionnes):
                    if m.est_vivant():
                        print(f"Monstre {i+1}: {m.nom} (Santé: {m.sante})")
                try:
                    action = input("\n1. Attaquer\n2. Utiliser un objet\n3. Fuir\nChoisissez une action : ")
                    if action == "1":
                        try:
                            cible = int(input(f"Quel monstre attaquer ? (1 à {nb_monstres}) : ")) - 1
                            if 0 <= cible < len(monstres_selectionnes) and monstres_selectionnes[cible].est_vivant():
                                joueur.attaquer(monstres_selectionnes[cible])
                            else:
                                print(f"{Fore.RED}Cible invalide ou déjà vaincue !{Style.RESET_ALL}")
                                continue
                        except ValueError:
                            print(f"{Fore.RED}Entrée invalide.{Style.RESET_ALL}")
                            continue
                    elif action == "2":
                        joueur.voir_inventaire()
                    elif action == "3":
                        if random.random() < 0.5:
                            print(f"{Fore.YELLOW}Vous avez réussi à fuir !{Style.RESET_ALL}")
                            return
                        else:
                            print(f"{Fore.RED}Échec de la fuite !{Style.RESET_ALL}")
                    else:
                        print(f"{Fore.RED}Action invalide.{Style.RESET_ALL}")
                        continue

                    for monstre in monstres_selectionnes:
                        if monstre.est_vivant():
                            monstre.attaquer(joueur)

                except ValueError:
                    print(f"{Fore.RED}Entrée invalide.{Style.RESET_ALL}")

            if not joueur.est_vivant():
                print(f"{Fore.RED}{joueur.nom} a été vaincu !{Style.RESET_ALL}")
                return

            for monstre in monstres_selectionnes:
                if not monstre.est_vivant():
                    loot = generer_loot(monstre.loot)
                    joueur.ajouter_objet(loot)
                    joueur.experience += random.randint(10, 30)
                    joueur.verifier_niveau()

            print(f"{Fore.GREEN}Tous les monstres ont été vaincus !{Style.RESET_ALL}")
        else:
            print(f"{Fore.RED}Choix invalide.{Style.RESET_ALL}")
    except ValueError:
        print(f"{Fore.RED}Entrée invalide.{Style.RESET_ALL}")

magasins = {
    "Épicerie": [
        Item("Oeuf", "Commun", 25, "nourriture", 10),
        Item("Pain", "Commun", 50, "nourriture", 20),
        Item("Poisson", "Rare", 100, "nourriture", 30),
        Item("Eau", "Commun", 30, "boisson", 10),
        Item("Lait", "Rare", 40, "boisson", 20),
        Item("Jus", "Rare", 60, "boisson", 30)
    ],
    "Boutique": [
        Item("Potion de Soin", "Commun", 500),
        Item("Potion de Force", "Rare", 750),
        Item("Potion de Régénération", "Épique", 1000),
        Item("Anti-Para", "Rare", 300),
        Item("Antidote", "Rare", 300),
        Item("Appât Commun", "Commun", 100, "appat"),
        Item("Appât Rare", "Rare", 250, "appat"),
        Item("Appât Épique", "Épique", 500, "appat"),
        Item("Canne à Pêche", "Commun", 1000, "outil", durabilite=50)
    ],
    "Forgeron": [
        Item("Épée en Fer", "Commun", 500, "arme", (10, 15), durabilite=20),
        Item("Armure en Fer", "Commun", 600, "armure", 10, durabilite=25),
        Item("Hache de Combat", "Rare", 800, "arme", (15, 20), durabilite=25),
        Item("Bouclier en Acier", "Rare", 700, "armure", 15, durabilite=30)
    ]
}

# Start rewriting from menu_boss
def menu_boss(joueur):
    print(f"\n{Fore.MAGENTA}╔════ Boss Disponibles ════╗{Style.RESET_ALL}")
    for i, boss in enumerate(bosses):
        statut = "Vaincu" if boss.vaincu else "Disponible"
        print(f"║ {i+1}. {boss.nom} (Niveau requis: {boss.niveau_requis}, {statut})")
    print(f"╚═════════════════════════╝{Style.RESET_ALL}")

    try:
        choix = int(input("\nChoisissez un boss à affronter (ou 0 pour quitter) : ")) - 1
        if choix == -1:
            return
        if 0 <= choix < len(bosses):
            boss = bosses[choix]
            if boss.niveau_requis > joueur.niveau:
                print(f"{Fore.RED}Niveau insuffisant ! Niveau requis : {boss.niveau_requis}.{Style.RESET_ALL}")
                return
            if boss.vaincu:
                print(f"{Fore.YELLOW}Ce boss a déjà été vaincu. Voulez-vous le ré-affronter ? (o/n) : {Style.RESET_ALL}")
                if input().lower() != 'o':
                    return
                boss.reset_stats(multiplicateur=joueur.niveau // 10)

            print(f"\n{Fore.YELLOW}Vous affrontez {boss.nom} (Santé: {boss.sante}, Force: {boss.force}) !{Style.RESET_ALL}")
            while boss.est_vivant() and joueur.est_vivant():
                print(f"\n{Fore.CYAN}Votre santé: {joueur.sante}/{joueur.sante_max} | Santé du boss: {boss.sante}/{boss.sante_max}{Style.RESET_ALL}")
                try:
                    action = input("\n1. Attaquer\n2. Utiliser un objet\n3. Fuir\nChoisissez une action : ")
                    if action == "1":
                        joueur.attaquer(boss)
                        if boss.est_vivant():
                            boss.attaquer(joueur)
                    elif action == "2":
                        joueur.voir_inventaire()
                    elif action == "3":
                        if random.random() < 0.3:
                            print(f"{Fore.YELLOW}Vous avez réussi à fuir !{Style.RESET_ALL}")
                            return
                        else:
                            print(f"{Fore.RED}Échec de la fuite !{Style.RESET_ALL}")
                            boss.attaquer(joueur)
                    else:
                        print(f"{Fore.RED}Action invalide.{Style.RESET_ALL}")
                except ValueError:
                    print(f"{Fore.RED}Entrée invalide.{Style.RESET_ALL}")

            if not joueur.est_vivant():
                print(f"{Fore.RED}{joueur.nom} a été vaincu par {boss.nom} !{Style.RESET_ALL}")
                return

            if not boss.est_vivant():
                boss.vaincu = True
                print(f"{Fore.GREEN}{joueur.nom} a vaincu {boss.nom} !{Style.RESET_ALL}")
                loot = generer_loot(boss.loot, quantite=2)  # Bosses drop 2 items
                joueur.ajouter_objet(loot)
                exp_gain = boss.niveau_requis * 10
                joueur.experience += exp_gain
                print(f"{Fore.GREEN}Vous gagnez {exp_gain} points d'expérience !{Style.RESET_ALL}")
                joueur.verifier_niveau()
        else:
            print(f"{Fore.RED}Choix invalide.{Style.RESET_ALL}")
    except ValueError:
        print(f"{Fore.RED}Entrée invalide.{Style.RESET_ALL}")

# Bosses
bosses = [
    Boss("Reine Araignée", 100, 25, loot_boss1, 10, peut_poison=True),
    Boss("Roi Squelette", 150, 30, loot_boss2, 20),
    Boss("Chef Orc", 200, 35, loot_boss3, 30),
    Boss("Dragon Noir", 250, 40, loot_boss4, 40, peut_poison=True),
    Boss("Seigneur des Ombres", 300, 45, loot_boss5, 50, peut_paralyser=True),
    Boss("Titan de Pierre", 350, 50, loot_boss6, 60),
    Boss("Seigneur Abyssal", 400, 55, loot_boss7, 70, peut_poison=True),
    Boss("Griffon Céleste", 450, 60, loot_boss8, 80),
    Boss("Hydre Éternelle", 500, 65, loot_boss9, 90, peut_poison=True),
    Boss("Basilic Immortel", 600, 70, loot_boss10, 100, peut_paralyser=True)
]

def magasin(joueur):
    print(f"\n{Fore.MAGENTA}╔════ Magasins Disponibles ════╗{Style.RESET_ALL}")
    for i, nom in enumerate(magasins.keys()):
        print(f"║ {i+1}. {nom}")
    print(f"╚══════════════════════════════╝{Style.RESET_ALL}")

    try:
        choix_magasin = int(input("\nChoisissez un magasin (ou 0 pour quitter) : ")) - 1
        if choix_magasin == -1:
            return
        magasin_nom = list(magasins.keys())[choix_magasin]
        items = magasins[magasin_nom]

        print(f"\n{Fore.MAGENTA}╔════ {magasin_nom} ════╗{Style.RESET_ALL}")
        for i, item in enumerate(items):
            print(f"║ {i+1}. {item} (Prix: {item.valeur} pièces)")
        print(f"╚══════════════════════╝{Style.RESET_ALL}")

        try:
            choix_item = int(input("\nChoisissez un objet à acheter (ou 0 pour quitter) : ")) - 1
            if choix_item == -1:
                return
            if 0 <= choix_item < len(items):
                item = items[choix_item]
                quantite = int(input(f"Combien de {item.nom} voulez-vous acheter ? : "))
                if quantite <= 0:
                    print(f"{Fore.RED}Quantité invalide.{Style.RESET_ALL}")
                    return
                cout_total = item.valeur * quantite
                if joueur.argent >= cout_total:
                    joueur.argent -= cout_total
                    for _ in range(quantite):
                        joueur.ajouter_objet(Item(item.nom, item.rarete, item.valeur, item.type_objet, item.stats, item.durabilite))
                    print(f"{Fore.GREEN}Vous avez acheté {quantite} x {item.nom} pour {cout_total} pièces !{Style.RESET_ALL}")
                    joueur.verifier_quetes(item=Item("Achat", "Commun", cout_total, "depenser"))
                else:
                    print(f"{Fore.RED}Pas assez d'argent !{Style.RESET_ALL}")
            else:
                print(f"{Fore.RED}Choix invalide.{Style.RESET_ALL}")
        except ValueError:
            print(f"{Fore.RED}Entrée invalide.{Style.RESET_ALL}")
    except (ValueError, IndexError):
        print(f"{Fore.RED}Choix invalide.{Style.RESET_ALL}")

def craft(joueur):
    print(f"\n{Fore.MAGENTA}╔════ Recettes Disponibles ════╗{Style.RESET_ALL}")
    for i, recette in enumerate(recettes):
        ingredients = ", ".join(recette["ingredients"])
        print(f"║ {i+1}. {recette['nom']} (Ingrédients: {ingredients})")
    print(f"╚══════════════════════════════╝{Style.RESET_ALL}")

    try:
        choix = int(input("\nChoisissez une recette à crafter (ou 0 pour quitter) : ")) - 1
        if choix == -1:
            return
        if 0 <= choix < len(recettes):
            joueur.craft_objet(recettes[choix])
        else:
            print(f"{Fore.RED}Choix invalide.{Style.RESET_ALL}")
    except ValueError:
        print(f"{Fore.RED}Entrée invalide.{Style.RESET_ALL}")

def pecher(joueur):
    canne = next((item for item in joueur.inventaire if item.nom == "Canne à Pêche"), None)
    if not canne:
        print(f"{Fore.RED}Vous avez besoin d'une Canne à Pêche !{Style.RESET_ALL}")
        return

    appats = [item for item in joueur.inventaire if item.type_objet == "appat"]
    if not appats:
        print(f"{Fore.RED}Vous avez besoin d'un appât !{Style.RESET_ALL}")
        return

    # Group baits by name to show quantities
    appats_types = {}
    for appat in appats:
        if appat.nom in appats_types:
            appats_types[appat.nom]["quantite"] += 1
        else:
            appats_types[appat.nom] = {"item": appat, "quantite": 1}

    print(f"\n{Fore.MAGENTA}╔════ Appâts Disponibles ════╗{Style.RESET_ALL}")
    appats_liste = list(appats_types.items())
    for i, (nom, info) in enumerate(appats_liste):
        print(f"║ {i+1}. {nom} (Rareté: {info['item'].rarete}, Quantité: {info['quantite']})")
    print(f"╚════════════════════════════╝{Style.RESET_ALL}")

    try:
        choix_appat = int(input("\nChoisissez un appât (ou 0 pour quitter) : ")) - 1
        if choix_appat == -1:
            return
        if 0 <= choix_appat < len(appats_liste):
            appat_nom, info = appats_liste[choix_appat]
            appat = info["item"]
            quantite = info["quantite"]
            tous = input(f"Voulez-vous utiliser tous les {quantite} {appat_nom} ? (o/n) : ").lower() == 'o'

            if tous:
                for _ in range(quantite):
                    if canne.durabilite <= 0:
                        print(f"{Fore.RED}Votre Canne à Pêche est cassée !{Style.RESET_ALL}")
                        joueur.inventaire.remove(canne)
                        return
                    if not any(item.nom == appat_nom for item in joueur.inventaire):
                        print(f"{Fore.RED}Plus de {appat_nom} disponible !{Style.RESET_ALL}")
                        break
                    appat_instance = next(item for item in joueur.inventaire if item.nom == appat_nom)
                    joueur.inventaire.remove(appat_instance)
                    print(f"\n{Fore.YELLOW}Vous pêchez avec {appat_nom}...{Style.RESET_ALL}")
                    time.sleep(2)
                    canne.durabilite -= 1
                    if random.random() < 0.1:  # 10% chance to encounter a fishable monster
                        monstre = random.choice(list(monstres_peche.values()))
                        print(f"{Fore.RED}Un {monstre.nom} a mordu à l'hameçon !{Style.RESET_ALL}")
                        while monstre.est_vivant() and joueur.est_vivant():
                            print(f"\n{Fore.CYAN}Votre santé: {joueur.sante}/{joueur.sante_max} | Santé du monstre: {monstre.sante}{Style.RESET_ALL}")
                            action = input("\n1. Attaquer\n2. Utiliser un objet\n3. Relâcher\nChoisissez une action : ")
                            if action == "1":
                                joueur.attaquer(monstre)
                                if monstre.est_vivant():
                                    monstre.attaquer(joueur)
                            elif action == "2":
                                joueur.voir_inventaire()
                            elif action == "3":
                                print(f"{Fore.YELLOW}Vous relâchez le {monstre.nom}.{Style.RESET_ALL}")
                                break
                            else:
                                print(f"{Fore.RED}Action invalide.{Style.RESET_ALL}")
                        if monstre.sante <= 0:
                            loot = generer_loot(monstre.loot)
                            joueur.ajouter_objet(loot)
                            joueur.experience += 50
                            joueur.verifier_niveau()
                    else:
                        poisson = generer_loot(loot_poissons)[0]
                        joueur.ajouter_objet(poisson)
                        print(f"{Fore.GREEN}Vous avez pêché un {poisson.nom} !{Style.RESET_ALL}")
                        joueur.experience += 10
                        joueur.verifier_niveau()
            else:
                if canne.durabilite <= 0:
                    print(f"{Fore.RED}Votre Canne à Pêche est cassée !{Style.RESET_ALL}")
                    joueur.inventaire.remove(canne)
                    return
                joueur.inventaire.remove(appat)
                print(f"\n{Fore.YELLOW}Vous commencez à pêcher avec {appat.nom}...{Style.RESET_ALL}")
                time.sleep(2)
                canne.durabilite -= 1
                if random.random() < 0.1:  # 10% chance to encounter a fishable monster
                    monstre = random.choice(list(monstres_peche.values()))
                    print(f"{Fore.RED}Un {monstre.nom} a mordu à l'hameçon !{Style.RESET_ALL}")
                    while monstre.est_vivant() and joueur.est_vivant():
                        print(f"\n{Fore.CYAN}Votre santé: {joueur.sante}/{joueur.sante_max} | Santé du monstre: {monstre.sante}{Style.RESET_ALL}")
                        action = input("\n1. Attaquer\n2. Utiliser un objet\n3. Relâcher\nChoisissez une action : ")
                        if action == "1":
                            joueur.attaquer(monstre)
                            if monstre.est_vivant():
                                monstre.attaquer(joueur)
                        elif action == "2":
                            joueur.voir_inventaire()
                        elif action == "3":
                            print(f"{Fore.YELLOW}Vous relâchez le {monstre.nom}.{Style.RESET_ALL}")
                            return
                        else:
                            print(f"{Fore.RED}Action invalide.{Style.RESET_ALL}")
                    if monstre.sante <= 0:
                        loot = generer_loot(monstre.loot)
                        joueur.ajouter_objet(loot)
                        joueur.experience += 50
                        joueur.verifier_niveau()
                else:
                    poisson = generer_loot(loot_poissons)[0]
                    joueur.ajouter_objet(poisson)
                    print(f"{Fore.GREEN}Vous avez pêché un {poisson.nom} !{Style.RESET_ALL}")
                    joueur.experience += 10
                    joueur.verifier_niveau()
            if canne.durabilite <= 0:
                print(f"{Fore.RED}Votre Canne à Pêche est cassée !{Style.RESET_ALL}")
                joueur.inventaire.remove(canne)
        else:
            print(f"{Fore.RED}Choix invalide.{Style.RESET_ALL}")
    except ValueError:
        print(f"{Fore.RED}Entrée invalide.{Style.RESET_ALL}")

def admin_menu(joueur):
    print(f"\n{Fore.RED}=== Mode Admin ==={Style.RESET_ALL}")
    username = input("Nom d'utilisateur : ")
    password = input("Mot de passe : ")
    if username == "admin" and password == "admin":
        while True:
            print(f"\n{Fore.RED}╔════ Menu Admin ════╗{Style.RESET_ALL}")
            print("║ 1. Modifier stats")
            print("║ 2. Ajouter argent")
            print("║ 3. Ajouter objet")
            print("║ 4. Ajouter expérience")
            print("║ 5. Donner toutes les armes")
            print("║ 6. Donner toutes les armures")
            print("║ 7. Donner tous les objets")
            print("║ 8. Quitter")
            print(f"╚════════════════════╝{Style.RESET_ALL}")

            try:
                choix = input("\nChoisissez une option : ")
                if choix == "1":
                    joueur.niveau = int(input("Nouveau niveau : "))
                    joueur.force = int(input("Nouvelle force : "))
                    joueur.sante_max = int(input("Nouvelle santé max : "))
                    joueur.sante = joueur.sante_max
                    print(f"{Fore.GREEN}Stats modifiées !{Style.RESET_ALL}")
                elif choix == "2":
                    argent = int(input("Argent à ajouter : "))
                    joueur.argent += argent
                    print(f"{Fore.GREEN}{argent} pièces ajoutées !{Style.RESET_ALL}")
                elif choix == "3":
                    nom = input("Nom de l'objet : ")
                    rarete = input("Rareté : ")
                    valeur = int(input("Valeur : "))
                    type_objet = input("Type (arme/armure/nourriture/boisson/appat/outil/général) : ")
                    stats = None
                    durabilite = None
                    if type_objet == "arme":
                        min_degats = int(input("Dégâts min : "))
                        max_degats = int(input("Dégâts max : "))
                        stats = (min_degats, max_degats)
                        durabilite = int(input("Durabilité : "))
                    elif type_objet == "armure":
                        stats = int(input("Protection (%) : "))
                        durabilite = int(input("Durabilité : "))
                    elif type_objet in ["nourriture", "boisson"]:
                        stats = int(input("Points de restauration : "))
                    elif type_objet == "outil":
                        durabilite = int(input("Durabilité : "))
                    joueur.ajouter_objet(Item(nom, rarete, valeur, type_objet, stats, durabilite))
                    print(f"{Fore.GREEN}Objet ajouté !{Style.RESET_ALL}")
                elif choix == "4":
                    exp = int(input("Expérience à ajouter : "))
                    joueur.experience += exp
                    joueur.verifier_niveau()
                    print(f"{Fore.GREEN}{exp} expérience ajoutée !{Style.RESET_ALL}")
                elif choix == "5":
                    all_weapons = set()
                    for loot_table in [loot_gobelin, loot_orc, loot_esprit, loot_dragon, loot_loup, loot_wyverne, loot_araignee,
                                      loot_zombie, loot_troll, loot_squelette, loot_golem, loot_lezard, loot_minotaure,
                                      loot_cerbere, loot_slime, loot_kraken, loot_griffon, loot_hydre, loot_spectre,
                                      loot_basilic, loot_boss1, loot_boss2, loot_boss3, loot_boss4, loot_boss5, loot_boss6,
                                      loot_boss7, loot_boss8, loot_boss9, loot_boss10, loot_abyssal_serpent, loot_coral_behemoth]:
                        for item in loot_table:
                            if item.type_objet == "arme":
                                all_weapons.add(item.nom)
                    for item in magasins["Forgeron"] + magasins["Boutique"]:
                        if item.type_objet == "arme":
                            all_weapons.add(item.nom)
                    for weapon_name in all_weapons:
                        for loot_table in [loot_gobelin, loot_orc, loot_esprit, loot_dragon, loot_loup, loot_wyverne, loot_araignee,
                                          loot_zombie, loot_troll, loot_squelette, loot_golem, loot_lezard, loot_minotaure,
                                          loot_cerbere, loot_slime, loot_kraken, loot_griffon, loot_hydre, loot_spectre,
                                          loot_basilic, loot_boss1, loot_boss2, loot_boss3, loot_boss4, loot_boss5, loot_boss6,
                                          loot_boss7, loot_boss8, loot_boss9, loot_boss10, loot_abyssal_serpent, loot_coral_behemoth]:
                            for item in loot_table:
                                if item.nom == weapon_name:
                                    joueur.ajouter_objet(Item(item.nom, item.rarete, item.valeur, item.type_objet, item.stats, item.durabilite))
                                    break
                        for item in magasins["Forgeron"] + magasins["Boutique"]:
                            if item.nom == weapon_name:
                                joueur.ajouter_objet(Item(item.nom, item.rarete, item.valeur, item.type_objet, item.stats, item.durabilite))
                                break
                    print(f"{Fore.GREEN}Toutes les armes ont été ajoutées !{Style.RESET_ALL}")
                elif choix == "6":
                    all_armors = set()
                    for loot_table in [loot_gobelin, loot_orc, loot_esprit, loot_dragon, loot_loup, loot_wyverne, loot_araignee,
                                      loot_zombie, loot_troll, loot_squelette, loot_golem, loot_lezard, loot_minotaure,
                                      loot_cerbere, loot_slime, loot_kraken, loot_griffon, loot_hydre, loot_spectre,
                                      loot_basilic, loot_boss1, loot_boss2, loot_boss3, loot_boss4, loot_boss5, loot_boss6,
                                      loot_boss7, loot_boss8, loot_boss9, loot_boss10, loot_abyssal_serpent, loot_coral_behemoth]:
                        for item in loot_table:
                            if item.type_objet == "armure":
                                all_armors.add(item.nom)
                    for item in magasins["Forgeron"] + magasins["Boutique"]:
                        if item.type_objet == "armure":
                            all_armors.add(item.nom)
                    for armor_name in all_armors:
                        for loot_table in [loot_gobelin, loot_orc, loot_esprit, loot_dragon, loot_loup, loot_wyverne, loot_araignee,
                                          loot_zombie, loot_troll, loot_squelette, loot_golem, loot_lezard, loot_minotaure,
                                          loot_cerbere, loot_slime, loot_kraken, loot_griffon, loot_hydre, loot_spectre,
                                          loot_basilic, loot_boss1, loot_boss2, loot_boss3, loot_boss4, loot_boss5, loot_boss6,
                                          loot_boss7, loot_boss8, loot_boss9, loot_boss10, loot_abyssal_serpent, loot_coral_behemoth]:
                            for item in loot_table:
                                if item.nom == armor_name:
                                    joueur.ajouter_objet(Item(item.nom, item.rarete, item.valeur, item.type_objet, item.stats, item.durabilite))
                                    break
                        for item in magasins["Forgeron"] + magasins["Boutique"]:
                            if item.nom == armor_name:
                                joueur.ajouter_objet(Item(item.nom, item.rarete, item.valeur, item.type_objet, item.stats, item.durabilite))
                                break
                    print(f"{Fore.GREEN}Toutes les armures ont été ajoutées !{Style.RESET_ALL}")
                elif choix == "7":
                    all_items = set()
                    for loot_table in [loot_gobelin, loot_orc, loot_esprit, loot_dragon, loot_loup, loot_wyverne, loot_araignee,
                                      loot_zombie, loot_troll, loot_squelette, loot_golem, loot_lezard, loot_minotaure,
                                      loot_cerbere, loot_slime, loot_kraken, loot_griffon, loot_hydre, loot_spectre,
                                      loot_basilic, loot_boss1, loot_boss2, loot_boss3, loot_boss4, loot_boss5, loot_boss6,
                                      loot_boss7, loot_boss8, loot_boss9, loot_boss10, loot_abyssal_serpent, loot_coral_behemoth, loot_poissons]:
                        for item in loot_table:
                            all_items.add(item.nom)
                    for magasin in magasins.values():
                        for item in magasin:
                            all_items.add(item.nom)
                    for item_name in all_items:
                        for loot_table in [loot_gobelin, loot_orc, loot_esprit, loot_dragon, loot_loup, loot_wyverne, loot_araignee,
                                          loot_zombie, loot_troll, loot_squelette, loot_golem, loot_lezard, loot_minotaure,
                                          loot_cerbere, loot_slime, loot_kraken, loot_griffon, loot_hydre, loot_spectre,
                                          loot_basilic, loot_boss1, loot_boss2, loot_boss3, loot_boss4, loot_boss5, loot_boss6,
                                          loot_boss7, loot_boss8, loot_boss9, loot_boss10, loot_abyssal_serpent, loot_coral_behemoth, loot_poissons]:
                            for item in loot_table:
                                if item.nom == item_name:
                                    joueur.ajouter_objet(Item(item.nom, item.rarete, item.valeur, item.type_objet, item.stats, item.durabilite))
                                    break
                        for magasin in magasins.values():
                            for item in magasin:
                                if item.nom == item_name:
                                    joueur.ajouter_objet(Item(item.nom, item.rarete, item.valeur, item.type_objet, item.stats, item.durabilite))
                                    break
                    print(f"{Fore.GREEN}Tous les objets ont été ajoutés !{Style.RESET_ALL}")
                elif choix == "8":
                    break
                else:
                    print(f"{Fore.RED}Option invalide.{Style.RESET_ALL}")
            except ValueError:
                print(f"{Fore.RED}Entrée invalide.{Style.RESET_ALL}")
    else:
        print(f"{Fore.RED}Accès refusé !{Style.RESET_ALL}")

patch_notes = [
    "Version 1.0.0 (Initial Release): Lancement de Dexzi Online avec donjons, boss, pêche, quêtes et crafting.",
    "Version 1.1.0: Ajout de l'Épicerie, achat multiple d'appâts, loot unique par monstre, perte d'équipement à la mort.",
    "Version 1.2.0 (Latest): Correction du bug des donjons, affichage de tous les boss, utilisation de tous les appâts, durabilité de la canne à pêche, menu Patch Notes, améliorations de l'admin menu, crédit baptistedev.fr."
]

def main():
    print(f"{Fore.MAGENTA}Bienvenue dans Dexzi Online ! Powered by baptistedev.fr{Style.RESET_ALL}")
    nom = input("Entrez le nom de votre personnage : ")
    joueur = Joueur(nom)
    assigner_quetes(joueur)

    while True:
        joueur.nourriture = max(0, joueur.nourriture - 1)
        joueur.soif = max(0, joueur.soif - 1)
        if joueur.nourriture <= 0 or joueur.soif <= 0:
            joueur.sante -= 10
            print(f"{Fore.RED}Faim ou soif critique ! Santé réduite : {joueur.sante}.{Style.RESET_ALL}")

        if joueur.sante <= 0:
            print(f"{Fore.RED}{joueur.nom} est mort !{Style.RESET_ALL}")
            joueur.arme = None
            joueur.armure = None
            joueur.sante = joueur.sante_max
            joueur.nourriture = joueur.nourriture_max
            joueur.soif = joueur.soif_max
            joueur.argent = int(joueur.argent * 0.5)
            print(f"{Fore.YELLOW}Vous avez perdu votre équipement et 50% de votre argent. Réapparition...{Style.RESET_ALL}")

        print(f"\n{Fore.MAGENTA}╔════ Menu Principal ════╗{Style.RESET_ALL}")
        print(f"║ Powered by baptistedev.fr")
        print(f"║ 1. Afficher stats")
        print(f"║ 2. Voir inventaire")
        print(f"║ 3. Aller au donjon")
        print(f"║ 4. Affronter un boss")
        print(f"║ 5. Magasin")
        print(f"║ 6. Vendre objets")
        print(f"║ 7. Pêcher")
        print(f"║ 8. Crafter")
        print(f"║ 9. Réparer équipement")
        print(f"║ 10. Voir quêtes")
        print(f"║ 11. Mode admin")
        print(f"║ 12. Quitter")
        print(f"║ 13. Voir les Patch Notes")
        print(f"╚════════════════════════╝{Style.RESET_ALL}")

        try:
            choix = input("\nChoisissez une option : ")
            if choix == "1":
                joueur.afficher_stats()
            elif choix == "2":
                joueur.voir_inventaire()
            elif choix == "3":
                donjon(joueur)
            elif choix == "4":
                menu_boss(joueur)
            elif choix == "5":
                magasin(joueur)
            elif choix == "6":
                vendre_objets(joueur)
            elif choix == "7":
                pecher(joueur)
            elif choix == "8":
                craft(joueur)
            elif choix == "9":
                joueur.reparer_equipement()
            elif choix == "10":
                if joueur.quetes:
                    print(f"\n{Fore.MAGENTA}╔════ Quêtes Actives ════╗{Style.RESET_ALL}")
                    for quete in joueur.quetes:
                        print(f"║ {quete.nom}: {quete.progression}/{quete.quantite} ({quete.cible})")
                    print(f"╚════════════════════════╝{Style.RESET_ALL}")
                else:
                    print(f"{Fore.RED}Aucune quête active.{Style.RESET_ALL}")
                assigner_quetes(joueur)
            elif choix == "11":
                admin_menu(joueur)
            elif choix == "12":
                print(f"{Fore.YELLOW}Merci d'avoir joué !{Style.RESET_ALL}")
                break
            elif choix == "13":
                print(f"\n{Fore.MAGENTA}╔════ Patch Notes ════╗{Style.RESET_ALL}")
                for note in patch_notes:
                    prefix = "★ " if note.startswith("Version 1.2.0") else "  "
                    print(f"║ {prefix}{note}")
                print(f"╚═════════════════════╝{Style.RESET_ALL}")
            else:
                print(f"{Fore.RED}Option invalide.{Style.RESET_ALL}")
        except ValueError:
            print(f"{Fore.RED}Entrée invalide.{Style.RESET_ALL}")

if __name__ == "__main__":
    main()