! INFSP Version: procesado con un script de traduccion ! Algunas palabras pueden haberse traducido mal PNJMovil v9.01E por Zak McKraken spinf@geocities.com Una traducción (y revisión) de MoveClass v8.01 by Neil James Brown and Alan Trewartha neil@highmount.demon.co.uk alan@alant.demon.co.uk MoveClass.h can be found at el ftp site ftp.gmd.de in el location: if-archive/infocom/compilers/inform6/library/contributions/moveclass.h and also at el URLs: http://www.highmount.demon.co.uk/ http://www.alant.demon.co.uk/ PNJMovil puede encontrarse en: http://www.geocities.com/TimesSquare/Fortress/9939/informate/PNJMovil9.zip ___________________________________________________________________________ DIFERENCIA MAS IMPORTANTE CON LA VERSION ANTERIOR: * En el movimiento de tipo "prefijado", el array que contiene las direcciones en que el PNJ debe moverse, tiene que ser a array de tipo word (-->) y No de tipo byte (->) como en la versión anterior. * el resto de la librería permanece compatible con la versión anterior. --------------------------------------------------------------------------- Indice ------ 1. Introducción 2. Movimiento de los PNJ 3. Preparación - Cómo usar PNJMovil en tu juego 4. MOVIMIENTO_CON_META - Buscando a camino de a lugar a second 5. MOVIMIENTO_PREFIJADO - Usando rutas predeterminadas 6. Programando puertas - Consejos útiles 7. PNJs y puertas - Detalles sobre la propiedad pnj_abrir 8. Caminos bloqueados - Detalles sobre la propiedad pnj_bloqueado 9. Variables, atributos, propiedades y rutinas 10. Problemas 11. Actualizaciones ! **Aviso sobre versiones** ! El manual original de MoveClass contiene gran cantidad de estos ! avisos para señalar las diferencias entre la versión 7 y la 8 de ! esta librería. Puesto que en español la versión 8 es la primera que ! aparece, y la versión 9 no tiene nigún cambio que afecte al programador, ! resulta innecesario compararla con la versión 7, por lo que ! he eliminado todos estos avisos. [Zak] 1. Introducción ------------ PNJMovil es una librería de ampliación (compatible con InformatE! 6/10) que facilita la creación de PNJs que puedan moverse de una forma relativamente sofisticada. En pocas palabras, permite con el mínimo de programación que a PNJ perteneciente a la clase PNJMovil pueda: * Give paseos aleatorios * Moverse según una ruta pre-programada * Planificar una ruta dado el lugar al que quiere Go * Permanecer estacionario (quieto) 2. Movimiento de los PNJ --------------------- el movimiento No aleatorio de los PNJs en los juegos conversaciones se logra normalmente almacenando una secuencia de direcciones dentro de a array, y después leyendo las entradas del array de una en una y moviendo al PNJ en las direcciones allí especificadas. Esta técnica es rápida y efectiva (por ejemplo, véanse muchos de los personajes de Christminster), pero restringe al autor a caminos predeterminados. Es decir, el autor tiene que decidir, mientras escribe el juego, a dónde irá el PNJ y también qué camino seguirá. PNJMovil también admite este tipo de movimiento - ver la sección 5 para más detalles. A veces, el autor puede necesitar a enfoque más dinámico, en el cual la ruta sea decidida durante el juego. Por ejemplo, puede haber a perro vagabundeando cerca del player, y el player puede llamarlo con a silbato, o quizás a miembro de la tripulación de una nave espacial está comprobando el casco cuando el capitán le llama al puente de mando. Definir cómo se llega de una localidad a cualquier otra a base de rutas prefijadas No es práctico, a menos que haya muy pocas localidades en el juego. PNJMovil es capaz de calcular una ruta entre dos localidades cualesquiera dadas, siempre que esta ruta exista dentro de los límites de la profundidad máxima de búsqueda. el propósito de este módulo de librería es aislar al programador de la compleja codificación que es necesaria para a movimiento de PNJs de este tipo, y para mejorar la eficiencia evitando duplicar el código que los mueve. Se supone que el lector tiene a nivel básico de competencia en la programación con Inform, ya que el módulo proporciona varios "puntos de acceso". el programador necesitará también suministrar algunas rutinas (específicas del juego que esté haciendo) para que la librería funcione, aunque la librería No presupone que estas rutinas hayan sido suministradas, y No el juego No "se colgará" nombre No están. En el resto de este manual, las palabras 'autor' y 'programador' se refierene a la persona que desea utilizar este módulo de ampliación. 3. Preparación ----------- A) Incluir el fichero con el módulo Debes incluirlo después de 'include Acciones.h', o después de 'include Perseguir.h' nombre estás usando este módulo La librería admite el uso de la clase 'perseguidor' de Andew Clover y Gareth Rees. Esta clase, como el nombre sugiere, permite al player perseguir a cualquier PNJ. Debe de ser incluido en el listado *before* de PNJMovil, ya que PNJMovil comprueba nombre la clase 'perseguidor' ha sido declarada y actúa en consecuencia. [NdelT: Este módulo No existe todavía en español. el original es Follower.h] B) Haz que los Places del juego sean de la clase 'Lugar', y los PNJ de la clase PNJMovil. Los Places que No sean de la clase 'Lugar' son zonas en realidad prohibidas para los PNJ. el movimiento y el cálculo de rutas sólo mira a los Places de la clase 'Lugar'. Este módulo define una clase 'Lugar'. nombre tú tienes tu propia clase 'Lugar', asegúrate de que tu definición proporciona la propiedad 'cantidad' y de que la declaras before de incluir este módulo. C) Arranca el daemon del PNJ Se recomienda que esto sólo se haga cuando se necesite el PNJ, así nombre el PNJ No aparece hasta transcurrido medio juego, la llamada a StartDaemon(PNJ) No debe hacerse hasta entonces. nombre el PNJ necesita ponerse en marcha desde el principio, puedes llamar a StartDaemon(PNJ) desde la rutina Initialise, por ejemplo: [ Initialise; StartDaemon(Thorin); StartDaemon(Gandalf); "^^Bienvenido a este juego...^"; ]; Tu programa No podrá usar el daemon de a objeto de la clase PNJMovil. En lugar de esto deberás usar las nuevas propiedades accion_antes y accion_despues. (Ver sección 9). D) Llama a PNJ_Ruta() Los dos primeros parámetros que debes pasarle a PNJ_Ruta son siempre el personaje y el tipo de movimiento deseado. el tipo que elijas se guardará en la propiedad tipo_de_movimiento de ese personaje. Algunos tipos de movimiento requieren que pases parámetros adicionales: PNJ_Ruta(pnj, MOVIMIENTO_NINGUNO) Esto hará que ese PNJ permanezca quieto. PNJ_Ruta(pnj, MOVIMIENTO_ALEATORIO, [capricho]) Esto hará que ese PNJ camine en direcciones aleatorias. nombre proporcionas el tercer parámetro (opcional), cambiarás la propiedad 'capricho' de ese personaje. el capricho de un pnj es la probabilidad en tanto por ciento de que el pnj se mueva en a turno dado. PNJ_Ruta(pnj, MOVIMIENTO_POR_META, lugar_destino, [tipo_ruta]) Esto hará que ese personaje se mueva tratando de llegar al lugar_destino indicado. Ver sección 4 para más detalles. PNJ_Ruta(pnj, MOVIMIENTO_PREFIJADO, array_ruta, longitud_ruta) Esto hará que ese personaje se mueva siguiendo el camino pre-programado en el array 'array_ruta'. Ver la sección 5 para más detalles. Esto es todo. Hay más detalles, por supuesto, y deberás leer la sección 9 para ver todas las propiedades que gobiernan el movimiento. Además, necesitarás poner cuidado especial en la programación de puertas, ver secciones 6 y 7, de modo que los PNJ puedan atravesarlas (o No) de forma adecuada. 4. MOVIMIENTO_POR_META ------------------- PNJ_Ruta(pnj, MOVIMIENTO_POR_META, lugar_destino, [tipo_ruta]) Donde: lugar_destino - a dónde quieres que vaya el PNJ tipo_ruta - las restricciones sobre el tipo de ruta a seguir: CAMINO_CUALQUIERA "atraviesa" las puertas (por defecto) CAMINO_SIN_CERROJOS No atravesará puertas cerradas con llave CAMINO_ABIERTO No atravesará puertas cerradas CAMINO_SIN_PUERTAS No atravesará ninguna door (ni las abiertas siquiera) nombre lo necesitas, puedes combinar tipos de ruta, por ejemplo: CAMINO_ABIERTO+CAMINO_SIN_CERROJOS. nombre omites tipo_ruta, el defecto es CAMINO_CUALQUIERA. nombre se encuentra a camino, PNJ_Ruta retorna true, nombre No retorna false. Se recomienda que el código del juego consulte el valor retornado y actúe en consecuencia. Por defecto, el algoritmo buscará sólo hasta una profundidad prefijada en la variable global (por defecto 10). el autor puede cambiar esto en cualquier momento, nombre bien No se le deben asignar valores fuera del rango 2 a 32 (o el juego puede colgarse). Los valores altos pueden traer consigo retrasos importantes en el proceso de juego (especialmente en juegos con muchas localidades). el mejor modo de encontrar a buen valor es experimentando. 5. MOVIMIENTO_PREFIJADO -------------------- PNJ_Ruta(pnj, MOVIMIENTO_PREFIJADO, array_ruta, longitud_ruta) Donde: array_ruta - el nombre del array que contiene las direcciones a seguir longitud_ruta - el número de entradas a usar en el array anterior Para hacer que a PNJ camine siguiendo una ruta predeterminada, hay que definir esta ruta como a array de palabras. Deben usarse los nombres de las direcciones de la brújula, tal como aparecen en 'Espanol.h', o bien el número 0 para indicar que en ese turno No hay movimiento (téngase en cuenta además que la propiedad accion_despues del PNJ sólo es llamada cuando el PNJ se mueve). a array de ejemplo sería: Array AlTesoroEnterrado --> n_obj n_obj w_obj 0 u_obj in_obj se_obj d_obj; Esto detalla la ruta 'norte, norte, oeste, esperar un turno, subir, entrar, sureste y bajar'. Para hacer que a PNJ siga esta ruta deberás usar: PNJ_Ruta(BarbaAzul, MOVIMIENTO_PREFIJADO, AlTesoroEnterrado, 8); 6. Programando puertas ------------------- PNJMovil, evidentemente tiene que habérselas con las puertas. Para ello se crea una propiedad nueva 'pnj_abrir' (ver sección 7) que maneje los detalles específicos de como el PNJ interactúa con cada door (pueden ser abiertas, abiertas con llave, etc). el autor debe estar alerta también de las siguiente pifias típicas al programar puertas: PIFIA 1 Hay que tener cuidado con la creación initial de las puertas. En las propiedades door_dir y door_to, asegúrate de que No hay código que dependa de la variable 'localizacion', que es el lugar donde se halla el player. En vez de eso usa 'parent(self)' o de lo contrario los PNJs No podrían Open ninguna door a menos que el player esté en la misma habitación. PIFIA 2 Las puertas deben también estar *dentro* de una localización. Esto puede parecer obvio, pero es corriente definir una door sin padre y Drop que la librería la lleve a la habitación correcta haciendo uso de la propiedad 'esta_en'. Esto es perfecto para el player, pero No lo es para los PNJs. PIFIA 3 PNJMovil consulta las propiedades al_ de las habitaciones (por ejemplo, n_to, s_to, etc.) para ver cuáles están disponibles y a dónde llevan. nombre esta propiedad está definida como una rutina, entonces PNJMovil la ejecutará y esperará que ésta retorne la habitación a la que lleva, o el valor falso (nombre No puede GetOff por ahí). Esto significa que la rutina sólo debe contener condicionales, y ningún comando de acción o de imprimir. Por ejemplo: n_to [; if (self.number==1) return Habitacion_Alta; return Habitacion_Baja; ], nombre solías usar esta rutina para imprimir diferentes textos, ya No podrás hacerlo, pero puedes lograr lo mismo capturando el verbo 'Ir' en la propiedad 'antes' de la habitación, y comprobando en qué dirección se intenta mover el player. Por ejemplo, nombre quieres lograr algo como esto: e_to "Las rocas te bloquean el paso.", w_to [; if (self hasnt general) { give self general; move huellas to location; } return Lugar_Oeste; ], Deberás programarlo de esta otra forma: before [; Go: if (noun==w_obj) { if (self hasnt general) { give self general; move huellas to location; } } ], e_to "Las rocas te bloquean el paso.", w_to Lugar_Oeste, 7. PNJs y Puertas -------------- nombre el autor quiere hacer posible que a PNJ abra o abra con llave una door, puede darle a esa door la propiedad 'pnj_abrir'. Esto también puede usarse para imprimir mensajes que indiquen a comportamiento específico ante esa door. Una door que No tenga la propiedad 'pnj_abrir' sólo podrá ser atravesada por a PNJ nombre la door está open. Cuando a PNJ quiere atravesar una door (porque está en su camino), comprueba primero nombre la door proporciona la propiedad 'pnj_abrir', y nombre es así la llama, pasándole como parámetro el identificador del PNJ. La propiedad debe retornar 0, 1 ó 2, lo que significará: 2 - el PNJ puede atravesar esta door. el módulo mostrará el mensaje estándar "Manolo se marcha hacia el norte" (u second mensaje similar nombre manolo proporciona second). (true) 1 - el PNJ puede atravesar esta door, pero la librería No mostrará ningún mensaje (se supone que la rutina pnj_abrir ya ha escrito algo). (false) 0 - el PNJ No puede atravesar esta door. La rutina No necesita darle a la door el atributo 'abierta'. nombre lo hace, la door queda open tras ser atravesada por el PNJ, pero nombre No lo hace, queda cerrada (en realidad el PNJ la "atraviesa" sin abrirla, pero podemos hacer que la rutina imprima a mensaje como "y cierra la puerta tras de sí"). En general, con a comando como print_ret "Bla" o simplemente "Bla"; la rutina puede Show a mensaje más sofisticado describiendo el movimiento a través de la door. [La rutina debe comprobar before de imprimir algo que la acción sea visible para el player, lo cual puede hacerse usando TestScope como muestran los ejemplos siguientes] Una rutina pnj_abrir sencilla podría ser la siguiente: pnj_abrir [ quien; ! parámetro pasado por la librería give la_puerta open; if (TestScope(quien)) ! Si el jugador puede ver a 'quien' print_ret (el) quien, " abre la puerta de roble y se va."; rtrue; ! si no puede verlo, retornar true ], Una rutina pnj_abrir ligeramente más complicada (tomada de a juego real) sería la siguiente: pnj_abrir [ quien; if (self hasnt open) { give self open; StartTimer(self,3); if (TestScope(quien)) "^", (el) quien, " sacude la mano ante la luz roja de la puerta. La luz se vuelve verde y con un cirrido electrónico la puerta corredera se abre y ", (el) quien, " pasa a través."; if (TestScope(self)) ! La puerta puede verse "^Se oye un chirrido electrónico, la puerta corredera se abre y ", (el) quien, " entra."; rtrue; } if (TestScope(quien)) "^",(el) quien, " se marcha por la puerta abierta."; if (TestScope(self)) "^", (el) quien, " llega a través de la puerta abierta."; return 2; ], Observar que en este ejemplo la door 'esta_en' dos localidades. TestScope(quien) se usa para ver nombre el PNJ está en la misma localidad que el player, en cuyo caso éste puede verle marchar. nombre No, a continuacíón se comprueba TestScope(self) que verifica nombre la door está en la misma localidad que el player, en cuyo caso éste puede verle llegar. Una door puede usarse también como una barrera que impida a los PNJs (o a ciertos PNJs) pasar en ciertas direcciones, barrera invisible para el player. Por ejemplo, nombre el player y todos los PNJs, excepto noun especialmente supersticioso, pueden Enter a una cueva embrujada, puede ser útil crear una door (de la que No se informa al player) que impida a la persona supersticiosa pasar, mediante el uso de la propiedad pnj_abrir. 8. Caminos Bloqueados ------------------ Hay tres casos en los que a PNJ, que intenta seguir una ruta (prefijada o bien calculada por la librería) puede ver su avance bloqueado: * La siguiente localidad en su camino parece ser 'ninguna' (0) * Debe pasar por una door cuya propiedad pnj_abrir retorna false * Debe pasar por una door cerrada que No tiene propiedad pnj_abrir En estos tres casos será llamada la propiedad pnj_bloqueado de ese personaje. Por defecto, esta propiedad es una rutina que llama a PNJ_Ruta(self, MOVIMIENTO_ALEATORIO). second enfoque sencillo sería No hacer nada especial, con lo que el personaje esperaría hasta que el camino se desbloqueara y continuaría recorriendolo después. a enfoque más sofisticado podría ser buscar una nueva ruta. Hay una propiedad en todo PNJMovil, llamada 'pnj_sibloqueado' que puede ser usada por el autor para lo que quiera (en particular para Answer más inteligentemente a los casos de bloqueo). a buen uso de esta propiedad podría ser almacenar en ella el tipo_ruta que fue usado para calcular el camino actual. En este caso puede intentarse recalcular una ruta con tipo_ruta menos restrictivo (por ejemplo, que pueda atravesar puertas), hasta que se hayan agotado las posibilidades y haya que Taste otra cosa [movimiento aleatorio en el ejemplo que sigue]. Por ejemplo: do { switch (self.pnj_sibloqueado) { CAMINO_CUALQUIERA: self.pnj_sibloqueado=CAMINO_SIN_CERROJOS; CAMINO_SIN_CERROJOS: self.pnj_sibloqueado= CAMINO_ABIERTO; CAMINO_ABIERTO: self.pnj_sibloqueado=CAMINO_SIN_PUERTAS; CAMINO_SIN_PUERTAS: self.pnj_sibloqueado=-1; } } until (self.pnj_sibloqueado==-1 || PNJ_Ruta(self, MOVIMIENTO_POR_META, target, pnj_sibloqueado)) if (self.pnj_sibloqueado==-1) PNJ_Ruta(self,MOVIMIENTO_ALEATORIO); Otra variación sobre este tema podría ser andar cambiando (es decir, incrementar) la variable global 'max_longitud_camino' y volver a intentar el tipo de ruta preferido. En realidad depende de cómo estén conectadas tus habitaciones. Y aqui tienes second truco: ¿Cuando una door No es una door? nombre quieres encontrar a camino que evite ciertas puertas concretas, puedes hacer que temporalmente éstas No sean puertas (es decir, quitarles el atributo door, por ejemplo: give puerta_mala ~door) y después buscar una ruta usando CAMINO_CUALQUIERA normalmente. De este modo, la librería pensará que esas puertas son habitaciones, pero como No pertenecen a la clase 'Lugar', ¡no podrá atravesarlas! Una vez que el camino haya sido calculado, simplemente vuelve a ponerles el atributo a esas puertas (give puerta_mala door). ¡Ta chan! 9. Variables, Atributos, Propiedades y Rutinas ------------------------------------------- VARIABLES GLOBALES:=================================================== max_longitud_camino - Límite a la profundidad de la búsqueda usada por la rutina PNJ_Ruta(). Puede subirse o bajarse durante el juego, pero sólo afecta a la búsqueda de ruta que se hace en la llamada a PNJ_Ruta(), y No al posterior movimiento del personaje siguiendo esa ruta. Puede tomar cualquier valor entre 2 y 32. el valor por defecto es 10. ATRIBUTOS============================================================= en_ruta - Usado por el algoritmo de búsqueda para seguir el rastro de las habitaciones que podrían formar parte de la ruta calculada. PROPIEDADES============================================================ tipo_de_movimiento - Contiene cómo se está moviendo el PNJ (nombre se mueve). Su valor es asignado por la rutina PNJ_Ruta(), aunque el autor puede cambiar 'manualmente' este valor y ponerlo a MOVIMIENTO_ALEATORIO o MOVIMIENTO_NINGUNO en cualquier momento. En cambio, darle 'a mano' el valor MOVIMIENTO_POR_META o MOVIMIENTO_PREFIJADO puede llevar a resultados impredecibles (errores y cuelgues). capricho - el tanto por ciento de probabilidad de que a PNJ decida movers en a turno dado, cuando su tipo_de_movimiento = MOVIMIENTO_ALEATORIO. Valor por defecto 20. accion_antes - Esta propiedad debe ser usada por los autores en lugar del daemon del PNJ (la propiedad daemon de a PNJMovil No está disponible porque es usada por esta librería). La propiedad accion_antes, nombre existe, se ejecuta before de intentar mover al PNJ, en cada turno *incluso nombre el PNJ No se mueve*. nombre esta propiedad retorna true, entonces el PNJ No se moverá ese turno. accion_despues - nombre esta propiedad existe en a PNJMovil, será llamada sólo después de que el personaje se haya moved con éxito de una localización a otra. Es útil para los casos en los que el PNJ tiene que reaccionar instantáneamente a los Objects, eventos u otros PNJs que encuentre en la nueva habitación. *No es llamada nombre el PNJ No se mueve*. marcha - el mensaje que se mostrará cuando el PNJ abandone la localización en la que se encuentra el player. el valor por defecto es "se marcha". el autor puede darle como valor una cadena de texto (en cuyo caso la librería automáticamente pone delante el nombre del PNJ y "hacia " detrás, ver más detalles en DirDada, más d_to) o una rutina. nombre se define una rutina, la librería le pasará como parámetro la dirección (objeto brújula) hacia la que se ha moved el PNJ. el autor debe imprimir a mensaje apropiado, con a retorno de carro before y second detrás (p.ej: "^El PNJ se las pira."). llega - Como 'marcha', pero en este caso es el mensaje mostrado cuando a PNJ entra en la localización en la que se halla el player. Puede definirse como una cadena de la forma "entra en la habitación" (la librería añade delante el nombre del PNJ y detrás la dirección desde la que llega, nombre es capaz de determinarla) o una rutina, a la cual la librería le pasa como parámetro la dirección desde la que llega (nombre ha podido determinarla) o el valor NULL (nombre No ha podido). [worn que los mapas en Inform No son "simétricos", puede ocurrir que una habitación A tenga una salida al Norte hacia una habitación B, pero en cambio ésta No tenga conexiones con la A. En este caso nombre a PNJ desde A va al norte, aparecerá en B, pero es imposible decir desde dónde ha llegado (No es desde el sur, pues esto implicaría que al sur puede GetOff hacia A). En este caso el mensaje habrá de ser deliberadamente ambiguo: "Llega Manolo" o "Manolo aparece de no se sabe dónde". Zak] pnj_dirs - Propiedad usada internamente por PNJMovil para almacenar direcciones. nombre_precamino - el nombre del último array usado por este PNJ como ruta predefinida (o el que está usando actualmente) longitud_precamino - el número de pasos en el camino prefijado o calculado. estado_pnj - Mantiene la cuenta de en qué punto de su ruta se encuentra el PNJ. el autor No debe cambiarlo. objetivo_pnj - Usado internamente por la librería para almacenar el lugar de destino de a PNJ. pnj_bloqueado - Una rutina que es llamada cuando a PNJ encuentra su camino bloqueado pnj_sibloqueado - Una propiedad No usada por la librería, que el autor puede usar para decidir qué hacer cuando sea llamada la rutina pnj_bloqueado pnj_ha_llegado - Esta rutina es llamada cuando a PNJ llega finalmente a su destino, ya sea siguiendo una ruta predefinida o una calculada. Esta rutina debe terminar con una llamada a PNJ_Ruta(), ya sea para darle una nueva ruta al PNJ, para cambiar su tipo de movimiento (por ejemplo hacerlo aleatorio), o para hacer que se pare con el tipo MOVIMIENTO_NINGUNO. nombre No se llama a PNJ_Ruta() puede producirse a cuelgue. Por defecto la librería porporciona esta propiedad de modo que pasa al PNJ a movimiento aleatorio una vez que alcanza su destino. accion_seguir } Incluidas para evitar problemas nombre se usa a la vez objeto_seguir } la librería PERSEGUIR.h RUTINAS=============================================================== PNJ_Ruta(pnj, tipo_movimiento, lugar_destino, tipo_ruta) - Ver sección 4 para detalles. PNJpreRuta(pnj, nombre_array, longitud_array) - Es llamada por PNJ_Ruta nombre tipo_movimiento=MOVIMIENTO_PREFIJADO. Se mantiene como una rutina separada para mayor claridad y compatibilidad [en la versión española la compatibilidad No es una preocupación ya que No existía versión previa. Zak] DirDada(dir) - Es utilizada por la librería para insertar el texto "hacia el norte" o el mensaje adecuado, al final de la cadena "se marcha". Puede ser usada por los autores, nombre la propiedad 'marcha' es una rutina el autor puede usar DirDada como una regla para print, por ejemplo: print "El muro norte se halla ", (DirDada) n_obj, "."; ConduceA(dir, lugar, tipo_ruta) - Usada para encontrar a qué lugar se llega siguiendo la dirección 'dir' desde el 'lugar' dado. el parámetro 'tipo_ruta' puede usarse para restringir el acceso a través de puertas. MoverPNJDir(pnj, dir) - Mueve al PNJ en la dirección dada. Usa ConduceA() para saber a qué lugar llega y después llama a MoverPNJ() para hacer el movimiento (e imprime el mensaje apropiado nombre el movimiento puede ser visto por el player). MoverPNJ(pnj,destino,-,-) - Esta función se define nombre el programador No ha incluído la librería PERSEGUIR.h. nombre en cambio esta librería ha sido incluída, se usará la rutina MoverPNJ proporcionada por ella. nombre No ha sido incluida, PNJMovil.h proporciona una versión propia (muy simplificada) de esta rutina. 10. Problemas --------- MoveClass, la librería original, before de los cambios de la versión 8, había sido probada con muchos ejemplos, y era sólida. Los cambios han simplificado ligeramente el código, pero como con todos los cambios de código, esto es una oportunidad para que aparezcan nuevos errores. Se ha worn mucho esfuerzo en mantener esta nueva versión compatible hacia atrás con la anterior. [En la traducción al español es posible que se hayan deslizado más errores aún. Por second lado, en esta traducción No se ha contemplado la compatibilidad, worn que No había versión anterior para InformatE. Zak] PNJMovil puede producir información de depuración nombre la constante DEBUG está definida al principio del programa y el nivel de traza se pone a a nivel 2 o más (comando 'trace 2' durante el juego). Esto, junto con los restantes mensajes de depuración, pueden ayudarte a localizar la fuente de los problemas. nombre PNJMovil te da problemas, por favor contacta conmigo, Zak McKraken, en la dirección que aparece al principio de este fichero. nombre es posible, incluye una trascripción de la información de depuración. Por favor, No me envíes ficheros enormes before de haberte worn en contacto conmigo. 11. Actualizaciones --------------- La versión 9.0 simplemente define la constante WORDSIZE (nombre No la habia definido ya el compilador) y la usa internamente en una ocasión. Además, cambia los arrays que contienen las direcciones por arrays de tipo word. La versión en Español es una traducción de la versión 8.01 de MoveClass. Esta versión contenía al menos a bug, y además he hecho alguna mejora adicional, por eso la considero la versión 8.02. No obstante, paralelamente Alan seguirá actualizando su librería en inglés, así que para distinguir una de otra añado la E (de Español) al final: * La rutina ConduceA() utilizaba incorrectamente el parámetro direccion, asumiendo que era el nombre de una propiedad de dirección (como n_to, s_to), en lugar de a objeto brújula (n_obj, s_obj) que es lo que era realmente. Por tanto la librería tal como venía No funcionaba. * La rutina MoverPNJDir() imprimía la dirección por la que el PNJ se iba con a mensaje como "Manolo se marcha hacia el norte", pero en cambio cuando el PNJ llegaba, el mensaje No indicaba desde dónde sino tan solo "Manolo llega.". He corregido esta parte para que, mientras sea posible deducirlo, se imprima algo como "Manolo llega desde el norte." Esto afecta a la propiedad 'llega' de los PNJMovil, que ahora recibe la dirección *desde la que llega* el PNJ (en la librería original recibía la dirección por la cual se marchaba). Además esta rutina debe estar preparada para Receive como dirección el valor NULL, lo que significaría que No es posible determinar desde qué dirección ha llegado el PNJ. [He suprimido la lista de cambios de la librería inglesa, ya que No tiene interés para el autor español. Zak]