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

Diff of /ambar/personaje.py

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

revision 2.19 by amoyav, Sun Aug 31 20:43:27 2003 UTC revision 2.20 by TuringTest, Fri Sep 5 21:26:01 2003 UTC
# Line 69  class Personaje(object): Line 69  class Personaje(object):
69      # Posiciones del cuerpo donde se pueden poner objetos      # Posiciones del cuerpo donde se pueden poner objetos
70      POSICIONES = [ 'cabeza', 'cuello', 'tronco', 'brazo-izq', 'brazo-der', 'mano-izq',      POSICIONES = [ 'cabeza', 'cuello', 'tronco', 'brazo-izq', 'brazo-der', 'mano-izq',
71                     'mano-der', 'dos-manos', 'piernas', 'tobillo-izq', 'tobillo-der',                     'mano-der', 'dos-manos', 'piernas', 'tobillo-izq', 'tobillo-der',
72                     'pie-izq', 'pie-der' ]                     'pie-izq', 'pie-der' ]
73    
74      # Atributos públicos de la clase      # Atributos públicos de la clase
75    
# Line 78  class Personaje(object): Line 78  class Personaje(object):
78      id = property(__leer_id,      id = property(__leer_id,
79                    doc="""(string): identifica univocamente al personaje.                    doc="""(string): identifica univocamente al personaje.
80    
81                        No puede contener espacios ni símbolos raros.                        No puede contener espacios ni símbolos raros.
82    
83                        Invariantes:                        Invariantes:
84                            id != None                            id != None
85                        """)                        """)
86    
87      def __leer_version(self): return self.__version      def __leer_version(self): return self.__version
88    
89      version = property(__leer_version,      version = property(__leer_version,
90                         doc="""(string): versión del sistema de personajes.                         doc="""(string): versión del sistema de personajes.
91                                                        
92                             Invariantes:                             Invariantes:
93                                 version != None                                 version != None
94                             """)                             """)
95    
96      def __leer_nombre(self): return self.__nombre      def __leer_nombre(self): return self.__nombre
97    
# Line 99  class Personaje(object): Line 99  class Personaje(object):
99                        doc="""(string): también identifica univocamente, pero este ya puede contener                        doc="""(string): también identifica univocamente, pero este ya puede contener
100                            espacios, porque es como se muestra en pantalla.                            espacios, porque es como se muestra en pantalla.
101    
102                            Invariantes:                            Invariantes:
103                                nombre != None                                nombre != None
104                            """)                            """)
105    
106      def __leer_descripcion(self): return self.__descripcion      def __leer_descripcion(self): return self.__descripcion
107    
# Line 127  class Personaje(object): Line 127  class Personaje(object):
127    
128      experiencia = property(__leer_experiencia,      experiencia = property(__leer_experiencia,
129                             doc="""(int): puntos de experiencia acumulados.                             doc="""(int): puntos de experiencia acumulados.
130                                                                
131                                 Invariantes:                                 Invariantes:
132                                     experiencia >= 0                                     experiencia >= 0
133                                 """)                                 """)
134                                                            
135    
136      def __leer_nivel(self): return self.__nivel      def __leer_nivel(self): return self.__nivel
# Line 138  class Personaje(object): Line 138  class Personaje(object):
138      nivel = property(__leer_nivel,      nivel = property(__leer_nivel,
139                       doc="""(int): poder del personaje.                       doc="""(int): poder del personaje.
140    
141                           Cada 1000 puntos de experiencia incrementan un nivel. El ajuste se hace                           Cada 1000 puntos de experiencia incrementan un nivel. El ajuste se hace
142                           automáticamente (al asignar experiencia se actualiza el nivel y viceversa).                           automáticamente (al asignar experiencia se actualiza el nivel y viceversa).
143    
144                           Invariantes:                           Invariantes:
145                               nivel >= 1                               nivel >= 1
146                           """)                           """)
147    
148      def __leer_vida(self): return self.__vida      def __leer_vida(self): return self.__vida
149    
150      vida = property(__leer_vida,      vida = property(__leer_vida,
151                      doc="""(int): puntos de vida que aguanta antes de morir.                      doc="""(int): puntos de vida que aguanta antes de morir.
152    
153                          Invariantes:                          Invariantes:
154                              vida > 0                              vida > 0
155                          """)                          """)
156    
157      def __leer_volumen(self): return self.__volumen      def __leer_volumen(self): return self.__volumen
158    
159      volumen = property(__leer_volumen,      volumen = property(__leer_volumen,
160                         doc="""(float): tamaño que ocupa, para ver si cabe o no en las salas                         doc="""(float): tamaño que ocupa, para ver si cabe o no en las salas
161                             (1 es igual al tamaño de un humano)                             (1 es igual al tamaño de un humano)
162    
163                             Invariantes:                             Invariantes:
164                                 volumen > 0.0                                 volumen > 0.0
165                             """)                             """)
166    
167      def __leer_estado(self): return self.__estado      def __leer_estado(self): return self.__estado
168      def __poner_estado(self, estado): self.__estado = estado      def __poner_estado(self, estado): self.__estado = estado
# Line 170  class Personaje(object): Line 170  class Personaje(object):
170      estado = property(__leer_estado,      estado = property(__leer_estado,
171                        doc="""(string): puede ser "vivo" o "muerto".                        doc="""(string): puede ser "vivo" o "muerto".
172    
173                            Invariantes:                            Invariantes:
174                                estado in ("vivo", "muerto")                                estado in ("vivo", "muerto")
175                            """)                            """)
176    
177      def __leer_aura(self): return self.__aura      def __leer_aura(self): return self.__aura
178      def __poner_aura(self, aura): self.__aura = aura      def __poner_aura(self, aura): self.__aura = aura
# Line 180  class Personaje(object): Line 180  class Personaje(object):
180      aura = property(__leer_aura,      aura = property(__leer_aura,
181                      doc="""(int): alineamiento del personaje (0=Morgoth, 50=neutral, 100=un Valar)                      doc="""(int): alineamiento del personaje (0=Morgoth, 50=neutral, 100=un Valar)
182    
183                          Invariantes:                          Invariantes:
184                              aura in range(0,100)                              aura in range(0,100)
185                          """)                          """)
186    
187      def __leer_sala(self): return self.__sala      def __leer_sala(self): return self.__sala
188    
189      sala = property(__leer_sala,      sala = property(__leer_sala,
190                      doc="""(Sala): sala actual en la que se encuentra el personaje.                      doc="""(Sala): sala actual en la que se encuentra el personaje.
191    
192                          Invariantes:                          Invariantes:
193                              sala != None                              sala != None
194                              self in sala.personajes.values()                              self in sala.personajes.values()
195                          """)                          """)
196    
197      def __leer_controlador(self): return self.__controlador      def __leer_controlador(self): return self.__controlador
198      def __poner_controlador(self, controlador): self.__controlador = controlador      def __poner_controlador(self, controlador): self.__controlador = controlador
199    
200      controlador = property(__leer_controlador, __poner_controlador,      controlador = property(__leer_controlador, __poner_controlador,
201                             doc="""(Controlador): la entidad que controla a este personaje,                             doc="""(Controlador): la entidad que controla a este personaje,
202                                 o None si está inactivo.                                 o None si está inactivo.
203    
204                                 Invariantes:                                 Invariantes:
205                                     controlador != None <-> ( sala.id != Mundo.ID_SALA_LIMBO and                                     controlador != None <-> ( sala.id != Mundo.ID_SALA_LIMBO and
206                                                               self in Mundo.pjs_activos.values() )                                                               self in Mundo.pjs_activos.values() )
207                                     controlador == None <-> ( sala.id == Mundo.ID_SALA_LIMBO and                                     controlador == None <-> ( sala.id == Mundo.ID_SALA_LIMBO and
208                                                               self not in Mundo.pjs_activos.values() )                                                               self not in Mundo.pjs_activos.values() )
209                                     controlador == None -> ( siguiente == None and anterior == None )                                     controlador == None -> ( siguiente == None and anterior == None )
210                                 """)                                 """)
211    
212      def __leer_atrib(self): return self.__atrib      def __leer_atrib(self): return self.__atrib
213    
214      atrib = property(__leer_atrib,      atrib = property(__leer_atrib,
215                       doc="""({String:int}): atributos del personaje.                       doc="""({String:int}): atributos del personaje.
216                                            
217                           Cada atributo tiene un nombre (un string que hace de índice) y un valor                           Cada atributo tiene un nombre (un string que hace de índice) y un valor
218                           entero. Los atributos son fuerza, destreza, constitucion, inteligencia,                           entero. Los atributos son fuerza, destreza, constitucion, inteligencia,
219                           sabiduria y carisma.                           sabiduria y carisma.
220    
221                           Invariantes:                           Invariantes:
222                               atrib != None                               atrib != None
223                               len(atrib) == 6                               len(atrib) == 6
224                           """)                           """)
225    
226      def __leer_idiomas(self): return self.__idiomas      def __leer_idiomas(self): return self.__idiomas
227    
228      idiomas = property(__leer_idiomas,      idiomas = property(__leer_idiomas,
229                         doc="""({Idioma:int}): lista de los idiomas que conoce.                         doc="""({Idioma:int}): lista de los idiomas que conoce.
230                                                
231                             Cada idioma es el índice de un diccionario que apunta al nivel que tiene                             Cada idioma es el índice de un diccionario que apunta al nivel que tiene
232                             el personaje en ese idioma.                             el personaje en ese idioma.
233    
234                             Invariantes:                             Invariantes:
235                                 idiomas != None                                 idiomas != None
236                                 len(idiomas) == len(Idioma_lista)                                 len(idiomas) == len(Idioma_lista)
237                             """)                             """)
238    
239      def __leer_idioma_base(self): return self.__idioma_base      def __leer_idioma_base(self): return self.__idioma_base
240    
241      idioma_base = property(__leer_idioma_base,      idioma_base = property(__leer_idioma_base,
242                             doc="""(Idioma): el idioma que habla por defecto.                             doc="""(Idioma): el idioma que habla por defecto.
243                                                        
244                                 Comienza siendo Idioma_oestron.                                 Comienza siendo Idioma_oestron.
245    
246                                 Invariantes:                                 Invariantes:
247                                     idioma_base != None                                     idioma_base != None
248                                     idioma_base in Idioma_lista                                     idioma_base in Idioma_lista
249                                 """)                                 """)
250    
251      def __leer_id_sala_original(self): return self.__id_sala_original      def __leer_id_sala_original(self): return self.__id_sala_original
252    
253      id_sala_original = property(__leer_id_sala_original,      id_sala_original = property(__leer_id_sala_original,
254                                  doc="""(string): solo mientras esta en el limbo, id de la sala                                  doc="""(string): solo mientras esta en el limbo, id de la sala
255                                      donde estaba antes.                                      donde estaba antes.
256                                      """)                                      """)
257    
258      def __leer_siguiente(self): return self.__siguiente      def __leer_siguiente(self): return self.__siguiente
259    
260      siguiente = property(__leer_siguiente,      siguiente = property(__leer_siguiente,
261                           doc="""(Personaje): el personaje que va detrás de el en la compañia                           doc="""(Personaje): el personaje que va detrás de el en la compañia
262                               (None si no está en ninguna compañia o va el último).                               (None si no está en ninguna compañia o va el último).
263    
264                               Invariantes:                               Invariantes:
265                                   siguiente != None -> siguiente.anterior == self                                   siguiente != None -> siguiente.anterior == self
266                               """)                               """)
267    
268      def __leer_anterior(self): return self.__anterior      def __leer_anterior(self): return self.__anterior
269    
270      anterior = property(__leer_anterior,      anterior = property(__leer_anterior,
271                          doc="""(Personaje): el personaje que va delante de el en la compañia                          doc="""(Personaje): el personaje que va delante de el en la compañia
272                              (None si no está en ninguna compañía o va el primero).                              (None si no está en ninguna compañía o va el primero).
273    
274                              Invariantes:                              Invariantes:
275                                  anterior != None -> anterior.siguiente == self                                  anterior != None -> anterior.siguiente == self
276                              """)                              """)
277    
278      def __leer_mochila(self): return self.__mochila      def __leer_mochila(self): return self.__mochila
279    
280      mochila = property(__leer_mochila,      mochila = property(__leer_mochila,
281                         doc="""(Objeto[][]): lista de todos los objetos que va cargando el personaje.                         doc="""(Objeto[][]): lista de todos los objetos que va cargando el personaje.
282                                                
283                             Es lista doble porque si hay varios objetos con el mismo id, van agrupados                             Es lista doble porque si hay varios objetos con el mismo id, van agrupados
284                             en forma de lista de instancias.                             en forma de lista de instancias.
285                                    
286                             Invariantes:                             Invariantes:
287                                 mochila != None                                 mochila != None
288                                 mochila[i] != None                                 mochila[i] != None
289                                 len(mochila[i] > 0)                                 len(mochila[i] > 0)
290                                 mochila[i][j] != None                                 mochila[i][j] != None
291                              """)                              """)
292    
293      def __leer_cuerpo(self): return self.__cuerpo      def __leer_cuerpo(self): return self.__cuerpo
294    
295      cuerpo = property(__leer_cuerpo,      cuerpo = property(__leer_cuerpo,
296                        doc="""({String:Objeto}): mapa con las partes del cuerpo del PJ, indicando                        doc="""({String:Objeto}): mapa con las partes del cuerpo del PJ, indicando
297                            el objeto que lleva puesto en cada parte, o None si no lleva nada.                            el objeto que lleva puesto en cada parte, o None si no lleva nada.
298                                                        
299                            Las partes o posiciones son:                            Las partes o posiciones son:
300    
301                            cabeza, cuello, tronco, brazo-izq, brazo-der, mano-izq, mano-der, dos-manos,                            cabeza, cuello, tronco, brazo-izq, brazo-der, mano-izq, mano-der, dos-manos,
302                            piernas, tobillo-izq, tobillo-der, pie-izq y pie-der.                            piernas, tobillo-izq, tobillo-der, pie-izq y pie-der.
303                                    
304                            Invariantes:                            Invariantes:
305                                cuerpo != None                                cuerpo != None
306                                len(cuerpo) == len(Personaje.POSICIONES)                                len(cuerpo) == len(Personaje.POSICIONES)
307                            """)                            """)
308    
309      def __leer_ids_amigos(self): return self.__ids_amigos      def __leer_ids_amigos(self): return self.__ids_amigos
310    
311      ids_amigos = property(__leer_ids_amigos,      ids_amigos = property(__leer_ids_amigos,
312                            doc="""(Diccionario): Se trata de un diccionario de la forma {id:int}                            doc="""(Diccionario): Se trata de un diccionario de la forma {id:int}
313                                en donde id es un string que identifica a un personaje e int es el                                en donde id es un string que identifica a un personaje e int es el
314                                grado de confianza, siendo 0 nada, 1 toda (de momento).                                grado de confianza, siendo 0 nada, 1 toda (de momento).
315    
316                                Invariantes:                                Invariantes:
317                                    ids_amigos != None                                    ids_amigos != None
318                                """)                                """)
319    
320      def __leer_salas_visitadas(self): return self.__salas_visitadas      def __leer_salas_visitadas(self): return self.__salas_visitadas
321    
322      salas_visitadas = property(__leer_salas_visitadas,      salas_visitadas = property(__leer_salas_visitadas,
323                                 doc="""(Diccionario): Un diccionario que tiene como claves todas las                                 doc="""(Diccionario): Un diccionario que tiene como claves todas las
324                                     salas que el personaje ha ido visitando en su vida (el valor mapeado                                     salas que el personaje ha ido visitando en su vida (el valor mapeado
325                                     no es relevante, y vale siempre 'si').                                     no es relevante, y vale siempre 'si').
326    
327                                     Habrá que recortar esto de alguna manera, para que no se vuelva                                     Habrá que recortar esto de alguna manera, para que no se vuelva
328                                     gigantescamente grande.                                     gigantescamente grande.
329    
330                                     Invariantes:                                     Invariantes:
331                                         salas_visitadas != None                                         salas_visitadas != None
332                                     """)                                     """)
333    
334      # Constructor      # Constructor
335    
# Line 363  class Personaje(object): Line 363  class Personaje(object):
363          self.__max_vida = vida          self.__max_vida = vida
364          self.__volumen = volumen          self.__volumen = volumen
365          self.__estado = estado          self.__estado = estado
366          self.__aura = aura          self.__aura = aura
367          self.__controlador = controlador          self.__controlador = controlador
368          self.__atrib = atrib          self.__atrib = atrib
369          self.__idiomas = idiomas          self.__idiomas = idiomas
# Line 378  class Personaje(object): Line 378  class Personaje(object):
378          from objeto import Objeto          from objeto import Objeto
379    
380          self.__mochila = []          self.__mochila = []
381          self.__cuerpo = {}          self.__cuerpo = {}
382          for posicion in Personaje.POSICIONES:          for posicion in Personaje.POSICIONES:
383              self.__cuerpo[posicion] = None              self.__cuerpo[posicion] = None
384    
385          self.__ids_amigos = {}          self.__ids_amigos = {}
386          self.__salas_visitadas = {}          self.__salas_visitadas = {}
# Line 393  class Personaje(object): Line 393  class Personaje(object):
393          if self.__controlador != None:          if self.__controlador != None:
394              self.liberar()              self.liberar()
395          if self.__sala != None:          if self.__sala != None:
396              if self in self.__sala.personajes.values():              if self in self.__sala.personajes.values():
397                  self.__sala.salir_personaje(self)                  self.__sala.salir_personaje(self)
398                  for otro_personaje in self.__sala.personajes.values():                  for otro_personaje in self.__sala.personajes.values():
399                      if otro_personaje.__controlador != None:                      if otro_personaje.__controlador != None:
400                          otro_personaje.__controlador.sale_personaje(self, "el vacío")                          otro_personaje.__controlador.sale_personaje(self, "el vacío")
401              self.__sala = None              self.__sala = None
402          if isinstance(self, PersonajeJugador):          if isinstance(self, PersonajeJugador):
403              self._PersonajeJugador__crono_subir_hambre.parar()              self._PersonajeJugador__crono_subir_hambre.parar()
404              self._PersonajeJugador__crono_subir_hambre = None              self._PersonajeJugador__crono_subir_hambre = None
405              self._PersonajeJugador__crono_subir_sed.parar()              self._PersonajeJugador__crono_subir_sed.parar()
406              self._PersonajeJugador__crono_subir_sed = None              self._PersonajeJugador__crono_subir_sed = None
407              if self._PersonajeJugador__crono_msg_hambre != None:              if self._PersonajeJugador__crono_msg_hambre != None:
408                  self._PersonajeJugador__crono_msg_hambre.parar()                  self._PersonajeJugador__crono_msg_hambre.parar()
409                  self._PersonajeJugador__crono_msg_hambre = None                  self._PersonajeJugador__crono_msg_hambre = None
410              if self._PersonajeJugador__crono_msg_sed != None:              if self._PersonajeJugador__crono_msg_sed != None:
411                  self._PersonajeJugador__crono_msg_sed.parar()                  self._PersonajeJugador__crono_msg_sed.parar()
412                  self._PersonajeJugador__crono_msg_sed = None                  self._PersonajeJugador__crono_msg_sed = None
413    
414    
415      def __getstate__(self):      def __getstate__(self):
416          """Método llamado para preguntar qué hay que salvar en un pickle."""          """Método llamado para preguntar qué hay que salvar en un pickle."""
417          from personajejugador import PersonajeJugador          from personajejugador import PersonajeJugador
418    
419          atributos = self.__dict__.copy()          atributos = self.__dict__.copy()
420    
# Line 430  class Personaje(object): Line 430  class Personaje(object):
430    
431          atributos["_Personaje__idiomas"] = idiomas_nombres          atributos["_Personaje__idiomas"] = idiomas_nombres
432    
433          atributos["_Personaje__idioma_base"] = self.__idioma_base.nombre          atributos["_Personaje__idioma_base"] = self.__idioma_base.nombre
434                    
435          if isinstance(self, PersonajeJugador):          if isinstance(self, PersonajeJugador):
436              # Lo mismo con la raza (solo PJ)              # Lo mismo con la raza (solo PJ)
437              atributos["_PersonajeJugador__raza"] = self._PersonajeJugador__raza.nombre              atributos["_PersonajeJugador__raza"] = self._PersonajeJugador__raza.nombre
438    
439          return atributos          return atributos
440    
441    
442      def __setstate__(self, atributos):      def __setstate__(self, atributos):
443          """Método llamado para restaurar los atributos provinientes de un pickle."""          """Método llamado para restaurar los atributos provinientes de un pickle."""
444          from personajejugador import PersonajeJugador          from personajejugador import PersonajeJugador
445          from personajenojugador import PersonajeNoJugador          from personajenojugador import PersonajeNoJugador
446          from interfazpnj import InterfazPNJ          from interfazpnj import InterfazPNJ
447          from raza import Raza_buscar          from raza import Raza_buscar
448          from mundo import Mundo          from mundo import Mundo
449    
450          self.__dict__ = atributos          self.__dict__ = atributos
451                            
452          # Verificar la versión.          # Verificar la versión.
453          if not self.__dict__.has_key("_Personaje__version"):          if not self.__dict__.has_key("_Personaje__version"):
454              raise ValueError("Cargado personaje " + self.__id + " obsoleto: sin versión" +              raise ValueError("Cargado personaje " + self.__id + " obsoleto: sin versión" +
455                               " cuando se esperaba " + Personaje.VERSION)                               " cuando se esperaba " + Personaje.VERSION)
456    
457          assert(Personaje.VERSION == "1.5.5")          assert(Personaje.VERSION == "1.5.5")
458          while self.__version != "1.5.5":          while self.__version != "1.5.5":
459    
460              # La versión 1.5.1 produce una ruptura con las anteriores ya que se migra al formato              # La versión 1.5.1 produce una ruptura con las anteriores ya que se migra al formato
461              # de clases de Python 2.2, y no es compatible con el anterior. Hay que borrar todas              # de clases de Python 2.2, y no es compatible con el anterior. Hay que borrar todas
462              # las salas, personajes y objetos.              # las salas, personajes y objetos.
463    
464              if self.__version == "1.5.1":              if self.__version == "1.5.1":
465                  # Versión 1.5.1 -> 1.5.2: añadir __max_vida                  # Versión 1.5.1 -> 1.5.2: añadir __max_vida
466                  self.__max_vida = self.__vida                  self.__max_vida = self.__vida
467                  self.__version = "1.5.2"                  self.__version = "1.5.2"
468                  escribir("Convertido personaje " + self.__id + " a versión 1.5.2")                  escribir("Convertido personaje " + self.__id + " a versión 1.5.2")
469              elif self.__version == "1.5.2":              elif self.__version == "1.5.2":
470                  # Versión 1.5.2 -> 1.5.3: añadir __hambre y __sed, la raza ahora                  # Versión 1.5.2 -> 1.5.3: añadir __hambre y __sed, la raza ahora
471                  # es solo el nombre y no la instancia entera.                  # es solo el nombre y no la instancia entera.
472                  if isinstance(self, PersonajeJugador):                  if isinstance(self, PersonajeJugador):
473                      self._PersonajeJugador__hambre = 0                      self._PersonajeJugador__hambre = 0
474                      self._PersonajeJugador__sed = 0                      self._PersonajeJugador__sed = 0
475                      self._PersonajeJugador__crono_subir_hambre = FechaHoraMineRel(horas = self._PersonajeJugador__raza.tiempo_hambre)                      self._PersonajeJugador__crono_subir_hambre = FechaHoraMineRel(horas = self._PersonajeJugador__raza.tiempo_hambre)
476                      self._PersonajeJugador__crono_subir_sed = FechaHoraMineRel(horas = self._PersonajeJugador__raza.tiempo_sed)                      self._PersonajeJugador__crono_subir_sed = FechaHoraMineRel(horas = self._PersonajeJugador__raza.tiempo_sed)
477                      self._PersonajeJugador__crono_msg_hambre = None                      self._PersonajeJugador__crono_msg_hambre = None
478                      self._PersonajeJugador__crono_msg_sed = None                      self._PersonajeJugador__crono_msg_sed = None
479                      self._PersonajeJugador__raza = self._PersonajeJugador__raza.nombre                      self._PersonajeJugador__raza = self._PersonajeJugador__raza.nombre
480                  self.__version = "1.5.3"                  self.__version = "1.5.3"
481                  escribir("Convertido personaje " + self.__id + " a versión 1.5.3")                  escribir("Convertido personaje " + self.__id + " a versión 1.5.3")
482              if self.__version == "1.5.3":              if self.__version == "1.5.3":
# Line 499  class Personaje(object): Line 499  class Personaje(object):
499          if isinstance(self, PersonajeNoJugador):          if isinstance(self, PersonajeNoJugador):
500    
501              # PNJ: se crea el controlador al momento              # PNJ: se crea el controlador al momento
502              self.controlador_automatico()              self.controlador_automatico()
503    
504          else:          else:
505    
# Line 514  class Personaje(object): Line 514  class Personaje(object):
514    
515          self.__idiomas = idiomas_instancias          self.__idiomas = idiomas_instancias
516    
517          idioma_base = Idioma_buscar(atributos["_Personaje__idioma_base"])          idioma_base = Idioma_buscar(atributos["_Personaje__idioma_base"])
518          self.__idioma_base = idioma_base          self.__idioma_base = idioma_base
519                    
520          # Lo mismo con la raza (solo PJ)          # Lo mismo con la raza (solo PJ)
521          if isinstance(self, PersonajeJugador):          if isinstance(self, PersonajeJugador):
522              self._PersonajeJugador__raza = Raza_buscar(self._PersonajeJugador__raza)              self._PersonajeJugador__raza = Raza_buscar(self._PersonajeJugador__raza)
523    
524    
525      # métodos normales      # métodos normales
526    
527      def cambiar_experiencia(self, puntos):      def cambiar_experiencia(self, puntos):
528          """Modifica el valor de la propiedad experiencia, sumando los puntos indicados.          """Modifica el valor de la propiedad experiencia, sumando los puntos indicados.
529                    
530          El nivel es ajustado correspondientemente.          El nivel es ajustado correspondientemente.
531          """          """
532          self.__experiencia += puntos          self.__experiencia += puntos
533          self.__nivel = self.__experiencia / 1000          self.__nivel = self.__experiencia / 1000
534    
535    
536      def cambiar_nivel(self, nuevo_nivel):      def cambiar_nivel(self, nuevo_nivel):
537          """Fuerza el nivel de un personaje, y resetea los puntos de experiencia al mínimo          """Fuerza el nivel de un personaje, y resetea los puntos de experiencia al mínimo
538          para ese nivel.          para ese nivel.
539                    
540          No tengo muy claro si tiene mucho sentido esto, se podría usar por ejemplo si te          No tengo muy claro si tiene mucho sentido esto, se podría usar por ejemplo si te
541          lanzan una maldición que hace que bajes un nivel y pierdas la experiencia          lanzan una maldición que hace que bajes un nivel y pierdas la experiencia
542          acumulada. No sé, no sé...          acumulada. No sé, no sé...
543          """          """
544          self.__nivel = nivel          self.__nivel = nivel
545          self.__experiencia = nivel * 1000          self.__experiencia = nivel * 1000
546    
547    
548      def cambiar_vida(self, puntos):      def cambiar_vida(self, puntos):
549          """Modifica el valor de la propiedad vida.          """Modifica el valor de la propiedad vida.
550    
551          El valor del parámetro puntos es sumado al de la propiedad. Puede ser negativo. Si el          El valor del parámetro puntos es sumado al de la propiedad. Puede ser negativo. Si el
552          resultado es menor que 0 o mayor que el máximo, se trunca.          resultado es menor que 0 o mayor que el máximo, se trunca.
553          """          """
554          self.__vida += puntos          self.__vida += puntos
555          if self.__vida < 0:          if self.__vida < 0:
556              self.__vida = 0              self.__vida = 0
557          if self.__vida > self.__max_vida:          if self.__vida > self.__max_vida:
558              self.__vida = self.__max_vida              self.__vida = self.__max_vida
559    
560    
561      def atributo(self, atributo):      def atributo(self, atributo):
562          """Devuelve el valor del atributo con el nombre indicado.          """Devuelve el valor del atributo con el nombre indicado.
563    
564          Es útil para requisitos.          Es útil para requisitos.
565    
566          Requiere:          Requiere:
567              atributo in self.__atrib.keys()              atributo in self.__atrib.keys()
568          """          """
569          return self.__atrib[atributo]          return self.__atrib[atributo]
570    
571    
572    
573      def cambiar_atributo(self, atributo, niveles):      def cambiar_atributo(self, atributo, niveles):
574          """Modifica el valor del atributo con el nombre indicado.          """Modifica el valor del atributo con el nombre indicado.
575    
576          El valor del parámetro niveles es sumado al del valor del atributo. Puede ser negativo.          El valor del parámetro niveles es sumado al del valor del atributo. Puede ser negativo.
577          Si el resultado es menor que 0 o mayor que el máximo, se trunca. <-%% ojo, sin hacer          Si el resultado es menor que 0 o mayor que el máximo, se trunca. <-%% ojo, sin hacer
578    
579          Requiere:          Requiere:
580              atributo in self.__atrib.keys()              atributo in self.__atrib.keys()
581          """          """
582          self.__atrib[atributo] += niveles          self.__atrib[atributo] += niveles
583          #%% OJO, comprobar los máximos...          #%% OJO, comprobar los máximos...
584    
585    
586      def cambiar_idioma(self, idioma, niveles):      def cambiar_idioma(self, idioma, niveles):
587          """Modifica el valor del idioma con el nombre indicado.          """Modifica el valor del idioma con el nombre indicado.
588    
589          El valor del parámetro niveles es sumado al del idioma. Puede ser negativo. Si el          El valor del parámetro niveles es sumado al del idioma. Puede ser negativo. Si el
590          resultado es menor que 0 o mayor que el máximo, se trunca.          resultado es menor que 0 o mayor que el máximo, se trunca.
591          """          """
592          print "[" + str(idioma) + "]"          print "[" + str(idioma) + "]"
593          self.__idiomas[idioma] += niveles          self.__idiomas[idioma] += niveles
594          #%% OJO, comprobar los máximos...          #%% OJO, comprobar los máximos...
595    
596    
597      def volumen_total(self):      def volumen_total(self):
598          """El total de volumen que ocupa el personaje y todos los objetos que carga.          """El total de volumen que ocupa el personaje y todos los objetos que carga.
599          Asegura:          Asegura:
600            return > 0.0            return > 0.0
601          """          """
602          total = self.__volumen          total = self.__volumen
603          for objeto in self.__mochila:          for objeto in self.__mochila:
604              for instancia in objeto:              for instancia in objeto:
605                  total += instancia.volumen                  total += instancia.volumen
606          for objeto in self.__cuerpo.values():          for objeto in self.__cuerpo.values():
607              if objeto != None:              if objeto != None:
608                  total += objeto.volumen                  total += objeto.volumen
609          return total          return total
610                    
611    
612      def color_texto(self):      def color_texto(self):
# Line 615  class Personaje(object): Line 615  class Personaje(object):
615          from personajenojugador import PersonajeNoJugador          from personajenojugador import PersonajeNoJugador
616          if isinstance(self, PersonajeNoJugador):          if isinstance(self, PersonajeNoJugador):
617              return chr(27) + "[1;" + str(35) + "m"              return chr(27) + "[1;" + str(35) + "m"
618          else:          else:
619              base = 0              base = 0
620              for letra in self.__nombre:              for letra in self.__nombre:
621                  base = base + ord(letra)                  base = base + ord(letra)
622              return color(31 + base % 7)              return color(31 + base % 7)
623    
624                    
625      def mover(self, sala_destino, automatico = 0):      def mover(self, sala_destino, automatico = 0):
# Line 627  class Personaje(object): Line 627  class Personaje(object):
627                    
628          Se avisa a la sala sala actual y a la nueva (y a todos los personajes en ambas).          Se avisa a la sala sala actual y a la nueva (y a todos los personajes en ambas).
629    
630          Si el personaje está en una compañía, pero no es el lider, la abandona. Si es          Si el personaje está en una compañía, pero no es el lider, la abandona. Si es
631          el líder, los personajes que le siguen se mueven también con él, con movimiento          el líder, los personajes que le siguen se mueven también con él, con movimiento
632          automático. Todos los personajes con movimiento automático producen un evento          automático. Todos los personajes con movimiento automático producen un evento
633          a su controlador.          a su controlador.
634    
635          Si la sala destino se llena, los que vengan detrás en compañia la abandonan.          Si la sala destino se llena, los que vengan detrás en compañia la abandonan.
636    
637          Se olvidan todas las tiradas y competiciones memorizadas.          Se olvidan todas las tiradas y competiciones memorizadas.
638    
# Line 640  class Personaje(object): Line 640  class Personaje(object):
640                    
641          Requiere:          Requiere:
642              sala_destino != None              sala_destino != None
643              sala_destino.volumen_ocupado() + self.volumen_total() <= sala_destino.volumen              sala_destino.volumen_ocupado() + self.volumen_total() <= sala_destino.volumen
644                            
645          Asegura:          Asegura:
646              self.sala == sala_destino              self.sala == sala_destino
647          """          """
648          try:          try:
649    
650              if not automatico:              if not automatico:
651                  if self.__anterior != None:                  if self.__anterior != None:
652                      self.no_seguir();                      self.no_seguir();
653    
654              self.__sala.salir_personaje(self)              self.__sala.salir_personaje(self)
655              for otro_personaje in self.__sala.personajes.values():              for otro_personaje in self.__sala.personajes.values():
# Line 663  class Personaje(object): Line 663  class Personaje(object):
663                      otro_personaje.controlador.entra_personaje(self)                      otro_personaje.controlador.entra_personaje(self)
664              self.__sala.entrar_personaje(self)              self.__sala.entrar_personaje(self)
665    
666              if automatico:              if automatico:
667                  if self.__controlador != None:                  if self.__controlador != None:
668                     self.__controlador.movimiento_automatico()                     self.__controlador.movimiento_automatico()
669    
670              if self.__siguiente != None:              if self.__siguiente != None:
671                  if sala_destino.volumen_ocupado() + self.__siguiente.volumen_total() <= sala_destino.volumen:                  if sala_destino.volumen_ocupado() + self.__siguiente.volumen_total() <= sala_destino.volumen:
672                      self.__siguiente.mover(sala_destino, 1)                      self.__siguiente.mover(sala_destino, 1)
673                  else:                  else:
674                      self.__siguiente.actuar_uno_mismo(                      self.__siguiente.actuar_uno_mismo(
675                          "Intentas seguir a " + self.__id + " pero el lugar a donde se dirige está " +                          "Intentas seguir a " + self.__id + " pero el lugar a donde se dirige está " +
676                          "al límite de su capacidad y no cabes. Ya no sigues a " + self.__id + ".")                          "al límite de su capacidad y no cabes. Ya no sigues a " + self.__id + ".")
677                      self.__siguiente.no_seguir()                      self.__siguiente.no_seguir()
678    
679              self.__tiradas = {}              self.__tiradas = {}
680              self.__competiciones = {}              self.__competiciones = {}
681    
682          except:          except:
683              escribir("Excepción imprevista durante el movimiento de un personaje.")              escribir("Excepción imprevista durante el movimiento de un personaje.")
684              escribir_excepcion()              escribir_excepcion()
685    
686              # Si hay algún error en los avisos, intentamos mover el pesonaje              # Si hay algún error en los avisos, intentamos mover el pesonaje
687              # a un estado consistente (cumpliendo todas las invariantes)              # a un estado consistente (cumpliendo todas las invariantes)
# Line 714  class Personaje(object): Line 714  class Personaje(object):
714    
715          escribir("Enviando al limbo a " + self.__id)          escribir("Enviando al limbo a " + self.__id)
716    
717          if self.__siguiente != None:          if self.__siguiente != None:
718              self.__siguiente.no_seguir()              self.__siguiente.no_seguir()
719    
720          self.__id_sala_original = self.__sala.id          self.__id_sala_original = self.__sala.id
721          self.mover(Mundo.localizar_sala(Mundo.ID_SALA_LIMBO))  # se asume que el limbo tiene          self.mover(Mundo.localizar_sala(Mundo.ID_SALA_LIMBO))  # se asume que el limbo tiene
# Line 726  class Personaje(object): Line 726  class Personaje(object):
726              Mundo.personaje_desactivado(self)              Mundo.personaje_desactivado(self)
727              self.actuar_global("ha salido de Minë")              self.actuar_global("ha salido de Minë")
728    
729              # Los cronometros de hambre y sed se detienen, se guarda el tiempo              # Los cronometros de hambre y sed se detienen, se guarda el tiempo
730              # que les queda para restaurarlos despues por donde iban.              # que les queda para restaurarlos despues por donde iban.
731              self._PersonajeJugador__crono_subir_hambre.pausar()              self._PersonajeJugador__crono_subir_hambre.pausar()
732              self._PersonajeJugador__crono_subir_sed.pausar()              self._PersonajeJugador__crono_subir_sed.pausar()
733              if self._PersonajeJugador__crono_msg_hambre != None:              if self._PersonajeJugador__crono_msg_hambre != None:
734                  self._PersonajeJugador__crono_msg_hambre.pausar()                  self._PersonajeJugador__crono_msg_hambre.pausar()
735              if self._PersonajeJugador__crono_msg_sed != None:              if self._PersonajeJugador__crono_msg_sed != None:
736                  self._PersonajeJugador__crono_msg_sed.pausar()                  self._PersonajeJugador__crono_msg_sed.pausar()
737    
738          # Si hay algún error en actuar_global, no hace falta restaurar nada, el          # Si hay algún error en actuar_global, no hace falta restaurar nada, el
739          # personaje queda en el limbo.          # personaje queda en el limbo.
# Line 754  class Personaje(object): Line 754  class Personaje(object):
754          from mundo import Mundo          from mundo import Mundo
755          from personajejugador import PersonajeJugador          from personajejugador import PersonajeJugador
756    
757          if isinstance(self, PersonajeJugador):          if isinstance(self, PersonajeJugador):
758              escribir("Trayendo desde el limbo a " + self.__id)              escribir("Trayendo desde el limbo a " + self.__id)
759    
760              id_sala_original = self.__id_sala_original              id_sala_original = self.__id_sala_original
761    
762              try:              try:
763    
764                  # Aquí tengo un dilema gordo: en teoría debería comprobar el volumen ocupado de la                  # Aquí tengo un dilema gordo: en teoría debería comprobar el volumen ocupado de la
765                  # sala y no dejarle entrar si está llena. Pero es una putada que alguien no pueda                  # sala y no dejarle entrar si está llena. Pero es una putada que alguien no pueda
766                  # recuperar su personaje porque en la sala donde lo dejó ha entrado un montón de                  # recuperar su personaje porque en la sala donde lo dejó ha entrado un montón de
767                  # gente. Como será un caso muy poco frecuente, haremos la vista gorda y permitiremos                  # gente. Como será un caso muy poco frecuente, haremos la vista gorda y permitiremos
768                  # que haya más gente en la sala de la que cabe, espero que no falle nada (durará                  # que haya más gente en la sala de la que cabe, espero que no falle nada (durará
769                  # sólo un ratito hasta que alguien salga)...                  # sólo un ratito hasta que alguien salga)...
770                  self.mover(Mundo.localizar_sala(self.__id_sala_original))                  self.mover(Mundo.localizar_sala(self.__id_sala_original))
771                  del self.__id_sala_original                  del self.__id_sala_original
772    
773                  self.__controlador = controlador                  self.__controlador = controlador
774    
775                  if isinstance(self, PersonajeJugador):                  if isinstance(self, PersonajeJugador):
776                      Mundo.personaje_activado(self)                      Mundo.personaje_activado(self)
777                      self.actuar_global("ha entrado en Minë")                      self.actuar_global("ha entrado en Minë")
778    
779                      # Restaurar los cronometros de hambre y sed                      # Restaurar los cronometros de hambre y sed
780                      self._PersonajeJugador__crono_subir_hambre.reanudar()                      self._PersonajeJugador__crono_subir_hambre.reanudar()
781                      self._PersonajeJugador__crono_subir_sed.reanudar()                      self._PersonajeJugador__crono_subir_sed.reanudar()
782                      if self._PersonajeJugador__crono_msg_hambre != None:                      if self._PersonajeJugador__crono_msg_hambre != None:
783                          self._PersonajeJugador__crono_msg_hambre.reanudar()                          self._PersonajeJugador__crono_msg_hambre.reanudar()
784                      if self._PersonajeJugador__crono_msg_sed != None:                      if self._PersonajeJugador__crono_msg_sed != None:
785                          self._PersonajeJugador__crono_msg_sed.reanudar()                          self._PersonajeJugador__crono_msg_sed.reanudar()
786    
787              except:              except:
788                  # Si casca algo, volvemos al limbo                  # Si casca algo, volvemos al limbo
789                  self.__id_sala_original = id_sala_original                  self.__id_sala_original = id_sala_original
790                  self.mover(Mundo.localizar_sala(Mundo.ID_SALA_LIMBO))  # se asume que el limbo tiene                  self.mover(Mundo.localizar_sala(Mundo.ID_SALA_LIMBO))  # se asume que el limbo tiene
791                  self.__controlador = None                              # capacidad de volumen infinita                  self.__controlador = None                              # capacidad de volumen infinita
792                  if isinstance(self, PersonajeJugador):                  if isinstance(self, PersonajeJugador):
793                      Mundo.personaje_desactivado(self)                      Mundo.personaje_desactivado(self)
794                  raise                  raise
795          else:          else:
796              self.__controlador = controlador              self.__controlador = controlador
797                                            
798                                    
799      def seguir(self, lider):      def seguir(self, lider):
800          """Entrar en una compañía, siguiendo a otro personaje que hace de lider.          """Entrar en una compañía, siguiendo a otro personaje que hace de lider.
801                    
802          Si el lider ya tenía algún seguidor, éste se coloca en medio de los dos.          Si el lider ya tenía algún seguidor, éste se coloca en medio de los dos.
803          Seguirá en la companía hasta que se llame explícitamente a no_seguir, o          Seguirá en la companía hasta que se llame explícitamente a no_seguir, o
804          se mueva de sala por voluntad propia.          se mueva de sala por voluntad propia.
805    
806          Si este personaje ya era lider de otra compañia, se mezclan ambas,          Si este personaje ya era lider de otra compañia, se mezclan ambas,
807          colocandose la de éste completa justo detras del lider.          colocandose la de éste completa justo detras del lider.
808                    
809          Requiere:          Requiere:
810              anterior == None              anterior == None
811    
812          Asegura:          Asegura:
813              anterior = lider              anterior = lider
814          """          """
815          # Localizar al ultimo personaje de la compañia actual (que puede          # Localizar al ultimo personaje de la compañia actual (que puede
816          # perfectamente ser este personaje si no es lider)          # perfectamente ser este personaje si no es lider)
817          ultimo = self          ultimo = self
818          while ultimo.siguiente != None:          while ultimo.siguiente != None:
819              ultimo = ultimo.siguiente              ultimo = ultimo.siguiente
820    
821          self.__anterior = lider          self.__anterior = lider
822          ultimo.__siguiente = lider.__siguiente          ultimo.__siguiente = lider.__siguiente
823          lider.__siguiente = self          lider.__siguiente = self
824          if ultimo.__siguiente != None:          if ultimo.__siguiente != None:
825              ultimo.__siguiente.__anterior = ultimo              ultimo.__siguiente.__anterior = ultimo
826    
827    
828      def no_seguir(self):      def no_seguir(self):
# Line 831  class Personaje(object): Line 831  class Personaje(object):
831          Requiere:          Requiere:
832              anterior != None              anterior != None
833    
834          Asegura:          Asegura:
835              anterior == None              anterior == None
836          """          """
837          self.__anterior.__siguiente = self.__siguiente          self.__anterior.__siguiente = self.__siguiente
838          if self.__siguiente != None:          if self.__siguiente != None:
# Line 899  class Personaje(object): Line 899  class Personaje(object):
899              for personaje in [ p for p in self.__sala.personajes.values()              for personaje in [ p for p in self.__sala.personajes.values()
900                                   if p.controlador != None]:                                   if p.controlador != None]:
901                  msg_f = self.mensaje_filtrado(texto, idioma, personaje)                  msg_f = self.mensaje_filtrado(texto, idioma, personaje)
902                  personaje.controlador.habla_personaje(self, msg_f)                  personaje.controlador.habla_personaje(self, msg_f)
903  #               else:  #               else:
904  #                       self.controlador.conn().send('Dices: '+ self.__personaje.color_texto() + msg_f)  #                       self.controlador.conn().send('Dices: '+ self.__personaje.color_texto() + msg_f)
905    
906    
907      def susurrar(self, oyente, texto, idioma=Idioma_oestron):      def susurrar(self, oyente, texto, idioma=Idioma_oestron):
# Line 932  class Personaje(object): Line 932  class Personaje(object):
932    
933      def actuar(self, texto):      def actuar(self, texto):
934          """Muestra lo que hace el personaje, de forma novelada, para que          """Muestra lo que hace el personaje, de forma novelada, para que
935          lo vean los personajes que estan en la sala."""          lo vean los personajes que estan en la sala."""
936          if self.__sala != None:          if self.__sala != None:
937              for personaje in [ p for p in self.__sala.personajes.values()              for personaje in [ p for p in self.__sala.personajes.values()
938                                 if p != self and p.controlador != None]:                                 if p != self and p.controlador != None]:
# Line 941  class Personaje(object): Line 941  class Personaje(object):
941    
942      def actuar_individual(self, espectador, texto):      def actuar_individual(self, espectador, texto):
943          """Muestra lo que hace el personaje, solo para que lo perciba          """Muestra lo que hace el personaje, solo para que lo perciba
944          otro personaje."""          otro personaje."""
945          espectador.controlador.actua_individual_personaje(self, texto)          espectador.controlador.actua_individual_personaje(self, texto)
946    
947    
# Line 952  class Personaje(object): Line 952  class Personaje(object):
952    
953      def actuar_global(self, texto):      def actuar_global(self, texto):
954          """Muestra lo que hace el personaje, de forma novelada, para que          """Muestra lo que hace el personaje, de forma novelada, para que
955          lo vean TODOS LOS JUGADORES CONECTADOS."""          lo vean TODOS LOS JUGADORES CONECTADOS."""
956          from mundo import Mundo          from mundo import Mundo
957          for sala in Mundo.salas:          for sala in Mundo.salas:
958              for personaje in [ p for p in sala.personajes.values()              for personaje in [ p for p in sala.personajes.values()
# Line 961  class Personaje(object): Line 961  class Personaje(object):
961    
962    
963      def describir_entorno(self, suceso):      def describir_entorno(self, suceso):
964          """El personaje describe un fenomeno ambiental, independiente de          """El personaje describe un fenomeno ambiental, independiente de
965          el mismo, para que lo vean los personajes que estan en la sala          el mismo, para que lo vean los personajes que estan en la sala
966          (incluido el personaje que lo describe)."""          (incluido el personaje que lo describe)."""
967          if self.__sala != None:          if self.__sala != None:
968              for personaje in [ p for p in self.__sala.personajes.values()              for personaje in [ p for p in self.__sala.personajes.values()
969                                 if p.controlador != None ]:                                 if p.controlador != None ]:
# Line 1028  class Personaje(object): Line 1028  class Personaje(object):
1028    
1029    
1030      def generar_dificultad(self, atributo, modif_atributo):      def generar_dificultad(self, atributo, modif_atributo):
1031          """Calcula la dificultad de una prueba que el personaje impone a otros,          """Calcula la dificultad de una prueba que el personaje impone a otros,
1032          basandose en un atributo (pero que no es una competicion).          basandose en un atributo (pero que no es una competicion).
1033    
1034          La dificultad sera tal que otro personaje con un atributo igual que el tendra          La dificultad sera tal que otro personaje con un atributo igual que el tendra
1035          un 50% de probabilidades de superar la prueba.          un 50% de probabilidades de superar la prueba.
1036    
1037          Ejemplos de prueba: esconder un objeto, atrancar una puerta, etc.          Ejemplos de prueba: esconder un objeto, atrancar una puerta, etc.
1038          """          """
1039    
1040          nivel_atrib = self.__atrib[atributo] + modif_atributo          nivel_atrib = self.__atrib[atributo] + modif_atributo
1041          n_dados = floor(nivel_atrib / 6) + 1          n_dados = floor(nivel_atrib / 6) + 1
1042          rango = rango_dados(n_dados)          rango = rango_dados(n_dados)
1043          dificultad = nivel_atrib + rango[(len(rango)-1) / 2]          dificultad = nivel_atrib + rango[(len(rango)-1) / 2]
1044    
1045          return dificultad          return dificultad
# Line 1050  class Personaje(object): Line 1050  class Personaje(object):
1050          tirada = self.__tiradas[id_tirada]          tirada = self.__tiradas[id_tirada]
1051          diferencia = tirada - (dificultad + modif_dificultad)          diferencia = tirada - (dificultad + modif_dificultad)
1052    
1053          # esto no me convence: la distribucion de las tiradas es muy rara,          # esto no me convence: la distribucion de las tiradas es muy rara,
1054          # y ademas no tiene sentido si la dificultad es cero          # y ademas no tiene sentido si la dificultad es cero
1055          #if diferencia >= 0:          #if diferencia >= 0:
1056          #    return floor(diferencia / dificultad) + 1          #    return floor(diferencia / dificultad) + 1
1057          #else:          #else:
1058          #    return floor(diferencia / dificultad) - 1          #    return floor(diferencia / dificultad) - 1
1059          return diferencia          return diferencia
1060    
1061    
1062      def prueba(self, atributo, modif_atributo, dificultad, modif_dificultad):      def prueba(self, atributo, modif_atributo, dificultad, modif_dificultad):
# Line 1068  class Personaje(object): Line 1068  class Personaje(object):
1068          modif_dificultad -- numero que hay que sumar o restar a la dificultad          modif_dificultad -- numero que hay que sumar o restar a la dificultad
1069    
1070          Devuelve el nº de exitos (>0) si la prueba ha sido superada o el nº de          Devuelve el nº de exitos (>0) si la prueba ha sido superada o el nº de
1071          fallos (<0) si no lo ha sido.          fallos (<0) si no lo ha sido.
1072          """          """
1073          self.tirar_atributo("prueba", atributo, modif_atributo)          self.tirar_atributo("prueba", atributo, modif_atributo)
1074          return self.resultado_tirada("prueba", dificultad, modif_dificultad)          return self.resultado_tirada("prueba", dificultad, modif_dificultad)
1075    
1076    
1077      def competicion(self, otro_personaje, atrib_este, atrib_otro):      def competicion(self, otro_personaje, atrib_este, atrib_otro, bonus=0, malus=0):
1078          """Realiza una competición entre los atributos de este personaje y otro.          """Realiza una competición entre los atributos de este personaje y otro.
1079    
1080          otro_personaje -- el oponente          otro_personaje -- el oponente
# Line 1100  class Personaje(object): Line 1100  class Personaje(object):
1100          self.__vida -= dano          self.__vida -= dano
1101          if self.__vida <= 0:          if self.__vida <= 0:
1102              #self.__estado = "muerto"              #self.__estado = "muerto"
1103              self.resucitar()              self.resucitar()
1104    
1105    
1106      def resucitar(self):      def resucitar(self):
# Line 1244  class Personaje(object): Line 1244  class Personaje(object):
1244    
1245    
1246      def coger(self, id_objeto, n_orden=1, n_instancia=1, cantidad=1, sigilo=0):      def coger(self, id_objeto, n_orden=1, n_instancia=1, cantidad=1, sigilo=0):
1247          """Extrae una o mas instancias de un objeto de la sala y las mete en la mochila.          """Extrae una o mas instancias de un objeto de la sala y las mete en la mochila.
1248    
1249          Genera un suceso de actuar, salvo si se indica con sigilo.          Genera un suceso de actuar, salvo si se indica con sigilo.
1250    
1251          - id_objeto es el identificador del objeto. Puede haber varios objetos distintos          - id_objeto es el identificador del objeto. Puede haber varios objetos distintos
1252            con el mismo id            con el mismo id
1253          - n_orden sirve para distinguir el objeto si hay mas de uno con el mismo id          - n_orden sirve para distinguir el objeto si hay mas de uno con el mismo id
1254          - n_instancia es para elegir una instancia concreta, si hay mas de una          - n_instancia es para elegir una instancia concreta, si hay mas de una
1255          - cantidad es el numero de instancias a extraer          - cantidad es el numero de instancias a extraer
1256          - sigilo indica si se hace intentando que los otros personajes de la sala no          - sigilo indica si se hace intentando que los otros personajes de la sala no
1257            se den cuenta            se den cuenta
1258    
1259          Devuelve el nombre completo del objeto cogido.          Devuelve el nombre completo del objeto cogido.
1260    
1261          Lanza ExcepcionDeJuego si no se puede coger (el id no existe, se piden mas          Lanza ExcepcionDeJuego si no se puede coger (el id no existe, se piden mas
1262          instancias de las que hay, etc.)          instancias de las que hay, etc.)
1263    
1264          Requiere:          Requiere:
1265              id_objeto != None              id_objeto != None
1266              n_orden >= 1              n_orden >= 1
1267              n_instancia >= 1              n_instancia >= 1
1268              cantidad >= 1              cantidad >= 1
1269    
1270          Asegura:          Asegura:
1271              return != None              return != None
1272          """          """
1273          n_objeto = self.__sala.buscar_objeto(id_objeto, n_orden)          n_objeto = self.__sala.buscar_objeto(id_objeto, n_orden)
1274          objetos = self.__sala.coger(n_objeto, n_instancia, cantidad)          objetos = self.__sala.coger(n_objeto, n_instancia, cantidad)
1275          self.meter_en_mochila(objetos)          self.meter_en_mochila(objetos)
1276    
1277          if not sigilo:          if not sigilo:
1278              #%% aquí habría que hacer una tirada en algún sitio...              #%% aquí habría que hacer una tirada en algún sitio...
1279              self.actuar("ha cogido " + objetos[0].nombre)              self.actuar("ha cogido " + objetos[0].nombre)
1280    
1281          return objetos[0].nombre          return objetos[0].nombre
1282    
1283    
1284      def dejar(self, id_objeto, n_orden=1, n_instancia=1, cantidad=1, sigilo=0):      def dejar(self, id_objeto, n_orden=1, n_instancia=1, cantidad=1, sigilo=0):
1285          """Saca una o más instancias de un objeto de la mochila y las suelta en la sala.          """Saca una o más instancias de un objeto de la mochila y las suelta en la sala.
1286    
1287          Resto de información del método igual que coger().          Resto de información del método igual que coger().
1288          """          """
1289          n_objeto = self.buscar_en_mochila(id_objeto, n_orden)          n_objeto = self.buscar_en_mochila(id_objeto, n_orden)
1290          objetos = self.sacar_de_mochila(n_objeto, n_instancia, cantidad)          objetos = self.sacar_de_mochila(n_objeto, n_instancia, cantidad)
1291          self.__sala.dejar(objetos)          self.__sala.dejar(objetos)
1292    
1293          if not sigilo:          if not sigilo:
1294              #%% aquí habría que hacer una tirada en algún sitio...              #%% aquí habría que hacer una tirada en algún sitio...
1295              self.actuar("ha dejado " + objetos[0].nombre)              self.actuar("ha dejado " + objetos[0].nombre)
1296    
1297          return objetos[0].nombre          return objetos[0].nombre
1298    
1299    
1300    
1301      def esconder(self, id_objeto, n_orden=1, n_instancia=1, cantidad=1, sigilo=1):      def esconder(self, id_objeto, n_orden=1, n_instancia=1, cantidad=1, sigilo=1):
1302          """Saca un objeto de la mochila y lo suelta en la sala, dejándolo escondido.          """Saca un objeto de la mochila y lo suelta en la sala, dejándolo escondido.
1303    
1304          La dificultad para encontrarlo dependerá de la inteligencia del personaje.          La dificultad para encontrarlo dependerá de la inteligencia del personaje.
1305    
1306          Resto de información del método igual que coger().          Resto de información del método igual que coger().
1307          """          """
1308          n_objeto = self.buscar_en_mochila(id_objeto, n_orden)          n_objeto = self.buscar_en_mochila(id_objeto, n_orden)
1309          objetos = self.sacar_de_mochila(n_objeto, n_instancia, cantidad)          objetos = self.sacar_de_mochila(n_objeto, n_instancia, cantidad)
1310          dificultad = self.generar_dificultad("inteligencia", 0)          dificultad = self.generar_dificultad("inteligencia", 0)
1311          self.__sala.dejar(objetos, dificultad)          self.__sala.dejar(objetos, dificultad)
1312    
1313          if not sigilo:          if not sigilo:
1314              #%% aquí habría que hacer una tirada en algún sitio...              #%% aquí habría que hacer una tirada en algún sitio...
1315              self.__personaje.actuar("ha escondido algo")              self.__personaje.actuar("ha escondido algo")
1316    
1317          return objeto.nombre          return objeto.nombre
1318    
1319    
1320      def dar(self, receptor, id_objeto, n_orden=1, n_instancia=1, cantidad=1, sigilo=0):      def dar(self, receptor, id_objeto, n_orden=1, n_instancia=1, cantidad=1, sigilo=0):
1321          """Saca una o más instancias de un objeto de la mochila y las mete en la          """Saca una o más instancias de un objeto de la mochila y las mete en la
1322          mochila de otro personaje.          mochila de otro personaje.
1323    
1324          El otro personaje sólo aceptará el objeto si el personaje que da está en la lista          El otro personaje sólo aceptará el objeto si el personaje que da está en la lista
1325          de confianza del receptor (salvo si el que da es un Maia).          de confianza del receptor (salvo si el que da es un Maia).
1326                    
1327          Genera un suceso de actuar, salvo si se indica con sigilo, y otro de actuar          Genera un suceso de actuar, salvo si se indica con sigilo, y otro de actuar
1328          individual.          individual.
1329    
1330          - receptor es el personaje que recibe el objeto          - receptor es el personaje que recibe el objeto
1331    
1332          Resto de información del método igual que coger().          Resto de información del método igual que coger().
1333          """          """
1334          # Comprobar que el personaje que da el objeto se encuentra en la lista          # Comprobar que el personaje que da el objeto se encuentra en la lista
1335          # de confianza del receptor (salvo que el que da sea un Maia...), y que          # de confianza del receptor (salvo que el que da sea un Maia...), y que
1336          # la confianza es >= 0.          # la confianza es >= 0.
1337          if not self.__es_maia:          if not self.__es_maia:
1338              try:              try:
1339                  confianza = receptor.ids_amigos[self.__id]                  confianza = receptor.ids_amigos[self.__id]
1340                  if confianza < 1:                  if confianza < 1:
1341                      raise KeyError                      raise KeyError
1342              except KeyError, e:              except KeyError, e:
1343                  self.actuar_individual(receptor, "te ha intentado dar " + id_objeto + " pero te has negado.")                  self.actuar_individual(receptor, "te ha intentado dar " + id_objeto + " pero te has negado.")
1344                  raise ExcepcionDeJuego(receptor.nombre + " no acepta tu objeto.")                  raise ExcepcionDeJuego(receptor.nombre + " no acepta tu objeto.")
1345    
1346          n_objeto = self.buscar_en_mochila(id_objeto, n_orden)          n_objeto = self.buscar_en_mochila(id_objeto, n_orden)
1347          objetos = self.sacar_de_mochila(n_objeto, n_instancia, cantidad)          objetos = self.sacar_de_mochila(n_objeto, n_instancia, cantidad)
1348          receptor.meter_en_mochila(objetos)          receptor.meter_en_mochila(objetos)
1349    
1350          if not sigilo:          if not sigilo:
1351              #%% aquí habría que hacer una tirada en algún sitio...              #%% aquí habría que hacer una tirada en algún sitio...
1352              self.__personaje.actuar("ha dado " + objetos[0].nombre + " a " + receptor.nombre)              self.__personaje.actuar("ha dado " + objetos[0].nombre + " a " + receptor.nombre)
1353    
1354          msg = "te ha dado " + objetos[0].nombre          msg = "te ha dado " + objetos[0].nombre
1355          if cantidad > 1:          if cantidad > 1:
1356              msg += ' (' + str(cantidad) + ' unidades)'              msg += ' (' + str(cantidad) + ' unidades)'
1357          self.actuar_individual(receptor, msg)          self.actuar_individual(receptor, msg)
1358    
1359          return objetos[0].nombre          return objetos[0].nombre
1360    
1361    
1362      def comer(self, id_objeto, n_orden=1, n_instancia=1, sigilo=0):      def comer(self, id_objeto, n_orden=1, n_instancia=1, sigilo=0):
1363          """Come una instancia de un objeto de la mochila.          """Come una instancia de un objeto de la mochila.
1364    
1365          Genera un suceso de actuar, salvo si se indica con sigilo, y un suceso personaje_come          Genera un suceso de actuar, salvo si se indica con sigilo, y un suceso personaje_come
1366          en el objeto comido.          en el objeto comido.
1367    
1368          - id_objeto es el identificador del objeto. Puede haber varios objetos distintos          - id_objeto es el identificador del objeto. Puede haber varios objetos distintos
1369            con el mismo id            con el mismo id
1370          - n_orden sirve para distinguir el objeto si hay mas de uno con el mismo id          - n_orden sirve para distinguir el objeto si hay mas de uno con el mismo id
1371          - n_instancia es para elegir una instancia concreta, si hay mas de una          - n_instancia es para elegir una instancia concreta, si hay mas de una
1372          - sigilo indica si se hace intentando que los otros personajes de la sala no          - sigilo indica si se hace intentando que los otros personajes de la sala no
1373            se den cuenta            se den cuenta
1374    
1375          Devuelve el nombre completo del objeto cogido.          Devuelve el nombre completo del objeto cogido.
1376    
1377          Lanza ExcepcionDeJuego si no se puede coger (el id no existe, se piden mas          Lanza ExcepcionDeJuego si no se puede coger (el id no existe, se piden mas
1378          instancias de las que hay, algún requisito lo impide, etc.)          instancias de las que hay, algún requisito lo impide, etc.)
1379    
1380          Requiere:          Requiere:
1381              id_objeto != None              id_objeto != None
1382              n_orden >= 1              n_orden >= 1
1383              n_instancia >= 1              n_instancia >= 1
1384    
1385          Asegura:          Asegura:
1386              return != None              return != None
1387          """          """
1388          n_objeto = self.buscar_en_mochila(id_objeto, n_orden)          n_objeto = self.buscar_en_mochila(id_objeto, n_orden)
1389          objeto = self.acceder_a_mochila(n_objeto, n_instancia)          objeto = self.acceder_a_mochila(n_objeto, n_instancia)
1390    
1391          result = objeto.personaje_come(self)          result = objeto.personaje_come(self)
1392          if result == 0:          if result == 0:
1393              raise ExcepcionDeJuego("No puedes comer este objeto.")              raise ExcepcionDeJuego("No puedes comer este objeto.")
1394          else:          else:
1395              if not sigilo:              if not sigilo:
1396                  #%% aquí habría que hacer una tirada en algún sitio...                  #%% aquí habría que hacer una tirada en algún sitio...
1397                  self.actuar("se come " + objeto.nombre)                  self.actuar("se come " + objeto.nombre)
1398    
1399          return objeto.nombre          return objeto.nombre
1400    
1401    
1402      def beber(self, id_objeto, n_orden=1, n_instancia=1, sigilo=0):      def beber(self, id_objeto, n_orden=1, n_instancia=1, sigilo=0):
1403          """Bebe una instancia de un objeto de la mochila.          """Bebe una instancia de un objeto de la mochila.
1404    
1405          Resto de información del método igual que comer().          Resto de información del método igual que comer().
1406          """          """
1407          n_objeto = self.buscar_en_mochila(id_objeto, n_orden)          n_objeto = self.buscar_en_mochila(id_objeto, n_orden)
1408          objeto = self.acceder_a_mochila(n_objeto, n_instancia)          objeto = self.acceder_a_mochila(n_objeto, n_instancia)
1409    
1410          result = objeto.personaje_bebe(self)          result = objeto.personaje_bebe(self)
1411          if result == 0:          if result == 0:
1412              raise ExcepcionDeJuego("No puedes beber este objeto.")              raise ExcepcionDeJuego("No puedes beber este objeto.")
1413          else:          else:
1414              if not sigilo:              if not sigilo:
1415                  #%% aquí habría que hacer una tirada en algún sitio...                  #%% aquí habría que hacer una tirada en algún sitio...
1416                  self.actuar("se bebe " + objeto.nombre)                  self.actuar("se bebe " + objeto.nombre)
1417    
1418          return objeto.nombre          return objeto.nombre
1419    
1420    
1421      def usar(self, id_objeto, n_orden=1, n_instancia=1, sigilo=0):      def usar(self, id_objeto, n_orden=1, n_instancia=1, sigilo=0):
1422          """Usa una instancia de un objeto de la mochila.          """Usa una instancia de un objeto de la mochila.
1423    
1424          Resto de información del método igual que comer().          Resto de información del método igual que comer().
1425          """          """
1426          n_objeto = self.buscar_en_mochila(id_objeto, n_orden)          n_objeto = self.buscar_en_mochila(id_objeto, n_orden)
1427          objeto = self.acceder_a_mochila(n_objeto, n_instancia)          objeto = self.acceder_a_mochila(n_objeto, n_instancia)
1428    
1429          result = objeto.personaje_usa(self)          result = objeto.personaje_usa(self)
1430          if result == 0:          if result == 0:
1431              raise ExcepcionDeJuego("No puedes usar este objeto.")              raise ExcepcionDeJuego("No puedes usar este objeto.")
1432          else:          else:
1433              if not sigilo:              if not sigilo:
1434                  #%% aquí habría que hacer una tirada en algún sitio...                  #%% aquí habría que hacer una tirada en algún sitio...
1435                  self.actuar("usa " + objeto.nombre)                  self.actuar("usa " + objeto.nombre)
1436    
1437          return objeto.nombre          return objeto.nombre
1438    
1439    
1440      def usar_con(self, id_objeto, n_orden=1, n_instancia=1,      def usar_con(self, id_objeto, n_orden=1, n_instancia=1,
1441                   id_objeto2=None, n_orden2=1, n_instancia2=1,                   id_objeto2=None, n_orden2=1, n_instancia2=1,
1442                   sigilo=0):                   sigilo=0):
1443          """Usa una instancia de un objeto de la mochila, con otra instancia de objeto,          """Usa una instancia de un objeto de la mochila, con otra instancia de objeto,
1444          que puede estar en la mochila o en la sala.          que puede estar en la mochila o en la sala.
1445    
1446          Resto de información del método igual que comer().          Resto de información del método igual que comer().
1447          """          """
1448          n_objeto = self.buscar_en_mochila(id_objeto, n_orden)          n_objeto = self.buscar_en_mochila(id_objeto, n_orden)
1449          objeto = self.acceder_a_mochila(n_objeto, n_instancia)          objeto = self.acceder_a_mochila(n_objeto, n_instancia)
1450    
1451          try:          try:
1452              n_objeto2 = self.buscar_en_mochila(id_objeto2, n_orden2)              n_objeto2 = self.buscar_en_mochila(id_objeto2, n_orden2)
1453              objeto2 = self.acceder_a_mochila(n_objeto2, n_instancia2)              objeto2 = self.acceder_a_mochila(n_objeto2, n_instancia2)
1454          except ExcepcionDeJuego:          except ExcepcionDeJuego:
1455              n_objeto2 = self.__sala.buscar_objeto(id_objeto2, n_orden2)              n_objeto2 = self.__sala.buscar_objeto(id_objeto2, n_orden2)
1456              objeto2 = self.__sala.acceder_a_objeto(n_objeto2, n_instancia2)              objeto2 = self.__sala.acceder_a_objeto(n_objeto2, n_instancia2)
1457    
1458          result = objeto.personaje_usa_con(self, objeto2)          result = objeto.personaje_usa_con(self, objeto2)
1459          if result == 0:          if result == 0:
1460              raise ExcepcionDeJuego("No puedes usar este objeto.")              raise ExcepcionDeJuego("No puedes usar este objeto.")
1461          else:          else:
1462              if not sigilo:              if not sigilo:
1463                  #%% aquí habría que hacer una tirada en algún sitio...                  #%% aquí habría que hacer una tirada en algún sitio...
1464                  self.actuar("usa " + objeto.nombre + " con " + objeto2.nombre)                  self.actuar("usa " + objeto.nombre + " con " + objeto2.nombre)
1465    
1466          return objeto.nombre          return objeto.nombre
1467    
1468    
1469      def meter_en_mochila(self, objetos):      def meter_en_mochila(self, objetos):
1470          """Introducir una o varias instancias de un objeto en la mochila del personaje.          """Introducir una o varias instancias de un objeto en la mochila del personaje.
1471    
1472          Requiere:          Requiere:
1473              objetos != None              objetos != None
1474              len(objetos) >= 1              len(objetos) >= 1
1475          """          """
1476          for objeto in objetos:          for objeto in objetos:
1477              objeto.contener(self)              objeto.contener(self)
1478    
1479          for instancias in self.__mochila:          for instancias in self.__mochila:
1480              if instancias[0].id == objetos[0].id:              if instancias[0].id == objetos[0].id:
1481                  instancias.extend(objetos)                  instancias.extend(objetos)
1482                  break                  break
1483          else:          else:
1484              self.__mochila.append(objetos)              self.__mochila.append(objetos)
1485    
1486    
1487      def buscar_en_mochila(self, id_objeto, n_orden=1):      def buscar_en_mochila(self, id_objeto, n_orden=1):
1488          """Localiza un objeto dentro de la mochila del personaje.          """Localiza un objeto dentro de la mochila del personaje.
1489    
1490          - id_objeto es el identificador del objeto. Puede haber varios objetos distintos          - id_objeto es el identificador del objeto. Puede haber varios objetos distintos
1491            con el mismo id            con el mismo id
1492          - n_orden sirve para distinguir el objeto si hay mas de uno con el mismo id          - n_orden sirve para distinguir el objeto si hay mas de uno con el mismo id
1493    
1494          Devuelve el indice dentro de la mochila que apunta al objeto buscado.          Devuelve el indice dentro de la mochila que apunta al objeto buscado.
1495    
1496          Lanza ExcepcionDeJuego si no se encuentra.          Lanza ExcepcionDeJuego si no se encuentra.
1497    
1498          Requiere:          Requiere:
1499              id_objeto != None              id_objeto != None
1500              n_orden >= 1              n_orden >= 1
1501    
1502          Asegura:          Asegura:
1503              return in range(0, len(self.__mochila))              return in range(0, len(self.__mochila))
1504          """          """
1505          encontrados = 0          encontrados = 0
1506          n_objeto = -1          n_objeto = -1
1507    
1508          for instancias in self.__mochila:          for instancias in self.__mochila:
1509              n_objeto = n_objeto + 1              n_objeto = n_objeto + 1
1510              if normalizar_id(id_objeto) == extraer_id(instancias[0].nombre):              if normalizar_id(id_objeto) == extraer_id(instancias[0].nombre):
1511                  encontrados = encontrados + 1                  encontrados = encontrados + 1
1512                  if encontrados == n_orden:                  if encontrados == n_orden:
1513                      break                      break
1514                                            
1515          if encontrados == 0:          if encontrados == 0:
1516              raise ExcepcionDeJuego("No tienes en la mochila ningún objeto con identificativo " +              raise ExcepcionDeJuego("No tienes en la mochila ningún objeto con identificativo " +
1517                                     id_objeto)                                     id_objeto)
1518          elif encontrados < n_orden:          elif encontrados < n_orden:
1519              raise ExcepcionDeJuego("No tienes en la mochila suficientes objetos con identificativo " +              raise ExcepcionDeJuego("No tienes en la mochila suficientes objetos con identificativo " +
1520                                     id_objeto + ", solo tienes " + str(encontrados))                                     id_objeto + ", solo tienes " + str(encontrados))
1521          else:          else:
1522              return n_objeto              return n_objeto
1523    
1524    
1525      def acceder_a_mochila(self, n_objeto, n_instancia=1):      def acceder_a_mochila(self, n_objeto, n_instancia=1):
1526          """Accede a una instancia de un objeto para trabajar con ella, pero sin sacarla de la mochila.          """Accede a una instancia de un objeto para trabajar con ella, pero sin sacarla de la mochila.
1527                    
1528          - n_objeto es el número de orden del objeto dentro de la mochila          - n_objeto es el número de orden del objeto dentro de la mochila
1529          - n_instancia es el número de orden de la instancia a extraer          - n_instancia es el número de orden de la instancia a extraer
1530    
1531          Devuelve la instancia extraida.          Devuelve la instancia extraida.
1532    
1533          Lanza ExcepcionDeJuego si no puede acceder (por ejemplo, se ha pedido un número de instancia          Lanza ExcepcionDeJuego si no puede acceder (por ejemplo, se ha pedido un número de instancia
1534          mayor que las que hay).          mayor que las que hay).
1535    
1536          Requiere:          Requiere:
1537              n_objeto in range(0, len(self.mochila))              n_objeto in range(0, len(self.mochila))
1538              n_instancia >= 1              n_instancia >= 1
1539    
1540          Asegura:          Asegura:
1541              return != None              return != None
1542          """          """
1543          instancias = self.__mochila[n_objeto]          instancias = self.__mochila[n_objeto]
1544          if (n_instancia) > len(instancias):          if (n_instancia) > len(instancias):
1545              raise ExcepcionDeJuego("No tienes " + str(n_instancia) +              raise ExcepcionDeJuego("No tienes " + str(n_instancia) +
1546                                     " unidades de ese objeto en la mochila, solo tienes " +                                     " unidades de ese objeto en la mochila, solo tienes " +
1547                                     str(len(instancias)))                                     str(len(instancias)))
1548    
1549          objeto = instancias[n_instancia-1]          objeto = instancias[n_instancia-1]
1550    
1551          return objeto          return objeto
1552    
1553    
1554      def sacar_de_mochila(self, n_objeto, n_instancia=1, cantidad=1):      def sacar_de_mochila(self, n_objeto, n_instancia=1, cantidad=1):
1555          """Sacar una o varias instancias de un objeto de la mochila del personaje.          """Sacar una o varias instancias de un objeto de la mochila del personaje.
1556                    
1557          - n_objeto es el número de orden del objeto dentro de la mochila          - n_objeto es el número de orden del objeto dentro de la mochila
1558          - n_instancia es el número de orden de la primera instancia a extraer          - n_instancia es el número de orden de la primera instancia a extraer
1559          - cantidad es el número de instancias a extraer          - cantidad es el número de instancias a extraer
1560    
1561          Devuelve una lista con las instancias extraidas.          Devuelve una lista con las instancias extraidas.
1562    
1563          Lanza ExcepcionDeJuego si no puede sacarlas (por ejemplo, se han pedido          Lanza ExcepcionDeJuego si no puede sacarlas (por ejemplo, se han pedido
1564          más instancias de las que hay).          más instancias de las que hay).
1565    
1566          Requiere:          Requiere:
1567              n_objeto in range(0, len(self.mochila))              n_objeto in range(0, len(self.mochila))
1568              n_instancia >= 1              n_instancia >= 1
1569              cantidad >= 1              cantidad >= 1
1570    
1571          Asegura:          Asegura:
1572              return != None              return != None
1573              len(return) == cantidad              len(return) == cantidad
1574          """          """
1575          instancias = self.__mochila[n_objeto]          instancias = self.__mochila[n_objeto]
1576    
1577          if (n_instancia + cantidad - 1) > len(instancias):          if (n_instancia + cantidad - 1) > len(instancias):
1578              raise ExcepcionDeJuego("No tienes " + str(n_instancia + cantidad - 1) +              raise ExcepcionDeJuego("No tienes " + str(n_instancia + cantidad - 1) +
1579                                     " unidades de ese objeto en la mochila, solo tienes " +                                     " unidades de ese objeto en la mochila, solo tienes " +
1580                                     str(len(instancias)))                                     str(len(instancias)))
1581    
1582          objetos_sacados = []          objetos_sacados = []
1583    
1584          for i in range(0, cantidad):          for i in range(0, cantidad):
1585              objetos_sacados.append(instancias[n_instancia-1])              objetos_sacados.append(instancias[n_instancia-1])
1586              instancias[n_instancia-1].activar()              instancias[n_instancia-1].activar()
1587              instancias[n_instancia-1].liberar()              instancias[n_instancia-1].liberar()
1588              del instancias[n_instancia-1]              del instancias[n_instancia-1]
1589    
1590          if len(instancias) == 0:          if len(instancias) == 0:
1591              del self.__mochila[n_objeto]              del self.__mochila[n_objeto]
1592    
1593          return objetos_sacados          return objetos_sacados
1594    
1595    
1596  #%%    def sacar_de_mochila(self, n_objeto, n_instancia):  #%%    def sacar_de_mochila(self, n_objeto, n_instancia):
1597  #%%     """Sacar un objeto de la mochila del personaje.  #%%     """Sacar un objeto de la mochila del personaje.
1598  #%%  #%%
1599  #%%     n_objeto es el numero de orden dentro de la mochila, y n_instancia es el  #%%     n_objeto es el numero de orden dentro de la mochila, y n_instancia es el
1600  #%%     numero de la instancia, ambos empezando por cero.  #%%     numero de la instancia, ambos empezando por cero.
1601  #%%  #%%
1602  #%%     Requiere:  #%%     Requiere:
1603  #%%         n_objeto in range(0, len(self.mochila)-1)  #%%         n_objeto in range(0, len(self.mochila)-1)
1604  #%%         n_instancia in range(0, len(self.mochila[n_objeto])-1)  #%%         n_instancia in range(0, len(self.mochila[n_objeto])-1)
1605  #%%  #%%
1606  #%%     Asegura:  #%%     Asegura:
1607  #%%         return != None  #%%         return != None
1608  #%%     """  #%%     """
1609  #%%     objeto = self.__mochila[n_objeto][n_instancia]  #%%     objeto = self.__mochila[n_objeto][n_instancia]
1610  #%%  #%%
1611  #%%     del self.__mochila[n_objeto][n_instancia]  #%%     del self.__mochila[n_objeto][n_instancia]
1612  #%%     if len(self.__mochila[n_objeto]) == 0:  #%%     if len(self.__mochila[n_objeto]) == 0:
1613  #%%         del self.__mochila[n_objeto]  #%%         del self.__mochila[n_objeto]
1614  #%%  #%%
1615  #%%     return objeto  #%%     return objeto
1616    
1617    
1618      def reservar_posicion(self, posicion):      def reservar_posicion(self, posicion):
1619          """Quitar todos los objetos necesarios para poder ponerse uno nuevo en          """Quitar todos los objetos necesarios para poder ponerse uno nuevo en
1620          la posicion indicada.          la posicion indicada.
1621    
1622          Normalmente solo habra que quitar el objeto que ya este en esa posicion,          Normalmente solo habra que quitar el objeto que ya este en esa posicion,
1623          si hay alguno. Pero con las posiciones "mano-izq", "mano-der" y "dos-manos"          si hay alguno. Pero con las posiciones "mano-izq", "mano-der" y "dos-manos"
1624          puede haber que quitar mas de uno.          puede haber que quitar mas de uno.
1625    
1626          Devuelve una lista con todos los objetos que se haya tenido que quitar.          Devuelve una lista con todos los objetos que se haya tenido que quitar.
1627    
1628          Requiere:          Requiere:
1629              posicion in Personaje.POSICIONES              posicion in Personaje.POSICIONES
1630    
1631          Asegura:          Asegura:
1632              return != None              return != None
1633          """          """
1634          objetos_quitados = []          objetos_quitados = []
1635    
1636          if self.__cuerpo[posicion] != None:          if self.__cuerpo[posicion] != None:
1637              objetos_quitados.append(self.__cuerpo[posicion])              objetos_quitados.append(self.__cuerpo[posicion])
1638              self.quitarse(posicion)              self.quitarse(posicion)
1639    
1640          if posicion == "dos-manos":          if posicion == "dos-manos":
1641              if self.__cuerpo["mano-izq"] != None:              if self.__cuerpo["mano-izq"] != None:
1642                  objetos_quitados.append(self.__cuerpo["mano-izq"])                  objetos_quitados.append(self.__cuerpo["mano-izq"])
1643                  self.quitarse("mano-izq")                  self.quitarse("mano-izq")
1644              if self.__cuerpo["mano-der"] != None:              if self.__cuerpo["mano-der"] != None:
1645                  objetos_quitados.append(self.__cuerpo["mano-der"])                  objetos_quitados.append(self.__cuerpo["mano-der"])
1646                  self.quitarse("mano-der")                  self.quitarse("mano-der")
1647    
1648          if posicion == "mano-izq" or posicion == "mano-der":          if posicion == "mano-izq" or posicion == "mano-der":
1649              if self.__cuerpo["dos-manos"] != None:              if self.__cuerpo["dos-manos"] != None:
1650                  objetos_quitados.append(self.__cuerpo["dos-manos"])                  objetos_quitados.append(self.__cuerpo["dos-manos"])
1651                  self.quitarse("dos-manos")                  self.quitarse("dos-manos")
1652    
1653          return objetos_quitados          return objetos_quitados
1654    
1655    
1656      def ponerse(self, posicion, id_objeto, n_orden=1, n_instancia=1, sigilo=0):      def ponerse(self, posicion, id_objeto, n_orden=1, n_instancia=1, sigilo=0):
1657          """Ponerse un objeto en una posicion del cuerpo.          """Ponerse un objeto en una posicion del cuerpo.
1658    
1659          Si ya hay algún objeto en esa posición, se lo quita y lo guarda en la mochila.          Si ya hay algún objeto en esa posición, se lo quita y lo guarda en la mochila.
1660    
1661          Genera un suceso de actuar_uno_mismo, uno de actuar (salvo si se indica sigilo)          Genera un suceso de actuar_uno_mismo, uno de actuar (salvo si se indica sigilo)
1662          y uno de personaje_pone_XXXX en el objeto puesto.          y uno de personaje_pone_XXXX en el objeto puesto.
1663    
1664          - posicion es la parte del cuerpo donde se pone          - posicion es la parte del cuerpo donde se pone
1665          - id_objeto es el identificador del objeto. Puede haber varios objetos distintos          - id_objeto es el identificador del objeto. Puede haber varios objetos distintos
1666            con el mismo id            con el mismo id
1667          - n_orden sirve para distinguir el objeto si hay mas de uno con el mismo id          - n_orden sirve para distinguir el objeto si hay mas de uno con el mismo id
1668          - n_instancia es para elegir una instancia concreta, si hay mas de una          - n_instancia es para elegir una instancia concreta, si hay mas de una
1669          - sigilo indica si se hace intentando que los otros personajes de la sala no          - sigilo indica si se hace intentando que los otros personajes de la sala no
1670            se den cuenta            se den cuenta
1671    
1672          Devuelve el nombre completo del objeto puesto.          Devuelve el nombre completo del objeto puesto.
1673    
1674          Lanza ExcepcionDeJuego si no se puede coger (el id no existe, se piden mas          Lanza ExcepcionDeJuego si no se puede coger (el id no existe, se piden mas
1675          instancias de las que hay, algún requisito lo impide, etc.)          instancias de las que hay, algún requisito lo impide, etc.)
1676    
1677          Requiere:          Requiere:
1678              posicion in Personaje.POSICIONES              posicion in Personaje.POSICIONES
1679              id_objeto != None              id_objeto != None
1680              n_orden >= 1              n_orden >= 1
1681              n_instancia >= 1              n_instancia >= 1
   
         Asegura:  
             self.cuerpo[posicion] == objeto  
             return != None  
         """  
         objetos_quitados = self.reservar_posicion(posicion)  
         if len(objetos_quitados) > 0:  
             self.meter_en_mochila(objetos_quitados)  
1682    
1683          n_objeto = self.buscar_en_mochila(id_objeto, n_orden)          Asegura:
1684          objeto = self.acceder_a_mochila(n_objeto, n_instancia)              self.cuerpo[posicion] == objeto
1685                return != None
1686            """
1687            objetos_quitados = self.reservar_posicion(posicion)
1688            if len(objetos_quitados) > 0:
1689                self.meter_en_mochila(objetos_quitados)
1690    
1691            n_objeto = self.buscar_en_mochila(id_objeto, n_orden)
1692            objeto = self.acceder_a_mochila(n_objeto, n_instancia)
1693    
1694          suceso = getattr(objeto, "personaje_pone_" + posicion)          suceso = getattr(objeto, "personaje_pone_" + posicion)
1695          result = suceso(self)          result = suceso(self)
1696          if result == 0:          if result == 0:
1697              raise ExcepcionDeJuego("No te puedes poner este objeto en esa posicion.")              raise ExcepcionDeJuego("No te puedes poner este objeto en esa posicion.")
1698          else:          else:
1699              objeto = self.sacar_de_mochila(n_objeto, n_instancia, 1)[0]              objeto = self.sacar_de_mochila(n_objeto, n_instancia, 1)[0]
1700              objeto.contener(self)              objeto.contener(self)
1701              self.__cuerpo[posicion] = objeto              self.__cuerpo[posicion] = objeto
1702              self.actuar_uno_mismo("Te pones " + objeto.nombre + " en " + posicion)              self.actuar_uno_mismo("Te pones " + objeto.nombre + " en " + posicion)
1703              if not sigilo:              if not sigilo:
1704                  #%% aquí habría que hacer una tirada en algún sitio...                  #%% aquí habría que hacer una tirada en algún sitio...
1705                  self.actuar("se pone " + objeto.nombre + " en " + posicion)                  self.actuar("se pone " + objeto.nombre + " en " + posicion)
1706    
1707          return objeto.nombre          return objeto.nombre
1708    
1709    
1710      def quitarse(self, posicion, sigilo=0):      def quitarse(self, posicion, sigilo=0):
1711          """Quitarse el objeto que esté en una posición del cuerpo y meterlo en la mochila.          """Quitarse el objeto que esté en una posición del cuerpo y meterlo en la mochila.
1712    
1713          Genera un suceso de actuar_uno_mismo, uno de actuar (salvo si se indica sigilo)          Genera un suceso de actuar_uno_mismo, uno de actuar (salvo si se indica sigilo)
1714          y uno de personaje_quita_XXXX en el objeto quitado.          y uno de personaje_quita_XXXX en el objeto quitado.
1715    
1716          Devuelve el nombre completo del objeto quitado.          Devuelve el nombre completo del objeto quitado.
1717    
1718          Lanza ExcepcionDeJuego si no hay ningún objeto en la posición indicada o algún          Lanza ExcepcionDeJuego si no hay ningún objeto en la posición indicada o algún
1719          requisito lo impide.          requisito lo impide.
1720    
1721          Requiere:          Requiere:
1722              posicion in Personaje.POSICIONES              posicion in Personaje.POSICIONES
1723    
1724          Asegura:          Asegura:
1725              self.cuerpo[posicion] == None              self.cuerpo[posicion] == None
1726              return != None              return != None
1727          """          """
1728          if self.__cuerpo[posicion] == None:          if self.__cuerpo[posicion] == None:
1729              raise ExcepcionDeJuego("No llevas nada puesto en " + posicion)              raise ExcepcionDeJuego("No llevas nada puesto en " + posicion)
1730    
1731          objeto = self.__cuerpo[posicion]          objeto = self.__cuerpo[posicion]
1732    
1733          suceso = getattr(objeto, "personaje_quita_" + posicion)          suceso = getattr(objeto, "personaje_quita_" + posicion)
1734          result = suceso(self)          result = suceso(self)
1735          if result == 0:          if result == 0:
1736              raise ExcepcionDeJuego("No te puedes quitar este objeto de esa posicion.")              raise ExcepcionDeJuego("No te puedes quitar este objeto de esa posicion.")
1737          else:          else:
1738              del self.__cuerpo[posicion]              del self.__cuerpo[posicion]
1739              objeto.liberar()              objeto.liberar()
1740              self.meter_en_mochila([objeto])              self.meter_en_mochila([objeto])
1741              self.actuar_uno_mismo("Te quitas " + objeto.nombre + " de " + posicion)              self.actuar_uno_mismo("Te quitas " + objeto.nombre + " de " + posicion)
1742              if not sigilo:              if not sigilo:
1743                  #%% aquí habría que hacer una tirada en algún sitio...                  #%% aquí habría que hacer una tirada en algún sitio...
1744                  self.actuar("se quita " + objeto.nombre + " de " + posicion)                  self.actuar("se quita " + objeto.nombre + " de " + posicion)
1745    
1746          return objeto.nombre          return objeto.nombre
1747    
1748    
1749      def objeto_desaparece(self, objeto):      def objeto_desaparece(self, objeto):
# Line 1790  class Personaje(object): Line 1790  class Personaje(object):
1790    
1791    
1792      def objeto_reemplazado(self, objeto_antiguo, objeto_nuevo):      def objeto_reemplazado(self, objeto_antiguo, objeto_nuevo):
1793          """Un objeto contenido en este personaje ha sido destruido, y reemplazado por otro.          """Un objeto contenido en este personaje ha sido destruido, y reemplazado por otro.
1794    
1795          Hay que eliminar el antiguo de la mochila o del cuerpo, donde esté, y añadir el nuevo          Hay que eliminar el antiguo de la mochila o del cuerpo, donde esté, y añadir el nuevo
1796          en el mismo lugar donde estaba el antiguo. No ocurre ningún suceso en particular. Este          en el mismo lugar donde estaba el antiguo. No ocurre ningún suceso en particular. Este
# Line 1816  class Personaje(object): Line 1816  class Personaje(object):
1816          else:          else:
1817              parte = None              parte = None
1818    
1819          objeto_nuevo.contener(self)          objeto_nuevo.contener(self)
1820                    
1821          if parte == None:          if parte == None:
1822              for instancias in self.__mochila:              for instancias in self.__mochila:
1823                  if instancias[0].id == objeto_nuevo.id:                  if instancias[0].id == objeto_nuevo.id:
1824                      instancias.append(objeto_nuevo)                      instancias.append(objeto_nuevo)
1825                      break                      break
1826              else:              else:
1827                  self.__mochila.append([objeto_nuevo])                  self.__mochila.append([objeto_nuevo])
1828          else:          else:
1829              self.__cuerpo[parte] = objeto_nuevo              self.__cuerpo[parte] = objeto_nuevo
1830    
1831    
1832      def personaje_mira(self, observador, sala):      def personaje_mira(self, observador, sala):

Legend:
Removed from v.2.19  
changed lines
  Added in v.2.20

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