def remplir_objet(conteneur, objet): """Met l'objet dans le conteneur de nourriture. Attention, l'objet conteneur ne peut en aucun cas être "flottant" mais doit lui-même être contenu quelque part (sol d'une salle, inventaire d'un personnage, autre conteneur...). """ if not conteneur.contenu: raise ErreurExecution("{} n'est contenu nul part".format( conteneur.get_nom())) if conteneur.est_de_type("conteneur de potion"): if conteneur.potion: raise ErreurExecution("{} est plein".format( conteneur.get_nom())) if objet.contenu: objet.contenu.retirer(objet) conteneur.potion = objet conteneur.onces = conteneur.onces_max return if not conteneur.est_de_type("conteneur de nourriture"): raise ErreurExecution("{} n'est pas un conteneur".format( conteneur.get_nom())) if objet.poids_unitaire > conteneur.poids_max: raise ErreurExecution("{} est plein".format(conteneur.get_nom())) if objet.contenu: objet.contenu.retirer(objet) conteneur.nourriture.append(objet)
def ajouter_chapitre(cle_livre, titre, texte): """Ajoute un chapitre au livre précisé en paramètre. Paramètres à préciser : * cle_livre : la clé identifiant le prototype d'objet de type livre ; * titre : une chaîne de caractères contenant le titre du chapitre ; * texte : une chaîne de caractères contenant le texte du chapitre. Cette action modifie les chapitres du prototype d'objet. Tous les objets créés sur ce prototype sont donc affectés. Exemple d'utilisation : ajouter_chapitre "chants_noel" "Jingle bells" "Dashin' through the snow" """ cle_livre = cle_livre.lower() try: livre = importeur.objet.prototypes[cle_livre] except KeyError: raise ErreurExecution("le prototype d'objet {} est " \ "introuvable".format(repr(cle_livre))) if not livre.est_de_type("livre"): raise ErreurExecution("le prototype d'objet {} n'est pas " \ "de type livre".format(repr(cle_livre))) chapitre = livre.ajouter_chapitre(titre) texte = texte.replace("_b_nl_b_", "\n") chapitre.description.paragraphes[:] = texte.split("\n")
def xp_secondaire(personnage, niveau_secondaire, niveau_prevu, pourcentage): """Donne l'XP absolue au personnage dans le niveau secondaire. Le nom du niveau secondaire doit être donné en son entier. Une partie de l'XP est automatiquement transmise au niveau principal. Note : l'XP relative est calculée pour le niveau secondaire mais pas pour le niveau principal. Le niveau principal actuel n'est pas pris en compte dans le calcul de l'XP relative. """ niveaux = [n for n in importeur.perso.niveaux.values() if \ supprimer_accents(n.nom).lower() == supprimer_accents( niveau_secondaire)] if not niveaux: raise ErreurExecution( "le niveau {} est introuvable".format(niveau_secondaire)) niveau_prevu = int(niveau_prevu) if niveau_prevu < 1 or niveau_prevu > \ importeur.perso.gen_niveaux.nb_niveaux: raise ErreurExecution("le niveau prévu doit être entre 1 et " \ "{}".format(importeur.perso.gen_niveaux.nb_niveaux)) personnage.gagner_xp_rel(niveau_prevu, int(pourcentage), niveaux[0].cle)
def remplir_proto_nb(conteneur, prototype, nb): """Pose dans le conteneur nb objets du prototype précisé. Attention, l'objet conteneur ne peut en aucun cas être "flottant" mais doit lui-même être contenu quelque part (sol d'une salle, inventaire d'un personnage, autre conteneur...). """ nb = int(nb) if not prototype in importeur.objet.prototypes: raise ErreurExecution("prototype {} introuvable".format(prototype)) prototype = importeur.objet.prototypes[prototype] if not conteneur.contenu: raise ErreurExecution("{} n'est contenu nul part".format( conteneur.get_nom())) if conteneur.est_de_type("conteneur de potion"): if conteneur.potion: raise ErreurExecution("{} est plein".format( conteneur.get_nom())) objet = importeur.objet.creer_objet(prototype) conteneur.potion = objet conteneur.onces = conteneur.onces_max return if not conteneur.est_de_type("conteneur de nourriture"): raise ErreurExecution("{} n'est pas un conteneur".format( conteneur.get_nom())) poids_total = 0 for i in range(nb): poids_total += prototype.poids if poids_total > conteneur.poids_max: raise ErreurExecution("{} est plein".format( conteneur.get_nom())) objet = importeur.objet.creer_objet(prototype) conteneur.nourriture.append(objet)
def creer_familier(prototype, maitre): """Crée un familier sur le prototype précisé. Paramètres à préciser : * prototype : la clé du prototype (celle de la fiche de familier) * maitre : le personnage qui deviendra le maître du familier Cette fonction retourne le PNJ créé, comme 'creer_PNJ'. Prenez garde de toujours stocker les PNJs créés dans des variables afin de ne pas créer de PNJs fantômes. """ if not prototype in importeur.pnj.prototypes: raise ErreurExecution("prototype {} introuvable".format(prototype)) if not prototype in importeur.familier.fiches: raise ErreurExecution("fiche de familier {} introuvable".format( prototype)) prototype = importeur.pnj.prototypes[prototype] if prototype.squelette is None: raise ErreurExecution("prototype {} sans squelette".format( prototype)) pnj = importeur.pnj.creer_PNJ(prototype) familier = importeur.familier.creer_familier(pnj) familier.maitre = maitre familier.trouver_nom() return pnj
def creer_familier_PNJ(pnj, maitre): """Crée un familier sur le PNJ existant. Paramètres à préciser : * pnj : le PNJ existant * maitre : le personnage qui deviendra le maître du familier Cette fonction travaille sur un PNJ déjà existant. Le PNJ doit avoir une fiche de familier valide (et ne pas déjà être un familier). Le PNJ est retourné. """ cle = getattr(pnj, "cle", None) identifiant = getattr(pnj, "identifiant", None) if cle not in importeur.familier.fiches: raise ErreurExecution("aucune fiche de famillier associée " \ "au personnage {}".format(repr(pnj))) if identifiant in importeur.familier.familiers: raise ErreurExecution("le PNJ {} est déjà un familier".format( repr(pnj))) familier = importeur.familier.creer_familier(pnj) familier.maitre = maitre familier.trouver_nom() return pnj
def creer_sortie(salle, direction, destination): """Crée une sortie de salle dans la direction vers la destination. La direction est à choisir parmi est, ouest, nord, sud, nord-est, nord-ouest, sud-est, sud-ouest, haut et bas. """ try: direction = salle.sorties.get_nom_long(direction) except KeyError: raise ErreurExecution("direction {} inconnue".format(direction)) dir_opposee = salle.sorties.get_nom_oppose(direction) if salle.sorties.sortie_existe(direction): raise ErreurExecution("sortie {} déjà définie dans {}".format( direction, salle)) if destination.sorties.sortie_existe(dir_opposee): raise ErreurExecution( "sortie opposée déjà définie dans {}".format(destination)) if salle is destination: raise ErreurExecution("salle et destination confondues") salle.sorties.ajouter_sortie(direction, direction, salle_dest=destination, corresp=dir_opposee) destination.sorties.ajouter_sortie(dir_opposee, dir_opposee, salle_dest=salle, corresp=direction)
def equiper_prototype(personnage, cle_prototype): """Fait équiper un objet à un personnage. Paramètres à préciser : * personnage : le personnage qui doit s'équiper * cle_prototype : la clé du prototype d'objet à équiper Exemple d'utilisation : equiper personnage "sabre_bois" Le personnage n'a pas besoin d'avoir l'objet indiqué dans son inventaire : il sera dans tous les cas créé. En outre, cette action ne vérifie pas que le joueur peut s'équiper à cet emplacement (utilisez la fonction 'peut_equiper' pour vérifier cela). """ if not cle_prototype in importeur.objet.prototypes: raise ErreurExecution("prototype d'objet {} introuvable".format( repr(cle_prototype))) prototype = importeur.objet.prototypes[cle_prototype] objet = importeur.objet.creer_objet(prototype) for membre in personnage.equipement.membres: if membre.peut_equiper(objet): membre.equiper(objet) return raise ErreurExecution("le personnage {} ne peut équiper {}".format( repr(personnage), repr(objet.cle)))
def desaffecter_personnage(personnage, affection): """Retire l'affection au personnage. Les paramètres à préciser sont : * personnage : le personnage à désaffecter * affection : la clé de l'affection sous la forme d'une chaîne. Si le personnage n'est pas aff"ecté par l'affection précisée, une alerte est levée. """ # Essaye de trouver l'affection cle = affection.lower() try: affection = importeur.affection.get_affection("personnage", cle) except KeyError: raise ErreurExecution("l'affection {} n'existe pas".format( repr(cle))) if cle not in personnage.affections: raise ErreurExecution("le personnage n'est pas affecté par " \ "cette affection") personnage.affections.pop(cle).detruire()
def recuperer_chaine(chaine, indice): """Récupère la lettre à la position spécifiée. Une chaîne est un ensemble composite au même titre qu'une liste. Elle ne contient que des lettres, cependant (des caractères, qui sont des chaînes de caractère de longueur 1). Vous pouvez utiliser cette fonction la lettre en début ou en fin d'une chaîne, par exemple. Paramètres à préciser : * chaine : la chaîne utilisée ; * indice : l'indice (numéro de la case où se trouve la lettre). Exemples d'utilisation : # Récupère la première lettre de la chaîne premiere = recuperer("juste quelques mots", 1) # 'premiere' contient "j" derniere = recuperer("juste quelques mots", -1) # 'derniere' contient "s" """ indice = int(indice) if indice > 0: if indice > len(chaine): raise ErreurExecution("L'indice précisé ({}) est trop " \ "important pour la chaîne {}.".format( indice, repr(chaine))) indice -= 1 elif indice < 0: if -indice > len(chaine): raise ErreurExecution("L'indice précisé ({}) est trop " \ "important pour la chaîne {}.".format( indice, repr(chaine))) else: raise ErreurExecution("L'indice précisé vaut 0.") return chaine[indice]
def desaffecter_salle(salle, affection): """Retire l'affection à la salle. Les paramètres à préciser sont : * salle : la salle à désaffecter * affection : la clé de l'affection sous la forme d'une chaîne. Si la salle n'est pas affectée par l'affection précisée, une alerte est créée. """ # Essaye de trouver l'affection cle = affection.lower() try: affection = importeur.affection.get_affection("salle", cle) except KeyError: raise ErreurExecution("l'affection {} n'existe pas".format( repr(cle))) if cle not in salle.affections: raise ErreurExecution("la salle n'est pas affectée par " \ "cette affection") salle.affections.pop(cle).detruire()
def ajouter_magasin(salle, quantite, service, cle): """Ajoute un service à l'inventaire du magasin. Paramètres à préciser : * salle : la salle contenant le magasin * quantite : la quantité de services à ajouter * service : le type de service (objet, potion, navire...) * cle : la clé du service (la clé de l'objet par exemple) Cette action s'utilise de façon très similaire à l'option /s dans l'éditeur de magasin d'une salle. Le service et la clé ont besoin d'être utilisés conjointement : le service le plus simple est 'objet' qui permet d'ajouter un ou plusieurs objets à la vente dans le magasin. Mais un magasin peut vendre d'autres services, comme des potions, de la nourriture, des navires, des familiers, des matelots, ainsi de suite. Pour chaque type de service, le nom à entrer est différent. Notez cependant qu'à la différence de l'option /s dans l'éditeur du magasin d'une salle, cette action ajoute le service directement dans l'inventaire du magasin, ce qui veut dire qu'il sera proposé en vente. En revanche, cela veut aussi dire qu'au renouvellement du magasin, qui arrive généralement au moins une fois par jour IG, le service ajouté disparaîtra. Exemples d'utilisation : salle = salle("zone:mnemo") # Ajoute 5 objets 'chausse_laine' ajouter salle 5 "objet" "chaussette_laine" # Ajoute 2 navires 'barque_peche' ajouter salle 2 "navire" "barque_peche" # Ajoute 4 familiers 'cheval_blanc' ajouter salle 4 "familier" "cheval_blanc" """ quantite = int(quantite) if quantite < 1: raise ErreurExecution( "Quantité {} négative ou nulle".format(quantite)) if service not in importeur.commerce.types_services: raise ErreurExecution("Type de service {} inconnu".format( repr(service))) objets = importeur.commerce.types_services[service] if cle not in objets: raise ErreurExecution("le produit {} de service {} n'a " \ "pas pu être trouvé".format(repr(cle), repr(service))) service = objets[cle] salle.magasin.ajouter_inventaire(service, quantite)
def bloc_existe(scriptable, nom_bloc): """Retourne vrai si le bloc existe dans le scriptable, False sinon. Paramètres à entrer : * scriptable : le scriptable (salle, objet, PNJ, ... ou chaîne) * nom_bloc : le nom du bloc dont on veut vérifier la présence. Vous pouvez entrer une information de localisation de scriptable sous la forme d'une chaîne. Par exemple "zone picte" pour faire référence au scriptable de la zone picte. Exemple d'utilisation : si bloc_existe(salle, "fondre"): appeler salle "fondre" finsi """ scriptables = importeur.scripting.valeurs if isinstance(scriptable, str): scriptable = supprimer_accents(scriptable).lower() trouve = False for nom, dictionnaire in scriptables.items(): if scriptable.startswith(nom): cle = scriptable[len(nom) + 1:].lower() if cle not in dictionnaire: raise ErreurExecution("Impossible de trouver " \ "le scriptable {} : clé {} " \ "introuvable".format(repr(scriptable), repr(cle))) trouve = True scriptable = dictionnaire[cle] break if not trouve: raise ErreurExecution("Impossible de trouver le scriptable " \ "{} : type d'information introuvable".format( repr(scriptable), repr(cle))) elif not hasattr(scriptable, "script"): raise ErreurExecution("le scriptable {} ne semble pas avoir " \ "de script".format(scriptable)) script = scriptable.script try: bloc = script.blocs[nom_bloc] except KeyError: return False return True
def appeler(appelant, nom, *parametres): """Appelle un bloc d'instruction. Cette action prend au moins deux paramètres : * Le script contenant le bloc. Si le bloc est défini dans le script d'une salle précis, passez en premier paramètre cette salle. * Le nom du bloc à appeler. Les autres paramètres dépendent du bloc : celui-ci peut avoir aucun, un ou plusieurs paramètres. Vous devez les appeler dans l'ordre dans cette action. Notez qu'à la place de l'appelant (premier paramètre), vous pouvez préciser un nom (chaîne) identifiant le scriptable. Par exemple, "zone picte" ou "salle picte:8". """ scriptables = importeur.scripting.valeurs if isinstance(appelant, str): appelant = supprimer_accents(appelant).lower() trouve = False for t_nom, dictionnaire in scriptables.items(): if appelant.startswith(t_nom): cle = appelant[len(t_nom) + 1:].lower() if cle not in dictionnaire: raise ErreurExecution("Impossible de trouver " \ "le scriptable {} : clé {} " \ "introuvable".format(repr(appelant), repr(cle))) trouve = True appelant = dictionnaire[cle] break if not trouve: raise ErreurExecution("Impossible de trouver le scriptable " \ "{} : type d'information introuvable".format( repr(appelant), repr(cle))) elif not hasattr(appelant, "script"): raise ErreurExecution("l'appelant {} ne semble pas avoir " \ "de script".format(appelant)) script = appelant.script try: bloc = script.blocs[nom] except KeyError: raise ErreurExecution("le bloc {} ne peut être trouvé dans " \ "l'appelant {}".format(repr(nom), appelant)) return bloc.executer(*parametres)
def direction(origine, destination, flags=""): """Retourne la direction entre deux salles. Les deux salles doivent avoir des coordonnées valides. La direction retournée est la direction absolue (est, sud-est, sud, sud-ouest...). Les flags permettent de préciser des options pour demander par exemple l'article (avoir "l'est", "le sud-est", "le sud"... précisés). Voir les exemples plus bas. Paramètres à préciser : * origine : la salle d'origine * destination : la salle de destination Flags possibles (troisième paramètre) : * complet : l'article est retourné avec le nom de la sortie Exemples d'utilisation : origine = salle("depart:1") destination = salle("depart:5") # Pour aller de depart:1 en depart:5 il faut prendre la sortie sud nom = direction(origine, destination) # nom contient maintenant "sud" nom = direction(origine, destination, "complet") # Cette fois nom contient "le sud" """ flags = flags.lower().split(" ") if origine is destination: raise ErreurExecution("{} est identique à {}".format( origine, destination)) if not origine.coords.valide: raise ErreurExecution( "{} n'a pas de coordonnées valides".format(origine)) if not destination.coords.valide: raise ErreurExecution( "{} n'a pas de coordonnées valides".format(destination)) o_x, o_y, o_z = origine.coords.tuple() d_x, d_y, d_z = destination.coords.tuple() vecteur = Vecteur(d_x - o_x, d_y - o_y, d_z - o_z) sortie = origine.get_sortie(vecteur, destination) retour = sortie.nom if "complet" in flags: retour = sortie.nom_complet return retour
def apparaitre_proto_nb(salle, prototype, nb): """Fait apparaître dans la salle nb PNJs modelés sur le prototype.""" nb = int(nb) if not prototype in importeur.pnj.prototypes: raise ErreurExecution("prototype {} introuvable".format(prototype)) prototype = importeur.pnj.prototypes[prototype] if prototype.squelette is None: raise ErreurExecution( "prototype {} sans squelette".format(prototype)) i = 0 while i < nb: pnj = importeur.pnj.creer_PNJ(prototype) pnj.salle = salle i += 1
def equiper_objet(personnage, objet): """Force un personnage à équiper l'objet précisé. Cette syntaxe de l'action se rapproche davantage de la commande **porter/wear**. Elle demande à un personnage d'équiper un objet qu'il possède (dans ses mains, ou dans un sac qu'il équipe). Paramètres à préciser : * personnage : le personnage que l'on souhaite équiper * objet : l'objet que l'on souhaite équiper. Cette action est susceptible de faire des erreurs, par exemple, si l'objet n'est pas possédé par le personnage ou si il ne peut être équipé par le personnage. Il est de bonne politique de tester avant d'équiper le personnage, sauf si on est dans une situation extrêmement limitée en aléatoire. Exemple d'utilisation : # On cherche à faire équiper un sabre de bois au personnage # Le personnage possède le sabre de bois dans son inventaire sabre = possede(personnage, "sabre_bois") si sabre: # On vérifié qu'il n'a rien dans la main gauche si !equipe(personnage, "*main gauche"): equiper personnage sabre finsi finsi """ if not any(o for o in personnage.equipement.inventaire if o is objet): raise ErreurExecution("{} ne possède visiblement pas {}".format( personnage.nom_unique, objet.identifiant)) # Si 'objet' est déjà équipé, ne fait rien if objet.contenu is personnage.equipement.equipes: return # Essaye d'équiper l'objet sur un membre for membre in personnage.equipement.membres: if membre.peut_equiper(objet): objet.contenu.retirer(objet) membre.equiper(objet) objet.script["porte"].executer(objet=objet, personnage=personnage) return raise ErreurExecution("{} ne peut équiper {}, aucun emplacement " \ "libre".format(personnage.nom_unique, objet.identifiant))
def fermee(salle, nom_sortie): """Retourne vrai si la sortie de la salle est fermée, faux sinon. NOTE: si la sortie indiquée n'est pas une porte, une erreur est envoyée. """ sortie = salle.sorties.get_sortie_par_nom_ou_direction(nom_sortie) if sortie is None: raise ErreurExecution("la sortie {} n'existe pas dans la " \ "salle {}".format(repr(nom_sortie), repr(salle.ident))) if not sortie.porte: raise ErreurExecution("cette sortie n'a aucune porte") return sortie.porte.fermee
def donner_prototype_nb(personnage, prototype, nb): """Donne au personnage nb objets modelés sur le prototype précisé.""" nb = int(nb) if not prototype in importeur.objet.prototypes: raise ErreurExecution("prototype {} introuvable".format(prototype)) prototype = importeur.objet.prototypes[prototype] for i in range(nb): objet = importeur.objet.creer_objet(prototype) if not objet.peut_prendre: raise ErreurExecution("{} ne peut pas être manipulé".format( objet.get_nom())) dans = personnage.ramasser(objet) if dans is None: raise ErreurExecution("{} ne peut pas prendre {}".format( personnage.nom, objet.get_nom()))
def creer_PNJ(prototype): """Crée un PNJ sur le prototype précisé. Prenez garde de toujours stocker les PNJs créés dans des variables afin de ne pas créer de PNJs fantômes. """ if not prototype in importeur.pnj.prototypes: raise ErreurExecution("prototype {} introuvable".format(prototype)) prototype = importeur.pnj.prototypes[prototype] if prototype.squelette is None: raise ErreurExecution( "prototype {} sans squelette".format(prototype)) pnj = importeur.pnj.creer_PNJ(prototype) return pnj
def noms(type): """Retourne les noms des informations demandées. Paramètres à préciser : * type : le type d'information (voir plus bas). Types possibles : * "joueur" : retourne le nom des joueurs ; * "salle" : retourne les identifiants de toutes les salles ; * "prototype de PNJ" : retourne les clés des prototypes de PNJ. Exemples d'utilisation : noms = noms("joueur") # noms contient la liste des noms de tous les joueurs identifiants = noms("salle") """ type = type.lower() if type == "joueur": return [j.nom for j in importeur.joueur.joueurs.values()] elif type == "salle": return [s.ident for s in importeur.salle._salles.values()] elif type == "prototype de pnj": return [p.cle for p in importeur.pnj._prototypes.values()] else: raise ErreurExecution("Type inconnu {}".format(repr(type)))
def correspond(expression, chaine): """Retourne vrai si la chaine correspond à l'expression. Paramètres à préciser : * expression : l'expression régulière * chaine : la chaîne à tester On retire les accents de la chaîne avant de la tester. Ainsi : correspond("^[a-z]+$", "tête") Retournera VRAI, car le ê est remplacé par un e standard. De plus, les majuscules ou minuscules n'ont pas d'importance dans la recherche. Pour plus d'informations sur les expressions régulirèes, rendez-vous [[regex|sur cette page d'aide]]. """ chaine = supprimer_accents(chaine) expression = expression.replace("_b_", "|") try: return re.search(expression, chaine, re.I) except re.error as err: raise ErreurExecution("Syntaxe de l'expression régulière " \ "invalide : " + str(err))
def rejoindre_guilde(personnage, cle_guilde): """Fait rejoindre la guilde au personnage. Cette action crée une alerte si le personnage ne peut rejoindre la guilde (si il n'a pas assez de points de guilde, par exemple). Si l'action réussit, le personnage se retrouve dans le premier rang de la guilde à 0% d'avancement. Paramètres à renseigner : * personnage : le personnage (futur membre) * cle_guilde : la clé de la guilde (une chaîne) Exemple d'utilisation : rejoindre_guilde personnage "forgerons" """ cle_guilde = cle_guilde.lower() if cle_guilde not in importeur.crafting.guildes: raise ErreurExecution("La guilde {} n'existe pas".format( repr(cle_guilde))) guilde = importeur.crafting.guildes[cle_guilde] guilde.rejoindre(personnage)
def destination(salle, nom_sortie): """Retourne la destination de la sortie indiquée. Paramètres à préciser : * salle : la salle dans laquelle on doit trouver la sortie * nom_sortie : le nom de la sortie Si trouvé, retourne la salle de destination de la sortie. Si la sortie n'existe pas, une alerte est créée. Vérifiez donc que la sortie existe : si sortie_existe(salle, "porte"): destination = destination(salle, "porte") """ try: sortie = salle.sorties.get_sortie_par_nom_ou_direction(nom_sortie) assert sortie is not None assert sortie.salle_dest is not None except (KeyError, AssertionError): raise ErreurExecution("la sortie {} dans la salle {} ne " \ "peut être trouvée.".format(repr(nom_sortie), salle)) return sortie.salle_dest
def nom_pavillon_salle(salle): """Retourne le nom du pavillon du navire. Paramètres à préciser : * salle : la salle de navire Si la salle ne fait pas parti du navire, crée une alerte. Le nom singulier du pavillon est retourné dans le cas contraire. Si le navire n'a pas de pavillon hissé, retourne une chaîne vide. Exemple d'utilisation : # On sait que la variable 'salle' contient une salle de navire nom = nom_pavillon(salle) # Si le navire n'a pas de pavillon, la chaîne sera vide si nom: # Le navire a un pavillon hissé sinon: # Le navire n'a pas de pavillon hissé """ if not hasattr(salle, "navire") or salle.navire is None or \ salle.navire.etendue is None: raise ErreurExecution("la salle {} n'est pas une salle de " \ "navire".format(salle)) navire = salle.navire if navire.pavillon is None: return "" return navire.pavillon.nom_singulier
def salles(nom_zone="*"): """Retourne toutes les salles. Si le nom de la zone est passé en paramètre, ne retourne que les salles de la zone indiquée. Paramètres à préciser : * nom_zone : le nom de la zone (une chaîne) Si la zone n'est pas précisée, retourne toutes les salles de l'univers. Exemples d'utilisation : # Capture toutes les salles dans une liste salles = salles() # Capture seulement les salles de la zone 'depart' salles = salles("depart") """ if nom_zone == "*": return list(importeur.salle._salles.values()) else: nom_zone = nom_zone.lower() try: zone = importeur.salle.zones[nom_zone] except KeyError: raise ErreurExecution("zone {} inconnue".format(repr(nom_zone))) return list(zone.salles)
def noyer(salle, degats): """Noie une salle de navire. Les dégâts précisés sont sous la forme de kilos : si vous entrez des dégâts de 50 et que la salle est noyable, la salle indiquée aura une brèche qui laissera entrer 50 kilos (plus ou moins 50 litres) d'eau. Si la salle n'est pas noyable, rien ne se passe. Si la salle n'est pas une salle de navire, une alerte est créée. Paramètres à renseigner : * salle : la salle de navire à noyer * degats : les dégâts sous la forme d'un nombre Exemple d'utilisation : noyer salle 30 """ if not hasattr(salle, "noyer"): raise ErreurExecution("La salle {} n'est pas une salle " \ "de navire".format(salle)) salle.noyer(int(degats))
def ajouter_chapitre_prototype(livre, titre, texte): """Ajoute un chapitre au livre précisé en paramètre. Paramètres à préciser : * livre : le prototype d'objet de type livre à modifier ; * titre : une chaîne de caractères contenant le titre du chapitre ; * texte : une chaîne de caractères contenant le texte du chapitre. Cette action modifie les chapitres du prototype d'objet. Tous les objets créés sur ce prototype sont donc affectés. Exemple d'utilisation : ajouter_chapitre "chants_noel" "Jingle bells" "Dashin' through the snow" """ if not livre.est_de_type("livre"): raise ErreurExecution("le prototype d'objet {} n'est pas " \ "de type livre".format(repr(cle_livre))) chapitre = livre.ajouter_chapitre(titre) texte = texte.replace("_b_", "|") texte = texte.replace("|nl|", "\n") chapitre.description.paragraphes[:] = texte.split("\n")
def apparaitre_proto_nb(pnj): """Fait disparaître le PNJ précisé (équivalent commande ppurge).""" if not hasattr(pnj, "prototype"): raise ErreurExecution("{} n'est pas un PNJ".format(pnj)) pnj.salle.retirer_personnage(pnj) pnj.salle = None importeur.pnj.supprimer_PNJ(pnj.identifiant)
def peut_prendre_proto(personnage, prototype, nb): """Renvoie vrai si le personnage peut prendre nb objets, faux sinon. Cet usage permet de tester à partir d'un objet non encore créé, et surtout de tester une quantité. """ nb = int(nb) if not prototype in importeur.objet.prototypes: raise ErreurExecution("prototype {} introuvable".format(prototype)) prototype = importeur.objet.prototypes[prototype] # on teste l'inventaire for o in personnage.equipement.inventaire: if o.est_de_type("conteneur") and o.accepte_type(prototype): try: o.conteneur.supporter_poids_sup(prototype.poids_unitaire * nb, recursif=False) except SurPoids: return False else: return True # on teste les membres if nb > 1: return False for membre in personnage.equipement.membres: if membre.peut_tenir() and membre.tenu is None: return True return False