Por Javier Basilio
Comenzamos aquí una sección
dedicada a la programación avanzada en el parser DAP. Estos artículos no
pretenden ser una descripción de cómo se usa el parser o de cómo hacer una
aventura con él: para eso ya está el manual de DAP, donde esto se explica
detalladamente con todo tipo de ejemplos. Nosotros nos dirigiremos al usuario
que ya sabe usar DAP y desea profundizar en él, explicando técnicas para
enriquecer tus aventuras. DAP es un parser que busca la sencillez absoluta y
por eso hay algunas características avanzadas que no se encuentran
explícitamente en él; esta serie te ayudará a implementar estas características
haciendo un hábil uso del microlenguaje de orgones.
En esta primera entrega trataremos del manejo de objetos consumibles; es decir, que se van gastando según los vamos usando. Hay varios enfoques para tratar este problema; veremos uno de los muchos posibles.
Desarrollaremos la técnica mediante un clásico ejemplo; el de la linterna que se va consumiendo según la vamos usando. La linterna tiene una cierta carga eléctrica que va bajando según permanece encendida. Hay ciertas localidades que están a oscuras, en las que no podemos ver nada sin la linterna.
Para mantener la carga de la linterna, vamos a hacer uso del flag auxiliar del que disponen todos los objetos a partir de la versión 4 de DAP. En DAP, los objetos están definidos por 4 campos:
- un número de objeto que lo identifica internamente
- una descripción de texto
- un precio
- un flag numérico auxiliar que no es usado por DAP y queda libre para el usuario.
Nosotros haremos uso precisamente de este flag: en él almacenaremos el estado del objeto consumible.
Vamos a imaginar que tenemos una aventura con los siguientes elementos:
- Una localidad (número 73) a oscuras (si tenemos más localidades, el proceso es análogo)
- Un objeto linterna con número 1
- Un objeto pilas con número 2
Al principio, la linterna está descargada y su flag auxiliar vale 0. La linterna además podrá estar encendida o apagada; esto lo controlaremos mediante uno de los flags globales del programa, por ejemplo, el flag 10:
Flag 10, significado:
Si vale 1, la linterna está encendida
Si vale 0, la linterna está apagada.
Además, para las comparaciones vamos a suponer que el flag 98 siempre vale 0 (es el valor que tiene inicialmente y no cambiará sino lo tocamos)
Así, por ejemplo, es muy sencillo crear una rutina para que el jugador pueda examinar la linterna y recibir información sobre si está encendida o apagada, y la carga que le queda:
Orden: ex linterna
Rutina EDAP:
OBJ 1,M1 // comprueba si el usuario tiene la linterna
PRINT M2 // escribe la descripción de la linterna
PRINT M3 // escribe la descripción de la carga de la linterna
OBFTOVAL 1 @2 // copia el flag de estado de la linterna al flag 2
PRINTVAL @2 // imprime el contenido del flag 2
VAL @10 1 M4 // comprueba si la linterna está apagada (si es así, imprime 4 y cancela)
PRINT M5 // linterna encendida
RET
Donde los mensajes valen, por ejemplo:
1- “No tienes ninguna linterna. Cómprate gafas”
2- “La linterna es compacta y liviana”
3- “La linterna tiene la siguiente carga:”
4- “La linterna está apagada.”
5- “La linterna está encendida.”
También supondremos que tenemos un mensaje 299 vacío, para los siguientes procedimientos en los que halla orgones de comprobación y no deseemos imprimir nada.
A la vista de esto, es muy fácil crear los procedimientos para encender y apagar la linterna, por ejemplo, este el que usaríamos para encenderla:
Orden: encender linterna (posible sinónimo: enciende
linterna)
Rutina EDAP:
OBJ 1,M1
CAMVAL @10,1,M5
RET
De acuerdo. Ahora bien, ¿cómo hacemos que la linterna se gaste cuando está encendida?. Es preciso crear un procedimiento global (un glolo, en la terminología de DAP) que se ejecute en cada ciclo de juego. Nada más sencillo; sólo hay que crear un procedimiento glolo asociado a la localidad 0 (los glolos son procedimientos que se ejecutan en una cierta localidad; si los asociamos a la localidad 0, hacemos que se ejecuten en todas las localidades). Por cierto, observa que no comprobamos que el jugador tenga el objeto linterna. La utilidad de esto es que la linterna se va consumiendo también si la dejamos si está encendida, como es lógico.
Glolo para la localidad 0
VAL @10,1,M299 // si no está encendida retorna (imprime mensaje vacio)
OBFTOVAL 1,@2 // copia el flag de estado de la linterna al flag 2
DEC @2 // decrementa el flag 1 (la linterna consume energía)
VALTOOBF @2,1 // copia el valor decrementado de nuevo al flag de estado del objeto
VAL @2,0,M299 // si la linterna no se gastó (flag 2=0) retorna con mensaje vacio
OBJG 1,9 // si tiene la linterna, salta a la línea 9 (hay que informar de que se apaga)
CAMVAL @10,0,M299 // apaga la linterna, pero no informa porque no se tiene el objeto
RET // termina
CAMVAL @10,0,M6 // apaga la linterna e informa porque el jugador sí tiene el objeto
RET // termina
(el mensaje 6 es algo así como “La linterna se ha quedado sin energía”)
El siguiente asunto a resolver es la carga de la linterna. Pero nada más sencillo. Por ejemplo, supongamos que el jugador tiene una pila, el objeto número 2 (quizás la halla obtenido de una máquina recarga-pilas en medio de una caverna repleta de tesoros).
Orden: carg linterna (posible sinónimo: met pila)
Procedimiento EDAP:
OBJ 1,M1
OBJ 2,M7
OBFTOVAL 1,@2
ADDVAL @2,1000 // le ponemos 1000 más de carga, por ejemplo
VALTOOBJ
@2,1
LOBJ 2,999,M8 // ¡la pila ya no está disponible (la movemos a la localidad fantasma)!
RET
Mensaje 7: “No tienes la pila.”
Mensaje 8: “Has cargado la linterna usando la pila”
Éste es un método algo rudimentario, por ejemplo, la pila se “evapora” después de cargar la linterna y no puede ser recuperada, ni siquiera vacía, pero como primera aproximación es válida. En artículos siguientes veremos como hacer objetos contenedores en DAP.
Tan sólo resta ver qué hacemos con la localidad a oscuras. Pero nada más sencillo; sólo hay que crear un glolo en la localidad que deseemos (73 en nuestro ejemplo) que varíe la descripción de la misma según la linterna esté encendida o no.
Glolo para localidad 73
CAMTXT 73,M10 // pone el texto de descripción oscura
VAL @10,1,M12 // retorna si la linterna no está encendida
CAMTXT 73,M11 // la linterna estaba encendida, rectifica al texto de descripción normal
RET
Mensaje 10: “No logras ver nada”
Mensaje 11: “Estás en el recolector de tesoros” (descripción habitual de la localidad 73)
Mensaje 12: “Te sumes en las más profunda oscuridad...”
Y con esto hemos acabado esta primera entrega, que espero que le halla sido útil a alguien. Tan sólo recordaros la página WEB del DAP, donde podéis encontrar la última versión del mismo en línea junto a todo tipo de documentación:
http://www.oocities.org/sytovos/dap.htm