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

Diff of /ambar/personajenojugador.py

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

revision 2.6 by amoyav, Sun Nov 10 13:48:16 2002 UTC revision 2.7 by amoyav, Sat Dec 7 23:09:36 2002 UTC
# Line 41  class PersonajeNoJugador(Personaje): Line 41  class PersonajeNoJugador(Personaje):
41      Opcionalmente puede guardar el documento xml leido del fichero, esto es válido      Opcionalmente puede guardar el documento xml leido del fichero, esto es válido
42      para editores de PNJs.      para editores de PNJs.
43            
44      Contiene los atributos comunes de un personaje, y ademas:      Contiene los atributos comunes de un personaje, y ademas los particulares de un
45       - __autor (string): nombre del autor del fichero de descripcion      personaje no jugador.
46       - __area (string): id del área por la que se mueve este pnj (si está vacío, puede  
47                          moverse por cualquier área)      Invariantes adicionales sobre los atributos de la clase base:
      - __tipo_controlador (string): descripcion del tipo de controlador  
      - __datos_controlador (string): información para configurar el controlador  
      - __arbol_xml (minidom.Document, opcional): arbol XML leido del fichero de descripcion  
       
     Invariantes:  
48          id tiene formato "id_fichero%clave_unica"          id tiene formato "id_fichero%clave_unica"
49          controlador != None          controlador != None
         __autor != None  
         __area != None  
         __tipo_controlador in ['estandar', 'hablante']  
         __datos_controlador != None  
50      """      """
51    
52      # Version del sistema de descripciones de pnj (se incrementa cada vez que cambia      # Version del sistema de descripciones de pnj (se incrementa cada vez que cambia
# Line 67  class PersonajeNoJugador(Personaje): Line 58  class PersonajeNoJugador(Personaje):
58    
59      # Contador para ir asignando ids a los pnjs nuevos      # Contador para ir asignando ids a los pnjs nuevos
60      contador_de_ids = 0      contador_de_ids = 0
61            
62    
63        # Métodos estáticos
64    
65        def nuevo_id():
66            """Devuelve un número único para usarlo en el id de un nuevo pnj."""
67            PersonajeNoJugador.contador_de_ids += 1
68            return str(PersonajeNoJugador.contador_de_ids)
69    
70        nuevo_id = staticmethod(nuevo_id)
71    
72    
73        # Atributos públicos de la clase
74    
75        def __leer_autor(self): return self.__autor
76    
77        autor = property(__leer_autor,
78                         doc="""(string): nombre del autor del fichero de descripcion.
79    
80                             Invariantes:
81                                 autor != None
82                             """)
83    
84        def __leer_area(self): return self.__area
85    
86        area = property(__leer_area,
87                        doc="""(string): id del área por la que se mueve este pnj (si está vacío,
88                            puede moverse por cualquier área).
89    
90                            Invariantes:
91                                area != None
92                            """)
93    
94        def __leer_tipo_controlador(self): return self.__tipo_controlador
95    
96        tipo_controlador = property(__leer_tipo_controlador,
97                                    doc="""(string): descripcion del tipo de controlador.
98    
99                                        Invariantes:
100                                            tipo_controlador in ['estandar', 'hablante']
101                                        """)
102    
103        def __leer_datos_controlador(self): return self.__datos_controlador
104    
105        datos_controlador = property(__leer_datos_controlador,
106                                     doc="""(string): información para configurar el controlador.
107    
108                                         Invariantes:
109                                             datos_controlador != None
110                                         """)
111    
112    
113        def __leer_intocable(self): return self.__intocable
114    
115        intocable = property(__leer_intocable,
116                             doc="""(string): si vale 'si', al pnj no se le puede matar.
117    
118                                 Esto no me convence nada, habrá que repensarlo mejor...
119    
120                                 Invariantes:
121                                     intocable in ['si', 'no']
122                                 """)
123    
124    
125        # Constructor
126    
127      def __init__(self, id, sala, conservar_arbol_xml = 0):      def __init__(self, id, sala, conservar_arbol_xml = 0):
128          """Método para crear un nuevo personaje no jugador.          """Método para crear un nuevo personaje no jugador.
129    
130          Al crearlo se le debe pasar un id unico, que no se repita dentro del juego          Al crearlo se le debe pasar un id unico, que no se repita dentro del juego
131          en ninguna otra instancia. Para ello, se añade al id que identifica el fichero          en ninguna otra instancia. Para ello, se añade al id que identifica el fichero
132          un simbolo % y un numero obtenido con PersonajeNoJugador_nuevo_id().          un simbolo % y un numero obtenido con PersonajeNoJugador.nuevo_id().
133    
134          Parametros:          Parametros:
135            id: el id del PNJ            id: el id del PNJ
# Line 84  class PersonajeNoJugador(Personaje): Line 140  class PersonajeNoJugador(Personaje):
140            id tiene formato "id_fichero%clave_unica"            id tiene formato "id_fichero%clave_unica"
141            sala != None            sala != None
142          """          """
143    
144            # Atributos privados:
145            #
146            # __arbol_xml (minidom.Document, opcional): arbol XML leido del fichero de descripcion.
147    
148          Personaje.__init__(self, id, sala)          Personaje.__init__(self, id, sala)
149    
150          archivo = os.path.join(PersonajeNoJugador.DIR_DESC_PNJS,          archivo = os.path.join(PersonajeNoJugador.DIR_DESC_PNJS,
151                                 self.id.split('%')[0] + PersonajeNoJugador.EXT_DESC_PNJS)                                 self._Personaje__id.split('%')[0] + PersonajeNoJugador.EXT_DESC_PNJS)
152    
153          arbol_xml = minidom.parse(archivo)          arbol_xml = minidom.parse(archivo)
154    
# Line 133  class PersonajeNoJugador(Personaje): Line 194  class PersonajeNoJugador(Personaje):
194          version_desc_pnj = extraer_atributo_xml(elem_pnj, 'version')          version_desc_pnj = extraer_atributo_xml(elem_pnj, 'version')
195    
196          if version_desc_pnj != PersonajeNoJugador.VERSION_DESC_PNJS:          if version_desc_pnj != PersonajeNoJugador.VERSION_DESC_PNJS:
197              raise ValueError("Version incorrecta del fichero descriptor de pnj " + self.id.split('%')[0] + ": " +              raise ValueError("Version incorrecta del fichero descriptor de pnj " + self._Personaje__id.split('%')[0] + ": " +
198                               version_desc_pnj + " cuando se esperaba " + Sala.VERSION_DESC_PNJS)                               version_desc_pnj + " cuando se esperaba " + Sala.VERSION_DESC_PNJS)
199                    
200          self.__autor = extraer_atributo_xml(elem_pnj, 'autor')          self.__autor = extraer_atributo_xml(elem_pnj, 'autor')
# Line 146  class PersonajeNoJugador(Personaje): Line 207  class PersonajeNoJugador(Personaje):
207      def __parsear_id(self, elem_id):      def __parsear_id(self, elem_id):
208          """Extrae el id del pnj"""          """Extrae el id del pnj"""
209          id_fichero = extraer_contenido_xml(elem_id)          id_fichero = extraer_contenido_xml(elem_id)
210          if id_fichero != self.id.split('%')[0]:          if id_fichero != self._Personaje__id.split('%')[0]:
211              raise ValueError("El id no coincide con el nombre del fichero")              raise ValueError("El id no coincide con el nombre del fichero")
212                    
213    
214      def __parsear_nombre(self, elem_nombre):      def __parsear_nombre(self, elem_nombre):
215          """Extrae el nombre del pnj"""          """Extrae el nombre del pnj"""
216          self.nombre = extraer_contenido_xml(elem_nombre)          self._Personaje__nombre = extraer_contenido_xml(elem_nombre)
217    
218    
219      def __parsear_descripcion(self, elem_descripcion):      def __parsear_descripcion(self, elem_descripcion):
220          """Extrae el texto y la dificultad de todos los items de descripcion del pnj."""          """Extrae el texto y la dificultad de todos los items de descripcion del pnj."""
221          self.descripcion = []          self._Personaje__descripcion = []
222    
223          elems_item = elem_descripcion.getElementsByTagName('item')          elems_item = elem_descripcion.getElementsByTagName('item')
224          for elem_item in elems_item:          for elem_item in elems_item:
# Line 169  class PersonajeNoJugador(Personaje): Line 230  class PersonajeNoJugador(Personaje):
230                  try:                  try:
231                      dif_item = int(extraer_atributo_xml(elem_item, 'dificultad'))                      dif_item = int(extraer_atributo_xml(elem_item, 'dificultad'))
232                  except ValueError:                  except ValueError:
233                      raise ValueError("Error en pnj " + self.id.split('%')[0] +                      raise ValueError("Error en pnj " + self._Personaje__id.split('%')[0] +
234                                       ". La dificultad en la descripción tiene que ser un número.")                                       ". La dificultad en la descripción tiene que ser un número.")
235                  if not dif_item in range(0, 101):                  if not dif_item in range(0, 101):
236                      raise ValueError("Error en pnj " + self.id.split('%')[0] +                      raise ValueError("Error en pnj " + self._Personaje__id.split('%')[0] +
237                                       ". La dificultad en la descripción tiene que ser de 0 a 100.")                                       ". La dificultad en la descripción tiene que ser de 0 a 100.")
238              else:              else:
239                  dif_item = 0                  dif_item = 0
240    
241              self.descripcion.append({"dificultad": dif_item, "texto": texto_item})              self._Personaje__descripcion.append({"dificultad": dif_item, "texto": texto_item})
242    
243    
244      def __parsear_propiedades(self, elem_propiedades):      def __parsear_propiedades(self, elem_propiedades):
# Line 190  class PersonajeNoJugador(Personaje): Line 251  class PersonajeNoJugador(Personaje):
251              - intocable              - intocable
252          """          """
253          try:          try:
254              self.experiencia = int(extraer_atributo_xml(elem_propiedades, 'experiencia'))              self._Personaje__experiencia = int(extraer_atributo_xml(elem_propiedades, 'experiencia'))
255          except ValueError:          except ValueError:
256              raise ValueError("Error en pnj " + self.id.split('%')[0] +              raise ValueError("Error en pnj " + self._Personaje__id.split('%')[0] +
257                               ". La experiencia tiene que ser un número.")                               ". La experiencia tiene que ser un número.")
258          if self.experiencia < 0:          if self._Personaje__experiencia < 0:
259              raise ValueError("Error en pnj " + self.id.split('%')[0] +              raise ValueError("Error en pnj " + self._Personaje__id.split('%')[0] +
260                               ". La experiencia tiene que ser mayor que cero.")                               ". La experiencia tiene que ser mayor que cero.")
261    
262          try:          try:
263              self.nivel = int(extraer_atributo_xml(elem_propiedades, 'nivel'))              self._Personaje__nivel = int(extraer_atributo_xml(elem_propiedades, 'nivel'))
264          except ValueError:          except ValueError:
265              raise ValueError("Error en pnj " + self.id.split('%')[0] +              raise ValueError("Error en pnj " + self._Personaje__id.split('%')[0] +
266                               ". El nivel tiene que ser un número.")                               ". El nivel tiene que ser un número.")
267          if self.nivel < 1:          if self._Personaje__nivel < 1:
268              raise ValueError("Error en pnj " + self.id.split('%')[0] +              raise ValueError("Error en pnj " + self._Personaje__id.split('%')[0] +
269                               ". El nivel tiene que ser mayor o igual que uno.")                               ". El nivel tiene que ser mayor o igual que uno.")
270    
271          try:          try:
272              self.vida = int(extraer_atributo_xml(elem_propiedades, 'vida'))              self._Personaje__vida = int(extraer_atributo_xml(elem_propiedades, 'vida'))
273          except ValueError:          except ValueError:
274              raise ValueError("Error en pnj " + self.id.split('%')[0] +              raise ValueError("Error en pnj " + self._Personaje__id.split('%')[0] +
275                               ". La vida tiene que ser un número.")                               ". La vida tiene que ser un número.")
276          if self.vida < 0:          if self._Personaje__vida < 0:
277              raise ValueError("Error en pnj " + self.id.split('%')[0] +              raise ValueError("Error en pnj " + self._Personaje__id.split('%')[0] +
278                               ". La vida tiene que ser mayor que cero.")                               ". La vida tiene que ser mayor que cero.")
279    
280          try:          try:
281              self.volumen = float(extraer_atributo_xml(elem_propiedades, 'volumen'))              self._Personaje__volumen = float(extraer_atributo_xml(elem_propiedades, 'volumen'))
282          except ValueError:          except ValueError:
283              raise ValueError("Error en pnj " + self.id.split('%')[0] +              raise ValueError("Error en pnj " + self._Personaje__id.split('%')[0] +
284                               ". El volumen tiene que ser un número.")                               ". El volumen tiene que ser un número.")
285          if self.volumen < 0:          if self._Personaje__volumen < 0:
286              raise ValueError("Error en pnj " + self.id.split('%')[0] +              raise ValueError("Error en pnj " + self._Personaje__id.split('%')[0] +
287                               ". El volumen tiene que ser mayor que cero.")                               ". El volumen tiene que ser mayor que cero.")
288    
289          self.estado = "vivo"          self._Personaje__estado = "vivo"
290    
291          try:          try:
292              self.aura = int(extraer_atributo_xml(elem_propiedades, 'aura'))              self._Personaje__aura = int(extraer_atributo_xml(elem_propiedades, 'aura'))
293          except ValueError:          except ValueError:
294              raise ValueError("Error en pnj " + self.id.split('%')[0] +              raise ValueError("Error en pnj " + self._Personaje__id.split('%')[0] +
295                               ". El aura tiene que ser un número.")                               ". El aura tiene que ser un número.")
296          if not self.aura in range(1, 101):          if not self._Personaje__aura in range(1, 101):
297              raise ValueError("Error en pnj " + self.id.split('%')[0] +              raise ValueError("Error en pnj " + self._Personaje__id.split('%')[0] +
298                               ". El aura tiene que ser de 1 a 100.")                               ". El aura tiene que ser de 1 a 100.")
299    
300          if elem_propiedades.hasAttribute('intocable'):          if elem_propiedades.hasAttribute('intocable'):
301              self.intocable = extraer_atributo_xml(elem_propiedades, 'intocable')              self.__intocable = extraer_atributo_xml(elem_propiedades, 'intocable')
302              if not self.intocable in ["si", "no"]:              if not self.__intocable in ["si", "no"]:
303                  raise ValueError('Error en pnj ' + self.id.split('%')[0] +                  raise ValueError('Error en pnj ' + self._Personaje__id.split('%')[0] +
304                                   '. El atributo intocable tiene que valer "si" o "no".')                                   '. El atributo intocable tiene que valer "si" o "no".')
305          else:          else:
306              self.intocable = "no"              self.__intocable = "no"
307    
308    
309      def __parsear_atributos(self, elem_atributos):      def __parsear_atributos(self, elem_atributos):
# Line 254  class PersonajeNoJugador(Personaje): Line 315  class PersonajeNoJugador(Personaje):
315              - sabiduria              - sabiduria
316              - carisma              - carisma
317          """          """
318          self.atrib = {}          self._Personaje__atrib = {}
319          for atrib in elem_atributos.attributes.values():          for atrib in elem_atributos.attributes.values():
320              if not atrib.name in ["fuerza", "destreza", "constitucion",              if not atrib.name in ["fuerza", "destreza", "constitucion",
321                                    "inteligencia", "sabiduria", "carisma"]:                                    "inteligencia", "sabiduria", "carisma"]:
322                  raise ValueError("Error en pnj " + self.id.split('%')[0] +                  raise ValueError("Error en pnj " + self._Personaje__id.split('%')[0] +
323                                   ". El atributo " + atrib.name + " no existe.")                                   ". El atributo " + atrib.name + " no existe.")
324              try:              try:
325                  nivel = int(atrib.value)                  nivel = int(atrib.value)
326              except ValueError:              except ValueError:
327                  raise ValueError("Error en pnj " + self.id.split('%')[0] +                  raise ValueError("Error en pnj " + self._Personaje__id.split('%')[0] +
328                                   ". El nivel del atributo " + atrib.name + " tiene que ser un número.")                                   ". El nivel del atributo " + atrib.name + " tiene que ser un número.")
329              if nivel < 1:              if nivel < 1:
330                  raise ValueError("Error en pnj " + self.id.split('%')[0] +                  raise ValueError("Error en pnj " + self._Personaje__id.split('%')[0] +
331                                   ". El nivel del atributo " + atrib.name + " tiene que ser mayor o igual que uno.")                                   ". El nivel del atributo " + atrib.name + " tiene que ser mayor o igual que uno.")
332    
333              self.atrib[atrib.name] = nivel              self._Personaje__atrib[atrib.name] = nivel
334    
335    
336      def __parsear_idiomas(self, elem_idiomas):      def __parsear_idiomas(self, elem_idiomas):
337          """Extrae la información del elemento idiomas."""          """Extrae la información del elemento idiomas."""
338          self.idiomas = {}          self._Personaje__idiomas = {}
339          for atrib in elem_idiomas.attributes.values():          for atrib in elem_idiomas.attributes.values():
340              idioma = Idioma_buscar(atrib.name)              idioma = Idioma_buscar(atrib.name)
341              if idioma == None:              if idioma == None:
342                  raise ValueError("Error en pnj " + self.id.split('%')[0] +                  raise ValueError("Error en pnj " + self._Personaje__id.split('%')[0] +
343                                   ". El idioma " + atrib.name + " no existe.")                                   ". El idioma " + atrib.name + " no existe.")
344              try:              try:
345                  nivel = int(atrib.value)                  nivel = int(atrib.value)
346              except ValueError:              except ValueError:
347                  raise ValueError("Error en pnj " + self.id.split('%')[0] +                  raise ValueError("Error en pnj " + self._Personaje__id.split('%')[0] +
348                                   ". El nivel del idioma " + atrib.name + " tiene que ser un número.")                                   ". El nivel del idioma " + atrib.name + " tiene que ser un número.")
349              if not nivel in range(0, 6):              if not nivel in range(0, 6):
350                  raise ValueError("Error en pnj " + self.id.split('%')[0] +                  raise ValueError("Error en pnj " + self._Personaje__id.split('%')[0] +
351                                   ". El nivel del idioma " + atrib.name + " tiene que ser de 0 a 5.")                                   ". El nivel del idioma " + atrib.name + " tiene que ser de 0 a 5.")
352    
353              self.idiomas[idioma] = nivel              self._Personaje__idiomas[idioma] = nivel
354    
355          self.idioma_base = Idioma_oestron          self._Personaje__idioma_base = Idioma_oestron
356    
357    
358      def __parsear_controlador(self, elem_controlador):      def __parsear_controlador(self, elem_controlador):
# Line 301  class PersonajeNoJugador(Personaje): Line 362  class PersonajeNoJugador(Personaje):
362          """          """
363          self.__tipo_controlador = extraer_atributo_xml(elem_controlador, 'tipo')          self.__tipo_controlador = extraer_atributo_xml(elem_controlador, 'tipo')
364          if not self.__tipo_controlador in ["estandar", "hablante"]:          if not self.__tipo_controlador in ["estandar", "hablante"]:
365              raise ValueError('Error en pnj ' + self.id.split('%')[0] +              raise ValueError('Error en pnj ' + self._Personaje__id.split('%')[0] +
366                               '. El tipo de controlador tiene que valer "estandar" o "hablante".')                               '. El tipo de controlador tiene que valer "estandar" o "hablante".')
367          if elem_controlador.hasAttribute('datos'):          if elem_controlador.hasAttribute('datos'):
368              self.__datos_controlador = extraer_atributo_xml(elem_controlador, 'datos')              self.__datos_controlador = extraer_atributo_xml(elem_controlador, 'datos')
# Line 321  class PersonajeNoJugador(Personaje): Line 382  class PersonajeNoJugador(Personaje):
382                  try:                  try:
383                      cantidad_objeto = int(extraer_atributo_xml(elem_objeto, 'cantidad'))                      cantidad_objeto = int(extraer_atributo_xml(elem_objeto, 'cantidad'))
384                  except ValueError:                  except ValueError:
385                      raise ValueError("Error en pnj " + self.id.split('%')[0] +                      raise ValueError("Error en pnj " + self._Personaje__id.split('%')[0] +
386                                       ". La cantidad del objeto " + id_objeto + " tiene que ser un número.")                                       ". La cantidad del objeto " + id_objeto + " tiene que ser un número.")
387                  if cantidad_objeto < 0:                  if cantidad_objeto < 0:
388                      raise ValueError("Error en pnj " + self.id.split('%')[0] +                      raise ValueError("Error en pnj " + self._Personaje__id.split('%')[0] +
389                                       ". La cantidad del objeto " + id_objeto + " tiene que ser mayor que cero.")                                       ". La cantidad del objeto " + id_objeto + " tiene que ser mayor que cero.")
390              else:              else:
391                  cantidad_objeto = 1                  cantidad_objeto = 1
# Line 338  class PersonajeNoJugador(Personaje): Line 399  class PersonajeNoJugador(Personaje):
399                      self.meter_en_mochila(Objeto(id_objeto))                      self.meter_en_mochila(Objeto(id_objeto))
400    
401    
402      def autor(self):      # Métodos normales
         return self.__autor  
   
   
     def area(self):  
         return self.__area  
   
403    
404      def controlador_automatico(self):      def controlador_automatico(self):
405          """Instancia un controlador automatico para este PNJ y se lo acopla.          """Instancia un controlador automatico para este PNJ y se lo acopla.
# Line 360  class PersonajeNoJugador(Personaje): Line 415  class PersonajeNoJugador(Personaje):
415          """          """
416          if self.__tipo_controlador == "hablante":          if self.__tipo_controlador == "hablante":
417              from interfazpnjhablante import InterfazPNJHablante              from interfazpnjhablante import InterfazPNJHablante
418              self.controlador = InterfazPNJHablante(self.__datos_controlador)              self._Personaje__controlador = InterfazPNJHablante(self.__datos_controlador)
419              self.controlador.controlar_personaje(self)              self._Personaje__controlador.controlar_personaje(self)
420          else:          else:
421              from interfazpnj import InterfazPNJ              from interfazpnj import InterfazPNJ
422              self.controlador = InterfazPNJ()              self._Personaje__controlador = InterfazPNJ()
423              self.controlador.controlar_personaje(self)              self._Personaje__controlador.controlar_personaje(self)
   
   
 # Metodos que se refieren a la clase pero tienen ambito de clase,  
 # y no de instancia  
   
 def PersonajeNoJugador_nuevo_id():  
     PersonajeNoJugador.contador_de_ids += 1  
     return str(PersonajeNoJugador.contador_de_ids)  
424    
425    
426  # Código para pruebas unitarias del módulo.  # Código para pruebas unitarias del módulo.
427    
428  if (__name__ == '__main__'):  if (__name__ == '__main__'):
429      from mundo import Mundo      from mundo import Mundo
430      from mundo import Mundo_localizar_sala      limbo = Mundo.localizar_sala(Mundo.ID_SALA_LIMBO)
     limbo = Mundo_localizar_sala(Mundo.ID_SALA_LIMBO)  
431    
432      id = raw_input("Introducir el id de un personaje no jugador: ")      id = raw_input("Introducir el id de un personaje no jugador: ")
433      id_unico = id + '%' + PersonajeNoJugador_nuevo_id()      id_unico = id + '%' + PersonajeNoJugador.nuevo_id()
434      pnj = PersonajeNoJugador(id_unico, limbo)      pnj = PersonajeNoJugador(id_unico, limbo)
435      limbo.entrar_personaje(pnj)      limbo.entrar_personaje(pnj)
436    
# Line 409  if (__name__ == '__main__'): Line 455  if (__name__ == '__main__'):
455      print "  idioma_base: %s" % pnj.idioma_base.nombre      print "  idioma_base: %s" % pnj.idioma_base.nombre
456    
457      print "\nmochila"      print "\nmochila"
458      if len(pnj.mochila()) == 0:      if len(pnj.mochila) == 0:
459          print "  vacía"          print "  vacía"
460      else:      else:
461          for instancias_objeto in pnj.mochila():          for instancias_objeto in pnj.mochila:
462              print "  %s (%d)" % (instancias_objeto[0].nombre(), len(instancias_objeto))              print "  %s (%d)" % (instancias_objeto[0].nombre(), len(instancias_objeto))
463    

Legend:
Removed from v.2.6  
changed lines
  Added in v.2.7

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