Code source de NaoQuest.objective

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
GNU AFFERO GENERAL PUBLIC LICENSE
    Version 3, 19 November 2007
"""
try:
    from globals_nao_quest import config
    from NaoCreator.SpeechToText import nao_key_reco
    from NaoCreator.SpeechToText.nao_listen import nao_listen
    from os.path import isfile
    from NaoCreator.setting import Setting

    import importlib
    import json
    import NaoCreator.Tool.speech_move as sm
    import copy
    import imp
except Exception as e:
    print e


[docs]class Objective(object): """ Classe abstraite représentant un Objectif. Modifie elle-même sa classe selon le type de l'objectif qui lui est donné. """ def __init__(self, scenario_name, quest_name, inner_name): """ Construit un objectif à partir du nom du scénario, du nom de la quête et du nom de l'objectif. :param scenario_name: Le nom du scnéraio contenant l'objectif :param quest_name: Le nom de la quête contenant l'objectif :param inner_name: Le nom de l'objectif """ if not scenario_name or not quest_name or not inner_name: return # On extrait le chemin relatif réel à partir de la config et des paramètres self.filepath = config["objectives"]["path"].format(scenario_name, quest_name, inner_name) self.inner_name = inner_name # représente le nom du fichier sans l'extension self.scenario_name = scenario_name self.quest_name = quest_name # Attributs de base self.on_fail_exit = True self.completed = False self.failed_interact = False self.answer = "" self.xp = 0 self.caller = None print self.filepath self.__dict__.update(json.load(open(self.filepath), "utf-8")) self.init_scripts() # on modifie la classe de l'objet créé afin d'utiliser les méthodes adéquates plutôt que # celles d'Objective if self.type: from NaoQuest.objectives.yn_question import YNQuestion from NaoQuest.objectives.info_objective import InfoObjective from NaoQuest.objectives.keyword_objective import KeyWordObjective from NaoQuest.objectives.custom_objective import CustomObjective from NaoQuest.objectives.cpt_objective import CptObjective if self.type == "yn": self.__class__ = YNQuestion elif self.type == "info": self.__class__ = InfoObjective elif self.type == "kw": self.__class__ = KeyWordObjective elif self.type == "custom": self.__class__ = CustomObjective elif self.type == "cpt": self.__class__ = CptObjective def init_scripts(self): print "Recréation des scripts..." # retro compa if Setting.NAO_QUEST_V == "2.0": pre = config["quest_scripts"]["path"].format(self.scenario_name, self.quest_name, self.inner_name, "pre") script = config["quest_scripts"]["path"].format(self.scenario_name, self.quest_name, self.inner_name, "script") post = config["quest_scripts"]["path"].format(self.scenario_name, self.quest_name, self.inner_name, "post") elif Setting.NAO_QUEST_V == "2.1": pre = config["scripts"]["path"].format(self.inner_name, "pre") script = config["scripts"]["path"].format(self.inner_name, "script") post = config["scripts"]["path"].format(self.inner_name, "post") else: Setting.critical("Bad Setting.NAO_QUEST_V version (= {})".format(Setting.NAO_QUEST_V)) if isfile(pre): self.pre_script = imp.load_source("scripts", pre).script if isfile(script): self.script = imp.load_source("scripts", script).script if isfile(post): self.post_script = imp.load_source("scripts", post).script def __getstate__(self): """ Permet de sérialiser l'objet sans les scripts (ils sont de toute manière ré-importés) :return: le state de l'objet en cours sans les scripts """ d = copy.copy(self.__dict__) d.pop("pre_script", None) d.pop("script", None) d.pop("post_script", None) return d def _pres(self): """ Présente l'objectif si l'attribut "pres" = True """ if self.pres and hasattr(self, "name") and self.name: sm.speech_and_move(u"L'intitulé de cet objectif est. {}.".format(self.name)) if hasattr(self, "desc") and self.desc: sm.speech_and_move(self.desc) def _exec(self): """ Exécution interne de l'objectif, doit être redéfini par une sous-classe """ raise Exception("Error! Using base \"Objective._exec\" instead of sub-class! ({})".format(self.inner_name)) def _interact(self): """ Interaction avec l'utilisateur (récupération de données) """ raise Exception("Error! Using base \"Objective._interact\" instead of sub-class! ({})".format(self.inner_name)) def _verif(self): """ Fonction de vérification des données, doit retourner True ou False selon si les tests ont réussi. :return: True si la vérification a réussi, False sinon """ raise Exception("Error! Using base \"Objective._verif\" instead of sub-class! ({})".format(self.inner_name)) def _success(self): """ Méthode exécutée lorsque _verif(1) réussi. """ self.completed = True if hasattr(self, "text_on_success"): sm.speech_and_move(self.text_on_success) def _failed(self): """ Méthode exécutée lorsque _verif(1) échoue. """ self.completed = False if hasattr(self, "text_on_failed"): sm.speech_and_move(self.text_on_failed) def _pre_script(self, player=None): """ Exécute le pre_script de l'objectif :param player: Le joueur en cours """ self.pre_script(self, player) def _script(self, player=None): """ Exécute le script de l'objectif :param player: Le joueur en cours """ self.script(self, player) def _post_script(self, player=None): """ Exécute le post_script de l'objectif :param player: Le joueur en cours """ self.post_script(self, player) def _make_repeat(self): """ Si l'attribut "repetable" est à True, alors, si l'objectif est completé, Nao demandera au joueur s'il veut recommencer cet objectif, le remettant alors à zéro. """ if (getattr(self, "repeatable", False) or getattr(self, "repetable", False)) and self.completed: sm.speech_and_move("Cet objectif est répétable, veux-tu le recommencer ?") answer = nao_key_reco.sentence_keywords(nao_listen(), ["oui", "ouais", "affirmatif"]) if answer: self.completed = False def __inner_execution(self, player=None): """ Exécution interne de l'objectif, ne doit à prioris pas être redéfini dans une sous-classe. :param player: Le joueur en cours """ self._exec() self._interact() if "script" in self.__dict__: self._script(player) self.success = self._verif() if self.success: self._success() if player: player.give_xp(self.xp) else: self._failed() if "post_script" in self.__dict__: self._post_script(player) self._make_repeat() return self.success def _finished(self): """ Exécuté lorsque l'objectif termine """ if hasattr(self, "text_on_finished"): sm.speech_and_move(self.text_on_finished)
[docs] def launch(self, player=None): """ Démarre l'objectif :param player: Le joueur en cours """ self.init_scripts() if player: player.current_objective = self if "pre_script" in self.__dict__: self._pre_script(player) self._pres() # Boucle d'exécution interne while True: if self.__inner_execution(player=player): self._finished() return True elif not self.on_fail_exit: return False