Objetos para leer y consultarEl modelo del mundoObjetos que pueden encenderse y apagarseObjetos en los que puede entrarse, viajar o empujar

Objetos en los que puede entrarse, viajar o empujar

Los objetos también pueden tener el atributo "entrable", que quiere decir que el jugador puede meterse dentro de ellos. En este caso dentro significa estar dentro, pero sólo a medias, como por ejemplo en una cama (pero aún está también en la habitación donde estaba la cama). Si se trata de un objeto más bien como una celda de prisión es mejor hacerlo como una localidad separada.

En la práctica los objetos entrables suelen ser también recipientes, o bien superficies, según el jugador quede "dentro" o "encima" una vez que ha entrado en el objeto. Por ejemplo, añadimos un altar a "Ruinas":

Objeto altar_piedra "altar de piedra" Sepulcro
  with  nombre 'altar' 'piedra' 'gran' 'losa' 'mesa',
        inicial "Una gran losa de piedra, como una mesa o un altar,
                 domina el Sepulcro",
  has entrable soporte;

Una silla en la que sentarse o una cama en la que echarse serían también objetos entrables, y deben ser también soportes.

Si el jugador entra en un recipiente y después lo cierra, el efecto es como si estuviera en un lugar nuevo (a menos que el recipiente tenga el atributo transparente y por tanto se podría ver a través de él la habitación original). El interior puede estar oscuro, pero si hay algún tipo de luz el jugador querrá ver una descripción. Y de cualquier forma, hay muchos objetos entrables que se ven diferentes desde dentro que desde fuera. Dentro de un vehículo el jugador podría ver un volante y un salpicadero, por ejemplo. Encima de una mesa podría ser posible ver a través de un tragaluz.

Para este cometido, cualquier objeto entrable puede proporcionar la propiedad descripcion_dentro, que puede ser una cadena de texto o una rutina que la imprima, como es habitual. Si la habitación exterior es aún visible (esto lo deduce la librería), entonces la descripcion_dentro se añade a la descripción habitual. Si no, la única descripción que el jugador verá será la descripcion_dentro.

Como un ejemplo extremo, supón que el jugador entra en un enorme armario, cerrando la puerta (no puede ver entonces la habitación exterior) y dentro de él hay una cabina de plástico transparente en la que entra también y cierra. La descripción de la habitación (si pone "Mira") podría ser así:

El armario enorme (en la cabina de plástico)
Es cómodo el armarito, casi una habitación por si solo.

En el armario enorme puedes ver una pila de ropa.

Las paredes de plástico de la cabina distorsionan la visión.

La primera línea es el título del lugar (que en este caso se toma del armario por no ser visible el lugar exterior). La segunda línea sería la propiedad descripcion_dentro del armario. La tercera línea la genera la librería automáticamente para mostrar los contenidos del armario. La cuarta línea es la descripcion_dentro de la cabina de plástico que se añade al resto de la escena (en vez de sustituirla) por ser transparente.

(?) EJERCICIO 14  Programa una jaula para "Ruinas" que sea un recipiente que se pueda abrir y cerrar, y en que el jugador pueda meterse.
(Solución)

Todos los juegos clásicos tienen vehículos en los que el jugador puede viajar (barcos, elevadores, globos aerostáticos), así que InformATE proporciona una forma fácil de programarlos. Aquí tenemos un ejemplo:

Object cochecito "cochecito rojo"
 with   nombre 'coche' 'cochecito' 'rojo' 'pequeno',
        descripcion "Es lo bastante grande como para poder
            entrar. Entre los controles hay un botón ON/OFF
            prominente. La matrícula es KAR 1.",
        si_encendido "Aquí está el coche rojo, con el motor aún
            encendido.",
        si_apagado "Hay aparcado un cochecito rojo.",
        antes [;
         Ir:
            if (cochecito has encendido) "¡Brumm, Brummm!";
            else print "(El motor está apagado)^";
        ],
 has    conmutable entrable estatico recipiente abierto;

Este objeto es un vehículo, aunque no lo parezca. Como ves, no es necesario especificar el atributo vehiculo (de hecho, no existe tal atributo). Por defecto, todos los objetos entrables, son vehículos; sólo que algunos nunca se mueven del sitio :-). La clave está en proporcionar una rutina antes que reaccione a la acción Ir. Si el jugador está dentro de un objeto entrable y en ese momento escribe "Norte" o cualquier otro verbo para caminar en alguna dirección, la rutina generará la acción Ir obj_n, y llamará a la rutina antes del objeto en el que está el jugador (por ejemplo, el cochecito anterior), como si le preguntara al objeto "¿Qué hacemos, dejamos que el jugador se mueva hacia el norte?". La rutina antes puede dar una de las siguientes respuestas:

true
Que significaría "Sí". Entonces la librería moverá hacia el norte al jugador y al objeto dentro del cual estaba metido, por lo que este objeto es de hecho un vehículo.
false
Que significaría "No". Entonces la librería escribirá el mensaje "No puedes ir a ningún lado mientras estés dentro del cochecito rojo" y ni el jugador ni el cochecito se moverán.
2
Si responde con el número 2, significaría "Impide el movimiento, pero no escribas el mensaje". Así que ni el jugador ni el coche se mueven, pero la librería no se lo dice al jugador. Se supone que en este caso la rutina antes ya ha usado print para informar con el mensaje adecuado de que el movimiento no es posible.
3
Si responde con el número 3 significaría "Ya me encargo yo de todo". En ese caso la librería no hace nada más. La rutina antes puede mover al jugador, o al cochecito, o a ambos a donde quiera, e imprimirá el mensaje adecuado usando print (cuidado no usar print_ret ya que ésta función causaría que antes respondiera true en vez de 3).

Si la rutina antes modifica la localización del jugador (lo mueve a otro lugar) es muy importante que retorne el valor 3. Si retornara el valor 2, la librería restauraría al jugador a su posición anterior, inutilizando el movimiento que pudiera haberse hecho desde la rutina antes.

Observa la rutina antes de nuestro cochecito. ¿Qué valor devuelve? Si el cochecito está encendido, simplemente se ejecutará la cadena de texto "¡Brumm, Brummm!", es decir, se imprime ese mensaje, un retorno de carro y se retorna true (por tanto la librería moverá, a continuación cochecito y jugador). Naturalmente este movimiento aún puede fracasar si la dirección especificada no es una salida, o está bloqueada por una puerta. Si en cambio el cochecito está apagado, se imprime la cadena "(El motor está apagado)", pero ya que se usa en este caso la orden print, no se añadirá automáticamente retorno de carro (por eso hay que especificarlo con "^") y tampoco se terminará la función, que seguirá ejecutándose por la línea siguiente. Ahora bien, ya no hay más líneas en la función, por lo que ésta termina de todas formas al llegar al corchete final, pero en este caso retorna false (que es el valor por defecto retornado por una rutina de un objeto). De modo que si no está encendido, se niega a moverse, imprime el mensaje indicando que el motor está apagado y después deja a la librería que imprima sus propios mensajes para esta situación (que sería en este caso "Tienes que salir del coche antes.").

(?) EJERCICIO 15  Modifica el código del cochecito rojo para que no pueda viajar hacia el oeste.
(Solución)

(!) Objetos como el coche o, por ejemplo una pelota de dos metros de diámetro, pueden ser demasiado grandes o pesados para que el jugador pueda cogerlos, pero al menos deberíamos dejar que el jugador pueda empujarlos de una habitación a otra. Si el jugador lo intenta (con una orden como "Empuja la pelota hacia el este"), se generará la acción EmpujarDir. La rutina antes de la pelota puede capturar esta acción, y retornar true o false. Si retorna true, la librería entiende que ya ha escrito algún mensaje del tipo "Es imposible empujar esa cosa enorme", por lo que no hará nada más. Si en cambio retorna false, la librería mostrará el mensaje estándar "¿Es lo mejor que se te ocurre?" y tampoco se moverá la pelota. En cualquiera de los dos casos la pelota no ha cambiado de lugar. ¿Qué hacer para que el jugador realmente pueda moverla de un lugar a otro a base de empujar? Para lograr esto la rutina antes tiene que llamar a la rutina PermitirEmpujarDir antes de retornar true (si retorna false no habrá movimiento de todas formas). La mejor forma de comprender cómo se hace esto es con un ejemplo:

Object bola_enorme "bola enorme de piedra pómez"
 with   nombre 'bola' 'pelota' 'esfera' 'enorme' 'pomez' 'piedra',
        descripcion "Tiene sus buenos dos metros de diámetro, pero es
            ligera.",
        inicial "Aquí descansa Una enorme bola de piedra pómez, de
            dos metros de diámetro.",
        antes [;
         Coger, Sacar: "Hay mucha piedra en una esfera de dos metros
            de diámetro.";
         Empujar, Tirar, Girar: "No parece muy difícil hacerla
            rodar.";
         EmpujarDir:
            if (localizacion==Encrucijada && otro==obj_w)
                "La entrada al corredor sólo tiene metro y medio de
                ancho.";
            else {
                PermitirEmpujarDir();
                rtrue;
            }
        ],
        despues [;
         EmpujarDir:
            if (otro==obj_s)
                "Es difícil parar la bola cuesta abajo.";
            if (otro==obj_n)
                "Con gran esfuerzo empujas la bola cuesta arriba.";
        ],
 has    estatico femenino;

(?) EJERCICIO 16  Supón que en la habitación donde está la bola hay una salida hacia el norte y hacia arriba, y otra hacia el sur y hacia abajo. El jugador puede poner "norte" o "arriba" indistintamente (si bien la primera forma generará la acción Ir obj_n y la segunda generará Ir obj_arriba, la habitación tiene las salidas al_n y arriba apuntando al mismo destino). No obstante, la librería impide empujar objetos hacia arriba o hacia abajo, incluso aunque se haya llamado a PermitirEmpujarDir(). ¿Cómo modificarías la bola para que el jugador pudiera "Empujar la bola hacia arriba"?
(La Solución tiene un poco de trampa. Hay que cambiar la acción generada por otra).


Zak McKraken - spinf@geocities.com

Objetos para leer y consultarEl modelo del mundoObjetos que pueden encenderse y apagarseObjetos en los que puede entrarse, viajar o empujar