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 |
# |
# |
23 |
#Fichero: sala.py |
#Fichero: sala.py |
24 |
|
|
25 |
"""Clase Sala.""" |
"""Clase Sala.""" |
26 |
|
|
27 |
|
|
28 |
from xml.dom import minidom |
from xml.dom import minidom |
29 |
import random |
import random |
30 |
import sys |
import sys |
31 |
import string |
import string |
32 |
import os |
import os |
33 |
import cPickle |
import cPickle |
34 |
|
|
35 |
from objeto import * |
from objeto import * |
36 |
from utils import * |
from utils import * |
37 |
from fechahoramine import * |
from fechahoramine import * |
38 |
|
|
39 |
class Sala: |
class Sala: |
40 |
"""Una habitacion o sala dentro del juego. |
"""Una habitacion o sala dentro del juego. |
41 |
|
|
42 |
Contiene los siguientes atributos: |
Contiene los siguientes atributos: |
43 |
- id (string): identifica univocamente a la sala. No puede contener espacios y debe |
- id (string): identifica univocamente a la sala. No puede contener espacios y debe |
44 |
tener el formato: nombre_de_area-identificador_de_sala. |
tener el formato: nombre_de_area-identificador_de_sala. |
45 |
- version (string): versión del sistema de salas. |
- version (string): versión del sistema de salas. |
46 |
- autor (string): nombre del autor de la descripción. |
- autor (string): nombre del autor de la descripción. |
47 |
- area (string): nombre del area a la que pertenece la sala. |
- area (string): nombre del area a la que pertenece la sala. |
48 |
- comentario (string): comentario explicativo del fichero de sala. |
- comentario (string): comentario explicativo del fichero de sala. |
49 |
- nombre (string): texto con el nombre corto de la sala, tal como sale en pantalla. |
- nombre (string): texto con el nombre corto de la sala, tal como sale en pantalla. |
50 |
- aura (int): nivel de aura de la sala (50 = normal, 0-50 = malvado, 50-100 = bueno). |
- aura (int): nivel de aura de la sala (50 = normal, 0-50 = malvado, 50-100 = bueno). |
51 |
- volumen (float): volumen total que puede contener (1 unidad = tamaño de un humano). |
- volumen (float): volumen total que puede contener (1 unidad = tamaño de un humano). |
52 |
- luz (int): nivel de iluminación (0 = oscuridad total, 100 = enfrente de Eru). |
- luz (int): nivel de iluminación (0 = oscuridad total, 100 = enfrente de Eru). |
53 |
- combate (string): si se puede combatir en esta sala ("si" o "no"). |
- combate (string): si se puede combatir en esta sala ("si" o "no"). |
54 |
- ocultabilidad (int): facilidad de ocultarse (0 = imposible, 100 = seguro). |
- ocultabilidad (int): facilidad de ocultarse (0 = imposible, 100 = seguro). |
55 |
- descripcion ({String:any}[]): descripcion de la sala. Consiste en una lista de items, |
- descripcion ({String:any}[]): descripcion de la sala. Consiste en una lista de items, |
56 |
y cada item es un conjunto de propiedades en forma de |
y cada item es un conjunto de propiedades en forma de |
57 |
diccionario: |
diccionario: |
58 |
- "dificultad" (int): dificultad para percibir el item |
- "dificultad" (int): dificultad para percibir el item |
59 |
(0 = automatico, 100 = imposible) |
(0 = automatico, 100 = imposible) |
60 |
- "texto" (string): el texto del item |
- "texto" (string): el texto del item |
61 |
- salidas ({String:any}[]): lista de salidas de la sala, siendo cada salida un diccionario: |
- salidas ({String:any}[]): lista de salidas de la sala, siendo cada salida un diccionario: |
62 |
- "direccion" (string): el punto cardinal (norte, sur, etc.) |
- "direccion" (string): el punto cardinal (norte, sur, etc.) |
63 |
- "dificultad" (int): dificultad para percibirla (0-100) |
- "dificultad" (int): dificultad para percibirla (0-100) |
64 |
- "id" (string): el id de la sala a donde se va por ahi |
- "id" (string): el id de la sala a donde se va por ahi |
65 |
- "descripcion" (string): lo que se ve al mirar en esa direccion |
- "descripcion" (string): lo que se ve al mirar en esa direccion |
66 |
- "tipo_cierre" (string): el tipo de cerradura que hay (ninguno, |
- "tipo_cierre" (string): el tipo de cerradura que hay (ninguno, |
67 |
cerradura, horario, magia) |
cerradura, horario, magia) |
68 |
- "datos_cierre" (string): información adicional sobre el cierre: |
- "datos_cierre" (string): información adicional sobre el cierre: |
69 |
* ninguno: vacío |
* ninguno: vacío |
70 |
* cerradura: id de objeto llave |
* cerradura: id de objeto llave |
71 |
* horario: rango(s) horario(s) de apertura, |
* horario: rango(s) horario(s) de apertura, |
72 |
formato hora_ini-hora_fin, separados por |
formato hora_ini-hora_fin, separados por |
73 |
comas. Puede incluir un espacio y el id |
comas. Puede incluir un espacio y el id |
74 |
de la llave que abre cuando está cerrada |
de la llave que abre cuando está cerrada |
75 |
* magia: id de hechizo (sin implementar) |
* magia: id de hechizo (sin implementar) |
76 |
- "mensaje_cerrado" (string): mensaje que sale si se intenta salir |
- "mensaje_cerrado" (string): mensaje que sale si se intenta salir |
77 |
estando cerrada. |
estando cerrada. |
78 |
- objetos ({String:any}[]): lista de objetos de la sala, siendo cada objeto un diccionario: |
- objetos ({String:any}[]): lista de objetos de la sala, siendo cada objeto un diccionario: |
79 |
- "id" (string): el id del objeto |
- "id" (string): el id del objeto |
80 |
- "probabilidad" (int): probabilidad de que reaparezca cada vez |
- "probabilidad" (int): probabilidad de que reaparezca cada vez |
81 |
que alguien entra en la sala (0-100) |
que alguien entra en la sala (0-100) |
82 |
- "maximo" (int): maximos objetos que pueden aparecer (si es |
- "maximo" (int): maximos objetos que pueden aparecer (si es |
83 |
0, no hay máximo) |
0, no hay máximo) |
84 |
- "dificultad" (int): dificultad para percibirlo (0-100) |
- "dificultad" (int): dificultad para percibirlo (0-100) |
85 |
- "instancias" (Objeto[]): lista con una o más instancias del |
- "instancias" (Objeto[]): lista con una o más instancias del |
86 |
objeto real (puede estar vacía si |
objeto real (puede estar vacía si |
87 |
probabilidad > 0, porque es posible |
probabilidad > 0, porque es posible |
88 |
que reaparezcan objetos más tarde) |
que reaparezcan objetos más tarde) |
89 |
- encuentros ({String:any}[]): lista de pnjs propios de la sala, siendo cada encuentro |
- encuentros ({String:any}[]): lista de pnjs propios de la sala, siendo cada encuentro |
90 |
un diccionario: |
un diccionario: |
91 |
- "id" (string): el id del pnj |
- "id" (string): el id del pnj |
92 |
- "probabilidad" (int): probabilidad de que reaparezca cada |
- "probabilidad" (int): probabilidad de que reaparezca cada |
93 |
vez que alguien entra en la sala |
vez que alguien entra en la sala |
94 |
(0-100) |
(0-100) |
95 |
- "maximo" (int): maximos pnjs que pueden aparecer (si es |
- "maximo" (int): maximos pnjs que pueden aparecer (si es |
96 |
0, no hay máximo) |
0, no hay máximo) |
97 |
- "dificultad" (int): dificultad para percibirlo (0-100) |
- "dificultad" (int): dificultad para percibirlo (0-100) |
98 |
- "descripcion" (string): que aspecto tiene el personaje |
- "descripcion" (string): que aspecto tiene el personaje |
99 |
- personajes (Personaje{}): diccionario con los personajes que se encuentran en la sala, |
- personajes (Personaje{}): diccionario con los personajes que se encuentran en la sala, |
100 |
indexado por id. NO MODIFICAR DIRECTAMENTE, SINO CON |
indexado por id. NO MODIFICAR DIRECTAMENTE, SINO CON |
101 |
entrar_personaje() Y salir_personaje() |
entrar_personaje() Y salir_personaje() |
102 |
- 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 |
103 |
- __fecha_fichero (int): fecha de la ultima modificacion del fichero de descripcion |
- __fecha_fichero (int): fecha de la ultima modificacion del fichero de descripcion |
104 |
|
|
105 |
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, |
106 |
poniendola en su estado inicial. Mas tarde, se puede salvar en un fichero de sala, |
poniendola en su estado inicial. Mas tarde, se puede salvar en un fichero de sala, |
107 |
borrarla y cargarla despues, manteniendo su estado (situacion de objetos y personajes |
borrarla y cargarla despues, manteniendo su estado (situacion de objetos y personajes |
108 |
contenidos, tanto PJs como PNJs). |
contenidos, tanto PJs como PNJs). |
109 |
|
|
110 |
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 |
111 |
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 |
112 |
formado por el atributo "sala" de la clase Personaje. |
formado por el atributo "sala" de la clase Personaje. |
113 |
|
|
114 |
Invariantes: |
Invariantes: |
115 |
id != None |
id != None |
116 |
version != None |
version != None |
117 |
autor != None |
autor != None |
118 |
area != None |
area != None |
119 |
comentario != None |
comentario != None |
120 |
nombre != None |
nombre != None |
121 |
aura in range(0,100) |
aura in range(0,100) |
122 |
volumen > 0 |
volumen > 0 |
123 |
luz in range(0,100) |
luz in range(0,100) |
124 |
combate in ["si", "no"] |
combate in ["si", "no"] |
125 |
ocultabilidad in range(0,100) |
ocultabilidad in range(0,100) |
126 |
|
|
127 |
descripcion != None |
descripcion != None |
128 |
len(descripcion) >= 0 |
len(descripcion) >= 0 |
129 |
descripcion[i]["dificultad"] in range(0,100) |
descripcion[i]["dificultad"] in range(0,100) |
130 |
descripcion[i]["texto"] != None |
descripcion[i]["texto"] != None |
131 |
|
|
132 |
salidas != None |
salidas != None |
133 |
len(salidas) >= 0 |
len(salidas) >= 0 |
134 |
salidas[i]["direccion"] != Null |
salidas[i]["direccion"] != Null |
135 |
salidas[i]["dificultad"] in range(0,100) |
salidas[i]["dificultad"] in range(0,100) |
136 |
salidas[i]["id"] != Null |
salidas[i]["id"] != Null |
137 |
salidas[i]["descripcion"] != Null |
salidas[i]["descripcion"] != Null |
138 |
salidas[i]["tipo_cierre"] in ("ninguno", "cerradura", "horario", "magia") |
salidas[i]["tipo_cierre"] in ("ninguno", "cerradura", "horario", "magia") |
139 |
salidas[i]["datos_cierre"] != Null |
salidas[i]["datos_cierre"] != Null |
140 |
salidas[i]["mensaje_cerrado"] != Null |
salidas[i]["mensaje_cerrado"] != Null |
141 |
|
|
142 |
objetos != None |
objetos != None |
143 |
len(objetos) >= 0 |
len(objetos) >= 0 |
144 |
objetos[i]["id"] != Null |
objetos[i]["id"] != Null |
145 |
objetos[i]["probabilidad"] in range(0,100) |
objetos[i]["probabilidad"] in range(0,100) |
146 |
objetos[i]["maximo"] >= 0 |
objetos[i]["maximo"] >= 0 |
147 |
objetos[i]["dificultad"] in range(0,100) |
objetos[i]["dificultad"] in range(0,100) |
148 |
objetos[i]["instancias"] != Null |
objetos[i]["instancias"] != Null |
149 |
|
|
150 |
encuentros != None |
encuentros != None |
151 |
len(encuentros) >= 0 |
len(encuentros) >= 0 |
152 |
encuentros[i]["id"] != Null |
encuentros[i]["id"] != Null |
153 |
encuentros[i]["probabilidad"] in range(0,100) |
encuentros[i]["probabilidad"] in range(0,100) |
154 |
encuentros[i]["maximo"] >= 0 |
encuentros[i]["maximo"] >= 0 |
155 |
encuentros[i]["dificultad"] in range(0,100) |
encuentros[i]["dificultad"] in range(0,100) |
156 |
encuentros[i]["descripcion"] != Null |
encuentros[i]["descripcion"] != Null |
157 |
|
|
158 |
personajes != None |
personajes != None |
159 |
personajes[i].sala == self |
personajes[i].sala == self |
160 |
|
|
161 |
n_jugadores >= 0 |
n_jugadores >= 0 |
162 |
n_jugadores <= len(personajes) |
n_jugadores <= len(personajes) |
163 |
|
|
164 |
__fecha_fichero >= 0 |
__fecha_fichero >= 0 |
165 |
""" |
""" |
166 |
|
|
167 |
# Version del sistema de descripciones de sala (se incrementa cada vez que cambia |
# Version del sistema de descripciones de sala (se incrementa cada vez que cambia |
168 |
# el formato de los ficheros de desc_salas) |
# el formato de los ficheros de desc_salas) |
169 |
VERSION_DESC_SALA = '1.2' |
VERSION_DESC_SALA = '1.2' |
170 |
|
|
171 |
# Version del sistema de salas (se incrementa cada vez que varian los atributos |
# Version del sistema de salas (se incrementa cada vez que varian los atributos |
172 |
# de la clase Sala) |
# de la clase Sala) |
173 |
VERSION_SALA = '1.2' |
VERSION_SALA = '1.2' |
174 |
|
|
175 |
DIR_DESC_SALAS = 'desc_salas' |
DIR_DESC_SALAS = 'desc_salas' |
176 |
EXT_DESC_SALAS = '.xml' |
EXT_DESC_SALAS = '.xml' |
177 |
DIR_SALAS = 'salas' |
DIR_SALAS = 'salas' |
178 |
EXT_SALAS = '' |
EXT_SALAS = '' |
179 |
|
|
180 |
|
|
181 |
def __init__(self, id): |
def __init__(self, id): |
182 |
"""Crea una sala nueva a partir de un fichero de descripción de sala. |
"""Crea una sala nueva a partir de un fichero de descripción de sala. |
183 |
|
|
184 |
Requiere: |
Requiere: |
185 |
id != None |
id != None |
186 |
id corresponde con un fichero existente |
id corresponde con un fichero existente |
187 |
""" |
""" |
188 |
|
|
189 |
self.id = id |
self.id = id |
190 |
self.__inicializar_sala() |
self.__inicializar_sala() |
191 |
|
|
192 |
|
|
193 |
def __inicializar_sala(self): |
def __inicializar_sala(self): |
194 |
"""Rellena todos los datos de la sala a partir de su fichero |
"""Rellena todos los datos de la sala a partir de su fichero |
195 |
de descripcion. |
de descripcion. |
196 |
""" |
""" |
197 |
self.personajes = {} |
self.personajes = {} |
198 |
self.n_jugadores = 0 |
self.n_jugadores = 0 |
199 |
|
|
200 |
archivo = os.path.join(Sala.DIR_DESC_SALAS, self.id.split('-')[0], |
archivo = os.path.join(Sala.DIR_DESC_SALAS, self.id.split('-')[0], |
201 |
self.id + Sala.EXT_DESC_SALAS) |
self.id + Sala.EXT_DESC_SALAS) |
202 |
stream = open(archivo) |
stream = open(archivo) |
203 |
doc_xml = minidom.parse(stream).documentElement |
doc_xml = minidom.parse(stream).documentElement |
204 |
stream.close() |
stream.close() |
205 |
|
|
206 |
self.__fecha_fichero = os.path.getmtime(archivo) |
self.__fecha_fichero = os.path.getmtime(archivo) |
207 |
|
|
208 |
self.__iniciar_parseador(doc_xml) |
self.__iniciar_parseador(doc_xml) |
209 |
|
|
210 |
self.__parsear_sala(doc_xml) |
self.__parsear_sala(doc_xml) |
211 |
self.__parsear_id(doc_xml) |
self.__parsear_id(doc_xml) |
212 |
self.__parsear_nombre(doc_xml) |
self.__parsear_nombre(doc_xml) |
213 |
self.__parsear_descripcion(doc_xml) |
self.__parsear_descripcion(doc_xml) |
214 |
self.__parsear_salidas(doc_xml) |
self.__parsear_salidas(doc_xml) |
215 |
self.__parsear_propiedades(doc_xml) |
self.__parsear_propiedades(doc_xml) |
216 |
self.__parsear_objetos(doc_xml) |
self.__parsear_objetos(doc_xml) |
217 |
self.__parsear_encuentros(doc_xml) |
self.__parsear_encuentros(doc_xml) |
218 |
|
|
219 |
|
|
220 |
def __iniciar_parseador(self, doc_xml): |
def __iniciar_parseador(self, doc_xml): |
221 |
"""Esta función borra todos los nodos de tipo Text de un |
"""Esta función borra todos los nodos de tipo Text de un |
222 |
elemento DOM""" |
elemento DOM""" |
223 |
|
|
224 |
for nodo in doc_xml.childNodes[:]: |
for nodo in doc_xml.childNodes[:]: |
225 |
if not 'Element:' in str(nodo).split(): |
if not 'Element:' in str(nodo).split(): |
226 |
doc_xml.childNodes.remove(nodo) |
doc_xml.childNodes.remove(nodo) |
227 |
|
|
228 |
|
|
229 |
def __parsear_sala(self, doc_xml): |
def __parsear_sala(self, doc_xml): |
230 |
"""Extrae la información del elemento sala: |
"""Extrae la información del elemento sala: |
231 |
area: el área a la que pertenece la sala |
area: el área a la que pertenece la sala |
232 |
autor: el autor de la sala |
autor: el autor de la sala |
233 |
version: la versión del tipo de sala""" |
version: la versión del tipo de sala""" |
234 |
version_desc_sala = doc_xml.attributes["version"].value.encode('ISO-8859-1') |
version_desc_sala = doc_xml.attributes["version"].value.encode('ISO-8859-1') |
235 |
|
|
236 |
if version_desc_sala != Sala.VERSION_DESC_SALA: |
if version_desc_sala != Sala.VERSION_DESC_SALA: |
237 |
raise ValueError("Version incorrecta del fichero descriptor de sala " + self.id + ": " + |
raise ValueError("Version incorrecta del fichero descriptor de sala " + self.id + ": " + |
238 |
version_desc_sala + " cuando se esperaba " + Sala.VERSION_DESC_SALA) |
version_desc_sala + " cuando se esperaba " + Sala.VERSION_DESC_SALA) |
239 |
|
|
240 |
self.version = Sala.VERSION_SALA |
self.version = Sala.VERSION_SALA |
241 |
|
|
242 |
self.autor = doc_xml.attributes["autor"].value.encode('ISO-8859-1') |
self.autor = doc_xml.attributes["autor"].value.encode('ISO-8859-1') |
243 |
self.area = doc_xml.attributes["area"].value.encode('ISO-8859-1') |
self.area = doc_xml.attributes["area"].value.encode('ISO-8859-1') |
244 |
try: |
try: |
245 |
self.comentario = doc_xml.attributes["comentario"].value.encode('ISO-8859-1') |
self.comentario = doc_xml.attributes["comentario"].value.encode('ISO-8859-1') |
246 |
except: |
except: |
247 |
self.comentario = "" |
self.comentario = "" |
248 |
|
|
249 |
|
|
250 |
def __parsear_id(self, doc_xml): |
def __parsear_id(self, doc_xml): |
251 |
"""Extrae el id de la sala""" |
"""Extrae el id de la sala""" |
252 |
id_fichero = doc_xml.childNodes[0].childNodes[0].data.encode('ISO-8859-1') |
id_fichero = doc_xml.childNodes[0].childNodes[0].data.encode('ISO-8859-1') |
253 |
if id_fichero != self.id: |
if id_fichero != self.id: |
254 |
raise ValueError("El id no coincide con el nombre del fichero") |
raise ValueError("El id no coincide con el nombre del fichero") |
255 |
|
|
256 |
|
|
257 |
def __parsear_nombre(self, doc_xml): |
def __parsear_nombre(self, doc_xml): |
258 |
"""Extrae el nombre de la sala""" |
"""Extrae el nombre de la sala""" |
259 |
self.nombre = doc_xml.childNodes[1].childNodes[0].data.encode('ISO-8859-1') |
self.nombre = doc_xml.childNodes[1].childNodes[0].data.encode('ISO-8859-1') |
260 |
|
|
261 |
|
|
262 |
def __parsear_propiedades(self, doc_xml): |
def __parsear_propiedades(self, doc_xml): |
263 |
"""Extrae las propiedades globales de la sala.""" |
"""Extrae las propiedades globales de la sala.""" |
264 |
try: |
try: |
265 |
self.aura = int(doc_xml.childNodes[4].attributes["aura"].value) |
self.aura = int(doc_xml.childNodes[4].attributes["aura"].value) |
266 |
except: |
except: |
267 |
self.aura = 50 |
self.aura = 50 |
268 |
try: |
try: |
269 |
self.tipo = doc_xml.childNodes[4].attributes["tipo"].value |
self.tipo = doc_xml.childNodes[4].attributes["tipo"].value |
270 |
except: |
except: |
271 |
self.tipo = 'sin_tipo' |
self.tipo = 'sin_tipo' |
272 |
self.volumen = float(doc_xml.childNodes[4].attributes["volumen"].value) |
self.volumen = float(doc_xml.childNodes[4].attributes["volumen"].value) |
273 |
self.luz = int(doc_xml.childNodes[4].attributes["luz"].value) |
self.luz = int(doc_xml.childNodes[4].attributes["luz"].value) |
274 |
try: |
try: |
275 |
self.combate = doc_xml.childNodes[4].attributes["combate"].value |
self.combate = doc_xml.childNodes[4].attributes["combate"].value |
276 |
except: |
except: |
277 |
self.combate = 'si' |
self.combate = 'si' |
278 |
try: |
try: |
279 |
self.subtipo = doc_xml.childNodes[4].attributes["subtipo"].value |
self.subtipo = doc_xml.childNodes[4].attributes["subtipo"].value |
280 |
except: |
except: |
281 |
self.subtipo = 'sin_subtipo' |
self.subtipo = 'sin_subtipo' |
282 |
self.ocultabilidad = int(doc_xml.childNodes[4].attributes["ocultabilidad"].value) |
self.ocultabilidad = int(doc_xml.childNodes[4].attributes["ocultabilidad"].value) |
283 |
|
|
284 |
|
|
285 |
def __parsear_descripcion(self, doc_xml): |
def __parsear_descripcion(self, doc_xml): |
286 |
"""Extrae el texto y la dificultad asociada de los items de descripcion de la sala""" |
"""Extrae el texto y la dificultad asociada de los items de descripcion de la sala""" |
287 |
|
|
288 |
nodo_descripcion = doc_xml.childNodes[2] |
nodo_descripcion = doc_xml.childNodes[2] |
289 |
|
|
290 |
# Limpiamos todos los subnodos de tipo Text, al igual |
# Limpiamos todos los subnodos de tipo Text, al igual |
291 |
# que hacíamos en la función __iniciar_parseador() |
# que hacíamos en la función __iniciar_parseador() |
292 |
for nodo in nodo_descripcion.childNodes[:]: |
for nodo in nodo_descripcion.childNodes[:]: |
293 |
if not 'Element:' in str(nodo).split(): |
if not 'Element:' in str(nodo).split(): |
294 |
doc_xml.childNodes[2].childNodes.remove(nodo) |
doc_xml.childNodes[2].childNodes.remove(nodo) |
295 |
|
|
296 |
self.descripcion = [] |
self.descripcion = [] |
297 |
|
|
298 |
for nodo_item in nodo_descripcion.childNodes[:]: |
for nodo_item in nodo_descripcion.childNodes[:]: |
299 |
|
|
300 |
texto_item = "" |
texto_item = "" |
301 |
for nodo_parrafo in nodo_item.childNodes[:]: |
for nodo_parrafo in nodo_item.childNodes[:]: |
302 |
texto_item += nodo_parrafo.data.encode('ISO-8859-1') |
texto_item += nodo_parrafo.data.encode('ISO-8859-1') |
303 |
|
|
304 |
texto_item = " ".join(texto_item.split()) |
texto_item = " ".join(texto_item.split()) |
305 |
|
|
306 |
if len(nodo_item._attrs) == 0: |
if len(nodo_item._attrs) == 0: |
307 |
dif_item = 0 |
dif_item = 0 |
308 |
else: |
else: |
309 |
dif_item = int(nodo_item._attrs.get('dificultad').value) |
dif_item = int(nodo_item._attrs.get('dificultad').value) |
310 |
|
|
311 |
self.descripcion.append({"dificultad": dif_item, "texto": texto_item}) |
self.descripcion.append({"dificultad": dif_item, "texto": texto_item}) |
312 |
|
|
313 |
|
|
314 |
def __parsear_decorativos(self, doc_xml): |
def __parsear_decorativos(self, doc_xml): |
315 |
"""Extrae el texto y la dificultad asociada de los items decorativos de la sala""" |
"""Extrae el texto y la dificultad asociada de los items decorativos de la sala""" |
316 |
|
|
317 |
nodo_decorativos = doc_xml.childNodes[3] |
nodo_decorativos = doc_xml.childNodes[3] |
318 |
|
|
319 |
# Limpiamos todos los subnodos de tipo Text, al igual |
# Limpiamos todos los subnodos de tipo Text, al igual |
320 |
# que hacíamos en la función __iniciar_parseador() |
# que hacíamos en la función __iniciar_parseador() |
321 |
for nodo in nodo_decorativos.childNodes[:]: |
for nodo in nodo_decorativos.childNodes[:]: |
322 |
if not 'Element:' in str(nodo).split(): |
if not 'Element:' in str(nodo).split(): |
323 |
doc_xml.childNodes[2].childNodes.remove(nodo) |
doc_xml.childNodes[2].childNodes.remove(nodo) |
324 |
|
|
325 |
self.decorativos = [] |
self.decorativos = [] |
326 |
|
|
327 |
for nodo_item in nodo_decorativos.childNodes[:]: |
for nodo_item in nodo_decorativos.childNodes[:]: |
328 |
|
|
329 |
nombre_item = nodo_item._attrs.get('nombre').value.encode('ISO-8859-1') |
nombre_item = nodo_item._attrs.get('nombre').value.encode('ISO-8859-1') |
330 |
texto_item = nodo_item._attrs.get('texto').value.encode('ISO-8859-1') |
texto_item = nodo_item._attrs.get('texto').value.encode('ISO-8859-1') |
331 |
|
|
332 |
if len(nodo_item._attrs) == 1: |
if len(nodo_item._attrs) == 1: |
333 |
dif_item = 0 |
dif_item = 0 |
334 |
else: |
else: |
335 |
dif_item = int(nodo_item._attrs.get('dificultad').value) |
dif_item = int(nodo_item._attrs.get('dificultad').value) |
336 |
|
|
337 |
self.decorativos.append({"nombre": nombre_item, "dificultad": dif_item, "texto": texto_item}) |
self.decorativos.append({"nombre": nombre_item, "dificultad": dif_item, "texto": texto_item}) |
338 |
|
|
339 |
|
|
340 |
def __parsear_salidas(self, doc_xml): |
def __parsear_salidas(self, doc_xml): |
341 |
"""Extrae toda la información de las salidas de la sala.""" |
"""Extrae toda la información de las salidas de la sala.""" |
342 |
|
|
343 |
nodo_salidas = doc_xml.childNodes[3] |
nodo_salidas = doc_xml.childNodes[3] |
344 |
|
|
345 |
# Limpiamos todos los subnodos de tipo Text, al igual |
# Limpiamos todos los subnodos de tipo Text, al igual |
346 |
# que hacíamos en la función __iniciar_parseador() |
# que hacíamos en la función __iniciar_parseador() |
347 |
for nodo in nodo_salidas.childNodes[:]: |
for nodo in nodo_salidas.childNodes[:]: |
348 |
if not 'Element:' in str(nodo).split(): |
if not 'Element:' in str(nodo).split(): |
349 |
nodo_salidas.childNodes.remove(nodo) |
nodo_salidas.childNodes.remove(nodo) |
350 |
|
|
351 |
self.salidas = [] |
self.salidas = [] |
352 |
|
|
353 |
for nodo_salida in nodo_salidas.childNodes[:]: |
for nodo_salida in nodo_salidas.childNodes[:]: |
354 |
|
|
355 |
direccion_salida = nodo_salida.nodeName.encode('ISO-8859-1') # oeste, este, norte, etc. |
direccion_salida = nodo_salida.nodeName.encode('ISO-8859-1') # oeste, este, norte, etc. |
356 |
try: |
try: |
357 |
dif_salida = int(nodo_salida._attrs.get('dificultad').value.encode('ISO-8859-1')) |
dif_salida = int(nodo_salida._attrs.get('dificultad').value.encode('ISO-8859-1')) |
358 |
except: |
except: |
359 |
dif_salida = 0 |
dif_salida = 0 |
360 |
try: |
try: |
361 |
tipo_cierre_salida = nodo_salida._attrs.get('tipo_cierre').value.encode('ISO-8859-1') |
tipo_cierre_salida = nodo_salida._attrs.get('tipo_cierre').value.encode('ISO-8859-1') |
362 |
except: |
except: |
363 |
tipo_cierre_salida = "ninguno" |
tipo_cierre_salida = "ninguno" |
364 |
try: |
try: |
365 |
datos_cierre_salida = nodo_salida._attrs.get('datos_cierre').value.encode('ISO-8859-1') |
datos_cierre_salida = nodo_salida._attrs.get('datos_cierre').value.encode('ISO-8859-1') |
366 |
except: |
except: |
367 |
datos_cierre_salida = "" |
datos_cierre_salida = "" |
368 |
try: |
try: |
369 |
mensaje_cerrado_salida = nodo_salida._attrs.get('mensaje_cerrado').value.encode('ISO-8859-1') |
mensaje_cerrado_salida = nodo_salida._attrs.get('mensaje_cerrado').value.encode('ISO-8859-1') |
370 |
except: |
except: |
371 |
mensaje_cerrado_salida = "Algo te impide pasar" |
mensaje_cerrado_salida = "Algo te impide pasar" |
372 |
|
|
373 |
id_salida = nodo_salida._attrs.get('id').value.encode('ISO-8859-1') |
id_salida = nodo_salida._attrs.get('id').value.encode('ISO-8859-1') |
374 |
desc_salida = nodo_salida.childNodes[0].data.encode('ISO-8859-1') |
desc_salida = nodo_salida.childNodes[0].data.encode('ISO-8859-1') |
375 |
|
|
376 |
self.salidas.append({"direccion": direccion_salida, |
self.salidas.append({"direccion": direccion_salida, |
377 |
"dificultad": dif_salida, |
"dificultad": dif_salida, |
378 |
"id": id_salida, |
"id": id_salida, |
379 |
"descripcion": desc_salida, |
"descripcion": desc_salida, |
380 |
"tipo_cierre": tipo_cierre_salida, |
"tipo_cierre": tipo_cierre_salida, |
381 |
"datos_cierre": datos_cierre_salida, |
"datos_cierre": datos_cierre_salida, |
382 |
"mensaje_cerrado": mensaje_cerrado_salida}) |
"mensaje_cerrado": mensaje_cerrado_salida}) |
383 |
|
|
384 |
# "horario": horario_salida, |
# "horario": horario_salida, |
385 |
# "error": error_salida}) |
# "error": error_salida}) |
386 |
|
|
387 |
def __parsear_objetos(self, doc_xml): |
def __parsear_objetos(self, doc_xml): |
388 |
"""Extrae toda la información de los objetos que hay en la sala inicialmente.""" |
"""Extrae toda la información de los objetos que hay en la sala inicialmente.""" |
389 |
|
|
390 |
nodo_objetos = doc_xml.childNodes[5] |
nodo_objetos = doc_xml.childNodes[5] |
391 |
|
|
392 |
# Limpiamos todos los subnodos de tipo Text, al igual |
# Limpiamos todos los subnodos de tipo Text, al igual |
393 |
# que hacíamos en la función __iniciar_parseador() |
# que hacíamos en la función __iniciar_parseador() |
394 |
for nodo in nodo_objetos.childNodes[:]: |
for nodo in nodo_objetos.childNodes[:]: |
395 |
if 'Element:' not in str(nodo).split(): |
if 'Element:' not in str(nodo).split(): |
396 |
nodo_objetos.childNodes.remove(nodo) |
nodo_objetos.childNodes.remove(nodo) |
397 |
|
|
398 |
self.objetos = [] |
self.objetos = [] |
399 |
|
|
400 |
for nodo_objeto in nodo_objetos.childNodes[:]: |
for nodo_objeto in nodo_objetos.childNodes[:]: |
401 |
|
|
402 |
id_objeto = nodo_objeto._attrs.get('id').value.encode('ISO-8859-1') |
id_objeto = nodo_objeto._attrs.get('id').value.encode('ISO-8859-1') |
403 |
try: |
try: |
404 |
cantidad_objeto = int(nodo_objeto._attrs.get('cantidad').value) |
cantidad_objeto = int(nodo_objeto._attrs.get('cantidad').value) |
405 |
except: |
except: |
406 |
cantidad_objeto = 1 |
cantidad_objeto = 1 |
407 |
try: |
try: |
408 |
max_objeto = int(nodo_objeto._attrs.get('maximo').value) |
max_objeto = int(nodo_objeto._attrs.get('maximo').value) |
409 |
except: |
except: |
410 |
max_objeto = cantidad_objeto |
max_objeto = cantidad_objeto |
411 |
try: |
try: |
412 |
prob_objeto = int(nodo_objeto._attrs.get('probabilidad').value) |
prob_objeto = int(nodo_objeto._attrs.get('probabilidad').value) |
413 |
except: |
except: |
414 |
prob_objeto = 0 |
prob_objeto = 0 |
415 |
try: |
try: |
416 |
dif_objeto = int(nodo_objeto._attrs.get('dificultad').value) |
dif_objeto = int(nodo_objeto._attrs.get('dificultad').value) |
417 |
except: |
except: |
418 |
dif_objeto = 0 |
dif_objeto = 0 |
419 |
desc_objeto = nodo_objeto.childNodes[0].data.encode('ISO-8859-1') |
desc_objeto = nodo_objeto.childNodes[0].data.encode('ISO-8859-1') |
420 |
|
|
421 |
instancias = [] |
instancias = [] |
422 |
for i in range(cantidad_objeto): |
for i in range(cantidad_objeto): |
423 |
instancias.append(Objeto(id_objeto)) |
instancias.append(Objeto(id_objeto)) |
424 |
|
|
425 |
self.objetos.append({"id": id_objeto, |
self.objetos.append({"id": id_objeto, |
426 |
"probabilidad": prob_objeto, |
"probabilidad": prob_objeto, |
427 |
"maximo": max_objeto, |
"maximo": max_objeto, |
428 |
"dificultad": dif_objeto, |
"dificultad": dif_objeto, |
429 |
"instancias": instancias}) |
"instancias": instancias}) |
430 |
|
|
431 |
|
|
432 |
def __parsear_encuentros(self, doc_xml): |
def __parsear_encuentros(self, doc_xml): |
433 |
"""Extrae toda la información de los PNJs que hay en la sala inicialmente.""" |
"""Extrae toda la información de los PNJs que hay en la sala inicialmente.""" |
434 |
|
|
435 |
nodo_encuentros = doc_xml.childNodes[6] |
nodo_encuentros = doc_xml.childNodes[6] |
436 |
|
|
437 |
# Limpiamos todos los subnodos de tipo Text, al igual |
# Limpiamos todos los subnodos de tipo Text, al igual |
438 |
# que hacíamos en la función __iniciar_parseador() |
# que hacíamos en la función __iniciar_parseador() |
439 |
for nodo in doc_xml.childNodes[6].childNodes[:]: |
for nodo in doc_xml.childNodes[6].childNodes[:]: |
440 |
if 'Element:' not in str(nodo).split(): doc_xml.childNodes[6].childNodes.remove(nodo) |
if 'Element:' not in str(nodo).split(): doc_xml.childNodes[6].childNodes.remove(nodo) |
441 |
|
|
442 |
self.encuentros=[] |
self.encuentros=[] |
443 |
|
|
444 |
for nodo_encuentro in nodo_encuentros.childNodes[:]: |
for nodo_encuentro in nodo_encuentros.childNodes[:]: |
445 |
id_encuentro = nodo_encuentro._attrs.get('id').value.encode('ISO-8859-1') |
id_encuentro = nodo_encuentro._attrs.get('id').value.encode('ISO-8859-1') |
446 |
try: |
try: |
447 |
cant_encuentro = int(nodo_encuentro._attrs.get('cantidad').value) |
cant_encuentro = int(nodo_encuentro._attrs.get('cantidad').value) |
448 |
except: |
except: |
449 |
cant_encuentro = 1 |
cant_encuentro = 1 |
450 |
try: |
try: |
451 |
max_encuentro = int(nodo_encuentro._attrs.get('maximo').value) |
max_encuentro = int(nodo_encuentro._attrs.get('maximo').value) |
452 |
except: |
except: |
453 |
max_encuentro = 0 |
max_encuentro = 0 |
454 |
try: |
try: |
455 |
prob_encuentro = int(nodo_encuentro._attrs.get('probabilidad')) |
prob_encuentro = int(nodo_encuentro._attrs.get('probabilidad')) |
456 |
except: |
except: |
457 |
prob_encuentro = 0 |
prob_encuentro = 0 |
458 |
try: |
try: |
459 |
dif_encuentro = int(nodo_encuentro._attrs.get('dificultad').value) |
dif_encuentro = int(nodo_encuentro._attrs.get('dificultad').value) |
460 |
except: |
except: |
461 |
dif_encuentro = 0 |
dif_encuentro = 0 |
462 |
desc_encuentro = nodo_encuentro.childNodes[0].data.encode('ISO-8859-1') |
desc_encuentro = nodo_encuentro.childNodes[0].data.encode('ISO-8859-1') |
463 |
|
|
464 |
self.encuentros.append({"id": id_encuentro, |
self.encuentros.append({"id": id_encuentro, |
465 |
"maximo": max_encuentro, |
"maximo": max_encuentro, |
466 |
"probabilidad": prob_encuentro, |
"probabilidad": prob_encuentro, |
467 |
"dificultad": dif_encuentro, |
"dificultad": dif_encuentro, |
468 |
"descripcion": desc_encuentro}) |
"descripcion": desc_encuentro}) |
469 |
|
|
470 |
escribir("Vamos a crear " + str(cant_encuentro) + " pnjs") |
escribir("Vamos a crear " + str(cant_encuentro) + " pnjs") |
471 |
for i in range(cant_encuentro): |
for i in range(cant_encuentro): |
472 |
id_unico = id_encuentro + '%' + PersonajeNoJugador_nuevo_id() |
id_unico = id_encuentro + '%' + PersonajeNoJugador_nuevo_id() |
473 |
escribir("Vamos a crear a " + id_unico) |
escribir("Vamos a crear a " + id_unico) |
474 |
self.personajes[id_unico] = PersonajeNoJugador(id_unico, self) |
self.personajes[id_unico] = PersonajeNoJugador(id_unico, self) |
475 |
|
|
476 |
|
|
477 |
def activar(self): |
def activar(self): |
478 |
"""Realiza algunos chequeos periodicos siempre que alguien |
"""Realiza algunos chequeos periodicos siempre que alguien |
479 |
necesita esta sala. |
necesita esta sala. |
480 |
""" |
""" |
481 |
from mundo import Mundo |
from mundo import Mundo |
482 |
|
|
483 |
if self.id != Mundo.ID_SALA_LIMBO: |
if self.id != Mundo.ID_SALA_LIMBO: |
484 |
# Todos los personajes no controlados deben estar siempre en el limbo, |
# Todos los personajes no controlados deben estar siempre en el limbo, |
485 |
# pero es posible que por algún fallo quede alguno suelto por ahí. |
# pero es posible que por algún fallo quede alguno suelto por ahí. |
486 |
# Si se da el caso, lo movemos al limbo. |
# Si se da el caso, lo movemos al limbo. |
487 |
for personaje in self.personajes.values()[:]: |
for personaje in self.personajes.values()[:]: |
488 |
if personaje.controlador == None: |
if personaje.controlador == None: |
489 |
escribir("OJO: restaurado pj " + personaje.id + " en sala " + self.id + |
escribir("OJO: restaurado pj " + personaje.id + " en sala " + self.id + |
490 |
". Moviendolo al limbo...") |
". Moviendolo al limbo...") |
491 |
personaje.liberar() |
personaje.liberar() |
492 |
else: |
else: |
493 |
# En el limbo, todos los personajes deben tener la sala original |
# En el limbo, todos los personajes deben tener la sala original |
494 |
# a donde devolverlos a la vuelta. Puede que por algún error, haya |
# a donde devolverlos a la vuelta. Puede que por algún error, haya |
495 |
# alguno con eso mal. Si es así, lo enviamos a la entrada. |
# alguno con eso mal. Si es así, lo enviamos a la entrada. |
496 |
for personaje in self.personajes.values()[:]: |
for personaje in self.personajes.values()[:]: |
497 |
if not hasattr(personaje, "id_sala_original") or \ |
if not hasattr(personaje, "id_sala_original") or \ |
498 |
personaje.id_sala_original == Mundo.ID_SALA_LIMBO: |
personaje.id_sala_original == Mundo.ID_SALA_LIMBO: |
499 |
escribir("OJO: personaje " + personaje.id + " en el limbo ha perdido " + |
escribir("OJO: personaje " + personaje.id + " en el limbo ha perdido " + |
500 |
"la sala original. Lo mandaremos a la entrada...") |
"la sala original. Lo mandaremos a la entrada...") |
501 |
personaje.id_sala_original = Mundo.ID_SALA_ENTRADA |
personaje.id_sala_original = Mundo.ID_SALA_ENTRADA |
502 |
|
|
503 |
|
|
504 |
archivo = os.path.join(Sala.DIR_DESC_SALAS, self.id.split('-')[0], self.id + Sala.EXT_DESC_SALAS) |
archivo = os.path.join(Sala.DIR_DESC_SALAS, self.id.split('-')[0], self.id + Sala.EXT_DESC_SALAS) |
505 |
if self.__fecha_fichero < os.path.getmtime(archivo): |
if self.__fecha_fichero < os.path.getmtime(archivo): |
506 |
# Si se modifica el fichero descriptor, recargarlo de nuevo |
# Si se modifica el fichero descriptor, recargarlo de nuevo |
507 |
# pero conservando la lista de personajes y los objetos *que no |
# pero conservando la lista de personajes y los objetos *que no |
508 |
# sean nativos* de la sala. |
# sean nativos* de la sala. |
509 |
escribir("Recargando sala " + self.id + " desde el fichero de descripcion") |
escribir("Recargando sala " + self.id + " desde el fichero de descripcion") |
510 |
|
|
511 |
objetos_guardados = self.objetos |
objetos_guardados = self.objetos |
512 |
personajes_guardados = self.personajes |
personajes_guardados = self.personajes |
513 |
n_jugadores_guardado = self.n_jugadores |
n_jugadores_guardado = self.n_jugadores |
514 |
|
|
515 |
self.__inicializar_sala() |
self.__inicializar_sala() |
516 |
|
|
517 |
self.personajes = personajes_guardados |
self.personajes = personajes_guardados |
518 |
self.n_jugadores = n_jugadores_guardado |
self.n_jugadores = n_jugadores_guardado |
519 |
for objeto_guardado in objetos_guardados: |
for objeto_guardado in objetos_guardados: |
520 |
og = ( objeto_guardado["id"], objeto_guardado["probabilidad"] ) |
og = ( objeto_guardado["id"], objeto_guardado["probabilidad"] ) |
521 |
if og not in [ (o["id"], o["probabilidad"]) for o in self.objetos ]: |
if og not in [ (o["id"], o["probabilidad"]) for o in self.objetos ]: |
522 |
self.objetos.append(objeto_guardado) |
self.objetos.append(objeto_guardado) |
523 |
|
|
524 |
|
|
525 |
def entrar_personaje(self, personaje): |
def entrar_personaje(self, personaje): |
526 |
"""Método llamado cuando un personaje entra en la sala. |
"""Método llamado cuando un personaje entra en la sala. |
527 |
|
|
528 |
Requiere: |
Requiere: |
529 |
personaje != None |
personaje != None |
530 |
personaje not in self.personajes.values() |
personaje not in self.personajes.values() |
531 |
personaje.sala == self |
personaje.sala == self |
532 |
self.volumen_ocupado() + personaje.volumen_total() <= self.volumen |
self.volumen_ocupado() + personaje.volumen_total() <= self.volumen |
533 |
|
|
534 |
Asegura: |
Asegura: |
535 |
personaje in self.personajes.values() |
personaje in self.personajes.values() |
536 |
""" |
""" |
537 |
|
|
538 |
# Actualizar la lista |
# Actualizar la lista |
539 |
self.personajes[personaje.id] = personaje |
self.personajes[personaje.id] = personaje |
540 |
|
|
541 |
# Actualizar el contador de PJs |
# Actualizar el contador de PJs |
542 |
from personajejugador import PersonajeJugador |
from personajejugador import PersonajeJugador |
543 |
if isinstance(personaje, PersonajeJugador): |
if isinstance(personaje, PersonajeJugador): |
544 |
self.n_jugadores += 1 |
self.n_jugadores += 1 |
545 |
|
|
546 |
# Ver si aparecen o desaparecen objetos |
# Ver si aparecen o desaparecen objetos |
547 |
for objeto in self.objetos: |
for objeto in self.objetos: |
548 |
if objeto["probabilidad"] > 0: |
if objeto["probabilidad"] > 0: |
549 |
if tirar_porcentaje() <= objeto["probabilidad"]: |
if tirar_porcentaje() <= objeto["probabilidad"]: |
550 |
if tirar_porcentaje() <= 50: |
if tirar_porcentaje() <= 50: |
551 |
if len(objeto["instancias"]) > 0: |
if len(objeto["instancias"]) > 0: |
552 |
del objeto["instancias"][0] |
del objeto["instancias"][0] |
553 |
else: |
else: |
554 |
if (objeto["maximo"] == 0 or |
if (objeto["maximo"] == 0 or |
555 |
len(objeto["instancias"]) < objeto["maximo"]): |
len(objeto["instancias"]) < objeto["maximo"]): |
556 |
objeto["instancias"].append(Objeto(objeto["id"])) |
objeto["instancias"].append(Objeto(objeto["id"])) |
557 |
|
|
558 |
|
|
559 |
def salir_personaje(self, personaje): |
def salir_personaje(self, personaje): |
560 |
"""Método llamado cuando un personaje sale de la sala. |
"""Método llamado cuando un personaje sale de la sala. |
561 |
|
|
562 |
Requiere: |
Requiere: |
563 |
personaje != None |
personaje != None |
564 |
personaje in self.personajes.values() |
personaje in self.personajes.values() |
565 |
|
|
566 |
Asegura: |
Asegura: |
567 |
personaje not in self.personajes.values() |
personaje not in self.personajes.values() |
568 |
""" |
""" |
569 |
|
|
570 |
#print "TRAZA-> Sala[" + self.id + "].salir_personaje(" + personaje.id + ")" |
#print "TRAZA-> Sala[" + self.id + "].salir_personaje(" + personaje.id + ")" |
571 |
|
|
572 |
# Actualizar la lista |
# Actualizar la lista |
573 |
del self.personajes[personaje.id] |
del self.personajes[personaje.id] |
574 |
|
|
575 |
# Actualizar el contador de PJs |
# Actualizar el contador de PJs |
576 |
from personajejugador import PersonajeJugador |
from personajejugador import PersonajeJugador |
577 |
if isinstance(personaje, PersonajeJugador): |
if isinstance(personaje, PersonajeJugador): |
578 |
self.n_jugadores -= 1 |
self.n_jugadores -= 1 |
579 |
|
|
580 |
|
|
581 |
def volumen_ocupado(self): |
def volumen_ocupado(self): |
582 |
"""El total de volumen que ocupa toda la gente y objetos que hay dentro. |
"""El total de volumen que ocupa toda la gente y objetos que hay dentro. |
583 |
Asegura: |
Asegura: |
584 |
return > 0.0 |
return > 0.0 |
585 |
return <= self.volumen |
return <= self.volumen |
586 |
""" |
""" |
587 |
ocupado = 0.0 |
ocupado = 0.0 |
588 |
for personaje in self.personajes.values(): |
for personaje in self.personajes.values(): |
589 |
ocupado += personaje.volumen_total() |
ocupado += personaje.volumen_total() |
590 |
|
|
591 |
for objeto in self.objetos: |
for objeto in self.objetos: |
592 |
for instancia in objeto["instancias"]: |
for instancia in objeto["instancias"]: |
593 |
ocupado += instancia.volumen() |
ocupado += instancia.volumen() |
594 |
|
|
595 |
return ocupado |
return ocupado |
596 |
|
|
597 |
|
|
598 |
def coger_objeto(self, n_objeto, n_instancia): |
def coger_objeto(self, n_objeto, n_instancia): |
599 |
"""Sacar una instancia de un objeto de la sala. |
"""Sacar una instancia de un objeto de la sala. |
600 |
|
|
601 |
n_objeto es el numero de orden dentro de los objetos de la sala, y n_instancia |
n_objeto es el numero de orden dentro de los objetos de la sala, y n_instancia |
602 |
es el numero de la instancia, ambos empezando por cero. |
es el numero de la instancia, ambos empezando por cero. |
603 |
|
|
604 |
Devuelve una instancia de clase Objeto. |
Devuelve una instancia de clase Objeto. |
605 |
|
|
606 |
Requiere: |
Requiere: |
607 |
n_objeto in range(0, len(self.objetos)-1) |
n_objeto in range(0, len(self.objetos)-1) |
608 |
n_instancia in range(0, len(self.objetos[n_objeto]["instancias"])-1) |
n_instancia in range(0, len(self.objetos[n_objeto]["instancias"])-1) |
609 |
|
|
610 |
Asegura: |
Asegura: |
611 |
return != None |
return != None |
612 |
""" |
""" |
613 |
objeto = self.objetos[n_objeto] |
objeto = self.objetos[n_objeto] |
614 |
|
|
615 |
instancia = objeto["instancias"][n_instancia] |
instancia = objeto["instancias"][n_instancia] |
616 |
|
|
617 |
del objeto["instancias"][n_instancia] |
del objeto["instancias"][n_instancia] |
618 |
if len(objeto["instancias"]) == 0 and objeto["probabilidad"] == 0: |
if len(objeto["instancias"]) == 0 and objeto["probabilidad"] == 0: |
619 |
del self.objetos[n_objeto] |
del self.objetos[n_objeto] |
620 |
|
|
621 |
instancia.activar() |
instancia.activar() |
622 |
|
|
623 |
return instancia |
return instancia |
624 |
|
|
625 |
|
|
626 |
def dejar_objeto(self, instancia, dificultad = 0): |
def dejar_objeto(self, instancia, dificultad = 0): |
627 |
"""Soltar un objeto en la sala. |
"""Soltar un objeto en la sala. |
628 |
|
|
629 |
instancia es de clase Objeto. Si ya habia mas instancias con el mismo id en la sala, |
instancia es de clase Objeto. Si ya habia mas instancias con el mismo id en la sala, |
630 |
se añade a la lista, y si no, se crea un item nuevo en self.objetos. |
se añade a la lista, y si no, se crea un item nuevo en self.objetos. |
631 |
|
|
632 |
Requiere: |
Requiere: |
633 |
instancia != None |
instancia != None |
634 |
dificultad in range(0, 100) |
dificultad in range(0, 100) |
635 |
""" |
""" |
636 |
encontrado = 0 |
encontrado = 0 |
637 |
|
|
638 |
for objeto in self.objetos: |
for objeto in self.objetos: |
639 |
if objeto["id"] == instancia.id(): |
if objeto["id"] == instancia.id(): |
640 |
encontrado = 1 |
encontrado = 1 |
641 |
objeto["instancias"].append(instancia) |
objeto["instancias"].append(instancia) |
642 |
break |
break |
643 |
|
|
644 |
if not encontrado: |
if not encontrado: |
645 |
self.objetos.append({"id":instancia.id(), |
self.objetos.append({"id":instancia.id(), |
646 |
"probabilidad":0, |
"probabilidad":0, |
647 |
"maximo":0, |
"maximo":0, |
648 |
"dificultad":dificultad, |
"dificultad":dificultad, |
649 |
"instancias":[instancia]}) |
"instancias":[instancia]}) |
650 |
|
|
651 |
|
|
652 |
def salida_cerrada(self, id_sala_destino): |
def salida_cerrada(self, id_sala_destino): |
653 |
"""Comprueba si la salida indicada, y si lo está devuelve el id de la llave, |
"""Comprueba si la salida indicada, y si lo está devuelve el id de la llave, |
654 |
y el mensaje a mostrar si no se puede entrar. |
y el mensaje a mostrar si no se puede entrar. |
655 |
|
|
656 |
Requiere: |
Requiere: |
657 |
id_sala_destino apunta a una salida que existe en la sala. |
id_sala_destino apunta a una salida que existe en la sala. |
658 |
|
|
659 |
Devuelve: |
Devuelve: |
660 |
una tupla (id_llave, mensaje_error). La id_llave vale None si la puerta está |
una tupla (id_llave, mensaje_error). La id_llave vale None si la puerta está |
661 |
abierta, y "" si no se puede abrir. |
abierta, y "" si no se puede abrir. |
662 |
""" |
""" |
663 |
for salida in self.salidas: |
for salida in self.salidas: |
664 |
if salida["id"] == id_sala_destino: |
if salida["id"] == id_sala_destino: |
665 |
|
|
666 |
tipo_cierre = salida["tipo_cierre"] |
tipo_cierre = salida["tipo_cierre"] |
667 |
if tipo_cierre == "ninguno": |
if tipo_cierre == "ninguno": |
668 |
|
|
669 |
return (None, "") |
return (None, "") |
670 |
|
|
671 |
elif tipo_cierre == "cerradura": |
elif tipo_cierre == "cerradura": |
672 |
|
|
673 |
return (salida["datos_cierre"], salida["mensaje_cerrado"]) |
return (salida["datos_cierre"], salida["mensaje_cerrado"]) |
674 |
|
|
675 |
elif tipo_cierre == "magia": |
elif tipo_cierre == "magia": |
676 |
|
|
677 |
return ("", salida["mensaje_cerrado"]) |
return ("", salida["mensaje_cerrado"]) |
678 |
|
|
679 |
elif tipo_cierre == "horario": |
elif tipo_cierre == "horario": |
680 |
|
|
681 |
# Vamos a procesar el argumento horario, que está en la forma |
# Vamos a procesar el argumento horario, que está en la forma |
682 |
# "horaini-horafin,horaini-horafin,... idllave" |
# "horaini-horafin,horaini-horafin,... idllave" |
683 |
|
|
684 |
# Primero, separar el id de la llave |
# Primero, separar el id de la llave |
685 |
aux = salida["datos_cierre"].split(" ") |
aux = salida["datos_cierre"].split(" ") |
686 |
rangos = aux[0].split(",") |
rangos = aux[0].split(",") |
687 |
if len(aux) > 1: |
if len(aux) > 1: |
688 |
id_llave = aux[1] |
id_llave = aux[1] |
689 |
else: |
else: |
690 |
id_llave = "" |
id_llave = "" |
691 |
|
|
692 |
# Luego, ver si la hora actual está dentro de alguno de los rangos |
# Luego, ver si la hora actual está dentro de alguno de los rangos |
693 |
abierto = 0 |
abierto = 0 |
694 |
ahora = FechaHoraMine_ahora() |
ahora = FechaHoraMine_ahora() |
695 |
for rango in rangos: |
for rango in rangos: |
696 |
aux = rango.split("-") |
aux = rango.split("-") |
697 |
hora_ini = int(aux[0]) |
hora_ini = int(aux[0]) |
698 |
hora_fin = int(aux[1]) |
hora_fin = int(aux[1]) |
699 |
if ahora.hora() >= hora_ini and ahora.hora() < hora_fin: |
if ahora.hora() >= hora_ini and ahora.hora() < hora_fin: |
700 |
abierto = 1 |
abierto = 1 |
701 |
break |
break |
702 |
|
|
703 |
if abierto: |
if abierto: |
704 |
return (None, "") |
return (None, "") |
705 |
else: |
else: |
706 |
return (id_llave, salida["mensaje_cerrado"]) |
return (id_llave, salida["mensaje_cerrado"]) |
707 |
|
|
708 |
|
|
709 |
def salvar(self): |
def salvar(self): |
710 |
"""Graba en un fichero de salas la sala con todo su contenido.""" |
"""Graba en un fichero de salas la sala con todo su contenido.""" |
711 |
|
|
712 |
#print "TRAZA-> Sala[" + self.id + "].salvar()" |
#print "TRAZA-> Sala[" + self.id + "].salvar()" |
713 |
|
|
714 |
fichero = open(os.path.join(Sala.DIR_SALAS, self.id + Sala.EXT_SALAS), 'w') |
fichero = open(os.path.join(Sala.DIR_SALAS, self.id + Sala.EXT_SALAS), 'w') |
715 |
cPickle.dump(self, fichero) |
cPickle.dump(self, fichero) |
716 |
fichero.close() |
fichero.close() |
717 |
|
|
718 |
|
|
719 |
def __setstate__(self, atributos): |
def __setstate__(self, atributos): |
720 |
"""Método llamado para restaurar los atributos provinientes de un |
"""Método llamado para restaurar los atributos provinientes de un |
721 |
pickle.""" |
pickle.""" |
722 |
|
|
723 |
self.__dict__ = atributos |
self.__dict__ = atributos |
724 |
|
|
725 |
# Verificar la versión. |
# Verificar la versión. |
726 |
if not self.__dict__.has_key("version"): |
if not self.__dict__.has_key("version"): |
727 |
raise ValueError("Cargada sala " + self.id + " obsoleta: sin versión" + |
raise ValueError("Cargada sala " + self.id + " obsoleta: sin versión" + |
728 |
" cuando se esperaba " + Sala.VERSION_SALA) |
" cuando se esperaba " + Sala.VERSION_SALA) |
729 |
|
|
730 |
assert(Sala.VERSION_SALA == "1.2") |
assert(Sala.VERSION_SALA == "1.2") |
731 |
while self.version != "1.2": |
while self.version != "1.2": |
732 |
|
|
733 |
if self.version == "1.0": |
if self.version == "1.0": |
734 |
# Versión 1.0 -> 1.1: añadir fecha de modificacion de archivo de descripcion |
# Versión 1.0 -> 1.1: añadir fecha de modificacion de archivo de descripcion |
735 |
archivo = os.path.join(Sala.DIR_DESC_SALAS, self.id + Sala.EXT_DESC_SALAS) |
archivo = os.path.join(Sala.DIR_DESC_SALAS, self.id + Sala.EXT_DESC_SALAS) |
736 |
self.__fecha_fichero = os.path.getmtime(archivo) |
self.__fecha_fichero = os.path.getmtime(archivo) |
737 |
self.version = "1.1" |
self.version = "1.1" |
738 |
escribir("Convertida sala " + self.id + " a versión 1.1") |
escribir("Convertida sala " + self.id + " a versión 1.1") |
739 |
elif self.version == "1.1": |
elif self.version == "1.1": |
740 |
# Versión 1.1 -> 1.2: cambiar horario y error por tipo_cierre, datos_cierre |
# Versión 1.1 -> 1.2: cambiar horario y error por tipo_cierre, datos_cierre |
741 |
# y mensaje_cerrado |
# y mensaje_cerrado |
742 |
for salida in self.salidas: |
for salida in self.salidas: |
743 |
horario = salida["horario"] |
horario = salida["horario"] |
744 |
error = salida["error"] |
error = salida["error"] |
745 |
del salida["horario"] |
del salida["horario"] |
746 |
del salida["error"] |
del salida["error"] |
747 |
if horario == "0-24": |
if horario == "0-24": |
748 |
salida["tipo_cierre"] = "ninguno" |
salida["tipo_cierre"] = "ninguno" |
749 |
salida["datos_cierre"] = "" |
salida["datos_cierre"] = "" |
750 |
salida["mensaje_cerrado"] = "" |
salida["mensaje_cerrado"] = "" |
751 |
else: |
else: |
752 |
salida["tipo_cierre"] = "horario" |
salida["tipo_cierre"] = "horario" |
753 |
salida["datos_cierre"] = horario |
salida["datos_cierre"] = horario |
754 |
salida["mensaje_cerrado"] = mensaje_cerrado |
salida["mensaje_cerrado"] = mensaje_cerrado |
755 |
self.version = "1.2" |
self.version = "1.2" |
756 |
escribir("Convertida sala " + self.id + " a versión 1.2") |
escribir("Convertida sala " + self.id + " a versión 1.2") |
757 |
else: |
else: |
758 |
raise ValueError("Cargada sala " + self.id + " con versión desconocida: " + |
raise ValueError("Cargada sala " + self.id + " con versión desconocida: " + |
759 |
self.version + " cuando se esperaba " + Sala.VERSION_SALA) |
self.version + " cuando se esperaba " + Sala.VERSION_SALA) |
760 |
|
|
761 |
|
|
762 |
# 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, |
763 |
# y no de instancia |
# y no de instancia |
764 |
|
|
765 |
|
|
766 |
def Sala_cargar(id): |
def Sala_cargar(id): |
767 |
"""Recupera una sala desde un fichero de salas. |
"""Recupera una sala desde un fichero de salas. |
768 |
|
|
769 |
Requiere: |
Requiere: |
770 |
id != None |
id != None |
771 |
id corresponde con un fichero existente |
id corresponde con un fichero existente |
772 |
|
|
773 |
Asegura: |
Asegura: |
774 |
return != None |
return != None |
775 |
""" |
""" |
776 |
|
|
777 |
#print "TRAZA-> Sala.cargar(" + id + ")" |
#print "TRAZA-> Sala.cargar(" + id + ")" |
778 |
|
|
779 |
fichero = open(os.path.join(Sala.DIR_SALAS, id + Sala.EXT_SALAS), 'r') |
fichero = open(os.path.join(Sala.DIR_SALAS, id + Sala.EXT_SALAS), 'r') |
780 |
sala = cPickle.load(fichero) |
sala = cPickle.load(fichero) |
781 |
fichero.close() |
fichero.close() |
782 |
|
|
783 |
return sala |
return sala |
784 |
|
|
785 |
|
|
786 |
# Código para pruebas unitarias del módulo. |
# Código para pruebas unitarias del módulo. |
787 |
|
|
788 |
if (__name__ == '__main__'): |
if (__name__ == '__main__'): |
789 |
print "No hay prueba unitaria de módulo. prueba con salatester.py" |
print "No hay prueba unitaria de módulo. prueba con salatester.py" |