/[ambar]/ambar/interfazpnjhablante.py
ViewVC logotype

Diff of /ambar/interfazpnjhablante.py

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 2.0 by pabloruiz, Sat Aug 17 21:11:09 2002 UTC revision 2.1 by amoyav, Fri Aug 23 12:51:18 2002 UTC
# Line 20  Line 20 
20  #  #
21    
22    
23  #Fichero: interfazpnjhablante.py  #Fichero: interfazpnjhablante.py
24    
25  """Clase InterfazPNJHablante."""  """Clase InterfazPNJHablante."""
26    
27  from controlador import *  from interfazpnj import *
28  from personaje import *  from conversacion import *
29  from personajejugador import *  from visita import *
30  from personajenojugador import *  import copy
31  from sala import *  
32  from utils import *  class InterfazPNJHablante(InterfazPNJ):
33  from timer import *      """Interfaz controla directamente a una instancia de clase PersonajeNoJugador con capacidad de dialogar.
34  from conversacion import *  
35  from visita import *      El control es automático, no necesita intervención de ningún jugador.
36  from idioma import *      
37  from dialogonormal import *      La clase funciona como una maquina de estados, que acepta los eventos de
38  import copy      Controlador, y reacciona apropiadamente en cada caso.
39        
40  class InterfazPNJHablante(InterfazPNJ):      Contiene los siguientes atributos:
41      """Interfaz controla directamente a una instancia de clase PersonajeNoJugador con capacidad de dialogar.      
42         - _conversacion (Conversacion): la conversacion que es capaz de mantener el PNJ
43      El control es automátic, no necesita intervención de ningún jugador.       - _visitas ([Visita]): los estados de conversacion que mantiene con distintos grupos de PJs.
44             - __personaje (Personaje): el personaje que controlamos
45      La clase funciona como una maquina de estados, que reacciona frente a los siguientes       - estado (string): el estado en el que se encuentra el interfaz
46      eventos:       - sub_estado (int): algunos estados tienen fases intermedias. Si no, None.
47             - timer (Timer): temporizador usado opcionalmente
48  *     - comando_recibido: el jugador ha enviado un comando por el socket       - oponente (Personaje): otro personaje con quien el nuestro está combatiendo    
49       - entra_personaje: otro personaje ha entrado en la sala       - _fragmentos: lista de fragmentos que falta por decir
50       - sale_personaje: otro personaje sale de la sala       - timers: temporizadores para mostrar los fragmentos restantes
51       - actua_pesonaje: otro personaje hace algo y lo ven los que están en la misma sala      
52  *     - habla_pesonaje: otro personaje dice algo a los que están en la misma sala       Los siguientes atributos provocan ajustes automáticos al ser modificados:
53  *     - susurra_pesonaje: otro personaje susurra algo a éste.  
54       - grita_personaje: otro personaje dice algo a todos los personajes del mundo       - personaje: se modifica también al personaje para que tenga a este interfaz como
55       - ataca_personaje: otro personaje ataca a este                    controlador
56                          
57      Contiene los siguientes atributos:       Invariantes:
58                _conversacion != None
59       - _conversacion (Conversacion): la conversacion que es capaz de mantener el PNJ          __personaje != None
60       - _visitas ([Visita]): los estados de conversacion que mantiene con distintos grupos de PJs.          len(_visitas) >= 0
61       - __personaje (Personaje): el personaje que controlamos          len(timers) >= 0
62       - estado (string): el estado en el que se encuentra el interfaz          len(_fragmentos) >= 0
63       - sub_estado (int): algunos estados tienen fases intermedias. Si no, None.          self.visita[i].activo  <--> len(self._fragmentos) > 0
64       - timer (Timer): temporizador usado opcionalmente       """
65       - oponente (Personaje): otro personaje con quien el nuestro está combatiendo      
66       - _fragmentos: lista de fragmentos que falta por decir  
67       - timers: temporizadores para mostrar los fragmentos restantes      def __init__(self, id):
68                InterfazPNJ.__init__(self)
69       Los siguientes atributos provocan ajustes automáticos al ser modificados:          idconversacion = id.split("%")[0]
70            self._conversacion = Conversacion(idconversacion)
71       - personaje: se modifica también al personaje para que tenga a este interfaz como          self._visitas = [Visita(self._conversacion, None)]
72                    controlador          self._fragmentos = []
73                      
74       Invariantes:  
75          _conversacion != None  
76          __personaje != None      def __setattr__(self, name, value):
77          len(_visitas) >= 0          """Realiza ajustes automáticos al modificar cualquier parámetro"""
78          len(timers) >= 0  
79          len(_fragmentos) >= 0          if name == "personaje":
80          self.visita[i].activo  <--> len(self._fragmentos) > 0              # Si es personaje, liberar al anterior y controlar al nuevo.
81       """              if (self.personaje != None): self.personaje.controlador = None
82                self.__dict__["personaje"] = value
83                if (self.personaje != None): self.personaje.controlador = self
84      def __init__(self, id):              # Y borrar las visitas que ha mantenido hasta ahora
85          InterfazPNJ.__init__(self)  #            self._visitas = []
86          idconversacion = id.split("%")[0]          else:
87          self._conversacion = Conversacion(idconversacion)              # En otro caso, asignar y ya esta
88          self._visitas = [Visita(self._conversacion, None)]              self.__dict__[name] = value
89          self._fragmentos = []              
90        def controlar_personaje(self, personaje):
91            """Pasar a estar controlando un personaje.
92            
93      def __setattr__(self, name, value):          Requiere:
94          """Realiza ajustes automáticos al modificar cualquier parámetro"""            self.__personaje == None
95              personaje != None
96          if name == "personaje":          """
97              # Si es personaje, liberar al anterior y controlar al nuevo.          self.__personaje = personaje
98              if (self.personaje != None): self.personaje.controlador = None          self.__personaje.controlar(self)
99              self.__dict__["personaje"] = value          self._visitas[0].pnj = self.__personaje
100              if (self.personaje != None): self.personaje.controlador = self              
101              # Y borrar las visitas que ha mantenido hasta ahora      # ----------------------------
102  #            self._visitas = []      # Metodos de manejo de eventos
103          else:      # ----------------------------
104              # En otro caso, asignar y ya esta      
105              self.__dict__[name] = value      def conversa_personaje(self, personaje, comando, nombretema):
106                        """Metodo llamado cuando otro personaje habla con este PNJ"""
107      def controlar_personaje(self, personaje):          visita = self._visitas[0]
108          """Pasar a estar controlando un personaje.          if visita.activo:
109                       if visita.pj_activo.atrib["carisma"] > personaje.atrib["carisma"]  : #visita.pj_activo.aura > personaje.controlador._DialogoNormal__personaje.aura:
110          Requiere:                  personaje.controlador.conn().send(visita.pnj.nombre +" está hablando con " + visita.pj_activo.nombre)
111            self.__personaje == None                  return
112            personaje != None             else:
113          """                 self.anular_conversacion()
114          self.__personaje = personaje          respuesta = visita.responder(personaje, comando, nombretema.lower())
115          self.__personaje.controlar(self)          escribir("Tema " + visita.estado())
116          self._visitas[0].pnj = self.__personaje          #print respuesta[len(respuesta)-1]
117                        if visita.estado() == Visita.ENCONTRADO or visita.estado() == Visita.OFFTOPIC:
118      # ----------------------------             visita.activar(respuesta)
119      # Metodos de manejo de eventos          
120      # ----------------------------          nombre = visita.pnj.nombre[0].lower() + visita.pnj.nombre[1:]
121                if comando == "decir":
122      def conversa_personaje(self, personaje, comando, nombretema):              visita.pj_activo.actuar("dice a " + nombre + " algo acerca de '" + nombretema + "'")        
123          """Metodo llamado cuando otro personaje habla con este PNJ"""              personaje.controlador.conn().send("Dices a " + nombre + " algo sobre '" + nombretema + "'")
124          visita = self._visitas[0]          else:
125          if visita.activo:              visita.pj_activo.actuar("pregunta a " + nombre + " acerca de '" + nombretema + "'")
126             if visita.pj_activo.atrib["carisma"] > personaje.atrib["carisma"]  : #visita.pj_activo.aura > personaje.controlador._DialogoNormal__personaje.aura:              personaje.controlador.conn().send("Preguntas a " + nombre + " sobre '" + nombretema + "'")
127                  personaje.controlador.conn().send(visita.pnj.nombre +" está hablando con " + visita.pj_activo.nombre)          
128                  return          fragmentos = []
129             else:          
130                 self.anular_conversacion()          
131          respuesta = visita.responder(personaje, comando, nombretema.lower())          for item in respuesta["especiales"]:
132          escribir("Tema " + visita.estado())               fragmentos = fragmentos + item._fragmentos
133          #print respuesta[len(respuesta)-1]  #            if type(item) == type(""):
134          if visita.estado() == Visita.ENCONTRADO or visita.estado() == Visita.OFFTOPIC:  #                escribir(str(item))
135             visita.activar(respuesta)  #            else:
136            #                self._fragmentos = self._fragmentos + copy.copy(item._fragmentos)
137          nombre = visita.pnj.nombre[0].lower() + visita.pnj.nombre[1:]          if respuesta["tema"]:
138          if comando == "decir":              fragmentos = fragmentos + respuesta["tema"]._fragmentos
139              visita.pj_activo.actuar("dice a " + nombre + " algo acerca de '" + nombretema + "'")          
140              personaje.controlador.conn().send("Dices a " + nombre + " algo sobre '" + nombretema + "'")          self.temporizar(fragmentos)
141          else:  #       self._fragmentos = self._fragmentos + copy.copy(respuesta["tema"]._fragmentos)
142              visita.pj_activo.actuar("pregunta a " + nombre + " acerca de '" + nombretema + "'")          
143              personaje.controlador.conn().send("Preguntas a " + nombre + " sobre '" + nombretema + "'")      def temporizar(self, fragmentos):
144                    """Programa la temporización del diálogo contenido en la lista de fragmentos."""
145          fragmentos = []          
146                    self.timers=[]  
147                    self._fragmentos = []
148          for item in respuesta["especiales"]:          timeout = 0
149               fragmentos = fragmentos + item._fragmentos          
150  #            if type(item) == type(""):          visita = self._visitas[0]
151  #                escribir(str(item))          for fragmento in fragmentos:
152  #            else:              # Comprueba requisitos de fragmento
153  #                self._fragmentos = self._fragmentos + copy.copy(item._fragmentos)              if fragmento.__dict__.has_key("_texto_unico"):
154          if respuesta["tema"]:                  hito = fragmento._texto_unico
155              fragmentos = fragmentos + respuesta["tema"]._fragmentos                  print hito + " " + visita.hito(hito)
156                    if visita.hito(hito):
157          self.temporizar(fragmentos)                      continue    # Fragmento repetido
158  #       self._fragmentos = self._fragmentos + copy.copy(respuesta["tema"]._fragmentos)                  else:
159                                self.timers.append(Timer(Mundo.timer_handler, timeout, lambda timer: visita.asignar_hito(hito)))
160      def temporizar(self, fragmentos):                      
161          """Programa la temporización del diálogo contenido en la lista de fragmentos."""              # Asigna temporizador para el fragmento
162                        self._fragmentos.append(copy.copy(fragmento))
163          self.timers=[]                print "temporizado " + str(timeout) + " segundos: " + str(fragmento)
164          self._fragmentos = []              self.timers.append(Timer(Mundo.timer_handler, timeout, lambda timer: self.show()))
165          timeout = 0              timeout = timeout + fragmento.retardo()
166                    self.timers.append(Timer(Mundo.timer_handler, timeout, lambda timer: self.anular_conversacion()))
167          visita = self._visitas[0]  
168          for fragmento in fragmentos:      def show(self):
169              # Comprueba requisitos de fragmento        try:
170              if fragmento.__dict__.has_key("_texto_unico"):          if not self._visitas[0].activo or len(self._fragmentos)==0: return
171                  hito = fragmento._texto_unico          # Actualiza el estado parcial del dialogo (consumiendo el siguiente fragmento)
172                  print hito + " " + visita.hito(hito)          pj = self._visitas[0].pj_activo
173                  if visita.hito(hito):          fragmento = self._fragmentos[0]
174                      continue    # Fragmento repetido          visita = self._visitas[0]
175                  else:          del self._fragmentos[0]
176                      self.timers.append(Timer(Mundo.timer_handler, timeout, lambda timer: visita.asignar_hito(hito)))          del self.timers[0]
177                        #       if not self._fragmentos:
178              # Asigna temporizador para el fragmento  #           self.anular_conversacion()
179              self._fragmentos.append(copy.copy(fragmento))              
180              print "temporizado " + str(timeout) + " segundos: " + str(fragmento)          if fragmento.clase() == "pregunta":
181              self.timers.append(Timer(Mundo.timer_handler, timeout, lambda timer: self.show()))              escribir(pj.nombre + " dice:  " + fragmento.mensaje_formateado(visita, "otros"))
182              timeout = timeout + fragmento.retardo()              pj.hablar(fragmento.mensaje_formateado(visita, "otros"), Idioma_oestron)
183          self.timers.append(Timer(Mundo.timer_handler, timeout, lambda timer: self.anular_conversacion()))              pj.controlador.conn().send("Dices: " + pj.color_texto()  + fragmento.mensaje_formateado(visita, "tu") + finl)
184            elif fragmento.clase() == "respuesta":
185      def show(self):              escribir(self.__personaje.nombre + " dice:  " + fragmento.mensaje_formateado(visita, "otros") + finl)
186        try:              self.__personaje.hablar(fragmento.mensaje_formateado(visita, "otros"))
187          if not self._visitas[0].activo or len(self._fragmentos)==0: return          elif fragmento.clase() == "hito":
188          # Actualiza el estado parcial del dialogo (consumiendo el siguiente fragmento)              visita.asignar_hito(fragmento._nombre, fragmento.mensaje_formateado(self, "otros"))
189          pj = self._visitas[0].pj_activo          elif fragmento.clase() == "redireccion":
190          fragmento = self._fragmentos[0]              self.anular_conversacion()
191          visita = self._visitas[0]              tema = fragmento.texto_xml().getAttribute("nombre").encode('ISO-8859-1')
192          del self._fragmentos[0]              respuesta = visita.responder(pj, "preguntar",tema.lower())
193          del self.timers[0]              if respuesta["tema"]:
194  #       if not self._fragmentos:                  # La redirección no dispara mensajes de offtopic
195  #           self.anular_conversacion()                  self.temporizar(respuesta["tema"]._fragmentos)
196                            else:
197          if fragmento.clase() == "pregunta":                  # Muestra mensajes de tema agotado o no encontrado
198              escribir(pj.nombre + " dice:  " + fragmento.mensaje_formateado(visita, "otros"))                  fragmentos = []
199              pj.hablar(fragmento.mensaje_formateado(visita, "otros"), Idioma_oestron)                  for item in respuesta["especiales"]:
200              pj.controlador.conn().send("Dices: " + pj.color_texto()  + fragmento.mensaje_formateado(visita, "tu") + finl)                      fragmentos = fragmentos + item._fragmentos
201          elif fragmento.clase() == "respuesta":                  self.temporizar(fragmentos)
202              escribir(self.__personaje.nombre + " dice:  " + fragmento.mensaje_formateado(visita, "otros") + finl)          else:
203              self.__personaje.hablar(fragmento.mensaje_formateado(visita, "otros"))              escribir("efecto especial de conversación:  " + fragmento.mensaje_formateado(visita, "otros"))
204          elif fragmento.clase() == "hito":              self.__personaje.describir(fragmento.mensaje_formateado(visita, "otros"))
205              visita.asignar_hito(fragmento._nombre, fragmento.mensaje_formateado(self, "otros"))        except Exception:
206          elif fragmento.clase() == "redireccion":              # Conviene protegerse contra errores en carga de salas. No es bueno que por
207              self.anular_conversacion()              # un fichero de sala mal escrito pete el servidor entero o te eche de la
208              tema = fragmento.texto_xml().getAttribute("nombre").encode('ISO-8859-1')              # conexión.
209              respuesta = visita.responder(pj, "preguntar",tema.lower())              escribir( "Ha saltado una excepcion al intentar mostrar un fragmento de conversación")
210              if respuesta["tema"]:              escribir_excepcion()
211                  # La redirección no dispara mensajes de offtopic  
212                  self.temporizar(respuesta["tema"]._fragmentos)      def anular_conversacion(self):
213              else:          self._fragmentos = []
214                  # Muestra mensajes de tema agotado o no encontrado          self._visitas[0].activo = None
215                  fragmentos = []          for timer in self.timers:
216                  for item in respuesta["especiales"]:            # Anula los timers que no se han ejecutado aún, asignandoles la función nula
217                      fragmentos = fragmentos + item._fragmentos              timer.timeout_func = lambda x: None
218                  self.temporizar(fragmentos)  
219          else:      def sale_personaje(self, personaje, nombre_sala_destino):
220              escribir("efecto especial de conversación:  " + fragmento.mensaje_formateado(visita, "otros"))          """Metodo llamado cuando otro personaje sale de la misma sala.
221              self.__personaje.describir(fragmento.mensaje_formateado(visita, "otros"))          
222        except Exception:          personaje -- el personaje que sale.
223              # Conviene protegerse contra errores en carga de salas. No es bueno que por          nombre_sala_destino -- el nombre de la sala a donde va
224              # un fichero de sala mal escrito pete el servidor entero o te eche de la          """
225              # conexión.          visita = self._visitas[0]
226              escribir( "Ha saltado una excepcion al intentar mostrar un fragmento de conversación")          if personaje == visita.pj_activo:
227              escribir_excepcion()              escribir("Conversacion anulada por abandono del hablante")
228                self.anular_conversacion()
229      def anular_conversacion(self):            
230          self._fragmentos = []      def old_conversa_personaje(self, dialogo, comando, nombretema):
231          self._visitas[0].activo = None          """Metodo llamado cuando otro personaje habla con este PNJ"""
232          for timer in self.timers:          visita = self._visitas[0]
233            # Anula los timers que no se han ejecutado aún, asignandoles la función nula          respuesta = visita.responder(dialogo._DialogoNormal__personaje, comando, nombretema)
234              timer.timeout_func = lambda x: None          for item in respuesta:
235                if type(item) == type(""):
236      def sale_personaje(self, personaje, nombre_sala_destino):                  escribir(str(item))
237          """Metodo llamado cuando otro personaje sale de la misma sala.              else:
238                            for fragmento in item._fragmentos:
239          personaje -- el personaje que sale.                      if fragmento.clase() == "pregunta":
240          nombre_sala_destino -- el nombre de la sala a donde va                          dialogo._DialogoNormal__personaje.hablar(fragmento.mensaje_formateado(visita, "otros"), Idioma_oestron)
241          """                          dialogo.conn().send("Dices: " + fragmento.mensaje_formateado(visita, "tu"))
242          visita = self._visitas[0]                      elif fragmento.clase() == "respuesta":
243          if personaje == visita.pj_activo:                          self.personaje.hablar(fragmento.mensaje_formateado(visita, "otros"), Idioma_oestron)
244              escribir("Conversacion anulada por abandono del hablante")                      else:
245              self.anular_conversacion()                          self.personaje.describir(fragmento.mensaje_formateado(visita, "otros"))
246              
247      def old_conversa_personaje(self, dialogo, comando, nombretema):  
248          """Metodo llamado cuando otro personaje habla con este PNJ"""  
249          visita = self._visitas[0]  # Código para pruebas unitarias del módulo.
250          respuesta = visita.responder(dialogo._DialogoNormal__personaje, comando, nombretema)  
251          for item in respuesta:  if (__name__ == '__main__'):
252              if type(item) == type(""):      print "No hay código para pruebas unitarias del módulo. Para probar, ejecutar ambar.py"
253                  escribir(str(item))      print "y conectarse via telnet."
             else:  
                 for fragmento in item._fragmentos:  
                     if fragmento.clase() == "pregunta":  
                         dialogo._DialogoNormal__personaje.hablar(fragmento.mensaje_formateado(visita, "otros"), Idioma_oestron)  
                         dialogo.conn().send("Dices: " + fragmento.mensaje_formateado(visita, "tu"))  
                     elif fragmento.clase() == "respuesta":  
                         self.personaje.hablar(fragmento.mensaje_formateado(visita, "otros"), Idioma_oestron)  
                     else:  
                         self.personaje.describir(fragmento.mensaje_formateado(visita, "otros"))  
   
   
   
 # Código para pruebas unitarias del módulo.  
   
 if (__name__ == '__main__'):  
     print "No hay código para pruebas unitarias del módulo. Para probar, ejecutar ambar.py"  
     print "y conectarse via telnet."  

Legend:
Removed from v.2.0  
changed lines
  Added in v.2.1

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26