|  |  | Mejorando detalles estéticos

## Mejorando detalles estéticos

### Más sobre atributos

Un atributo es una característica que un objeto dado puede tener o bien no tener. Por ejemplo, la luz de una habitación. Son características del tipo SI/NO sin posibilidad de valores intermedios. Si necesitas que en tu juego la luz sea algo más elaborado (por ejemplo: mucha luz, luz normal, penumbra, semioscuridad, oscuridad total), entonces no podrás usar un atributo para representar la luz. Para representar características que pueden tomar varios valores se deben usar "propiedades" (que veremos en una sección posterior).

Inform tiene predefinidos un buen montón de atributos. Cuando creas un objeto puedes "activar" cualquiera de ellos. Los que no actives explícitamente se consideran "desactivados". Ya hemos visto cómo se hace esto en los ejemplos anteriores, ya que todas las localidades tenían el atributo `light (luz)`, y la antorcha tenía el atributo `female (femenino)`. Un objeto puede tener varios atributos activos a la vez, así por ejemplo la antorcha, además de `female` podría tener `light`. Para lograr esto basta poner todos los atributos que se quieran separados por espacios. Por ejemplo:

    Object antorcha "antorcha"
    with name 'antorcha' 'tea',
     ....
    has female light;

También puedes activar o desactivar un atributo en cualquier momento del juego. Por ejemplo, una localidad podría comenzar sin el atributo `light` (y el jugador no podría ver nada al entrar en ella), pero hacer que, si el jugador pulsa un interruptor localizado en otro lugar, entonces se active la luz de esta habitación. Esto es muy sencillo, ya que para poner un atributo a un objeto basta la instrucción:

      give objeto atributo;

que se leería "dale al objeto este atributo". De modo que para activar la luz de una localidad llamada `Tunel` la cosa sería tan simple como: `give Tunel light;` La próxima vez que el jugador entre en esa localidad, ya podrá ver (y si el jugador estaba en esa localidad en el instante en que esta instrucción es ejecutada, al final de este turno "se hará la luz" y se le mostrará al jugador la descripción del lugar).

Para desactivar un atributo (por ejemplo, para apagar la luz de una localidad) la sintaxis es un poco rara:

      give objeto ~atributo;

que se leería "dale al objeto este atributo desactivado". El signo `~` delante de un atributo indica su desactivación. Así pues, para apagar las luces del tunel, por ejemplo sería: `give Tunel ~light;`

El hecho de activar un atributo en un objeto, tiene efectos sobre el juego. En el ejemplo de la `luz` la cosa está clara. Pero hay otros muchos atributos y cada uno tiene su efecto sobre el juego. Por ejemplo, existe el atributo `open (abierto)` que indica cuando un recipiente está abierto, y según el valor de este atributo el juego te dejará ver o no lo que hay dentro del recipiente.

Iremos viendo algunos atributos y sus efectos sobre el juego a medida que los vayamos necesitando.

### Mejorando la antorcha

Sólo nos queda un detalle por mejorar en la antorcha. Observa de nuevo la descripción de la localidad:

    Escalera de caracol
    Los desgastados peldaños de piedra resbalan en ocasiones.
    A mitad de la escalera una antorcha en la pared impide
    que la oscuridad sea completa.

    Puedes ver una antorcha.

Vaya. La antorcha es mencionada dos veces. Esto se debe a que Inform primero imprime la descripción de la localidad, y seguidamente crea una lista de todos los objetos que hay en esa localidad, que encabeza con "Puedes ver..."

Por suerte (o por desgracia, según se mire) el programador tiene muchas formas de afectar este mecanismo, y puede lograr entre otros los siguientes efectos:

- Que Inform no mencione un objeto en la lista "Puedes ver...", aunque se halle realmente en esa localidad. Esto puede sernos útil para la antorcha.
- Que un objeto concreto tenga una "linea para él solo". Por ejemplo, imagina que en la localidad hay un caballo, y una moneda que el jugador ha dejado en el suelo. Inform añadiría al final de la descripción de la localidad la frase: "Puedes ver un caballo y una moneda".

  Parece que el caballo requeriría más protagonismo. Es fácil asignarle al caballo una línea para él solo, con el texto que el programador desee, de forma que el resultado sea este otro: "Un caballo de aspecto imponente te mira con desconfianza. Puedes ver también una moneda."

- Que un objeto tenga diferente descripción según esté abierto o cerrado, o según esté encendido o apagado. Así, en lugar de "Puedes ver una caja", Inform puede producir la frase "Una caja abierta yace en el suelo." o "Hay una caja cerrada en el suelo", según el valor del atributo `open` de ese objeto.
- Que un objeto tenga diferente descripción la primera vez (hasta que el jugador lo coge). Así, por ejemplo, podemos hacer que un objeto `Seta` se mencione con la frase: "Del suelo emerge una seta de tallo estrecho", pero tan pronto como el jugador la coja y la suelte de nuevo, pasa a la forma por defecto "Puedes ver una seta.".

Como ves, las posibilidades son muchas. Para lograr uno u otro efecto, debemos hacer uso de atributos y propiedades. Vamos a centrarnos de momento en nuestro problema, que es hacer que no se mencione la antorcha en la linea "Puedes ver..." que es el caso más sencillo.

Para lograr esto, basta que la antorcha tenga el atributo `concealed (oculto)`. Y puesto que queremos que este atributo esté activo desde el principio del juego, lo mejor es dárselo ya en la propia declaración de la antorcha.

Vete por tanto a la línea final de la antocha, que tenía `has female` y cambiala por:

      has female concealed;

| El nombre de este atributo es un poco engañoso. Quizás debería haberse llamado `no_mention`, o algo así, ya que realmente lo único que logras con este atributo es que Inform no mencione ese objeto cuando describa la habitación. Sin embargo, el objeto no está realmente oculto, ya que el jugador podría cogerlo o realizar cualquier otra acción sobre él.

Si compilas y ejecutas esta versión, verás que en la localidad de la antorcha ya no se menciona esta (salvo, claro está, en la propia descripción de la localidad). Por tanto hemos logrado el objetivo.

Otro atributo con efectos similares es el `scenery (escenario)`. Cuando un objeto tiene este atributo, tampoco es mencionado en la localidad. Además, por defecto la librería no dejará efectuar ninguna acción sobre ese objeto que implique moverlo. Por ejemplo, empuja, tira, coge, mueve, etc... todas fracasarán. En cambio sí permite examinarlo. De este modo te ahorras tener que programar tú mismo en la rutina `before` todas las respuestas necesarias para evitar estas acciones.

Podríamos haber puesto a la antorcha el atributo `scenery` y esto no afectaría a su correcto funcionamiento ante `Pull` o `Push`, ya que la antorcha tiene su propio código para manejar estas acciones, y el código del objeto siempre tiene prioridad sobre la acción por defecto de la librería. Sólo cuando la antorcha no contemple una acción, se ejecutará el caso por defecto para la librería. De hecho, sería más prudente hacer que la antorcha sea `scenery`, pues de este modo, si se nos ha olvidado programar alguna respuesta por defecto ante alguna acción que implique mover la antorcha, la librería tendrá una por defecto una que impedirá ese movimiento. Por ejemplo, imagina que hubieramos olvidado programar la acción `Take` de la antorcha. Si la antorcha es `scenery`, la librería impedirá esta acción. Sin embargo, si no es `scenery`, ¡el jugador podría llevarse la antorcha a otra localidad! Y lo que es peor, una vez que se la ha llevado, si la empuja o tira de ella, ¡¡el mecanismo de la puerta de la mazmorra seguiría funcionando!!

| En resumen, si quieres asegurarte de que un objeto nunca va a poder ser llevado de su localidad de origen, ponle el atributo `scenery`.

Por otra parte, `scenery` implica `concealed`, es decir, que el objeto no es mencionado en la descripción de la localidad. Si quieres evitar que un objeto pueda moverse, pero quieres que Inform lo mencione normalmente en la linea "Puedes ver..." debes darle el atributo `static (estatico)`.

### Descripciones variables

Ahora quedaría bonito que la descripción de la localidad hiciera referencia a la entrada a la mazmorra (si está abierta, claro). Esto es mucho más fácil de lo que puede parecer a primera vista, ya que Inform permite que la descripción de una localidad sea una rutina embebida, en lugar de un texto estático.

Es decir, podemos poner, en lugar de una cadena entre comillas como aquí:

      description "Bla bla bla",

Una rutina como aquí:

      description [;
            print "Bla bla bla";
          ],

En este caso la diferencia no es mucha, ya que el resultado que verá el jugador será exactamente el mismo. Sin embargo para el programador es todo un mundo de diferencia, porque si la descripción es una rutina ¡puede usar `if` para generar diferentes descripciones, según se cumplan o no ciertas condiciones!

| Haciendo que una propiedad sea una rutina, podemos lograr que produzca diferentes resultados en diferentes instantes del juego. Esta idea no sólo vale para la descripción. Como veremos, en Inform prácticamente cualquier propiedad puede ser, bien un valor fijo, o bien una rutina.

Aplicando esta idea a la localidad `EscaleraCaracol2`, podemos hacer que la descripción añada una observación sobre la entrada a la mazmorra o que calle, según el valor de la salida `w_to`. La nueva programación de esta localidad sería:

    Object  EscaleraCaracol2 "Escalera de caracol"
     with   description [;
                print "Los desgastados peldaños de piedra resbalan en
                  ocasiones. A mitad de la escalera una antorcha en la
                  pared impide que la oscuridad sea completa.^";
                if (EscaleraCaracol2.w_to==Mazmorra)
                   print "^Parte de la pared oeste ha deslizado mostrando
                       una entrada.^";
            ],
            d_to EscaleraCaracol1,
            w_to 0,
            u_to AltoTorre,
     has    light;

El código con esta mejora (y con la antorcha `concealed`) lo tienes aquí, lista para que la compiles (), ejecutes () y pruebes.

|  |  | Mejorando detalles estéticos