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

Diff of /ambar/pnj.py

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

revision 2.0 by pabloruiz, Sat Aug 17 21:11:09 2002 UTC revision 2.1 by pabloruiz, Tue Nov 5 22:58:22 2002 UTC
# Line 1  Line 1 
1  #!/usr/bin/env python  #!/usr/bin/env python
2  #  #
3  #Minë. Mundo Interactivo-Narrativo en Español [Tierra-Media]  #Minë. Mundo Interactivo-Narrativo en Español [Tierra-Media]
4  #Copyright (C) 2002  Pablo Ruiz Múzquiz  #Copyright (C) 2002  Pablo Ruiz Múzquiz
5  #  #
6  #  #
7  #This program is free software; you can redistribute it and/or modify  #This program is free software; you can redistribute it and/or modify
8  #it under the terms of the GNU General Public License as published by  #it under the terms of the GNU General Public License as published by
9  #the Free Software Foundation; either version 2 of the License, or  #the Free Software Foundation; either version 2 of the License, or
10  #(at your option) any later version.  #(at your option) any later version.
11  #  #
12  #This program is distributed in the hope that it will be useful,  #This program is distributed in the hope that it will be useful,
13  #but WITHOUT ANY WARRANTY; without even the implied warranty of  #but WITHOUT ANY WARRANTY; without even the implied warranty of
14  #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  #GNU General Public License for more details.  #GNU General Public License for more details.
16  #  #
17  #You should have received a copy of the GNU General Public License  #You should have received a copy of the GNU General Public License
18  #along with this program; if not, write to the Free Software  #along with this program; if not, write to the Free Software
19  #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA  #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20  #  #
21  #  #
22  #Fichero: pnj.py  #Fichero: pnj.py
23    
24  """Clase pnj."""  """Clase pnj."""
25    
26    
27  from xml.dom import minidom  from xml.dom import minidom
28  import random  import random
29  import sys  import sys
30  import string  import string
31  import os  import os
32  import cPickle  import cPickle
33    
34  from personaje import *  from personaje import *
35  from personajejugador import *  from personajejugador import *
36  from personajenojugador import *  from personajenojugador import *
37  from interfazpnj import *  from interfazpnj import *
38    
39    
40    
41  class Pnj:  class Pnj:
42      """Un personaje no jugador.      """Un personaje no jugador.
43      FIXME!      FIXME!
44      Contiene los siguientes atributos:      Contiene los siguientes atributos:
45       - nombre (string): identifica univocamente al pnj       - nombre (string): identifica univocamente al pnj
46       - descripcion (string): texto largo que explica todo lo que cualquier jugador ve al entrar       - descripcion (string): texto largo que explica todo lo que cualquier jugador ve al entrar
47       - descripcion_especial (string): texto describiendo mas cosas que solo se ven superando       - descripcion_especial (string): texto describiendo mas cosas que solo se ven superando
48                                        una tirada de percepcion                                        una tirada de percepcion
49       - direcciones (string[]): lista con los nombres de las salas accesibles desde esta       - direcciones (string[]): lista con los nombres de las salas accesibles desde esta
50       - encuentro (PersonajeNoJugador): el PersonajeNoJugador que hay en la sala o None si no hay ninguno       - encuentro (PersonajeNoJugador): el PersonajeNoJugador que hay en la sala o None si no hay ninguno
51       - tesoro (string): nombre del objeto que hay en la sala, o "" si no hay ninguno       - tesoro (string): nombre del objeto que hay en la sala, o "" si no hay ninguno
52       - personajes (Personaje{}): diccionario con los personajes que se encuentran en la sala,       - personajes (Personaje{}): diccionario con los personajes que se encuentran en la sala,
53                                indexado por nombre. NO MODIFICAR DIRECTAMENTE, SINO CON                                indexado por nombre. NO MODIFICAR DIRECTAMENTE, SINO CON
54                                entrar_personaje() Y salir_personaje()                                entrar_personaje() Y salir_personaje()
55       - n_jugadores (int): numero de personajes de tipo PersonajeJugador dentro de la sala       - n_jugadores (int): numero de personajes de tipo PersonajeJugador dentro de la sala
56            
57      Al instanciar una sala, se crea nueva y se lee desde el fichero de descripcion de sala,      Al instanciar una sala, se crea nueva y se lee desde el fichero de descripcion de sala,
58      poniendola en su estado inicial (se lee el tesoro y se crea un PersonajeNoJugador partiendo      poniendola en su estado inicial (se lee el tesoro y se crea un PersonajeNoJugador partiendo
59      del valor del atributo "encuentro"). Mas tarde, se puede salvar en un fichero de sala,      del valor del atributo "encuentro"). Mas tarde, se puede salvar en un fichero de sala,
60      borrarla y cargarla despues, manteniendo su estado (situacion del tesoro y de los personajes      borrarla y cargarla despues, manteniendo su estado (situacion del tesoro y de los personajes
61      contenidos).      contenidos).
62            
63      Importante: al salvar una sala se salvan también todos los objetos y todos los personajes      Importante: al salvar una sala se salvan también todos los objetos y todos los personajes
64      contenidas en ella. El módulo "Pickle" se encarga de todo, incluyendo la resolución del bucle      contenidas en ella. El módulo "Pickle" se encarga de todo, incluyendo la resolución del bucle
65      formado por el atributo "sala" de la clase Personaje.      formado por el atributo "sala" de la clase Personaje.
66      """      """
67    
68      DIR_DESC_PNJS = 'desc_pnjs'      DIR_DESC_PNJS = 'desc_pnjs'
69      DIR_PNJS = 'pnjs'      DIR_PNJS = 'pnjs'
70    
71    
72    
73      def __init__(self, archivo):      def __init__(self, archivo):
74    
75          """Método inicial para leer los datos de un fichero de pnj"""          """Método inicial para leer los datos de un fichero de pnj"""
76    
77          self.id = archivo                self.id = archivo      
78          self.archivo=archivo+".xml"          self.archivo=archivo+".xml"
79          self.archivo=os.path.join(Pnj.DIR_DESC_PNJS, self.archivo)          self.archivo=os.path.join(Pnj.DIR_DESC_PNJS, self.archivo)
80          print self.archivo          print self.archivo
81          fuente = openAnything(self.archivo)          fuente = openAnything(self.archivo)
82          self.source = minidom.parse(fuente).documentElement          self.source = minidom.parse(fuente).documentElement
83          fuente.close()          fuente.close()
84                    
85          self.iniciar_parseador(self.source)          self.iniciar_parseador(self.source)
86    
87          self.parsear_pnj(self.source)          self.parsear_pnj(self.source)
88          self.parsear_id(self.source)              self.parsear_id(self.source)    
89          self.parsear_nombre(self.source)                  self.parsear_nombre(self.source)        
90          self.parsear_descripcion(self.source)          self.parsear_descripcion(self.source)
91          self.parsear_propiedades(self.source)          self.parsear_propiedades(self.source)
92          self.parsear_atributos(self.source)          self.parsear_atributos(self.source)
93          self.parsear_idiomas(self.source)          self.parsear_idiomas(self.source)
94          self.parsear_controlador(self.source)          self.parsear_controlador(self.source)
95          self.parsear_objetos(self.source)          self.parsear_objetos(self.source)
96    
97          del self.source          del self.source
98          del self.descripcion          del self.descripcion
99    
100                    
101                    
102            
103      def iniciar_parseador(self, fuente):      def iniciar_parseador(self, fuente):
104          """Esta función borra todos los nodos de tipo Text de un          """Esta función borra todos los nodos de tipo Text de un
105          elemento DOM"""          elemento DOM"""
106                    
107          for node in fuente.childNodes[:]:          for node in fuente.childNodes[:]:
108              if  not 'Element:' in str(node).split(): fuente.childNodes.remove(node)              if  not 'Element:' in str(node).split(): fuente.childNodes.remove(node)
109                    
110      def parsear_pnj(self, fuente):      def parsear_pnj(self, fuente):
111          """Extrae la información del elemento pnj:          """Extrae la información del elemento pnj:
112              autor: el autor de la sala              autor: el autor de la sala
113              version: la versión del tipo de sala"""              version: la versión del tipo de sala"""
114    
115          self.autor = fuente.attributes["autor"].value          self.autor = fuente.attributes["autor"].value
116          self.version = fuente.attributes["version"].value          self.version = fuente.attributes["version"].value
117          try:          try:
118              self.area = fuente.attributes["area"].value              self.area = fuente.attributes["area"].value
119          except: self.area = 'sin area'          except: self.area = 'sin area'
120                            
121                            
122      def parsear_id(self, fuente):      def parsear_id(self, fuente):
123          """Extrae el id del pnj"""          """Extrae el id del pnj"""
124                    
125          self.id=fuente.childNodes[0].childNodes[0].data.encode('ISO-8859-1')          self.id=fuente.childNodes[0].childNodes[0].data.encode('ISO-8859-1')
126                    
127      def parsear_nombre(self, fuente):      def parsear_nombre(self, fuente):
128          """Extrae el nombre del pnj"""          """Extrae el nombre del pnj"""
129                    
130          self.nombre=fuente.childNodes[1].childNodes[0].data.encode('ISO-8859-1')          self.nombre=fuente.childNodes[1].childNodes[0].data.encode('ISO-8859-1')
131    
132                    
133      def parsear_descripcion(self, fuente):      def parsear_descripcion(self, fuente):
134          """Extrae el texto y la dificultad asociada de los items          """Extrae el texto y la dificultad asociada de los items
135          de descripcion del pnj"""          de descripcion del pnj"""
136                    
137          for node in fuente.childNodes[2].childNodes[:]:          for node in fuente.childNodes[2].childNodes[:]:
138              if  not 'Element:' in str(node).split(): fuente.childNodes[2].childNodes.remove(node)              if  not 'Element:' in str(node).split(): fuente.childNodes[2].childNodes.remove(node)
139                                            
140                    
141          self.descripcion=fuente.childNodes[2]          self.descripcion=fuente.childNodes[2]
142          self.items={}          self.items={}
143    
144          for item in self.descripcion.childNodes[:]:          for item in self.descripcion.childNodes[:]:
145              texto_item=""              texto_item=""
146              for frase in item.childNodes[:]:              for frase in item.childNodes[:]:
147    
148                  frase.data=frase.data.encode('ISO-8859-1')                  frase.data=frase.data.encode('ISO-8859-1')
149    
150                  texto_item=texto_item+frase.data                  texto_item=texto_item+frase.data
151                            
152              if item._attrs == {}: dif_item = 0              if item._attrs == {}: dif_item = 0
153              else:              else:
154                  dif_item=int(item._attrs.get('dificultad').value)                  dif_item=int(item._attrs.get('dificultad').value)
155                                    
156              self.items.update({dif_item:texto_item})              self.items.update({dif_item:texto_item})
157                            
158      def parsear_propiedades(self, fuente):            def parsear_propiedades(self, fuente):      
159                                    
160          self.aura=int(fuente.childNodes[3].attributes["aura"].value)          self.aura=int(fuente.childNodes[3].attributes["aura"].value)
161          self.volumen=fuente.childNodes[3].attributes["volumen"].value          self.volumen=fuente.childNodes[3].attributes["volumen"].value
162          self.experiencia=int(fuente.childNodes[3].attributes["experiencia"].value)          self.experiencia=int(fuente.childNodes[3].attributes["experiencia"].value)
163          self.nivel=int(fuente.childNodes[3].attributes["nivel"].value)          self.nivel=int(fuente.childNodes[3].attributes["nivel"].value)
164          self.vida=int(fuente.childNodes[3].attributes["vida"].value)          self.vida=int(fuente.childNodes[3].attributes["vida"].value)
165          try:          try:
166              self.intocable=fuente.childNodes[3].attributes["intocable"].value.encode('ISO-8859-1')              self.intocable=fuente.childNodes[3].attributes["intocable"].value.encode('ISO-8859-1')
167          except:          except:
168              self.intocable = 'no'              self.intocable = 'no'
169        
170      def parsear_atributos(self, fuente):              def parsear_atributos(self, fuente):        
171                                    
172          self.fuerza=int(fuente.childNodes[4].attributes["fuerza"].value)          self.fuerza=int(fuente.childNodes[4].attributes["fuerza"].value)
173          self.destreza=fuente.childNodes[4].attributes["destreza"].value          self.destreza=fuente.childNodes[4].attributes["destreza"].value
174          self.constitucion=int(fuente.childNodes[4].attributes["constitucion"].value)          self.constitucion=int(fuente.childNodes[4].attributes["constitucion"].value)
175          self.inteligencia=int(fuente.childNodes[4].attributes["inteligencia"].value)          self.inteligencia=int(fuente.childNodes[4].attributes["inteligencia"].value)
176          self.sabiduria=int(fuente.childNodes[4].attributes["sabiduria"].value)          self.sabiduria=int(fuente.childNodes[4].attributes["sabiduria"].value)
177          self.carisma=int(fuente.childNodes[4].attributes["carisma"].value)          self.carisma=int(fuente.childNodes[4].attributes["carisma"].value)
178    
179      def parsear_idiomas(self, fuente):      def parsear_idiomas(self, fuente):
180                    
181          self.idiomas = {}          self.idiomas = {}
182                    
183          self.oestron = int(fuente.childNodes[5].attributes["oestron"].value)          self.oestron = int(fuente.childNodes[5].attributes["oestron"].value)
184          self.idiomas.update({'oestron':self.oestron})          self.idiomas.update({'oestron':self.oestron})
185          try:          try:
186              self.quenya = fuente.childNodes[5].attributes["quenya"].value              self.quenya = fuente.childNodes[5].attributes["quenya"].value
187          except:          except:
188              self.quenya = 0              self.quenya = 0
189          self.idiomas.update({'quenya':self.quenya})          self.idiomas.update({'quenya':self.quenya})
190          try:          try:
191              self.orco=int(fuente.childNodes[5].attributes["orco"].value)              self.orco=int(fuente.childNodes[5].attributes["orco"].value)
192          except:          except:
193              self.orco = 0              self.orco = 0
194          self.idiomas.update({'orco':self.orco})          self.idiomas.update({'orco':self.orco})
195          try:          try:
196              self.enano=int(fuente.childNodes[5].attributes["enano"].value)              self.enano=int(fuente.childNodes[5].attributes["enano"].value)
197          except:          except:
198              self.enano = 0              self.enano = 0
199          self.idiomas.update({'enano':self.enano})          self.idiomas.update({'enano':self.enano})
200                            
201    
202    
203      def parsear_controlador(self, fuente):      def parsear_controlador(self, fuente):
204                    
205          self.controlador = fuente.childNodes[6].attributes["tipo"].value.encode('ISO-8859-1')          self.controlador = fuente.childNodes[6].attributes["tipo"].value.encode('ISO-8859-1')
206                    
207      def parsear_objetos(self, doc_xml):      def parsear_objetos(self, doc_xml):
208          """Extrae toda la información de los objetos que hay en el pnj inicialmente."""          """Extrae toda la información de los objetos que hay en el pnj inicialmente."""
209                    
210          nodo_objetos = doc_xml.childNodes[7]          nodo_objetos = doc_xml.childNodes[7]
211                    
212          # Limpiamos todos los subnodos de tipo Text, al igual          # Limpiamos todos los subnodos de tipo Text, al igual
213          # que hacíamos en la función iniciar_parseador()          # que hacíamos en la función iniciar_parseador()
214          for nodo in nodo_objetos.childNodes[:]:          for nodo in nodo_objetos.childNodes[:]:
215              if  'Element:' not in str(nodo).split():              if  'Element:' not in str(nodo).split():
216                  nodo_objetos.childNodes.remove(nodo)                  nodo_objetos.childNodes.remove(nodo)
217                                    
218          self.objetos = []          self.objetos = []
219                            
220          for nodo_objeto in nodo_objetos.childNodes[:]:          for nodo_objeto in nodo_objetos.childNodes[:]:
221                                    
222              id_objeto = nodo_objeto._attrs.get('id').value.encode('ISO-8859-1')              id_objeto = nodo_objeto._attrs.get('id').value.encode('ISO-8859-1')
223              try:              try:
224                  cantidad_objeto = int(nodo_objeto._attrs.get('cantidad').value)                  cantidad_objeto = int(nodo_objeto._attrs.get('cantidad').value)
225              except:              except:
226                  cantidad_objeto = 1                  cantidad_objeto = 1
227              try:              try:
228                  prob_objeto = int(nodo_objeto._attrs.get('probabilidad').value)                  prob_objeto = int(nodo_objeto._attrs.get('probabilidad').value)
229              except:              except:
230                  prob_objeto = 0                  prob_objeto = 0
231              desc_objeto = nodo_objeto.childNodes[0].data.encode('ISO-8859-1')              desc_objeto = nodo_objeto.childNodes[0].data.encode('ISO-8859-1')
232                                            
233              self.objetos.append({"id": id_objeto,              self.objetos.append({"id": id_objeto,
234              "cantidad": cantidad_objeto,              "cantidad": cantidad_objeto,
235              "probabilidad": prob_objeto,              "probabilidad": prob_objeto,
236              "descripcion": desc_objeto})              "descripcion": desc_objeto})
237                                            
238                                            
239                                            
240      def salvar(self):      def salvar(self):
241          """Graba en un fichero de DIR_PNJS el pnj con todo su contenido."""          """Graba en un fichero de DIR_PNJS el pnj con todo su contenido."""
242                    
243          fichero = open(os.path.join(Objeto.DIR_PNJS, self.id), 'w')          fichero = open(os.path.join(Objeto.DIR_PNJS, self.id), 'w')
244          cPickle.dump(self, fichero)          cPickle.dump(self, fichero)
245          fichero.close()          fichero.close()
246    
247          print "TRAZA: hemos dumpeado con pickle el fichero",self.id          print "TRAZA: hemos dumpeado con pickle el fichero",self.id
248    
249                    
250  # Métodos que se refieren a la clase pero tienen ámbito de clase,  # Métodos que se refieren a la clase pero tienen ámbito de clase,
251  # y no de instancia  # y no de instancia
252    
253  def openAnything(source):  def openAnything(source):
254      """URI, filename, or string --> stream      """URI, filename, or string --> stream
255            
256      This function lets you define parsers that take any input source      This function lets you define parsers that take any input source
257      (URL, pathname to local or network file, or actual data as a string)      (URL, pathname to local or network file, or actual data as a string)
258      and deal with it in a uniform manner.  Returned object is guaranteed      and deal with it in a uniform manner.  Returned object is guaranteed
259      to have all the basic stdio read methods (read, readline, readlines).      to have all the basic stdio read methods (read, readline, readlines).
260      Just .close() the object when you're done with it.      Just .close() the object when you're done with it.
261            
262      Examples:      Examples:
263          >>> from xml.dom import minidom          >>> from xml.dom import minidom
264          >>> sock = openAnything("http://localhost/kant.xml")          >>> sock = openAnything("http://localhost/kant.xml")
265          >>> doc = minidom.parse(sock)          >>> doc = minidom.parse(sock)
266          >>> sock.close()          >>> sock.close()
267          >>> sock = openAnything("c:\\inetpub\\wwwroot\\kant.xml")          >>> sock = openAnything("c:\\inetpub\\wwwroot\\kant.xml")
268          >>> doc = minidom.parse(sock)          >>> doc = minidom.parse(sock)
269          >>> sock.close()          >>> sock.close()
270          >>> sock = openAnything("<ref id='conjunction'><text>and</text><text>or</text></ref>")          >>> sock = openAnything("<ref id='conjunction'><text>and</text><text>or</text></ref>")
271          >>> doc = minidom.parse(sock)          >>> doc = minidom.parse(sock)
272          >>> sock.close()          >>> sock.close()
273          """          """
274                    
275      # try to open with urllib (if source is http, ftp, or file URL)      # try to open with urllib (if source is http, ftp, or file URL)
276      import urllib      import urllib
277      try:      try:
278          return urllib.urlopen(source)          return urllib.urlopen(source)
279      except IOError:      except IOError:
280          pass          pass
281            
282      # try to open with native open function (if source is pathname)      # try to open with native open function (if source is pathname)
283      try:      try:
284          return open(source)          return open(source)
285      except IOError:      except IOError:
286          pass          pass
287            
288      # assume source is string, create stream      # assume source is string, create stream
289      import StringIO      import StringIO
290      return StringIO.StringIO(source)      return StringIO.StringIO(source)
291    
292    
293    
294  def Objeto_cargar(archivo):  def Objeto_cargar(archivo):
295      fichero = open(os.path.join(Objeto.DIR_OBJETOS, archivo), "r")      fichero = open(os.path.join(Objeto.DIR_OBJETOS, archivo), "r")
296      objeto = cPickle.load(fichero)      objeto = cPickle.load(fichero)
297      fichero.close()      fichero.close()
298            
299      return objeto      return objeto
300    
301    
302  # Código para pruebas unitarias del módulo.  # Código para pruebas unitarias del módulo.
303    
304  if (__name__ == '__main__'):  if (__name__ == '__main__'):
305      print "No hay prueba unitaria de módulo. prueba con pnjtester.py"      print "No hay prueba unitaria de módulo. prueba con pnjtester.py"

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

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