 PNJMovil  v9.0E     por Zak McKraken
                      spinf@geocities.com

 Una traduccin (y revisin) 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 the ftp site ftp.gmd.de in the location:
   if-archive/infocom/compilers/inform6/library/contributions/moveclass.h

 and also at the 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 un array
de tipo word (-->) y no de tipo byte (->) como en la versin anterior.

* El resto de la librera permanece compatible con la versin anterior.

---------------------------------------------------------------------------

  Indice
  ------
 1. Introduccin
 2. Movimiento de los PNJ
 3. Preparacin             - Cmo usar PNJMovil en tu juego
 4. MOVIMIENTO_CON_META     - Buscando un camino de un lugar a otro
 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 sealar las diferencias entre la versin 7 y la 8 de
! esta librera. Puesto que en espaol la versin 8 es la primera que
! aparece, y la versin 9 no tiene nign cambio que afecte al programador, 
! resulta innecesario compararla con la versin 7, por lo que
! he eliminado todos estos avisos. [Zak]


 1. Introduccin
    ------------

PNJMovil es una librera de ampliacin (compatible con InformatE! 6/10)
que facilita la creacin de PNJs que puedan moverse de una forma
relativamente sofisticada. En pocas palabras, permite con el mnimo de
programacin que un PNJ perteneciente a la clase PNJMovil pueda:

  * Dar paseos aleatorios
  * Moverse segn una ruta pre-programada
  * Planificar una ruta dado el lugar al que quiere ir
  * 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
un array, y despus leyendo las entradas del array de una en una y
moviendo al PNJ en las direcciones all especificadas. Esta tcnica es
rpida y efectiva (por ejemplo, vanse 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 dnde
ir el PNJ y tambin qu camino seguir.

PNJMovil tambin admite este tipo de movimiento - ver la seccin 5
para ms detalles.

A veces, el autor puede necesitar un enfoque ms dinmico, en el cual
la ruta sea decidida durante el juego. Por ejemplo, puede haber un
perro vagabundeando cerca del jugador, y el jugador puede llamarlo con
un silbato, o quizs un miembro de la tripulacin de una nave espacial
est comprobando el casco cuando el capitn le llama al puente de
mando. Definir cmo se llega de una localidad a cualquier otra a base
de rutas prefijadas no es prctico, 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 lmites
de la profundidad mxima de bsqueda.

El propsito de este mdulo de librera es aislar al programador de la
compleja codificacin que es necesaria para un movimiento de PNJs de
este tipo, y para mejorar la eficiencia evitando duplicar el cdigo
que los mueve. Se supone que el lector tiene un nivel bsico de
competencia en la programacin con Inform, ya que el mdulo
proporciona varios "puntos de acceso". El programador necesitar
tambin suministrar algunas rutinas (especficas del juego que est
haciendo) para que la librera funcione, aunque la librera no
presupone que estas rutinas hayan sido suministradas, y no el juego no
"se colgar" si no estn.

En el resto de este manual, las palabras 'autor' y 'programador' se
refierene a la persona que desea utilizar este mdulo de ampliacin.


 3. Preparacin
    -----------

A) Incluir el fichero con el mdulo
   Debes incluirlo despus de 'include Acciones.h', o despus de
   'include Perseguir.h' si ests usando este mdulo 

   La librera admite el uso de la clase 'perseguidor' de Andew Clover y
   Gareth Rees. Esta clase, como el nombre sugiere, permite al jugador
   perseguir a cualquier PNJ. Debe de ser incluido en el listado
   *antes* de PNJMovil, ya que PNJMovil comprueba si la clase
   'perseguidor' ha sido declarada y acta en consecuencia.

   [NdelT: Este mdulo no existe todava en espaol. El original es
   Follower.h]


B) Haz que los lugares del juego sean de la clase 'Lugar', y los PNJ
   de la clase PNJMovil. Los lugares que no sean de la clase 'Lugar'
   son zonas en realidad prohibidas para los PNJ. El movimiento y el
   clculo de rutas slo mira a los lugares de la clase 'Lugar'.

   Este mdulo define una clase 'Lugar'. Si t tienes tu propia clase
   'Lugar', asegrate de que tu definicin proporciona la propiedad
   'cantidad' y de que la declaras antes de incluir este mdulo.

C) Arranca el daemon del PNJ
   Se recomienda que esto slo se haga cuando se necesite el PNJ, as
   si el PNJ no aparece hasta transcurrido medio juego, la llamada a
   ArrancarDaemon(PNJ) no debe hacerse hasta entonces. Si el PNJ
   necesita ponerse en marcha desde el principio, puedes llamar a
   ArrancarDaemon(PNJ) desde la rutina Inicializar, por ejemplo:

      [ Inicializar;
        ArrancarDaemon(Thorin);
        ArrancarDaemon(Gandalf);
        "^^Bienvenido a este juego...^";
      ];
    
    Tu programa no podr usar el daemon de un objeto de la clase
    PNJMovil. En lugar de esto debers usar las nuevas propiedades
    accion_antes y accion_despues. (Ver seccin 9).

D) Llama a PNJ_Ruta()
   Los dos primeros parmetros 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
   parmetros 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. Si
  proporcionas el tercer parmetro (opcional), cambiars 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 un 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 seccin 4 para ms 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 seccin 5 para ms
   detalles. 

Esto es todo. Hay ms detalles, por supuesto, y debers leer la
seccin 9 para ver todas las propiedades que gobiernan el
movimiento. Adems, necesitars poner cuidado especial en la
programacin 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 dnde 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 puerta (ni
                                    las abiertas siquiera)

Si lo necesitas, puedes combinar tipos de ruta, por ejemplo:
CAMINO_ABIERTO+CAMINO_SIN_CERROJOS. Si omites tipo_ruta, el defecto es
CAMINO_CUALQUIERA.

Si se encuentra un camino, PNJ_Ruta retorna true, si no retorna
false. Se recomienda que el cdigo del juego consulte el valor
retornado y acte en consecuencia.

Por defecto, el algoritmo buscar slo hasta una profundidad prefijada
en la variable global (por defecto 10). El autor puede cambiar esto en
cualquier momento, si 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 un 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 nmero de entradas a usar en el array anterior

Para hacer que un PNJ camine siguiendo una ruta predeterminada, hay
que definir esta ruta como un array de palabras. Deben usarse los nombres
de las direcciones de la brjula, tal como aparecen en 'Espanol.h', o
bien el nmero 0 para indicar que en ese turno no hay movimiento
(tngase en cuenta adems que la propiedad accion_despues del PNJ slo
es llamada cuando el PNJ se mueve). Un array de ejemplo sera:

  Array AlTesoroEnterrado --> 
     obj_n obj_n obj_o  0 obj_arriba obj_adentro obj_se obj_abajo;

Esto detalla la ruta 'norte, norte, oeste, esperar un turno, subir,
entrar, sureste y bajar'. Para hacer que un PNJ siga esta ruta
debers usar:

  PNJ_Ruta(BarbaAzul, MOVIMIENTO_PREFIJADO, AlTesoroEnterrado, 8);



 6. Programando puertas
    -------------------

PNJMovil, evidentemente tiene que habrselas con las puertas. Para
ello se crea una propiedad nueva 'pnj_abrir' (ver seccin 7) que
maneje los detalles especficos de como el PNJ interacta con cada
puerta (pueden ser abiertas, abiertas con llave, etc). El autor debe
estar alerta tambin de las siguiente pifias tpicas al programar
puertas:

PIFIA 1
Hay que tener cuidado con la creacin inicial de las puertas. En las
propiedades direcc_puerta y puerta_a, asegrate de que no hay cdigo
que dependa de la variable 'localizacion', que es el lugar donde se
halla el jugador. En vez de eso usa 'parent(self)' o de lo contrario
los PNJs no podran abrir ninguna puerta a menos que el jugador est
en la misma habitacin.

PIFIA 2
Las puertas deben tambin estar *dentro* de una localizacin. Esto
puede parecer obvio, pero es corriente definir una puerta sin padre y
dejar que la librera la lleve a la habitacin correcta haciendo uso
de la propiedad 'esta_en'. Esto es perfecto para el jugador, pero no
lo es para los PNJs.

PIFIA 3
PNJMovil consulta las propiedades al_<direccion> de las habitaciones
(por ejemplo, al_n, al_s, etc.) para ver cules estn disponibles y a
dnde llevan. Si esta propiedad est definida como una rutina,
entonces PNJMovil la ejecutar y esperar que sta retorne la
habitacin a la que lleva, o el valor falso (si no puede salirse por
ah). Esto significa que la rutina slo debe contener condicionales, y
ningn comando de accin o de imprimir. Por ejemplo:

   al_n [; if (self.cantidad==1) return Habitacion_Alta;
           return Habitacion_Baja;
        ],


Si solas usar esta rutina para imprimir diferentes textos, ya no
podrs hacerlo, pero puedes lograr lo mismo capturando el verbo 'Ir'
en la propiedad 'antes' de la habitacin, y comprobando en qu
direccin se intenta mover el jugador. Por ejemplo, si quieres lograr
algo como esto:

   al_e "Las rocas te bloquean el paso.",
   al_o [; if (self hasnt general)
           { give self general;
             move huellas to localizacion;
           }
           return Lugar_Oeste;
        ],
   <etc>

Debers programarlo de esta otra forma:

   before [;
      Ir: 
          if (noun==obj_o)
          { if (self hasnt general)
            { give self general;
              move huellas to location;
            }
          }
   ],
   al_e "Las rocas te bloquean el paso.",
   al_o Lugar_Oeste,
    <etc>



 7. PNJs y Puertas
    --------------

Si el autor quiere hacer posible que un PNJ abra o abra con llave una
puerta, puede darle a esa puerta la propiedad 'pnj_abrir'. Esto
tambin puede usarse para imprimir mensajes que indiquen un
comportamiento especfico ante esa puerta. Una puerta que no tenga la
propiedad 'pnj_abrir' slo podr ser atravesada por un PNJ si la
puerta est abierta.

Cuando un PNJ quiere atravesar una puerta (porque est en su camino),
comprueba primero si la puerta proporciona la propiedad 'pnj_abrir', y
si es as la llama, pasndole como parmetro el identificador del
PNJ. La propiedad debe retornar 0, 1  2, lo que significar:

           2 - El PNJ puede atravesar esta puerta. El mdulo mostrar
	   el mensaje estndar "Manolo se marcha hacia el norte" (u
	   otro mensaje similar si manolo proporciona otro).

    (true) 1 - El PNJ puede atravesar esta puerta, pero la librera no
           mostrar ningn mensaje (se supone que la rutina pnj_abrir
           ya ha escrito algo).

   (false) 0 - El PNJ no puede atravesar esta puerta.

La rutina no necesita darle a la puerta el atributo 'abierta'. Si lo
hace, la puerta queda abierta tras ser atravesada por el PNJ, pero si
no lo hace, queda cerrada (en realidad el PNJ la "atraviesa" sin
abrirla, pero podemos hacer que la rutina imprima un mensaje como "y
cierra la puerta tras de s"). En general, con un comando como
print_ret "Bla" o simplemente "Bla"; la rutina puede mostrar un
mensaje ms sofisticado describiendo el movimiento a travs de la
puerta. [La rutina debe comprobar antes de imprimir algo que la accin
sea visible para el jugador, lo cual puede hacerse usando
PruebaDeAlcance como muestran los ejemplos siguientes]

Una rutina pnj_abrir sencilla podra ser la siguiente:

    pnj_abrir [ quien;        ! parmetro pasado por la librera
        give la_puerta abierta;
        if (PruebaDeAlcance(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 ms complicada (tomada de un juego
real) sera la siguiente:

    pnj_abrir [ quien;
      if (self hasnt abierta)
      {   give self abierta;
          ArrancarReloj(self,3);
          if (PruebaDeAlcance(quien))
            "^", (_El) quien, " sacude la mano ante la luz roja de la
	    puerta. La luz se vuelve verde y con un cirrido
	    electrnico la puerta corredera se abre y ", (el)
            quien, " pasa a travs.";
           if (PruebaDeAlcance(self)) ! La puerta puede verse
            "^Se oye un chirrido electrnico, la puerta corredera se
             abre y ", (el) quien, " entra.";
          rtrue;
      }
      if (PruebaDeAlcance(quien))
        "^",(_El) quien, " se marcha por la puerta abierta.";
      if (PruebaDeAlcance(self))
        "^", (_El) quien, " llega a travs de la puerta abierta.";
      return 2;
    ],

Observar que en este ejemplo la puerta 'esta_en' dos
localidades. PruebaDeAlcance(quien) se usa para ver si el PNJ est en
la misma localidad que el jugador, en cuyo caso ste puede verle
marchar. Si no, a continuacn se comprueba PruebaDeAlcance(self) que
verifica si la puerta est en la misma localidad que el jugador, en
cuyo caso ste puede verle llegar.

Una puerta puede usarse tambin como una barrera que impida a los PNJs
(o a ciertos PNJs) pasar en ciertas direcciones, barrera invisible
para el jugador. Por ejemplo, si el jugador y todos los PNJs, excepto
uno especialmente supersticioso, pueden entrar a una cueva embrujada,
puede ser til crear una puerta (de la que no se informa al jugador)
que impida a la persona supersticiosa pasar, mediante el uso de la
propiedad pnj_abrir.



 8. Caminos Bloqueados
    ------------------

Hay tres casos en los que un PNJ, que intenta seguir una ruta
(prefijada o bien calculada por la librera) puede ver su avance
bloqueado:

   * La siguiente localidad en su camino parece ser 'ninguna' (0)
   * Debe pasar por una puerta cuya propiedad pnj_abrir retorna false
   * Debe pasar por una puerta 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). Otro enfoque sencillo sera no
hacer nada especial, con lo que el personaje esperara hasta que el
camino se desbloqueara y continuara recorriendolo despus. Un enfoque
ms sofisticado podra 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
responder ms inteligentemente a los casos de bloqueo). Un buen uso de
esta propiedad podra 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 probar 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 variacin sobre este tema podra 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 cmo estn
conectadas tus habitaciones.

Y aqui tienes otro truco: Cuando una puerta no es una puerta?

Si quieres encontrar un camino que evite ciertas puertas concretas,
puedes hacer que temporalmente stas no sean puertas (es decir,
quitarles el atributo puerta, por ejemplo: give puerta_mala
~puerta) y despus buscar una ruta usando CAMINO_CUALQUIERA
normalmente. De este modo, la librera 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
puerta). Ta chan!



 9. Variables, Atributos, Propiedades y Rutinas
    -------------------------------------------

VARIABLES GLOBALES:===================================================
max_longitud_camino - Lmite a la profundidad de la bsqueda usada por
              la rutina PNJ_Ruta(). Puede subirse o bajarse durante el
              juego, pero slo afecta a la bsqueda 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 bsqueda para seguir el
             rastro de las habitaciones que podran formar parte de la
	     ruta calculada.

PROPIEDADES============================================================
tipo_de_movimiento - Contiene cmo se est moviendo el PNJ (si 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 un PNJ
             decida movers en un 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 un PNJMovil no
             est disponible porque es usada por esta librera). La
             propiedad accion_antes, si existe, se ejecuta antes de
             intentar mover al PNJ, en cada turno *incluso si el PNJ
             no se mueve*. Si esta propiedad retorna true, entonces el
             PNJ no se mover ese turno.

accion_despues  - Si esta propiedad existe en un PNJMovil, ser
             llamada slo despus de que el personaje se haya movido
             con xito de una localizacin a otra. Es til para los
             casos en los que el PNJ tiene que reaccionar
             instantneamente a los objetos, eventos u otros PNJs que
             encuentre en la nueva habitacin. *No es llamada si el
             PNJ no se mueve*.

marcha       - El mensaje que se mostrar cuando el PNJ abandone la
             localizacin en la que se encuentra el jugador. El valor
             por defecto es "se marcha". El autor puede darle como
             valor una cadena de texto (en cuyo caso la librera
             automticamente pone delante el nombre del PNJ y "hacia
             <direccion>" detrs, ver ms detalles en DirDada, ms
             abajo) o una rutina. Si se define una rutina, la librera
             le pasar como parmetro la direccin (objeto brjula)
             hacia la que se ha movido el PNJ. El autor debe imprimir
             un mensaje apropiado, con un retorno de carro antes y
             otro detrs (p.ej: "^El PNJ se las pira.").

llega        - Como 'marcha', pero en este caso es el mensaje mostrado
             cuando un PNJ entra en la localizacin en la que se halla
             el jugador. Puede definirse como una cadena de la forma
             "entra en la habitacin" (la librera aade delante el
             nombre del PNJ y detrs la direccin desde la que
             llega, si es capaz de determinarla) o una rutina, a la
             cual la librera le pasa como parmetro la direccin
             desde la que llega (si ha podido determinarla) o el valor
             NULL (si no ha podido). [Puesto que los mapas en Inform no
             son "simtricos", puede ocurrir que una habitacin A
             tenga una salida al Norte hacia una habitacin B, pero en
             cambio sta no tenga conexiones con la A. En este caso si
             un PNJ desde A va al norte, aparecer en B, pero es
             imposible decir desde dnde ha llegado (no es desde el
             sur, pues esto implicara que al sur puede salirse hacia
             A). En este caso el mensaje habr de ser deliberadamente
             ambiguo: "Llega Manolo" o "Manolo aparece de no se sabe
             dnde". 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 nmero 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 librera para almacenar el
              lugar de destino de un PNJ.

pnj_bloqueado - Una rutina que es llamada cuando un PNJ encuentra su
              camino bloqueado 

pnj_sibloqueado - Una propiedad no usada por la librera, que el autor
              puede usar para decidir qu hacer cuando sea llamada la
              rutina pnj_bloqueado

pnj_ha_llegado - Esta rutina es llamada cuando un 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. Si no se llama a PNJ_Ruta() puede
              producirse un cuelgue. Por defecto la librera
              porporciona esta propiedad de modo que pasa al PNJ a
              movimiento aleatorio una vez que alcanza su destino.

accion_seguir } Incluidas para evitar problemas si se usa a la vez
objeto_seguir } la librera PERSEGUIR.h


RUTINAS===============================================================
PNJ_Ruta(pnj, tipo_movimiento, lugar_destino, tipo_ruta)
             - Ver seccin 4 para detalles.

PNJpreRuta(pnj, nombre_array, longitud_array)
             - Es llamada por PNJ_Ruta si
             tipo_movimiento=MOVIMIENTO_PREFIJADO.  Se mantiene como
             una rutina separada para mayor claridad y compatibilidad
             [en la versin espaola la compatibilidad no es una
             preocupacin ya que no exista versin previa. Zak]

DirDada(dir) - Es utilizada por la librera para insertar el texto
             "hacia el norte" o el mensaje adecuado, al final de la
             cadena "se marcha". Puede ser usada por los autores, si
             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) obj_n, ".";

ConduceA(dir, lugar, tipo_ruta)
             -  Usada para encontrar a qu lugar se llega siguiendo la
             direccin 'dir' desde el 'lugar' dado. El parmetro
             'tipo_ruta' puede usarse para restringir el acceso a
             travs de puertas.

MoverPNJDir(pnj, dir)
             - Mueve al PNJ en la direccin dada. Usa ConduceA() para
             saber a qu lugar llega y despus llama a MoverPNJ() para
             hacer el movimiento (e imprime el mensaje apropiado si el
             movimiento puede ser visto por el jugador).

MoverPNJ(pnj,destino,-,-)
             - Esta funcin se define si el programador no ha includo
             la librera PERSEGUIR.h. Si en cambio esta librera ha
             sido includa, se usar la rutina MoverPNJ proporcionada
             por ella. Si no ha sido incluida, PNJMovil.h proporciona
             una versin propia (muy simplificada) de esta rutina.


10. Problemas
    ---------

MoveClass, la librera original, antes de los cambios de la versin 8,
haba sido probada con muchos ejemplos, y era slida. Los cambios han
simplificado ligeramente el cdigo, pero como con todos los cambios de
cdigo, esto es una oportunidad para que aparezcan nuevos errores. Se
ha puesto mucho esfuerzo en mantener esta nueva versin compatible
hacia atrs con la anterior. [En la traduccin al espaol es posible
que se hayan deslizado ms errores an. Por otro lado, en esta
traduccin no se ha contemplado la compatibilidad, puesto que no haba
versin anterior para InformatE. Zak]

PNJMovil puede producir informacin de depuracin si la constante
DEBUG est definida al principio del programa y el nivel de traza se
pone a un nivel 2 o ms (comando 'trace 2'  durante el juego). Esto,
junto con los restantes mensajes de depuracin, pueden ayudarte a
localizar la fuente de los problemas. Si PNJMovil te da problemas, por
favor contacta conmigo, Zak McKraken, en la direccin que aparece al
principio de este fichero. Si es posible, incluye una trascripcin de
la informacin de depuracin. Por favor, no me enves ficheros enormes
antes de haberte puesto en contacto conmigo.



11. Actualizaciones
    ---------------

La versin 9.0 simplemente define la constante WORDSIZE (si no la
habia definido ya el compilador) y la usa internamente en una
ocasin. Adems, cambia los arrays que contienen las direcciones
por arrays de tipo word.

La versin en Espaol es una traduccin de la versin 8.01 de
MoveClass. Esta versin contena al menos un bug, y adems he hecho
alguna mejora adicional, por eso la considero la versin 8.02. No
obstante, paralelamente Alan seguir actualizando su librera en
ingls, as que para distinguir una de otra aado la E (de Espaol)
al final:

* La rutina ConduceA() utilizaba incorrectamente el parmetro
  direccion, asumiendo que era el nombre de una propiedad de direccin
  (como al_n, al_s), en lugar de un objeto brjula (obj_n, obj_s) que
  es lo que era realmente. Por tanto la librera tal como vena no
  funcionaba. 


* La rutina MoverPNJDir() imprima la direccin por la que el PNJ se
  iba con un mensaje como "Manolo se marcha hacia el norte", pero en
  cambio cuando el PNJ llegaba, el mensaje no indicaba desde dnde
  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 direccin *desde la que llega* el PNJ (en la librera original
  reciba la direccin por la cual se marchaba). Adems esta rutina
  debe estar preparada para recibir como direccin el valor NULL, lo
  que significara que no es posible determinar desde qu direccin ha
  llegado el PNJ.


[He suprimido la lista de cambios de la librera inglesa, ya que no
tiene inters para el autor espaol. Zak]


