! 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_<direccion> 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;
        ],
   <etc>

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,
    <etc>



 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
             <direccion>" 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]


