!% -~S !% -G !% $MAX_STATIC_DATA=20000 !% $MAX_PROP_TABLE_SIZE=63840 !% $MAX_VERBS=200 !% $MAX_ZCODE_SIZE=45000 !% $MAX_VERBSPACE=4500 ! ! "A·L·I·E·N" - Edición Especial ! ! Copyright (c) 2008-2018 Ricardo Pérez López (Alpha Aventuras) ! ! This program is free software: you can redistribute it and/or modify ! it under the terms of the GNU General Public License as published by ! the Free Software Foundation, either version 3 of the License, or ! (at your option) any later version. ! ! This program is distributed in the hope that it will be useful, ! but WITHOUT ANY WARRANTY; without even the implied warranty of ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ! GNU General Public License for more details. ! ! You should have received a copy of the GNU General Public License ! along with this program. If not, see . ! ==================================================================== ! ! CONSTANTES ! ! ==================================================================== Constant Story "~A·L·I·E·N~: La aventura - Edición Especial"; Constant Headline "^(c) 2008-2018 Alpha Aventuras^^ Teclea CRÉDITOS si quieres saber más acerca de la aventura, o AYUDA cuando estés bloqueado.^"; Release 1; Serial "180720"; ! Queremos usar el comando 'Salidas' Constant ADMITIR_COMANDO_SALIDAS; ! No queremos usar los comandos 'Lugares' y 'Objetos' Constant NO_PLACES; ! No queremos usar puntuación Constant NO_SCORE; ! Queremos que se muestren las deducciones del parser !Constant IMPRIMIR_DEDUCCIONES; ! Hay curiosidades al final del juego Constant AMUSING_PROVIDED; !Constant IMPRIMIR_DESCRIPCION_MAPA; ! Rutas de los móviles: !Constant RUTA_NINGUNA = 0; !Constant RUTA_ALEATORIA = 1; !Constant RUTA_SEGUIR_JUGADOR = 2; ! Máximo nivel de carga para la batería: Constant MAX_NIVEL_CARGA = 600; ! Alturas de los gráficos: Constant GRAFICOS_MINUSCULOS = 200; Constant GRAFICOS_PEQUENOS = 250; Constant GRAFICOS_MEDIANOS = 350; Constant GRAFICOS_GRANDES = 500; ! Canales de sonido y sus volúmenes: Constant CANAL_DETECTOR = 1; Constant VOLUMEN_DETECTOR = 70; Constant CANAL_TELETIPO = 2; Constant VOLUMEN_TELETIPO = 100; Constant CANAL_TICTAC = 3; Constant VOLUMEN_TICTAC = 100; Constant CANAL_SIRENA = 4; Constant VOLUMEN_SIRENA = 20; ! El canal de la música de fondo siempre tiene que ser ! DAMUSIX_NCANALMAX - 1 = 10 - 1 = 9: Constant CANAL_FONDO = 9; Constant VOLUMEN_FONDO = 50; ! Vamos a usar Damusix junto con SGW+DMX Constant SGW_CON_DAMUSIX; Constant SONIDO_BUCLE_INFINITO = -1; ! El color de fondo de la ventana gráfica es negro: Constant CLR_GG_PERSBACK = CLR_GG_BLACK; ! Es importante que todos los timers tengan duración distinta, porque ! esa es la forma que tengo de distinguirlos (es muy cutre, pero va): Constant TIMER_TICK = 1000; ! El timer a aplicar para el trueno: Constant TIMER_DURACION_TRUENO = 3; ! El timer para el laberinto es más largo: Constant TIMER_DURACION_LABERINTO = 7; ! El timer para cuando el alien está en la misma localidad: Constant TIMER_DURACION_ALIEN = 6; ! Tiempo de espera desde que sale el rayo hasta que desaparece: Constant TIMER_DURACION_ESPERA_TRUENO = 1; ! Timer de la autodestruccion: Constant TIMER_DURACION_AUTODESTRUCCION = 4; ! Timer de la batería de la linterna: Constant TIMER_DURACION_BATERIA = 5; ! ==================================================================== ! ! VARIABLES GLOBALES ! ! ==================================================================== ! Alto de la ventana gráfica: Global altoVentanaGrafica = GRAFICOS_MEDIANOS; ! Hay gráficos o no: Global hayGraficos = true; ! Hay sonidos: Global haySonido = true; Global haySonidoFondo = true; Global haySonidoDetector = true; ! Hay eventos en tiempo real: Global hayTiempoReal = true; ! Hay efecto de teletipo: Global hayTeletipo = true; ! Si se ha activado el listado automático de salidas: Global mostrarSalidas = true; ! Se pone a true y false en la rutina PermitirEmpujarDir, y luego se consulta en ! MensajesLibreria: Global estoyEmpujando = false; ! Interruptor de pistas: Global hayPistas = 0; ! Interruptor para indicar si hay que dibujar o no la línea de estado ! (ver rutina Inicializar): Global dibujarEstado = false; ! La imagen que representa la oscuridad: Global SGW_IMAGEN_OSCURIDAD = Oscuridad_jpg; ! ==================================================================== ! ! INCLUDES Y REPLACES ! ! ==================================================================== ! Nuestra versión de esta rutina sólo redibuja la línea de estado cuando ! la variable global dibujarEstado está a true: Replace DrawStatusLine; ! En este juego no se usa el BuscarEn (MIRA EN, BUSCA EN/DENTRO/DE/SOBRE, REGISTRA...) Replace SearchSub; ! En este juego no se usa el Consultar (CONSULTA, LEE, BUSCA EN x SOBRE y...) Replace ConsultSub; ! En este juego no se habla, ni se responde, ni se dice: Replace TellSub; Replace AnswerSub; Replace DecirSub; ! Con el siguiente Replace conseguimos que el objeto empujado hacia una dirección ! aparezca en la descripción de la localidad de destino del "empuje": Replace AllowPushDir; ! Ponemos nuestra propia versión de ZIPI_RunMenu y ZIPI_RunOtro, ! para el menú principal y las pistas: Replace ZIPI_RunMenu; Replace ZIPI_RunOtro; ! Nuestra versión elimina también los signos de admiración e interrogación: Replace QuitarAcentos; Replace EncenderGraficos; ! ==================================================================== Replace KeyDelay; Include "Parser"; Replace InitGlkWindow; Replace HandleGlkEvent; Replace IdentifyGlkObject; Include "SGW+DMX_NG"; ! Entre EParser y Acciones Include "alien.bli"; ! Los recursos gráficos de la aventura [ Amusing; print "- La aventura está basada en una idea original de Manolo (nuestro grafista).^^"; KeyDelay(); print "- La primera versión de A·L·I·E·N fue desarrollada hace más de quince años.^^"; KeyDelay(); print "- Esa primera versión la escribió Manolo en Spectrum usando el PAWS original^"; print " comprado a AD.^^"; KeyDelay(); print "- Inicialmente, esta aventura iba a ser un remake de ese ~clásico~, pero durante^"; print " el proceso decidimos ampliar bastante más la historia.^^"; KeyDelay(); print "- Hay una segunda parte de la versión original en Spectrum perdida en una casette^"; print " olvidada dentro de alguna caja extraviada en casa de Manolo.^^"; KeyDelay(); print "- El ~laberinto~ inicial estaba formado sólo por cinco localidades, para después^"; print " pasar a tener más de 70, y finalmente acabar teniendo alrededor de 30.^^"; KeyDelay(); print "- Esta Edición Especial es una versión muy, muy mejorada de la versión original^"; print " que se publicó en 2008.^^"; KeyDelay(); print "- La versión original de A·L·I·E·N publicada en 2008 recibió los siguientes^"; print " galardones:^^"; print " * La Comp Más Monstruosa (2008):^"; print " - Premio al relato más espeluznante^^"; print " * Premios Hispanos (2008):^"; print " - Nominada en las siguientes categorías: Mejor aventura, Aventura con^"; print " mejores puzzles, Mejor puzzle (pulsar los dos botones a la vez) y^"; print " Mejor PSI (el Alien y Jason, siendo la única aventura nominada dos^"; print " veces en la misma categoría)^"; print " - Premiada en las siguientes categorías: Interactividad, Jugabilidad,^"; print " Mejores PSIs y Mejor PSI (por Jason)^^"; KeyDelay(); print "- Todos las imágenes del juego son dibujos originales de Manolo, diseñados para^"; print " la ocasión.^^"; KeyDelay(); print "- ¿Has visto ya el documento ~", (s_b) "Holocubo.pdf", "~ usando la contraseña apropiada?^"; print " Contiene información muy interesante sobre el xenoforme.^^"; KeyDelay(); print "- Si te estás preguntado para qué sirve la palanca... Efectivamente: no sirve^"; print " para nada en absoluto.^^"; ]; [ ImprimirPrompt; print (s_in) "^> "; ]; Object LibraryMessages with before [; Look: ! Copiamos el código de Mensajes.h. Sólo cambiamos el segundo ! EscribirListaDesde, para que cuando se deje en el suelo la ! linterna, no diga: "Puedes ver una linterna (en la que ves una batería)." switch (lm_n) { 1: print " (sobre ", (the) lm_o, ")"; 2: print " (en ", (the) lm_o, ")"; 3: print " (como ", (object) lm_o, ")"; 4: print "^Sobre ", (the) lm_o; WriteListFrom(child(lm_o), ENGLISH_BIT + RECURSE_BIT + PARTINV_BIT + TERSE_BIT + ISARE_BIT + CONCEAL_BIT); "."; default: if (lm_o ~= location) { if (lm_o has supporter) print "^Sobre "; else print "^En "; print (the) lm_o; print " puedes ver "; } else print "^También puedes ver "; if (n == 5) print "también "; ! ????? ! Quitamos RECURSIVO_BIT y INFOPARCIAL_BIT: WriteListFrom(child(lm_o), ENGLISH_BIT + WORKFLAG_BIT + TERSE_BIT + CONCEAL_BIT); if (lm_o ~= location) "."; "."; } Prompt: if (location == procesador) { procesador.comprobar_segunda_parte(); } ImprimirPrompt(); rtrue; Go: switch (lm_n) { 2: if (estoyEmpujando) { "^No puedes seguir empujando porque no hay salida hacia ", (the) noun, "."; } else { "No puedes ir por ahí, porque no hay salida hacia ", (the) noun, "."; } 5: if (estoyEmpujando) { "^No puedes empujar nada a través ", (del) lm_o, "."; } else { "No puedes pasar a través ", (del) lm_o, "."; } } Take: if (lm_n == 1) { print "Recoges "; ! Corrige fallo de la librería: no se puede usar lm_o aquí, no sé por qué. ! En su lugar, hay que usar noun. ! Ver INFSP6/Spanish.h línea 3908. if (noun has moved) { print (the) noun; } else { print (a) noun; } "."; } Drop: if (lm_n == 4) { "Dejas ", (the) lm_o, "."; } Remove: if (lm_n == 3) { if (verb_word == 'quita') { "Quitas ", (the) lm_o, " ", (del) second, "."; } else { "Sacas ", (the) lm_o, " ", (del) second, "."; } } Miscellany: switch (lm_n) { 4: TextoLlamativo(" ¡Enhorabuena! Has acabado la aventura "); rtrue; 10: rtrue; 13: ! Reactivamos timer en caso de UNDO: ! ControlTimer.ReactivarTick(); "[Retrocediendo al turno anterior.]"; 17: switch (random(4)) { 1: "Está muy oscuro y no puedes ver nada."; 2: "Todo está demasiado oscuro y no aprecias nada con claridad."; 3: "La oscuridad te impide ver dónde te encuentras."; 4: "Te mueves a tientas a través de una oscuridad que te impide ver nada."; } 19: "Has tenido días mejores..."; 30: switch (random(3)) { 1: "No encuentro eso que dices."; 2: "No veo nada parecido por aquí."; 3: "Parece que no hay nada de eso."; }; 27: "Las palabras se te agolpan en los labios."; 38: switch (random(5)) { 1: "¿Qué quieres decir con eso?"; 2: "Lo siento, no te entiendo."; 3: "Intenta ser un poco más preciso."; 4: "No comprendo eso que dices."; 5: "¿Qué intentas decir?"; } } ]; ! ==================================================================== Include "VerbLib"; [ InScope actor; ! Ponemos a Jason al alcance para hablar, ya que tenemos comunicador: if (scope_reason == TALKING_REASON or EACH_TURN_REASON && comunicador in player && comunicador has worn) { if (jason has absent) { PlaceInScope(jason_inerte); } else if (jason notin LugarReal() || location == thedark) { PlaceInScope(jason); } } ! Ya no la ponemos al alcance. En su lugar, decimos que está en todas partes ! (ver su propiedad esta_en). El motivo es que así ya podemos pedirle a ! Madre que abra puertas cuando estemos delante de ellas: ! ! Ponemos a Madre al alcance para hablar y para que se ejecute su ! ! rutina cada_turno: ! if (razon_alcance == RAZON_HABLAR or RAZON_CADA_TURNO && ! comunicador in jugador && comunicador has puesto) { ! PonerAlAlcance(computadora); ! } ! ! ! Madre está físicamente en nave1 y en nave2. Aquí no preguntamos por ! ! razon_al_alcance, por lo que Madre estará al alcance para cualquier ! ! acción, como si se pusiera 'esta_en nave1, nave2'. Pero no uso la ! ! propiedad esta_en porque entonces se ejecutaría dos veces su rutina ! ! cada_turno: ! if (LugarReal() == nave1 or nave2) { ! PonerAlAlcance(computadora); ! } ! Ponemos la compuerta de la nave al alcance de la computadora, para que pueda abrirla ! aunque no estemos físicamente delante de la puerta: if (actor == computadora) { PlaceInScope(nave); PlaceInScope(puerta_nave); PlaceInScope(compartimento_trajes); } ! Así le puedes decir "jason, sigueme" o "jason, quedate" incluso aunque no esté en la ! misma localidad que tú: if (action_to_be == ##Seguir or ##Quedar or ##Wait && actor == jason) { PlaceInScope(player); } rfalse; ]; Include "Rastros_NG"; ! Mis rastros son: sangre del alien, cable blanco y cable negro Include "Barra"; ! Para cambiar la barra de estado Object barra_estado class objeto_barra_estado with modo BE_COMPUESTO, disposicion 1 1 true BE_LOCALIDAD 29 1 true BE_TEXTO 45 1 true BE_TEXTO 65 1 true BE_TEXTO 68 1 true BE_TURNOS, texto [ x; switch (x) { 1: if (linterna has on && bateria in linterna) { print_ret " | Linterna: ", bateria.nivel_carga(), "%"; } 2: if (alien.comportamiento == 4 && autodestruccion.falta_en_barra > 0) { print " | Autodestruc: ", autodestruccion.falta_en_barra, " "; if (autodestruccion hasnt general) { "min."; } else { "seg."; } } else if (rifle in player && detector_movimiento has on && alien.distancia > 0 && alien.distancia < 6 && alien hasnt absent) { if (parent(alien) == LugarReal()) { print_ret " | Detector: 0 m."; } else { print " | Detector: ", 10 * alien.distancia, " m. "; switch (alien.sentido) { n_obj: "N"; s_obj: "S"; e_obj: "E"; w_obj: "O"; u_obj: "AR"; d_obj: "AB"; } } rtrue; } 3: print " |"; } ], lineas_inv BE_INV_TOTAL; [ DrawStatusLine; if (dibujarEstado) { barra_estado.dibujar(); } ]; ! Hay que definirla antes de incluir Moviles_NG: Class Lugar class LugarConRastro with sgw_mus Estancia_ogg, sgw_vol VOLUMEN_FONDO, describe [; PrintOrRun(self, description); if (mostrarSalidas) { print "^"; glk_set_style(style_Emphasized); ; style roman; rtrue; } else { rtrue; } ], number, dibujado false, before [; Examine, Touch: if (noun == d_obj) { ! Examinamos el suelo if (EsExterior(self)) { ! Si estamos en el exterior... "Una superficie de polvo y arena en forma de barro que se acumula en las suelas de tus botas. Además, la lluvia se encharca con relativa frecuencia."; } else { "Una superficie metálica y sólida."; } } else if (noun == u_obj && self ~= hueco_techo) { ! Examinamos el techo if (EsExterior(self)) { ! Si estamos en el exterior... if (tu_traje in self && tu_traje has worn) { "La intensa lluvia baña tu casco."; } else { "La intensa lluvia ciega tus ojos."; } } else { "Tuberías y estructuras metálicas recorren el techo."; } } ], after [; Go: ! Si no está el alien presente, se resetea su oportunidad a cero y ! su capricho a 50: if (alien notin LugarReal()) { if (alien.oportunidad ~= 0) { alien.oportunidad = 0; } if (alien.comportamiento == 1 or 3 && alien.capricho == 0) { alien.capricho = 50; } } ], each_turn [; ! Así conseguimos que el alien vaya el doble de lento que nosotros cuando nos ! persiga (alternamos persecución con detención). Pero irá igual de rápido cuando ! estemos dentro de la zona de emergencia con la puerta cerrada (para que no deje ! de decir que hay algo intentando abrir la puerta): if (alien.comportamiento == 3) { if (alien.tipo_de_movimiento == MOVIMIENTO_PERSEGUIR && (puerta_emergencia has open || (puerta_emergencia hasnt open && (LugarReal() ofclass ZonaEmergencia && parent(alien) ofclass ZonaEmergencia) || (~~(LugarReal() ofclass ZonaEmergencia) && ~~(parent(alien) ofclass ZonaEmergencia))))) { PNJ_Ruta(alien, MOVIMIENTO_NINGUNO); } else { PNJ_Ruta(alien, MOVIMIENTO_PERSEGUIR, player); } } ], has ~light; Include "Moviles_NG"; ! La librería Moviles retocada por mí Include "PnjPuertas_NG"; ! La librería PnjPuertas retocada por mí (muy poco) Include "PNJactor_NG"; ! Librerías que hacen que un PNJ pueda coger y dejar Include "PNJacciones_NG"; ! objetos como el PJ (poner detrás de Moviles y PnjPuertas) Include "Etemas"; ! Los temas de conversación Include "Decorado_NG"; ! Objetos de decorado Include "ExaminarFalso"; ! Poder examinar objetos sólo con su nombre Include "Teletipo"; ! Teletipo para sacar mensajes letra a letra Include "Pistas"; ! Las pistas creadas con ZIPI Include "Timer"; ! Mi librería de eventos temporizados Include "IntNombre"; ! Poder usar adjetivos como en InformATE class EscenarioAbrible with when_open [; print (The) self, " está abiert", (o) self, ".^"; rtrue; ], when_closed [; print (The) self, " está cerrad", (o) self, ".^"; rtrue; ], ! Cuando está abierto, pasa de ser escenario a ser estático. Esto se hace para que ! se muestre cuando está abierto, usando la propiedad si_abierto. En realidad, la ! propiedad si_cerrado no se usa, porque cuando está cerrado es un escenario, y por ! tanto no se describe. abrir [; self.sonido_abrir_cerrar(); give self open; give self ~scenery; give self static; ], cerrar [; self.sonido_abrir_cerrar(); give self ~open; give self scenery; give self ~static; ], sonido_abrir_cerrar [ snd; if (self notin LugarReal()) rfalse; snd = 0; switch (self) { puerta_nave: snd = Puerta2_ogg; puerta_procesador: snd = Puerta2_ogg; puerta_emergencia: snd = Puerta2_ogg; compartimento_trajes: snd = Puerta1_ogg; } if (snd ~= 0) Damusix.TocarV(snd); ], after [; Open: self.abrir(); Close: self.cerrar(); ], has scenery openable; ! Un contenedor que, cuando se examina, describe su contenido. Un objeto de esta clase ! debe usar la propiedad descripcion_real en lugar de descripcion: class Contenedor with descripcion_real "", description [; print (string) self.descripcion_real, " "; if (self has open) { if (children(self) == 0) { "Está abiert", (o) self, ", pero vací", (o) self, "."; } else { print "Está abiert", (o) self, ", y en su interior puedes ver "; WriteListFrom(child(self), ENGLISH_BIT); print ".^"; } } else { if (self has transparent) { print "Está cerrad", (o) self, ", pero al ser transparente puedes ver "; if (children(self) == 0) { "que está vacío."; } else { print "que en su interior hay "; WriteListFrom(child(self), ENGLISH_BIT); print ".^"; } } else { "Está cerrad", (o) self, "."; } } ], has container; ! ==================================================================== ! ! HABITACIONES ! ! ==================================================================== ! El atributo general indica si no es la primera vez que se sale de la nave. Se usa para ! explicar (o no) lo de la zona intermedia de descompresión Object nave1 "Interior de la nave" class Lugar with description "La nave de exploración Alpha dispone de todo lo necesario para satisfacer los requisitos más básicos en cuanto a soporte vital y contención. Los instrumentos brillan y parpadean de forma insana, y frente a ellos se disponen los dos únicos asientos del vehículo. Sus angostas paredes aumentan la sensación de claustrofobia y los enormes ventanales ofrecen una vista desoladora del exterior.", w_to nave2, out_to puerta_nave, sgw_img Nave1_jpg, sgw_mus Nave_ogg, Close [; puerta_nave.cerrar(); HablaMadre("Cerrando compuerta de la nave."); ], before [ i k t; Examine: if (noun == out_obj) { PrintOrRun(decorado_nave1, desc_ventanales); rtrue; } Sentarse: "No es necesario sentarse para poder operar con los controles de la nave, ni para hablar con su computadora."; ! Exit: ! <>; Go: if (noun == out_obj) { ! Si el procesador atmosférico funciona, no hay que entrar a mirar si llevan trajes if (procesador.arreglado()) { ! self.mostrar_quien_sale(jason in self && ! jason.tipo_de_movimiento == MOVIMIENTO_PERSEGUIR && ! jason.perseguido == jugador); rfalse; } if (puerta_nave hasnt open) { rfalse; } k = 0; ! Comprueba si el jugador lleva puesto el traje. Para ello, recorre todos los ! objetos del jugador en busca de uno que sea de la clase TrajeAtmosferico y ! que además lo lleve puesto encima. objectloop (i in player) { if (i ofclass TrajeAtmosferico && i has worn) k++; } if (k == 0) { HablaMadre("No debería salir sin llevar puesto su traje atmosférico."); "^Decides seguir sus sabios consejos."; } ! Comprobar si Jason está aquí, y sigue al jugador, y lleva puesto el traje. ! Si no lo lleva puesto, se lo pone antes de salir. if (jason in self && jason.tipo_de_movimiento == MOVIMIENTO_PERSEGUIR && jason.perseguido == player) { t = 0; objectloop (i in jason) { if (i ofclass TrajeAtmosferico) t = i; } ! Si no lleva ningún traje atmosférico, intenta cogerlo: if (t == 0) { ! PNJ_Ruta(jason, MOVIMIENTO_NINGUNO); if (traje_jason notin jason) { if (PuedeVer(jason, traje_jason)) { HablaJason("De acuerdo, pero antes cogeré el traje atmosférico."); if (~~(jason.intentar_coger(traje_jason))) { PNJ_Ruta(jason, MOVIMIENTO_NINGUNO); ! rfalse; } else { give traje_jason worn; move jason to exterior1; } print "^"; } else { HablaJason("No puedo salir de la nave. No llevo puesto mi traje, y no lo veo por aquí."); ! rfalse; } } else { if (traje_jason hasnt worn) { give traje_jason worn; HablaJason("De acuerdo, pero antes me pondré el traje atmosférico."); print "^"; move jason to exterior1; } } ! print "[Jason se queda dentro, al no disponer de protección vital para ! el exterior.]^^"; } else { ! Si lo tiene, sale o se lo pone antes. if (t hasnt worn) { give t worn; ! jason.precamino = RUTA_SEGUIR_JUGADOR; PNJ_Ruta(jason, MOVIMIENTO_PERSEGUIR, player); print "[Jason se pone el traje antes de salir.]^^"; } else { print "[Jason sale de la nave con su traje puesto.]^^"; } move jason to exterior1; } self.mostrar_quien_sale(traje_jason in jason && traje_jason has worn); ! t ~= 0 rfalse; } self.mostrar_quien_sale(0); rfalse; } ], mostrar_quien_sale [ c; ! El parámetro c indica si el jugador sale solo de la nave, o Jason va con él ! c = true: Salen juntos ; c = false: El jugador sale solo Damusix.TocarV(Descompresion_ogg, 100); ! Si es la primera vez que se sale: if (self hasnt general) { give self general; if (c) { ! Salen juntos: print "Ataviados con vuestros trajes atmosféricos, Jason y tú cruzais la compuerta de la nave y os introducís en un reducido habitáculo destinado a la descompresión y aislamiento del exterior. Madre cierra la puerta que acabais de pasar, se observan chorros de aire y vapor saliendo de todas los rincones del cubículo y, tras varios segundos, la compuerta exterior se abre, dejando vía libre para que podáis salir de la nave.^"; KeyDelay(); "^Lentamente vais bajando por la rampa de acceso. La lluvia impregna vuestros trajes, y vuestros pies tocan finalmente el barro de la superficie." ; } else { ! Sólo sale el jugador: print "Ataviado con tu traje atmosférico, cruzas la compuerta de la nave y te introduces en un reducido habitáculo destinado a la descompresión y aislamiento del exterior. Madre cierra la puerta que acabas de pasar, se observan chorros de aire y vapor saliendo de todas los rincones del cubículo y, tras varios segundos, la compuerta exterior se abre, dejando vía libre para que puedas salir de la nave.^"; KeyDelay(); "^Lentamente vas bajando por la rampa de acceso. La lluvia impregna tu traje, y tus pies tocan finalmente el barro de la superficie." ; } } else { if (~~(procesador.arreglado())) { if (c) { "Jason y tú salís al exterior sin problemas, protegidos por vuestros trajes atmosféricos."; } else { "Sales al exterior sin problemas, protegido por tu traje atmosférico."; } } ! print " A continuación, Madre cierra la compuerta de la nave.^"; } ], after [ jason_viene; Go: ! Si venimos de fuera: if (noun == in_obj) { jason_viene = jason in exterior1 && jason.tipo_de_movimiento == MOVIMIENTO_PERSEGUIR && jason.perseguido == player; Damusix.TocarV(Descompresion_ogg); if (jason_viene) { print "Entráis "; } else { print "Entras "; } print "al interior de la nave a través del compartimento de descompresión.^"; puerta_nave.cerrar(); if (jason in self && jason.tipo_de_movimiento ~= MOVIMIENTO_PERSEGUIR) { PNJ_Ruta(jason, MOVIMIENTO_PERSEGUIR, player); } else { if (jason_viene) { move jason to nave1; PNJ_Ruta(jason, MOVIMIENTO_PERSEGUIR, player); } } } ], ! Comprueba si se ha llegado al final del juego. Para ello, comprueba que ! Jason está aquí, y que la vaina está abierta. Esto último significará que ! lo hemos sacado de la vaina, y por tanto, si hemos llegado hasta aquí, es ! que hemos acabado la aventura: each_turn [ t; if (jason in self && vaina has open) { Bandera_Fin(2); t = false; if (hayGraficos) { t = true; ApagarGraficosSub(true); } KeyDelay(); clearMainWindow(); tt_final.visualiza(); Damusix.TocarV(Grito_Jason_ogg); if (t) { EncenderGraficosSub(true); viewImageCenter(Logo_Alien_jpg); } } ], has light; Object decorado_nave1 nave1 class Decorado with desc_instrumentos "Los paneles de instrumentación están llenos de indicadores y botones por todas partes. En un lateral también se aprecia un cargador de baterías.", desc_ventanales "A través de las ventanas que dan al exterior únicamente se aprecia una densa luz blanco-amarillenta, proveniente de los focos que iluminan el lugar de aterrizaje con un fulgor fantasmagórico de un tono uniforme ocasionalmente roto por el tintinear de la lluvia impactando en el cristal y la cegadora luminiscencia de los relámpagos.", desc_asientos "Son unos asientos mullidos y cómodos. Algo que contrasta mucho con la deshumanización del resto del decorado.", desc_paredes "En una de las paredes puedes observar un compartimento destinado a almacenar los trajes atmosféricos.", before [; Touch: switch (self.number) { 'ventanales', 'ventanal', 'cristales', 'cristal', 'ventanas', 'ventana': "Una superficie lisa que, sin embargo, traspasa la humedad del exterior."; 'paneles', 'panel', 'instrumentos', 'instrumento', 'indicadores', 'indicador': "La mayoría de las funciones de la nave están gobernadas por Madre, así que lo mejor será tocar lo menos posible."; 'asientos', 'asiento': "Son mullidos y confortables, pero ahora no es el momento de sentarse."; 'paredes', 'pared': "Son frías y sólidas al tacto."; } ], describe 'paneles' [; return self.desc_instrumentos; ] G_PLURAL 'panel' [; return self.desc_instrumentos; ] 0 'instrumentos' [; return self.desc_instrumentos; ] G_PLURAL 'instrumento' [; return self.desc_instrumentos; ] 0 'indicadores' [; return self.desc_instrumentos; ] G_PLURAL 'indicador' [; return self.desc_instrumentos; ] 0 'botones' [; return self.desc_instrumentos; ] G_PLURAL 'boton' [; return self.desc_instrumentos; ] 0 'ventanales' [; return self.desc_ventanales; ] G_PLURAL 'ventanal' [; return self.desc_ventanales; ] 0 'ventanas' [; return self.desc_ventanales; ] G_FEMENINO + G_PLURAL 'ventana' [; return self.desc_ventanales; ] G_FEMENINO 'cristales' [; return self.desc_ventanales; ] G_PLURAL 'cristal' [; return self.desc_ventanales; ] 0 'lluvia' [; return self.desc_ventanales; ] G_FEMENINO 'asientos' [; return self.desc_asientos; ] G_PLURAL 'asiento' [; return self.desc_asientos; ] 0 'paredes' [; return self.desc_paredes; ] G_FEMENINO + G_PLURAL 'pared' [; return self.desc_paredes; ] G_FEMENINO; Object nave "nave" class EscenarioAbrible with name_m 'vehiculo', name_f 'nave' 'alpha', adjectives 'exploracion', gender G_FEMENINO, found_in nave1 nave2 exterior1, before [; Open: <>; Close: <>; Examine: switch (LugarReal()) { nave1, nave2: PrintOrRun(LugarReal(), description); exterior1: "Parece más grande por fuera..."; } rtrue; ]; Object descompresion "cámara de descompresión" with name_m 'habitaculo', name_f 'camara' 'cabina' 'descompresion' 'despresurizacion', gender G_FEMENINO, description "Es el recinto intermedio entre la nave y el exterior. Se usa para acomodar la presión y la atmósfera al salir o entrar en la nave.", before [; GoIn, Enter: <>; ], has scenery; Object puerta_nave "compuerta de la nave" nave1 class PNJPuerta class EscenarioAbrible with ! La librería PnjPuertas ya incluye la palabra 'puerta' como nombre name 'compuerta', adjectives 'nave' 'vehiculo', description [; if (self hasnt open) { print "La puerta está cerrada, impidiendo el acceso al "; if (LugarReal() == nave1) { "exterior."; } else { "interior."; } } else { print "La puerta está abierta y permite acceder al "; if (LugarReal() == nave1) { print "exterior"; } else { print "interior"; } " de la nave."; } ], pnj_abrir [ act; if (self hasnt open) { if (act == jason) { HablaJason("¡No puedo entrar! ¡La compuerta de la nave está cerrada!"); rfalse; } print "^Alguien intenta entrar en la nave, pero la compuerta está cerrada.^"; rfalse; } else { return 2; } ], out_to exterior1, in_to nave1, interior nave1, exterior exterior1, before [; Open: if (self hasnt open) { "No puedes abrir la compuerta directamente. Pide ayuda a la computadora."; } else { "La compuerta de la nave ya está abierta."; } Close: if (self has open) { "No puedes cerrar la compuerta directamente. Pide ayuda a la computadora."; } else { "La compuerta de la nave ya está cerrada."; } ! Esto es para que la librería no diga que está abierta o cerrada: Examine: PrintOrRun(self, description); rtrue; ], has female; Object compartimento_trajes "compartimento de trajes" nave1 class Contenedor class EscenarioAbrible with name 'compartimento', adjectives 'trajes' 'atmosfericos', descripcion_real "El compartimento donde se almacenan los trajes se encuentra acoplado a una de las paredes de la nave.", before [; Open, Close: "No puede hacerse directamente. Pide ayuda a la computadora."; ], has transparent; Object cargador "cargador" nave1 with name 'cargador' 'recargador', ! esta_en nave1 oficina aula, adjectives 'bateria' 'baterias', description [; print "Es un pequeño compartimento metálico con la forma y el tamaño justos para poder contener una batería estándar."; if (bateria in self) { print " Dentro está la batería de la linterna."; } ""; ], before [; Take: "El cargador está fijo en el panel de instrumentos."; ], ! Impide que puedas meter otra cosa que no sean las baterías: react_before [; RecargarEn: if (bateria in player || parent(bateria) in player) { if (bateria in linterna && linterna hasnt open) { give linterna open; print "Abres la linterna para sacar la batería. "; } move bateria to player; <>; } else { "No tienes nada que recargar."; } Insert: if (second == self) { if (noun ~= bateria) { HablaMadre("El cargador sólo admite baterías de formato estándar."); rtrue; } } ], after [; Receive: bateria.energia = MAX_NIVEL_CARGA; print "Metes la batería de la linterna dentro del cargador...^"; if (LugarReal() == nave1) { HablaMadre("Batería recargada al 100%."); } rtrue; ], has scenery container open; class TrajeAtmosferico with name 'traje' 'atmosferico' 'trajes//p' 'atmosfericos//p', ! nombre_corto "traje atmosférico", ! plural "trajes atmosféricos", ! describir [; ! "El traje atmosférico ", (string) self.color, " yace inerte en el suelo."; ! ], color "", lateral "", ! Los trajes se muestran juntos al listarse una localidad o un inventario. Quedaría: ! "Puedes ver dos trajes atmosféricos (tu traje y el traje de Jason)" list_together "trajes atmosféricos", add_to_scope 0, description [; print "Es un traje hermético, compuesto por un mono de un material resistente, botas, guantes y un casco destinado a proporcionar aislamiento y oxígeno al usuario. Es de color ", (string) self.color, ", y lleva impreso ", (string) self.lateral, " en un lateral."; if (self == traje_jason && jason in vaina) { " Tiene un corte bastante grande en un costado."; } else { ""; } ], before [ l; Touch: "El traje atmosférico está compuesto de un tejido fino pero muy resistente, permitiendo una gran movilidad sin perder sus características de aislamiento."; Disrobe: ! El jugador (o Jason) muere si se quita el traje fuera de la nave si no está ! arreglado el procesador atmosférico if (actor == player) { l = LugarReal(); } else { l = parent(actor); } if (l ~= nave1 or nave2 && circuito hasnt general) { if (actor == player) { "No deberías quitarte el traje fuera de la nave hasta que el aire sea respirable."; } else { HablaJason("No quiero morir de asfixia, señor..."); rtrue; } } rfalse; ], after [; Examine: ! El jugador ya puede ver las botas, los guantes y el casco tu_traje.add_to_scope = decorado_traje; traje_jason.add_to_scope = decorado_traje; ], invent [; if (inventory_stage == 2) { if (self has worn) { print " (puesto)"; } rtrue; } ], has clothing; Object tu_traje "traje" compartimento_trajes class TrajeAtmosferico with name 'mi' 'mio' 'tu' 'tuyo', ! Para poder decir: "coge mi traje", o "coge el traje rojo" adjectives 'rojo', ! Para que diga: "puedes ver tu traje" articles "Tu" "tu" "tu", color "rojo", lateral "tu nombre", react_before [; Touch: if (self has worn && noun ~= soldador && noun ~= rastro_acido) { "Tu tacto es muy poco sensible a través de los guantes."; } Smell: if (self has worn) { "Apenas puedes oler nada a través del casco."; } Listen: if (self has worn && (~~(parent(self) ofclass ZonaNorte))) { "El casco te impide oir nada con claridad."; } Taste: if (self has worn) { "No puedes llevarte nada a la boca con el casco puesto."; } ], before [; ! El jugador no puede ponerse dos trajes a la vez Wear: if (traje_jason in player && traje_jason has worn) { print_ret "Ya llevas puesto ", (the) traje_jason, "."; } ]; Object traje_jason "traje de Jason" compartimento_trajes class TrajeAtmosferico with ! Para poder decir: "jason, coge tu traje", "coge el traje de jason" o ! "coge el traje verde" adjectives 'jason' 'verde' 'suyo', ! No sé si es realmente necesario, pero lo pongo por si acaso... article "el", color "verde", lateral "el nombre de Jason", invent [; if (parent(self) == jason) { ! En el caso de que el traje lo lleve Jason: if (action == ##Inv) { print "mi traje"; ! Caso "jason, inventario" } else { print "su traje"; ! Caso "ex jason" } } else { print "el traje de Jason"; ! En el caso de que el traje no lo lleve Jason } if (self has worn) { print " (puesto)"; } rtrue; ], before [; Wear: if (noun == traje_jason) { "No es de tu talla."; } if (tu_traje in player && tu_traje has worn) { print_ret "Ya llevas puesto ", (the) tu_traje, "."; } ]; ! El decorado de los trajes: Object decorado_traje class Decorado with desc_guantes "Sujetos firmemente al resto del traje, son flexibles y muy cómodos.", desc_botas "Recias y fuertes, para su uso en cualquier entorno.", before [; Touch: if (TestScope(traje_jason) && ObjectIsUntouchable(traje_jason)) rtrue; if (ObjectIsUntouchable(tu_traje)) rtrue; switch (self.number) { 'guantes', 'guante': "Son guantes fuertes y resistentes."; 'botas', 'bota': "Las botas son gruesas, y tienen una suela dura como el granito."; 'casco': "El casco es liso y suave al tacto, pero tan duro como el metal, si bien no da sensación de frío."; } Wear: <>; Disrobe: <>; Take: <>; Drop: <>; ], describe 'guantes' [; return self.desc_guantes; ] G_PLURAL 'guante' [; return self.desc_guantes; ] 0 'botas' [; return self.desc_botas; ] G_FEMENINO + G_PLURAL 'bota' [; return self.desc_botas; ] G_FEMENINO 'casco' "Un casco herméticamente cerrado que permite respirar en este nocivo ambiente, y provisto de un enorme visor." 0; Object traje_inutil "restos del traje de Jason" with name 'restos' 'traje', adjectives 'jason', article "los", add_to_scope decorado_traje_inutil, description "Esto es lo que ha quedado del traje de Jason tras su enfrentamiento con la criatura. Tiene una generosa hendidura en un lateral. Sin duda, está del todo inservible.", initial "El traje de Jason reposa inservible en el suelo de la sala.", before [; Examine: rfalse; default: "No merece la pena. No sirve para nada ya."; ], has pluralname; Object decorado_traje_inutil class Decorado with desc_guantes "Los guantes han perdido su estanqueidad con el resto del traje.", desc_botas "Las botas están llenas de barro y de la misma sustancia pegajosa que se puede apreciar en toda la estancia.", before [; Touch: switch (self.number) { 'guantes', 'guante': "Son guantes fuertes y resistentes."; 'botas', 'bota': "Están pegajosas debido a la asquerosa sustancia que las recubre."; 'casco': "La rotura del casco parece causada por algún tipo de sustancia cáustica, más que por un objeto cortante o romo."; } ], describe 'guantes' [; return self.desc_guantes; ] G_PLURAL 'guante' [; return self.desc_guantes; ] 0 'botas' [; return self.desc_botas; ] G_FEMENINO + G_PLURAL 'bota' [; return self.desc_botas; ] G_FEMENINO 'casco' "El casco está roto por la parte lateral del visor." 0; Object nave2 "Parte posterior de la nave" class Lugar with description "Esta zona de la nave está destinada a bodega y almacenamiento. El armario plateado y brillante situado al fondo es el único mobiliario visible. Por lo demás, destaca el enorme contraste con la proa de la nave en cuanto a falta de decoración e instrumentación.", e_to nave1, sgw_img Nave2_jpg, sgw_mus Nave_ogg, has light; Object decorado_nave2 nave2 class Decorado with desc_paredes "Las paredes en esta zona de la nave resultan más austeras y frías.", before [; if (self.number == 'paredes' or 'pared') { "Frías y secas al tacto."; } ], describe 'paredes' [; return self.desc_paredes; ] G_FEMENINO + G_PLURAL 'pared' [; return self.desc_paredes; ] G_FEMENINO; Object armario "armario" nave2 class Contenedor class EscenarioAbrible with name 'armario', descripcion_real "Un armario metálico, de aspecto plateado y liso. Sobresale de una pared al fondo.", before [; Touch: "Suave, liso... pero fuerte al mismo tiempo."; ]; Object destornillador "destornillador" armario with name 'destornillador' 'atornillador', description "Un destornillador manual de precisión, con puntas intercambiables para poder trabajar con tornillos de cualquier forma y tamaño estándar."; Object palanca "palanca" armario with name 'palanca', description "Una palanca de un metal duro pero ligero.", has female; Object linterna "linterna" armario with name 'linterna', description [; print "Una linterna "; if (self has on) print "(encendida)"; else print "(apagada)"; "."; ], before [; Receive: if (noun ~= bateria) { "En la linterna sólo puedes meter una batería estándar."; } Examine: print "Es un dispositivo que proyecta un haz de luz directo muy potente"; if (self hasnt on) { print ". Está apagada"; if (self has open) { print ", pero no la podrás encender hasta que la cierres"; } } else { if (bateria.energia < 10) { print ". Brilla con una luz muy tenue"; } else { print ". Está encendida"; } } if (bateria notin self) { ". Además, le falta la batería."; } else { ". Lleva dentro una batería de energía que actualmente está al ", bateria.nivel_carga(), "% de su capacidad de carga."; } Burn: <>; SwitchOn: if (bateria notin self) { "A la linterna le falta la batería."; } if (self has open) { "Tienes que cerrar la linterna primero."; } if (bateria.energia <= 0) { "Desgraciadamente, parece que se ha agotado la batería."; } ], encender [; if (player hasnt light && location == thedark && real_location hasnt light) { viewImageCenter(real_location.sgw_img); } give self on; give self light; StartDaemon(self); ], apagar [; if (player hasnt light && location hasnt light) { viewImageCenter(SGW_IMAGEN_OSCURIDAD); } give self ~on; give self ~light; StopDaemon(self); ], after [; Open: if (self has on) { self.apagar(); "Abres la linterna. Al hacerlo, esta se apaga automáticamente. Dentro ves la batería que le suministra energía."; } else { if (bateria in linterna) { "Abres la linterna. Dentro ves la batería que le suministra energía."; } } SwitchOn: self.encender(); SwitchOff: self.apagar(); Receive: print "Colocas la batería dentro de la linterna, y a continuación la cierras.^"; keep_silent = 1; ; keep_silent = 0; rtrue; ], pierde_energia [; if (self has on && bateria.energia > 0) { bateria.energia = bateria.energia - bateria.decremento; if (bateria.energia <= 0) { bateria.energia = 0; self.apagar(); ControlTimer.PrepararImpresion(); "^La linterna se ha quedado sin batería."; } if (bateria.nivel_carga() < 10) { ControlTimer.PrepararImpresion(); "^La linterna se está quedando sin batería..."; } } ], daemon [; self.pierde_energia(); ], invent [; if (inventory_stage == 2) { if (self has on) { print " (encendida)"; } else { print " (apagada)"; } rtrue; } ], has female switchable openable container transparent; Object bateria "batería" linterna with name_f 'bateria' 'pila', name_fp 'baterias' 'pilas', gender G_FEMENINO, description [ p; print "La batería de la linterna es del tipo RU75 universal. "; p = parent(self); if (~~((p ofclass Lugar) || (p ofclass Movil) || (bateria in player))) { print "Está colocada en ", (the) p, ". "; } "Actualmente está al ", self.nivel_carga(), "% de su capacidad."; ], nivel_carga [; return (self.energia * 100) / MAX_NIVEL_CARGA; ], energia MAX_NIVEL_CARGA, decremento 4, before [; SwitchOn, Tie: <>; ]; class LugarExterior class Lugar, has light; Object exterior1 "Junto a la nave" class LugarExterior with description "Estás en el exterior, junto a tu nave. La tenue luz blanquecina que flota en el ambiente apenas te deja discernir las enormes y majestuosas formas de la colonia minera. A causa de la lluvia, una neblina fantasmagórica lo envuelve todo, lo que hace que las siluetas de la colonia se difuminen. La temperatura es elevada, y la sensación de agobio, palpable.", sgw_img Exterior1_jpg, sgw_mus Lluvia_ogg, in_to puerta_nave, s_to exterior3, n_to junto_procesador, antesPNJ [; Go: if (noun == in_obj && puerta_nave hasnt open) { HablaJason("La compuerta de la nave está cerrada."); } ], after [; Go: ! Si venimos de dentro de la nave, Madre cierra la puerta automáticamente if (noun == out_obj) { puerta_nave.cerrar(); } ]; Object decorado_exterior1 exterior1 class Decorado with desc_niebla "Es un efecto provocado por la intensa lluvia, que te impide ver con claridad los límites exteriores de la colonia.", describe 'luz' "Es un halo inmaterial que lo envuelve todo con un manto azulado." G_FEMENINO 'lluvia' "Las gotas de lluvia caen con fuerza, casi con intención." G_FEMENINO 'neblina' [; return self.desc_niebla; ] G_FEMENINO 'niebla' [; return self.desc_niebla; ] G_FEMENINO 'colonia' "La colonia minera se alza no muy lejos, esperando." G_FEMENINO; Object junto_procesador "Junto al procesador atmosférico" class LugarExterior with description "Te encuentras junto a la entrada al recinto de la maquinaria de purificación ambiental. En el interior es donde se produce y se renueva el aire para la colonia. Una puerta metálica da acceso al procesador, y junto a ella se ha situado un panel de control. El edificio es altísimo, y su fachada frontal tiene signos de haber sido maltratada. Sigue lloviendo, y el calor es asfixiante.", sgw_img Junto_Procesador_jpg, sgw_mus Lluvia_ogg, ! Junto_Procesador_ogg, s_to exterior1, in_to puerta_procesador, tenga_cuidado false, before [; Go: if (noun == in_obj && (~~(procesador.arreglado())) && jason in LugarReal() && puerta_procesador has open && ~~(self.tenga_cuidado)) { self.tenga_cuidado = true; print "Jason apoya una mano en tu hombro y mirándote fijamente te dice...^"; HablaJason("Tenga cuidado..."); if (linterna in jason) { move linterna to player; print "^Y devolviéndote la linterna, concluye...^"; HablaJason("Y tome su linterna. Está muy oscuro ahí dentro."); } viewImageCenter(self.sgw_img); ! Por si acaso coincide con un trueno KeyDelay(); } ], antesPNJ [; Go: if (second == in_obj) { if (puerta_procesador has open) { if (linterna in jason) { if (bateria notin linterna) { HablaJason("Está demasiado oscuro para ver nada, y a la linterna le falta la batería."); rtrue; } if (bateria.energia <= 0) { HablaJason("Está demasiado oscuro para ver nada, y la linterna no tiene energía suficiente."); rtrue; } print "Jason "; if (linterna hasnt on) { give linterna ~open; linterna.encender(); print "enciende la linterna. A continuación, "; } print "se acerca a la puerta y se asoma al interior. Mueve el haz de la linterna varias veces en distintas direcciones, y concluye:^"; HablaJason("Parece que todo está tranquilo. Puede pasar, pero tenga cuidado."); move linterna to player; "^Jason te devuelve la interna con gesto inexpresivo."; } else { if (linterna in player) { HablaJason("Está demasiado oscuro para ver nada. Páseme su linterna."); } else { HablaJason("Está demasiado oscuro para ver nada. Deberíamos buscar una fuente de luz."); } } } else { HablaJason("Primero habrá que buscar la forma de abrir la puerta."); } rtrue; } ]; Object decorado_junto_procesador junto_procesador class Decorado with desc_paredes "La lluvia y otros fenómenos atmosféricos han hecho mella en la otrora lisa y pulida superficie de la pared del complejo.", describe 'paredes' [; return self.desc_paredes; ] G_FEMENINO + G_PLURAL 'pared' [; return self.desc_paredes; ] G_FEMENINO 'fachada' [; return self.desc_paredes; ] G_FEMENINO 'edificio' "La construcción tiene una amplia base cilíndrica que se prolonga con forma semicónica elevándose muy alto hacia el cielo." 0 'luz' "Es un halo inmaterial que lo envuelve todo con un manto blanco-azulado." G_FEMENINO 'lluvia' "Las gotas de lluvia caen con fuerza, casi con intención." G_FEMENINO 'entrada' "Sobria y, en cierta forma, intimidante..." G_FEMENINO; Object cables "cables" junto_procesador with name 'cable' 'cables//p', description [; if (bateria notin panel_control) { "Son unos siete u ocho cables de varios colores. Sobresalen, inertes, del panel de control."; } else { "Dos de los cables están temporalmente unidos a los bornes de la batería."; } ], before [; Touch: if (panel_control has general) { "Ahora parece que los cables dan algo de calambre."; } else { "Incluso mojados como están, no te provocan ni siquiera un ligero calambre, lo que te hace pensar que por ellos no circula energía."; } SwitchOn: <>; Receive: <>; Tie: if (second ~= nothing && second ~= cables) { if (second == bateria) { <>; } else { "No es lógico conectar los cables ", (al) second, "."; } } else { "No consigues nada uniendo los cables entre sí."; } ], has scenery pluralname; Object puerta_procesador "puerta del procesador atmosférico" junto_procesador class PNJPuerta class EscenarioAbrible with ! La librería PnjPuertas ya incluye la palabra 'puerta' como nombre name 'compuerta', adjectives 'procesador' 'metalica', description [; if (self hasnt open) "La puerta impide el acceso al interior del procesador atmosférico."; else "La puerta está abierta y permite el paso al procesador atmosférico."; ], in_to procesador, out_to junto_procesador, interior procesador, exterior puerta_procesador, before [; Open: if (self hasnt open) { "Para abrir la puerta necesitarás accionar algún mecanismo."; } else { "La puerta ya está abierta."; } Close: "No puedes hacerlo con el panel de control en esas condiciones."; ! Esto es para que la librería no diga que está abierta o cerrada: Examine: PrintOrRun(self, description); rtrue; ], has female; ! La puerta sólo se puede abrir usando el panel de control. ! general sirve para indicar que el panel está listo para recibir el código de apertura ! (es decir: tiene dentro la batería y tiene energía suficiente) Object panel_control "panel de control" junto_procesador with name 'cuadro' 'mandos' 'panel' 'control' 'teclado' 'display' 'pantalla' 'visualizador' 'proteccion', description [; print "Un cuadro de mandos con un display visualizador y un teclado, situado junto a la puerta. Su panel de protección está abierto, faltan algunos tornillos y varios cables sobresalen de su interior."; if (bateria in self) { print " Varios de sus cables están temporalmente unidos a los bornes de una batería. "; if (puerta_procesador hasnt open) { print "En el display puedes leer ~"; tt_computadora.visualiza("Semilla: 9957. ¿Código?"); print "~."; } } else { if (puerta_procesador hasnt open) { print " Aunque su aspecto no es muy bueno, concluyes que lo único que necesitaría para funcionar correctamente es algún aporte de energía eléctrica."; } else { print " Parece totalmente muerto."; } } ""; ], ! codigo_viejo: se usa en el objeto computadora ! codigo_viejo == 0: El jugador aún no ha intentado el código antiguo ! codigo_viejo == 1: El jugador ha intentado meter el código antiguo codigo_viejo 0, ! Impide que puedas meter otra cosa que no sean las baterías react_before [; Insert: if (second == self && noun ~= bateria) { ! Intentamos meter algo que no es la batería "No parece que tenga demasiado sentido poner eso ahí."; } ], ! general sirve para indicar que la batería está puesta y tiene energía suficiente before [ t ; Arreglar: "Tendrás que ser más específico."; Soldar: "Así no conseguirás nada."; SwitchOn, Burn, SwitchOff: "No es algo que necesite encenderse o apagarse."; Teclear: if (self hasnt general) { "El panel de control no tiene energía suficiente."; } t = WordAddress(2); if (WordLength(2) == 6 && t->0 == '2' && t ->1 == '6' && t->2 == '8' && t->3 == '7' && t->4 == '4' && t->5 == '1') { ! Código nuevo: 268741 puerta_procesador.abrir(); junto_procesador.sgw_img = Junto_Procesador_Abierto_jpg; viewImageCenter(junto_procesador.sgw_img); give self ~general; bateria.energia = 0; print "El display dice: ~"; tt_computadora.visualiza("Código correcto. Acceso permitido."); Damusix.TocarV(Chispazo_ogg, 100); "~^^La puerta se abre y, a continuación, una enorme chispa salta de los bornes de conexión de la batería. Finalmente, el panel de control se apaga por falta de energía."; } else if (WordLength(2) == 6 && t->0 == '7' && t ->1 == '5' && t->2 == '9' && t->3 == '8' && t->4 == '1' && t->5 == '2') { ! Código viejo: 759812 if (self.codigo_viejo == 0) { self.codigo_viejo = 1; print "El display dice: ~"; tt_computadora.visualiza("Código incorrecto. Acceso denegado."); print "~^^Parece que ese código ya no sirve, después de que el sistema de control del panel se haya reiniciado.^"; if (SeVen(player, jason)) { if (SeVen(player, robot)) { print "Jason se dirige al androide:^"; jason.decir = false; robot.decir = false; HablaJason("¿759812? ¡¿759812?! ¡Esa no es la clave, saco de tuercas!"); HablaRobot("Código... cambiado... cambiado..."); HablaJason("A ti sí que te voy a cambiar la cara como no te calles..."); } else { jason.decir = false; HablaJason("¡Ey! ¿Es que alguien está mintiendo por aquí?"); } } rtrue; } else { print "El display insiste: ~"; tt_computadora.visualiza("Código incorrecto. Acceso denegado."); "~. Habrá que buscar el nuevo código."; } } else { print "El display muestra: ~"; tt_computadora.visualiza("Código incorrecto. Acceso denegado."); "~."; } Receive: if (puerta_procesador has open) { ! Si la puerta ya está abierta, no tiene sentido volver a meter la batería "La puerta ya está abierta, y el panel está destrozado. No tiene sentido volver a colocar la batería ahí."; } Open: "El panel de protección ya está abierto."; Close: "No puedes: está roto."; Tie: if (second == bateria) { <>; } else { "No es lógico conectar la batería ", (al) second, "."; } ], after [; Search: if (bateria notin self) { "Está lleno de cables de varios colores."; } Receive: print "Metes la batería dentro del panel y ajustas varios cables sueltos a sus bornes, "; if (bateria.energia < 20) { "pero no parece dar mucho resultado. Probablemente la batería no tenga suficiente energía."; } else { give self general; Damusix.TocarV(Chispazo_ogg, 100); print "provocando una lluvia de chispas. El display se enciende y suena un zumbido. En la pantalla aparecen símbolos y caracteres que indican que el sistema de control del panel se está reiniciando. Finalmente, en el display puedes leer: ~"; tt_computadora.visualiza("Semilla: 9957. ¿Código?"); "~."; } LetGo: if (self has general) { give self ~general; "Al sacar la batería, el panel de control se apaga y enmudece."; } else { "Sacas la batería, soltando los cables que la mantenían unida al panel de control."; } ], has scenery container open; Object procesador "Procesador atmosférico" class Lugar with description [; print "Este es el corazón de la maquinaria de purificación ambiental. Una red de tuberías y dispositivos de refrigeración y renovación se extiende hasta donde alcanza tu vista. Hay charcos de agua por todas partes debido a las goteras. La humedad en el ambiente provoca que el calor aquí dentro sea casi insoportable. La instalación está gobernada por una unidad central rodeada por cientos de cables."; if (self.arreglado()) { print " La maquinaria opera ahora a plena potencia, suministrando oxígeno y aire perfectamente respirable a las zonas cercanas al procesador de aire."; } ""; ], sgw_img Procesador_jpg, sgw_mus Procesador_ogg, out_to puerta_procesador, before [; Go: if (noun == out_obj && alien.comportamiento > 0 && rifle notin player) { "¡No te vayas sin dejar aquí el arma de Jason! Podría serte de mucha utilidad."; } ], each_turn [; self.comprobar_segunda_parte(); ], arreglar [; give circuito general; remove robot; give robot absent; move robot_inutil to procesador; give player light; procesador.sgw_mus = Maquinaria_ogg; junto_procesador.sgw_mus = Junto_Procesador_ogg; junto_procesador.sgw_vol = VOLUMEN_FONDO - 10; ], ! ¿Se ha arreglado el procesador atmosférico? arreglado [; return circuito has general; ], ! Comprobamos si hay que pasar a la seguda parte (el alien se lleva a Jason): comprobar_segunda_parte [; if (alien.comportamiento == 0) { ! Si hay luz, y está el alien, y entras solo, te mata. Si entras con Jason, se lo ! lleva a él if (location ~= thedark && alien in self) { if (jason notin self) { remove comunicador; ! Esto es para que Jason no hable give comunicador absent; ! cuando nos están matando clearTextWindow(); print "^El monstruo gira la cabeza hacia ti, y emite un chillido insoportable, agudo, que te hiela la sangre nada más oirlo. Te quedas petrificado ante tal visión, y sólo tienes fuerzas para observar a la criatura acercarse cada vez más deprisa hasta tu posición. Por tu mente pasa entonces una única idea: ~Ojalá estuviera Jason aquí...~. Instantes después, todo es oscuridad y silencio...^^"; KeyDelay(); Bandera_Fin(1); "Cuando despiertas, notas que sólo puedes mover los ojos. Estás completamente inmóvil, atrapado dentro de una especie de capullo gelatinoso de una enorme dureza. Y es cuando te das cuenta de que lo más terrible no es eso, sino la certeza de saber que nadie podrá oir tus gritos...^"; } else { SegundaParte(); ! En un par de turnos se oye a alien rompiendo la puerta del complejo ! (ver rutina ruido_puerta_rota.tiempo_agotado) StartTimer(ruido_puerta_rota, 2); Damusix.TocarV(Grito_Jason_ogg); viewImageCenter(Alien_Rapta_Jason_jpg); clearTextWindow(); print "^El monstruo gira la cabeza hacia vosotros, y emite un chillido insoportable, agudo, que os hiela la sangre nada más oirlo. Tú te quedas petrificado ante tal visión, pero Jason grita salvajemente y comienza a disparar su rifle contra la criatura, que eleva su grito sobre el del soldado. Rápidamente, el ser se dirige hasta donde se encuentra Jason, y de un sólo movimiento lo atrapa por el cuello y sale corriendo por la puerta del procesador atmosférico. Comienzas a respirar de nuevo cuando te das cuenta de que estás solo...^"; KeyDelay(); ; } } } ]; Object unidad_central "unidad central" procesador with name 'instalacion' 'unidad' 'central', description "La unidad central gobierna el funcionamiento del procesador atmosférico. Es, básicamente, una masa informe de cables y tubos. Una caja de conexiones es lo que más llama tu atención.", has scenery female; Object decorado_procesador procesador class Decorado with desc_cables "Los cables entran y salen por decenas de la unidad central.", desc_tubos "Metros y metros de tubos lisos y estriados serpentean por la sala y hacia el exterior.", desc_charcos "El agua estancada se forma a base de paciencia y gotas de agua que se filtran por el techo.", describe 'cables' [; return self.desc_cables; ] G_PLURAL 'cable' [; return self.desc_cables; ] 0 'tubos' [; return self.desc_tubos; ] G_PLURAL 'tuberias' [; return self.desc_tubos; ] G_FEMENINO + G_PLURAL 'tuberia' [; return self.desc_tubos; ] G_FEMENINO 'tubo' [; return self.desc_tubos; ] 0 'charcos' [; return self.desc_charcos; ] G_PLURAL 'charco' [; return self.desc_charcos; ] 0 'agua' [; return self.desc_charcos; ] G_FEMENINO; Object conexiones "caja de conexiones" procesador class Contenedor class EscenarioAbrible with name 'caja', adjectives 'conexiones', descripcion_real "Una caja de conexiones llena de cables y de circuitos electrónicos interconectados unos con otros.", when_open "La caja de conexiones de la unidad central está abierta.", with_key destornillador, before [; ! Para el caso de ATORNILLAR y DESATORNILLAR Turn: if (destornillador in player) { <>; } else { "No tengo la herramienta apropiada."; } Open: ! Si intentas abrir con algo que no sea el destornillador if (self has locked) { switch (second) { nothing: "La tapa de la caja está sujeta con un fuerte tornillo."; destornillador: break; default: print_ret (The) second, " no sirve para quitar el tornillo."; } } Receive: ! Intentas meter algo dentro de la caja "No cabe nada dentro; sólo puede contener circuitos."; Unlock: if (second ~= nothing) { if (self hasnt open) { ! Se intenta abrir la caja con algo if (self has locked && second ~= destornillador) { print_ret (The) second, " no sirve para quitar el tornillo."; } if (self hasnt locked) { "La caja ya está lo bastante abierta como para poder trabajar con su contenido."; } } else { "La caja ya está lo bastante abierta como para poder trabajar con su contenido."; } } else { "Necesitas usar algo para poder quitarle el tornillo a la tapa."; } ], after [; Unlock: print "Abres la caja de conexiones quitando un tornillo de cierre que impedía abrir la tapa. A continuación tiras el tornillo lejos de ti, inservible ya.^"; remove tornillo; give tornillo absent; keep_silent = 1; ! Para que no diga que abres la caja a continuación ; ! Abres la caja (pero el intérprete no dice nada) keep_silent = 0; ! Vuelves a la situación normal rtrue; ], has female lockable locked; Object tornillo "tornillo" procesador with name 'tornillo', description "Es un tornillo bastante fuerte, de un tamaño típico, con punta 4-X.", before [; Examine: rfalse; Open: <>; Turn: <>; Unlock: <>; Take, Remove, Push, Pull: "Para poder retirar el tornillo necesitarás una herramienta."; ], has scenery; ! El circuito. El atributo general indica que está arreglado Object circuito "circuito fotónico" conexiones with name_m 'circuito' 'fotonico' 'danado' 'defectuoso' 'estropeado' 'abierto', name_f 'conexion' 'danada' 'abierta', gender G_MASCULINO, description [; print "Es un circuito elaborado con material polimérico. Por su ubicación, parece destinado a gestionar una parte importante del sistema de control del procesador atmosférico. "; if (self hasnt general) { "Parece tener una conexión rota en una de sus esquinas. Haría falta soldarla."; } else { "Ves el circuito arreglado gracias a la conexión de emergencia llevada a cabo por el robot."; } ], before [; Arreglar, Close: "La única forma de arreglar este circuito es soldando la conexión que tiene abierta."; Soldar: "No dispones de las herramientas adecuadas para poder soldar."; ], has static; Object exterior3 "Exterior de la colonia" class LugarExterior with description "Estás cerca del complejo de la colonia minera. Una zona amplia y yerma, una superficie fangosa de terreno duro, predregoso en algunos puntos, sin vida, carente de todo tipo de vegetación y cubierto de charcos y lodo húmedo. Multitud de piezas mecánicas aparecen desperdigadas por el suelo.", sgw_img Exterior3_jpg, sgw_mus Lluvia_ogg, n_to exterior1, e_to junto_puerta, before [; Examine: if (noun == d_obj) { PrintOrRun(decorado_exterior3, desc_lodo); rtrue; } ]; Object decorado_exterior3 exterior3 class Decorado with desc_lodo "Una superficie de polvo y arena forma el barro que se acumula en las suelas de tus botas. Y sobre dicha superficie, montones de tuercas y tornillos abandonados a su suerte.", desc_charcos "Agua de lluvia estancada aquí y allá, difícil de filtrar en este terreno tan duro.", describe 'lodo' [; return self.desc_lodo; ] 0 'barro' [; return self.desc_lodo; ] 0 'terreno' [; return self.desc_lodo; ] 0 'charcos' [; return self.desc_charcos; ] G_PLURAL 'charco' [; return self.desc_charcos; ] 0 'lluvia' "Aquí es ligeramente más débil por la cercanía con el edificio del complejo." G_FEMENINO 'sombra' "¿Qué fuente de luz la provocará?" G_FEMENINO; Object "piezas metálicas" exterior3 with name_m 'tornillo' 'artefacto', name_f 'pieza' 'tuerca', name_mp 'tornillos' 'artefactos', name_fp 'piezas' 'metalicas' 'tuercas', gender G_FEMENINO + G_PLURAL, description "Tuercas, tornillos, dispositivos electrónicos y todo tipo de artefactos metálicos; algunos oxidados, otros casi nuevos.", before [; Take: "No merece la pena... No son más que piezas inservibles."; ], has scenery; Object ascensor_arriba "ascensor de emergencia" with name 'ascensor' 'elevador' 'cubiculo' 'emergencia', description "Es una especie de cabina rectangular de cristal muy resistente, reforzado por cientos de remaches metálicos. Su tamaño aproximado es de unos cinco por cinco metros. Sobresale del suelo, con la puerta abierta y cubierto de barro. Sin duda, ha cumplido perfectamente su misión.", initial "Sobresaliendo del suelo como una planta carnívora, permanece a tu lado el ascensor que os ha sacado a Jason y a ti del complejo colonial.", react_before [; Enter: "¡Ni se te ocurra volver a entrar! ¡Huye!"; ], before [; "Olvídate ahora de él. ¡Corre!"; ], has static; Object junto_puerta "Junto a la entrada de acceso al complejo" class LugarExterior with description "Te encuentras frente a la puerta que da acceso al complejo colonial. Parece que desde aquí es la única entrada. El edificio es relativamente bajo, pero muy extenso. Todo tiene aspecto de haber sido innecesariamente maltrado. Más allá sólo continúa la superficie de la colonia, que apenas alcanzas a ver debido a la neblina.", sgw_img Junto_Puerta_jpg, sgw_mus Lluvia_ogg, w_to exterior3, in_to puerta_rara; Object decorado_junto_puerta junto_puerta class Decorado with desc_edificio "Desde aquí te parece enorme, frío y estéril. Nadie diría que es una estructura diseñada para albergar vida.", desc_niebla "Es un efecto provocado por la intensa lluvia, que te impide ver con claridad los límites exteriores de la colonia.", describe 'edificio' [; return self.desc_edificio; ] 0 'complejo' [; return self.desc_edificio; ] 0 'colonia' [; return self.desc_edificio; ] G_FEMENINO 'neblina' [; return self.desc_niebla; ] G_FEMENINO 'niebla' [; return self.desc_niebla; ] G_FEMENINO; class Complejo class Lugar has ~light; class Laberinto class Complejo with short_name "Túneles", description [ o k ns; print "Estás en uno de los pasillos interiores del complejo. Metros y metros de estructura metálica recorren estos túneles, que parecen no acabar nunca. Las filtraciones en las paredes y el techo forman irregulares charcos de agua aquí y allá, y dotan al ambiente de una humedad malsana y asfixiante."; ns = 0; objectloop (o in compass) { if (~~(self provides o.door_dir)) { ! No hay salida en esa dirección continue; } if (o == in_obj or out_obj) { continue; } k = self.(o.door_dir); if (ZRegion(k) == 2) { ! Rutina que devuelve k = k(); } if (ZRegion(k) ~= 1) { ! No se puede pasar continue; } if (k) { ns++; if (k ofclass Laberinto) { print " El túnel se alarga hacia ", (the) o; if (k.(sibling(o).door_dir) ofclass Laberinto) { print " y continúa por ", (the) sibling(o), "."; o = sibling(o); ns++; } else { print "."; } } else { switch (o) { n_obj: print " ", (_Al) o, " ves "; s_obj: print " Por ", (the) o, " se llega hasta "; e_obj: print " Hacia ", (the) o, ", el túnel desemboca en "; w_obj: print " ", (_Al) o, " se alcanza "; u_obj: print " Sobre tu cabeza divisas "; d_obj: print " Bajando ves "; default: print " Hacia ", (the) o, " se observa "; } if (k has door) { ! Es una puerta print "una puerta."; } else { if (~~(k ofclass Balcon)) { if (k hasnt female && k hasnt pluralname) { print "un"; } else if (k has female && k hasnt pluralname) { print "una"; } else if (k hasnt female && k has pluralname) { print "unos"; } else { print "unas"; } print " ", (string) k.nombre_localidad, "."; } else { print "el balcón que da al ", (name) k.posicion, " de la veta."; } } } } } if (ns == 1) { print " Y parece la única salida posible, ya que el túnel termina aquí como un callejón sin salida."; } ""; ], sgw_img Laberinto_Este_jpg, sgw_mus Pasillo_ogg, before [; Examine: if (noun == d_obj) { PrintOrRun(decorado_laberinto, desc_charcos); rtrue; } ]; Object decorado_laberinto class Decorado with found_in [; return LugarReal() ofclass Laberinto; ], desc_paredes "Por las curvadas paredes de los túneles discurren enormes tuberías. Pero observando más de cerca puedes apreciar restos de sangre reseca manchando la estructura.", desc_charcos "El agua se filtra por los enormes tubos de las paredes y se encharca en algunos puntos del suelo.", desc_tubos "Son largos y sinuosos cilindros de varios tamaños que recorren las paredes transportando quién sabe qué.", describe 'tuneles' [; return self.desc_paredes; ] G_PLURAL 'tunel' [; return self.desc_paredes; ] 0 'tuberias' [; return self.desc_tubos; ] G_FEMENINO + G_PLURAL 'tuberia' [; return self.desc_tubos; ] G_FEMENINO 'tubos' [; return self.desc_tubos; ] G_PLURAL 'tubo' [; return self.desc_tubos; ] 0 'charcos' [; return self.desc_charcos; ] G_PLURAL 'charco' [; return self.desc_charcos; ] 0 'agua' [; return self.desc_charcos; ] 0 'paredes' [; return self.desc_paredes; ] G_FEMENINO + G_PLURAL 'pared' [; return self.desc_paredes; ] G_FEMENINO 'sangre' "Sólo eso: sangre salpicada (o proyectada) contra la pared. No hay ninguna pista sobre a qué ser (persona o animal) pertenecía." G_FEMENINO; class Balcon class Complejo with short_name [; print "Balcón ", (name) self.posicion, " a la veta"; rtrue; ], nombre_localidad "balcón a la veta", description [; print "Estás en la plataforma ", (name) self.posicion, " del nivel ", self.nivel, " de acceso a los túneles. Esta superficie rodea la veta que han construido los colonos para la extracción del mineral. Desde aquí, puedes ver la veta si miras al ", (name) IntercambiarDireccion(self.posicion), "."; if (puerta_emergencia in self) { print " En la pared sur hay una puerta con una ranura en un lateral."; } if (montacargas in self) { print " "; PrintOrRun(montacargas, initial); } else { ""; } ], posicion 0, nivel 0, sgw_mus Balcon_ogg, before [; Go, Examine: if (noun == IntercambiarDireccion(self.posicion)) { if (location ~= thedark) { "Te acercas a asomarte a la veta de mineral. Es enorme..."; } else { "La oscuridad te impide apreciar nada con claridad."; } } else { rfalse; } ]; Object decorado_balcon class Decorado with desc_mineral "El Vibrantium es un mineral muy valioso y escaso. Esta veta es particularmente rica; no hay más que ver el brillo tan puro que emite.", desc_balcon "Es la plataforma que rodea la veta.", found_in [; return LugarReal() ofclass Balcon; ], before [; Touch: "No alcanzas a tocarl", (o) self.number, " desde el balcón."; ], describe 'veta' [; return self.desc_mineral; ] G_FEMENINO 'mineral' [; return self.desc_mineral; ] 0 'vibrantium' [; return self.desc_mineral; ] 0 'plataforma' [; return self.desc_balcon; ] G_FEMENINO 'balcon' [; return self.desc_balcon; ] 0; Object montacargas "montacargas" with description "Es una plataforma situada al borde del balcón y que permite el transporte vertical de objetos.", name 'montacargas' 'ascensor' 'elevador', found_in balcon4 balcon8 balcon12, nivel 0, viene_jason false, initial [ p; p = parent(self); print "Además, observas un montacargas que te permite "; if (p.u_to ~= nothing) { print "subir al nivel ", p.nivel + 1; if (p.d_to ~= nothing) { print ", o bien "; } } if (p.d_to ~= nothing) { print "bajar al nivel ", p.nivel - 1; } "."; ], react_before [; self.viene_jason = jason in parent(self); ], reaccionar_antesPNJ [; if ((self in balcon4 && second == d_obj) || (self in balcon8 && second == u_obj or d_to) || (self in balcon12 && second == u_obj)) { if (parent(self) ~= LugarReal()) { HablaJason("Mejor vayamos juntos."); rtrue; } } ], before [; GoIn: switch (parent(self)) { balcon4: <>; balcon12: <>; balcon8: "¿Qué quieres hacer: subir o bajar?"; } ], react_after [; Go: if (noun == u_obj or d_obj) { self.nivel = parent(self).nivel; } if (noun == u_obj) { if (self.viene_jason) { self.viene_jason = false; print "Subís"; } else { print "Subes"; } } else if (noun == d_obj && LugarReal() has visited) { if (self.viene_jason) { self.viene_jason = false; print "Bajais"; } else { print "Bajas"; } } else { rfalse; } if (procesador.arreglado()) { print " por el montacargas hasta el nivel "; } else { print " escalando con cuidado hasta el nivel "; } print self.nivel, "...^"; ], has scenery enterable; ! La propiedad general indica que no es la primera vez que entramos aquí con la puerta ! viscosa Object entrada "Entrada al complejo" class Complejo with description "Estás en la entrada que da acceso al complejo de la colonia minera. Nada de decoración lujosa ni elementos ornamentales, sino más bien un sencillo y amplio pasillo, semejante a un recibidor, totalmente vacío y sin vida.", sgw_img Entrada_jpg, out_to puerta_rara, s_to balcon1, each_turn [; if (self hasnt general && puerta_viscosa in self && jason in self) { give self general; print "^Jason observa la puerta sellada con esa sustancia, y exclama:^"; jason.decir = false; HablaJason("¡Maldita sea! Tendremos que buscar otra forma de salir de aquí. Y de paso... ¡mandar todo esto al infierno!"); } ]; Object puerta_rara "puerta del complejo" entrada class PNJPuerta class EscenarioAbrible with ! La librería PnjPuertas ya incluye la palabra 'puerta' como nombre name 'compuerta' 'agujero', adjectives 'complejo', description [; if (self hasnt open) { "La puerta es metálica y de aspecto recio e intimidante."; } else { "Restos de ácido gotean por los dentados bordes de la grieta abierta."; } ], ! "La puerta, de aspecto infranqueable, se alza formidable en la entrada al complejo.", ! si_cerrada "La puerta tiene un aspecto muy extraño y parece imposible de abrir.", when_open "Un enorme agujero de forma irregular abre el paso a través de la puerta.", out_to junto_puerta, in_to entrada, interior entrada, exterior junto_puerta, before [; Open, Unlock: if (self has open) { "No es necesario abrirla, ya que puedes pasar perfectamente a través del enorme agujero que se ha formado."; } else { "No ves ningún cuadro de mandos ni cerradura que pudieras usar para abrirla."; ! "Es imposible que un ser humano pueda abrir manualmente esta puerta, y no ves ! ningún cuadro de mandos ni cerradura que pudieras usar para abrirla."; } Push, PushDir, Pull: "Es imposible que un ser humano pueda abrirla manualmente."; Close: "La puerta ya está cerrada, aunque puedes pasar por el agujero."; ! Esto es para que la librería no diga que está abierta o cerrada: Examine: PrintOrRun(self, description); rtrue; Touch: if (self has open) { "Yo que tú no tocaría: ese ácido parece muy corrosivo."; } ], has female; Object puerta_viscosa "puerta del complejo" class PNJPuerta with ! La librería PnjPuertas ya incluye la palabra 'puerta' como nombre name 'compuerta' 'enorme' 'grande' 'enorme' 'agujero' 'viscosa' 'viscosidad' 'sustancia' 'gelatinosa', adjectives 'complejo', description "El monstruo ha sellado el agujero de la puerta, haciéndola de nuevo infranqueable.", when_closed "El agujero de la puerta ha sido sellado por una sustancia viscosa muy dura y resistente. Parece imposible de romper.", ! Inicialmente no está conectada a ninguna habitación. Más tarde, cuando cambiemos ! la puerta_rara por ésta, actualizaremos sus conexiones: in_to [; rfalse; ], out_to [; rfalse; ], interior entrada, exterior junto_puerta, before [; Attack: <>; Open: "Intentas romper la sustancia viscosa que tapona el agujero, pero en seguida te das cuenta de que resulta imposible. Tendrás que buscar una salida por otra parte."; Close: "La puerta ya está suficientemente taponada."; ! Esto es para que la librería no diga que está abierta o cerrada: Examine: PrintOrRun(self, description); rtrue; Touch: "Su tacto es desagradablemente gelatinoso y sólido al mismo tiempo."; ], has female openable; Object oficina "Oficina" class Complejo with description [; print "Has llegado a lo que parece ser una oficina. Todas los puestos están perfectamente delimitados e impolutamente ordenados, equipados cada uno con una moderna consola de trabajo. Al fondo, una mesa que da la impresión de ser la de algún pez gordo. "; if (procesador.arreglado()) { print "La iluminación en esta sala es excelente, así como la decoración, sorprendentemente lujosa para un complejo como este."; } else { print "La decoración es sorprendentemente lujosa para un complejo como este."; } " Una serie de archivadores se alinean perfectamente bajo decenas de cuadros que prácticamente ocultan por completo la pared con escenas marciales y bélicas, lo que dota a la estancia de un estilo retro muy de siglos pasados. En una esquina, cerca del techo, una cámara de seguridad lo observa todo con su único ojo."; ], sgw_img Oficina_jpg, e_to balcon2, before [; Examine: if (noun == u_obj) { if (procesador.arreglado()) { "Hay una cámara girando lentamente cerca del techo de la sala."; } else { "Hay una cámara cerca del techo de la sala."; } } ]; Object decorado_oficina oficina class Decorado with desc_cuadros [; print "Se ve que al responsable le encantaba la antigua práctica, habitual en los siglos XIX y XX, de colgar innumerables cuadros por las paredes, cubriéndolas casi por completo. Todos son muy oscuros y, al mismo tiempo, alegóricos."; if (cuadro in oficina) { " Hay uno en concreto que te llama la atención."; } else { ""; } ], desc_puestos "Típicos escritorios de despacho, salvo la mesa del fondo.", desc_papeles "Cientos y cientos de documentos con información que no te resultan para nada interesantes.", desc_archivadores "Son inmensos muebles metálicos firmemente sujetos al suelo y a la pared sobre la que descansan. Todos están cerrados, y no parece que haya una forma fácil de abrirlos.", desc_iluminacion [; if (procesador.arreglado()) { "En contraste con el resto del complejo, parece que el sol mismo se filtra por las paredes de esta habitación. La iluminación proviene directamente del techo."; } else { "¿Iluminación? Estás a oscuras, ¿recuerdas?"; } ], desc_paredes "Las paredes están casi ocultas por una enorme cantidad de cuadros. En una esquina, pegada casi al techo, hay una cámara de seguridad.", before [; Take, Push, Pull, Touch: if (self.number == 'cuadro' or 'cuadros') { print "¿Cuál tengo que "; LanguageVerb(verb_word); "? ¡Hay decenas!"; } else if (self.number == 'papeles' or 'papel' or 'folios' or 'folio' or 'documentos' or 'documento' && action == ##Take or ##Touch) { "No merece la pena... Básicamente, son listados de cuentas y gastos."; } else if (self.number == 'iluminacion' or 'luz' or 'luces') { print "¿Lo dices en serio? ¿Quieres "; LanguageVerb(verb_word); " la luz?"; } Open, Pull, Push: "Tiras y tiras, pero es imposible... No hay forma de abrir esos archivadores."; Examine: rfalse; ], describe 'oficina' [; return oficina.description; ] G_FEMENINO 'archivadores' [; return self.desc_archivadores; ] G_PLURAL 'archivador' [; return self.desc_archivadores; ] 0 'cuadros' [; return self.desc_cuadros; ] G_PLURAL 'cuadro' [; return self.desc_cuadros; ] 0 'puestos' [; return self.desc_puestos; ] G_PLURAL 'puesto' [; return self.desc_puestos; ] 0 'mesas' [; return self.desc_puestos; ] G_FEMENINO + G_PLURAL 'escritorios' [; return self.desc_puestos; ] G_FEMENINO + G_PLURAL 'papeles' [; return self.desc_papeles; ] G_PLURAL 'papel' [; return self.desc_papeles; ] 0 'folios' [; return self.desc_papeles; ] G_PLURAL 'folio' [; return self.desc_papeles; ] 0 'documentos' [; return self.desc_papeles; ] G_PLURAL 'documento' [; return self.desc_papeles; ] 0 'iluminacion' [; return self.desc_iluminacion; ] G_FEMENINO 'luces' [; return self.desc_iluminacion; ] G_PLURAL 'luz' [; return self.desc_iluminacion; ] 0 'paredes' [; return self.desc_paredes; ] G_FEMENINO + G_PLURAL 'pared' [; return self.desc_paredes; ] G_FEMENINO; Object "equipos de la oficina" oficina with name_m 'ordenador' 'computador' 'equipo', name_f 'consola', name_mp 'ordenadores' 'computadores' 'equipos', name_fp 'computadoras' 'consolas', adjectives 'oficina' 'informaticos', gender G_MASCULINO + G_PLURAL, description "Estos equipos tan potentes no son fáciles de encontrar... Todos están apagados.", before [; SwitchOn, Burn: "Pulsas todos los botones de encendido, sin éxito."; default: "Olvida los equipos informáticos... Está claro que no podrás usarlos, y además no hay ningún motivo para ello."; ], has scenery; Object "mesa" oficina with name 'mesa' 'escritorio', adjectives 'fondo', description "Esto sí que es un escritorio amplio y con clase. Te recuerda el estilo clásico de las antiguas mesas de abogado propias del S. XX (salvo por la falta de madera, naturalmente). Más allá de su recargado estilo decorativo, tan sólo destacar las pilas de documentos garabateados y mecanoimpresos que descansan sobre su superficie.", before [; Take, Push, Pull: "Debe pesar una barbaridad... No se ha desplazado ni un centímetro."; Open, Close: print "No hay nada que puedas "; LanguageVerb(verb_word); " en esa mesa."; ], has scenery; ! El cuadro se crea cuando has visto las grabaciones de la cámara de seguridad Object cuadro "cuadro" with name 'cuadro', adjectives 'exaltador' 'patriotico', description [; print "Un patriótico cuadro exaltador de la vida al servicio de tu país. "; if (caja_fuerte notin oficina) { "No parece muy sujeto a la pared..."; } else { "Descansa en un suelo, apoyado con desgana en la pared."; } ], before [; Take, Push, Pull, Remove: if (caja_fuerte notin oficina) { move caja_fuerte to oficina; "Deslizas lateralmente el cuadro para comprobar que escondía una caja fuerte."; } else { "Ya has movido el cuadro y has encontrado la caja fuerte... No esperes mucho más de él."; } ], has scenery; ! El atributo general indica si se ha introducido correctamente la combinación Object caja_fuerte "caja fuerte" class Contenedor with name 'caja' 'fuerte' 'teclado' 'numerico', descripcion_real "Es una caja fuerte sencilla, sin ningún tipo de adorno exterior, pero que tiene todo el aspecto de ser muy resistente. Lleva acoplado un teclado numérico en la puerta, sin duda para poder introducir algún tipo de combinación y poder abrirla.", when_open "Hay una caja fuerte abierta incrustada en la pared.", when_closed "Ves una caja fuerte cerrada incrustada en la pared.", before [ t; Open: if (self hasnt general) { "No puedes abrirla hasta que introduzcas correctamente la combinación."; } Teclear: if (~~(procesador.arreglado())) { "No hay energía en el complejo, así que la caja fuerte no funciona."; } if (self has general) { "La caja fuerte ya está abierta, y teclear algo más en su teclado no tendrá ningún efecto."; } t = WordAddress(2); ! 111582 if (WordLength(2) < 6 || t->0 ~= '1' || t ->1 ~= '1' || t->2 ~= '1' || t->3 ~= '5' || t->4 ~= '8' || t->5 ~= '2' || WordLength(2) > 6) { "No pasa nada. Parece ser que la combinación no es la correcta..."; } else { give self general; Damusix.TocarV(Puerta1_ogg); "Se oye un ligero chasquido y unos motores internos accionan el desbloqueo de la caja fuerte."; } ], has static female openable; Object holocubo "holocubo" caja_fuerte with name 'cubo' 'holografico' 'holocubo', description "Un cubo holográfico es un soporte de almacenamiento de datos usado principalmente para contener imágenes."; Object tarjeta "tarjeta" caja_fuerte with name 'tarjeta' 'llave', description "Es una tarjeta fabricada con un material mezcla de plástico y metal, con forma rectangular, de unos cinco por siete centímetros. Tiene una enorme letra ~E~ grabada en un dorso.", has female; Object enfermeria "Enfermería" class Complejo with nombre_localidad "enfermería", description [; print "Te encuentras en la enfermería del complejo. Por lo que puedes observar, está perfectamente equipada. "; if (procesador.arreglado()) { print "Su magnífica iluminación baña toda la sala con una lechosa luz blanca. "; } "La estancia se encuentra rodeada por una gran fila de armarios. Un charco de sangre roja y brillante reposa en el suelo junto a varias camillas desperdigadas."; ], sgw_img Enfermeria_jpg, s_to laberinto16, w_to balcon7, has female; Object decorado_enfermeria enfermeria class Decorado with desc_armarios "Los armarios tienen puertas en su parte superior y cajones en la inferior, y están salpicados de sangre.", desc_camillas "Todas las camillas están tiradas y volcadas por el suelo. Rastros de sangre contrastan de forma impactante con el blanco inmaculado de las sábanas.", desc_iluminacion [; if (procesador.arreglado()) { "Una pulcra luz blanca, propia de los entornos sanitarios."; } else { "No hay iluminación artificial en un complejo sin energía."; } ], desc_cajones "Multitud de cajones situados en la parte inferior de los armarios. De entre todos ellos, sólo uno parece poder abrirse.", desc_puertas "Amplias puertas que llegan casi hasta el techo de la sala, y que impiden el acceso al interior de los armarios.", desc_sabanas "Sábanas blancas manchadas de sangre.", before [; if (self.number == 'iluminacion' or 'luz' or 'luces' && action == ##Take or ##Touch or ##Pull or ##Push) { print "¿Lo dices en serio? ¿Quieres "; LanguageVerb(verb_word); " la luz?"; } Touch: if (self.number == 'sabanas' or 'sabana') { "No quieres mancharte las manos de sangre."; } Open, Push, Pull: if (self.number == 'armarios' or 'armario' or 'puertas' or 'puerta') { "Imposible... No ves ningún pomo o cerradura que puedas usar para poder abrir ninguna de las puertas."; } else if (self.number == 'cajones') { "Hay muchos, pero sólo uno tiene pinta de poder abrirse."; } Push, Pull, PushDir: if (self.number == 'camillas' or 'camilla') { "No merece la pena."; } Close: if (self.number == 'armarios' or 'armario' or 'puertas' or 'puerta') { "Los armarios ya están bastante cerrados. ¿No lo ves?"; } ], describe 'armarios' [; return self.desc_armarios; ] G_PLURAL 'armario' [; return self.desc_armarios; ] 0 'puertas' [; return self.desc_puertas; ] G_FEMENINO + G_PLURAL 'puerta' [; return self.desc_puertas; ] G_FEMENINO 'cajones' [; return self.desc_cajones; ] G_PLURAL 'camillas' [; return self.desc_camillas; ] G_FEMENINO + G_PLURAL 'camilla' [; return self.desc_camillas; ] G_FEMENINO 'sabanas' [; return self.desc_sabanas; ] G_FEMENINO + G_PLURAL 'sabana' [; return self.desc_sabanas; ] G_FEMENINO 'iluminacion' [; return self.desc_iluminacion; ] G_FEMENINO 'luces' [; return self.desc_iluminacion; ] G_PLURAL 'luz' [; return self.desc_iluminacion; ] 0; Object cajon "cajón" enfermeria class Contenedor class EscenarioAbrible with name 'cajon', descripcion_real "Es un cajón situado en la parte inferior del armario más grande.", when_open "Hay un cajón abierto en uno de los armarios.", before [; Pull: <>; Push: <>; ]; Object "sangre" enfermeria with name_f 'sangre', name_m 'charco', gender G_FEMENINO, description "Es un generoso charco de sangre brillante y muy roja. Parece relativamente reciente.", before [; Touch: "Mejor no tocar eso... Podrías pillar una infección..."; Examine: rfalse; default: "Mejor no... Ese charco de sangre en el suelo te recuerda que no deberías perder el tiempo."; ], has scenery; ! El atributo general indica si se ha vaciado Object jeringa "jeringa" cajon with name_f 'jeringuilla' 'inyeccion' 'jeringa' 'aguja', name_m 'inyectable', adjectives 'hipodermica', gender G_FEMENINO, description [; print "Es una gruesa jeringa hipodérmica de 50 cc. y con una enorme aguja de unos 15 centímetros."; if (self hasnt general) { " Según indica la etiqueta pegada a la misma, contiene 30 cc. de adrenalina."; } else { " Está vacía."; } ], before [; Pinchar: if (self has general) { "La jeringa ya está vacía. No puede inyectar nada."; } if (second == jason) { HablaJason("¿De qué va, amigo? ¡Ni se le ocurra!"); rtrue; } else if (second == jason_inerte) { remove jason_inerte; give jason_inerte absent; give jason ~absent; move jason to LugarReal(); give self general; print "Clavas la aguja justo en el corazón de Jason, y le inyectas toda la adrenalina que había en la jeringa. El Mayor abre los ojos y lanza un grito desgarrador... Retiras la aguja rápidamente de su pecho, y comienza a toser fuertemente mientras se aprieta el tórax con las manos... ¡Está vivo y despierto! ¡Ha funcionado!^"; print "^Jason mira la interminable aguja de la jeringa, y exclama:^"; HablaJason("Dios mío... ¿Ha tenido que ensartarme con ESO?"); PreguntaSiNo = 1; rtrue; } ]; Object laboratorio "Laboratorio" class Complejo with nombre_localidad "laboratorio", description "El laboratorio de la colonia es bastante grande, y se encuentra dividido en dos áreas claramente delimitadas. En la zona sur, multitud de tubos de ensayo, probetas y cosas similares yacen rotos por el suelo. Las estanterías están prácticamente vacías y medio descolgadas y, sobre algunas de las mesas, descansan lo que parecen ser embriones de seres irreconocibles, embutidos en grandes botes transparentes. La zona este tiene el aspecto de haber sido un área de contención, pero sea lo que sea lo que hubiera estado confinado dentro, ya no lo está. Manchas y charcos de sangre cubren ciertas partes de la estancia, y una cámara situada cerca del techo barre la sala de lado a lado.", sgw_img Laboratorio_jpg, n_to laberinto19, before [; Examine: if (noun == u_obj) { if (procesador.arreglado()) { "Hay una cámara girando lentamente cerca del techo de la sala."; } else { "Hay una cámara cerca del techo de la sala."; } } ]; Object decorado_laboratorio laboratorio class Decorado with desc_tubos "La mayor variedad de probetas y tubos de ensayo que hayas visto nunca en una misma sala. No queda ninguno en pie... Todos están rodando por el suelo, algunos en buen estado, pero la mayoría completamente destrozados.", desc_mesas "Los botes transparentes, situados aquí y alla sobre la superficie de las mesas, contienen restos orgánicos semejantes a fetos o embriones de una especie que te resulta imposible identificar.", desc_paredes [; if (procesador.arreglado()) { "No hay mucho más que destacar. Tan sólo la cámara que se desplaza suavemente en lo alto de una de las paredes."; } else { "No hay mucho más que destacar. Tan sólo la cámara situada inerte en lo alto de una de las paredes."; } ], desc_estanterias [; print "La mayoría de las estanterías están sueltas, tiradas o directamente destrozadas"; if (bisturi has concealed && bisturi hasnt moved) { give bisturi ~concealed; return ", pero buscando bien en una de ellas, encuentras una especie de objeto afilado... Al mirarlo de cerca, compruebas que se trata de un bisturí láser."; } else { return "."; } ], desc_sangre before [; Touch, Taste: switch (self.number) { 'tubos', 'tubo', 'probetas', 'probeta', 'botes', 'bote', 'fetos', 'feto', 'embriones', 'embrion': "Mejor no... No quieres contagiarte de una posible infección."; } ], describe 'laboratorio' [; return laboratorio.description; ] G_FEMENINO 'paredes' [; return self.desc_paredes; ] G_FEMENINO + G_PLURAL 'pared' [; return self.desc_paredes; ] G_FEMENINO 'tubos' [; return self.desc_tubos; ] G_PLURAL 'tubo' [; return self.desc_tubos; ] 0 'probetas' [; return self.desc_tubos; ] G_FEMENINO + G_PLURAL 'probeta' [; return self.desc_tubos; ] G_FEMENINO 'botes' [; return self.desc_mesas; ] G_PLURAL 'bote' [; return self.desc_mesas; ] 0 'mesas' [; return self.desc_mesas; ] G_FEMENINO + G_PLURAL 'mesa' [; return self.desc_mesas; ] G_FEMENINO 'fetos' [; return self.desc_mesas; ] G_PLURAL 'feto' [; return self.desc_mesas; ] 0 'embriones' [; return self.desc_mesas; ] G_PLURAL 'embrion' [; return self.desc_mesas; ] 0 'estanterias' [; return self.desc_estanterias(); ] G_FEMENINO + G_PLURAL 'estanteria' [; return self.desc_estanterias(); ] G_FEMENINO 'sangre' [; return self.desc_sangre; ] G_FEMENINO; Object "sangre" laboratorio with name_f 'sangre' 'mancha', name_fp 'manchas', name_m 'charco', name_mp 'charcos', gender G_FEMENINO, description "Multitud de charcos de sangre cubren el suelo y la mayor parte del mobiliario.", before [; Touch, Taste: "La sangre no parece reciente. De hecho, en algunas zonas está reseca. La humedad del ambiente ha debido conservarla mejor de lo esperado."; ], has scenery; Object area_contencion "área de contención" laboratorio with name 'area' 'contencion' 'jaula' 'cabina', description "Es una especie de jaula construida a base de cristal y metal, y tiene un tamaño enorme, pues ocupa toda la zona este del laboratorio. La puerta, que ocupa toda una cara de la jaula, tiene dos hojas: una está completamente abierta, mientras que la otra está, más que rota, disuelta o corroída.", before [; Take, Touch, Taste: "Intuyes que el daño de la puerta pudo haberse debido a la fuga de algún tipo de ácido."; ], has scenery; Object bisturi "bisturí láser" laboratorio with name_m 'bisturi' 'laser', name_f 'cuchilla', adjectives 'cirujano', initial "Sobre una de las pocas estanterías intactas reposa lo que parece ser un bisturí de cirujano.", description "Es un bisturí láser de gran potencia de corte. Sólo actúa directamente sobre la superficie a cortar.", after [; Take: if (self has concealed) { give self ~concealed; } ], has concealed; Object camara_seguridad "cámara de seguridad" with name 'camara' 'seguridad', description [; if (procesador.arreglado()) { print "Es una cámara de seguridad que se mueve lentamente a izquierda y derecha y que emite una parpadeante luz roja junto al objetivo."; } else { print "Es una cámara de seguridad que parece no estar funcionando."; } print " Por detrás le sale un cable de color "; if (LugarReal() == oficina) { print "blanco "; } else { print "negro "; } "que se pierde fuera de la habitación, fijado a la parte superior de la pared."; ], found_in oficina laboratorio, visto_en_oficina false, visto_en_laboratorio false, after [; Examine: if (LugarReal() == oficina && ~~(self.visto_en_oficina) && ~~(decorado_seguridad.visto_en_seguridad)) { self.visto_en_oficina = true; PonerCableBlanco(); move rastro_cable_blanco to oficina; rfalse; } if (LugarReal() == laboratorio && ~~(self.visto_en_laboratorio) && ~~(decorado_seguridad.visto_en_seguridad)) { self.visto_en_laboratorio = true; PonerCableNegro(); move rastro_cable_negro to laboratorio; rfalse; } ], has female scenery; ! El abrazacaras en la oscuridad: Object abrazacaras_oscuridad thedark with each_turn [; if (real_location ofclass ZonaNorte) { real_location.each_turn(); } ], has concealed; class ZonaNorte with contador_muerte 0, ya_has_oido false, donde_estoy [; switch (self) { comedor1: if (despensa has visited) { return "la despensa"; } else { return "la sala situada al este"; } despensa: return "esta habitación"; cocina: if (despensa has visited) { return "la despensa"; } else { return "la sala que está al oeste"; } } ], after [; Go: if (noun == n_obj && self.ya_has_oido) { print "Sería mejor evitar esta zona: no parece muy segura...^"; } ], before [; Listen: if (self.ZonaNorte::contador_muerte >= 10) { "Oyes un ruido que procede de alguna parte de la despensa. Es un sonido agudo, como de animal."; } else { if (tu_traje in player && tu_traje has worn) { "El casco te impide oir nada con claridad."; } } Go: if (noun == s_obj) { if (self.ZonaNorte::contador_muerte >= 10) { print "Uff... Parece que lo que sea que emitía ese sonido se ha calmado... No cabe duda de que esa zona resulta muy peligrosa. Lo mejor será evitarla siempre que se pueda.^"; } self.ZonaNorte::contador_muerte = 0; } ], each_turn [; if (self.ZonaNorte::contador_muerte >= 15 && self == despensa) { ControlTimer.PrepararImpresion(); if (location == thedark) { print "^Sin apenas darte tiempo a reaccionar, algo blando, húmedo, frío y repulsivo al tacto "; } else { print "^Y entonces la ves. "; if (hueco_techo has visited) { print "Una araña idéntica a la que habías visto muerta en la sala de ventilación, "; } else { print "Una especie de araña, provista de unas patas anormalmente largas y delgadas y de una poderosa y serpenteante cola, "; } print "sale rápidamente de entre los expositores y "; } print "salta como una exhalación hacia ti. Te tapa completamente la cara, no puedes respirar, sus patas se cierran alrededor de tu cabeza en una suerte de abrazo terrible, y su larga cola se enrosca rodeando tu cuello. La hinchazón que provoca en tu laringe te hace sentir con dolorosa precisión que algo desciende por tu esófago, justo antes de perder el conocimiento...^"; KeyDelay(); Bandera_Fin(1); print "^Cuando despiertas, notas un regusto amargo en la boca, y la garganta te duele horrores. Pero lo peor no es eso... Algo se mueve dentro de ti... Algo que lucha por salir, que te presiona el pecho, que te deja casi sin respiración... No puedes soportar el dolor y gritas... gritas como nunca antes lo habías hecho, y tu grito coincide con el momento en que tus costillas se rompen hacia afuera y tu pecho estalla en sangre, carne y vísceras..."; if (location ~= thedark) { " Pero vives lo suficiente para ver esa pequeña y redonda cabeza llena de dientes saliendo de tu cuerpo...^"; } else { "^"; } } else { if (self.ZonaNorte::contador_muerte < 16) { self.ZonaNorte::contador_muerte++; } } if ((~~(self.ya_has_oido) && self.ZonaNorte::contador_muerte >= 10)) { self.ya_has_oido = true; } if (self.ZonaNorte::contador_muerte == 10 or 12 or 14 or 16) { ControlTimer.PrepararImpresion(); } switch (self.ZonaNorte::contador_muerte) { 10: Damusix.TocarV(Arana_Corto_ogg, 50); "^Oyes ruidos procedentes de alguna parte de ", (string) self.donde_estoy(), "."; 11: Damusix.TocarV(Arana_Corto_ogg, 50); 12: Damusix.TocarV(Arana_Largo_ogg, 100); "^Los ruidos se hacen más fuertes, y siguen viniendo de ", (string) self.donde_estoy(), "... Esto no te gusta nada..."; 13: Damusix.TocarV(Arana_Largo_ogg, 100); 14: Damusix.TocarV(Arana_Chillido_ogg, 100); "^Es un chillido... Claramente es un chillido... ¡Hay algo en ", (string) self.donde_estoy(), "! ¡Corre!"; 15: Damusix.TocarV(Arana_Chillido_ogg, 100); 16: Damusix.TocarV(Arana_Chillido_ogg, 100); "^¡Corre! ¡Sal de aquí! ¡Pero no pases por ", (string) self.donde_estoy(), "!"; } ]; Object despensa "Despensa" class Complejo class ZonaNorte with description "La despensa. En la zona frigorífica, frente a tí, es donde guardan los elementos perecederos. Desde aquí alcanzas a ver trozos de carne y frutas. A tu alrededor, cientos de expositores soportan los distintos tipos de comida prefabricada o enlatada de la que disponen los colonos. Algunos de los expositores están rotos y con la comida desperdigada por los alrededores.", sgw_img Despensa_jpg, w_to comedor1, e_to cocina; Object decorado_despensa despensa class Decorado with desc_frigorifico "Los alimentos se congelan en esa especie de gigantesco armario frigorífico. Está cerrado, y no parece abrirse.", desc_carne "Enormes trozos de carne sin procesar. Incomestibles, desde luego.", desc_frutas "Alcanzas a distinguir manzanas y algunas naranjas. El resto no lo habías visto en tu vida.", desc_m_p_m "Todo parece bastante jugoso. Aún así, no te fías...", desc_expositores "Muestran al posible consumidor la oferta de alimentos disponibles. Algunos están rotos, exponiendo la comida al aire.", desc_comida "Nada por lo que perderías el apetito.", before [; Take, Touch, Taste, Eat: if (self.number == 'carne' or 'trozos' or 'cerdo' or 'frutas' or 'fruta' or 'manzanas' or 'manzana' or 'naranjas' or 'naranja' or 'comidas' or 'comida' or 'alimentos' or 'alimento') { "Será mejor que no pruebes nada. Ni toque siquiera. Nunca se sabe..."; } Open, Pull, Push: if (self.number == 'frigorifico' or 'armario' or 'congelador') { PrintOrRun(self, no_puedes_abrir); rtrue; } ], no_puedes_abrir "Lo intentas con todas tus fuerzas, pero te resulta imposible: está herméticamente cerrado.", describe 'despensa' [; return despensa.description; ] G_FEMENINO 'frigorifico' [; return self.desc_frigorifico; ] 0 'armario' [; return self.desc_frigorifico; ] 0 'congelador' [; return self.desc_frigorifico; ] 0 'carne' [; return self.desc_carne; ] 0 'trozos' [; return self.desc_carne; ] G_PLURAL 'cerdo' [; return self.desc_carne; ] 0 'frutas' [; return self.desc_frutas; ] G_FEMENINO + G_PLURAL 'fruta' [; return self.desc_frutas; ] G_FEMENINO 'manzanas' [; return self.desc_m_p_m; ] G_FEMENINO + G_PLURAL 'manzana' [; return self.desc_m_p_m; ] G_FEMENINO 'peras' [; return self.desc_m_p_m; ] G_FEMENINO + G_PLURAL 'pera' [; return self.desc_m_p_m; ] G_FEMENINO 'melocotones' [; return self.desc_m_p_m; ] G_PLURAL 'melocoton' [; return self.desc_m_p_m; ] 0 'expositores' [; return self.desc_expositores; ] G_PLURAL 'expositor' [; return self.desc_expositores; ] 0 'comidas' [; return self.desc_comida; ] G_FEMENINO + G_PLURAL 'comida' [; return self.desc_comida; ] G_FEMENINO 'alimentos' [; return self.desc_comida; ] G_PLURAL 'alimento' [; return self.desc_comida; ] 0; Object "zona frigorífica" despensa with name 'zona' 'frigorifica', description [; PrintOrRun(decorado_despensa, desc_frigorifico); ], before [; Open, Pull, Push: PrintOrRun(decorado_despensa, no_puedes_abrir); rtrue; ], has scenery female; Object comedor1 "Comedor" class Complejo class ZonaNorte with nombre_localidad "comedor", description "Estás en el comedor de la colonia. Docenas de mesas se extienden a derecha e izquierda, de este a oeste, dejando únicamente un gran pasillo central por donde pasar cómodamente. Un sencillo cálculo mental tras un rápido vistazo arrojan una capacidad aproximada de cien personas. Una gran barra, por donde pasar las bandejas y servir la comida, se extiende hacia la habitación contigua hasta penetrar en ella. En una mesa cercana hay algunas bandejas de comida sin consumir.", sgw_img Comedor_jpg, e_to despensa, s_to balcon6; Object decorado_comedor comedor1 class Decorado with desc_mesas "Las mesas se alinean ordenadamente, fijas como están al suelo y, salvo una, todas se encuentran bastante limpias.", desc_bandejas "Algunas bandejas se alinean en la barra como soldados en formación, mientras que otras reposan toscamente en una de las mesas.", desc_comida "Es sólo comida putrefacta.", before [; Eat, Take: if (self.number == 'comida') { "Es evidente que no está en buen estado."; } Take: if (self.number == 'bandejas' or 'bandeja') { "No hay nada que merezca la pena."; } ], describe 'comedor' [; return comedor1.description; ] 0 'mesas' [; return self.desc_mesas; ] G_FEMENINO + G_PLURAL 'mesa' [; return self.desc_comida; ] G_FEMENINO 'barra' "Es una superficie rectangular, lisa y alargada, que tiene como finalidad servir de soporte a las bandejas de comida." G_FEMENINO 'bandejas' [; return self.desc_bandejas; ] G_FEMENINO + G_PLURAL 'bandeja' [; return self.desc_comida; ] G_FEMENINO 'comida' [; return self.desc_comida; ] G_FEMENINO 'alimentos' [; return self.desc_comida; ] G_PLURAL 'alimento' [; return self.desc_comida; ] 0; Object cocina "Cocina" class Complejo class ZonaNorte with description "Esta enorme cocina está unida al comedor por medio de las barras de autoservicio. Una gran cantidad de cacharros y pucheros penden de un techo bajo y claustrofóbico. El único mobiliario visible lo forman las mesas para preparar la comida. Diez enormes campanas de extracción adornan la parte alta de sendos fogones. Por lo demás, resulta sorprendende la ausencia de todo rastro de comida.", nombre_localidad "cocina", sgw_img Cocina_jpg, s_to balcon7, w_to despensa, has female; Object decorado_cocina cocina class Decorado with desc_barras "Es una superficie rectangular, lisa y alargada, que tiene como finalidad la de servir de soporte a las bandejas de comida. Se pierde por el oeste hacia el comedor situado junto a la cocina.", desc_cacharros "Ollas, cacerolas y todo tipo de utensilios de cocina, colgando del techo de forma laxa.", desc_mesas "Amplias e impolutas. Esta cocina parece no haberse usado en siglos.", desc_campanas "Potentes extractores de aire que expulsan el humo y el vapor. Ahora mismo se encuentran apagados, y no ves forma de hacerlos funcionar.", desc_fogones "Están compuestos de un material cerámico que se activa automáticamente y desprende calor al poner algo encima, aunque estos de aquí no parecen funcionar.", describe 'cocina' [; return cocina.description; ] G_FEMENINO 'barras' [; return self.desc_barras; ] G_FEMENINO + G_PLURAL 'barra' [; return self.desc_barras; ] G_FEMENINO 'cacharros' [; return self.desc_cacharros; ] G_PLURAL 'cacharro' [; return self.desc_cacharros; ] 0 'pucheros' [; return self.desc_cacharros; ] G_PLURAL 'puchero' [; return self.desc_cacharros; ] 0 'mesas' [; return self.desc_mesas; ] G_FEMENINO + G_PLURAL 'mesa' [; return self.desc_mesas; ] G_FEMENINO 'campanas' [; return self.desc_campanas; ] G_FEMENINO + G_PLURAL 'campana' [; return self.desc_campanas; ] G_FEMENINO 'extractores' [; return self.desc_campanas; ] G_PLURAL 'extractor' [; return self.desc_campanas; ] 0 'fogones' [; return self.desc_fogones; ] G_PLURAL 'fogon' [; return self.desc_fogones; ] 0; Object balcon1 class Balcon, with nivel 0, posicion n_obj, sgw_img Balcon_Oeste_Norte_jpg, n_to entrada, e_to laberinto3, w_to laberinto1, after [; Go: if (self hasnt visited && location ~= thedark) { print "Llegas a una especie de balcón desde donde se puede observar claramente la forma y la estructura del complejo. Todo está construido alrededor de la veta de mineral, situada en el centro del edificio, y hay balcones como este al norte, sur, este y oeste de dicha veta. Además, es evidente que este no es el único nivel del complejo, ya que continúa hacia abajo rodeando siempre al mineral. Las distancias son difíciles de calcular desde esta perspectiva, pero la sensación que transmite es que te encuentras ante algo grande.^"; } ]; Object balcon2 class Balcon, with nivel 0, posicion w_obj, sgw_img Balcon_Oeste_Norte_jpg, n_to laberinto1, s_to laberinto11, w_to oficina; Object balcon3 class Balcon, with nivel 0, posicion e_obj, sgw_img Balcon_Este_Sur_jpg, n_to laberinto3, s_to laberinto6, e_to laberinto7; Object balcon4 class Balcon, with nivel 0, posicion s_obj, sgw_img Balcon_Este_Sur_jpg, e_to laberinto6, w_to laberinto11, d_to balcon8, before [; Go: if (noun == d_obj) { if (procesador.arreglado()) { Damusix.TocarV(Montacargas_ogg, 50); } if (balcon8 hasnt visited) { if (procesador.arreglado()) { print "Te subes al montacargas y comienzas a bajar lentamente hacia el nivel -1...^"; } else { print "Al no haber energía en el montacargas, desciendes lentamente apoyándote en los salientes disponibles y finalmente alcanzas el nivel -1...^"; } KeyDelay(); rfalse; } } ]; Object balcon6 class Balcon, with nivel -1, posicion w_obj, sgw_img Balcon_Oeste_Norte_jpg, n_to comedor1, s_to laberinto18, ! Al oeste hay un hábitat before [; Go: if (noun == w_obj) { PrintOrRun(habitat, direccion); rtrue; } ], salidas [ d; switch (d) { w_obj: return 3; default: rfalse; } ]; Object balcon7 class Balcon, with nivel -1, posicion e_obj, sgw_img Balcon_Este_Sur_jpg, n_to cocina, s_to laberinto19, e_to enfermeria; Object balcon8 class Balcon, with nivel -1, posicion s_obj, sgw_img Balcon_Este_Sur_jpg, in_to puerta_emergencia, e_to laberinto19, w_to laberinto18, u_to balcon4, d_to balcon12, before [; Go: if (noun == d_obj or u_obj && procesador.arreglado()) { Damusix.TocarV(Montacargas_ogg, 50); } if (noun == d_obj && balcon12 hasnt visited) { if (procesador.arreglado()) { print "Lentamente, el montacargas va descendiendo aún más hacia las profundidades del complejo."; } else { print "Al no haber energía en el montacargas, desciendes lentamente apoyándote en los salientes disponibles y penetrando aún más hacia las profundidades del complejo."; } if (location ~= thedark) { print " Es evidente que estás entrando en un nivel aún inacabado (y el último construido hasta ahora, según puedes comprobar), diseñado para dar soporte y mantenimiento a los niveles superiores, y continuar descubriendo la veta aún más hacia el interior del planeta. La sensación de agobio se hace mayor por momentos, y las paredes y el techo se acercan entre sí como en una tenebrosa emboscada...^"; } else { print "^"; } KeyDelay(); rfalse; } ]; Object balcon12 class Balcon, with nivel -2, posicion s_obj, sgw_img Balcon_Este_Sur_jpg, cant_go "Este nivel aún está sin terminar. No hay más salidas.", e_to laberinto36, w_to laberinto28, u_to balcon8, before [; Go: if (noun == u_obj) { Damusix.TocarV(Montacargas_ogg, 50); } ]; class SalaEmergencia class Complejo with description [; "Te encuentras en la sala ", (string) self.situacion, " del área de emergencia. Está absolutamente vacía, a excepción de un gran botón pulsador situado en el centro de la pared opuesta a la puerta. Todo, desde sus pequeñas dimensiones a la total falta de decoración, favorece la sensación de asfixia."; ]; class ZonaEmergencia; Object emergencia_este "Sala este de emergencia" class SalaEmergencia class ZonaEmergencia with sgw_img Emergencia_Este_jpg, situacion "este", w_to emergencia_pasillo; Object emergencia_pasillo "Pasillo de emergencia" class Complejo class ZonaEmergencia with description "Estás en el pasillo central del área de emergencia. El pasillo discurre de este a oeste, hacia sendas salas separadas entre sí unos diez metros. La luz aquí es de un amarillo muy tenue, y la enorme letra ~E~ dibujada en la pared te recuerda que te encuentras en un lugar especialmente restringido.", out_to puerta_emergencia, e_to emergencia_este, w_to emergencia_oeste, sgw_img Emergencia_Pasillo_jpg, each_turn [; ! Cuando pasamos por el pasillo y hay algún botón pulsado, éste se escucha más ! bajito: if (boton_este has general || boton_oeste has general) { Damusix.VolumenCanal(CANAL_TICTAC, 60); } ], after [; Go: if (self hasnt visited) { print "Al cruzar la puerta te das cuenta de que has accedido... ¡al área de emergencia!"; KeyDelay(); print "^"; } ]; Object decorado_pasillo emergencia_pasillo class Decorado with desc_paredes "Las paredes están absolutamente desnudas, salvo por unas flechas dibujadas sobre un diseño rayado y una letra ~E~ tan alta como la pared misma, recordándote que estás en la zona de emergencia.", desc_flechas "Apuntan a cada una de las dos salas de emergencia, situadas en los extremos del pasillo.", describe 'paredes' [; return self.desc_paredes; ] G_FEMENINO + G_PLURAL 'pared' [; return self.desc_paredes; ] G_FEMENINO 'pasillo' [; return emergencia_pasillo.description; ] 0 'flechas' [; return self.desc_flechas; ] G_FEMENINO + G_PLURAL 'flecha' [; return self.desc_flechas; ] G_FEMENINO; Object "letra ~E~" emergencia_pasillo with name 'letra' 'e//', description "Es una enorme letra ~E~ que ocupa casi toda la altura de una pared del pasillo. Te informa de que estás en la zona de emergencia.", has scenery; Object "diseño rayado" emergencia_pasillo with name 'diseno' 'rayado' 'rayas', description "Es un motivo decorativo formado por una sucesión de rayas amarillas y negras.", has scenery; ! El atributo general indica que no es la primera vez que se abre Object puerta_emergencia "puerta" emergencia_pasillo class PNJPuerta class EscenarioAbrible with ! La librería PnjPuertas ya incluye la palabra 'puerta' como nombre name 'compuerta' 'emergencia', description [; print "Es una puerta sin ningún tipo de identificación. Tan sólo cabe destacar una ranura en un panel situado junto a ella."; if (self has open) { " Ahora mismo está abierta."; } else { ""; } ], when_closed "La puerta de emergencia está cerrada.", when_open "La puerta de emergencia está abierta.", in_to emergencia_pasillo, out_to balcon8, interior emergencia_pasillo, exterior balcon8, with_key tarjeta, lado_cierre balcon8, tras_abrir NO_PUEDE_ABRIR, before [; Open: if (self has locked) { "La puerta está bloqueada. Necesitas desbloquearla primero."; } if (LugarReal() == emergencia_pasillo && parent(jason) ofclass ZonaEmergencia && alien.comportamiento == 3 && alien in balcon8) { if (jason in LugarReal()) { HablaJason("Pero... ¿qué hace? ¡No abra la puerta con ese monstruo ahí!"); jason.decir = false; rtrue; } else { "¡Sería una locura abrir la puerta con ese monstruo al otro lado!"; } } Unlock: if (self hasnt locked) { print "(La puerta ya no está bloqueada, y no necesitas de nuevo la tarjeta para abrirla.)^^"; <>; } if (second ~= nothing && second ~= tarjeta) { print (The) second, " no parece entrar en la ranura.^"; rtrue; } if (~~(procesador.arreglado())) { "Introduces la tarjeta en la ranura, pero la puerta no responde ante la falta de energía del complejo."; } Lock: "Lo más que puedes hacer es cerrarla, pero no bloquearla."; Close: if (parent(alien) ofclass ZonaEmergencia) { "¡No cierres la puerta con el monstruo dentro!"; } ! Esto es para que la librería no diga que está abierta o cerrada: Examine: PrintOrRun(self, description); rtrue; ], after [; Open: self.abrir(); if (self hasnt general) { give self general; "Insertas la tarjeta en la ranura... y tras un leve zumbido, el cierre hidráulico de la puerta se desbloquea. Rápidamente recoges la tarjeta, abres la puerta y descubres un estrecho y largo pasillo."; } Unlock: <>; Close: if (alien.comportamiento == 3 && parent(jason) ofclass ZonaEmergencia) { print "Cierras la puerta.^"; HablaJason("¡Uff! Menos mal. Aquí estaremos a salvo... por un tiempo."); rtrue; } ], has female lockable locked; Object ranura "ranura" balcon8 with name 'ranura' 'raja' 'panel', description "En el panel metálico que hay junto a la puerta sólo destaca una fina ranura horizontal, de unos seis centímetros de largo por dos o tres milímetros de ancho. Se encuentra casi a la altura de los ojos.", before [; Receive: if (noun ~= tarjeta) { print (The) noun, " no parece entrar en la ranura.^"; rtrue; } <>; ], has female scenery container; Object emergencia_oeste "Sala oeste de emergencia" class SalaEmergencia class ZonaEmergencia with sgw_img Emergencia_Oeste_jpg, situacion "oeste", e_to emergencia_pasillo; class BotonEmergencia with name 'boton' 'pulsador', color, description [; print "Es un enorme botón de color ", (string) self.color, " que sobresale de la pared a la altura de los ojos."; if (self has general) { print " Ahora mismo está pulsado y se oye un tic tac que sale de él."; } ""; ], pulsar_ya_pulsado "El botón se ha quedado hundido y ya no se puede hacer nada con él. ¡Olvídalo!", descripcion_ya_pulsado [; "Es un enorme botón de color ", (string) self.color, " que sobresale de la pared a la altura de los ojos. Se ha quedado pulsado y no se puede actuar sobre él."; ], time_left, each_turn [; if (self has general) { Damusix.VolumenCanal(CANAL_TICTAC, VOLUMEN_TICTAC); } ], before [; Push: if (puerta_emergencia has open) { "Los botones no funcionarán hasta que se cierre la puerta."; } self.pulsar(); rtrue; ], alguien_pulsa [ vol; ! Si el botón ya está pulsado, no se puede volver a pulsar: if (self has general) { switch (actor) { selfobj: "El botón ya está pulsado, sigue hundido y no se puede pulsar más."; jason: HablaJason("¿Cómo voy a volver a pulsarlo si sigue pulsado? ¡Ya no entra más!"); rtrue; } } give self general; if (LugarReal() == parent(self)) { vol = 100; } else { switch (LugarReal()) { emergencia_pasillo: vol = 60; default: vol = 30; } } Damusix.VolumenCanal(CANAL_TICTAC, vol); Damusix.Tocar(Tic_ogg); switch (actor) { selfobj: "Al pulsar el botón, este se queda hundido y se oye un tic tac..."; jason: HablaJason("¡He pulsado el botón, se ha quedado dentro y se oye algo que no sé qué es!"); rtrue; } ], liberar_boton [; give self ~general; Damusix.PararCanal(CANAL_TICTAC); if (LugarReal() == parent(self)) { "^El botón salta a su posición inicial y el tic tac se detiene."; } else { "^Desde lejos oyes que el botón de la otra sala salta a su posición inicial."; } if (jason in parent(self)) { HablaJason("El botón ha saltado y ahora está como al principio."); rtrue; } ], has scenery; ! El primero de los botones que hay que pulsar. ! El atributo general indica que está pulsado Object boton_este "botón rojo" emergencia_este class BotonEmergencia with color "rojo", adjectives 'rojo', time_out [; if (boton_oeste hasnt general) { self.liberar_boton(); } ], pulsar [; if (self hasnt general) { StartTimer(self, 2); self.alguien_pulsa(); } else { switch (actor) { selfobj: "El botón ya está pulsado, sigue hundido y no se puede pulsar más."; jason: HablaJason("¡Si ya está pulsado!"); } } ]; ! El segundo de los botones que hay que pulsar. ! El atributo general indica que está pulsado Object boton_oeste "botón azul" emergencia_oeste class BotonEmergencia with color "azul", adjectives 'azul', time_out [; self.liberar_boton(); ], pulsar [; if (boton_este hasnt general) { StartTimer(self, 2); self.alguien_pulsa(); } else { StopTimer(self); StopTimer(boton_este); give self general; switch (actor) { selfobj: print "¡El botón se queda hundido!^"; jason: HablaJason("¡Esto parece que funciona!"); } ! Se activa la autodestrucción: QuintaParte(); } ]; Object aula "Aula" class Complejo with nombre_localidad "aula", description [; print "Una sala de mediano tamaño, con el aspecto propio de un salón de reuniones o aula de formación, se extiende ante tus ojos"; if (procesador.arreglado()) { print " iluminada uniformemente desde el techo"; } ". La mesa que parece destinada al docente domina la estancia desde un lateral de la habitación, enfrentada a las demás mesas o pupitres, más pequeñas y sencillas. En el centro de la sala hay un proyector orientado hacia una enorme pantalla blanca, situada al fondo."; ], sgw_img Aula_jpg, w_to laberinto3, s_to laberinto7, before [; Go: if (noun == w_obj or s_obj && alien.comportamiento == 3 && holocubo notin player && holocubo notin jason) { HablaJason("¡Tenemos que llevarnos el holocubo! ¡La gente debe saber qué pasa aquí!"); rtrue; } ]; Object decorado_aula aula class Decorado with desc_patas "Son, sencillamente, las patas que sujetan la mesa del docente.", describe 'aula' [; return aula.decorado; ] G_FEMENINO 'patas' [; return self.desc_patas; ] G_FEMENINO + G_PLURAL 'pata' [; return self.desc_patas; ] G_FEMENINO; Object "mesas de los alumnos" aula with name 'mesa' 'mesas//p' 'pupitre' 'pupitres//p' 'puesto' 'puestos//p', adjectives 'alumno' 'alumnos//p', description "Cada mesa tiene el aspecto de un pupitre no muy grande, rectangular, emparejado con su correspondiente silla, sencilla y acolchada. La mesa del profesor es bastante más grande y dispone de un sillón que resulta de entrada mucho más confortable a la vista.", has female pluralname scenery; Object "sillas de los alumnos" aula with name 'silla' 'sillas//p', adjetivs 'alumno' 'alumnos//p', description "Son pequeñas y escuetas sillas de color gris. No parecen demasiado incómodas, pero desde luego no invitan a descansar en ellas.", has female pluralname scenery; Object "mesa del profesor" aula with name 'mesa', adjectives 'profesor' 'docente', description "Una mesa de mayor tamaño que el resto de los pupitres de la sala, compuesta, al igual que las demás, de una superficie rectangular apoyada en cuatro patas metálicas.", has female scenery; Object "silla del profesor" aula with name 'silla' 'sillon', adjectives 'profesor' 'docente', description "Es un sillón amplio, de color negro, con reposabrazos.", has female scenery; Object proyector "proyector" aula with name 'proyector', description "Un proyector.", describe [; if (self has on) { "^El proyector está emitiendo imágenes hacia la pantalla."; } else { rtrue; } ], react_before [; Listen: if (self has on) { "Oyes la voz de la grabación, describiendo minuciosamente y con todo detalle la fisionomía de un ser extraterrestre. Por sus palabras y lo visto en la pantalla de proyección, no te cabe duda de que está hablando del mismo ser que os atacó antes a Jason y a ti."; } else { rfalse; } ], before [; Examine: print "Es un dispositivo destinado a proyectar el contenido audiovisual almacenado en un holocubo"; if (holocubo notin self) { ", pero no contiene ninguno dentro para proyectar."; } if (self has open) { ", y contiene uno, pero no se podrá poner en funcionamiento hasta que el proyector se cierre."; } if (self hasnt on) { ". Está apagado."; } ", y está emitiendo imágenes hacia una pantalla situada en frente."; Burn: <>; SwitchOn: if (holocubo notin self) { "No hay nada que proyectar."; } if (self has open) { "Tienes que cerrar el proyector primero."; } if (~~(procesador.arreglado())) { "No hay energía suficiente en el complejo para encender el proyector."; } ], after [; SwitchOn: "Enciendes el proyector, y sobre la pantalla empiezan a desfilar imágenes."; Open: if (self has on) { keep_silent = 1; ; keep_silent = 0; "Al abrir el proyector, éste se apaga automáticamente."; } ], invent [; if (inventory_stage == 2) { if (self has on) { print " (encendido)"; } else { print " (apagado)"; } rtrue; } ] has switchable openable open container static; ! El atributo general indica si es la primera vez que examinamos la pantalla con el ! proyector encendido: Object pantalla "pantalla" aula with name 'pantalla', description "Una amplia superficie blanca y rectangular, de textura fibrosa, anclada en el techo de la sala y ocupando la mayor parte de la pared norte.", before [; Examine: if (proyector has on) { if (self hasnt general) { give self general; if (jason.sacado()) { Damusix.TocarV(Tension_ogg); sacador_de_aliens.meter_alien(); alien.comportamiento = 3; PNJ_Ruta(alien, MOVIMIENTO_PERSEGUIR, player); print "Al mirar a la pantalla, ves el contenido del holocubo. Y lo que ves te da la solución a tu problema:^^"; } else { print "Al mirar a la pantalla, ves el contenido del holocubo:^^"; } } print (s_b) "*** HOLOCUBO DE SEGURIDAD - PROTOCOLO DE EMERGENCIA: ***^^"; print "En caso de emergencia, proceder a la autodestrucción del complejo siguiendo el siguiente procedimiento:^^"; print "1. Penetrar en la zona de emergencia (nivel -1, zona sur).^"; print "2. Cerrar su única entrada para aislarla del exterior.^"; print "3. Pulsar simultáneamente los botones rojo y azul, en ese orden, antes de que vuelvan a su posición inicial.^^"; print (s_b) "*** NOTAS: ***^^"; print "a. Tras la activación del protocolo, se abrirá el ascensor de emergencia (nivel -2, zona norte).^"; print "b. El ascensor será la única vía de salida mientras dure la emergencia.^"; print "c. Se dispondrá de un máximo de diez minutos para evacuar el complejo.^"; print "d. El protocolo no puede abortarse en ningún momento.^^"; print "[La clave para acceder al documento ~", (s_b) "Holocubo.pdf", "~ es ", (s_b) "APOGEO", " (en mayúsculas).]^^"; print "¡En el documento está todo! Todo lo necesario para demostrar quiénes son los culpables. ¡Hay que llevarse el holocubo y usarlo como prueba!^"; if (jason in LugarReal()) { HablaJason("¡Vamos a volar todo esto en pedazos!"); jason.decir = false; PNJ_Ruta(jason, MOVIMIENTO_PERSEGUIR, player); } rtrue; } else { "La pantalla permanece en blanco."; } ], has female scenery; Object seguridad "Sala de seguridad" class Complejo with nombre_localidad "sala", description [; print "En la sala de seguridad, tan fría y estéril como el restro del complejo, llama principalmente la atención la consola de control, un dispositivo pantalla-teclado que abarca en extensión casi todo el ancho de la estancia. Un cable blanco y otro negro entran en la sala por medio de una hendidura en la pared, para acabar conectados a la parte posterior de la consola. "; if (procesador.arreglado()) { "La luz, lúgubre y tenue, proyecta sombras en los paneles laterales de la habitación, por los que fluyen tubos de varios grosores."; } else { "Por los paneles laterales de la habitación fluyen tubos de varios grosores."; } ], sgw_img Seguridad_jpg, n_to laberinto18, has female; Object decorado_seguridad seguridad class Decorado with visto_en_seguridad, desc_cables [; if (~~(camara_seguridad.visto_en_oficina)) { decorado_seguridad.visto_en_seguridad = true; PonerCableBlanco(); move rastro_cable_blanco to seguridad; } if (~~(camara_seguridad.visto_en_laboratorio)) { decorado_seguridad.visto_en_seguridad = true; PonerCableNegro(); move rastro_cable_negro to seguridad; } return "Son dos cables (uno blanco y otro negro) que provienen del exterior de la sala y que están conectados a la consola."; ], desc_tubos "Algunos anchos, otros delgados... Todos metálicos, reptando por la pared, entrando o saliendo de ella.", desc_paredes "Lo único digno de destacar de las paredes son los tubos que las cruzan y los dos cables que salen de una de ellas por un agujero.", desc_agujero "Es un agujero situado en la parte superior de la pared del fondo, por el que salen dos cables de distinto color.", before [; Take, Touch: if (self.number == 'tubos' or 'tubo') { "Los tubos están muy sujetos a las paredes, y su tacto es frío y seco."; } else if (self.number == 'cables' or 'cable') { "Mejor no tocarlos demasiado. Podrías llevarte una buena descarga..."; } else if (self.number == 'hendidura' or 'agujero' or 'orificio') { "El agujero está muy alto y no alcanzas. Pero está claro que tampoco es demasiado importante..."; } ], describe 'sala' [; return seguridad.description; ] G_FEMENINO 'hendidura' [; return self.desc_agujero; ] G_FEMENINO 'agujero' [; return self.desc_agujero; ] 0 'orificio' [; return self.desc_agujero; ] 0 'paredes' [; return self.desc_paredes; ] G_FEMENINO + G_PLURAL 'pared' [; return self.desc_paredes; ] G_FEMENINO 'tubos' [; return self.desc_tubos; ] G_PLURAL 'tubo' [; return self.desc_tubos; ] 0 'cables' [; return self.desc_cables(); ] G_PLURAL 'cable' [; return self.desc_cables(); ] 0; ! posicion_actual: ! = 0: Situación de partida ! = 1: Se ha visto la grabación del alien escapando ! = 2: Se ha visto la grabación de la caja fuerte Object consola "consola de control" seguridad with name 'consola' 'seguridad' 'control', description "Es una consola que sirve para poder ver las grabaciones de las cámaras de seguridad. Está formada por un monitor de televisión y un pequeño teclado en el que destaca un botón ~Reproducir~.", ! Tiene un botón ~Reproducir~, otro botón ~Retroceder~ y ! otro más para seleccionar la grabación a reproducir, etiquetado con ! la palabra ~Seleccionar~.", posicion_actual 0, before [; Burn: if (procesador.arreglado()) { "Ya está encendida."; } else { "No hay energía suficiente."; } SwitchOff: "No ves cómo ni por qué hacerlo."; ], has female transparent scenery; !Object boton_retroceder "botón Retroceder" consola ! with ! nombre 'boton', ! adjetivos 'retroceder', ! descripcion "Es un botón que sirve para poder volver a visualizar la grabación desde ! el principio."; Object teclado_consola "teclado de la consola" consola with name 'teclado', description "Una sencilla formación de diversos botones entre los que llama la atención uno etiquetado con la palabra ~Reproducir~.", before [; Burn: if (procesador.arreglado()) { "La consola ya está encendida."; } else { "No hay energía suficiente."; } SwitchOff: "No ves cómo ni por qué hacerlo."; Push: "Pulsar botones al azar no serviría de nada."; ]; Object monitor "monitor de televisión" consola with name 'monitor' 'pantalla' 'aparato' 'television', description [; print "Es el aparato que muestra las imágenes grabadas por las cámaras de seguridad. Ahora mismo "; ], before [; Burn: if (procesador.arreglado()) { "Ya está encendido."; } else { "No hay energía suficiente."; } SwitchOff: "No ves cómo ni por qué hacerlo."; ], after [; Examine: if (~~(procesador.arreglado())) { "está totalmente apagado."; } switch (consola.posicion_actual) { 0: "sólo muestra caracteres al azar..."; 1: "muestra la última imagen del alien escapando."; 2: "muestra la caja fuerte abierta."; 3: "indica que no hay más imágenes grabadas."; } ]; Object boton_reproducir "botón Reproducir" consola with name_m 'boton' 'reproducir', name_f 'tecla', ! adjetivos 'reproducir', description "Es un botón que sirve para poder visualizar la grabación desde su posición actual.", grabacion_laboratorio [; print "Al pulsar el botón de reproducción, comienzan a aparecer imágenes en el monitor de la consola. Y lo que ves parece ser la grabación de la cámara de seguridad de un laboratorio"; if (laboratorio has visited) { print " (evidentemente, el mismo laboratorio que ya conoces)"; } print ", donde varias personas vestidas con batas blancas caminan aquí y allá llevando materiales y anotando datos.^"; KeyDelay(); print "^¡Un momento! ¡En una especie de jaula de contención se vislumbra claramente la figura del monstruo! ¡Lo tienen encerrado para estudiarlo! Ahora lo entiendes todo... Ese monstruo es un arma demasiado poderosa para ser ignorada, y ese laboratorio no es más que el lugar donde pretendían sacar partido de su potencial destructivo. El ansia de poder de estos burócratas es aún mayor de lo que esperabas...^"; KeyDelay(); print "^¿Qué...? ¡El monstruo ha roto la cabina de contención y se escapa! ¡Dios santo... qué carnicería! No puedes seguir manteniendo la mirada en la pantalla, pero casi puedes oir la sangre derramándose al salir de sus destrozados cuerpos. ¡Malditos sean mil veces los responsables de esta masacre! Por su culpa, todo este complejo ha pasado a convertirse en un enorme cementerio.^"; KeyDelay(); print "^Cuando por fin reúnes el valor suficiente para seguir mirando, ves que la grabación se ha detenido, y que la consola indica que hay otra grabación pendiente de ser visionada.^"; rtrue; ], grabacion_oficina [; move cuadro to oficina; print "En esta grabación ves una oficina"; if (oficina has visited) { print "(la oficina que ya conoces)"; } print ", en la que hay varias personas trabajando, con sus importantísimos documentos oficiales y sus potentísimos equipos informáticos. En un momento dado, el que parece de mayor graduación dice algo y los demás abandonan la habitación.^"; KeyDelay(); print "^Una vez que se ve por fin solo, se levanta y se dirige hacia uno de los muchos cuadros que tiene en la pared del fondo. Lo retira y... ¡ves que detrás hay una caja fuerte! El pez gordo introduce ahora la combinación de la caja, y a continuación la abre. El monitor lo ha mostrado bien claro: el número de la combinación es el 111582.^"; KeyDelay(); print "^El hombre saca algo de su bolsillo... Es un objeto no muy grande, en forma rectangular... Finalmente, lo mete en la caja fuerte y la cierra, volviendo a colocar el cuadro en su posición original.^"; rtrue; ], before [; Push: if (~~(procesador.arreglado())) { "No ocurre nada. No hay energía para poner esto en marcha."; } if (consola.posicion_actual < 3) { consola.posicion_actual++; switch (consola.posicion_actual) { 0: "El monitor sólo muestra caracteres al azar..."; 1: self.grabacion_laboratorio(); rtrue; 2: self.grabacion_oficina(); rtrue; 3: "No hay más imágenes grabadas."; } } else { "No ocurre nada. Parece que se han agotado las grabaciones."; } ]; !Object boton_seleccionar "botón Seleccionar" consola ! with ! nombre 'boton', ! adjetivos 'seleccionar', ! descripcion "Es un botón que sirve para poder seleccionar qué grabación se desdea ! reproducir."; Object laberinto1 class Laberinto, with sgw_img Laberinto_Oeste_jpg, s_to balcon2, e_to balcon1, ! Al oeste hay un hábitat before [; Go: if (noun == w_obj) { PrintOrRun(habitat, direccion); rtrue; } ], salidas [ d; switch (d) { w_obj: return 3; default: rfalse; } ]; Object habitat "hábitat" with name 'puerta' 'vivienda', adjectives 'habitat', found_in laberinto1 laberinto11 balcon6 laberinto18, description "Es la puerta de acceso a un hábitat. Está cerrada y no ves manera de abrirla.", direccion "En esa dirección hay una puerta cerrada que da acceso al hábitat de algún colono o familia.", before [; Open, Unlock: "No hay forma de abrir esa puerta. En realidad, no deberías molestarte en ella."; Close: "Ya está bastante cerrada."; ], has scenery; Object laberinto3 class Laberinto, with s_to balcon3, e_to aula, w_to balcon1; Object laberinto6 class Laberinto, with n_to balcon3, w_to balcon4; Object laberinto7 class Laberinto, with n_to aula, w_to balcon3; Object laberinto11 class Laberinto, with sgw_img Laberinto_Oeste_jpg, n_to balcon2, e_to balcon4, ! Al oeste hay un hábitat before [; Go: if (noun == w_obj) { PrintOrRun(habitat, direccion); rtrue; } ], salidas [ d; switch (d) { w_obj: return 3; default: rfalse; } ]; Object laberinto16 class Laberinto, with n_to enfermeria, w_to laberinto19; Object laberinto18 class Laberinto, with sgw_img Laberinto_Oeste_jpg, n_to balcon6, e_to balcon8, s_to seguridad, ! Al oeste hay un hábitat before [; Go: if (noun == w_obj) { PrintOrRun(habitat, direccion); rtrue; } ], salidas [ d; switch (d) { w_obj: return 3; default: rfalse; } ]; Object laberinto19 class Laberinto, with n_to balcon7, w_to balcon8, e_to laberinto16, s_to laboratorio; Object laberinto28 class Laberinto, with sgw_img Ascensor_Emergencia_jpg, e_to balcon12, in_to laberinto28, ! Esto es para que funcione "jason, vete adentro" cant_go "Este nivel aún está sin terminar. No hay más salidas.", before [ t; Go: if (noun == in_obj) { if (ascensor has open) { if (jason in self && jason.tipo_de_movimiento == MOVIMIENTO_PERSEGUIR && jason.perseguido == player) { if (holocubo notin player && holocubo notin jason) { if (pantalla has general) { HablaJason("¡Tenemos que llevarnos el holocubo! ¡Necesitamos una prueba de lo que ha pasado aquí!"); jason.decir = false; rtrue; } else { HablaJason("¡No podemos irnos sin una prueba que demuestre lo que ha pasado aquí!"); jason.decir = false; rtrue; } } else { if (pantalla hasnt general) { HablaJason("¡No sabemos si algo de lo que llevamos podría servirnos de prueba contra estos cabrones! ¡Tenemos que estar seguros!"); jason.decir = false; rtrue; } } t = false; if (hayGraficos) { t = true; ApagarGraficosSub(true); } clearMainWindow(); ControlTimer.PausarTick(); ! Para que no corra el tiempo ahora tt_escape1.visualiza(); Damusix.TocarV(Rugido_ogg); tt_escape2.visualiza(); Damusix.VolumenCanal(CANAL_SIRENA, VOLUMEN_SIRENA / 2); move ascensor_arriba to exterior3; move jason to exterior3; PlayerTo(exterior3); if (t) { EncenderGraficosSub(true); } ControlTimer.ReanudarTick(); ! Para que vuelva a correr el tiempo rtrue; } else { "¡No dejes a Jason aquí!"; } } else { "No podrás entrar en el ascensor hasta que esté abierto."; } } ], antesPNJ [; Go: if (second == in_obj) { if (ascensor has open) { HablaJason("¡Entre usted primero! ¡Vamos!"); } else { HablaJason("No puedo entrar ahí... Está cerrado."); } } rtrue; ]; Object laberinto30 class Laberinto, with w_to balcon12, e_to laberinto36; Object laberinto36 class Laberinto, with description "Estás en uno de los pasillos interiores del complejo. Metros y metros de estructura metálica recorren estos túneles, que parecen no acabar nunca. Puedes apreciar que las paredes en esta sección son más curvadas, y los techos bastante más bajos: tanto que, en esta sala, casi hay que pasar agachado. El corredor continúa por el oeste, y hacia arriba hay acceso a través de una trampilla en el techo.", u_to ventilacion1, w_to balcon12, cant_go "Este nivel aún está sin terminar. No hay más salidas.", before [; Examine: if (noun == u_obj) { "Hay una trampilla a la que tienes un fácil acceso, debido a la poca altura a la que se encuentra el techo."; } ]; Object trampilla "trampilla" laberinto36 with name 'trampilla' 'techo' 'orificio', description "Es una trampilla abierta en el techo.", before [; GoIn: <>; Examine: rfalse; default: "Es un simple agujero de acceso a una zona superior. No hay mucho más que añadir."; ], has scenery; Object ascensor "ascensor de emergencia" laberinto28 with name 'ascensor' 'elevador' 'cubiculo' 'emergencia', description "Es una especie de cabina rectangular de cristal muy resistente, reforzado por cientos de remaches metálicos. Su tamaño aproximado es de unos cinco por cinco metros. Próximo a él, junto a la pared, hay un cartel que dice: ~ASCENSOR DE EMERGENCIA: Apertura automática~.", when_closed "En un lateral del túnel hay un cubículo en forma de ascensor.", when_open "El ascensor de emergencia está abierto. ¡Yo que tú me andaría con prisas!", before [; Open, Attack: if (self hasnt open) { "Al parecer, el ascensor sólo se abrirá en caso de emergencia. No hay cerradura ni panel de control con el que accionarlo."; } else { "El ascensor ya está abierto. ¡Aprovecha la ocasión!"; } Close: if (self hasnt open) { "No está abierto, así que no puedes cerrarlo."; } else { "No es posible cerrarlo, y no creo que sea el momento ahora de pensar en ello."; } GoIn: <>; ], has static container openable; ! Hay que poner recipiente con si_abierto y si_cerrado Object ventilacion1 class Complejo with short_name "Sala oeste de ventilación", nombre_localidad "sala destinada a la ventilación", description "Estás en una de las salas de ventilación en los pasillos interiores del complejo. Situados en el techo anormalmente bajo de la estancia puedes observar varios de los muchos ventiladores que se encargan de suministrar aire a todo el nivel subterráneo del complejo. El zumbido que producen es casi hipnótico.", sgw_mus Ventilacion_ogg, sgw_img Ventilacion1_jpg, d_to laberinto36, e_to hueco_techo, before [; Listen: "El sonido de las corrientes de aire provocadas por los ventiladores es constante y rítmico. Es de esos sonidos que no te dejan pensar."; Examine: if (noun == d_obj) { "Desde aquí puedes bajar al túnel inferior."; } else if (noun == u_obj) { "Los ventiladores rugen fuertemente allá arriba, inyectando aire hacia el interior."; } ], has female; Object decorado_ventilacion1 ventilacion1 class Decorado with desc_ventiladores [; print "Pequeños pero potentes ingenios que giran veloces absorbiendo aire del exterior y expulsándolo al interior del complejo."; if (~~(procesador.arreglado())) { "La energía necesaria para moverlos debe provenir del exterior del complejo."; } else { print "^"; } ], desc_paredes "Las paredes son metálicas y lisas, sin ningún adorno.", describe 'sala' [; return ventilacion1.description; ] G_FEMENINO 'paredes' [; return self.desc_paredes; ] G_PLURAL 'pared' [; return self.desc_paredes; ] 0 'ventiladores' [; return self.desc_ventiladores; ] G_PLURAL 'ventilador' [; return self.desc_ventiladores; ] 0 'aspas' [; return self.desc_ventiladores; ] G_FEMENINO + G_PLURAL 'aspa' [; return self.desc_ventiladores; ] G_FEMENINO; Object hueco_techo "Sala este de ventilación" class Complejo with description "Estás en una sala de ventilación en los pasillos interiores del complejo. Todos los ventiladores que deberían estar girando en el techo se encuentran esparcidos por el suelo con sus aspas rotas e inútiles. Una enfermiza luz de color verde pálido lo mancha todo sin que sea posible apreciar su fuente. Pero lo que más llama tu atención es la sustancia mucosa y repugnante que cubre casi la totalidad de las paredes y el techo. Un techo tan bajo que casi te impide permanecer totalmente de pie, y en el que, además, se aprecia un enorme hueco, cubierto también por la misma desagradable viscosidad.", sgw_mus Vaina_ogg, sgw_img Hueco_Techo_jpg, w_to ventilacion1, before [; Examine: if (noun == d_obj) { "En el suelo sólo cabe destacar las aspas rotas de los ventiladores y la asquerosa sustancia que lo empapa todo y que casi te impide caminar."; } else if (noun == u_obj) { <>; } ], after [; Go: if (self hasnt visited) { print "Avanzas un poco más, dejando atrás los sonoros ventiladores... y por un momento tu mente te hace creer que lo que tienes ante ti no es más que una alucinación producto del hipnotizante ritmo del aire... Pero no: lo que ves es muy real, así que algo no marcha bien... Nada bien...^"; KeyDelay(); print (s_em) "^Dios santo... Pero... ¿qué...? ¿Qué es esto...?^"; KeyDelay(); print (s_b) "^Oh... Dios... mío...^"; KeyDelay(); } ]; Object techo "techo" hueco_techo with name 'hueco' 'techo', description "Incrustado dentro del hueco en el techo ves una vaina viscosa y verde de aspecto repulsivo y ligeramente fosforescente.", after [; Examine: vaina.aparecer(); ], has scenery; Object abrazacaras "araña" hueco_techo with name_f 'arana', name_m 'animal' 'aracnido' 'abrazacaras', gender G_FEMENINO, description [; print "Es un animal muerto, parecido a una araña, tumbado boca arriba en el suelo. Es de color crema, con ocho delgadas y articuladas patas, y una cola larga y con forma de serpiente. En lo que parece ser el ~cuerpo~, observas órganos internos y una especie de trompa que parece hacer las veces de ~boca~. Verdaderamente, es un ser asqueroso."; if (self.cortada) { " En una de sus patas hay una pequeña incisión."; } else { ""; } ], initial "Una especie de araña nauseabunda yace muerta en el suelo, junto a un enorme huevo.", cortada false, before [; Examine: rfalse; Cut: if (second == nothing) { "Necesitarás usar algún instrumento cortante."; } if (second == bisturi) { if (vaina has open) { "El bisturí ya no tiene energía para cortar nada."; } if (~~(self.cortada)) { self.cortada = true; hueco_techo.marcaRastro(alien, rastro_acido, d_obj, nivelClaro); move rastro_acido to hueco_techo; "Acercas el bisturí a una de las patas de la ~criatura~ y, al activarlo, un humo denso y tóxico comienza a surgir del punto de corte. Al mismo tiempo, una gota de ácido brota de la herida y cae al suelo, disolviendo todo a su paso..."; } else { "Mejor no... No conseguiste nada la primera vez."; } } else { "Eso no sirve para cortar nada."; } default: "No te atreves ni a acercarte, aunque sabes que está muerta."; ], has static; Object decorado_hueco hueco_techo class Decorado with desc_paredes "Las paredes están prácticamente cubiertas por esa sustancia viscosa tan desagradable.", desc_ventiladores "Las enormes aspas de los ventiladores yacen por el suelo, rotas en pedazos.", before [; Cut: if (self.number == 'huevo') { "No es necesario cortarlo: ya está abierto por arriba."; } Touch: switch (self.number) { 'sustancia': <>; 'huevo': "Es algo membranoso al tacto... aunque muy duro."; 'cola': "Tiene el tacto y la dureza de una serpiente."; 'luz': "¿Tocar algo inmaterial? ¿Te encuentras bien?"; } Take: switch (self.number) { 'ventiladores', 'ventilador', 'aspas', 'aspa': "No serviría de nada. Las aspas están rotas y son inservibles."; 'cola': "La tomas en tus manos, pero un miedo irracional te obliga a soltarla y alejarte del animal."; 'huevo': "Parece pegado al suelo. De todas formas, no hay razón para llevárselo."; } ], describe 'sala' [; return hueco_techo.description; ] G_FEMENINO 'ventiladores' [; return self.desc_ventiladores; ] G_PLURAL 'ventilador' [; return self.desc_ventiladores; ] 0 'aspas' [; return self.desc_ventiladores; ] G_FEMENINO + G_PLURAL 'aspa' [; return self.desc_ventiladores; ] G_FEMENINO 'paredes' [; return self.desc_paredes; ] G_FEMENINO + G_PLURAL 'pared' [; return self.desc_paredes; ] G_FEMENINO 'cola' "Es un apéndice muy largo y robusto que sobresale de la parte posterior del animal." G_FEMENINO 'sustancia' "Es una sustancia muy pegajosa, unas veces muy blanda y otras muy sólida y rígida." G_FEMENINO 'luz' "Es una luminiscencia débil de un color verde muy apagado, única hasta ahora en todo el complejo." G_FEMENINO 'huevo' "El huevo está abierto por la parte superior, merced a cuatro membranas que se pliegan hacia fuera mostrando el interior. Al acercarte, observas que está vacío, y que las paredes están compuestas de algún tipo de proteína traslúcida que deja pasar algo de luz. Por lo demás, está completamente cubierto (por dentro y por fuera) de la sustancia viscosa que inunda la sala." 0; Object "patas" hueco_techo with name 'patas' 'pata', description [; print "Ocho patas grotescamente largas y delgadas, con varias articulaciones."; if (abrazacaras.cortada()) { " Una de ellas tiene una pequeña incisión."; } else { ""; } ], before [; Cut: <>; Take: <>; Push: <>; Pull: <>; default: "Deja las patas en paz... Te dan malas vibraciones."; ], has scenery; Object "incisión" with name_m 'corte', name_f 'incisión', gender G_FEMENINO, description "Es un pequeño corte por el que salió antes una gota de ácido.", has scenery; ! El atributo general indica que ya sabemos que Jason está dentro de la vaina Object vaina "vaina mucosa" hueco_techo with name 'vaina' 'mucosa' 'gelatinosa' 'mucosidad' 'viscosidad' 'viscosa' 'gelatina' 'capullo' 'mocos', description [; print "Es una especie de capullo mucoso y gelatinoso, pero que, al mismo tiempo, tiene el aspecto de ser terríblemente duro. Calculas que tendrá más de dos metros de alto por casi un metro de ancho. Está incrustado dentro del hueco del techo, firmemente pegado al mismo por grandes y pequeños filamentos pegajosos de la misma sustancia que lo forma. "; if (self has open) { print "Muestra un enorme corte, lo bastante grande como para dejar pasar un cuerpo humano adulto. "; } if (jason in self) { if (self has general) { print "Jason sigue dentro. ¡Sácalo de ahí!"; } else { give self general; ! general indica que ya sabemos que Jason está dentro give self transparent; print "Espera... Un momento... No puedes creer lo que ves... Te acercas todo lo que puedes, pegando casi tu cara contra el nauseabundo capullo... y entonces lo ves..."; KeyDelay(); print (s_b) "^^¡VES A JASON DENTRO DE LA VAINA!"; } } ""; ], when_closed [; print "Hay una vaina gelatinosa y rígida pegada en un hueco en el techo. "; if (jason in self && self has general) { "Jason sigue dentro de ella."; } else { ""; } ], when_open [; print "La vaina mucosa del techo muestra un enorme corte, lo bastante grande como para dejar pasar un cuerpo humano adulto. "; if (jason in self && self has general) { "Jason sigue dentro de ella."; } else { ""; } ], with_key bisturi, ! El bisturi nos permite abrir la vaina before [; Open, Attack: ! Si no hay aire fuera, no se deja: if (self.comprobar_aire()) { rtrue; } ! Si intentas abrir con algo que no sea el bisturí if (self has locked && second ~= bisturi) { "Necesitarás algún objeto cortante para poder abrir esa sustancia tan rígida."; } Cut: ! Si no hay aire fuera, no se deja: if (self.comprobar_aire()) { rtrue; } ! Si intentas cortar con algo que no sea el cortador if (self has locked && second ~= bisturi) { "Necesitarás algún objeto cortante para poder cortar esa sustancia tan rígida."; } <>; Receive: ! Intentas meter algo en la vaina "No, no lo hagas."; LetGo: ! Intentas sacar algo de la vaina. Si está cerrada, se dice, y retorna true. ! Si está abierta, se retorna false, y se permite. self.dejar_salir(); Unlock: ! Si no hay aire fuera, no se deja: if (self.comprobar_aire()) { rtrue; } ! Se intenta abrir la vaina con algo if (self has locked && second ~= bisturi) { "Necesitarás algún objeto cortante para poder abrir esa sustancia tan rígida."; } if (self hasnt locked) { "La vaina ya está suficientemente abierta."; } Close: ! Se intenta cerrar la vaina "Imposible, e ilógico."; ], comprobar_aire [; ! Se intenta abrir la vaina antes de arreglar el procesador atmosférico if (circuito hasnt general) { "No deberías intentar sacar a Jason de esa vaina antes de disponer de aire respirable. Su traje parece roto desde aquí, y probablemente esté vivo gracias a que el aire del traje no ha podido escapar a través de esa vaina herméticamente sellada. Debes conseguir que Jason tenga aire respirable fuera de esa vaina antes de sacarlo."; } else { rfalse; } ], ! Esta rutina se llama desde vaina.antes y desde jason.antes dejar_salir [; if (self hasnt open) { "La vaina es demasiado dura para poder sacarlo."; } ], aparecer [; give self ~scenery; give self static; ], after [; Examine: self.aparecer(); Unlock: Damusix.TocarV(Bisturi_ogg); print "Desgarras cuidadosamente la vaina usando el bisturí, procurando no dañar a Jason. Cuando terminas, la vaina presenta un amplio corte longitudinal. Justo a tiempo, ya que el bisturí ha dejado de funcionar por agotamiento de su energía interna.^"; keep_silent = 1; ! Para que no diga que abres la vaina a continuación ; ! Abres la vaina (pero el intérprete no dice nada) keep_silent = 0; ! Vuelves a la situación normal rtrue; ], has scenery female container lockable locked openable; ! ==================================================================== ! ! PERSONAJES ! ! ==================================================================== Object jason "Jason" nave1 class Movil with name 'jason' 'mayor' 'soldado' 'marine' 'companero', description [; if (self in vaina) { print "A través de la vaina semi-transparente puedes ver que tiene los ojos cerrados, y que no parece muy consciente de tu presencia. Realmente tiene mal aspecto. Su traje tiene un corte bastante grande en un costado"; if (vaina hasnt open) { " y, por lo que puedes intuir, el oxígeno de su traje llena ahora por completo la vaina."; } else { "."; } } if (self.sacado()) { ! Lo hemos sacado de la vaina: print "No tiene muy buen aspecto, aunque se esfuerza en aparentar lo contrario. "; } else { print "Jason, tu compañero. Es bastante más grande y corpulento que tú, y su mirada refleja sarcasmo y frialdad a partes iguales. Es, en definitiva, todo un ejemplo de duro y capacitado soldado, siempre dispuesto para el combate. "; } if (children(self) ~= 0) { print "Lleva "; WriteListFrom(child(self), FULLINV_BIT + ENGLISH_BIT + RECURSE_BIT); "."; } else { ""; } ], initial "^Jason, tu compañero de expedición, está junto a ti aguardando tus órdenes.", decir true, ! Propiedad que indica si ya hemos sacado a Jason de la vaina: sacado [; return procesador.arreglado() && jason notin vaina; ], describe [; ! La propiedad general sirve para saber si es la primera vez que se describe if (self hasnt general) { give self general; PrintOrRun(self, initial); rtrue; } else { print "^"; if (~~(self.sacado())) { switch (random(6)) { 1: "Jason se encuentra a tu lado."; 2: "Jason te mira expectante."; 3: "Jason mira alrededor con atención."; 4: "Jason, tu compañero, está a tu lado esperando órdenes."; 5: "Jason te mira de reojo con cierto recelo."; 6: "Junto a ti se encuentra Jason, el marine."; } } else { switch (random(3)) { 1: "Jason camina con cierta lentitud."; 2: print "Jason se encuentra a tu lado, respirando con cierta dificultad."; if (~~EsExterior(parent(self))) { " De vez en cuando, se apoya en una pared."; } else { ""; } 3: "Jason te mira con cara de estar pasándolo realmente mal."; } } } ], grammar [ s1 s2 a o f; a = NULL; switch (verb_word) { 'coge', 'toma', 'recoge': a = ##Take; 'saca': a = ##Remove; 'deja', 'suelta': a = ##Drop; 'ponte': a = ##Wear; 'quitate', 'sacate': a = ##Disrobe; 'da': a = ##Give; 'dispara': a = ##Disparar; 'enciende', 'activa': a = ##SwitchOn; 'apaga', 'desactiva': a = ##SwitchOff; 'pulsa', 'empuja': a = ##Push; 'entra': a = ##Enter; 'metete': a = ##GoIn; 'sal': a = ##Exit; 'salte': a = ##GetOff; 'no', 'nx': if (NextWord() == 'te' && NextWord() == 'muevas' or 'vayas') { action = ##Quedar; rtrue; } default: rfalse; } s1 = NextWord(); f = 0; ! Si se dice: "JASON, COGE TRAJE" sin especificar cuál, se da prioridad ! al de Jason (si lo ve; si no, le da prioridad al que ve): if (s1 == 'traje') { if (TestScope(traje_jason, jason)) { noun = traje_jason; } else { noun = tu_traje; } action = a; rtrue; } if (s1 == '-me') { f = 1; s1 = NextWord(); } s2 = NextWord(); if (s2 == 'traje') { verb_wordnum++; switch(s1) { 'tu': o = traje_jason; 'mi': o = tu_traje; 'el': if (TestScope(traje_jason, jason)) { o = traje_jason; } else { o = tu_traje; } default: switch (a) { ##Take: return -'coge'; ##Remove: return -'saca'; ##Drop: return -'deja'; ##Wear: return -'ponte'; ##Disrobe: return -'quitate'; ##Give: return -'da'; ##Disparar: return -'dispara'; ##SwitchOn: return -'enciende'; ##SwitchOff: return -'apaga'; ##Push: return -'empuja'; ##Enter: return -'entra'; ##GoIn: return -'metete'; ##Exit: return -'sal'; ##GetOff: return -'salte'; NULL: rfalse; } } action = a; if (f == 1) { noun = o; second = selfobj; } else { noun = o; } rtrue; } else { rfalse; } ], comprobar_inconsciencia [; ! Si está en la vaina, permanece en semi-inconsciencia: if (self in vaina) { "Sólo oyes un débil sonido de respiración..."; } rfalse; ], before [; Quitarle: ! Si queremos quitarle un objeto a Jason que él tiene: if (jason in vaina) { if (second == traje_jason) { if (vaina has open) { "Mejor espera a sacar a Jason de la vaina."; } else { "No, mejor no quitarle el traje hasta estar seguro de que puede respirar sin él."; } } else { "Jason no está en condiciones de que le quites nada."; } } else { if (IndirectlyContains(jason, second)) { HablaJason("Mejor pídamelo a mí, señor. Por educación, sobre todo..."); rtrue; } else { "Jason no tiene eso. No se lo puedes quitar."; } } Take: if (self in vaina) { <>; } Remove: ! Si no especificas, se entiende que quieres sacarlo de la vaina: if (second == nothing && LugarReal() == hueco_techo) { second = vaina; } ! A Jason sólo se le puede sacar de la vaina: if (second ~= vaina) { "¿De dónde? Pero si Jason no está ahí..."; } if (jason notin vaina) { "No hay que sacar a Jason de ningún sitio."; } if (vaina hasnt general) { "¿Dónde se supone que está Jason para sacarlo?"; } ! Sacar a Jason de la vaina: if (vaina hasnt open) { ! Si la vaina no está abierta vaina.dejar_salir(); ! te dice que está demasiado dura rtrue; ! y sale. } else { ! Si la vaina está abierta: move jason to hueco_techo; ! lo sacas PNJ_Ruta(jason, MOVIMIENTO_PERSEGUIR, player); remove traje_jason; give traje_jason absent; move traje_inutil to hueco_techo; max_longitud_camino = 30; alien.pnj_ha_llegado = alien.pnj_ha_llegado_puerta; sacador_de_aliens.meter_alien(); PNJ_Ruta(alien, MOVIMIENTO_POR_META, entrada, CAMINO_SIN_PUERTAS); alien.comportamiento = 2; self.decir = false; StartTimer(self, 7); print "Sacas a Jason de la vaina. Parece inconsciente, y su dañado traje ha perdido prácticamente toda su reserva de oxígeno. Inmediatamente le retiras su casco y el resto del traje atmosférico, y tras unos instantes de aturdimiento, se despierta algo mareado.^"; HablaJason("Me duele la garganta... Pero estoy bien... me recuperaré... Gracias por venir a rescatarme..."); if (detector_movimiento hasnt on) { give detector_movimiento on; print "^Inmediatamente a continuación, echa un vistazo a su rifle y exclama:^"; HablaJason("¿Ha llegado hasta aquí con el detector de movimiento desactivado? Dios santo...¡Activelo!"); "^No es necesario pensar mucho para ver que tiene razón, así que le haces caso."; } rtrue; } Attack, Disparar: if (action == ##Disparar && rifle notin player) { rfalse; } if (self.comprobar_inconsciencia()) { rtrue; } HablaJason("Conozco ciento cincuenta formas de matar a un hombre. Sólo necesito la mitad de una de ellas para acabar con usted."); rtrue; Push, PushDir, Pull: if (self in vaina) { if (vaina has open) { <>; } else { vaina.dejar_salir(); rtrue; } } HablaJason("No vuelva a hacerlo. En serio. No lo haga."); rtrue; Touch: if (self.comprobar_inconsciencia()) { rtrue; } HablaJason("Yo que usted no lo haría..."); rtrue; ], ! precamino RUTA_NINGUNA, ! En realidad no sé si hace falta tras_abrir NO_PUEDE_ABRIR, ! Comportamiento después de pasar por una puerta life [ tema; if (self.comprobar_inconsciencia()) { rtrue; } Ask: self.decir = false; tema = AveriguarTema(TemasJason); switch (tema) { tema_jason_donde_estas: if (parent(self) == LugarReal()) { HablaJason("Con usted, amigo... Qué remedio..."); } else if (EsExterior(parent(self))) { HablaJason("Bajo una lluvia de mil demonios."); } else if (parent(self) == nave1 or nave2) { HablaJason("En la nave."); } else { switch(random(2)) { 1: HablaJason("No tengo ni idea, pero le aseguro que no es un lugar agradable."); 2: HablaJason("En cualquier sitio menos donde quisiera estar."); } } tema_jason_alien: if (alien.primera_vez) { HablaJason("¿A qué se refiere? No sé de qué me está hablando..."); } else { HablaJason("Me desmayé casi inmediatamente, nada más sentir el tacto de ese bicho monstruoso... Pero no dejo de recordar que le vacié el cargador entero de mi rifle, y aún así siguió avanzando... No sé mucho más que usted. Pero sí sé que es el hijo de puta más peligroso que he visto en mi vida."); } tema_jason_colonia: HablaJason("Los colonos deben vivir en condiciones infrahumanas para satisfacer las ~necesidades~ de la Compañía. Dígame usted si estar encerrado aquí es ~vivir~..."); tema_jason_comunicador: HablaJason("Me permite no perder el contacto con usted... pero que eso sea o no una ventaja, aún no lo tengo muy claro."); tema_jason_detector: HablaJason("Es un detector de movimiento, y sirve para saber si tenemos compañía."); tema_jason_gente: HablaJason("No hay nadie... Nadie... Por ninguna parte... ¿Cómo es posible?"); tema_jason_jason: HablaJason("Prefiero no hablar mucho de mí. Cuando intimas con alguien, luego es más duro saber que ha muerto."); tema_jason_madre: HablaJason("Tanta inteligencia artificial y tantos buenos modales me pone de los nervios."); tema_jason_mision: HablaJason("Tan sólo me limito a obedecer ordenes. Pero si quiere saber mi opinión, hoy me he puesto mis calzoncillos de la suerte."); tema_jason_planeta: HablaJason("No es donde vendría a pasar mis vacaciones, desde luego..."); tema_jason_rifle: if (rifle in jason) { HablaJason("Ésta es sin duda mi mejor amiga... ¡Jajajaja...!"); } else { HablaJason("Ya no la quiero... No me ha servido de nada..."); } tema_jason_robot: if (panel_control.codigo_viejo == 0) { HablaJason("Nunca me han gustado esos aparatos andantes. No son de fiar. Nadie lo es... Especialmente ellos."); } else { HablaJason("Para lo único que ha servido hasta ahora es para darnos un código falso."); } tema_jason_vaina: if (jason.sacado()) { HablaJason("No quiero hablar de ello... Estar allí dentro ha sido la experiencia más desagradable de mi vida... Estaba como ido, pero a veces me daba cuenta de dónde me encontraba... allí metido, sin poder moverme, casi sin recordar quién era ni qué hacía allí... Y esa oscuridad..."); } else { HablaJason("¿De qué demonios me está hablando?"); } default: HablaJason("No entiendo qué quiere decirme."); } rtrue; Give: if (noun in player) { move noun to self; print "Le das ", (the) noun, " a Jason.^"; HablaJason("Muy amable..."); rtrue; } default: switch (random(2)) { 1: HablaJason("No entiendo qué quiere decirme."); 2: HablaJason("¿Perdone?"); } rtrue; ], intentar_coger [ o; if (o == 0) { o = noun; } if (~~(PuedeVer(self, o))) { HablaJason("No puedo ver eso que dice."); rfalse; } if (~~(PNJCoger(self, o))) { switch (RazonErrorPNJ) { PNJ_INTENTA_COGERSE_A_SI_MISMO: HablaJason("Yo ya me tengo a mí mismo, gracias..."); PNJ_OBJETO_NO_PRESENTE: HablaJason("No puedo ver ", o, " por aquí."); PNJ_EN_RECIPIENTE_CERRADO: HablaJason("Puedo ver ", o, "pero no puedo cogerl", o, " porque estoy aquí metido."); PNJ_INTENTA_COGER_AL_JUGADOR: HablaJason("No es usted mi tipo..."); PNJ_INTENTA_COGER_CRIATURA: if (noun in player) { move noun to self; print "Le das ", (the) o, " a Jason.^"; HablaJason("Muy amable..."); } PNJ_OBJETO_ESCENARIO_O_ESTATICO: HablaJason("No puedo coger eso."); PNJ_INTENTA_COGER_SUBOBJETO: print "Jason intenta coger ", (the) o, " pero no puede porque forma parte", (del) parent(o), "."; PNJ_OBJETO_INACCESIBLE: HablaJason("No puedo coger ", o, ". No está a mi alcance."); PNJ_OBJETO_EN_RECIPIENTE_CERRADO: HablaJason("No puedo coger ", o, ". Está metido dentro ", 0, 0, parent(o), "."); } rfalse; } rtrue; ], ! antesPNJ [; ! Ir: ! HablaJason("¡No quiero moverme, jo!"); ! rtrue; ! Coger: ! HablaJason("¡No quiero coger nada, jo!"); ! rtrue; ! ], orden_entrar [; if (self in exterior1) { if (puerta_nave has open) { move self to nave1; puerta_nave.cerrar(); if (player in nave1 or nave2) { PNJ_Ruta(jason, MOVIMIENTO_PERSEGUIR, player); } else { PNJ_Ruta(self, MOVIMIENTO_NINGUNO); } "Jason entra en la nave. A continuación, Madre cierra la compuerta exterior."; } else { HablaJason("La compuerta de la nave está cerrada."); rfalse; } } self.orden_ir(in_obj); rtrue; ], orden_salir [; if (self in nave1 or nave2) { if (puerta_nave hasnt open) { HablaJason("La compuerta de la nave está cerrada."); rfalse; } if (~~(procesador.arreglado())) { if (traje_jason notin jason) { if (PuedeVer(jason, traje_jason)) { if (traje_jason in player) { HablaJason("De acuerdo, pero antes deme mi traje."); print "^Le das a Jason su traje y, a continuación, se lo pone.^^"; move traje_jason to jason; give traje_jason worn; } else { HablaJason("De acuerdo, pero antes cogeré el traje atmosférico."); if (~~(self.intentar_coger(traje_jason))) { rfalse; } give traje_jason worn; print "^"; } } else { HablaJason("No puedo salir de la nave. No llevo puesto mi traje, y no lo veo por aquí."); rfalse; } } else { if (traje_jason hasnt worn) { give traje_jason worn; HablaJason("De acuerdo, pero antes me pondré el traje atmosférico."); print "^"; } } } move self to exterior1; puerta_nave.cerrar(); PNJ_Ruta(self, MOVIMIENTO_NINGUNO); "Jason sale al exterior protegido por su traje espacial. A continuación, Madre cierra la compuerta de la nave."; } self.orden_ir(out_obj); rtrue; ], orden_ir [ d; if (~~(PNJIr(self, d))) { switch (RazonErrorPNJ) { PNJ_SIN_SALIDA: HablaJason("No puedo ir por ahí."); PNJ_PUERTA_CERRADA: HablaJason("La puerta está cerrada."); PNJ_PUERTA_BLOQUEADA: HablaJason("No puedo pasar por la puerta."); } } else { HablaJason("Ya estoy."); if (self.tipo_de_movimiento == MOVIMIENTO_PERSEGUIR) { if (self.perseguido == player) { PNJ_Ruta(self, MOVIMIENTO_NINGUNO); HablaJason("A partir de ahora dejaré de seguirle."); } else { HablaJason("Ahora mismo estoy siguiendo a ", self.perseguido, "."); rtrue; } } } rtrue; ], orders [ tmp; if (self.comprobar_inconsciencia()) { rtrue; } self.decir = false; Yes: HablaJason("¿Sí qué?"); rtrue; No: HablaJason("Supongo que los jefes están para decir que no..."); rtrue; Go: if (noun == in_obj) { self.orden_entrar(); rtrue; } if (noun == out_obj) { self.orden_salir(); rtrue; } if (self.tipo_de_movimiento == MOVIMIENTO_PERSEGUIR && self.perseguido ~= player) { HablaJason("Ahora mismo estoy siguiendo a ", self.perseguido, "."); rtrue; } if (alien.comportamiento == 3 || (alien.comportamiento == 1 && alien.tipo_de_movimiento == MOVIMIENTO_PERSEGUIR && alien.perseguido == player)) { if (jason in LugarReal()) { HablaJason("¡Ahora no es un buen momento! ¡Ese bicho nos acecha!"); } else { HablaJason("¿Para que me persiga a mí también? ¡Ni hablar!"); } rtrue; } self.orden_ir(noun); rtrue; Enter, GoIn: if (noun == montacargas && self in balcon4 or balcon12) { if (parent(jason) ~= LugarReal()) { HablaJason("Será mejor que lo hagamos juntos."); rtrue; } else { <>; } } self.orden_entrar(); rtrue; Exit, GetOff: self.orden_salir(); rtrue; Subir: if (montacargas in parent(self)) { if (parent(jason) ~= LugarReal()) { HablaJason("Será mejor que lo hagamos juntos."); rtrue; } else { <>; } } self.orden_ir(u_obj); rtrue; Bajar: if (montacargas in parent(self)) { if (parent(jason) ~= LugarReal()) { HablaJason("Será mejor que lo hagamos juntos."); rtrue; } else { <>; } } self.orden_ir(d_obj); rtrue; Strong, Mild: print "Jason te mira con cara de pocos amigos, y más que decir, escupe:^"; HablaJason("Está jugando con fuego..."); rtrue; Take, Remove: if (noun in self) { HablaJason("Ya tenía ", noun, "."); rtrue; } if (noun == comunicador) { "Mejor no. Si le das el comunicador, perderías el contacto con él y con la nave."; } self.intentar_coger(); rtrue; Drop: if (noun == rifle && noun in self) { HablaJason("Ni hablar. No pienso despegarme de mi arma."); rtrue; } else if (noun == detector_movimiento && rifle in self) { HablaJason("Para eso tendría que dejar mi rifle, y no pienso hacerlo."); rtrue; } else if (noun notin self) { HablaJason("No llevo eso encima."); rtrue; } PNJDejar(self, noun); rtrue; Wear: if (~~(noun ofclass TrajeAtmosferico)) { HablaJason("No puedo ponerme eso."); rtrue; } if (noun ~= traje_jason) { HablaJason("Lo siento; no es de mi talla."); rtrue; } if (noun notin self) { if (~~(PuedeVer(noun, self))) { HablaJason("No veo mi traje por aquí."); rtrue; } if (noun in player) { print "(Primero se lo das)^"; move noun to jason; } else { print "(Primero intenta cogerlo)^"; self.no_mostrar_despues = true; tmp = self.intentar_coger(); self.no_mostrar_despues = false; if (~~tmp) { rtrue; } } } else { if (noun has worn) { "Jason ya lleva puesto su traje."; } } give noun worn; HablaJason("Ya está. Me he puesto ", noun, "."); rtrue; Disrobe: if (noun in self && noun has worn) { if (noun == traje_jason or tu_traje && jason notin nave1 or nave2 && circuito hasnt general) { HablaJason("No quiero morir envenenado, señor..."); rtrue; } give noun ~worn; HablaJason("Ya está. Me he quitado ", noun, "."); rtrue; } else { HablaJason("No puedo quitarme eso. No lo llevo puesto."); rtrue; } Give: if (noun == nothing) { HablaJason("No entiendo qué quiere que le dé."); rtrue; } if (noun == rifle && noun in self) { HablaJason("Ni hablar. No pienso despegarme de mi arma."); rtrue; } else if (noun == detector_movimiento && rifle in self) { HablaJason("Para eso tendría que darle mi rifle, y no pienso hacerlo."); rtrue; } ! Si le pides que te dé algo, te lo da if (noun in self) { if (noun has worn) { give noun ~worn; ! Se lo quita, por si acaso lo tenía puesto } move noun to player; if (noun == tu_traje) { HablaJason("Tome, aquí tiene su traje."); } else { HablaJason("Tome, aquí tiene ", noun, "."); } rtrue; } else { HablaJason("No tengo eso."); rtrue; } SwitchOn: if (noun in self || (noun == detector_movimiento && parent(noun) in self)) { if (noun hasnt on) { if (noun == linterna) { linterna.encender(); } else { give noun on; } HablaJason("Ya está. He encendido ", noun, "."); rtrue; } else { HablaJason("Me temo que ", noun, " ya está encendid", noun, "."); rtrue; } } else { HablaJason("No llevo ", noun, " encima para poder encenderl", noun, "."); rtrue; } SwitchOff: if (noun in self || (noun == detector_movimiento && parent(noun) in self)) { if (noun has on) { give noun ~on; HablaJason("Ya está. He apagado ", noun, "."); rtrue; } else { HablaJason("Me temo que ", noun, " ya está apagado."); rtrue; } } else { HablaJason("No llevo ", noun, " encima para poder apagarlo."); rtrue; } Inv: ! Si le pides inventario de lo que lleva encima if (children(self) == 0) { HablaJason("No llevo nada encima."); rtrue; } else { print (s_b) "^JASON: ", "~Llevo "; WriteListFrom(child(self), FULLINV_BIT + ENGLISH_BIT + RECURSE_BIT); "~."; } Venir, Seguir, VagueGo: if (noun == nothing) { noun = player; } if (noun ~= player) { HablaJason("No entiendo a quién quiere que siga."); rtrue; } if (player in nave1 or nave2 && self in exterior1 && puerta_nave hasnt open) { HablaJason("La compuerta de la nave está cerrada."); rtrue; } if (self.tipo_de_movimiento == MOVIMIENTO_PERSEGUIR && self.perseguido == player) { if (nave2 hasnt visited && exterior1 hasnt visited) { ! Si no nos hemos movido de la primera localidad, Jason ! dice otra cosa: HablaJason("Voy pisándole los talones."); } else { switch (random(2)) { 1: HablaJason("¡Pero si voy detrás suya todo el rato!"); 2: HablaJason("Voy pisándole los talones."); } } rtrue; } if (jason in nave1 or nave2 && LugarReal() ~= nave1 && LugarReal() ~= nave2) { ! print "^"; if (~~(self.orden_salir())) { rtrue; } } HablaJason("De acuerdo. Le seguiré."); PNJ_Ruta(jason, MOVIMIENTO_PERSEGUIR, player); rtrue; Quedar, Wait: if (alien.comportamiento == 4 || alien.comportamiento == 3 && (puerta_emergencia has open || (puerta_emergencia hasnt open && (parent(jason) ofclass ZonaEmergencia && parent(alien) ofclass ZonaEmergencia) || (~~(parent(jason) ofclass ZonaEmergencia) && (~~(parent(alien) ofclass ZonaEmergencia)))))) { HablaJason("¡No pienso quedarme quieto con esa cosa acechando!"); rtrue; } if (self.tipo_de_movimiento == MOVIMIENTO_NINGUNO) { HablaJason("Ya estoy más quieto que un muerto."); } else { PNJ_Ruta(jason, MOVIMIENTO_NINGUNO); HablaJason("De acuerdo. Me quedaré aquí."); } rtrue; Callar: HablaJason("Hablar me ayuda a mantenerme alerta."); rtrue; Saludar: HablaJason("Será mejor no perder el tiempo en protocolos y centrarse en la misión."); rtrue; Disparar, Dispararte, Dispararme: if (rifle in self) { if (noun == player || action == ##Dispararme) { HablaJason("¿Tan pronto quiere dejar este mundo, señor?"); PreguntaSiNo = 1; rtrue; } else if (noun == jason || action == ##Dispararte) { HablaJason("Esa no es la solución... todavía."); rtrue; } else if (jason in nave1 or nave2) { HablaJason("Disparar dentro de la nave puede resultar muy peligroso, señor."); rtrue; } else { HablaJason("Será mejor que no desperdiciemos la munición."); rtrue; } } else { HablaJason("¡No tengo nada con lo que disparar!"); rtrue; } SwitchOn: if (noun == detector_movimiento) { if (rifle in jason) { if (detector_movimiento hasnt on) { give detector_movimiento on; HablaJason("Ya está. He activado el detector de movimiento."); rtrue; } else { HablaJason("Ya llevo encendido el detector de movimiento."); rtrue; } } else { HablaJason("No puedo activarlo, porque no llevo mi rifle encima."); rtrue; } } else { HablaJason("Mejor enciéndalo usted. Usted es el cerebrito, ¿no?"); rtrue; } SwitchOff: if (noun == detector_movimiento) { if (rifle in jason) { if (detector_movimiento has on) { give detector_movimiento ~on; HablaJason("Ya está. He desactivado el detector de movimiento."); rtrue; } else { HablaJason("Ya llevo desactivado el detector de movimiento."); rtrue; } } else { HablaJason("No puedo desactivarlo, porque no llevo mi rifle encima."); rtrue; } } else { HablaJason("Yo no sé hacerlo. Hágalo usted mismo."); rtrue; } Push: if (noun == boton_este or boton_oeste && TestScope(noun, self)) { if (LugarReal() ~= parent(noun)) { if (puerta_emergencia has open) { HablaJason("Lo he pulsado, pero parece que no hace nada..."); rtrue; } else { noun.pulsar(); rtrue; } } else { HablaJason("¿Por qué no lo hace usted mismo, ya que está aquí?"); rtrue; } } else { HablaJason("¿Para qué se supone que tengo que hacer eso?"); rtrue; } Ayudar: if (alien.comportamiento == 0) { ! Estamos en la primera parte del juego if (LugarReal() == nave1 or nave2) { HablaJason("Deberíamos salir de la nave."); } else { HablaJason("Tenemos que entrar en el complejo de la colonia minera."); } } else { ! El alien ya se ha llevado a Jason y Has sacado a Jason de la vaina if (entrada hasnt general) { ! Aún no sabes que la puerta está sellada HablaJason("Tenemos que salir de aquí cagando leches."); } else { ! Sabes que la puerta está sellada HablaJason("Tenemos que buscar otra salida."); } } rtrue; NotUnderstood, Tell: <>; ! accion = ##Preguntar; ! rfalse; default: HablaJason("Mejor hágalo usted mismo..."); rtrue; ], no_mostrar_despues false, despuesPNJ [; if (self.comprobar_inconsciencia()) rtrue; Take: if (~~(self.no_mostrar_despues)) { if (noun == tu_traje) { HablaJason("Ya está. He recogido su traje."); } else { HablaJason("Ya está. He recogido ", noun, "."); } } rtrue; Drop: if (noun == tu_traje) { HablaJason("Ya está. He dejado su traje."); } else { HablaJason("Ya está. He dejado ", noun, "."); } rtrue; ], each_turn [; if (deadflag ~= 0) { rtrue; } if (~~(self.decir)) { self.decir = true; rtrue; } ! El alien va corriendo hacia nosotros: if ((alien.comportamiento == 3 && ~~(puerta_emergencia hasnt open && LugarReal() ofclass ZonaEmergencia && parent(jason) ofclass ZonaEmergencia)) || (alien.comportamiento == 1 && alien.tipo_de_movimiento == MOVIMIENTO_PERSEGUIR && alien.perseguido == player && jason in LugarReal())) { if (random(100) < 50) { switch (random(3)) { 1: if (alien notin LugarReal()) { HablaJason("¡Se está acercando! ¡Se está acercando!"); } else { HablaJason("¡Está aquí! ¡Está aquí! ¡Huyamos!"); } 2: HablaJason("¡Corra, Dios mío! ¡Viene a por nosotros!"); 3: HablaJason("¡Huyamos!"); } } rtrue; } if (alien.comportamiento == 4) { if (random(100) < 60) { switch (random(3)) { 1: if (EsExterior(LugarReal())) { HablaJason("¡Vamos a la nave, deprisa!"); } else { HablaJason("¡Vamos a la salida de emergencia!"); } 2: HablaJason("¡Rápido, salgamos de aquí!"); 3: HablaJason("¡Vámonos!"); } } rtrue; } ! Situaciones "normales": if (alien.comportamiento == 0 or 1 or 2) { if (self notin vaina) { if (random(100) < 20) { if (self in LugarReal()) { if (~~(self.sacado())) { if (SeVen(robot, jason)) { switch (random(3)) { 1: HablaJason("Me parece que este robot no anda muy bien de la sesera."); rtrue; 2: HablaJason("A este robot le falta un tornillo, y nunca mejor dicho."); rtrue; 3: switch (random(2)) { 1: print "^Jason da una sonora patada al cuerpo del robot y dice:^"; 2: print "^Jason mira con evidente antipatía al robot y dice:^"; } if (robot.ha_hablado) { HablaJason("¡Este trasto de lata está como una cabra! ¡Sólo dice tonterías sin sentido!"); } else { HablaRobot("Menudo montón de chatarra..."); } rtrue; } } switch (random(15)) { 1: HablaJason("¡Estoy deseando entrar en acción!"); 2: HablaJason("Este lugar me da escalofríos..."); 3: HablaJason("En el espacio sólo puedes fiarte de ti mismo."); 4: switch (random(2)) { 1: if (traje_jason in jason && traje_jason has worn) { HablaJason("Todo esto es muy extraño... Muy, muy extraño..."); } else { print "^Con una rapidez inusitada, Jason produce un gorgojeante sonido en su boca y garganta, y dispara un enorme escupitajo al suelo.^"; switch (random(2)) { 1: HablaJason("¿Por qué me mira de ese modo? ¿Me va a regañar?"); PreguntaSiNo = 1; 2: HablaJason("Tengo mucha saliva, ¿vale?"); PreguntaSiNo = 1; } } 2: HablaJason("No le podrá la tensión, ¿verdad, señor?"); PreguntaSiNo = 1; } 5: if (EsExterior(LugarReal())) { HablaJason("Aquí sólo hay barro y desolación... ¿Qué coño hacemos en este lugar?"); } else { HablaJason("¿Qué hacemos aquí todavía? ¡La acción está ahí fuera!"); } 6: switch (random(2)) { 1: print "^Jason acaricia su arma con una expresión casi obscena.^"; 2: print "^Jason sopesa su arma y apunta con ella al azar.^"; } switch (random(2)) { 1: HablaJason("Hay que cuidarla, ¿sabe? Y así ella también cuidará de uno."); 2: HablaJason("No encontrará un aliado mejor en momentos como este."); } 7: HablaJason("Acabemos de una vez con esto y larguémonos de aquí."); 8: if (jason notin nave1 && jason notin nave2) { print "^Jason se lleva la mano al oído y dice:^"; } HablaJason("¿Sabes, nena? Tienes una voz muy dulce... No tendrás por casualidad una hermana soltera, ¿verdad?"); HablaMadre("Mi pariente más cercano es un procesador de cámaras frigoríficas. No creo que sea su tipo, Mayor."); "^Jason se echa a reir a carcajadas."; 9: if (LugarReal() == nave1 or nave2) { print "^Jason toca una pared de la nave y, dirigiendo la mirada a ningún sitio en particular, dice:^"; HablaJason("Madre: ¿nunca sientes necesidad de...? Venga, ya sabes..."); HablaMadre("No, lo lamento."); "^Jason se encoge de hombros."; } else { print "^Jason se lleva la mano al oído y dice:^"; HablaJason("Sigues ahí, ¿verdad, Madre? No te vayas sin nosotros, ¿eh?"); HablaMadre("No se preocupe, Mayor. Mis directrices me lo impiden por más que lo deseara."); "^Se ve que se llevan maravillosamente."; } 10: HablaJason("Me encanta este clima."); 11: HablaJason("Señor, deme una alegría y dígame que hay un bar por aquí cerca..."); PreguntaSiNo = 1; 12: HablaJason("Me pregunto cuántas mujeres viven en este complejo..."); HablaMadre("12 mujeres censadas, Mayor."); HablaJason("Ya lo sabía, G-R-A-C-I-A-S."); 13: HablaJason("Esto no me gusta nada. NADA."); 14: print "^Jason se acerca y te susurra:^"; HablaJason("Hágame un favor: apague a esa entrometida en cuanto todo esto acabe."); HablaMadre("No tengo un enchufe del que pueda tirar, Mayor."); HablaJason("Mierda, me ha oído..."); 15: HablaJason("Cuanto antes nos vayamos, más tiempo viviremos."); } } else { ! Ya lo hemos sacado de la vaina: switch (random(4)) { 1: HablaJason("No me encuentro muy bien..."); 2: HablaJason("Vámonos ya de aquí, por favor..."); 3: HablaJason("Por favor, ayúdeme a llegar a la nave..."); 4: HablaJason("Santo Cielo... ¿A qué nos enfrentamos?"); } } } else { ! Jason no está contigo: switch (random(5)) { 1: HablaJason("¡No me deje aquí!"); 2: HablaJason("¿Qué hago yo mientras tanto?"); 3: HablaJason("¿Qué se supone que tengo que hacer aquí?"); 4: HablaJason("¿Por qué me deja aquí?"); 5: HablaJason("¿Hola? ¿Está ahí?"); PreguntaSiNo = 1; } } } } else { ! Jason está dentro de la vaina, y habla poco y menos: if (random(100) < 10) { switch (random(4)) { 1: HablaJason("Aaaaaaahhhh..."); 2: HablaJason("Ayúdemeeeeeeee...."); 3: HablaJason("(lamento ahogado)"); 4: HablaJason("(respiración entrecortada)"); } if (~~(self.habla_en_vaina)) { self.habla_en_vaina = true; print (s_b) "^¡ES JASON! ¡ESTÁ VIVO!^"; rtrue; } } } } ], habla_en_vaina false, time_left, time_out [ o p sig; p = parent(self); ! Se le cae todo antes de quedar inconsciente: o = child(self); while (o ~= nothing) { sig = sibling(o); move o to p; o = sig; } remove self; give self absent; move jason_inerte to p; if (p == LugarReal()) { "^De repente, ves que Jason cae al suelo inconsciente. Rápidamente, te agachas a ver cómo se encuentra... y le notas pulso. Al menos está vivo, pero por mucho que lo zarandeas, no hay manera de despertarlo. Tendrás que buscar algo que te ayude a sacarlo de su estado de inconsciencia."; } else { "^Oyes por el comunicador que algo grande cae al suelo con un golpe seco."; } ], has animate proper transparent; ! Hay que comprobar si funciona bien sin el transparente Object jason_inerte "Jason" with name 'jason' 'mayor', description "Está inconsciente en el suelo.", describe "^Jason yace en el suelo, inconsciente.", before [; Tell, Answer, Decir, Ask, Saludar: "No va a responderte. Está inconsciente."; Take, Push, Pull: "Imposible. Pesa demasiado."; WakeOther: "No reacciona."; default: "Está inconsciente. Tienes que intentar reanimarlo."; ], has animate proper; Object computadora "Madre" with name_f 'madre' 'computadora', name_m 'computador' 'ordenador', adjectives 'nave', description [; print "Madre es la computadora de la nave. Es lo último y más sofisticado en inteligencia artificial, aunque Jason prefiere el término ~estupidez artificial~. Gobierna el funcionamiento interno de todos los sistemas como lo haría el cerebro de un gigantesco organismo. "; if (LugarReal() == nave1 or nave2) { "No se encuentra en un lugar específico; en realidad, puedes sentir su presencia en todas las estancias del vehículo."; } else { "Se encuentra en la nave... o mejor dicho, ES la nave."; } ], ! esta_en nave1 nave2, found_in [; rtrue; ], ! Está en todas partes gender G_FEMENINO, decir true, grammar [; return -'madre,'; ], before [; ! Esto es para que no diga: "Madre está apagada." cuando la examinamos: Examine: PrintOrRun(self, description); rtrue; Listen: self.mensaje_aleatorio(); rtrue; SwitchOn: "Madre ya está encendida."; SwitchOff: "No hay forma de desactivar a Madre, y si la hubiera, no querrías hacerlo."; Take, Drop, Push, PushDir, Pull, Touch, Taste, Smell: "Madre es una inteligencia artificial incorpórea. ¿Sabes lo que es eso?"; ], ! codigo_nuevo == 0: indica que Madre todavía no ha calculado el nuevo código ! codigo_nuevo == 1: sí lo ha calculado codigo_nuevo 0, life [ tema; Ask: self.decir = false; tema = AveriguarTema(TemasComputadora); switch (tema) { tema_madre_alien: if (procesador.arreglado()) { HablaMadre("No puedo darle información. No tenía constancia de la existencia de un ser de esas características."); } else { HablaMadre("No sé a qué clase de criatura se refiere, señor."); } tema_madre_arreglar: if (procesador.arreglado()) { HablaMadre("El procesador atmosférico ya está completamente arreglado."); } else { HablaMadre("Detectado un fallo en uno de los circuitos principales del procesador atmosférico. Probabilidad de conexión rota por sobrecalentamiento: 97%. Su reparación requiere soldar el circuito."); } tema_madre_ascensor: HablaMadre("El ascensor de emergencia se encuentra situado en el nivel -2 del complejo. Sólo se abre de forma automática en caso de activarse el protocolo de emergencia."); tema_madre_atmosfera: if (circuito hasnt general) { HablaMadre("La atmósfera natural del planeta es irrespirable, debido a una alta concentración de dióxido de azufre en suspensión. Se requiere la transformación artificial del aire por medio de un procesador atmosférico."); } else { HablaMadre("La atmósfera del planeta está siendo transformada artificialmente por el procesador atmosférico para hacerla respirable. Es posible salir al exterior sin equipo de protección."); } tema_madre_ayuda: HablaMadre("Simplemente indíqueme qué información necesita o qué órdenes debo cumplir."); tema_madre_cajafuerte: HablaMadre("No puedo acceder al computador del complejo para consultar la combinación de la caja fuerte."); tema_madre_cargador: HablaMadre("Para recargar las baterías puede usarse el cargador situado en el panel de instrumentos de la nave."); tema_madre_circuito: if (TestScope(circuito, player)) { if (circuito hasnt general) { HablaMadre("La única forma de arreglar una conexión en un circuito fotónico es soldar las conexiones que tenga abiertas, y para ello se requiere un soldador industrial controlado por un autómata."); } else { HablaMadre("El circuito fotónico ya ha sido soldado y funciona dentro de sus parámetros operativos."); } } else { HablaMadre("No sé a qué circuito o conexión se refiere, señor."); } tema_madre_codigo: if (panel_control.codigo_viejo == 0) { ! El jugador todavía no ha intentado meter el código viejo HablaMadre("El código de acceso de la puerta al procesador atmosférico, según indican los informes que me fueron grabados antes de partir, es el 759812."); } else { ! El jugador ha intentado meter el código viejo, y no le funciona if (self.codigo_nuevo == 0) { HablaMadre("Al parecer, el control de la puerta se ha reiniciado, haciendo que el código de acceso sea otro distinto. Hay que calcular el nuevo código a partir de su semilla."); } else { ! Ya se ha calculado el nuevo código a partir de la semilla: HablaMadre("El nuevo código de acceso al procesador atmosférico es el 268741."); } } tema_madre_complejo: HablaMadre("El complejo minero rodea la veta de Vibrantium, y dispone de todo lo necesario para hacer factible la vida en el planeta."); tema_madre_compuerta: HablaMadre("La compuerta de la nave está bloqueada por motivos de seguridad. Si desea que la abra, sólo tiene que indicármelo."); tema_madre_compuerta: HablaMadre("El compartimento destinado a los trajes atmosféricos se puede abrir abrir y cerrar si lo desea. Tan sólo tiene que pedírmelo."); tema_madre_energia: if (circuito hasnt general) { HablaMadre("El suministro de energía ha sido interrumpido debido a un fallo en el sistema de control del procesador atmosférico."); } else { HablaMadre("La energía del complejo se halla restablecida al 100%."); } tema_madre_habitats: HablaMadre("La zona oeste del complejo está dedicada a los hábitats de los colonos. Son los recintos destinados a dormitorio y aseo. Sólo un colono puede acceder a ellos. En todo caso, con el computador central dañado será imposible abrir las puertas."); tema_madre_holocubo: HablaMadre("El holocubo es un soporte de datos muy utilizado por su alta durabilidad y gran capacidad de almacenamiento. Para reproducir su contenido se require de un dispositivo proyector."); tema_madre_informe: HablaMadre("Todos los sistemas de la nave se encuentran operativos."); tema_madre_jason: HablaMadre("El Mayor Jason es un marine condecorado con varias medallas al valor en el campo de batalla. El número de misiones en las que ha participado es incalculable. Por otra parte, es el ser humano más maleducado y desagradable con quien he tenido el privilegio de trabajar."); if (jason notin vaina && (~~(procesador.arreglado()))) { jason.decir = false; switch (random(3)) { 1: HablaJason("Me pitan los oídos. ¿Habláis de mi?"); 2: HablaJason("Yo también te quiero, saco de circuitos."); 3: HablaJason("Tú tampoco eres mi tipo, ¿sabes?"); } } tema_madre_localizarle: if (jason in nave1 or nave2) { HablaMadre("El Mayor Jason está dentro del vehículo, señor."); } else { HablaMadre("Lo lamento, pero no puedo precisar la localización concreta en la que se encuentra el Mayor."); } tema_madre_localizarme: if (LugarReal() == nave1 or nave2) { HablaMadre("Se encuentra dentro del vehículo, señor."); } else if (LugarReal() == procesador) { HablaMadre("Se encuentra dentro del procesador atmosférico."); } else if (EsExterior(LugarReal())) { HablaMadre("Se encuentra en el exterior, directamente sobre la superficie del planeta."); } else { switch (montacargas.nivel) { 0: HablaMadre("Sólo puedo indicarle que se encuentra en el nivel 0 del complejo, y que hay dos niveles más hacia abajo."); -1: HablaMadre("Se encuentra en el nivel -1 del complejo, y arriba y abajo puede encontrar los niveles 0 y -2, respectivamente. Lamento no poder precisar más."); -2: HablaMadre("Se encuentra en el nivel -2, el más profundo del complejo, y hacia arriba se encuentran los niveles 0 y -1. No puedo darle más información."); } } tema_madre_madre: HablaMadre("Soy la computadora de la nave. Una inteligencia artificial diseñada para llevar a cabo tareas sencillas y razonar de pensamientos profundos."); tema_madre_mision: HablaMadre("El objetivo de la misión es elaborar un informe completo de la situación producida en la colonia minera, reestablecer las comunicaciones y determinar las causas de lo ocurrido."); tema_madre_ordenadores: if (entrada has visited) { HablaMadre("El sistema lógico del complejo ha sido dañado y no puedo comunicarme con el computador central del complejo."); } else { HablaMadre("Yo misma gobierno la nave sin necesidad de computadores periféricos."); } tema_madre_planeta: HablaMadre("Objeto 2003 UB313. Nombre alternativo: Eris. Cuerpo celeste clase V. El mayor plutoide y objeto transneptuniano. Satélite natural: Disnomia. Diámetro: 2.400 km. Órbita: 557 años terrestres. Clasificado como «cuerpo del disco disperso del Cinturón de Kuiper». Ausencia de vida autóctona."); tema_madre_procesador: if (circuito hasnt general) { HablaMadre("El procesador atmosférico es el mecanismo utilizado para transformar artificialmente el aire y hacerlo respirable para el ser humano. Toda instalación colonial enclavada en una atmósfera venenosa requiere de al menos uno. El estado actual del procesador atmosférico es: INOPERANTE. Atmósfera irrespirable."); } else { HablaMadre("El procesador atmosférico es el mecanismo utilizado para transformar artificialmente el aire y hacerlo respirable para el ser humano. El estado actual del procesador atmosférico es: OPERATIVO. Atmósfera respirable."); } tema_madre_semilla: switch (self.codigo_nuevo) { 0: HablaMadre("El código de acceso se calcula a partir de la semilla del generador pseudoaleatorio. Indíqueme el valor de la nueva semilla que aparece en el display, para que pueda calcular el código correcto."); new_line; print "[Prueba usando ~", (s_in) "MADRE, LA SEMILLA ES n", "~, sustituyendo ~", (s_in) "n", "~ por el valor de la semilla.]^"; 1: HablaMadre("El código de acceso se calcula a partir de la semilla del generador pseudoaleatorio. A partir de la semilla que me ha indicado, he calculado que el nuevo código de acceso es 268741."); } tema_madre_salir: if (LugarReal() == nave1 or nave2) { HablaMadre("Para salir sólo tiene que pedirme que abra la puerta."); rtrue; } if (EsExterior(LugarReal())) { HablaMadre("Ya se encuentra en terreno abierto, señor..."); rtrue; } if (player in procesador) { HablaMadre("La puerta ya está abierta, señor. Nada le impide salir al exterior."); } HablaMadre("La única salida conocida del complejo es la entrada situada al norte del nivel 0. Existe una salida de emergencia que siempre está cerrada salvo en casos excepcionales."); tema_madre_trajes: if (compartimento_trajes has open) { HablaMadre("El compartimento de los trajes ya está abierto."); } else { HablaMadre("Los trajes atmosféricos de protección se encuentran almacenados en un compartimento acoplado a una de las paredes de la cabina."); } default: HablaMadre("Lo siento. No he podido identificar el sentido de sus palabras."); rtrue; } rtrue; ], orders [; self.decir = false; Yes: HablaMadre("Dígame cómo puedo ayudarle..."); rtrue; No: HablaMadre("Como desee..."); rtrue; Semilla: if (parsed_number == 9957) { self.codigo_nuevo = 1; HablaMadre("Parece una semilla correcta. El valor generado es 268741. Ese debería ser el nuevo código."); } else { HablaMadre("Ese número no corresponde a un valor de semilla correcto."); } rtrue; Despegar: HablaMadre("Mis parámetros me impiden abandonar el planeta en esta etapa tan temprana de la misión."); rtrue; Open: switch (noun) { puerta_nave, nave: if (noun == nave) { noun = puerta_nave; } if (noun hasnt open) { noun.abrir(); move descompresion to nave1; HablaMadre("Abriendo compuerta de la nave."); if (LugarReal() == nave1 or nave2 or exterior1) { print "^Se oye el rugido de los servomecanismos de la compuerta de la nave mientras se desplaza suavemente hacia arriba."; if (LugarReal() ~= nave2) { " Desde tu posición puedes observar el habitáculo de descompresión."; } new_line; } rtrue; } else { HablaMadre("La compuerta de la nave ya ha sido abierta. Proceso interrumpido."); rtrue; } compartimento_trajes: if (noun hasnt open) { noun.abrir(); HablaMadre("Abriendo compartimento de trajes atmosféricos."); if (LugarReal() == nave1 or exterior1) { "^Un sonido hidráulico en una pared lateral llama tu atención hacia la puerta transparente del compartimento, mientras ésta se desplaza lateralmente para dejar acceso a su interior."; } rtrue; } else { HablaMadre("El compartimento de trajes ya ha sido abierto. Proceso interrumpido."); rtrue; } armario: HablaMadre("El armario es un dispositivo de apertura manual. Puede abrirlo usted mismo."); rtrue; cargador: Hablamadre("No es necesario abrir el cargador para operar con él."); rtrue; puerta_procesador: if (noun hasnt open) { if (panel_control has general) { HablaMadre("No puedo abrir la puerta desde aquí. El sistema parece haberse reinicializado, y el código de acceso que tengo registrado ya no sirve. Hay que calcular el nuevo código a partir de la semilla que se muestra."); } else { HablaMadre("No tengo acceso al sistema de control de la puerta."); } } else { HablaMadre("La puerta de acceso al procesador atmosférico ya se encuentra abierta."); } rtrue; default: if (noun has door) { HablaMadre("El computador interno del complejo está dañado, y no me permite accionar ninguna puerta."); rtrue; } if (noun has openable) { HablaMadre("No puedo abrir nada a distancia, señor."); rtrue; } HablaMadre("No se ha podido determinar qué se desea abrir."); rtrue; } Close: switch (noun) { puerta_nave, nave: if (noun == nave) { noun = puerta_nave; } if (noun has open) { noun.cerrar(); remove descompresion; HablaMadre("Cerrando compuerta de la nave."); rtrue; } else { HablaMadre("La compuerta de la nave ya ha sido cerrada. Proceso interrumpido."); rtrue; } compartimento_trajes: if (noun has open) { noun.cerrar(); HablaMadre("Cerrando compartimento de trajes atmosféricos."); rtrue; } else { HablaMadre("El compartimento de trajes ya ha sido cerrado. Proceso interrumpido."); rtrue; } puerta_procesador: HablaMadre("El computador interno del complejo está dañado, y no me permite accionar ninguna puerta."); rtrue; default: if (noun has door) { HablaMadre("El computador interno del complejo está dañado, y no me permite accionar ninguna puerta."); rtrue; } if (noun has openable) { HablaMadre("No puedo cerrar nada a distancia, señor."); } else { HablaMadre("No se ha podido determinar qué se desea cerrar."); } rtrue; } Saludar: HablaMadre("Siempre dispuesta a cumplir sus órdenes."); rtrue; NotUnderstood, Tell: <>; Ayudar: if (alien.comportamiento == 0) { ! Estamos en la primera parte del juego if (LugarReal() == nave1 or nave2) { HablaMadre("Su misión principal consiste en investigar la situación. Debe entrar en el complejo y descubrir qué está pasando."); } else { HablaMadre("Debería arreglar el procesador atmosférico para restablecer el suministro de oxígeno."); } } else { ! El alien ya se ha llevado a Jason if (jason in vaina) { ! Jason sigue en la vaina HablaMadre("Sus órdenes siguen siendo comprobar la situación actual y restablecer las comunicaciones. Rescatar a un herido en combate no forma parte de la misión. Aunque... claro está... yo no soy humana..."); } else { ! Has sacado a Jason de la vaina if (entrada hasnt general) { ! Aún no sabes que la puerta está sellada HablaMadre("Deberían escapar lo antes posible de ese lugar."); } else { ! Sabes que la puerta está sellada HablaMadre("La única salida alternativa que aparece en mis planos es el ascensor de emergencia, pero normalmente permanece inaccesible."); } } } rtrue; default: ! Cuando es una orden distinta a las de arriba, dice "La computadora tiene mejores ! cosas que hacer". Lo suyo es que diga otra cosa: HablaMadre("Lamento decirle que mi programación no es tan sofisticada."); rtrue; ], mensaje_aleatorio [; switch (random(4)) { 1: HablaMadre("¿Desea alguna cosa?"); PreguntaSiNo = 1; 2: HablaMadre("¿Puedo ayudarle en algo?"); PreguntaSiNo = 1; 3: HablaMadre("¿En qué puedo serle de utilidad?"); 4: HablaMadre("¿Puedo hacer algo por usted?"); PreguntaSiNo = 1; } self.decir = false; ], each_turn [; ! No muestra mensajes aleatorios cuando alien.comportamiento >= 3, para ! no molestar en momentos críticos: if (self.decir && deadflag == 0 && alien.comportamiento < 3) { if (random(100) < 5) { self.mensaje_aleatorio(); } } else { self.decir = true; } ], has scenery animate proper switchable; ! El alien cuando estamos en la oscuridad: Object alien_oscuridad thedark with each_turn [; if (alien in real_location && real_location ofclass Complejo) { if (alien.comportamiento == 1 or 3) { if (alien.oportunidad < 4) { if (alien.oportunidad > 0) { ControlTimer.PrepararImpresion(); print "^¡Notas que algo se dirige rápidamente hacia ti!^"; Damusix.TocarV(Rugido_ogg); } alien.oportunidad = alien.oportunidad + 2; rtrue; } if (alien.oportunidad >= 4) { alien.muerte_final(); } } } ], has concealed; ! comportamiento = ! 0: Está en el procesador atmosférico esperando a que lleguemos ! 1: Está en el laberinto moviéndose al azar (después de haberse llevado a Jason) ! (OJO: Jason puede estar o no en la vaina) ! 2: Va camino de la puerta para taparla (de aquí se pasa de nuevo al 1) ! 3: Va hacia ti corriendo (cuando vas a activar la autodestrucción) ! 4: "Desaparece" después de activar la autodestrucción Object alien procesador class Movil class ObjetoRastreable with short_name "monstruo", name_m 'alien' 'alienigena' 'bicho' 'monstruo' 'ser' 'xenomorfo' 'xenoforme', name_f 'criatura', gender G_MASCULINO, description [; print "Puedes apreciar que tiene una cabeza enorme, lisa, alargada de forma obscena hacia atrás, sin ojos, con una boca rebosante de afilados dientes, sobre una estructura semihumana de largos y delgados brazos y piernas, acabando todos ellos en manos y pies con seis dedos y largas uñas. También posee una larga cola, que mueve con una velocidad y precisión asombrosas."; if (alien.comportamiento > 0) { print " Sin duda, es la misma criatura que os atacó en el procesador atmosférico."; } ""; ], llega_por 0, llega [ dir; self.llega_por = dir; ControlTimer.PrepararImpresion(); if (self.tipo_de_movimiento == MOVIMIENTO_PERSEGUIR && self.perseguido == player && self.time_left > 0) { if (jason in LugarReal()) { print "^¡", (The) self, " os sigue desde ", (the) dir, "! ¡Corred!^"; } else { print "^¡", (The) self, " te sigue desde ", (the) dir, "! ¡Corre!^"; } } else { print "^", (The) self, " aparece"; if (dir ~= NULL) { print " por ", (the) dir; print ".^"; } } ], pnj_ha_llegado_default [; if (self.tipo_de_movimiento ~= MOVIMIENTO_PERSEGUIR) { PNJ_Ruta(self, MOVIMIENTO_ALEATORIO); } ], pnj_ha_llegado pnj_ha_llegado_default, pnj_ha_llegado_puerta [; if (self.tipo_de_movimiento == MOVIMIENTO_POR_META && self in entrada) { AlienBloqueaPuerta(); if (LugarReal() == entrada) { ControlTimer.PrepararImpresion(); "¡Ves al monstruo tapando la entrada con una sustancia viscosa que se vuelve inmediatamente rígida!"; } } ], ! precamino RUTA_NINGUNA, tras_abrir NO_PUEDE_ABRIR, ! Comportamiento después de pasar por una puerta capricho 50, ! 50% de probabilidades de moverse en un turno (defecto = 20%) distancia 0, ! En cada turno, contiene la longitud de la ruta hasta el jugador oportunidad 0, ! Se le da una oportunidad al jugador para escapar del alien cuando ! los dos se encuentren en la misma localidad comportamiento 0, primera_vez true, ! ¿Es la primera vez que lo vemos? muerte_final [; Bandera_Fin(1); viewImageCenter(Alien_Mata_jpg); ControlTimer.PrepararImpresion(); "El monstruo salta sobre ti. Sientes sus afiladas garras hundirse en tu carne como si fuese mantequilla, y su poderosa boca se abre completamente alrededor de tu cabeza, que en pocos segundos deja de formar parte de tu cuerpo.^"; ], describe [ v; if (self.primera_vez) { self.primera_vez = false; viewImageCenter(procesador.sgw_img); Damusix.PararCanal(CANAL_FONDO); KeyDelay(); Damusix.TocarV(Rugido_ogg); clearTextWindow(); print "^De pronto, observas aterrado que un ser de aspecto grotescamente terrorífico comienza a sobresalir entre un conglomerado de tuberías. Conforme se va incorporando, lo tienes más fácil para comprobar su enorme altura y su terrible fisionomía: una cabeza enorme, lisa, alargada de forma obscena hacia atrás, sin ojos, con una boca rebosante de afilados dientes, coronando una estructura antropomorfa de largos y delgados brazos y piernas, culminando todos ellos en apéndices con seis dedos y largas y amenazadoras uñas. Al separarse completamente de la pared en la que se encontraba escondido, puedes ver su larga cola, que mueve con una velocidad y precisión asombrosas.^"; KeyDelay(); v = Damusix.QueVolumenCanal(CANAL_FONDO); Damusix.AsignarCanal(procesador.sgw_mus, CANAL_FONDO, v, SONIDO_BUCLE_INFINITO); Damusix.TocarCanal(CANAL_FONDO); rtrue; } else { ! A partir de ahora, la rutina cada_turno se encargará de describir la presencia ! del alien, y no la rutina describir: rtrue; } ], time_left, time_out [; if (self.comportamiento == 1) { self.time_left = -1; self.oportunidad = 0; PNJ_Ruta(self, MOVIMIENTO_ALEATORIO); if (self in LugarReal()) { ControlTimer.PrepararImpresion(); "^Vaya... Parece que ha dejado de seguirte... Aún no te ha visto..."; } } ], ! Se usa por si el alien surge de repente de la pared. En ese caso, no se debe decir ! que está aquí, porque ya lo ha dicho el objeto sacador_de_aliens: callado false, ! accion_antes [; ! if (self.comportamiento == 1 or 3 && self in LugarReal()) { ! self.capricho = 0; ! } else { ! self.capricho = 50; ! } ! ], react_before [; Go: if (noun == self.llega_por) { "¡", (The) self, " está justo en esa dirección y te bloquea el paso!"; } ], before [; Disparar: if (rifle notin player) { rfalse; } Bandera_Fin(1); viewImageCenter(Alien_Mata_jpg); ControlTimer.PrepararImpresion(); "Descargas una ráfaga de munición directamente en el ~corazón~ del monstruoso ser, provocando una lluvia verde de sangre ácida que cae directamente sobre tu cuerpo. Y mientras éste se disuelve, casi desintegrándose a marchas forzadas, pides por favor que el monstruo no se demore mucho en arrancarte la cabeza y librarte del inenarrable dolor que sientes..."; Examine: rfalse; default: self.muerte_final(); rtrue; ], ! Esta propiedad la usa el MovedorDeMoviles (en Moviles_NG.h) como condición previa ! a mover un móvil. Si se devuelve false no se moverá: condicion_movimiento [; if (self.comportamiento == 1 or 3 && self in LugarReal()) { self.capricho = 0; rfalse; } else { self.capricho = 50; rtrue; } ], each_turn [; ! Cambia aleatoriamente el nombre del alien: switch (random(3)) { 1: self.short_name = "criatura"; self.gender = G_FEMENINO; 2: self.short_name = "monstruo"; self.gender = G_MASCULINO; 3: self.short_name = "ser"; self.gender = G_MASCULINO; } self.condicion_movimiento(); if (self in LugarReal()) { if (self.callado) { self.callado = false; rtrue; } ControlTimer.PrepararImpresion(); if (self.comportamiento == 1) { ! Se le da dos oportunidades. Después lo mata. if (self.oportunidad < 4) { switch (self.oportunidad) { 0: if (self.tipo_de_movimiento == MOVIMIENTO_PERSEGUIR) { ! print "^¡El monstruo te está siguiendo! ¡Corre!^"; self.oportunidad = self.oportunidad + 2; if (random(3) == 1) { Damusix.TocarV(Rugido_ogg); } } else { if (self.time_left ~= -1) { print "^¡El monstruo está aquí! Por suerte, parece que aún no "; if (jason in LugarReal()) { print "os ha visto...^"; switch (random(2)) { 1: HablaJason("(en voz baja) Está ahí... Está ahí..."); 2: HablaJason("(susurrando) Vámonos ahora que aún podemos..."); } } else { print "te ha visto...^"; } } } 1: if (location == thedark) { print "^Puedes notar la mirada del ser taladrándote incluso a través de la oscuridad.^"; } else { print "^¡El monstruo gira su cabeza y "; if (jason in LugarReal()) { print "os observa amenazador!^"; switch (random(2)) { 1: HablaJason("¿Qué coño está haciendo? ¡Vamonos YA!"); 2: HablaJason("¡¡Vámonos de una puta vez!!"); } } else { print "te observa amenazador!^"; } } 2: if (location == thedark) { print "^¡Sientes que el"; } else { print "^¡El"; } print " monstruo comienza a caminar hacia "; if (jason in LugarReal()) { print "vosotros!^"; switch (random(2)) { 1: HablaJason("¡No puedo más! ¡Nooooooooo!"); 2: HablaJason("¡Aléjate de mí! ¡Déjameeeeeeeee!"); } jason.capricho = 100; PNJ_Ruta(jason, MOVIMIENTO_ALEATORIO); jason.movimiento(); } else { print "ti!^"; } Damusix.TocarV(Monstruo_ogg); 3: print "^¡El monstruo salta sobre "; if (jason in LugarReal()) { print "vosotros! ¡Corred!^"; HablaJason("¡¡¡AAAAAAAAAAAAAAGH!!!"); } else { print "ti! ¡Corre!^"; } Damusix.TocarV(Rugido_ogg); } if (self.time_left >= 0) { if (self.oportunidad > 0) { PNJ_Ruta(alien, MOVIMIENTO_PERSEGUIR, player); StartTimer(self, 5 + random(5)); } } else { self.time_left = 0; } self.oportunidad++; rtrue; } } else if (self.comportamiento == 3) { if (self.oportunidad < 4) { switch (self.oportunidad) { 0: print "^¡El monstruo "; if (jason in LugarReal()) { print "os"; } else { print "te"; } print " observa amenazador!^"; 1, 2, 3, 4: print "^¡El monstruo salta sobre "; if (jason in LugarReal()) { print "vosotros!^"; switch (random(2)) { 1: HablaJason("¡No puedo más! ¡Nooooooooo!"); 2: HablaJason("¡Aléjate de mí! ¡Déjameeeeeeeee!"); } jason.capricho = 100; PNJ_Ruta(jason, MOVIMIENTO_ALEATORIO); jason.movimiento(); } else { print "ti!^"; } Damusix.TocarV(Rugido_ogg); } self.oportunidad = self.oportunidad + 3; rtrue; } } } if (self.oportunidad >= 4) { print "^"; self.muerte_final(); } ], has animate; ! El atributo general indica que se ha movido de su sitio (empujándolo) Object robot "robot de mantenimiento" exterior3, with name 'robot' 'androide', adjectives 'mantenimiento', description "Son los restos de un robot humanoide, usado principalmente para llevar a cabo tareas de mantenimiento. No cabe duda de que a este ejemplar en concreto no le han tratado con mucho cuidado recientemente. Ha perdido toda su estructura inferior, por lo que no tiene piernas ni posibilidad de movimiento autónomo. Asimismo, todo su antebrazo izquierdo se encuentra seriamente dañado. Pese a todo, tiene aspecto de conservar parte de su capacidad de funcionamiento. Su brazo derecho termina en un dispositivo con forma de soldador que parece plenamente operativo.", describe [; if (self hasnt general) { "^Tirado en el suelo, junto a una pared del complejo, se observa la parte superior de un androide."; } else { "^Hay un medio androide descansando en el suelo."; } ], ! "Decir" y "hablar" es lo mismo que "preguntar" react_before [; Decir: <>; ], ! Indica si el robot tiene permiso para decir algo aleatoriamente a continuación: decir true, ! Indica si el robot ha hablado alguna vez (se actualiza en HablaRobot) ha_hablado false, before [; Take, Remove: "El robot pesa demasiado como para poder cogerlo. Lo más que puedes hacer es intentar empujarlo..."; Push, Pull, Turn: "Prueba a empujarlo en una dirección concreta."; PushDir: AllowPushDir(); rtrue; ], after [; Examine: if (self hasnt general) { viewImageCenter(Robot_jpg); KeyDelay(); viewImageCenter(exterior3.sgw_img); } PushDir: give self general; "Empujas al robot hacia ", (the) second, "..."; ], life [ tema; Ask: self.decir = false; tema = AveriguarTema(TemasRobot); switch (tema) { tema_robot_alien: HablaRobot("Foooorma de... vida dddeeessss... cconn... desconocidddda... cortar... soldar... arreglar..."); tema_robot_codigo: HablaRobot("Código... seeeeeeeeeisssss dígitosssssss..."); tema_robot_complejo: HablaRobot("Colonia espacial... ppfpffkkkk... prospeccion mineral autorizada... trabajo..."); tema_robot_cortar_abrir: HablaRobot("Es posible... seccionar... usando... un dispositivo cortador... adddddddd... adecuado..."); tema_robot_gente: HablaRobot("Todos desaparecidos... ggiiiijjjj... señales de vida cesaron... no queda nadie... gggg... de repente"); tema_robot_procesador: HablaRobot("Debo... ir... processssssador atttmmmm... Arreglar... Prioridad máximmma..."); tema_robot_puerta: HablaRobot("Puerta al complejo... bloqueada... inutilizada..."); tema_robot_robot: HablaRobot("Soy un robot... Soy un robot de mantenimiento diseñado para... diseñado... arreglar... cortar... seccionar... fijar..."); tema_robot_semilla: HablaRobot("Semilla... Generador... Pseudoaleatorio... Nuevo código... basado en semilla..."); default: print "El robot se queda en silencio. Parece no entender lo que le acabas de decir... pero finalmente dice:^"; self.mensaje_aleatorio(); rtrue; } rtrue; ], orders [; self.decir = false; Arreglar, Soldar: if (noun == cables) { "Unes los extremos de varios cables entre sí, para ayudar al robot a soldarlos, pero te das cuenta de que, por mucho que pruebas a unir unos con otros, el resultado siempre es negativo. Es evidente que el problema no es que la energía no puede circular, sino más bien que NO HAY energía..."; } else if (noun == circuito) { HablaRobot("Soldando... soldando..."); procesador.arreglar(); Damusix.TocarV(Chispazo_ogg, 100); print "^El robot mueve su brazo soldador hasta situarlo justo delante del circuito dañado. Se ven y oyen ráfagas de chispas eléctricas saliendo del punto de unión entre el circuito y la punta del soldador. Finalmente, retira su brazo, justo en el momento en el que toda la maquinaria del procesador comienza un peculiar traqueteo y las luces de la sala se encienden... ¡Está funcionando! ¡Casi puedes oler el oxígeno a través de tu traje!^^ La peor parte se la lleva el robot: toda su energía se ha consumido en su última operación, y yace inerte en el suelo como un trasto más.^"; KeyDelay(); "^Ya no será necesario llevar trajes atmosféricos para poder respirar. Y en cuanto a la linterna, una vez que has reestablecido la luz eléctrica en toda la instalación, está claro que no hace falta llevarla encendida."; } else { HablaRobot("No soldable. No soldable."); rtrue; } NotUnderstood: <>; default: self.decir = false; HablaRobot("Comando incorrecto."); rtrue; ], each_turn [; if (self.decir) { if (self in junto_procesador && puerta_procesador hasnt open) { if (panel_control.codigo_viejo == 0) { HablaRobot("Código puerta... 759812... Código puerta... 759812..."); } } else { if (random(100) < 60) { self.mensaje_aleatorio(); } } } else { self.decir = true; } ], mensaje_aleatorio [; switch (random(5)) { 1,2: HablaRobot("Fffff... 759812... Zzzzzz..."); 3: HablaRobot("Soy un robot de la serie UUR7-35A."); 4: HablaRobot("Directivas principales: cortar... soldar... arreglar..."); 5: HablaRobot("Click... 65712... 12... 12..."); } ], has ! Es transparente para que se pueda usar "pide cortador a robot" static animate transparent; Object "brazo izquierdo" with name_m 'brazo', name_mp 'brazos', name_f 'mano', name_fp 'manos', adjectives 'izquierdo' 'izquierda' 'robot' 'androide', gender G_MASCULINO, found_in robot robot_inutil, description "Al robot le falta su mano izquierda.", has scenery; Object "brazo derecho" with name_m 'brazo', name_mp 'brazos', name_f 'mano', name_fp 'manos', adjectives 'derecho' 'derecha' 'robot' 'androide', gender G_MASCULINO, found_in robot robot_inutil, description "Su brazo derecho parece estar en buenas condiciones. El extremo del mismo te recuerda a un rudimentario soldador.", has scenery; Object "piernas" with name_f 'pierna', name_fp 'piernas', name_m 'pie', name_mp 'pies', adjectives 'robot' 'androide', gender G_FEMENINO + G_PLURAL, found_in robot robot_inutil, description "¡Pero si no tiene piernas!", has scenery; Object soldador "soldador" with name_m 'soldador' 'extremo', name_f 'punta', adjectives 'metalica' 'metalico' 'robot' 'androide', gender G_MASCULINO, found_in robot robot_inutil, description "Es una punta metálica ligeramente decolorida y que emite un calor apenas perceptible.", before [; Touch, Take, Remove: "¡Cuidado! Puedes quemarte..."; ], has scenery; Object "cabeza" with name_f 'cabeza', name_m 'cerebro' 'craneo', adjectives 'robot' 'androide', gender G_FEMENINO, found_in robot robot_inutil, description "La cabeza del robot, aunque dañada, parece poder funcionar con normalidad. No podrías decir lo mismo de su ~cerebro~ interior...", has scenery; ! Este robot sustituye al robot normal cuando se arregla el procesador atmosférico Object robot_inutil "robot" with name 'robot' 'androide', description "Cumplió adecuadamente su trabajo hasta el último momento.", initial "El robot de mantenimiento reposa aquí, sin energía, sin vida...", before [; "Este robot ya no sirve para nada. Aunque te duela, no es más que un montón de chatarra."; ], has transparent; ! ==================================================================== ! ! TEMAS RAIZ ! ! ==================================================================== ! Cuidado con los infinitivos. Si pones un infinitivo aquí, luego no se puede usar ! como verbo ! Temas del robot Object TemasRobot; Object tema_robot_puerta "la puerta" TemasRobot with name 'puerta' 'como' 'abierta' 'abrir' 'cerrada' 'cerrar'; Object tema_robot_robot "el robot" TemasRobot with name 'robot' 'androide' 'ti' 'si' 'mismo'; Object tema_robot_cortar_abrir "cortar o abrir" TemasRobot with name 'cortar' 'corta' 'abre' 'sacar' 'vaina' 'gelatina' 'mucosidad' 'moco' 'mocos' 'viscosidad'; Object tema_robot_complejo "el complejo" TemasRobot with name 'complejo' 'colonia' 'minera' 'mina'; Object tema_robot_gente "la gente" TemasRobot with name 'gente' 'personas' 'humanos' 'alguien'; Object tema_robot_alien "el monstruo" TemasRobot with name 'alien' 'alienigena' 'monstruo' 'bicho' 'ser' 'criatura' 'xenoforme' 'xenomorfo'; Object tema_robot_codigo "el código de acceso" TemasRobot with name 'codigo' 'clave' 'contrasena' 'panel' 'control' 'puerta' 'procesador'; Object tema_robot_procesador "el procesador atmosférico" TemasRobot with name 'procesador' 'atmosferico'; Object tema_robot_semilla "la semilla" TemasRobot with name 'semilla' 'valor' 'display' 'codigo' 'puerta' 'procesador'; ! Temas de la computadora Object TemasComputadora; Object tema_madre_compuerta "la compuerta" TemasComputadora with name 'puerta' 'compuerta' 'abierta' 'abrir'; Object tema_madre_compartimento "la compuerta" TemasComputadora with name 'puerta' 'compartimento' 'trajes' 'atmosfericos' 'abierta' 'abrir'; Object tema_madre_planeta "el planeta" TemasComputadora with name 'planeta' 'superficie'; Object tema_madre_atmosfera "la atmósfera" TemasComputadora with name 'atmosfera' 'aire' 'respirar'; Object tema_madre_procesador "el procesador atmosférico" TemasComputadora with name 'procesador' 'atmosferico'; Object tema_madre_arreglar "arreglar el procesador" TemasComputadora with name 'arreglar' 'arregla' 'arreglo' 'reparar' 'repara' 'reparo' 'procesador' 'atmosferico'; Object tema_madre_trajes "los trajes" TemasComputadora with name 'donde' 'esta' 'estan' 'traje' 'trajes'; Object tema_madre_informe "el informe de situación" TemasComputadora with name 'informe' 'situacion' 'estado'; Object tema_madre_cargador "el cargador de baterías" TemasComputadora with name 'bateria' 'baterias' 'cargador' 'cargar' 'recargar'; Object tema_madre_holocubo "el holocubo" TemasComputadora with name 'holocubo' 'cubo' 'holografico'; Object tema_madre_ayuda "pedir ayuda" TemasComputadora with name 'ayuda' 'socorro'; Object tema_madre_mision "la misión" TemasComputadora with name 'mision' 'objetivo'; Object tema_madre_madre "la computadora" TemasComputadora with name 'ti' 'si' 'misma' 'quien' 'eres'; Object tema_madre_complejo "el complejo" TemasComputadora with name 'complejo' 'colonia' 'minera' 'mina'; Object tema_madre_codigo "el código de acceso" TemasComputadora with name 'codigo' 'clave' 'contrasena' 'panel' 'control' 'puerta' 'procesador' 'abrir'; Object tema_madre_semilla "la semilla" TemasComputadora with name 'calcula' 'calcular' 'nueva' 'nuevo' 'contrasena' 'clave' 'codigo' 'semilla' 'valor' 'display' 'puerta' 'procesador'; Object tema_madre_jason "Jason" TemasComputadora with name 'quien' 'es' 'jason' 'soldado' 'mayor' 'marine' 'companero'; Object tema_madre_localizarme "localizarme" TemasComputadora with name 'localizame' 'localizarme' 'donde' 'estoy' 'estamos'; Object tema_madre_localizarle "localizarle" TemasComputadora with name 'localiza' 'localizar' 'donde' 'esta' 'jason'; Object tema_madre_alien "el monstruo" TemasComputadora with name 'alien' 'alienigena' 'monstruo' 'bicho' 'ser' 'criatura' 'xenoforme' 'xenomorfo'; Object tema_madre_salir "salir" TemasComputadora with name 'salir' 'salgo' 'como' 'puedo' 'podemos' 'aqui' 'escapar' 'escapamos' 'escapo'; Object tema_madre_cajafuerte "la caja fuerte" TemasComputadora with name 'caja' 'fuerte' 'combinacion' 'abrir'; Object tema_madre_ordenadores "los ordenadores" TemasComputadora with name 'ordenadores' 'ordenador' 'computadores' 'computador' 'computadoras' 'computadora'; Object tema_madre_ascensor "el ascensor de emergencia" TemasComputadora with name 'ascensor' 'emergencia'; Object tema_madre_habitats "los hábitats" TemasComputadora with name 'habitat' 'habitats'; Object tema_madre_circuito "el circuito" TemasComputadora with name 'circuito' 'conexion' 'fotonico'; Object tema_madre_energia "la energía" TemasComputadora with name 'energia' 'luz'; ! Temas de Jason Object TemasJason; Object tema_jason_donde_estas "dónde estas" TemasJason with name 'donde' 'estas' 'esta'; Object tema_jason_detector "el detector" TemasJason with name 'detector' 'movimiento' 'presencia'; Object tema_jason_jason "jason" TemasJason with name 'jason' 'ti' 'si' 'mismo' 'quien' 'eres'; Object tema_jason_rifle "el rifle" TemasJason with name 'rifle' 'arma' 'pistola'; Object tema_jason_comunicador "el comunicador" TemasJason with name 'comunicador' 'intercomunicador' 'transmisor'; Object tema_jason_colonia "la colonia" TemasJason with name 'colonia' 'minera' 'complejo'; Object tema_jason_gente "la gente" TemasJason with name 'gente' 'personas' 'humanos' 'alguien'; Object tema_jason_alien "el monstruo" TemasJason with name 'alien' 'alienigena' 'monstruo' 'bicho' 'ser' 'criatura' 'xenoforme' 'xenomorfo'; Object tema_jason_planeta "el planeta" TemasJason with name 'planeta' 'superficie'; Object tema_jason_vaina "la vaina" TemasJason with name 'vaina' 'capullo' 'mucosa' 'gelatinosa' 'mucosidad' 'viscosidad' 'viscosa'; Object tema_jason_madre "Madre" TemasJason with name 'madre' 'computadora' 'computador' 'ordenador' 'nave'; Object tema_jason_mision "la misión" TemasJason with name 'mision' 'objetivo' 'objetivos'; Object tema_jason_robot "el robot" TemasJason with name 'robot' 'androide' 'robots' 'androides'; ! ==================================================================== ! ! OBJETOS QUE LLEVAN LOS PERSONAJES AL EMPEZAR ! ! ==================================================================== Object rifle "rifle de asalto" jason with name 'tu' 'rifle' 'asalto' 'arma' 'kolmogorov', description "Un rifle de asalto Kolmogorov 773. Dispara proyectiles con un alto poder de penetración. Lleva acoplado un detector de movimiento.", ! inicial "Lo único que queda de Jason es su rifle tirado en el suelo como la huella de ! un momento terrible.", react_before [; Take, Drop: if (noun == detector_movimiento) { print_ret (The) noun, " forma parte ", (del) self, "."; } ], before [; Give: if (second == jason) { HablaJason("Quédeselo usted... Ya no lo quiero..."); rtrue; } else { "Deberías quedártelo. Es demasiado valioso para desprenderte de él."; } Drop: "Es demasiado valioso para desprenderte de él."; Take: if (self in jason) { HablaJason("Lo siento, señor, pero preferiría continuar con mi arma."); rtrue; } ], after [; Take: if (detector_movimiento hasnt on) { give detector_movimiento on; "Al coger el rifle del suelo, no dudas ni un instante en activar el detector de movimiento que lleva acoplado. Está claro puede serte de mucha utilidad."; } ], has transparent; Object detector_movimiento "detector de movimiento" rifle with name 'detector' 'sensor' 'localizador' 'dispositivo', adjectives 'movimiento', description "Es un dispositivo que detecta la distancia y dirección a la que se encuentra un objeto móvil. Tiene un alcance de unos 50 metros, y está programado para percibir objetos grandes o voluminosos, para así evitar falsos positivos.", ! El pitido que está sonando por el detector. Se usa para que evitar el feo efecto ! de que se detiene y vuelve a sonar el mismo sonido que antes (ver "presencia" ! un poco más abajo): ! esta_sonando null, before [; Examine: print (string) self.description; if (self hasnt on) { " Está apagado."; } else { " Está encendido."; } SwitchOff: if (jason.sacado() || alien.comportamiento >= 1) { if (jason in LugarReal()) { jason.decir = false; HablaJason("¿Está loco? Ese aparato es lo único que nos puede ayudar a mantenernos con vida. ¿Y quiere apagarlo?"); rtrue; } else { "Dada la situación, desactivarlo no parece lo más sensato."; } } ], primera_vez true, presencia [ t; if (deadflag ~= 0) { rtrue; } if (self hasnt on) { ControlTimer.PrepararImpresion(); print "Está apagado."; rtrue; } if (alien has absent) { if (Damusix.SonandoDeFondoCanal(CANAL_DETECTOR)) { Damusix.PararCanal(CANAL_DETECTOR); } rtrue; } ! Aquí se calcula la distancia del alien al detector. Se crea una ruta de persecución ! hasta el objetivo (el detector), y se copia en la propiedad distancia la longitud ! del camino que ha calculado PNJ_Ruta. move testigo to parent(alien); PNJ_Ruta(testigo, MOVIMIENTO_PERSEGUIR, parent(rifle)); alien.distancia = testigo.longitud_precamino; alien.sentido = testigo.sentido; PNJ_Ruta(testigo, MOVIMIENTO_NINGUNO); remove testigo; t = false; if ((~~(self.primera_vez)) && alien.comportamiento == 3 && alien.distancia > 0 && alien.distancia < 6 && alien hasnt absent && alien notin LugarReal()) { ControlTimer.PrepararImpresion(); switch (random(2)) { 1: print "^¡", (The) alien, " se está acercando! ¡Corre!^"; 2: print "^¡", (The) alien, " se acerca!^"; } } ! El detector empieza a funcionar después de que el alien se haya llevado a Jason if (alien.comportamiento > 0) { self.sonar(); if (alien in LugarReal()) { if (location == thedark) { ControlTimer.PrepararImpresion(); t = true; print (s_b) "^¡El detector capta movimiento aquí mismo!^"; } } else { if (alien.distancia > 0 && alien.distancia < 6 && alien hasnt absent) { if (self.primera_vez || ~~hayTiempoReal) { ControlTimer.PrepararImpresion(); t = true; print "^El detector capta movimiento a una distancia de ", (number) 10 * alien.distancia, " metros hacia ", (the) alien.sentido; if (alien.comportamiento == 3) { t = true; print ", ¡Y ACERCÁNDOSE!"; } else { t = true; print "."; } } } } if (t) { if (self.primera_vez && hayTiempoReal) { self.primera_vez = false; print (s_em) " [A partir de ahora, el detector de movimiento informará de la presencia de la criatura a través de la barra de estado, en la parte superior derecha, junto al contador de turnos. Por tanto, no volverás a ver mensajes de este tipo en lo sucesivo. Un consejo: consulta frecuentemente dicha información para intentar evitar a la criatura.]^"; if (OffersLight(location)) { viewImageCenter(location.sgw_img); } barra_estado.dibujar(); } else { print "^"; } } } ], after [; SwitchOn: give self on; if (rifle in jason) { jason.decir = false; HablaJason("Déjeme hacerlo a mí..."); "^Jason enciende el detector de movimiento."; } SwitchOff: give self ~on; Damusix.PararCanal(CANAL_DETECTOR); if (rifle in jason) { jason.decir = false; HablaJason("Déjeme hacerlo a mí..."); "^Jason apaga el detector de movimiento."; } ], tocar [ s v; v = Damusix.QueVolumenCanal(CANAL_DETECTOR); Damusix.AsignarCanal(s, CANAL_DETECTOR, v, SONIDO_BUCLE_INFINITO); Damusix.Tocar(s); ], sonar [ s; if (Damusix.SonandoDeFondo(Sirena_ogg)) { rfalse; } if (alien in LugarReal()) { if (Damusix.SonandoDeFondo(Detector5_ogg) == 0) { self.Tocar(Detector5_ogg); } } else { if (alien.distancia > 0 && alien.distancia < 6 && alien hasnt absent) { switch (alien.distancia) { 5: s = Detector1_ogg; 4: s = Detector2_ogg; 3: s = Detector3_ogg; 2: s = Detector4_ogg; 1: s = Detector5_ogg; } if (Damusix.SonandoDeFondo(s) == 0) { self.Tocar(s); } } else { Damusix.PararCanal(CANAL_DETECTOR); } } ], ! Imprimir en cada turno la distancia al alien each_turn [; if (rifle in player && self has on) { self.presencia(); } ], has switchable; Object comunicador "comunicador" selfobj with name 'comunicador' 'intercomunicador' 'transmisor', description "El comunicador permite ponerte en contacto directamente con Jason y Madre. De esta forma, podrás hablar con ellos y oírles aunque no os encontréis cerca uno del otro. Lo llevas acoplado a tu pabellón auditivo.", before [; Drop, Disrobe: "No sería conveniente perder el contacto con Jason o la nave."; ], invent [; if (inventory_stage == 2) { if (self has worn) { print " (acoplado a tu oído)"; } rtrue; } ], has worn; ! ==================================================================== ! ! OTROS OBJETOS ! ! ==================================================================== ! Móvil "especial" creado para calcular la distancia y posición a la que se encuentra ! el alien. Se usa en la rutina "presencia" del detector de movimiento: Object testigo "testigo" class Movil; Object rastro_acido "rastro de ácido" class TipoRastro with adjectives 'acido' 'verde', nombre_plural "rastros de ácido", visto_en_exterior false, visto_en_interior false, description [; if (EsExterior(parent(self))) { if (self.visto_en_exterior) { print "Es el rastro de ácido corrosivo que ya viste antes. "; } else { self.visto_en_exterior = true; print "Son agujeros profundos en la tierra, unos grandes y otros pequeños, formados por algún tipo de sustancia líquida corrosiva. "; } } else { if (self.visto_en_interior) { print "Son las gotas de sangre ácida que ya viste antes. "; } else { self.visto_en_interior = true; print "Si no fuese imposible, dirías que esas salpicaduras de ácido corrosivo aparentan ser manchas de sangre verde. Las gotas agujerean el suelo a enorme profundidad. "; } } ], initial [ contador padre number; padre = parent(self); if ((padre) && (padre ofclass LugarConRastro)) { number = padre.numeroClase(self, nivelPerceptible); } else { number = 0; } if (number == 0) { "Ves un rastro muy difuso de algo verde en el suelo."; } print "Ves un rastro de ácido verde en el suelo que "; for (contador = 0 : contador < 8 : contador++) { ! Miramos la 'intensidad' para buscar una que sea cero if ((padre.&rastros-->(2 + contador * 5) == self) && (padre.&rastros-->(3 + contador * 5) >= nivelPerceptible)) { if (padre.&rastros-->(4 + contador * 5) ~= 0) print "proviene"; else print "se dirige"; self.describeRastro(padre.&rastros-->(0 + contador * 5), ! origen padre.&rastros-->(1 + contador * 5), ! direccion padre.&rastros-->(3 + contador * 5), ! intensidad padre.&rastros-->(4 + contador * 5)); ! otra_direccion print ".^"; } } ], multDisipacion 0, ! Un rastro de ácido no se debería disipar nunca before [; Touch, Taste, Eat, Take: "Yo que tú no lo haría... Es evidente que esa sustancia es altamente corrosiva."; ]; ! Hace falta un objeto rastreable, así que creo uno "vacío": Object cable_rastreable class ObjetoRastreable; ! El atributo general indica si es la primera vez que se examina class RastroCable class TipoRastro with name 'cable' 'cables//p', color "", sala_origen "", nombre_plural "cables", list_together "cables", description [; print "Es un cable ", (string) self.color, " del que no te habías percatado antes, pues va semioculto por la parte superior de la pared. "; if (parent(self) == oficina or laboratorio) { print "Sale de detrás de la cámara de seguridad. "; } else { if (camara_seguridad.visto_en_oficina || camara_seguridad.visto_en_laboratorio) { print "Sin duda es el cable que sale de la cámara de seguridad ", (string) self.sala_origen, ". "; } else { print "Sin duda es el cable que sale de la consola que hay en la sala de seguridad. "; } } ], before [; Take, Touch: "No alcanzas. Está muy alto."; ], describeRastro [ origen direccion intensidad otra_direccion; origen = origen + intensidad; ! Evita un warning if (otra_direccion ~= 0) { print " desde ", (the) direccion, " ", (al) otra_direccion; } else { print " hacia ", (the) direccion; } ], multDisipacion 0; ! No se disipa nunca Object rastro_cable_blanco "cable blanco" class RastroCable with adjectives 'blanco', color "blanco", sala_origen "de la oficina", encontrado false, describe [; if (rastro_cable_negro notin parent(self)) { if (self hasnt general) { give self general; "^Un cable (que no habías apreciado hasta ahora) te llama la atención en la parte superior de la pared."; } else { "^Mirando hacia arriba aprecias un cable ", (string) self.color, " cruzando la pared."; } } else { "^Mirando hacia arriba aprecias dos cables (uno blanco y otro negro) cruzando juntos la pared."; } ]; Object rastro_cable_negro "cable negro" class RastroCable with adjectives 'negro', color "negro", sala_origen "del laboratorio", encontrado false, describe [; if (rastro_cable_blanco notin parent(self)) { if (self hasnt general) { give self general; "^Un cable (que no habías apreciado hasta ahora) te llama la atención en la parte superior de la pared."; } else { "^Mirando hacia arriba aprecias un cable ", (string) self.color, " cruzando la pared."; } } else { rtrue; } ]; Object tuberias "tuberías" with name 'tuberias' 'tuberia' 'estructuras' 'estructura' 'techo', description "No son más que eso: tuberías que cruzan el techo y las paredes de un lado a otro.", found_in [ l; l = LugarReal(); return (~~(EsExterior(l))) && (~~(l == ventilacion1 or hueco_techo)); ], has scenery; Object autodestruccion with tiempo 50, falta [ t; if (t ~= 0) { if (self hasnt general) { return t * 10 / 50; } else { return t; } } else { if (self hasnt general) { return self.tiempo * 10 / 50; } else { return self.tiempo; } } ], falta_en_barra 0, daemon [; self.cuenta_atras(); ], cuenta_atras [ t; if (self.tiempo > 0) { if (self hasnt general) { t = self.falta(); if (self.falta(self.tiempo - 1) ~= t) { if (t > 0) { ControlTimer.PrepararImpresion(); print (s_b) "^MEGAFONÍA: ", "~Falta"; if (t > 1) { print "n"; } print " ", t, " minuto"; if (t > 1) { print "s"; } print " para la autodestrucción.~^"; self.falta_en_barra = t; barra_estado.dibujar(); } } if (t == 0 && self hasnt general) { give self general; self.tiempo = 60; } } else { t = self.falta(); ControlTimer.PrepararImpresion(); print (s_b) "^MEGAFONÍA: ", "~Falta"; if (t > 1) { print "n"; } print " ", t, " segundo"; if (t > 1) { print "s"; } print " para la autodestrucción.~^"; self.falta_en_barra = t; barra_estado.dibujar(); } self.tiempo--; } else { Bandera_Fin(1); Damusix.TocarV(Explosion_ogg); ControlTimer.PrepararImpresion(); "^El complejo estalla en una gigantesca explosión, llevándose consigo todo lo que había en su interior y alrededores... incluyéndote a ti.^"; } ]; ! Para que el sacador de aliens funcione también en la oscuridad, tengo que ! crear este objeto y meterlo en la localidad laoscuridad: Object sacador_de_aliens_oscuridad thedark with each_turn [; if (alien.comportamiento == 1) { sacador_de_aliens.each_turn(); } ], has concealed; ! El objeto que se encarga de sacar y meter al alien en el juego, de forma aleatoria, ! simulando el hecho de que se mete por las tuberías de los túneles. ! Cuando el alien está en el juego, ~general. Cuando está fuera, general. Object sacador_de_aliens with agujero, found_in [; return alien.comportamiento == 1; ], max_laberintos 0, time_left 0, time_out [; if (alien.comportamiento ~= 1) { rfalse; } if (self hasnt general) { ! Si está dentro del juego: if (parent(alien) ofclass Laberinto && ! Y está en un túnel y no nos persigue: (~~(alien.tipo_de_movimiento == MOVIMIENTO_PERSEGUIR && alien.perseguido == player))) { self.sacar_alien(); } else { StartTimer(self, 1); ! Lo intentamos en el próximo turno rfalse; } } else { self.meter_alien(); } self.time_left = 0; ], sacar_alien [; if (self has general) { rfalse; } ! Sacamos al alien del juego give self general; alien.llega_por = 0; self.agujero = parent(alien); remove alien; give alien absent; if (LugarReal() == self.agujero) { "^¡Ves que el monstruo se mete de repente entre los tubos de la pared y desaparece!"; } else { if (Damusix.SonandoDeFondoCanal(CANAL_DETECTOR)) { print "^De repente, el detector de movimiento enmudece... ¡Aquello que estaba detectando ha desaparecido!^"; if (jason in LugarReal() && random(100) < 50) { jason.decir = false; HablaJason("¿Qué pasa? ¿Dónde se ha metido?"); } rtrue; } } ], meter_alien [ s; if (self hasnt general) { rfalse; } give self ~general; ! Volvemos a meter al alien en el juego, pero en un túnel aleatorio: give alien ~absent; alien.llega_por = 0; s = self.seleccionar_salida(); move alien to s; ! antes era self.agujero if (LugarReal() == s) { alien.callado = true; alien.time_left = 0; alien.oportunidad = 1; "^¡El monstruo aparece de repente entre los tubos y estructuras de la pared!"; } ], each_turn [; ! Si hay que volver a arrancar el reloj, lo activamos con más o menos tiempo ! dependiendo de si hay que sacar al alien o meterlo: if (self.time_left == 0) { ! Antes < 0 if (self hasnt general) { StartTimer(self, 7 + random(10)); } else { StartTimer(self, 10 + random(10)); } } ], calcular_max_laberintos [ i o; i = 0; objectloop (o ofclass Laberinto) { i++; } self.max_laberintos = i; ], seleccionar_salida [ o n i; ! Selecciona un túnel al azar: n = random(self.max_laberintos); i = 1; objectloop (o ofclass Laberinto) { if (i == n) { return o; } else { i++; } } return o; ], has concealed; Object ruido_puerta_rota with time_left, time_out [; Damusix.TocarV(Rotura_ogg); "^¡Se oye un ruido terrible! Un estruendoso crujir y chirriar de metales rompiéndose y doblándose. El sonido proviene de la puerta del complejo."; ]; Class MiTeletipo class Teletipo, with gancho_antes [; Damusix.TocarCanal(CANAL_TELETIPO); ], gancho_despues [; Damusix.PararCanal(CANAL_TELETIPO); ]; Object tt_inicial1 class MiTeletipo private sonido 1, PausaMensaje 250, elementos "> Aproximación a planeta 2003 UB313...^" POR_LETRA LETRA_FIJA PAUSA_NORMAL "^> Atmósfera irrespirable... Posible daño en el procesador atmosférico...^" POR_LETRA LETRA_FIJA PAUSA_DOBLE "^El objetivo de la misión está bien claro:^" POR_MENSAJE LETRA_CURSIVA PAUSA_NORMAL "^~Elaborar un informe completo de la situación.~^" POR_MENSAJE LETRA_NEGRITA SIN_PAUSA; Object tt_inicial2 class MiTeletipo private sonido 1, PausaMensaje 500, elementos "^~Desde hace casi tres años, el Gobierno ha estado utilizando una rica mina de Vibrantium en el planeta 2003 UB313, pero llevamos quince días sin tener noticias de la colonia minera situada en el planeta.~^" POR_MENSAJE LETRA_NEGRITA PAUSA_DOBLE "^(¿Intereses comerciales? ¿Militares? ¿Ambas cosas?)^" POR_MENSAJE LETRA_CURSIVA PAUSA_DOBLE "^~Deberá partir inmediatamente a dicho planeta para hacer un informe de campo sobre la situación y restablecer las comunicaciones con la colonia. Para esta tarea, que no debería resultar peligrosa, le acompañará el Mayor Jason, un experto marine estelar que llevará consigo su equipo habitual de combate y dispondrá de pleno apoyo logístico para que le ayude en su misión.^" POR_MENSAJE LETRA_NEGRITA 5 "^Le serán enviados más datos cuando se estime oportuno.~^" POR_MENSAJE LETRA_NEGRITA SIN_PAUSA; Object tt_inicial3 class MiTeletipo private sonido 1, PausaMensaje 500, elementos "^(Estupendo: La misión no es peligrosa, pero me asignan a todo un experto marine.)^" POR_MENSAJE LETRA_CURSIVA PAUSA_NORMAL "^> Los sensores biométricos no detectan presencia de" POR_LETRA LETRA_FIJA SIN_PAUSA "^ vida orgánica evidente en la superficie...^" POR_LETRA LETRA_FIJA PAUSA_NORMAL "^~La nave, que estará autogobernada, les dejará en el punto de encuentro establecido junto a los edificios principales de la colonia. El primero de ellos está destinado a la purificación ambiental, mientras que el otro es el complejo principal, construido alrededor de una veta central de mineral.^" POR_MENSAJE LETRA_NEGRITA 5 "^Le serán enviados más datos cuando se estime oportuno.~^" POR_MENSAJE LETRA_NEGRITA SIN_PAUSA; Object tt_inicial4 class MiTeletipo private sonido 1, PausaMensaje 500, elementos "^(El mineral, no hay duda. Nada les corrompe más que el dinero, salvo el poder.)^" POR_MENSAJE LETRA_CURSIVA PAUSA_DOBLE "^~El objetivo de su misión será elaborar un informe detallado de la situación, restablecer las comunicaciones y, en el improbable caso de que no lo consiga, traer consigo algún elemento que permita a la cúpula militar evaluar el estado actual de la colonia.~^" POR_MENSAJE LETRA_NEGRITA PAUSA_TRIPLE "^(¿Por qué me temo que ese ~improbable caso~ será finalmente el más probable?)^" POR_MENSAJE LETRA_CURSIVA SIN_PAUSA; Object tt_inicial5 class MiTeletipo private sonido 1, PausaMensaje 500, elementos "^> Confirmado contacto con la superficie... Maniobra correcta...^" POR_LETRA LETRA_FIJA PAUSA_NORMAL "^La nave se posa suavemente en la superficie, y todo está en silencio.^" POR_MENSAJE LETRA_NORMAL PAUSA_DOBLE "^Demasiado silencio...^" POR_MENSAJE LETRA_CURSIVA SIN_PAUSA; Object tt_escape1 class MiTeletipo private sonido 1, PausaMensaje 500, elementos "Rápidamente, Jason y tú entráis en el ascensor. El marine no pierde un segundo en pulsar el botón del lateral, tras lo cual las puertas del ascensor se cierran y éste empieza a subir lentamente.^" POR_MENSAJE LETRA_NORMAL PAUSA_DOBLE "^La sirena de emergencia sigue sonando con la misma estridencia que antes, y la sensación agobiante de estar encerrados en una pequeña cabina apenas es un ligero inconveniente frente a la idea de saber que estáis escapando de una muerte segura.^" POR_MENSAJE LETRA_NORMAL PAUSA_DOBLE "^JASON: ~¿Por qué no sube más deprisa este cacharro?~^" POR_MENSAJE LETRA_NEGRITA PAUSA_DOBLE "^Os miráis por unos segundos, y ambos observáis la misma expresión de alarma en vuestros rostros. Algo ocurre, sin duda. Y como si una misteriosa fuerza invisible os empujara, os acercáis al borde del ascensor, miráis hacia abajo y...^" POR_MENSAJE LETRA_NORMAL PAUSA_DOBLE "^¡AHÍ ESTÁ LA CRIATURA!^" POR_MENSAJE LETRA_NEGRITA PAUSA_DOBLE "^El monstruoso ser se encuentra agarrado a la estructura inferior del ascensor. Lo véis colgando de un brazo, mientras que el otro lo agita salvajemente contra la puerta del habitáculo. Casi podrías decir que ¡está sonriendo! Una sonrisa malévola, casi obscena, una sonrisa que anuncia dolor e inhumanidad.^" POR_MENSAJE LETRA_NORMAL PAUSA_DOBLE "^El ascensor sigue subiendo renqueante, lentamente, casi con dolor, mientras trata de luchar contra el enorme peso de ese monstruo. Los sonidos lastimeros de sus motores y mecanismos os dicen que su estructura no resistirá mucho así.^" POR_MENSAJE LETRA_NORMAL PAUSA_DOBLE "^Y con convicción y decisión supremas, le pides a Jason que abra el ascensor. Al principio parece congelado, bloqueado... Pero finalmente reacciona. Sabe que es la única oportunidad que tenéis de salir vivos. Pulsa el botón de apertura justo en el momento en el que el ser intenta trepar.^" POR_MENSAJE LETRA_NORMAL PAUSA_DOBLE "^Las puertas se abren, ¡y en ese momento el monstruo pone su otra mano dentro del ascensor!^" POR_MENSAJE LETRA_NEGRITA PAUSA_NORMAL; Object tt_escape2 class MiTeletipo private sonido 1, PausaMensaje 500, elementos "^No hay vuelta atrás, ni segundas oportunidades. Das la vuelta al rifle... ¡y golpeas la mano del monstruo con la culata! Un grito desgarrador sale de su enorme boca abierta, transformando su risa en dolor. Momento que aprovecha Jason para patear su cabeza... ¡y lanzarlo al vacío!^" POR_MENSAJE LETRA_NORMAL PAUSA_DOBLE "^El ascensor, ahora sí, va adquiriendo velocidad, subiendo más y más deprisa. Cierras la puerta y te agarras a donde puedes. Jason hace lo mismo, mientras el ascensor sube y sube hasta que...^" POR_MENSAJE LETRA_NORMAL PAUSA_NORMAL "^... emergéis del suelo, fuera del edificio de la colonia. Salís enseguida del habitáculo, casi sin creerlo... ¡Estáis vivos!^" POR_MENSAJE LETRA_NORMAL ESPERAR_TECLA; Object tt_final class MiTeletipo private sonido 1, PausaMensaje 500, elementos "^Ordenas a Madre, jadeando y casi sin aliento, que despegue inmediatamente la aeronave. El rugido de sus potentes motores suena a música en tus oídos, y podrías decir que percibes en tu piel el momento exacto en el que el tren de aterrizaje deja de tener contacto con la superficie del planeta.^" POR_MENSAJE LETRA_NORMAL PAUSA_DOBLE "^Desde el aire, ya a salvo, ves y oyes la explosión que destruye por completo el complejo y su terrible inquilino.^" POR_MENSAJE LETRA_NORMAL PAUSA_DOBLE "^(Al menos, eso esperas...)^" POR_MENSAJE LETRA_NORMAL PAUSA_DOBLE "^~Jason, ¿estás bien?~^" POR_MENSAJE LETRA_CURSIVA PAUSA_DOBLE "^~¿Jason?~^" POR_MENSAJE LETRA_CURSIVA PAUSA_DOBLE "^~¡¿JASON?!~^" POR_MENSAJE LETRA_INVERSA PAUSA_DOBLE "^Y el grito de dolor inenarrable proveniente de la garganta del marine coincide en el tiempo con el crujido de sus costillas al romperse...^" POR_MENSAJE LETRA_NORMAL ESPERAR_TECLA; ! ==================================================================== ! ! RUTINAS ! ! ==================================================================== [ QuitarAcentos buffer parse x i word at len; for (x = 0: x < parse-->0: x++) { ! para cada palabra word = parse-->(x * 3 + 1); at = parse-->(x * 3 + 3); len = parse-->(x * 3 + 2); if (word == 0) { ! no comprendida for (i = at: i < at + len: i++) ! [080625] Quitados caracteres en mayúscula switch(buffer->i) { 225: buffer->i = 'a'; ! 225: á 233: buffer->i = 'e'; ! 233: é 237: buffer->i = 'i'; ! 237: í 243: buffer->i = 'o'; ! 243: ó 250, 252: buffer->i = 'u'; ! 250: ú, 252: ü 241: buffer->i = 'n'; ! 241: ñ '?': buffer->i = ' '; 191: buffer->i = ' '; '!': buffer->i = ' '; 161: buffer->i = ' ' ; } Tokenise__(buffer, parse); } } ]; [ IniciarGraficosSonidos; if (~~testGraphics()) { print "^Lo sentimos, pero este juego necesita un intérprete Glulx con capacidades gráficas.^^"; RecomiendaGargoyle(); } if (Damusix.TestAudio() == 0) { print "^Lo sentimos, pero este juego necesita un intérprete Glulx que pueda reproducir sonido.^^"; RecomiendaGargoyle(); } if (glk_gestalt(gestalt_Timer,0) == 0) { print "^Lo sentimos, pero este juego necesita un intérprete Glulx que tenga soporte para eventos temporizados.^^"; RecomiendaGargoyle(); } ! Inicialización sonora IniciarSonidos(); ! Inicialización gráfica initializeSGW(altoVentanaGrafica); ]; [ IniciarAventura logo v; location = thedark; dibujarEstado = false; ! Esto es para que el juego dé siempre la descripción de la habitación, aunque ! ya la hayamos visitado lookmode = 2; ! Inventario en una sola frase inventory_style = ENGLISH_BIT + RECURSE_BIT + FULLINV_BIT; ! Usamos un parser más "tonto": ! parser_listo = 0; ! Parseado estricto: parseado_estricto = 1; ! Nombre de la oscuridad thedark.short_name = "Zona de oscuridad"; ! Calcular número total de laberintos: sacador_de_aliens.calcular_max_laberintos(); ! Localización donde comienza el jugador location = nave1; clearTextWindow(); PNJ_Ruta(jason, MOVIMIENTO_PERSEGUIR, player); PNJ_Ruta(alien, MOVIMIENTO_NINGUNO); PNJ_Ruta(testigo, MOVIMIENTO_NINGUNO); IniciarMoviles(); IniciarPuertas(); IniciarRastros(); v = Damusix.QueVolumenCanal(CANAL_FONDO); Damusix.AsignarCanal(location.sgw_mus, CANAL_FONDO, v, SONIDO_BUCLE_INFINITO); Damusix.TocarCanal(CANAL_FONDO); if (logo) { clearGraphicWindow(); DibujaLogoAlien(); } print "Copyright (c) 2008-2018 Alpha Aventuras"; KeyDelay(); clearMainWindow(); ! Desde el primer momento, dibujamos la primera pantalla y activamos el timer: viewImageCenter(Nave1_jpg); ! timer_espera_trueno.AgregarGestor(); timer_trueno.AgregarGestor(); timer_alien.AgregarGestor(); timer_laberinto.AgregarGestor(); timer_bateria.AgregarGestor(); timer_autodestruccion.AgregarGestor(); ControlTimer.ActivarTick(TIMER_TICK); ]; [ RecomiendaGargoyle; print "~A·L·I·E·N: La aventura - Edición Especial~ ha sido diseñada para funcionar con el intérprete Gargoyle, que puedes descargar de la siguiente dirección:^^", (s_pre) "http://code.google.com/p/garglk/downloads^"; KeyDelay(); quit; ]; ! Rutina principal y obligatoria de todo juego InformATE [ Initialise r v; if (KeyDelay(30)) { hayTeletipo = false; }; IniciarGraficosSonidos(); openGraphicWindow(250); clearGraphicWindow(); barra_estado.numero_lineas = 23; barra_estado.dibujar(); clearMainWindow(); viewImageCenter(Logo_Alpha_Aventuras_Corto_jpg); v = Damusix.QueVolumenCanal(CANAL_FONDO); Damusix.AsignarCanal(Estancia_ogg, CANAL_FONDO, v, SONIDO_BUCLE_INFINITO); Damusix.Tocar(Estancia_ogg); ZIPI_Intro(); .Menu; r = ZIPI_RunMenu(ZIPI_Menu_Principal, true); if (r == 3) jump Menu; if (r ~= 2) quit; barra_estado.numero_lineas = 1; barra_estado.dibujar(); if (hayGraficos) EncenderGraficosSub(true); else ApagarGraficosSub(true); clearTextWindow(); ]; [ ZIPI_RunOtro _o r; ZIPI_PintaTitulo(_o.ZIPI_titulo); print "^"; r = _o.ZIPI_ejecutar(); if (~~r) ZIPI_Espera(); return r; ]; [ ZIPI_RunMenu _m top i j count cur key target redibujar ft r; redibujar = 1; cur = 0; count = _m.#ZIPI_item / WORDSIZE; count = count + 2; ft = true; for (::) { if (redibujar) { ZIPI_PintaTitulo(_m.ZIPI_titulo); redibujar = 0; } for (i = 0: i < count - 2: i++) { j = i + 3; ZIPI_setcursor(5,j); if (ft && hayTeletipo) { tt_computadora.visualiza((_m.&ZIPI_item-->i).ZIPI_titulo); } else { style fixed; if ((_m.&ZIPI_item-->i).ZIPI_titulo ofclass Routine) (_m.&ZIPI_item-->i).ZIPI_titulo(); else print (string)(_m.&ZIPI_item-->i).ZIPI_titulo; style roman; } } j = i + 4; ZIPI_setcursor(5,j); if (ft) { if (top) { tt_computadora.visualiza("Salir"); } else { tt_computadora.visualiza("Volver"); } } else { if (top) { print (s_pre) "Salir"; } else { print (s_pre) "Volver"; } } ft = false; j = cur + 3; ZIPI_setcursor(2, j); print ">"; ZIPI_setcursor(2, j); key = ZIPI_tecla(); print " "; if (key > ZIPI_EVENTO_HYPER) { cur = key - ZIPI_EVENTO_HYPER - 2; if (cur == -1) key = 27; else key = 13; } switch(key) { 'k', 'p', '-', '_', 129, -4: do { cur--; if (cur == count - 2) cur--; if (cur < 0) cur = count - 1; } until ((_m.&ZIPI_item-->cur) ~= ZIPI_Separador); break; 'j', 'n', '=', '+', 130, -5: do { cur++; if (cur == count - 2) cur++; if (cur >= count) cur = 0; } until ((_m.&ZIPI_item-->cur) ~= ZIPI_Separador); break; 'q', 'Q', 27, 131, 10, 8, -2: rfalse; 132, 13, 'n', ' ', -3, -6: if (cur == count - 1) rfalse; if (cur == count - 2) break; target = _m.&ZIPI_item-->cur; if (target ofclass ZIPI_Menu) ZIPI_RunMenu(target); else if (target ofclass ZIPI_Pista) ZIPI_RunPista(target); else if (target provides ZIPI_cambiar) target.ZIPI_cambiar(); else { r = ZIPI_RunOtro(target); if (target == ZIPI_Restaurar) return 3; if (r == 2) return r; } redibujar = 1; break; } } rfalse; ]; ZIPI_Menu ZIPI_Menu_Principal with ZIPI_titulo "A·L·I·E·N: La aventura - Edición Especial", ZIPI_item ZIPI_Jugar_Con_Intro ZIPI_Jugar_Sin_Intro ZIPI_Restaurar ZIPI_Configuracion ZIPI_Separador ZIPI_Menu1; ZIPI_Menu ZIPI_Configuracion with ZIPI_titulo "Opciones de gráficos y sonido", ZIPI_item ZIPI_Graficos ZIPI_Tamano_Graficos ZIPI_Sonido ZIPI_Sonido_Fondo ZIPI_Sonido_Detector ZIPI_Separador ZIPI_Accesibilidad; ZIPI_Otro ZIPI_Graficos with ZIPI_titulo [; if (hayGraficos) { "Gráficos: SÍ (recomendado)"; } else { "Gráficos: NO"; } ], ZIPI_cambiar [; hayGraficos = ~~hayGraficos; ], ZIPI_ejecutar [; rtrue; ]; ZIPI_Otro ZIPI_Tamano_Graficos with ZIPI_titulo [; switch (altoVentanaGrafica) { GRAFICOS_MINUSCULOS: "Tamaño de gráficos: ", GRAFICOS_MINUSCULOS, " px. (MINÚSCULOS)"; GRAFICOS_PEQUENOS: "Tamaño de gráficos: ", GRAFICOS_PEQUENOS, " px. (PEQUEÑOS)"; GRAFICOS_MEDIANOS: "Tamaño de gráficos: ", GRAFICOS_MEDIANOS, " px. (MEDIANOS, recomendado)"; GRAFICOS_GRANDES: "Tamaño de gráficos: ", GRAFICOS_GRANDES, " px. (GRANDES)"; default: "Tamaño de gráficos: ", altoVentanaGrafica, " px."; } ], ZIPI_cambiar [; if (altoVentanaGrafica < GRAFICOS_GRANDES) { altoVentanaGrafica = altoVentanaGrafica + 50; } else { altoVentanaGrafica = GRAFICOS_MINUSCULOS; } ], ZIPI_ejecutar [; rtrue; ]; ZIPI_Otro ZIPI_Sonido with ZIPI_titulo [; if (haySonido) { "Sonido global: SÍ (recomendado)"; } else { "Sonido global: NO"; } ], ZIPI_cambiar [; haySonido = ~~haySonido; if (haySonido) { Damusix.ActivarAudio(); } else { Damusix.DesactivarAudio(); } ], ZIPI_ejecutar [; rtrue; ]; ZIPI_Otro ZIPI_Sonido_Fondo with ZIPI_titulo [; if (haySonidoFondo) { "Sonido de fondo: SÍ (recomendado)"; } else { "Sonido de fondo: NO"; } ], ZIPI_cambiar [; haySonidoFondo = ~~haySonidoFondo; if (haySonidoFondo) { Damusix.VolumenCanal(CANAL_FONDO, VOLUMEN_FONDO); } else { Damusix.VolumenCanal(CANAL_FONDO, 0); } ], ZIPI_ejecutar [; rtrue; ]; ZIPI_Otro ZIPI_Sonido_Detector with ZIPI_titulo [; if (haySonidoDetector) { "Sonido del detector: SÍ (recomendado)"; } else { "Sonido del detector: NO"; } ], ZIPI_cambiar [; haySonidoDetector = ~~haySonidoDetector; if (haySonidoDetector) { Damusix.VolumenCanal(CANAL_DETECTOR, VOLUMEN_DETECTOR); } else { Damusix.VolumenCanal(CANAL_DETECTOR, 0); } ], ZIPI_ejecutar [; rtrue; ]; ZIPI_Menu ZIPI_Accesibilidad with ZIPI_titulo "Opciones de accesibilidad", ZIPI_item ZIPI_Efecto_Teletipo ZIPI_Tiempo_Real; ZIPI_Otro ZIPI_Efecto_Teletipo with ZIPI_titulo [; if (hayTeletipo) { "Efecto teletipo: SÍ (recomendado)"; } else { "Efecto teletipo: NO"; } ], ZIPI_cambiar [; hayTeletipo = ~~hayTeletipo; ], ZIPI_ejecutar [; rtrue; ]; ZIPI_Otro ZIPI_Tiempo_Real with ZIPI_titulo [; if (hayTiempoReal) { "Tiempo real: SÍ (recomendado)"; } else { "Tiempo real: NO"; } ], ZIPI_cambiar [; hayTiempoReal = ~~hayTiempoReal; ], ZIPI_ejecutar [; rtrue; ]; ZIPI_Otro ZIPI_Jugar_Con_Intro with ZIPI_titulo "Comenzar la aventura con introducción", ZIPI_ejecutar [; StatusLineHeight(1); glk($002A, gg_statuswin); ! window_clear glk($002F, gg_mainwin); ! set_window if (hayGraficos) EncenderGraficosSub(true); else ApagarGraficosSub(true); clearTextWindow(); Introduccion(); IniciarAventura(); dibujarEstado = true; return 2; ]; ZIPI_Otro ZIPI_Jugar_Sin_Intro with ZIPI_titulo "Comenzar la aventura saltando la introducción", ZIPI_ejecutar [; StatusLineHeight(1); glk($002A, gg_statuswin); ! window_clear glk($002F, gg_mainwin); ! set_window if (hayGraficos) EncenderGraficosSub(true); else ApagarGraficosSub(true); clearTextWindow(); IniciarAventura(true); dibujarEstado = true; return 2; ]; ZIPI_Otro ZIPI_Restaurar with ZIPI_titulo "Restaurar una partida guardada", ZIPI_ejecutar [ res fref; StatusLineHeight(1); clearTextWindow(); glk($002F, gg_mainwin); ! set_window ImprimirPrompt(); fref = glk($0062, $01, $02, 0); ! fileref_create_by_prompt if (fref == 0) jump RFailed; gg_savestr = glk($0042, fref, $02, GG_SAVESTR_ROCK); ! stream_open_file glk($0063, fref); ! fileref_destroy if (gg_savestr == 0) jump RFailed; @restore gg_savestr res; glk($0044, gg_savestr, 0); ! stream_close gg_savestr = 0; .RFailed; glk($002F, gg_statuswin); StatusLineHeight(24); tt_computadora.visualiza("^Error: no se ha podido cargar la partida"); rfalse; ]; ZIPI_Otro ZIPI_Salir with ZIPI_titulo "Salir", ZIPI_ejecutar [; quit; ]; [ DibujaLogoAlien i; if (~~hayGraficos) rtrue; for (i = 0 : i < 15 : i++) { viewImageCenter(ALIEN_Sin_Puntos_png, true); KeyDelay(20); } for (i = 0 : i < 15 : i++) { viewImageCenter(Puntos_png, true); KeyDelay(20); } ]; [ IniciarSonidos; Damusix.VolumenCanal(CANAL_FONDO, VOLUMEN_FONDO); Damusix.VolumenCanal(CANAL_DETECTOR, VOLUMEN_DETECTOR); Damusix.AsignarCanal(Teletipo_ogg, CANAL_TELETIPO, VOLUMEN_TELETIPO, SONIDO_BUCLE_INFINITO); Damusix.AsignarCanal(Tic_ogg, CANAL_TICTAC, VOLUMEN_TICTAC, SONIDO_BUCLE_INFINITO); ]; [ InitGlkWindow winrock; switch (winrock) { GG_MAINWIN_ROCK: glk_stylehint_set(wintype_TextBuffer, style_Normal, stylehint_TextColor, $ffffff); glk_stylehint_set(wintype_TextBuffer, style_Normal, stylehint_BackColor, $000000); glk_stylehint_set(wintype_TextBuffer, style_Normal, stylehint_Size, 1); glk_stylehint_set(wintype_TextBuffer, style_Normal, stylehint_Weight, 0); glk_stylehint_set(wintype_TextBuffer, style_Normal, stylehint_Proportional, 1); glk_stylehint_set(wintype_TextBuffer, style_Normal, stylehint_Justification, stylehint_just_LeftRight); glk_stylehint_set(wintype_TextBuffer, style_Input, stylehint_TextColor, $00ff00); glk_stylehint_set(wintype_TextBuffer, style_Input, stylehint_BackColor, $000000); glk_stylehint_set(wintype_TextBuffer, style_Input, stylehint_Size, 1); glk_stylehint_set(wintype_TextBuffer, style_Input, stylehint_Proportional, 0); glk_stylehint_set(wintype_TextBuffer, style_Input, stylehint_Weight, 1); ! Esta será mi negrita: glk_stylehint_set(wintype_TextBuffer, style_User1, stylehint_TextColor, $00ff00); glk_stylehint_set(wintype_TextBuffer, style_User1, stylehint_BackColor, $000000); glk_stylehint_set(wintype_TextBuffer, style_User1, stylehint_Size, 1); glk_stylehint_set(wintype_TextBuffer, style_User1, stylehint_Proportional, 1); glk_stylehint_set(wintype_TextBuffer, style_User1, stylehint_Weight, 1); glk_stylehint_set(wintype_TextBuffer, style_User2, stylehint_TextColor, $000000); glk_stylehint_set(wintype_TextBuffer, style_User2, stylehint_BackColor, $00ff00); glk_stylehint_set(wintype_TextBuffer, style_User2, stylehint_Size, 1); glk_stylehint_set(wintype_TextBuffer, style_User2, stylehint_Proportional, 0); glk_stylehint_set(wintype_TextBuffer, style_User2, stylehint_Weight, 1); glk_stylehint_set(wintype_TextBuffer, style_Alert, stylehint_TextColor, $00ff00); glk_stylehint_set(wintype_TextBuffer, style_Alert, stylehint_BackColor, $000000); glk_stylehint_set(wintype_TextBuffer, style_Alert, stylehint_Size, 1); glk_stylehint_set(wintype_TextBuffer, style_Alert, stylehint_Proportional, 1); glk_stylehint_set(wintype_TextBuffer, style_Alert, stylehint_Oblique, 1); glk_stylehint_set(wintype_TextBuffer, style_Alert, stylehint_Weight, 1); glk_stylehint_set(wintype_TextBuffer, style_Emphasized, stylehint_TextColor, $ffffff); glk_stylehint_set(wintype_TextBuffer, style_Emphasized, stylehint_BackColor, $000000); glk_stylehint_set(wintype_TextBuffer, style_Emphasized, stylehint_Size, 1); glk_stylehint_set(wintype_TextBuffer, style_Emphasized, stylehint_Proportional, 1); glk_stylehint_set(wintype_TextBuffer, style_Emphasized, stylehint_Oblique, 1); glk_stylehint_set(wintype_TextBuffer, style_Emphasized, stylehint_Weight, 1); glk_stylehint_set(wintype_TextBuffer, style_Preformatted, stylehint_TextColor, $00aa00); glk_stylehint_set(wintype_TextBuffer, style_Preformatted, stylehint_BackColor, $000000); glk_stylehint_set(wintype_TextBuffer, style_Preformatted, stylehint_Size, 1); glk_stylehint_set(wintype_TextBuffer, style_Preformatted, stylehint_Proportional, 0); glk_stylehint_set(wintype_TextBuffer, style_Preformatted, stylehint_Weight, 0); glk_stylehint_set(wintype_TextBuffer, style_Header, stylehint_TextColor, $00ff00); glk_stylehint_set(wintype_TextBuffer, style_Header, stylehint_BackColor, $000000); glk_stylehint_set(wintype_TextBuffer, style_Header, stylehint_Size, 1); glk_stylehint_set(wintype_TextBuffer, style_Header, stylehint_Weight, 1); glk_stylehint_set(wintype_TextBuffer, style_Subheader, stylehint_TextColor, $00ff00); glk_stylehint_set(wintype_TextBuffer, style_Subheader, stylehint_BackColor, $000000); glk_stylehint_set(wintype_TextBuffer, style_SubHeader, stylehint_Size, 1); glk_stylehint_set(wintype_TextBuffer, style_SubHeader, stylehint_Weight, 1); glk_stylehint_set(wintype_TextBuffer, style_Note, stylehint_TextColor, $ffffff); glk_stylehint_set(wintype_TextBuffer, style_Note, stylehint_BackColor, $000000); glk_stylehint_set(wintype_TextBuffer, style_BlockQuote, stylehint_TextColor, $000000); glk_stylehint_set(wintype_TextBuffer, style_BlockQuote, stylehint_BackColor, $ffffff); glk_stylehint_set(wintype_TextGrid, style_Normal, stylehint_TextColor, $ffffff); glk_stylehint_set(wintype_TextGrid, style_Normal, stylehint_BackColor, $000000); glk_stylehint_set(wintype_TextGrid, style_Normal, stylehint_Size, 1); glk_stylehint_set(wintype_TextGrid, style_Normal, stylehint_Weight, 0); glk_stylehint_set(wintype_TextGrid, style_Normal, stylehint_Proportional, 0); glk_stylehint_set(wintype_TextGrid, style_Normal, stylehint_Justification, stylehint_just_LeftRight); glk_stylehint_set(wintype_TextGrid, style_Input, stylehint_TextColor, $00ff00); glk_stylehint_set(wintype_TextGrid, style_Input, stylehint_BackColor, $000000); glk_stylehint_set(wintype_TextGrid, style_Input, stylehint_Size, 1); glk_stylehint_set(wintype_TextGrid, style_Input, stylehint_Proportional, 0); glk_stylehint_set(wintype_TextGrid, style_Input, stylehint_Weight, 1); glk_stylehint_set(wintype_TextGrid, style_User1, stylehint_TextColor, $ffffff); glk_stylehint_set(wintype_TextGrid, style_User1, stylehint_BackColor, $000000); glk_stylehint_set(wintype_TextGrid, style_User1, stylehint_Size, 1); glk_stylehint_set(wintype_TextGrid, style_User1, stylehint_Proportional, 0); glk_stylehint_set(wintype_TextGrid, style_User1, stylehint_Weight, 1); glk_stylehint_set(wintype_TextGrid, style_User2, stylehint_TextColor, $000000); glk_stylehint_set(wintype_TextGrid, style_User2, stylehint_BackColor, $00ff00); glk_stylehint_set(wintype_TextGrid, style_User2, stylehint_Size, 1); glk_stylehint_set(wintype_TextGrid, style_User2, stylehint_Proportional, 0); glk_stylehint_set(wintype_TextGrid, style_User2, stylehint_Weight, 1); glk_stylehint_set(wintype_TextGrid, style_Alert, stylehint_TextColor, $ffffff); glk_stylehint_set(wintype_TextGrid, style_Alert, stylehint_BackColor, $000000); glk_stylehint_set(wintype_TextGrid, style_Alert, stylehint_Size, 1); glk_stylehint_set(wintype_TextGrid, style_Alert, stylehint_Proportional, 0); glk_stylehint_set(wintype_TextGrid, style_Alert, stylehint_Oblique, 1); glk_stylehint_set(wintype_TextGrid, style_Alert, stylehint_Weight, 1); glk_stylehint_set(wintype_TextGrid, style_Emphasized, stylehint_TextColor, $ffffff); glk_stylehint_set(wintype_TextGrid, style_Emphasized, stylehint_BackColor, $000000); glk_stylehint_set(wintype_TextGrid, style_Emphasized, stylehint_Size, 1); glk_stylehint_set(wintype_TextGrid, style_Emphasized, stylehint_Proportional, 0); glk_stylehint_set(wintype_TextGrid, style_Emphasized, stylehint_Oblique, 1); glk_stylehint_set(wintype_TextGrid, style_Emphasized, stylehint_Weight, 1); glk_stylehint_set(wintype_TextGrid, style_Emphasized, stylehint_Justification, stylehint_just_LeftRight); glk_stylehint_set(wintype_TextGrid, style_Preformatted, stylehint_TextColor, $00aa00); glk_stylehint_set(wintype_TextGrid, style_Preformatted, stylehint_BackColor, $000000); glk_stylehint_set(wintype_TextGrid, style_Preformatted, stylehint_Size, 1); glk_stylehint_set(wintype_TextGrid, style_Preformatted, stylehint_Proportional, 0); glk_stylehint_set(wintype_TextGrid, style_Preformatted, stylehint_Weight, 1); glk_stylehint_set(wintype_TextGrid, style_Header, stylehint_TextColor, $00ff00); glk_stylehint_set(wintype_TextGrid, style_Header, stylehint_BackColor, $000000); glk_stylehint_set(wintype_TextGrid, style_Header, stylehint_Size, 1); glk_stylehint_set(wintype_TextGrid, style_Header, stylehint_Weight, 1); glk_stylehint_set(wintype_TextGrid, style_Subheader, stylehint_TextColor, $00ff00); glk_stylehint_set(wintype_TextGrid, style_Subheader, stylehint_BackColor, $000000); glk_stylehint_set(wintype_TextGrid, style_SubHeader, stylehint_Size, 1); glk_stylehint_set(wintype_TextGrid, style_SubHeader, stylehint_Weight, 1); glk_stylehint_set(wintype_TextGrid, style_Note, stylehint_TextColor, $ffffff); glk_stylehint_set(wintype_TextGrid, style_Note, stylehint_BackColor, $000000); glk_stylehint_set(wintype_TextGrid, style_BlockQuote, stylehint_TextColor, $000000); glk_stylehint_set(wintype_TextGrid, style_BlockQuote, stylehint_BackColor, $ffffff); } rfalse; ! si te olvidas esta linea, el juego no funcionará bien ]; Object timer_espera_trueno class GestorTimer with duracion TIMER_DURACION_ESPERA_TRUENO, condicion [; return timer_trueno.hay_trueno; ], evento [; timer_trueno.hay_trueno = false; ControlTimer.DesactivarMutex(); self.SustituirGestor(timer_trueno); ControlTimer.ActivarTick(TIMER_TICK); viewImageCenter(LugarReal().sgw_img); rtrue; ! Hace que el resto de los eventos se salten hasta el siguiente tick ]; Object timer_trueno class GestorTimer with duracion TIMER_DURACION_TRUENO, condicion [ l; if (self.hay_trueno) rfalse; l = LugarReal(); return EsExterior(l) || l == nave1 or nave2; ], hay_trueno false, preparar_espera_trueno [; self.SustituirGestor(timer_espera_trueno); ControlTimer.ActivarMutex(timer_espera_trueno); ControlTimer.ActivarTick(100); self.hay_trueno = true; ], evento [ l r p; l = LugarReal(); r = random(100); if (l == nave1 or nave2 && r < 35) { r = 20 * random(5); if (r >= 65) { if (l == nave1) { viewImageCenter(Nave1_Trueno_jpg); } else { viewImageCenter(Nave2_Trueno_jpg); } Damusix.TocarV(Trueno_ogg, random(4) * 4); self.preparar_espera_trueno(); } } else if (EsExterior(l) && r < 38) { r = 20 * random(5); p = 80; if (r >= p) { viewImageCenter(Fondo_Blanco_jpg); } Damusix.TocarV(Trueno_ogg, r); if (r >= p) { self.preparar_espera_trueno(); } } rtrue; ]; Object timer_bateria class GestorTimer with duracion TIMER_DURACION_BATERIA, condicion [; return hayTiempoReal && linterna has on && bateria.energia > 0; ], evento [; bateria.decremento = 2; linterna.pierde_energia(); barra_estado.dibujar(); bateria.decremento = 4; ]; Object timer_laberinto class GestorTimer with duracion TIMER_DURACION_LABERINTO, condicion [ l; l = LugarReal(); return l ofclass Complejo && alien notin l && alien.comportamiento == 1 or 3; ], evento [ l r snd; l = LugarReal(); if (l ofclass Complejo && alien.comportamiento == 1 or 3) { if (l ofclass Laberinto || l ofclass Balcon) { r = 20 * random(3) + 40; switch (random(4)) { 1: snd = Gota_Oscura_ogg; 2: snd = Gotas_Agua_ogg; 3: snd = Cueva_Oscura_ogg; 4: if (alien notin l) { snd = Monstruo_ogg; if (alien.distancia == 0) r = 100; else r = 100 / alien.distancia; } else { snd = Cueva_Oscura_ogg; } } Damusix.TocarV(snd, r); } else if (l ofclass ZonaNorte && hayTiempoReal) { l.each_turn(); } if (~~hayTiempoReal) rtrue; if (alien notin l) { alien.se_ha_movido = false; if (alien.condicion_movimiento()) { alien.movimiento(); } if (alien.se_ha_movido) { detector_movimiento.each_turn(); barra_estado.dibujar(); } } } ]; Object timer_autodestruccion class GestorTimer with duracion TIMER_DURACION_AUTODESTRUCCION, condicion [; return alien.comportamiento == 4 && hayTiempoReal; ], evento [; autodestruccion.cuenta_atras(); ]; Object timer_alien class GestorTimer with duracion TIMER_DURACION_ALIEN, condicion [; return alien in LugarReal() && alien.comportamiento == 1 or 3 && hayTiempoReal; ], evento [; alien.each_turn(); ]; [ ComoHablar; print "[Para hablar con un personaje, usa la forma ~", (s_in) "PERSONAJE, lo que sea", "~. Por ejemplo: ~", (s_in) "JASON, QUÉ OPINAS DE MADRE"; "~.]"; ]; [ AllowPushDir i tmp; if (parent(second) ~= compass) return L__M (##PushDir, 2, noun); if (second == u_obj or d_obj) return L__M (##PushDir, 3, noun); AfterRoutines(); i = noun; move i to player; tmp = location; ! (c) Alpha estoyEmpujando = true; ! (c) Alpha ; estoyEmpujando = false; ! (c) Alpha if (location == thedark) move i to real_location; else move i to location; if (tmp ~= location && location ~= thedark) ! (c) Alpha PrintOrRun(i, describe); ! (c) Alpha ]; [ Introduccion i v; clearMainWindow(); viewImageCenter(Oscuridad_jpg); v = Damusix.QueVolumenCanal(CANAL_FONDO); Damusix.AsignarCanal(Intro_ogg, CANAL_FONDO, v, 1); Damusix.Tocar(Intro_ogg, 1); tt_inicial1.visualiza(); for (i = 0 : i < 15 : i++) { viewImageCenter(A_png, true); KeyDelay(20); } KeyDelay(300); tt_inicial2.visualiza(); for (i = 0 : i < 15 : i++) { viewImageCenter(AI_png, true); KeyDelay(20); } KeyDelay(900); tt_inicial3.visualiza(); for (i = 0 : i < 15 : i++) { viewImageCenter(AIN_png, true); KeyDelay(20); } KeyDelay(900); tt_inicial4.visualiza(); for (i = 0 : i < 15 : i++) { viewImageCenter(AIEN_png, true); KeyDelay(20); } KeyDelay(800); tt_inicial5.visualiza(); KeyDelay(600); DibujaLogoAlien(); if (v ~= 0) { glk($00D6, 500); ! request_timer_events glk($00D2, gg_mainwin); ! glk_request_char_event(gg_mainwin); while (1) { glk($00C0, gg_arguments); ! glk_select(gg_arguments); switch (gg_arguments-->0) { evtype_CharInput: glk($00D3, gg_mainwin); ! cancel_char_event Damusix.SimpleFadeOut(Intro_ogg, 3000); Damusix.PararCanal(CANAL_FONDO); Damusix.VolumenCanal(CANAL_FONDO, v); jump Exit; evtype_Timer: glk($00D6, 500); ! request_timer_events evtype_SoundNotify: glk($00D6, 0); ! request_timer_events jump Exit; } } } .Exit; rfalse; ]; [ DejarRastros t; t = 40; procesador.marcaRastro(alien, rastro_acido, out_obj, t + 20); junto_procesador.marcaRastro(alien, rastro_acido, s_obj, t + 22); exterior1.marcaRastro(alien, rastro_acido, s_obj, t + 24); exterior3.marcaRastro(alien, rastro_acido, e_obj, t + 26); junto_puerta.marcaRastro(alien, rastro_acido, in_obj, t + 28); entrada.marcaRastro(alien, rastro_acido, s_obj, t + 30); balcon1.marcaRastro(alien, rastro_acido, w_obj, t + 32); laberinto1.marcaRastro(alien, rastro_acido, s_obj, t + 34); balcon2.marcaRastro(alien, rastro_acido, s_obj, t + 36); laberinto11.marcaRastro(alien, rastro_acido, e_obj, t + 38); balcon4.marcaRastro(alien, rastro_acido, d_obj, t + 40); balcon8.marcaRastro(alien, rastro_acido, d_obj, t + 42); balcon12.marcaRastro(alien, rastro_acido, e_obj, t + 42); laberinto36.marcaRastro(alien, rastro_acido, u_obj, t + 64); ventilacion1.marcaRastro(alien, rastro_acido, e_obj, t + 66); ! Si no pongo esta última línea, el rastro de ácido no aparecerá en la localidad del ! procesador hasta que salga y vuelva a entrar: move rastro_acido to procesador; ]; ! El cable que sale de la oficina: [ PonerCableBlanco; if (~~(rastro_cable_blanco.encontrado)) { rastro_cable_blanco.encontrado = true; oficina.marcaRastro(cable_rastreable, rastro_cable_blanco, e_obj, nivelClaro, camara_seguridad); balcon2.marcaRastro(cable_rastreable, rastro_cable_blanco, s_obj, nivelClaro, w_obj); laberinto11.marcaRastro(cable_rastreable, rastro_cable_blanco, e_obj, nivelClaro, n_obj); balcon4.marcaRastro(cable_rastreable, rastro_cable_blanco, d_obj, nivelClaro, w_obj); balcon8.marcaRastro(cable_rastreable, rastro_cable_blanco, w_obj, nivelClaro, u_obj); laberinto18.marcaRastro(cable_rastreable, rastro_cable_blanco, s_obj, nivelClaro, e_obj); seguridad.marcaRastro(cable_rastreable, rastro_cable_blanco, consola, nivelClaro, n_obj); } rfalse; ]; ! El cable que sale del laboratorio: [ PonerCableNegro; if (~~(rastro_cable_negro.encontrado)) { rastro_cable_negro.encontrado = true; laboratorio.marcaRastro(cable_rastreable, rastro_cable_negro, n_obj, nivelClaro, camara_seguridad); laberinto19.marcaRastro(cable_rastreable, rastro_cable_negro, w_obj, nivelClaro, s_obj); balcon8.marcaRastro(cable_rastreable, rastro_cable_negro, w_obj, nivelClaro, e_obj); laberinto18.marcaRastro(cable_rastreable, rastro_cable_negro, s_obj, nivelClaro, e_obj); seguridad.marcaRastro(cable_rastreable, rastro_cable_negro, consola, nivelClaro, n_obj); } rfalse; ]; [ HablaJason msg1 obj1 msg2 obj2 msg3 obj3 msg4 l; l = LugarReal(); if (jason in l || (l == hueco_techo && jason in vaina && vaina has open)) { print (s_b) "^JASON: "; } else { Damusix.TocarV(Transmisor_ogg); print (s_b) "^JASON (por el comunicador): "; } print "~", (string) msg1; if (obj1 ~= 0) { if (obj1 == traje_jason && actor == jason) { print "mi traje"; } else { print (the) obj1; } } if (msg2 ~= 0) { print (string) msg2; } if (obj2 ~= 0) { print (o) obj2; } if (msg3 ~= 0) { print (string) msg3; } if (obj3 ~= 0) { print (del) obj3; } if (msg4 ~= 0) { print (string) msg4; } print "~^"; ]; [ HablaRobot msg; robot.ha_hablado = true; Damusix.TocarV(Robot_ogg); print (s_b) "^ROBOT: ", "~", (string) msg, "~^"; ]; Object tt_computadora class MiTeletipo private sonido 1, elementos "" POR_LETRA LETRA_FIJA SIN_PAUSA; [ HablaMadre msg; if (LugarReal() ~= nave1 or nave2) { Damusix.TocarV(Transmisor_ogg); print (s_b) "^MADRE (por el comunicador): "; } else { print (s_b) "^MADRE: "; } print "~"; tt_computadora.visualiza(msg); print "~^"; ]; [ Bandera_Fin bf; Damusix.PararCanal(CANAL_FONDO); Damusix.PararCanal(CANAL_DETECTOR); Damusix.PararCanal(CANAL_SIRENA); ControlTimer.DesactivarTick(); if (bf == 1) { autodestruccion.falta_en_barra = 0; barra_estado.dibujar(); Damusix.TocarV(Grito_Jugador_ogg); } deadflag = bf; rfalse; ]; [ SegundaParte o sig; alien.primera_vez = false; ! A Jason se le cae todo cuando se lo lleva el alien, ! menos el traje: o = child(jason); while (o ~= nothing) { sig = sibling(o); if (o ~= traje_jason) move o to procesador; o = sig; } move jason to vaina; PNJ_Ruta(jason, MOVIMIENTO_NINGUNO); ! Pasa a moverse aleatoriamente después de dejar a Jason en la vaina: alien.comportamiento = 1; move alien to laberinto16; ! El alien empieza a moverse aleatoriamente PNJ_Ruta(alien, MOVIMIENTO_ALEATORIO); ! La puerta ahora está rota puerta_rara.abrir(); junto_puerta.sgw_img = Junto_Puerta_Abierta_jpg; ! give puerta_rara abierta; ! Pero no ya no permite abrirla. Esto se hace para que los PNJ no abran ni cierren la ! puerta cuando la crucen automáticamente. ! give puerta_rara ~abrible; ! Deja los rastros de ácido por el camino hasta la vaina DejarRastros(); ]; [ QuintaParte; remove alien; give alien absent; alien.comportamiento = 4; give ascensor open; Damusix.PararCanal(CANAL_TICTAC); Damusix.AsignarCanal(Sirena_ogg, CANAL_SIRENA, VOLUMEN_SIRENA, SONIDO_BUCLE_INFINITO); Damusix.Tocar(Sirena_ogg); StartDaemon(autodestruccion); PNJ_Ruta(jason, MOVIMIENTO_PERSEGUIR, player); laberinto28.sgw_img = Ascensor_Abierto_jpg; boton_oeste.pulsar = boton_oeste.pulsar_ya_pulsado; boton_oeste.description = boton_oeste.descripcion_ya_pulsado; boton_este.pulsar = boton_este.pulsar_ya_pulsado; boton_este.description = boton_este.descripcion_ya_pulsado; print (s_b) "^¡HAS ACTIVADO EL PROTOCOLO DE AUTODESTRUCCIÓN!^"; ]; ! Rutina para comprobar si una localidad es exterior o interior ! Devuelve true si es exterior [ EsExterior l; ! return l == exterior1 or exterior3 or junto_procesador or junto_puerta; return l ofclass LugarExterior; ]; [ LugarReal; if (location == thedark) { return real_location; } else { return location; } ]; ! El alien ha llegado a bloquear la puerta, y empieza a moverse aleatoriamente: [ AlienBloqueaPuerta; remove puerta_rara; give puerta_rara absent; junto_puerta.in_to = puerta_viscosa; entrada.out_to = puerta_viscosa; puerta_viscosa.in_to = entrada; puerta_viscosa.out_to = junto_puerta; move puerta_viscosa to entrada; IniciarPuertas(); max_longitud_camino = 10; alien.pnj_ha_llegado = alien.pnj_ha_llegado_default; alien.comportamiento = 1; PNJ_Ruta(alien, MOVIMIENTO_ALEATORIO); entrada.sgw_img = Entrada_Sellada_jpg; junto_puerta.sgw_img = Junto_Puerta_Sellada_jpg; if (location == entrada) { viewImageCenter(entrada.sgw_img); } ]; [ s_em text; glk_set_style(style_Emphasized); print (string) text; glk_set_style(style_Normal); ]; [ s_in text; glk_set_style(style_Input); print (string) text; glk_set_style(style_Normal); ]; [ s_pre text; glk_set_style(style_Preformatted); print (string) text; glk_set_style(style_Normal); ]; [ s_b text; glk_set_style(style_User1); print (string) text; glk_set_style(style_Normal); ]; [ EncenderGraficos; hayGraficos = true; openGraphicWindow(altoVentanaGrafica); clearGraphicWindow(); if (location ~= thedark) { if (LugarReal() provides sgw_img) { viewImageCenter(LugarReal().sgw_img); } else { viewImageCenter(Logo_Alpha_Aventuras_jpg); } } ]; ! ==================================================================== ! ! LINEAS DE GRAMATICA ! ! ==================================================================== Include "SpanishG"; Include "Decir"; ! Para poder usar DECIR ... A ... ! Copio aquí (desde Gramatica.h) las gramáticas de los verbos en infinitivo ! que se usan en temas de conversación. Si no lo hago, hay problemas cuando ! el jugador intenta usar verbos en infinitivo: Verb 'abrir' * noun -> Open * 'a//' creature -> Open * noun 'con' held -> Unlock; Verb 'cerrar' * noun -> Close * noun 'con' 'pestillo' -> Lock * noun 'con' held -> Lock; Verb 'cortar' 'rasgar' * noun -> Cut * noun 'con' held -> Cut; Verb 'sacar' * -> SacarNadaDeNada * 'a//' -> SacarNadaDeNada * multiinside -> Take * 'a//' multiinside -> Take * multiinside 'de' noun -> Remove * 'a//' creature 'de' noun -> Remove * multiinside 'de' 'dentro' 'de' noun -> Remove; Verb 'salir' * -> Exit * 'de' noun -> GetOff * 'por' noun -> GoIn ! [VERGIT] Descomentada * 'fuera' -> Exit * 'afuera' -> Exit; Verb 'gilipollas' * -> Strong; Verb 'guarro' * -> Strong; Extend 'quitale' first * 'el' 'traje' 'a//' creature -> QuitarleTrajeA * 'el' 'traje' 'de' 'jason' 'a//' creature -> QuitarleTrajeA * 'el' 'traje' 'atmosferico' 'a//' creature -> QuitarleTrajeA * 'el' 'traje' 'atmosferico' 'de' 'jason' 'a//' creature -> QuitarleTrajeA * 'a//' 'jason' 'el' 'traje' -> QuitarleTraje * 'a//' 'jason' 'el' 'traje' 'de' 'jason' -> QuitarleTraje * 'a//' 'jason' 'el' 'traje' 'atmosferico' -> QuitarleTraje * 'a//' 'jason' 'el' 'traje' 'atmosferico' 'de' 'jason' -> QuitarleTraje * multiinside 'a//' creature -> QuitarleA * '-le' 'a//' creature multiinside -> Quitarle * '-le' 'el' 'traje' 'a//' creature -> QuitarleTrajeA * '-le' 'el' 'traje' 'de' 'jason' 'a//' creature -> QuitarleTrajeA * '-le' 'el' 'traje' 'atmosferico' 'a//' creature -> QuitarleTrajeA * '-le' 'el' 'traje' 'atmosferico' 'de' 'jason' 'a//' creature -> QuitarleTrajeA * '-le' 'a//' 'jason' 'el' 'traje' -> QuitarleTraje * '-le' 'a//' 'jason' 'el' 'traje' 'de' 'jason' -> QuitarleTraje * '-le' 'a//' 'jason' 'el' 'traje' 'atmosferico' -> QuitarleTraje * '-le' 'a//' 'jason' 'el' 'traje' 'atmosferico' 'de' 'jason' -> QuitarleTraje * '-le' multiinside 'a//' creature -> QuitarleA * '-le' 'a//' creature multiinside -> Quitarle; Verb 'madre,' * 'semilla' number -> Semilla * 'semilla' 'es'/'vale' number -> Semilla * 'la' 'semilla' 'es'/'vale' number -> Semilla * 'semilla' 'es' 'igual' 'a' number -> Semilla * 'la' 'semilla' 'es' 'igual' 'a' number -> Semilla * 'valor' 'de' 'semilla' number -> Semilla * 'valor' 'de' 'semilla' 'es'/'vale' number -> Semilla * 'valor' 'de' 'la' 'semilla' number -> Semilla * 'valor' 'de' 'la' 'semilla' 'es'/'vale' number -> Semilla * 'el' 'valor' 'de' 'semilla' 'es'/'vale' number -> Semilla * 'el' 'valor' 'de' 'la' 'semilla' 'es'/'vale' number -> Semilla * 'valor' 'de' 'semilla' 'igual' 'a' number -> Semilla * 'valor' 'de' 'semilla' 'es' 'igual' 'a' number -> Semilla * 'valor' 'de' 'la' 'semilla' 'igual' 'a' number -> Semilla * 'valor' 'de' 'la' 'semilla' 'es' 'igual' 'a' number -> Semilla * 'el' 'valor' 'de' 'semilla' 'es' 'igual' 'a' number -> Semilla * 'el' 'valor' 'de' 'la' 'semilla' 'es' 'igual' 'a' number -> Semilla; Verb 'usa' 'utiliza' * -> Usar * noun -> Usar * noun noun -> Usar * noun 'con' noun -> Usar; Verb meta 'configuracion' * -> Configuracion; Verb meta 'sonido' 'sonidos' * -> Sonido * 'on' / 'encendido' / 'si' -> EncenderSonido * 'off' / 'apagado' / 'no' / 'nx' -> ApagarSonido * 'detector' -> SonidoDetector * 'detector' 'on' / 'encendido' / 'si' -> EncenderSonidoDetector * 'detector' 'off' / 'apagado' / 'no' / 'nx' -> ApagarSonidoDetector * 'fondo' -> Musica * 'fondo' 'on' / 'encendida' / 'si' -> EncenderMusica * 'fondo' 'off' / 'apagada' / 'no' / 'nx' -> ApagarMusica; Verb meta 'musica' * -> Musica * 'fondo' 'on' / 'encendida' / 'si' -> EncenderMusica * 'fondo' 'off' / 'apagada' / 'no' / 'nx' -> ApagarMusica * 'on' / 'encendida' / 'si' -> EncenderMusica * 'off' / 'apagada' / 'no' / 'nx' -> ApagarMusica; Verb 'activa' * noun -> SwitchOn; Extend 'une' first * noun 'con' noun -> Tie * noun 'entre' 'si' -> UnirEntreSi * noun 'uno' 'con' 'otro' -> UnirEntreSi * noun 'una' 'con' 'otra' -> UnirEntreSi * noun 'unos' 'con' 'otros' -> UnirEntreSi * noun 'unas' 'con' 'otras' -> UnirEntreSi; Extend 'conecta' first * noun 'con' noun -> Tie * noun 'entre' 'si' -> UnirEntreSi * noun 'uno' 'con' 'otro' -> UnirEntreSi * noun 'una' 'con' 'otra' -> UnirEntreSi * noun 'unos' 'con' 'otros' -> UnirEntreSi * noun 'unas' 'con' 'otras' -> UnirEntreSi; Verb 'desactiva' * noun -> SwitchOff; Verb 'teclea' 'escribe' 'introduce' * -> TeclearMal * topic 'en' -> TeclearMal * topic 'en' noun -> Teclear * noun -> TeclearMal * noun topic -> TeclearMal ! * topic -> TeclearMal * 'en' noun topic -> TeclearMal * 'en' noun -> TeclearMal; VerboIrregular "introducir" with imperativo 'introduce'; Verb 'sigue' * creature -> Seguir * creature 'aqui' -> Seguir; Verb 'ven' 'regresa' * -> Venir * 'aqui' -> Venir * 'conmigo' -> Venir * 'aqui' 'conmig' -> Venir; Verb 'vamos' * -> Venir; Verb 'vamonos' 'vayamonos' * -> Venir * 'de' 'aqui' -> Venir; VerboIrregular "seguir" with imperativo 'sigue'; VerboIrregular "venir" with imperativo 'ven'; Verb 'queda' * -> Quedar * 'aqui' -> Quedar * creature -> Quedar * creature 'aqui' -> Quedar; VerboIrregular "quedarse" with imperativo 'queda'; Verb 'calla' 'callate' * -> Callar; VerboIrregular "callarse" with imperativo 'calla'; Verb 'deten' 'para' * creature -> Quedar * -> Quedar * 'aqui' -> Quedar; VerboIrregular "detenerse" with imperativo 'deten'; VerboIrregular "pararse" with imperativo 'para'; Verb 'esperate' * -> Wait * 'aqui' -> Wait; Extend 'vuelve' * 'aqui' -> Venir * 'conmigo' -> Venir * 'aqui' 'conmigo' -> Venir; Extend 'espera' * 'aqui' -> Wait; Verb meta 'creditos' * -> Creditos; Extend 'examina' * 'dentro' 'de' noun -> Search * 'en' noun -> Search; Extend 'x//' * 'en' noun -> Search * 'dentro' 'de' noun -> Search; VerboIrregular "mostrar las salidas" with imperativo 'salidas'; Ifdef DEBUG; Verb meta 'xrecarga' * -> XRecargar; EndIf; Verb 'recarga' 'carga' 'recargar' * -> Recargar * noun -> Recargar * noun 'en'/'con' noun -> RecargarEn; Extend 'cargar' last * -> Recargar * noun -> Recargar * noun 'en' noun -> RecargarEn; Ifdef DEBUG; Verb meta 'primera' * -> PrimeraParte; Verb meta 'segunda' * -> SegundaParte; Verb meta 'cuarta' * -> CuartaParte; Verb meta 'quinta' * -> QuintaParte; Endif; Extend 'salidas' * 'on' / 'si' -> ActivarSalidas * 'off' / 'no' / 'nx' -> DesactivarSalidas; Verb 'ayuda' 'socorro' 'auxilio' * -> Ayudar * creature -> Ayudar; VerboIrregular "pedir ayuda" with imperativo 'ayuda'; Verb 'hola' * -> Saludar * creature -> Saludar; Extend 'saluda' first * -> Saludar; Verb 'dispara' * -> Disparar * noun -> Disparar * 'hacia'/'a//'/'contra'/'al' noun -> Disparar; Verb 'disparate' * -> Dispararte; Verb 'disparame' * -> Dispararme; Extend 'sientate' first * -> Sentarse * 'en' noun -> Sentarse; Extend 'empuja' first * noun -> Push * 'a//' noun -> Push * noun 'a//'/'hacia' noun -> PushDir * 'a//' noun 'a//'/'hacia' noun -> PushDir * 'a//' noun noun -> PushDir; Extend 'gira' first * 'a//' noun -> Turn; Verb 'arregla' 'arreglar' 'repara' 'reparar' * noun -> Arreglar * noun noun -> Arreglar * noun 'con' noun -> Arreglar; Verb 'suelda' * noun -> Soldar * noun noun -> Soldar * noun 'con' noun -> Soldar; VerboIrregular "soldar" with imperativo 'suelda'; Extend 'rompe' first * noun 'con' noun -> AtacarCon; Verb meta 'graficos' * -> Graficos * 'on' / 'encendido' / 'si' -> EncenderGraficos * 'off' / 'apagado' / 'no' / 'nx' -> ApagarGraficos * 'pequenos' -> GraficosPequenos * 'medianos' -> GraficosMedianos * 'grandes' -> GraficosGrandes; Extend 'sal' last * 'por' noun -> GoIn; Extend 'salte' last * 'por' noun -> GoIn; Extend 'quita' last * noun 'con' held -> Unlock; Extend 'desatornilla' last * noun 'con' held -> Turn; Extend 'atornilla' last * noun 'con' held -> Turn; Extend 'saca' first * -> SacarNadaDeNada * 'a//' -> SacarNadaDeNada * multiinside -> Take * 'a//' multiinside -> Take; Extend 'saca' last * multiinside 'de' 'dentro' 'de' noun -> Remove; Extend 'coge' last * multiinside 'de' 'dentro' 'de' noun -> Remove; Verb 'pincha' 'clava' 'inyecta' * creature held -> Pinchar reverse * held 'en' noun -> Pinchar * held 'a//' creature -> Pinchar * held noun -> Pinchar * 'con' held 'en' noun -> Pinchar * 'con' held 'a//' creature -> Pinchar * 'con' held noun -> Pinchar * noun 'con' held -> Pinchar reverse * 'a//' creature 'con' held -> Pinchar reverse; Verb 'inyectale' 'pinchale' 'clavale' * creature held -> Pinchar reverse * held 'a//' creature -> Pinchar * 'con' held 'a//' creature -> Pinchar * 'a//' creature 'con' held -> Pinchar reverse; Verb 'despega' * -> Despegar * 'nave' -> Despegar; Extend 'empuja' first * noun 'a//'/'hacia' door -> EmpujarHaciaPuerta * noun door -> EmpujarHaciaPuerta * 'a//' noun 'a//'/'hacia' door -> EmpujarHaciaPuerta * 'a//' noun door -> EmpujarHaciaPuerta; Verb 'bloquea' * noun -> Lock * noun 'con' held -> Lock; Verb 'desbloquea' * noun -> Unlock * noun 'con' held -> Unlock; Verb meta 'pistas' * -> Pistas * 'no' / 'nx' -> PistasNo; Extend 'quita' first * -> Push; Extend 'habla' first * creature -> Tell * 'con'/'a//' creature -> Tell; Extend 'responde' first * creature -> Tell * 'a//' creature -> Tell * topic -> Tell; Extend 'di' first * creature -> Tell * 'a//' creature -> Tell * topic -> Tell; ! ==================================================================== ! ! RUTINAS VERBOSUB ! ! ==================================================================== [ DispararteSub; <>; ]; [ DispararmeSub; <>; ]; [ QuitarleTrajeSub; <>; ]; [ QuitarleTrajeASub; <>; ]; [ QuitarleSub; <>; ]; [ QuitarleASub; <>; ]; [ ConfiguracionSub v m; ControlTimer.PausarTick(); if (hayGraficos) { ApagarGraficosSub(true); hayGraficos = true; } barra_estado.numero_lineas = 26; barra_estado.dibujar(); clearMainWindow(); ZIPI_RunMenu(ZIPI_Configuracion, true); v = Damusix.QueVolumenCanal(CANAL_FONDO); m = LugarReal().sgw_mus; if (haySonidoFondo && v ~= 0 && ~~(Damusix.SonandoDeFondo(m))) { Damusix.AsignarCanal(m, CANAL_FONDO, v, SONIDO_BUCLE_INFINITO); Damusix.TocarCanal(CANAL_FONDO); } barra_estado.numero_lineas = 1; barra_estado.dibujar(); if (hayGraficos) { EncenderGraficosSub(true); } clearTextWindow(); ControlTimer.ReanudarTick(); <>; ]; [ GraficosSub; print (s_em) "[Por favor, usa la forma ~", (s_in) "GRAFICOS SI", (s_em) "~ o ~", (s_in) "GRAFICOS NO", (s_em) "~ para activar o desactivar, respectivamente, el uso de gráficos. También puedes cambiar el tamaño de la ventana gráfica usando ~", (s_in) "GRAFICOS PEQUEÑOS", (s_em) "~, ~", (s_in) "GRAFICOS MEDIANOS", (s_em) "~ o ~", (s_in) "GRAFICOS GRANDES", (s_em) "~.]^"; ]; [ GraficosPequenosSub; altoVentanaGrafica = GRAFICOS_PEQUENOS; EncenderGraficosSub(); ]; [ GraficosMedianosSub; altoVentanaGrafica = GRAFICOS_MEDIANOS; EncenderGraficosSub(); ]; [ GraficosGrandesSub; altoVentanaGrafica = GRAFICOS_GRANDES; EncenderGraficosSub(); ]; [ SonidoSub; print (s_em) "[Por favor, usa la forma ~", (s_in) "SONIDO SI", (s_em) "~ o ~", (s_in) "SONIDO NO", (s_em) "~ para activar o desactivar, respectivamente, todos los efectos sonoros.]^"; ]; [ MusicaSub; print (s_em) "[Por favor, usa la forma ~", (s_in) "SONIDO FONDO SI", (s_em) "~ o ~", (s_in) "SONIDO FONDO NO", (s_em) "~ para activar o desactivar, respectivamente, el sonido de fondo.]^"; ]; [ SonidoDetectorSub; print (s_em) "[Por favor, usa la forma ~", (s_in) "SONIDO DETECTOR SI", (s_em) "~ o ~", (s_in) "SONIDO DETECTOR NO", (s_em) "~ para activar o desactivar, respectivamente, el sonido del detector de movimiento.]^"; ]; [ TeclearMalSub; print (s_em) "[Por favor, usa la forma ~", (s_in) "TECLEA tal EN cual", (s_em) "~. Por ejemplo: ~", (s_in) "TECLEA HOLA EN EL TECLADO", (s_em) "~.]^"; ]; [ SemillaSub; rfalse; ]; [ EmpujarHaciaPuertaSub o i l; objectloop (o in compass) { i = o.door_dir; l = LugarReal(); if (l provides i && l.i has door) { <>; } } ]; [ DespegarSub; if (LugarReal() == nave1 or nave2) { "El control de la nave está en manos de Madre."; } else { "Debes estar dentro de la nave si quieres despegar."; } ]; [ PincharSub; "No tiene sentido clavar ", (the) noun, " en ", (the) second, "."; ]; [ UnirEntreSiSub; <>; ]; [ EncenderGraficosSub t; EncenderGraficos(); if (~~t) { glk_set_style(style_Emphasized); print "[Activados los gráficos (tamaño "; switch (altoVentanaGrafica) { GRAFICOS_PEQUENOS: print "pequeño"; GRAFICOS_MEDIANOS: print "mediano"; GRAFICOS_GRANDES: print "grande"; } print ").]^"; style roman; } ]; [ ApagarGraficosSub t; hayGraficos = false; closeGraphicWindow(); if (~~t) { print (s_em) "[Desactivados los gráficos.]^"; } ]; [ UsarSub; "Los verbos ~USAR~ o ~UTILIZAR~ no tienen efecto en esta aventura. Prueba a indicar más concretamente qué acción deseas realizar."; ]; [ AyudarSub; print "Prueba a pedir ayuda a alguien. Si necesitas pistas más elaboradas, puedes usar el sistema de pistas interactivas tecleando el comando ", (s_in) "PISTAS", ".^"; ]; [ AtacarConSub; <>; ]; [ ArreglarSub; "¿Arreglarl", (o) noun, " cómo? Tendrás que ser más específico."; ]; [ SoldarSub; "¿Soldar cómo?"; ]; [ RecargarSub; if (cargador in LugarReal()) { <>; } else { "Debes indicar con qué quieres recargar. O tal vez no tengas un recargador a mano..."; } ]; [ RecargarEnSub; if (noun ~= cargador || cargador notin LugarReal()) { "Sólo se puede recargar si hay un recargador cerca."; } ]; [ DispararSub; if (rifle notin player) { "¿Cómo pretendes disparar, si no llevas ningún arma?"; } if (noun == nothing) { "¿A quién o qué hay que disparar?"; } if (noun == player) { "¿Tan desesperado estás?"; } "Será mejor que guardes las balas para mejor ocasión."; ]; [ SaludarSub; if (noun ~= nothing) { "Saludas a ", (the) noun, "."; } else { "Mueves la mano en actitud amistosa."; } ]; [ VenirSub; <>; ]; [ SeguirSub; "Tú no tienes que seguir a nadie. Si acaso, deberían seguirte a ti."; ]; [ QuedarSub; "Ahora mismo estás parado..."; ]; [ CallarSub; "No tiene mucho sentido mandarse callar a uno mismo..."; ]; [ ActivarSalidasSub; mostrarSalidas = true; ! give mostrar_salidas ~oculto; print (s_em) "[Activado el listado automático de salidas.]^"; ]; [ DesactivarSalidasSub; mostrarSalidas = false; ! give mostrar_salidas oculto; print (s_em) "[Desactivado el listado automático de salidas.]^"; ]; Ifdef DEBUG; [ PrimeraParteSub; move tu_traje to player; give tu_traje worn; move traje_jason to jason; give traje_jason worn; move bateria to linterna; move linterna to player; move destornillador to player; linterna.encender(); ! puerta_procesador.abrir(); move jason to junto_procesador; PlayerTo(junto_procesador); ]; [ SegundaParteSub; SegundaParte(); procesador.arreglar(); move tu_traje to player; give tu_traje worn; move bateria to linterna; move linterna to player; linterna.encender(); give detector_movimiento on; puerta_procesador.abrir(); junto_procesador.sgw_img = Junto_Procesador_Abierto_jpg; move rifle to player; move bisturi to player; move tarjeta to player; PlayerTo(entrada); ]; [ CuartaParteSub; move bateria to linterna; move linterna to player; move destornillador to player; linterna.encender(); remove puerta_procesador; give puerta_procesador absent; move puerta_viscosa to entrada; alien.primera_vez = false; move rifle to player; give detector_movimiento on; remove traje_jason; give traje_jason absent; move traje_inutil to hueco_techo; move jason to aula; PNJ_Ruta(jason, MOVIMIENTO_PERSEGUIR, player); move alien to laberinto18; ! Por ejemplo DejarRastros(); remove tu_traje; give tu_traje absent; puerta_procesador.abrir(); move bisturi to player; give circuito general; give player light; give vaina open; AlienBloqueaPuerta(); move tarjeta to player; move holocubo to proyector; give proyector ~open; PlayerTo(aula); ]; [ QuintaParteSub; QuintaParte(); ]; [ XRecargarSub; bateria.energia = MAX_NIVEL_CARGA; "[Baterías recargadas.]"; ]; Endif; [ EncenderSonidoSub; haySonido = true; Damusix.ActivarAudio(); print (s_em) "[Activados todos los efectos sonoros.]^"; ]; [ ApagarSonidoSub; haySonido = false; Damusix.DesactivarAudio(); print (s_em) "[Desactivados todos los efectos sonoros.]^"; ]; [ EncenderMusicaSub i; haySonidoFondo = true; Damusix.VolumenCanal(CANAL_FONDO, VOLUMEN_FONDO); if (~~i) { print (s_em) "[Activado el sonido de fondo.]^"; } ]; [ ApagarMusicaSub; haySonidoFondo = false; Damusix.VolumenCanal(CANAL_FONDO, 0); print (s_em) "[Desactivado el sonido de fondo.]^"; ]; [ EncenderSonidoDetectorSub; haySonidoDetector = true; Damusix.VolumenCanal(CANAL_DETECTOR, VOLUMEN_DETECTOR); print (s_em) "[Activado el sonido del detector de movimiento.]^"; ]; [ ApagarSonidoDetectorSub; haySonidoDetector = false; Damusix.VolumenCanal(CANAL_DETECTOR, 0); print (s_em) "[Desactivado el sonido del detector de movimiento.]^"; ]; [ CreditosSub; viewImageCenter(Logo_Alpha_Aventuras_jpg); print "A·L·I·E·N: LA AVENTURA - EDICIÓN ESPECIAL^"; print "(c) 2008-2018 Alpha Aventuras^^"; print "- PROGRAMACIÓN Y DISEÑO:^"; print " Ricardo Pérez López^^"; print "- GRÁFICOS E IDEA ORIGINAL:^"; print " Manuel Millán Ruiz^^"; print "- TEXTOS:^"; print " Ricardo Pérez López^"; print " Francisco J. Roldán Domínguez^"; print " Manuel I. Monge García^^"; print "- MAPEADO Y DOCUMENTACIÓN:^"; print " Francisco J. Roldán Domínguez^"; print " Ricardo Pérez López^"; print " Antonio Matiola Ortiz^^"; print "- PRUEBAS:^"; print " Ricardo Pérez López^"; print " Francisco J. Roldán Domínguez^"; print " Manuel Millán Ruiz^"; print " Francisco Picazo Millán^"; print " Manuel I. Monge García^^"; KeyDelay(); print "Desarrollado usando el lenguaje Inform, de Graham Nelson,^"; print "con la ayuda de las siguientes librerías:^^"; print "- INFSP6, de INFSP Task Team.^"; print "- Adaptación de SGW+DMX, de Eliuk Blau^"; print "- Damusix, de Eliuk Blau^"; print "- PNJactor_NG y PNJacciones_NG (adaptaciones de los originales de Zak y Carlos)^"; print "- Rastros_NG (adaptación de Rastros, de Mel Hython)^"; print "- Moviles_NG (adaptación de Moviles, de Mel Hython)^"; print "- PnjPuertas_NG (Adaptación de PnjPuertas, de Jaevius)^"; print "- Decir, de Zak^"; print "- Etemas, de Zak^"; print "- Decorado_NG (adaptación de Decorado, de Zak y Mel Hython)^"; print "- Escr_NG (adaptación de Escr, de Baltasarq)^"; print "- Adaptación de Barra, de Presi^"; print "- Adaptación de ZIPI, de Zak"; KeyDelay(); print "^^Nuestro agradecimiento a todos los integrantes del CAAD que nos han ayudado, directa o indirectamente, en el desarrollo de esta aventura.^^ (c) 2008-2018 Alpha Aventuras^^ Este programa es software libre, publicado bajo la licencia GNU GPL v3. El texto completo de la licencia se encuentra en la siguiente dirección:^^"; print (s_pre) "http://www.gnu.org/licenses/gpl.txt^"; print "^El código fuente del programa está disponible en Github:^^"; print (s_pre) "https://github.com/ricpelo/alien^"; KeyDelay(); print "^Visítanos en:^^"; print (s_pre) "http://wiki.caad.es/Alpha_Aventuras^ http://www.facebook.com/alphaaventuras^"; print "^Contacta con nosotros en ", (s_pre) "alpha.aventuras@@64gmail.com", ".^"; KeyDelay(); viewImageCenter(LugarReal().sgw_img); ]; [ TeclearSub; if (noun == 0) { TeclearMalSub(); rtrue; } else { "No puedes teclear nada ahí."; } ]; [ SentarseSub; if (LugarReal() ~= nave1) { "Ahora no es momento de descansar."; } rfalse; ]; [ PistasSub t v; switch (hayPistas) { 0: hayPistas = 1; jason.decir = computadora.decir = robot.decir = false; print (s_em) "[Advertencia: Es sabido que la tentación de la ayuda es a veces tan fuerte que se suelen obtener pistas prematuramente. Por tanto, en cualquier momento durante el juego puedes poner ", (s_in) "PISTAS NO", (s_em) ", y eso te impedirá obtener ayuda en la sesión de juego actual. Si sigues queriendo una pista, pon ", (s_in) "PISTAS", (s_em) " otra vez.]^"; 1: ControlTimer.PausarTick(); t = false; if (hayGraficos) { t = true; ApagarGraficosSub(true); } barra_estado.numero_lineas = 26; barra_estado.dibujar(); v = Damusix.QueVolumenCanal(CANAL_FONDO); Damusix.AsignarCanal(Estancia_ogg, CANAL_FONDO, v, SONIDO_BUCLE_INFINITO); Damusix.Tocar(Estancia_ogg); ZIPI_Empezar(); v = Damusix.QueVolumenCanal(CANAL_FONDO); Damusix.AsignarCanal(LugarReal().sgw_mus, CANAL_FONDO, v, SONIDO_BUCLE_INFINITO); Damusix.TocarCanal(CANAL_FONDO); barra_estado.numero_lineas = 1; barra_estado.dibujar(); if (t) { EncenderGraficosSub(true); } clearTextWindow(); ControlTimer.ReanudarTick(); <>; 2: print (s_em) "[Las pistas han sido desactivadas.]^"; } ]; [ PistasNoSub; switch (hayPistas) { 2: print (s_em) "[Las pistas ya han sido desactivadas.]^"; default: hayPistas = 2; print (s_em) "[PISTAS desactivadas.]^"; } ]; [ SearchSub; <>; ]; [ ConsultSub; <>; ]; [ TellSub; ComoHablar(); ]; [ AnswerSub; ComoHablar(); ]; [ DecirSub; ComoHablar(); ]; [ SacarNadaDeNadaSub; "¿Que saque qué de dónde?"; ]; Include "Mapeador"; [ HandleGlkEvent ev context buffer; SGW_HandleGlk(ev); ControlTimer.CT_HandleGlkEvent(ev, context, buffer); Mapa_HandleGlkEvent(ev, context, buffer); ]; [ IdentifyGlkObject fase tipo ref rock; SGW_IdentifyGlk(fase, tipo, ref, rock); Damusix.IdentificarSonidos(fase); ! Mapa_IdentifyGlkObject(fase, tipo, ref, rock); if (fase == 2) ControlTimer.ReactivarTick(); ]; ! Fin del código