diff --git a/distrib/sets/lists/minix/mi b/distrib/sets/lists/minix/mi index 634bf0d2c..affc035a4 100644 --- a/distrib/sets/lists/minix/mi +++ b/distrib/sets/lists/minix/mi @@ -556,6 +556,9 @@ ./usr/etc/daily minix-sys ./usr/etc/dhcptags.conf minix-sys ./usr/etc/rc minix-sys +./usr/games minix-sys +./usr/games/adventure minix-sys +./usr/games/hide minix-sys ./usr/include minix-sys ./usr/include/aio.h minix-sys ./usr/include/a.out.h minix-sys @@ -4746,6 +4749,7 @@ ./usr/man/man5/usermgmt.conf.5 minix-sys ./usr/man/man5/utmp.5 minix-sys ./usr/man/man6 minix-sys +./usr/man/man6/adventure.6 minix-sys ./usr/man/man7 minix-sys ./usr/man/man7/ascii.7 minix-sys ./usr/man/man7/atf.7 minix-sys atf @@ -4990,6 +4994,7 @@ ./usr/share/examples/lutok/hello.cpp minix-sys kyua ./usr/share/examples/lutok/interpreter.cpp minix-sys kyua ./usr/share/examples/lutok/raii.cpp minix-sys kyua +./usr/share/games minix-sys ./usr/share/info minix-sys ./usr/share/info/as.info minix-sys binutils ./usr/share/info/bfd.info minix-sys binutils diff --git a/etc/mtree/NetBSD.dist.base b/etc/mtree/NetBSD.dist.base index e1972712f..344a55c21 100644 --- a/etc/mtree/NetBSD.dist.base +++ b/etc/mtree/NetBSD.dist.base @@ -42,6 +42,8 @@ ./usr/benchmarks/unixbench/tmp ./usr/benchmarks/unixbench/testdir ./usr/benchmarks/unixbench/results +./usr/games +./usr/games/hide gname=games mode=0750 ./usr/include ./usr/include/arpa ./usr/include/compat @@ -111,6 +113,7 @@ ./usr/share/doc/psd ./usr/share/doc/psd/19.curses ./usr/share/info +./usr/share/games ./usr/share/misc ./usr/share/mk ./usr/share/nvi diff --git a/etc/profile b/etc/profile index 71c1a4e1b..6daff7af1 100755 --- a/etc/profile +++ b/etc/profile @@ -4,7 +4,7 @@ set -o emacs # Set the default path -PATH=/usr/local/bin:/usr/pkg/bin:/usr/bin:/bin +PATH=/usr/local/bin:/usr/pkg/bin:/usr/bin:/bin:/usr/games # Add ~/bin, iff it is present if [ -e ${HOME}/bin ]; then diff --git a/games/Makefile b/games/Makefile new file mode 100644 index 000000000..780ac9292 --- /dev/null +++ b/games/Makefile @@ -0,0 +1,18 @@ +# $NetBSD: Makefile,v 1.29 2013/11/12 17:46:20 mbalmer Exp $ +# @(#)Makefile 8.3 (Berkeley) 7/24/94 + +# Missing: dungeon warp +# Moved: chess +# Don't belong: xneko xroach + +.include + +SUBDIR= adventure + +.if !defined(__MINIX) +.if ${MKCXX} != "no" +SUBDIR+= dab +.endif +.endif # !defined(__MINIX) + +.include diff --git a/games/Makefile.inc b/games/Makefile.inc new file mode 100644 index 000000000..5566c295f --- /dev/null +++ b/games/Makefile.inc @@ -0,0 +1,23 @@ +# $NetBSD: Makefile.inc,v 1.15 2012/06/19 05:46:08 dholland Exp $ +# @(#)Makefile.inc 8.1 (Berkeley) 5/31/93 + +MKHIDEGAME?= no + +.if defined(HIDEGAME) && (${MKHIDEGAME} != no) && defined(PROG) +BINDIR= /usr/games/hide +BINGRP= games +.if defined(SETGIDGAME) +USE_FORT?= yes +BINMODE= 2550 +.else +BINMODE= 550 +.endif +SYMLINKS+= dm /usr/games/${PROG} +.else +BINDIR= /usr/games +.if defined(SETGIDGAME) +BINGRP= games +BINMODE= 2555 +.endif +.endif +WARNS?= 5 diff --git a/games/adventure/Makefile b/games/adventure/Makefile new file mode 100644 index 000000000..8f3467e00 --- /dev/null +++ b/games/adventure/Makefile @@ -0,0 +1,19 @@ +# $NetBSD: Makefile,v 1.14 2013/02/16 16:30:28 jmcneill Exp $ +# @(#)Makefile 8.1 (Berkeley) 6/12/93 + +PROG= adventure +SRCS= main.c init.c done.c save.c subr.c vocab.c wizard.c io.c data.c crc.c +MAN= adventure.6 +HIDEGAME=hidegame +CLEANFILES+=mkdata setup.lo data.c + +data.c: glorkz mkdata + ${_MKTARGET_CREATE} + ./mkdata ${.CURDIR}/glorkz > data.c + +setup.lo: hdr.h +mkdata: setup.lo + ${_MKTARGET_LINK} + ${HOST_LINK.c} -o ${.TARGET} ${.ALLSRC} + +.include diff --git a/games/adventure/adventure.6 b/games/adventure/adventure.6 new file mode 100644 index 000000000..cc8c7a858 --- /dev/null +++ b/games/adventure/adventure.6 @@ -0,0 +1,55 @@ +.\" $NetBSD: adventure.6,v 1.4 2003/08/07 09:36:50 agc Exp $ +.\" +.\" Copyright (c) 1991, 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" The game adventure was originally written in Fortran by Will Crowther +.\" and Don Woods. It was later translated to C and enhanced by Jim +.\" Gillogly. This code is derived from software contributed to Berkeley +.\" by Jim Gillogly at The Rand Corporation. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. Neither the name of the University nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" @(#)adventure.6 8.1 (Berkeley) 5/31/93 +.\" +.Dd May 31, 1993 +.Dt ADVENTURE 6 +.Os +.Sh NAME +.Nm adventure +.Nd an exploration game +.Sh SYNOPSIS +.Nm +.Op saved-file +.Sh DESCRIPTION +The object of the game is to locate and explore Colossal Cave, find the +treasures hidden there, and bring them back to the building with you. +The program is self-descriptive to a point, but part of the game is to +discover its rules. +.Pp +To terminate a game, enter +.Dq quit ; +to save a game for later resumption, enter +.Dq suspend . diff --git a/games/adventure/crc.c b/games/adventure/crc.c new file mode 100644 index 000000000..dafd76267 --- /dev/null +++ b/games/adventure/crc.c @@ -0,0 +1,145 @@ +/* $NetBSD: crc.c,v 1.13 2012/01/08 18:16:00 dholland Exp $ */ + +/*- + * Copyright (c) 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * James W. Williams of the University of Maryland. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#ifndef lint +#if 0 +static char sccsid[] = "@(#)crc.c 8.1 (Berkeley) 5/31/93"; +static char ORIGINAL_sccsid[] = "@(#)crc.c 5.2 (Berkeley) 4/4/91"; +#else +__RCSID("$NetBSD: crc.c,v 1.13 2012/01/08 18:16:00 dholland Exp $"); +#endif +#endif /* not lint */ + +#include "extern.h" + +static const uint32_t crctab[256] = { + 0x7fffffff, + 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, + 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, + 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, + 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, + 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, 0x646ba8c0, + 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, + 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, + 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, + 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, + 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, 0xc8d75180, + 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, + 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, + 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106, + 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, + 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, + 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, 0x6b6b51f4, + 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, + 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, + 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, + 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, + 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, + 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, + 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, + 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, 0x5edef90e, + 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, + 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, + 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, + 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, + 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, 0x8708a3d2, + 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, + 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, + 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, + 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, + 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, + 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, + 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, + 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, + 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, + 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, + 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, 0x95bf4a82, + 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, + 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, + 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, + 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, + 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, + 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, + 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, + 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, 0xbdbdf21c, + 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, + 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, + 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d +}; + +/* + * crc -- + * Compute a POSIX.2 checksum. This routine modified by Jim Gillogly + * to work on sequential data rather than on a file. Initial call to + * crc_start initializes the sum, and subsequent calls to crc update + * it. + */ + +void +crc_start(struct crcstate *c) +{ + c->crcval = 0; + c->step = 0; +} + +/* + * Process NUM bytes pointed to by DATA + */ +void +crc_add(struct crcstate *c, const void *data, size_t num) +{ + const unsigned char *udata; + size_t pos; + unsigned x; + + udata = data; + pos = 0; + while (pos < num) { + x = (c->crcval >> 24 ^ udata[pos++]) & 0xff; + if (x == 0) { + x = c->step++; + if (c->step >= __arraycount(crctab)) { + c->step = 0; + } + } + c->crcval = (c->crcval << 8) ^ crctab[x]; + } +} + +uint32_t +crc_get(struct crcstate *c) +{ + return c->crcval; +} diff --git a/games/adventure/done.c b/games/adventure/done.c new file mode 100644 index 000000000..8693937d8 --- /dev/null +++ b/games/adventure/done.c @@ -0,0 +1,172 @@ +/* $NetBSD: done.c,v 1.10 2009/08/25 06:56:52 dholland Exp $ */ + +/*- + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * The game adventure was originally written in Fortran by Will Crowther + * and Don Woods. It was later translated to C and enhanced by Jim + * Gillogly. This code is derived from software contributed to Berkeley + * by Jim Gillogly at The Rand Corporation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#ifndef lint +#if 0 +static char sccsid[] = "@(#)done.c 8.1 (Berkeley) 5/31/93"; +#else +__RCSID("$NetBSD: done.c,v 1.10 2009/08/25 06:56:52 dholland Exp $"); +#endif +#endif /* not lint */ + +/* Re-coding of advent in C: termination routines */ + +#include +#include +#include "hdr.h" +#include "extern.h" + +int +score(void) +{ /* sort of like 20000 */ + int myscore, i; + + maxscore = myscore = 0; + for (i = 50; i <= maxtrs; i++) { + if (ptext[i].txtlen == 0) + continue; + k = 12; + if (i == chest) + k = 14; + if (i > chest) + k = 16; + if (prop[i] >= 0) + myscore += 2; + if (place[i] == 3 && prop[i] == 0) + myscore += k - 2; + maxscore += k; + } + myscore += (maxdie - numdie) * 10; + maxscore += maxdie * 10; + if (!(scoring || gaveup)) + myscore += 4; + maxscore += 4; + if (dflag != 0) + myscore += 25; + maxscore += 25; + if (isclosing) + myscore += 25; + maxscore += 25; + if (closed) { + if (bonus == 0) + myscore += 10; + if (bonus == 135) + myscore += 25; + if (bonus == 134) + myscore += 30; + if (bonus == 133) + myscore += 45; + } + maxscore += 45; + if (place[magazine] == 108) + myscore++; + maxscore++; + myscore += 2; + maxscore += 2; + for (i = 1; i <= hintmax; i++) + if (hinted[i]) + myscore -= hints[i][2]; + return myscore; +} + +/* entry=1 means goto 13000 */ /* game is over */ +/* entry=2 means goto 20000 */ /* 3=19000 */ +void +done(int entry) +{ + int i, sc; + if (entry == 1) + mspeak(1); + if (entry == 3) + rspeak(136); + printf("\n\n\nYou scored %d out of a ", (sc = score())); + printf("possible %d using %d turns.\n", maxscore, turns); + for (i = 1; i <= classes; i++) + if (cval[i] >= sc) { + speak(&ctext[i]); + if (i == classes - 1) { + printf("To achieve the next higher rating"); + printf(" would be a neat trick!\n\n"); + printf("Congratulations!!\n"); + exit(0); + } + k = cval[i] + 1 - sc; + printf("To achieve the next higher rating, you need"); + printf(" %d more point", k); + if (k == 1) + printf(".\n"); + else + printf("s.\n"); + exit(0); + } + printf("You just went off my scale!!!\n"); + exit(0); +} + +/* label 90 */ +void +die(int entry) +{ + int i; + if (entry != 99) { + rspeak(23); + oldloc2 = loc; + } + if (isclosing) { /* 99 */ + rspeak(131); + numdie++; + done(2); + } + yea = yes(81 + numdie * 2, 82 + numdie * 2, 54); + numdie++; + if (numdie == maxdie || !yea) + done(2); + place[water] = 0; + place[oil] = 0; + if (toting(lamp)) + prop[lamp] = 0; + for (i = 100; i >= 1; i--) { + if (!toting(i)) + continue; + k = oldloc2; + if (i == lamp) + k = 1; + drop(i, k); + } + loc = 3; + oldloc = loc; +} diff --git a/games/adventure/extern.h b/games/adventure/extern.h new file mode 100644 index 000000000..c0ba1ed4c --- /dev/null +++ b/games/adventure/extern.h @@ -0,0 +1,112 @@ +/* $NetBSD: extern.h,v 1.16 2012/01/08 18:17:41 dholland Exp $ */ + +/* + * Copyright (c) 1997 Christos Zoulas. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include + +/* crc.c */ +struct crcstate { + uint32_t crcval; + unsigned step; +}; + +void crc_start(struct crcstate *); +void crc_add(struct crcstate *, const void *, size_t); +uint32_t crc_get(struct crcstate *); + +/* done.c */ +int score(void); +void done(int) __dead; +void die(int); + +/* init.c */ +void init(void); +char *decr(int, int, int, int, int); +void trapdel(int); +void startup(void); + +/* io.c */ +void getin(char **, char **); +int yes(int, int, int); +int yesm(int, int, int); +void rdata(void); +#ifdef DEBUG +void twrite(int); +#endif +void rspeak(int); +void mspeak(int); +struct text; +void speak(const struct text *); +void pspeak(int, int); + +/* save.c */ +int save(const char *); +int restore(const char *); + +/* subr.c */ +int toting(int); +int here(int); +int at(int); +int liq(void); +int liqloc(int); +int forced(int); +int dark(void); +int pct(int); +int fdwarf(void); +int march(void); +void bug(int) __dead; +void checkhints(void); +int trsay(void); +int trtake(void); +int trdrop(void); +int tropen(void); +int trkill(void); +int trtoss(void); +int trfeed(void); +int trfill(void); +void closing(void); +void caveclose(void); + +/* vocab.c */ +void destroy(int); +void juggle(int); +void move(int, int); +int put(int, int, int); +void carry(int, int); +void drop(int, int); +int vocab(const char *, int, int); + +/* These three used to be functions in vocab.c */ +#define copystr(src, dest) strcpy((dest), (src)) +#define weq(str1, str2) (!strncmp((str1), (str2), 5)) +#define length(str) (strlen((str)) + 1) + +/* wizard.c */ +void datime(int *, int *); +void poof(void); +int Start(void); +void ciao(void); +int ran(int); diff --git a/games/adventure/glorkz b/games/adventure/glorkz new file mode 100644 index 000000000..a00d400f0 --- /dev/null +++ b/games/adventure/glorkz @@ -0,0 +1,1815 @@ +1 +1 You are standing at the end of a road before a small brick building. +1 Around you is a forest. A small stream flows out of the building and +1 down a gully. +2 You have walked up a hill, still in the forest. The road slopes back +2 down the other side of the hill. There is a building in the distance. +3 You are inside a building, a well house for a large spring. +4 You are in a valley in the forest beside a stream tumbling along a +4 rocky bed. +5 You are in open forest, with a deep valley to one side. +6 You are in open forest near both a valley and a road. +7 At your feet all the water of the stream splashes into a 2-inch slit +7 in the rock. Downstream the streambed is bare rock. +8 You are in a 20-foot depression floored with bare dirt. Set into the +8 dirt is a strong steel grate mounted in concrete. A dry streambed +8 leads into the depression. +9 You are in a small chamber beneath a 3x3 steel grate to the surface. +9 A low crawl over cobbles leads inward to the west. +10 You are crawling over cobbles in a low passage. There is a dim light +10 at the east end of the passage. +11 You are in a debris room filled with stuff washed in from the surface. +11 A low wide passage with cobbles becomes plugged with mud and debris +11 here, but an awkward canyon leads upward and west. A note on the wall +11 says "Magic word XYZZY". +12 You are in an awkward sloping east/west canyon. +13 You are in a splendid chamber thirty feet high. The walls are frozen +13 rivers of orange stone. An awkward canyon and a good passage exit +13 from east and west sides of the chamber. +14 At your feet is a small pit breathing traces of white mist. An east +14 passage ends here except for a small crack leading on. +15 You are at one end of a vast hall stretching forward out of sight to +15 the west. There are openings to either side. Nearby, a wide stone +15 staircase leads downward. The hall is filled with wisps of white mist +15 swaying to and fro almost as if alive. A cold wind blows up the +15 staircase. There is a passage at the top of a dome behind you. +16 The crack is far too small for you to follow. +17 You are on the east bank of a fissure slicing clear across the hall. +17 The mist is quite thick here, and the fissure is too wide to jump. +18 This is a low room with a crude note on the wall. The note says, +18 "You won't get it up the steps". +19 You are in the Hall of the Mountain King, with passages off in all +19 directions. +20 You are at the bottom of the pit with a broken neck. +21 You didn't make it. +22 The dome is unclimbable. +23 You are at the west end of the Twopit Room. There is a large hole in +23 the wall above the pit at this end of the room. +24 You are at the bottom of the eastern pit in the Twopit Room. There is +24 a small pool of oil in one corner of the pit. +25 You are at the bottom of the western pit in the Twopit Room. There is +25 a large hole in the wall about 25 feet above you. +26 You clamber up the plant and scurry through the hole at the top. +27 You are on the west side of the fissure in the Hall of Mists. +28 You are in a low N/S passage at a hole in the floor. The hole goes +28 down to an E/W passage. +29 You are in the south side chamber. +30 You are in the west side chamber of the Hall of the Mountain King. +30 A passage continues west and up here. +31 >$< +32 You can't get by the snake. +33 You are in a large room, with a passage to the south, a passage to the +33 west, and a wall of broken rock to the east. There is a large "Y2" on +33 a rock in the room's center. +34 You are in a jumble of rock, with cracks everywhere. +35 You're at a low window overlooking a huge pit, which extends up out of +35 sight. A floor is indistinctly visible over 50 feet below. Traces of +35 white mist cover the floor of the pit, becoming thicker to the right. +35 Marks in the dust around the window would seem to indicate that +35 someone has been here recently. Directly across the pit from you and +35 25 feet away there is a similar window looking into a lighted room. A +35 shadowy figure can be seen there peering back at you. +36 You are in a dirty broken passage. To the east is a crawl. To the +36 west is a large passage. Above you is a hole to another passage. +37 You are on the brink of a small clean climbable pit. A crawl leads +37 west. +38 You are in the bottom of a small pit with a little stream, which +38 enters and exits through tiny slits. +39 You are in a large room full of dusty rocks. There is a big hole in +39 the floor. There are cracks everywhere, and a passage leading east. +40 You have crawled through a very low wide passage parallel to and north +40 of the Hall of Mists. +41 You are at the west end of Hall of Mists. A low wide crawl continues +41 west and another goes north. To the south is a little passage 6 feet +41 off the floor. +42 You are in a maze of twisty little passages, all alike. +43 You are in a maze of twisty little passages, all alike. +44 You are in a maze of twisty little passages, all alike. +45 You are in a maze of twisty little passages, all alike. +46 Dead end +47 Dead end +48 Dead end +49 You are in a maze of twisty little passages, all alike. +50 You are in a maze of twisty little passages, all alike. +51 You are in a maze of twisty little passages, all alike. +52 You are in a maze of twisty little passages, all alike. +53 You are in a maze of twisty little passages, all alike. +54 Dead end +55 You are in a maze of twisty little passages, all alike. +56 Dead end +57 You are on the brink of a thirty foot pit with a massive orange column +57 down one wall. You could climb down here but you could not get back +57 up. The maze continues at this level. +58 Dead end +59 You have crawled through a very low wide passage parallel to and north +59 of the Hall of Mists. +60 You are at the east end of a very long hall apparently without side +60 chambers. To the east a low wide crawl slants up. To the north a +60 round two foot hole slants down. +61 You are at the west end of a very long featureless hall. The hall +61 joins up with a narrow north/south passage. +62 You are at a crossover of a high N/S passage and a low E/W one. +63 Dead end +64 You are at a complex junction. A low hands and knees passage from the +64 north joins a higher crawl from the east to make a walking passage +64 going west. There is also a large room above. The air is damp here. +65 You are in Bedquilt, a long east/west passage with holes everywhere. +65 To explore at random select north, south, up, or down. +66 You are in a room whose walls resemble Swiss cheese. Obvious passages +66 go west, east, NE, and NW. Part of the room is occupied by a large +66 bedrock block. +67 You are at the east end of the Twopit Room. The floor here is +67 littered with thin rock slabs, which make it easy to descend the pits. +67 There is a path here bypassing the pits to connect passages from east +67 and west. There are holes all over, but the only big one is on the +67 wall directly over the west pit where you can't get to it. +68 You are in a large low circular chamber whose floor is an immense slab +68 fallen from the ceiling (Slab Room). East and west there once were +68 large passages, but they are now filled with boulders. Low small +68 passages go north and south, and the south one quickly bends west +68 around the boulders. +69 You are in a secret N/S canyon above a large room. +70 You are in a secret N/S canyon above a sizable passage. +71 You are in a secret canyon at a junction of three canyons, bearing +71 north, south, and SE. The north one is as tall as the other two +71 combined. +72 You are in a large low room. Crawls lead north, SE, and SW. +73 Dead end crawl. +74 You are in a secret canyon which here runs E/W. It crosses over a +74 very tight canyon 15 feet below. If you go down you may not be able +74 to get back up. +75 You are at a wide place in a very tight N/S canyon. +76 The canyon here becomes too tight to go further south. +77 You are in a tall E/W canyon. A low tight crawl goes 3 feet north and +77 seems to open up. +78 The canyon runs into a mass of boulders -- dead end. +79 The stream flows out through a pair of 1 foot diameter sewer pipes. +79 It would be advisable to use the exit. +80 You are in a maze of twisty little passages, all alike. +81 Dead end +82 Dead end +83 You are in a maze of twisty little passages, all alike. +84 You are in a maze of twisty little passages, all alike. +85 Dead end +86 Dead end +87 You are in a maze of twisty little passages, all alike. +88 You are in a long, narrow corridor stretching out of sight to the +88 west. At the eastern end is a hole through which you can see a +88 profusion of leaves. +89 There is nothing here to climb. Use "up" or "out" to leave the pit. +90 You have climbed up the plant and out of the pit. +91 You are at the top of a steep incline above a large room. You could +91 climb down here, but you would not be able to climb up. There is a +91 passage leading back to the north. +92 You are in the Giant Room. The ceiling here is too high up for your +92 lamp to show it. Cavernous passages lead east, north, and south. On +92 the west wall is scrawled the inscription, "Fee fie foe foo" [sic]. +93 The passage here is blocked by a recent cave-in. +94 You are at one end of an immense north/south passage. +95 You are in a magnificent cavern with a rushing stream, which cascades +95 over a sparkling waterfall into a roaring whirlpool which disappears +95 through a hole in the floor. Passages exit to the south and west. +96 You are in the Soft Room. The walls are covered with heavy curtains, +96 the floor with a thick pile carpet. Moss covers the ceiling. +97 This is the Oriental Room. Ancient oriental cave drawings cover the +97 walls. A gently sloping passage leads upward to the north, another +97 passage leads SE, and a hands and knees crawl leads west. +98 You are following a wide path around the outer edge of a large cavern. +98 Far below, through a heavy white mist, strange splashing noises can be +98 heard. The mist rises up through a fissure in the ceiling. The path +98 exits to the south and west. +99 You are in an alcove. A small NW path seems to widen after a short +99 distance. An extremely tight tunnel leads east. It looks like a very +99 tight squeeze. An eerie light can be seen at the other end. +100 You're in a small chamber lit by an eerie green light. An extremely +100 narrow tunnel exits to the west. A dark corridor leads NE. +101 You're in the Dark-Room. A corridor leading south is the only exit. +102 You are in an arched hall. A coral passage once continued up and east +102 from here, but is now blocked by debris. The air smells of sea water. +103 You're in a large room carved out of sedimentary rock. The floor and +103 walls are littered with bits of shells embedded in the stone. A +103 shallow passage proceeds downward, and a somewhat steeper one leads +103 up. A low hands and knees passage enters from the south. +104 You are in a long sloping corridor with ragged sharp walls. +105 You are in a cul-de-sac about eight feet across. +106 You are in an anteroom leading to a large passage to the east. Small +106 passages go west and up. The remnants of recent digging are evident. +106 A sign in midair here says "Cave under construction beyond this point. +106 Proceed at own risk. [Witt construction company]" +107 You are in a maze of twisty little passages, all different. +108 You are at Witt's End. Passages lead off in *all* directions. +109 You are in a north/south canyon about 25 feet across. The floor is +109 covered by white mist seeping in from the north. The walls extend +109 upward for well over 100 feet. Suspended from some unseen point far +109 above you, an enormous two-sided mirror is hanging parallel to and +109 midway between the canyon walls. (The mirror is obviously provided +109 for the use of the dwarves, who as you know, are extremely vain.) A +109 small window can be seen in either wall, some fifty feet up. +110 You're at a low window overlooking a huge pit, which extends up out of +110 sight. A floor is indistinctly visible over 50 feet below. Traces of +110 white mist cover the floor of the pit, becoming thicker to the left. +110 Marks in the dust around the window would seem to indicate that +110 someone has been here recently. Directly across the pit from you and +110 25 feet away there is a similar window looking into a lighted room. A +110 shadowy figure can be seen there peering back at you. +111 A large stalactite extends from the roof and almost reaches the floor +111 below. You could climb down it, and jump from it to the floor, but +111 having done so you would be unable to reach it to climb back up. +112 You are in a little maze of twisting passages, all different. +113 You are at the edge of a large underground reservoir. An opaque cloud +113 of white mist fills the room and rises rapidly upward. The lake is +113 fed by a stream, which tumbles out of a hole in the wall about 10 feet +113 overhead and splashes noisily into the water somewhere within the +113 mist. The only passage goes back toward the south. +114 Dead end +115 You are at the northeast end of an immense room, even larger than the +115 Giant Room. It appears to be a repository for the "Adventure" +115 program. Massive torches far overhead bathe the room with smoky +115 yellow light. Scattered about you can be seen a pile of bottles (all +115 of them empty), a nursery of young beanstalks murmuring quietly, a bed +115 of oysters, a bundle of black rods with rusty stars on their ends, and +115 a collection of brass lanterns. Off to one side a great many dwarves +115 are sleeping on the floor, snoring loudly. A sign nearby reads: "Do +115 not disturb the dwarves!" An immense mirror is hanging against one +115 wall, and stretches to the other end of the room, where various other +115 sundry objects can be glimpsed dimly in the distance. +116 You are at the southwest end of the Repository. To one side is a pit +116 full of fierce green snakes. On the other side is a row of small +116 wicker cages, each of which contains a little sulking bird. In one +116 corner is a bundle of black rods with rusty marks on their ends. A +116 large number of velvet pillows are scattered about on the floor. A +116 vast mirror stretches off to the northeast. At your feet is a large +116 steel grate, next to which is a sign which reads, "Treasure Vault. +116 Keys in Main Office." +117 You are on one side of a large, deep chasm. A heavy white mist rising +117 up from below obscures all view of the far side. A SW path leads away +117 from the chasm into a winding corridor. +118 You are in a long winding corridor sloping out of sight in both +118 directions. +119 You are in a secret canyon which exits to the north and east. +120 You are in a secret canyon which exits to the north and east. +121 You are in a secret canyon which exits to the north and east. +122 You are on the far side of the chasm. A NE path leads away from the +122 chasm on this side. +123 You're in a long east/west corridor. A faint rumbling noise can be +123 heard in the distance. +124 The path forks here. The left fork leads northeast. A dull rumbling +124 seems to get louder in that direction. The right fork leads southeast +124 down a gentle slope. The main corridor enters from the west. +125 The walls are quite warm here. From the north can be heard a steady +125 roar, so loud that the entire cave seems to be trembling. Another +125 passage leads south, and a low crawl goes east. +126 You are on the edge of a breath-taking view. Far below you is an +126 active volcano, from which great gouts of molten lava come surging +126 out, cascading back down into the depths. The glowing rock fills the +126 farthest reaches of the cavern with a blood-red glare, giving every- +126 thing an eerie, macabre appearance. The air is filled with flickering +126 sparks of ash and a heavy smell of brimstone. The walls are hot to +126 the touch, and the thundering of the volcano drowns out all other +126 sounds. Embedded in the jagged roof far overhead are myriad twisted +126 formations composed of pure white alabaster, which scatter the murky +126 light into sinister apparitions upon the walls. To one side is a deep +126 gorge, filled with a bizarre chaos of tortured rock which seems to +126 have been crafted by the devil himself. An immense river of fire +126 crashes out from the depths of the volcano, burns its way through the +126 gorge, and plummets into a bottomless pit far off to your left. To +126 the right, an immense geyser of blistering steam erupts continuously +126 from a barren island in the center of a sulfurous lake, which bubbles +126 ominously. The far right wall is aflame with an incandescence of its +126 own, which lends an additional infernal splendor to the already +126 hellish scene. A dark, foreboding passage exits to the south. +127 You are in a small chamber filled with large boulders. The walls are +127 very warm, causing the air in the room to be almost stifling from the +127 heat. The only exit is a crawl heading west, through which is coming +127 a low rumbling. +128 You are walking along a gently sloping north/south passage lined with +128 oddly shaped limestone formations. +129 You are standing at the entrance to a large, barren room. A sign +129 posted above the entrance reads: "Caution! Bear in room!" +130 You are inside a barren room. The center of the room is completely +130 empty except for some dust. Marks in the dust lead away toward the +130 far end of the room. The only exit is the way you came in. +131 You are in a maze of twisting little passages, all different. +132 You are in a little maze of twisty passages, all different. +133 You are in a twisting maze of little passages, all different. +134 You are in a twisting little maze of passages, all different. +135 You are in a twisty little maze of passages, all different. +136 You are in a twisty maze of little passages, all different. +137 You are in a little twisty maze of passages, all different. +138 You are in a maze of little twisting passages, all different. +139 You are in a maze of little twisty passages, all different. +140 Dead end +-1 End +2 +1 You're at end of road again. +2 You're at hill in road. +3 You're inside building. +4 You're in valley. +5 You're in forest. +6 You're in forest. +7 You're at slit in streambed. +8 You're outside grate. +9 You're below the grate. +10 You're in Cobble Crawl. +11 You're in Debris Room. +13 You're in Bird Chamber. +14 You're at top of small pit. +15 You're in Hall of Mists. +17 You're on east bank of fissure. +18 You're in Nugget of Gold Room. +19 You're in Hall of Mt King. +23 You're at west end of Twopit Room. +24 You're in east pit. +25 You're in west pit. +33 You're at "Y2". +35 You're at window on pit. +36 You're in dirty passage. +39 You're in Dusty Rock room. +41 You're at west end of Hall of Mists. +57 You're at brink of pit. +60 You're at east end of Long Hall. +61 You're at west end of Long Hall. +64 You're at Complex Junction. +66 You're in Swiss Cheese room. +67 You're at east end of Twopit Room. +68 You're in Slab Room. +71 You're at junction of three secret canyons. +74 You're in secret E/W canyon above tight canyon. +88 You're in narrow corridor. +91 You're at steep incline above large room. +92 You're in Giant Room. +95 You're in cavern with waterfall. +96 You're in Soft Room. +97 You're in Oriental Room. +98 You're in Misty Cavern. +99 You're in Alcove. +100 You're in Plover Room. +101 You're in Dark-Room. +102 You're in Arched Hall. +103 You're in Shell Room. +106 You're in Anteroom. +108 You're at Witt's End. +109 You're in Mirror Canyon. +110 You're at window on pit. +111 You're at top of stalactite. +113 You're at Reservoir. +115 You're at NE end. +116 You're at SW end. +117 You're on SW side of chasm. +118 You're in sloping corridor. +122 You're on NE side of chasm. +123 You're in corridor. +124 You're at fork in path. +125 You're at junction with warm walls. +126 You're at Breath-taking View. +127 You're in Chamber of Boulders. +128 You're in limestone passage. +129 You're in front of barren room. +130 You're in Barren Room. +-1 +3 +1 2 2 44 29 +1 3 3 12 19 43 +1 4 5 13 14 46 30 +1 5 6 45 43 +1 8 63 +2 1 2 12 7 43 45 30 +2 5 6 45 46 +3 1 3 11 32 44 +3 11 62 +3 33 65 +3 79 5 14 +4 1 4 12 45 +4 5 6 43 44 29 +4 7 5 46 30 +4 8 63 +5 4 9 43 30 +5 50005 6 7 45 +5 6 6 +5 5 44 46 +6 1 2 45 +6 4 9 43 44 30 +6 5 6 46 +7 1 12 +7 4 4 45 +7 5 6 43 44 +7 8 5 15 16 46 +7 595 60 14 30 +8 5 6 43 44 46 +8 1 12 +8 7 4 13 45 +8 303009 3 19 30 +8 593 3 +9 303008 11 29 +9 593 11 +9 10 17 18 19 44 +9 14 31 +9 11 51 +10 9 11 20 21 43 +10 11 19 22 44 51 +10 14 31 +11 303008 63 +11 9 64 +11 10 17 18 23 24 43 +11 12 25 19 29 44 +11 3 62 +11 14 31 +12 303008 63 +12 9 64 +12 11 30 43 51 +12 13 19 29 44 +12 14 31 +13 303008 63 +13 9 64 +13 11 51 +13 12 25 43 +13 14 23 31 44 +14 303008 63 +14 9 64 +14 11 51 +14 13 23 43 +14 150020 30 31 34 +14 15 30 +14 16 33 44 +15 18 36 46 +15 17 7 38 44 +15 19 10 30 45 +15 150022 29 31 34 35 23 43 +15 14 29 +15 34 55 +16 14 1 +17 15 38 43 +17 312596 39 +17 412021 7 +17 412597 41 42 44 69 +17 27 41 +18 15 38 11 45 +19 15 10 29 43 +19 311028 45 36 +19 311029 46 37 +19 311030 44 7 +19 32 45 +19 35074 49 +19 211032 49 +19 74 66 +20 0 1 +21 0 1 +22 15 1 +23 67 43 42 +23 68 44 61 +23 25 30 31 +23 648 52 +24 67 29 11 +25 23 29 11 +25 724031 56 +25 26 56 +26 88 1 +27 312596 39 +27 412021 7 +27 412597 41 42 43 69 +27 17 41 +27 40 45 +27 41 44 +28 19 38 11 46 +28 33 45 55 +28 36 30 52 +29 19 38 11 45 +30 19 38 11 43 +30 62 44 29 +31 524089 1 +31 90 1 +32 19 1 +33 3 65 +33 28 46 +33 34 43 53 54 +33 35 44 +33 159302 71 +33 100 71 +34 33 30 55 +34 15 29 +35 33 43 55 +35 20 39 +36 37 43 17 +36 28 29 52 +36 39 44 +36 65 70 +37 36 44 17 +37 38 30 31 56 +38 37 56 29 11 +38 595 60 14 30 4 5 +39 36 43 23 +39 64 30 52 58 +39 65 70 +40 41 1 +41 42 46 29 23 56 +41 27 43 +41 59 45 +41 60 44 17 +42 41 29 +42 42 45 +42 43 43 +42 45 46 +42 80 44 +43 42 44 +43 44 46 +43 45 43 +44 43 43 +44 48 30 +44 50 46 +44 82 45 +45 42 44 +45 43 45 +45 46 43 +45 47 46 +45 87 29 30 +46 45 44 11 +47 45 43 11 +48 44 29 11 +49 50 43 +49 51 44 +50 44 43 +50 49 44 +50 51 30 +50 52 46 +51 49 44 +51 50 29 +51 52 43 +51 53 46 +52 50 44 +52 51 43 +52 52 46 +52 53 29 +52 55 45 +52 86 30 +53 51 44 +53 52 45 +53 54 46 +54 53 44 11 +55 52 44 +55 55 45 +55 56 30 +55 57 43 +56 55 29 11 +57 13 30 56 +57 55 44 +57 58 46 +57 83 45 +57 84 43 +58 57 43 11 +59 27 1 +60 41 43 29 17 +60 61 44 +60 62 45 30 52 +61 60 43 +61 62 45 +61 100107 46 +62 60 44 +62 63 45 +62 30 43 +62 61 46 +63 62 46 11 +64 39 29 56 59 +64 65 44 70 +64 103 45 74 +64 106 43 +65 64 43 +65 66 44 +65 80556 46 +65 68 61 +65 80556 29 +65 50070 29 +65 39 29 +65 60556 45 +65 75072 45 +65 71 45 +65 80556 30 +65 106 30 +66 65 47 +66 67 44 +66 80556 46 +66 77 25 +66 96 43 +66 50556 50 +66 97 72 +67 66 43 +67 23 44 42 +67 24 30 31 +68 23 46 +68 69 29 56 +68 65 45 +69 68 30 61 +69 331120 46 +69 119 46 +69 109 45 +69 113 75 +70 71 45 +70 65 30 23 +70 111 46 +71 65 48 +71 70 46 +71 110 45 +72 65 70 +72 118 49 +72 73 45 +72 97 48 72 +73 72 46 17 11 +74 19 43 +74 331120 44 +74 121 44 +74 75 30 +75 76 46 +75 77 45 +76 75 45 +77 75 43 +77 78 44 +77 66 45 17 +78 77 46 +79 3 1 +80 42 45 +80 80 44 +80 80 46 +80 81 43 +81 80 44 11 +82 44 46 11 +83 57 46 +83 84 43 +83 85 44 +84 57 45 +84 83 44 +84 114 50 +85 83 43 11 +86 52 29 11 +87 45 29 30 +88 25 30 56 43 +88 20 39 +88 92 44 27 +89 25 1 +90 23 1 +91 95 45 73 23 +91 72 30 56 +92 88 46 +92 93 43 +92 94 45 +93 92 46 27 11 +94 92 46 27 23 +94 309095 45 3 73 +94 611 45 +95 94 46 11 +95 92 27 +95 91 44 +96 66 44 11 +97 66 48 +97 72 44 17 +97 98 29 45 73 +98 97 46 72 +98 99 44 +99 98 50 73 +99 301 43 23 +99 100 43 +100 301 44 23 11 +100 99 44 +100 159302 71 +100 33 71 +100 101 47 22 +101 100 46 71 11 +102 103 30 74 11 +103 102 29 38 +103 104 30 +103 114618 46 +103 115619 46 +103 64 46 +104 103 29 74 +104 105 30 +105 104 29 11 +105 103 74 +106 64 29 +106 65 44 +106 108 43 +107 131 46 +107 132 49 +107 133 47 +107 134 48 +107 135 29 +107 136 50 +107 137 43 +107 138 44 +107 139 45 +107 61 30 +108 95556 43 45 46 47 48 49 50 29 30 +108 106 43 +108 626 44 +109 69 46 +109 113 45 75 +110 71 44 +110 20 39 +111 70 45 +111 40050 30 39 56 +111 50053 30 +111 45 30 +112 131 49 +112 132 45 +112 133 43 +112 134 50 +112 135 48 +112 136 47 +112 137 44 +112 138 30 +112 139 29 +112 140 46 +113 109 46 11 109 +114 84 48 +115 116 49 +116 115 47 +116 593 30 +117 118 49 +117 233660 41 42 69 47 +117 332661 41 +117 303 41 +117 332021 39 +117 596 39 +118 72 30 +118 117 29 +119 69 45 11 +119 653 43 7 +120 69 45 +120 74 43 +121 74 43 11 +121 653 45 7 +122 123 47 +122 233660 41 42 69 49 +122 303 41 +122 596 39 +122 124 77 +122 126 28 +122 129 40 +123 122 44 +123 124 43 77 +123 126 28 +123 129 40 +124 123 44 +124 125 47 36 +124 128 48 37 30 +124 126 28 +124 129 40 +125 124 46 77 +125 126 45 28 +125 127 43 17 +126 125 46 23 11 +126 124 77 +126 610 30 39 +127 125 44 11 17 +127 124 77 +127 126 28 +128 124 45 29 77 +128 129 46 30 40 +128 126 28 +129 128 44 29 +129 124 77 +129 130 43 19 40 3 +129 126 28 +130 129 44 11 +130 124 77 +130 126 28 +131 107 44 +131 132 48 +131 133 50 +131 134 49 +131 135 47 +131 136 29 +131 137 30 +131 138 45 +131 139 46 +131 112 43 +132 107 50 +132 131 29 +132 133 45 +132 134 46 +132 135 44 +132 136 49 +132 137 47 +132 138 43 +132 139 30 +132 112 48 +133 107 29 +133 131 30 +133 132 44 +133 134 47 +133 135 49 +133 136 43 +133 137 45 +133 138 50 +133 139 48 +133 112 46 +134 107 47 +134 131 45 +134 132 50 +134 133 48 +134 135 43 +134 136 30 +134 137 46 +134 138 29 +134 139 44 +134 112 49 +135 107 45 +135 131 48 +135 132 30 +135 133 46 +135 134 43 +135 136 44 +135 137 49 +135 138 47 +135 139 50 +135 112 29 +136 107 43 +136 131 44 +136 132 29 +136 133 49 +136 134 30 +136 135 46 +136 137 50 +136 138 48 +136 139 47 +136 112 45 +137 107 48 +137 131 47 +137 132 46 +137 133 30 +137 134 29 +137 135 50 +137 136 45 +137 138 49 +137 139 43 +137 112 44 +138 107 30 +138 131 43 +138 132 47 +138 133 29 +138 134 44 +138 135 45 +138 136 46 +138 137 48 +138 139 49 +138 112 50 +139 107 49 +139 131 50 +139 132 43 +139 133 44 +139 134 45 +139 135 30 +139 136 48 +139 137 29 +139 138 46 +139 112 47 +140 112 45 11 +-1 +4 +2 road +2 hill +3 enter +4 upstr +5 downs +6 fores +7 forwa +7 conti +7 onwar +8 back +8 retur +8 retre +9 valle +10 stair +11 out +11 outsi +11 exit +11 leave +12 build +12 house +13 gully +14 strea +15 rock +16 bed +17 crawl +18 cobbl +19 inwar +19 insid +19 in +20 surfa +21 null +21 nowhe +22 dark +23 passa +23 tunne +24 low +25 canyo +26 awkwa +27 giant +28 view +29 upwar +29 up +29 u +29 above +29 ascen +30 d +30 downw +30 down +30 desce +31 pit +32 outdo +33 crack +34 steps +35 dome +36 left +37 right +38 hall +39 jump +40 barre +41 over +42 acros +43 east +43 e +44 west +44 w +45 north +45 n +46 south +46 s +47 ne +48 se +49 sw +50 nw +51 debri +52 hole +53 wall +54 broke +55 y2 +56 climb +57 look +57 exami +57 touch +57 descr +58 floor +59 room +60 slit +61 slab +61 slabr +62 xyzzy +63 depre +64 entra +65 plugh +66 secre +67 cave +69 cross +70 bedqu +71 plove +72 orien +73 caver +74 shell +75 reser +76 main +76 offic +77 fork +1001 keys +1001 key +1002 lamp +1002 headl +1002 lante +1003 grate +1004 cage +1005 wand +1005 rod +1006 wand +1006 rod (must be next object after "real" rod) +1007 steps +1008 bird +1009 door +1010 pillo +1010 velve +1011 snake +1012 fissu +1013 table +1014 clam +1015 oyste +1016 magaz +1016 issue +1016 spelu +1016 "spel +1017 dwarf +1017 dwarv +1018 knife +1018 knive +1019 food +1019 ratio +1020 bottl +1020 jar +1021 water +1021 h2o +1022 oil +1023 mirro +1024 plant +1024 beans +1025 plant (must be next object after "real" plant) +1026 stala +1027 shado +1027 figur +1028 axe +1029 drawi +1030 pirat +1031 drago +1032 chasm +1033 troll +1034 troll (must be next object after "real" troll) +1035 bear +1036 messa +1037 volca +1037 geyse (same as volcano) +1038 machi +1038 vendi +1039 batte +1040 carpe +1040 moss +1050 gold +1050 nugge +1051 diamo +1052 silve +1052 bars +1053 jewel +1054 coins +1055 chest +1055 box +1055 treas +1056 eggs +1056 egg +1056 nest +1057 tride +1058 vase +1058 ming +1058 shard +1058 potte +1059 emera +1060 plati +1060 pyram +1061 pearl +1062 rug +1062 persi +1063 spice +1064 chain +2001 carry +2001 take +2001 keep +2001 catch +2001 steal +2001 captu +2001 get +2001 tote +2002 drop +2002 relea +2002 free +2002 disca +2002 dump +2003 say +2003 chant +2003 sing +2003 utter +2003 mumbl +2004 unloc +2004 open +2005 nothi +2006 lock +2006 close +2007 light +2007 on +2008 extin +2008 off +2009 wave +2009 shake +2009 swing +2010 calm +2010 placa +2010 tame +2011 walk +2011 run +2011 trave +2011 go +2011 proce +2011 conti +2011 explo +2011 goto +2011 follo +2011 turn +2012 attac +2012 kill +2012 slay +2012 fight +2012 hit +2012 strik +2013 pour +2014 eat +2014 devou +2015 drink +2016 rub +2017 throw +2017 toss +2018 quit +2019 find +2019 where +2020 inven +2020 inv +2021 feed +2022 fill +2023 blast +2023 deton +2023 ignit +2023 blowu +2024 score +2025 fee +2025 fie +2025 foe +2025 foo +2025 fum +2026 brief +2027 read +2027 perus +2028 break +2028 shatt +2028 smash +2029 wake +2029 distu +2030 suspe +2030 pause +2030 save +2031 hours +3001 fee +3002 fie +3003 foe +3004 foo +3005 fum +3050 sesam +3050 opens +3050 abra +3050 abrac +3050 shaza +3050 hocus +3050 pocus +3051 help +3051 ? +3064 tree +3064 trees +3066 dig +3066 excav +3068 lost +3069 mist +3079 fuck +3139 stop +3142 info +3142 infor +3147 swim +-1 +5 +1 Set of keys +000 There are some keys on the ground here. +2 Brass lantern +000 There is a shiny brass lamp nearby. +100 There is a lamp shining nearby. +3 *Grate +000 The grate is locked. +100 The grate is open. +4 Wicker cage +000 There is a small wicker cage discarded nearby. +5 Black rod +000 A three foot black rod with a rusty star on an end lies nearby. +6 Black rod +000 A three foot black rod with a rusty mark on an end lies nearby. +7 *Steps +000 Rough stone steps lead down the pit. +100 Rough stone steps lead up the dome. +8 Little bird in cage +000 A cheerful little bird is sitting here singing. +100 There is a little bird in the cage. +9 *Rusty door +000 The way north is barred by a massive, rusty, iron door. +100 The way north leads through a massive, rusty, iron door. +10 Velvet pillow +000 A small velvet pillow lies on the floor. +11 *Snake +000 A huge green fierce snake bars the way! +100 >$< (Chased away) +12 *Fissure +000 >$< +100 A crystal bridge now spans the fissure. +200 The crystal bridge has vanished! +13 *Stone tablet +000 A massive stone tablet embedded in the wall reads: +000 "Congratulations on bringing light into the Dark-Room!" +14 Giant clam >grunt!< +000 There is an enormous clam here with its shell tightly closed. +15 Giant oyster >groan!< +000 There is an enormous oyster here with its shell tightly closed. +100 Interesting. There seems to be something written on the underside of +100 The oyster. +16 "Spelunker Today" +000 There are a few recent issues of "Spelunker Today" magazine here. +19 Tasty food +000 There is food here. +20 Small bottle +000 There is a bottle of water here. +100 There is an empty bottle here. +200 There is a bottle of oil here. +21 Water in the bottle +22 Oil in the bottle +23 *Mirror +000 >$< +24 *Plant +000 There is a tiny little plant in the pit, murmuring "Water, water, ..." +100 The plant spurts into furious growth for a few seconds. +200 There is a 12-foot-tall beanstalk stretching up out of the pit, +200 bellowing "WATER!! WATER!!" +300 The plant grows explosively, almost filling the bottom of the pit. +400 There is a gigantic beanstalk stretching all the way up to the hole. +500 You've over-watered the plant! It's shriveling up! It's, it's... +25 *Phony plant (seen in twopit room only when tall enough) +000 >$< +100 The top of a 12-foot-tall beanstalk is poking out of the west pit. +200 There is a huge beanstalk growing out of the west pit up to the hole. +26 *Stalactite +000 >$< +27 *Shadowy figure +000 The shadowy figure seems to be trying to attract your attention. +28 Dwarf's axe +000 There is a little axe here. +100 There is a little axe lying beside the bear. +29 *Cave drawings +000 >$< +30 *Pirate +000 >$< +31 *Dragon +000 A huge green fierce dragon bars the way! +100 Congratulations! You have just vanquished a dragon with your bare +100 hands! (Unbelievable, isn't it?) +200 The body of a huge green dead dragon is lying off to one side. +32 *Chasm +000 A rickety wooden bridge extends across the chasm, vanishing into the +000 mist. A sign posted on the bridge reads, "Stop! Pay troll!" +100 The wreckage of a bridge (and a dead bear) can be seen at the bottom +100 of the chasm. +33 *Troll +000 A burly troll stands by the bridge and insists you throw him a +000 treasure before you may cross. +100 The troll steps out from beneath the bridge and blocks your way. +200 >$< (Chased away) +34 *Phony troll +000 The troll is nowhere to be seen. +35 >$< (Bear uses rtext 141) +000 There is a ferocious cave bear eying you from the far end of the room! +100 There is a gentle cave bear sitting placidly in one corner. +200 There is a contented-looking bear wandering about nearby. +300 >$< (Dead) +36 *Message in second maze +000 There is a message scrawled in the dust in a flowery script, reading: +000 "This is not the maze where the pirate leaves his treasure chest." +37 *Volcano and/or geyser +000 >$< +38 *Vending machine +000 There is a massive vending machine here. The instructions on it read: +000 "Drop coins here to receive fresh batteries." +39 Batteries +000 There are fresh batteries here. +100 Some worn-out batteries have been discarded nearby. +40 *Carpet and/or moss +000 >$< +50 Large gold nugget +000 There is a large sparkling nugget of gold here! +51 Several diamonds +000 There are diamonds here! +52 Bars of silver +000 There are bars of silver here! +53 Precious jewelry +000 There is precious jewelry here! +54 Rare coins +000 There are many coins here! +55 Treasure chest +000 The pirate's treasure chest is here! +56 Golden eggs +000 There is a large nest here, full of golden eggs! +100 The nest of golden eggs has vanished! +200 Done! +57 Jeweled trident +000 There is a jewel-encrusted trident here! +58 Ming vase +000 There is a delicate, precious, Ming vase here! +100 The vase is now resting, delicately, on a velvet pillow. +200 The floor is littered with worthless shards of pottery. +300 The Ming vase drops with a delicate crash. +59 Egg-sized emerald +000 There is an emerald here the size of a plover's egg! +60 Platinum pyramid +000 There is a platinum pyramid here, 8 inches on a side! +61 Glistening pearl +000 Off to one side lies a glistening pearl! +62 Persian rug +000 There is a Persian rug spread out on the floor! +100 The dragon is sprawled out on a Persian rug!! +63 Rare spices +000 There are rare spices here! +64 Golden chain +000 There is a golden chain lying in a heap on the floor! +100 The bear is locked to the wall with a golden chain! +200 There is a golden chain locked to the wall! +-1 +6 +1 Somewhere nearby is Colossal Cave, where others have found fortunes in +1 treasure and gold, though it is rumored that some who enter are never +1 seen again. Magic is said to work in the cave. I will be your eyes +1 and hands. Direct me with commands of 1 or 2 words. I should warn +1 you that I look at only the first five letters of each word, so you'll +1 have to enter "northeast" as "ne" to distinguish it from "north". +1 (Should you get stuck, type "help" for some general hints. For +1 information on how to end your adventure, etc., type "info".) +1 - - - +1 This program was originally developed by Will Crowther. Most of the +1 features of the current program were added by Don Woods. Address +1 complaints about the UNIX version to Jim Gillogly (jim@rand.org). +2 A little dwarf with a big knife blocks your way. +3 A little dwarf just walked around a corner, saw you, threw a little +3 axe at you (which missed), cursed, and ran away. +4 There is a threatening little dwarf in the room with you! +5 One sharp nasty knife is thrown at you! +6 None of them hit you! +7 One of them gets you! +8 A hollow voice says "Plugh". +9 There is no way to go that direction. +10 I am unsure how you are facing. Use compass points or nearby objects. +11 I don't know in from out here. Use compass points or name something +11 in the general direction you want to go. +12 I don't know how to apply that word here. +13 I don't understand that! +14 I'm game. Would you care to explain how? +15 Sorry, but I am not allowed to give more detail. I will repeat the +15 long description of your location. +16 It is now pitch dark. If you proceed you will likely fall into a pit. +17 If you prefer, simply type w rather than west. +18 Are you trying to catch the bird? +19 The bird is frightened right now and you cannot catch it no matter +19 what you try. Perhaps you might try later. +20 Are you trying to somehow deal with the snake? +21 You can't kill the snake, or drive it away, or avoid it, or anything +21 like that. There is a way to get by, but you don't have the necessary +21 resources right now. +22 Do you really want to quit now? +23 You fell into a pit and broke every bone in your body! +24 You are already carrying it! +25 You can't be serious! +26 The bird was unafraid when you entered, but as you approach it becomes +26 disturbed and you cannot catch it. +27 You can catch the bird, but you cannot carry it. +28 There is nothing here with a lock! +29 You aren't carrying it! +30 The little bird attacks the green snake, and in an astounding flurry +30 drives the snake away. +31 You have no keys! +32 It has no lock. +33 I don't know how to lock or unlock such a thing. +34 It was already locked. +35 The grate is now locked. +36 The grate is now unlocked. +37 It was already unlocked. +38 You have no source of light. +39 Your lamp is now on. +40 Your lamp is now off. +41 There is no way to get past the bear to unlock the chain, which is +41 probably just as well. +42 Nothing happens. +43 Where? +44 There is nothing here to attack. +45 The little bird is now dead. Its body disappears. +46 Attacking the snake both doesn't work and is very dangerous. +47 You killed a little dwarf. +48 You attack a little dwarf, but he dodges out of the way. +49 With what? Your bare hands? +50 Good try, but that is an old worn-out magic word. +51 I know of places, actions, and things. Most of my vocabulary +51 describes places and is used to move you there. To move, try words +51 like forest, building, downstream, enter, east, west, north, south, +51 up, or down. I know about a few special objects, like a black rod +51 hidden in the cave. These objects can be manipulated using some of +51 the action words that I know. Usually you will need to give both the +51 object and action words (in either order), but sometimes I can infer +51 the object from the verb alone. Some objects also imply verbs; in +51 particular, "inventory" implies "take inventory", which causes me to +51 give you a list of what you're carrying. The objects have side +51 effects; for instance, the rod scares the bird. Usually people having +51 trouble moving just need to try a few more words. Usually people +51 trying unsuccessfully to manipulate an object are attempting something +51 beyond their (or my!) capabilities and should try a completely +51 different tack. To speed the game you can sometimes move long +51 distances with a single word. For example, "building" usually gets +51 you to the building from anywhere above ground except when lost in the +51 forest. Also, note that cave passages turn a lot, and that leaving a +51 room to the north does not guarantee entering the next from the south. +51 Good luck! +52 It misses! +53 It gets you! +54 OK +55 You can't unlock the keys. +56 You have crawled around in some little holes and wound up back in the +56 main passage. +57 I don't know where the cave is, but hereabouts no stream can run on +57 the surface for long. I would try the stream. +58 I need more detailed instructions to do that. +59 I can only tell you what you see as you move about and manipulate +59 things. I cannot tell you where remote things are. +60 I don't know that word. +61 What? +62 Are you trying to get into the cave? +63 The grate is very solid and has a hardened steel lock. You cannot +63 enter without a key, and there are no keys nearby. I would recommend +63 looking elsewhere for the keys. +64 The trees of the forest are large hardwood oak and maple, with an +64 occasional grove of pine or spruce. There is quite a bit of under- +64 growth, largely birch and ash saplings plus nondescript bushes of +64 various sorts. This time of year visibility is quite restricted by +64 all the leaves, but travel is quite easy if you detour around the +64 spruce and berry bushes. +65 Welcome to Adventure!! Would you like instructions? +66 Digging without a shovel is quite impractical. Even with a shovel +66 progress is unlikely. +67 Blasting requires dynamite. +68 I'm as confused as you are. +69 Mist is a white vapor, usually water, seen from time to time in +69 caverns. It can be found anywhere but is frequently a sign of a deep +69 pit leading down to water. +70 Your feet are now wet. +71 I think I just lost my appetite. +72 Thank you, it was delicious! +73 You have taken a drink from the stream. The water tastes strongly of +73 minerals, but is not unpleasant. It is extremely cold. +74 The bottle of water is now empty. +75 Rubbing the electric lamp is not particularly rewarding. Anyway, +75 nothing exciting happens. +76 Peculiar. Nothing unexpected happens. +77 Your bottle is empty and the ground is wet. +78 You can't pour that. +79 Watch it! +80 Which way? +81 Oh dear, you seem to have gotten yourself killed. I might be able to +81 help you out, but I've never really done this before. Do you want me +81 to try to reincarnate you? +82 All right. But don't blame me if something goes wr...... +82 --- Poof!! --- +82 You are engulfed in a cloud of orange smoke. Coughing and gasping, +82 you emerge from the smoke and find.... +83 You clumsy oaf, you've done it again! I don't know how long I can +83 keep this up. Do you want me to try reincarnating you again? +84 Okay, now where did I put my orange smoke?.... >poof!< +84 Everything disappears in a dense cloud of orange smoke. +85 Now you've really done it! I'm out of orange smoke! You don't expect +85 me to do a decent reincarnation without any orange smoke, do you? +86 Okay, if you're so smart, do it yourself! I'm leaving! +90 >>> Messages 81 thru 90 are reserved for "obituaries". <<< +91 Sorry, but I no longer seem to remember how it was you got here. +92 You can't carry anything more. You'll have to drop something first. +93 You can't go through a locked steel grate! +94 I believe what you want is right here with you. +95 You don't fit through a two-inch slit! +96 I respectfully suggest you go across the bridge instead of jumping. +97 There is no way across the fissure. +98 You're not carrying anything. +99 You are currently holding the following: +100 It's not hungry (it's merely pinin' for the fjords). Besides, you +100 have no bird seed. +101 The snake has now devoured your bird. +102 There's nothing here it wants to eat (except perhaps you). +103 You fool, dwarves eat only coal! Now you've made him *really* mad!! +104 You have nothing in which to carry it. +105 Your bottle is already full. +106 There is nothing here with which to fill the bottle. +107 Your bottle is now full of water. +108 Your bottle is now full of oil. +109 You can't fill that. +110 Don't be ridiculous! +111 The door is extremely rusty and refuses to open. +112 The plant indignantly shakes the oil off its leaves and asks, "water?" +113 The hinges are quite thoroughly rusted now and won't budge. +114 The oil has freed up the hinges so that the door will now move, +114 although it requires some effort. +115 The plant has exceptionally deep roots and cannot be pulled free. +116 The dwarves' knives vanish as they strike the walls of the cave. +117 Something you're carrying won't fit through the tunnel with you. +117 You'd best take inventory and drop something. +118 You can't fit this five-foot clam through that little passage! +119 You can't fit this five-foot oyster through that little passage! +120 I advise you to put down the clam before opening it. >strain!< +121 I advise you to put down the oyster before opening it. >wrench!< +122 You don't have anything strong enough to open the clam. +123 You don't have anything strong enough to open the oyster. +124 A glistening pearl falls out of the clam and rolls away. Goodness, +124 this must really be an oyster. (I never was very good at identifying +124 bivalves.) Whatever it is, it has now snapped shut again. +125 The oyster creaks open, revealing nothing but oyster inside. It +125 promptly snaps shut again. +126 You have crawled around in some little holes and found your way +126 blocked by a recent cave-in. You are now back in the main passage. +127 There are faint rustling noises from the darkness behind you. +128 Out from the shadows behind you pounces a bearded pirate! "Har, har," +128 he chortles, "I'll just take all this booty and hide it away with me +128 chest deep in the maze!" He snatches your treasure and vanishes into +128 the gloom. +129 A sepulchral voice reverberating through the cave, says, "Cave closing +129 soon. All adventurers exit immediately through Main Office." +130 A mysterious recorded voice groans into life and announces: +130 "This exit is closed. Please leave via Main Office." +131 It looks as though you're dead. Well, seeing as how it's so close to +131 closing time anyway, I think we'll just call it a day. +132 The sepulchral voice intones, "The cave is now closed." As the echoes +132 fade, there is a blinding flash of light (and a small puff of orange +132 smoke). . . . As your eyes refocus, you look around and find... +133 There is a loud explosion, and a twenty-foot hole appears in the far +133 wall, burying the dwarves in the rubble. You march through the hole +133 and find yourself in the Main Office, where a cheering band of +133 friendly elves carry the conquering adventurer off into the sunset. +134 There is a loud explosion, and a twenty-foot hole appears in the far +134 wall, burying the snakes in the rubble. A river of molten lava pours +134 in through the hole, destroying everything in its path, including you! +135 There is a loud explosion, and you are suddenly splashed across the +135 walls of the room. +136 The resulting ruckus has awakened the dwarves. There are now several +136 threatening little dwarves in the room with you! Most of them throw +136 knives at you! All of them get you! +137 Oh, leave the poor unhappy bird alone. +138 I dare say whatever you want is around here somewhere. +139 I don't know the word "stop". Use "quit" if you want to give up. +140 You can't get there from here. +141 You are being followed by a very large, tame bear. +142 If you want to end your adventure early, say "quit". To suspend your +142 adventure such that you can continue later, say "suspend" (or "pause" +142 or "save"). To see what hours the cave is normally open, say "hours". +142 To see how well you're doing, say "score". To get full credit for a +142 treasure, you must have left it safely in the building, though you get +142 partial credit just for locating it. You lose points for getting +142 killed, or for quitting, though the former costs you more. There are +142 also points based on how much (if any) of the cave you've managed to +142 explore; in particular, there is a large bonus just for getting in (to +142 distinguish the beginners from the rest of the pack), and there are +142 other ways to determine whether you've been through some of the more +142 harrowing sections. If you think you've found all the treasures, just +142 keep exploring for a while. If nothing interesting happens, you +142 haven't found them all yet. If something interesting *does* happen, +142 it means you're getting a bonus and have an opportunity to garner many +142 more points in the Master's Section. I may occasionally offer hints +142 if you seem to be having trouble. If I do, I'll warn you in advance +142 how much it will affect your score to accept the hints. Finally, to +142 save paper, you may specify "brief", which tells me never to repeat +142 the full description of a place unless you explicitly ask me to. +143 Do you indeed wish to quit now? +144 There is nothing here with which to fill the vase. +145 The sudden change in temperature has delicately shattered the vase. +146 It is beyond your power to do that. +147 I don't know how. +148 It is too far up for you to reach. +149 You killed a little dwarf. The body vanishes in a cloud of greasy +149 black smoke. +150 The shell is very strong and is impervious to attack. +151 What's the matter, can't you read? Now you'd best start over. +152 The axe bounces harmlessly off the dragon's thick scales. +153 The dragon looks rather nasty. You'd best not try to get by. +154 The little bird attacks the green dragon, and in an astounding flurry +154 gets burnt to a cinder. The ashes blow away. +155 On what? +156 Okay, from now on I'll only describe a place in full the first time +156 you come to it. To get the full description, say "look". +157 Trolls are close relatives with the rocks and have skin as tough as +157 that of a rhinoceros. The troll fends off your blows effortlessly. +158 The troll deftly catches the axe, examines it carefully, and tosses it +158 back, declaring, "Good workmanship, but it's not valuable enough." +159 The troll catches your treasure and scurries away out of sight. +160 The troll refuses to let you cross. +161 There is no longer any way across the chasm. +162 Just as you reach the other side, the bridge buckles beneath the +162 weight of the bear, which was still following you around. You +162 scrabble desperately for support, but as the bridge collapses you +162 stumble back and fall into the chasm. +163 The bear lumbers toward the troll, who lets out a startled shriek and +163 scurries away. The bear soon gives up the pursuit and wanders back. +164 The axe misses and lands near the bear where you can't get at it. +165 With what? Your bare hands? Against *his* bear hands?? +166 The bear is confused; he only wants to be your friend. +167 For crying out loud, the poor thing is already dead! +168 The bear eagerly wolfs down your food, after which he seems to calm +168 down considerably and even becomes rather friendly. +169 The bear is still chained to the wall. +170 The chain is still locked. +171 The chain is now unlocked. +172 The chain is now locked. +173 There is nothing here to which the chain can be locked. +174 There is nothing here to eat. +175 Do you want the hint? +176 Do you need help getting out of the maze? +177 You can make the passages look less alike by dropping things. +178 Are you trying to explore beyond the Plover Room? +179 There is a way to explore that region without having to worry about +179 falling into a pit. None of the objects available is immediately +179 useful in discovering the secret. +180 Do you need help getting out of here? +181 Don't go west. +182 Gluttony is not one of the troll's vices. Avarice, however, is. +183 Your lamp is getting dim. You'd best start wrapping this up, unless +183 You can find some fresh batteries. I seem to recall there's a vending +183 machine in the maze. Bring some coins with you. +184 Your lamp has run out of power. +185 There's not much point in wandering around out here, and you can't +185 explore the cave without a lamp. So let's just call it a day. +186 There are faint rustling noises from the darkness behind you. As you +186 turn toward them, the beam of your lamp falls across a bearded pirate. +186 He is carrying a large chest. "Shiver me timbers!" he cries, "I've +186 been spotted! I'd best hie meself off to the maze to hide me chest!" +186 With that, he vanishes into the gloom. +187 Your lamp is getting dim. You'd best go back for those batteries. +188 Your lamp is getting dim. I'm taking the liberty of replacing the +188 batteries. +189 Your lamp is getting dim, and you're out of spare batteries. You'd +189 best start wrapping this up. +190 I'm afraid the magazine is written in Dwarvish. +191 "This is not the maze where the pirate leaves his treasure chest." +192 Hmmm, this looks like a clue, which means it'll cost you 10 points to +192 read it. Should I go ahead and read it anyway? +193 It says, "there is something strange about this place, such that one +193 of the words I've always known now has a new effect." +194 It says the same thing it did before. +195 I'm afraid I don't understand. +196 "Congratulations on bringing light into the Dark-Room!" +197 You strike the mirror a resounding blow, whereupon it shatters into a +197 myriad tiny fragments. +198 You have taken the vase and hurled it delicately to the ground. +199 You prod the nearest dwarf, who wakes up grumpily, takes one look at +199 you, curses, and grabs for his axe. +200 Is this acceptable? +201 There's no point in suspending a demonstration game. +202 You awaken only to discover your bits have been dissolving while you +202 slept. You disappear in a cloud of greasy black smoke. +-1 +7 +1 3 +2 3 +3 8 9 +4 10 +5 11 +6 0 +7 14 15 +8 13 +9 94 -1 +10 96 +11 19 -1 +12 17 27 +13 101 -1 +14 103 +15 0 +16 106 +17 0 -1 +18 0 +19 3 +20 3 +21 0 +22 0 +23 109 -1 +24 25 -1 +25 23 67 +26 111 -1 +27 35 110 +28 0 +29 97 -1 +30 0 -1 +31 119 121 +32 117 122 +33 117 122 +34 0 0 +35 130 -1 +36 0 -1 +37 126 -1 +38 140 -1 +39 0 +40 96 -1 +50 18 +51 27 +52 28 +53 29 +54 30 +55 0 +56 92 +57 95 +58 97 +59 100 +60 101 +61 0 +62 119 121 +63 127 +64 130 -1 +-1 +8 +1 24 +2 29 +3 0 +4 33 +5 0 +6 33 +7 38 +8 38 +9 42 +10 14 +11 43 +12 110 +13 29 +14 110 +15 73 +16 75 +17 29 +18 13 +19 59 +20 59 +21 174 +22 109 +23 67 +24 13 +25 147 +26 155 +27 195 +28 146 +29 110 +30 13 +31 13 +-1 +9 +0 1 2 3 4 5 6 7 8 9 10 +0 100 115 116 126 +2 1 3 4 7 38 95 113 24 +1 24 +3 46 47 48 54 56 58 82 85 86 +3 122 123 124 125 126 127 128 129 130 +4 8 +5 13 +6 19 +7 42 43 44 45 46 47 48 49 50 51 +7 52 53 54 55 56 80 81 82 86 87 +8 99 100 101 +9 108 +-1 +10 +35 You are obviously a rank amateur. Better luck next time. +100 Your score qualifies you as a Novice class Adventurer. +130 You have achieved the rating: "Experienced Adventurer". +200 You may now consider yourself a "Seasoned Adventurer". +250 You have reached "Junior Master" status. +300 Your score puts you in Master Adventurer Class C. +330 Your score puts you in Master Adventurer Class B. +349 Your score puts you in Master Adventurer Class A. +9999 All of Adventuredom gives tribute to you, Adventurer Grandmaster! +-1 +11 +2 9999 10 0 0 +3 9999 5 0 0 +4 4 2 62 63 +5 5 2 18 19 +6 8 2 20 21 +7 75 4 176 177 +8 25 5 178 179 +9 20 3 180 181 +-1 +12 +1 A large cloud of green smoke appears in front of you. It clears away +1 to reveal a tall wizard, clothed in grey. He fixes you with a steely +1 glare and declares, "This adventure has lasted too long." With that +1 he makes a single pass over you with his hands, and everything around +1 you fades away into a grey nothingness. +2 Even wizards have to wait longer than that! +3 I'm terribly sorry, but Colossal Cave is closed. Our hours are: +4 Only wizards are permitted within the cave right now. +5 We do allow visitors to make short explorations during our off hours. +5 Would you like to do that? +6 Colossal Cave is open to regular adventurers at the following hours: +7 Very well. +8 Only a wizard may continue an adventure this soon. +9 I suggest you resume your adventure at a later time. +10 Do you wish to see the hours? +11 Do you wish to change the hours? +12 New magic word (null to leave unchanged): +13 New magic number (null to leave unchanged): +14 Do you wish to change the message of the day? +15 Okay. You can save this version now. +16 Are you a wizard? +17 Prove it! Say the magic word! +18 That is not what I thought it was. Do you know what I thought it was? +19 Oh dear, you really *are* a wizard! Sorry to have bothered you . . . +20 Foo, you are nothing but a charlatan! +21 New hours specified by defining "prime time". Give only the hour +21 (E.g. 14, not 14:00 or 2pm). Enter a negative number after last pair. +22 New hours for Colossal Cave: +23 Limit lines to 70 chars. End with null line. +24 Line too long, retype: +25 Not enough room for another line. Ending message here. +26 Do you wish to (re)schedule the next holiday? +27 To begin how many days from today? +28 To last how many days (zero if no holiday)? +29 To be called what (up to 20 characters)? +30 Too small! Assuming minimum value (45 minutes). +31 Break out of this and save your core-image. +32 Be sure to save your core-image... +-1 +0 + glorkz 8.1 93/05/31 diff --git a/games/adventure/hdr.h b/games/adventure/hdr.h new file mode 100644 index 000000000..8a2359f39 --- /dev/null +++ b/games/adventure/hdr.h @@ -0,0 +1,157 @@ +/* $NetBSD: hdr.h,v 1.13 2009/08/25 06:56:52 dholland Exp $ */ + +/*- + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * The game adventure was originally written in Fortran by Will Crowther + * and Don Woods. It was later translated to C and enhanced by Jim + * Gillogly. This code is derived from software contributed to Berkeley + * by Jim Gillogly at The Rand Corporation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)hdr.h 8.1 (Berkeley) 5/31/93 + */ + +/* ADVENTURE -- Jim Gillogly, Jul 1977 + * This program is a re-write of ADVENT, written in FORTRAN mostly by + * Don Woods of SAIL. In most places it is as nearly identical to the + * original as possible given the language and word-size differences. + * A few places, such as the message arrays and travel arrays were changed + * to reflect the smaller core size and word size. The labels of the + * original are reflected in this version, so that the comments of the + * fortran are still applicable here. + * + * The data file distributed with the fortran source is assumed to be called + * "glorkz" in the directory where the program is first run. + * + * The original FORTRAN version can be found at + * . + */ + +/* hdr.h: included by c advent files */ + +#include + +extern volatile sig_atomic_t delhit; +extern int yea; +extern char data_file[]; /* Virtual data file */ + +#define TAB 011 +#define LF 012 +#define FLUSHLINE do { int flushline_ch; while ((flushline_ch = getchar()) != EOF && flushline_ch != '\n'); } while (0) +#define FLUSHLF while (next()!=LF) + +extern int loc, newloc, oldloc, oldloc2, wasdark, gaveup, kq, k, k2; +extern char *wd1, *wd2; /* the complete words */ +extern int verb, obj, spk; +extern int blklin; +extern int saveday, savet, maxscore, latency; + +#define SHORT 50 /* How short is a demo game? */ + +#define MAXSTR 20 /* max length of user's words */ + +#define HTSIZE 512 /* max number of vocab words */ +extern struct hashtab { /* hash table for vocabulary */ + int val; /* word type &index (ktab) */ + char *atab; /* pointer to actual string */ +} voc[HTSIZE]; +#define SEED 1815622 /* "Encryption" seed */ + +struct text { + char *seekadr;/* Msg start in virtual disk */ + int txtlen; /* length of msg starting here */ +}; + +#define RTXSIZE 205 +extern struct text rtext[RTXSIZE]; /* random text messages */ + +#define MAGSIZE 35 +extern struct text mtext[MAGSIZE]; /* magic messages */ + +extern int classes; +#define CLSMAX 12 +extern struct text ctext[CLSMAX]; /* classes of adventurer */ +extern int cval[CLSMAX]; + +extern struct text ptext[101]; /* object descriptions */ + +#define LOCSIZE 141 /* number of locations */ +extern struct text ltext[LOCSIZE]; /* long loc description */ +extern struct text stext[LOCSIZE]; /* short loc descriptions */ + +extern struct travlist { /* direcs & conditions of travel */ + struct travlist *next; /* ptr to next list entry */ + int conditions; /* m in writeup (newloc / 1000) */ + int tloc; /* n in writeup (newloc % 1000) */ + int tverb; /* the verb that takes you there */ +} *travel[LOCSIZE], *tkk; /* travel is closer to keys(...) */ + +extern int atloc[LOCSIZE]; + +extern int plac[101]; /* initial object placement */ +extern int fixd[101], fixed[101]; /* location fixed? */ + +extern int actspeak[35]; /* rtext msg for verb */ + +extern int cond[LOCSIZE]; /* various condition bits */ + +extern int setbit[16]; /* bit defn masks 1,2,4,... */ + +extern int hintmax; +extern int hints[20][5]; /* info on hints */ +extern int hinted[20], hintlc[20]; + +extern int place[101], prop[101], links[201]; +extern int abb[LOCSIZE]; + +extern int maxtrs, tally, tally2; /* treasure values */ + +#define FALSE 0 +#define TRUE 1 + +extern int keys, lamp, grate, cage, rod, rod2, steps, /* mnemonics */ + bird, door, pillow, snake, fissure, tablet, clam, oyster, + magazine, dwarf, knife, food, bottle, water, oil, plant, plant2, + axe, mirror, dragon, chasm, troll, troll2, bear, message, + vend, batter, nugget, coins, chest, eggs, trident, vase, + emerald, pyramid, pearl, rug, chain, spices, back, look, cave, + null, entrance, depression, /*enter, stream, pour,*/ say, lock, + throw, find, invent; + +extern int chloc, chloc2, dseen[7], dloc[7], /* dwarf stuff */ + odloc[7], dflag, daltloc; + +extern int tk[21], stick, dtotal, attack; +extern int turns, lmwarn, iwest, knfloc, detail, /* various flags and + * counters */ + abbnum, maxdie, numdie, holding, dkill, foobar, bonus, clock1, + clock2, saved, isclosing, panic, closed, scoring; + +extern int demo, limit; + +#define DECR(a,b,c,d,e) decr(a+'+',b+'-',c+'#',d+'&',e+'%') diff --git a/games/adventure/init.c b/games/adventure/init.c new file mode 100644 index 000000000..bb316c515 --- /dev/null +++ b/games/adventure/init.c @@ -0,0 +1,302 @@ +/* $NetBSD: init.c,v 1.20 2011/08/31 16:24:55 plunky Exp $ */ + +/*- + * Copyright (c) 1993 + * The Regents of the University of California. All rights reserved. + * + * The game adventure was originally written in Fortran by Will Crowther + * and Don Woods. It was later translated to C and enhanced by Jim + * Gillogly. This code is derived from software contributed to Berkeley + * by Jim Gillogly at The Rand Corporation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#ifndef lint +#if 0 +static char sccsid[] = "@(#)init.c 8.1 (Berkeley) 6/2/93"; +#else +__RCSID("$NetBSD: init.c,v 1.20 2011/08/31 16:24:55 plunky Exp $"); +#endif +#endif /* not lint */ + +/* Re-coding of advent in C: data initialization */ + +#include +#include +#include +#include +#include +#include + +#include "hdr.h" +#include "extern.h" + +static void linkdata(void); + +int blklin = TRUE; + +int setbit[16] = {1, 2, 4, 010, 020, 040, 0100, 0200, 0400, 01000, 02000, + 04000, 010000, 020000, 040000, 0100000}; + +volatile sig_atomic_t delhit; +int yea; + +int loc, newloc, oldloc, oldloc2, wasdark, gaveup, kq, k, k2; +char *wd1, *wd2; /* the complete words */ +int verb, obj, spk; +int saveday, savet, maxscore, latency; + +struct hashtab voc[HTSIZE]; + +struct text rtext[RTXSIZE]; /* random text messages */ + +struct text mtext[MAGSIZE]; /* magic messages */ + +int classes; + +struct text ctext[CLSMAX]; /* classes of adventurer */ +int cval[CLSMAX]; + +struct text ptext[101]; /* object descriptions */ + +struct text ltext[LOCSIZE]; /* long loc description */ +struct text stext[LOCSIZE]; /* short loc descriptions */ + +struct travlist *travel[LOCSIZE], *tkk; /* travel is closer to keys(...) */ + +int atloc[LOCSIZE]; + +int plac[101]; /* initial object placement */ +int fixd[101], fixed[101]; /* location fixed? */ + +int actspeak[35]; /* rtext msg for verb */ + +int cond[LOCSIZE]; /* various condition bits */ + +int hintmax; +int hints[20][5]; /* info on hints */ +int hinted[20], hintlc[20]; + +int place[101], prop[101], links[201]; +int abb[LOCSIZE]; + +int maxtrs, tally, tally2; /* treasure values */ + +int keys, lamp, grate, cage, rod, rod2, steps, /* mnemonics */ + bird, door, pillow, snake, fissure, tablet, clam, oyster, + magazine, dwarf, knife, food, bottle, water, oil, plant, plant2, + axe, mirror, dragon, chasm, troll, troll2, bear, message, + vend, batter, nugget, coins, chest, eggs, trident, vase, + emerald, pyramid, pearl, rug, chain, spices, back, look, cave, + null, entrance, depression, say, lock, throw, + find, invent; + +static int enter, /*stream,*/ pour; + +int chloc, chloc2, dseen[7], dloc[7], /* dwarf stuff */ + odloc[7], dflag, daltloc; + +int tk[21], stick, dtotal, attack; +int turns, lmwarn, iwest, knfloc, detail, /* various flags and + * counters */ + abbnum, maxdie, numdie, holding, dkill, foobar, bonus, clock1, + clock2, saved, isclosing, panic, closed, scoring; + +int demo, limit; + +/* everything for 1st time run */ +void +init(void) +{ + rdata(); /* read data from orig. file */ + linkdata(); + poof(); +} + +char * +decr(int a, int b, int c, int d, int e) +{ + static char buf[6]; + + buf[0] = a - '+'; + buf[1] = b - '-'; + buf[2] = c - '#'; + buf[3] = d - '&'; + buf[4] = e - '%'; + buf[5] = 0; + return buf; +} + +static void +linkdata(void) +{ /* secondary data manipulation */ + int i, j; + + /* array linkages */ + for (i = 1; i < LOCSIZE; i++) + if (ltext[i].seekadr != 0 && travel[i] != 0) + if ((travel[i]->tverb) == 1) + cond[i] = 2; + for (j = 100; j > 0; j--) + if (fixd[j] > 0) { + drop(j + 100, fixd[j]); + drop(j, plac[j]); + } + for (j = 100; j > 0; j--) { + fixed[j] = fixd[j]; + if (plac[j] != 0 && fixd[j] <= 0) + drop(j, plac[j]); + } + + maxtrs = 79; + tally = 0; + tally2 = 0; + + for (i = 50; i <= maxtrs; i++) { + if (ptext[i].seekadr != 0) + prop[i] = -1; + tally -= prop[i]; + } + + /* define mnemonics */ + keys = vocab(DECR('k', 'e', 'y', 's', '\0'), 1, 0); + lamp = vocab(DECR('l', 'a', 'm', 'p', '\0'), 1, 0); + grate = vocab(DECR('g', 'r', 'a', 't', 'e'), 1, 0); + cage = vocab(DECR('c', 'a', 'g', 'e', '\0'), 1, 0); + rod = vocab(DECR('r', 'o', 'd', '\0', '\0'), 1, 0); + rod2 = rod + 1; + steps = vocab(DECR('s', 't', 'e', 'p', 's'), 1, 0); + bird = vocab(DECR('b', 'i', 'r', 'd', '\0'), 1, 0); + door = vocab(DECR('d', 'o', 'o', 'r', '\0'), 1, 0); + pillow = vocab(DECR('p', 'i', 'l', 'l', 'o'), 1, 0); + snake = vocab(DECR('s', 'n', 'a', 'k', 'e'), 1, 0); + fissure = vocab(DECR('f', 'i', 's', 's', 'u'), 1, 0); + tablet = vocab(DECR('t', 'a', 'b', 'l', 'e'), 1, 0); + clam = vocab(DECR('c', 'l', 'a', 'm', '\0'), 1, 0); + oyster = vocab(DECR('o', 'y', 's', 't', 'e'), 1, 0); + magazine = vocab(DECR('m', 'a', 'g', 'a', 'z'), 1, 0); + dwarf = vocab(DECR('d', 'w', 'a', 'r', 'f'), 1, 0); + knife = vocab(DECR('k', 'n', 'i', 'f', 'e'), 1, 0); + food = vocab(DECR('f', 'o', 'o', 'd', '\0'), 1, 0); + bottle = vocab(DECR('b', 'o', 't', 't', 'l'), 1, 0); + water = vocab(DECR('w', 'a', 't', 'e', 'r'), 1, 0); + oil = vocab(DECR('o', 'i', 'l', '\0', '\0'), 1, 0); + plant = vocab(DECR('p', 'l', 'a', 'n', 't'), 1, 0); + plant2 = plant + 1; + axe = vocab(DECR('a', 'x', 'e', '\0', '\0'), 1, 0); + mirror = vocab(DECR('m', 'i', 'r', 'r', 'o'), 1, 0); + dragon = vocab(DECR('d', 'r', 'a', 'g', 'o'), 1, 0); + chasm = vocab(DECR('c', 'h', 'a', 's', 'm'), 1, 0); + troll = vocab(DECR('t', 'r', 'o', 'l', 'l'), 1, 0); + troll2 = troll + 1; + bear = vocab(DECR('b', 'e', 'a', 'r', '\0'), 1, 0); + message = vocab(DECR('m', 'e', 's', 's', 'a'), 1, 0); + vend = vocab(DECR('v', 'e', 'n', 'd', 'i'), 1, 0); + batter = vocab(DECR('b', 'a', 't', 't', 'e'), 1, 0); + + nugget = vocab(DECR('g', 'o', 'l', 'd', '\0'), 1, 0); + coins = vocab(DECR('c', 'o', 'i', 'n', 's'), 1, 0); + chest = vocab(DECR('c', 'h', 'e', 's', 't'), 1, 0); + eggs = vocab(DECR('e', 'g', 'g', 's', '\0'), 1, 0); + trident = vocab(DECR('t', 'r', 'i', 'd', 'e'), 1, 0); + vase = vocab(DECR('v', 'a', 's', 'e', '\0'), 1, 0); + emerald = vocab(DECR('e', 'm', 'e', 'r', 'a'), 1, 0); + pyramid = vocab(DECR('p', 'y', 'r', 'a', 'm'), 1, 0); + pearl = vocab(DECR('p', 'e', 'a', 'r', 'l'), 1, 0); + rug = vocab(DECR('r', 'u', 'g', '\0', '\0'), 1, 0); + chain = vocab(DECR('c', 'h', 'a', 'i', 'n'), 1, 0); + + back = vocab(DECR('b', 'a', 'c', 'k', '\0'), 0, 0); + look = vocab(DECR('l', 'o', 'o', 'k', '\0'), 0, 0); + cave = vocab(DECR('c', 'a', 'v', 'e', '\0'), 0, 0); + null = vocab(DECR('n', 'u', 'l', 'l', '\0'), 0, 0); + entrance = vocab(DECR('e', 'n', 't', 'r', 'a'), 0, 0); + depression = vocab(DECR('d', 'e', 'p', 'r', 'e'), 0, 0); + enter = vocab(DECR('e', 'n', 't', 'e', 'r'), 0, 0); + + pour = vocab(DECR('p', 'o', 'u', 'r', '\0'), 2, 0); + say = vocab(DECR('s', 'a', 'y', '\0', '\0'), 2, 0); + lock = vocab(DECR('l', 'o', 'c', 'k', '\0'), 2, 0); + throw = vocab(DECR('t', 'h', 'r', 'o', 'w'), 2, 0); + find = vocab(DECR('f', 'i', 'n', 'd', '\0'), 2, 0); + invent = vocab(DECR('i', 'n', 'v', 'e', 'n'), 2, 0); + + /* initialize dwarves */ + chloc = 114; + chloc2 = 140; + for (i = 1; i <= 6; i++) + dseen[i] = FALSE; + dflag = 0; + dloc[1] = 19; + dloc[2] = 27; + dloc[3] = 33; + dloc[4] = 44; + dloc[5] = 64; + dloc[6] = chloc; + daltloc = 18; + + /* random flags & ctrs */ + turns = 0; + lmwarn = FALSE; + iwest = 0; + knfloc = 0; + detail = 0; + abbnum = 5; + for (i = 0; i <= 4; i++) + if (rtext[2 * i + 81].seekadr != 0) + maxdie = i + 1; + numdie = holding = dkill = foobar = bonus = 0; + clock1 = 30; + clock2 = 50; + saved = 0; + isclosing = panic = closed = scoring = FALSE; +} + +/* come here if he hits a del */ +void +trapdel(int n __unused) +{ + delhit = 1; /* main checks, treats as QUIT */ + signal(SIGINT, trapdel);/* catch subsequent DELs */ +} + + +void +startup(void) +{ + demo = Start(); + srand((int)time(NULL)); /* random seed */ +#if 0 + srand(371); /* non-random seed */ +#endif + hinted[3] = yes(65, 1, 0); + newloc = 1; + delhit = 0; + limit = 330; + if (hinted[3]) + limit = 1000; /* better batteries if instrucs */ +} diff --git a/games/adventure/io.c b/games/adventure/io.c new file mode 100644 index 000000000..eae7695c5 --- /dev/null +++ b/games/adventure/io.c @@ -0,0 +1,610 @@ +/* $NetBSD: io.c,v 1.22 2009/08/25 06:56:52 dholland Exp $ */ + +/*- + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * The game adventure was originally written in Fortran by Will Crowther + * and Don Woods. It was later translated to C and enhanced by Jim + * Gillogly. This code is derived from software contributed to Berkeley + * by Jim Gillogly at The Rand Corporation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#ifndef lint +#if 0 +static char sccsid[] = "@(#)io.c 8.1 (Berkeley) 5/31/93"; +#else +__RCSID("$NetBSD: io.c,v 1.22 2009/08/25 06:56:52 dholland Exp $"); +#endif +#endif /* not lint */ + +/* Re-coding of advent in C: file i/o and user i/o */ + +#include +#include +#include +#include +#include "hdr.h" +#include "extern.h" + +static int next(void); +static void rdesc(int); +static void rdefault(void); +static void rhints(void); +static void rliq(void); +static void rlocs(void); +static int rnum(void); +static void rtrav(void); +static void rvoc(void); + +/* get command from user */ +/* no prompt, usually */ +void +getin(char **wrd1, char **wrd2) +{ + char *s; + static char wd1buf[MAXSTR], wd2buf[MAXSTR]; + int first, numch, c; + + *wrd1 = wd1buf; /* return ptr to internal str */ + *wrd2 = wd2buf; + wd2buf[0] = 0; /* in case it isn't set here */ + for (s = wd1buf, first = 1, numch = 0;;) { + c = getchar(); + if ((*s = (char)c) >= 'A' && *s <= 'Z') + *s = *s - ('A' - 'a'); + /* convert to upper case */ + switch (c) { /* start reading from user */ + case '\n': + *s = 0; + return; + case ' ': + if (s == wd1buf || s == wd2buf) /* initial blank */ + continue; + *s = 0; + if (first) { /* finished 1st wd; start 2nd */ + first = numch = 0; + s = wd2buf; + break; + } else { /* finished 2nd word */ + FLUSHLINE; + *s = 0; + return; + } + case EOF: + printf("user closed input stream, quitting...\n"); + exit(0); + default: + if (++numch >= MAXSTR) { /* string too long */ + printf("Give me a break!!\n"); + wd1buf[0] = wd2buf[0] = 0; + FLUSHLINE; + return; + } + s++; + } + } +} + +/* confirm with rspeak */ +int +yes(int x, int y, int z) +{ + int result = TRUE; /* pacify gcc */ + int ch; + for (;;) { + rspeak(x); /* tell him what we want */ + if ((ch = getchar()) == 'y') + result = TRUE; + else if (ch == 'n') + result = FALSE; + else if (ch == EOF) { + printf("user closed input stream, quitting...\n"); + exit(0); + } + FLUSHLINE; + if (ch == 'y' || ch == 'n') + break; + printf("Please answer the question.\n"); + } + if (result == TRUE) + rspeak(y); + if (result == FALSE) + rspeak(z); + return (result); +} + +/* confirm with mspeak */ +int +yesm(int x, int y, int z) +{ + int result = TRUE; /* pacify gcc */ + int ch; + for (;;) { + mspeak(x); /* tell him what we want */ + if ((ch = getchar()) == 'y') + result = TRUE; + else if (ch == 'n') + result = FALSE; + else if (ch == EOF) { + printf("user closed input stream, quitting...\n"); + exit(0); + } + FLUSHLINE; + if (ch == 'y' || ch == 'n') + break; + printf("Please answer the question.\n"); + } + if (result == TRUE) + mspeak(y); + if (result == FALSE) + mspeak(z); + return (result); +} +/* FILE *inbuf,*outbuf; */ + +static char *inptr; /* Pointer into virtual disk */ + +static int outsw = 0; /* putting stuff to data file? */ + +static const char iotape[] = "Ax3F'\003tt$8h\315qer*h\017nGKrX\207:!l"; +static const char *tape = iotape; /* pointer to encryption tape */ + +/* next virtual char, bump adr */ +static int +next(void) +{ + int ch; + + ch = (*inptr ^ random()) & 0xFF; /* Decrypt input data */ + if (outsw) { /* putting data in tmp file */ + if (*tape == 0) + tape = iotape; /* rewind encryption tape */ + *inptr = ch ^ *tape++; /* re-encrypt and replace value */ + } + inptr++; + return (ch); +} + +static char breakch; /* tell which char ended rnum */ + +/* "read" data from virtual file */ +void +rdata(void) +{ + int sect; + char ch; + + inptr = data_file; /* Pointer to virtual data file */ + srandom(SEED); /* which is lightly encrypted. */ + + classes = 1; + for (;;) { /* read data sections */ + sect = next() - '0'; /* 1st digit of section number */ +#ifdef VERBOSE + printf("Section %c", sect + '0'); +#endif + if ((ch = next()) != LF) { /* is there a second digit? */ + FLUSHLF; +#ifdef VERBOSE + putchar(ch); +#endif + sect = 10 * sect + ch - '0'; + } +#ifdef VERBOSE + putchar('\n'); +#endif + switch (sect) { + case 0: /* finished reading database */ + return; + case 1: /* long form descriptions */ + rdesc(1); + break; + case 2: /* short form descriptions */ + rdesc(2); + break; + case 3: /* travel table */ + rtrav(); + break; + case 4: /* vocabulary */ + rvoc(); + break; + case 5: /* object descriptions */ + rdesc(5); + break; + case 6: /* arbitrary messages */ + rdesc(6); + break; + case 7: /* object locations */ + rlocs(); + break; + case 8: /* action defaults */ + rdefault(); + break; + case 9: /* liquid assets */ + rliq(); + break; + case 10: /* class messages */ + rdesc(10); + break; + case 11: /* hints */ + rhints(); + break; + case 12: /* magic messages */ + rdesc(12); + break; + default: + printf("Invalid data section number: %d\n", sect); + for (;;) + putchar(next()); + } + if (breakch != LF) /* routines return after "-1" */ + FLUSHLF; + } +} + +static char nbf[12]; + +/* read initial location num */ +static int +rnum(void) +{ + char *s; + tape = iotape; /* restart encryption tape */ + for (s = nbf, *s = 0;; s++) + if ((*s = next()) == TAB || *s == '\n' || *s == LF) + break; + breakch = *s; /* save char for rtrav() */ + *s = 0; /* got the number as ascii */ + if (nbf[0] == '-') + return (-1); /* end of data */ + return (atoi(nbf)); /* convert it to integer */ +} + +static char *seekhere; + +/* read description-format msgs */ +static void +rdesc(int sect) +{ + int locc; + char *seekstart, *maystart; + + seekhere = inptr; /* Where are we in virtual file? */ + outsw = 1; /* these msgs go into tmp file */ + for (oldloc = -1, seekstart = seekhere;;) { + maystart = inptr; /* maybe starting new entry */ + if ((locc = rnum()) != oldloc && oldloc >= 0 /* finished msg */ + /* unless sect 5 */ + && !(sect == 5 && (locc == 0 || locc >= 100))) { + switch (sect) { /* now put it into right table */ + case 1:/* long descriptions */ + ltext[oldloc].seekadr = seekhere; + ltext[oldloc].txtlen = maystart - seekstart; + break; + case 2:/* short descriptions */ + stext[oldloc].seekadr = seekhere; + stext[oldloc].txtlen = maystart - seekstart; + break; + case 5:/* object descriptions */ + ptext[oldloc].seekadr = seekhere; + ptext[oldloc].txtlen = maystart - seekstart; + break; + case 6:/* random messages */ + if (oldloc >= RTXSIZE) + errx(1,"Too many random msgs"); + rtext[oldloc].seekadr = seekhere; + rtext[oldloc].txtlen = maystart - seekstart; + break; + case 10: /* class messages */ + ctext[classes].seekadr = seekhere; + ctext[classes].txtlen = maystart - seekstart; + cval[classes++] = oldloc; + break; + case 12: /* magic messages */ + if (oldloc >= MAGSIZE) + errx(1,"Too many magic msgs"); + mtext[oldloc].seekadr = seekhere; + mtext[oldloc].txtlen = maystart - seekstart; + break; + default: + errx(1,"rdesc called with bad section"); + } + seekhere += maystart - seekstart; + } + if (locc < 0) { + outsw = 0; /* turn off output */ + seekhere += 3; /* -1 */ + return; + } + if (sect != 5 || (locc > 0 && locc < 100)) { + if (oldloc != locc) /* starting a new message */ + seekstart = maystart; + oldloc = locc; + } + FLUSHLF; /* scan the line */ + } +} + +/* read travel table */ +static void +rtrav(void) +{ + int locc; + struct travlist *t = NULL; + char *s; + char buf[12]; + int len, m, n, entries = 0; + + for (oldloc = -1;;) { /* get another line */ + /* end of entry */ + if ((locc = rnum()) != oldloc && oldloc >= 0 && t) { + t->next = 0; /* terminate the old entry */ + /* printf("%d:%d entries\n",oldloc,entries); */ + /* twrite(oldloc); */ + } + if (locc == -1) + return; + if (locc != oldloc) { /* getting a new entry */ + t = travel[locc] = calloc(1, sizeof(*t)); + if (t == NULL) + err(1, NULL); + /* printf("New travel list for %d\n",locc); */ + entries = 0; + oldloc = locc; + } + for (s = buf;; s++) /* get the newloc number /ASCII */ + if ((*s = next()) == TAB || *s == LF) + break; + *s = 0; + len = length(buf) - 1; /* quad long number handling */ + /* printf("Newloc: %s (%d chars)\n",buf,len); */ + if (len < 4) { /* no "m" conditions */ + m = 0; + n = atoi(buf); /* newloc mod 1000 = newloc */ + } else { /* a long integer */ + n = atoi(buf + len - 3); + buf[len - 3] = 0; /* terminate newloc/1000 */ + m = atoi(buf); + } + while (breakch != LF) { /* only do one line at a time */ + if (t == NULL) + abort(); + if (entries++) { + t->next = calloc(1, sizeof(*t)); + if (t->next == NULL) + err(1, NULL); + t = t->next; + } + t->tverb = rnum(); /* get verb from the file */ + t->tloc = n; /* table entry mod 1000 */ + t->conditions = m; /* table entry / 1000 */ + /* printf("entry %d for %d\n",entries,locc); */ + } + } +} +#ifdef DEBUG + +/* travel options from this loc */ +void +twrite(int loq) +{ + struct travlist *t; + printf("If"); + speak(<ext[loq]); + printf("then\n"); + for (t = travel[loq]; t != 0; t = t->next) { + printf("verb %d takes you to ", t->tverb); + if (t->tloc <= 300) + speak(<ext[t->tloc]); + else + if (t->tloc <= 500) + printf("special code %d\n", t->tloc - 300); + else + rspeak(t->tloc - 500); + printf("under conditions %d\n", t->conditions); + } +} +#endif /* DEBUG */ + +/* read the vocabulary */ +static void +rvoc(void) +{ + char *s; + int idx; + char buf[6]; + for (;;) { + idx = rnum(); + if (idx < 0) + break; + for (s = buf, *s = 0;; s++) /* get the word */ + if ((*s = next()) == TAB || *s == '\n' || *s == LF + || *s == ' ') + break; + /* terminate word with newline, LF, tab, blank */ + if (*s != '\n' && *s != LF) + FLUSHLF;/* can be comments */ + *s = 0; + /* printf("\"%s\"=%d\n",buf,idx); */ + vocab(buf, -2, idx); + } +/* prht(); */ +} + +/* initial object locations */ +static void +rlocs(void) +{ + for (;;) { + if ((obj = rnum()) < 0) + break; + plac[obj] = rnum(); /* initial loc for this obj */ + if (breakch == TAB) /* there's another entry */ + fixd[obj] = rnum(); + else + fixd[obj] = 0; + } +} + +/* default verb messages */ +static void +rdefault(void) +{ + for (;;) { + if ((verb = rnum()) < 0) + break; + actspeak[verb] = rnum(); + } +} + +/* liquid assets &c: cond bits */ +static void +rliq(void) +{ + int bitnum; + for (;;) { /* read new bit list */ + if ((bitnum = rnum()) < 0) + break; + for (;;) { /* read locs for bits */ + int n = rnum(); + if (n < 0) + break; + cond[n] |= setbit[bitnum]; + if (breakch == LF) + break; + } + } +} + +static void +rhints(void) +{ + int hintnum, i; + hintmax = 0; + for (;;) { + if ((hintnum = rnum()) < 0) + break; + for (i = 1; i < 5; i++) + hints[hintnum][i] = rnum(); + if (hintnum > hintmax) + hintmax = hintnum; + } +} + + +void +rspeak(int msg) +{ + if (msg != 0) + speak(&rtext[msg]); +} + + +void +mspeak(int msg) +{ + if (msg != 0) + speak(&mtext[msg]); +} + + +/* read, decrypt, and print a message (not ptext) */ +/* msg is a pointer to seek address and length of mess */ +void +speak(const struct text *msg) +{ + char *s, nonfirst; + + s = msg->seekadr; + nonfirst = 0; + while (s - msg->seekadr < msg->txtlen) { /* read a line at a time */ + tape = iotape; /* restart decryption tape */ + while ((*s++ ^ *tape++) != TAB); /* read past loc num */ + /* assume tape is longer than location number */ + /* plus the lookahead put together */ + if ((*s ^ *tape) == '>' && + (*(s + 1) ^ *(tape + 1)) == '$' && + (*(s + 2) ^ *(tape + 2)) == '<') + break; + if (blklin && !nonfirst++) + putchar('\n'); + do { + if (*tape == 0) + tape = iotape; /* rewind decryp tape */ + putchar(*s ^ *tape); + } while ((*s++ ^ *tape++) != LF); /* better end with LF */ + } +} + +/* read, decrypt and print a ptext message */ +/* msg is the number of all the p msgs for this place */ +/* assumes object 1 doesn't have prop 1, obj 2 no prop 2 &c */ +void +pspeak(int m, int skip) +{ + char *s, nonfirst; + char *numst; + struct text *msg; + char *tbuf; + + msg = &ptext[m]; + if ((tbuf = (char *) malloc(msg->txtlen + 1)) == NULL) + err(1, NULL); + memcpy(tbuf, msg->seekadr, msg->txtlen + 1); /* Room to null */ + s = tbuf; + + nonfirst = 0; + while (s - tbuf < msg->txtlen) { /* read line at a time */ + tape = iotape; /* restart decryption tape */ + for (numst = s; (*s ^= *tape++) != TAB; s++); /* get number */ + + /* Temporarily trash the string (cringe) */ + *s++ = 0; /* decrypting number within the string */ + + if (atoi(numst) != 100 * skip && skip >= 0) { + while ((*s++ ^ *tape++) != LF) /* flush the line */ + if (*tape == 0) + tape = iotape; + continue; + } + if ((*s ^ *tape) == '>' && (*(s + 1) ^ *(tape + 1)) == '$' && + (*(s + 2) ^ *(tape + 2)) == '<') + break; + if (blklin && !nonfirst++) + putchar('\n'); + do { + if (*tape == 0) + tape = iotape; + putchar(*s ^ *tape); + } while ((*s++ ^ *tape++) != LF); /* better end with LF */ + if (skip < 0) + break; + } + free(tbuf); +} diff --git a/games/adventure/main.c b/games/adventure/main.c new file mode 100644 index 000000000..ee30e14ec --- /dev/null +++ b/games/adventure/main.c @@ -0,0 +1,763 @@ +/* $NetBSD: main.c,v 1.21 2009/08/25 06:56:52 dholland Exp $ */ + +/*- + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * The game adventure was originally written in Fortran by Will Crowther + * and Don Woods. It was later translated to C and enhanced by Jim + * Gillogly. This code is derived from software contributed to Berkeley + * by Jim Gillogly at The Rand Corporation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#ifndef lint +__COPYRIGHT("@(#) Copyright (c) 1991, 1993\ + The Regents of the University of California. All rights reserved."); +#endif /* not lint */ + +#ifndef lint +#if 0 +static char sccsid[] = "@(#)main.c 8.1 (Berkeley) 6/2/93"; +#else +__RCSID("$NetBSD: main.c,v 1.21 2009/08/25 06:56:52 dholland Exp $"); +#endif +#endif /* not lint */ + +/* Re-coding of advent in C: main program */ + +#include +#include +#include +#include +#include +#include +#include "hdr.h" +#include "extern.h" + +int +main(int argc, char **argv) +{ + int i; + int rval, ll; + struct text *kk; + + /* revoke setgid privileges from dm */ + setgid(getgid()); + + init(); /* Initialize everything */ + signal(SIGINT, trapdel); + + if (argc > 1) { /* Restore file specified */ + /* Restart is label 8305 (Fortran) */ + i = restore(argv[1]); /* See what we've got */ + switch (i) { + case 0: /* The restore worked fine */ + yea = Start(); + k = null; + unlink(argv[1]); /* Don't re-use the save */ + goto l8; /* Get where we're going */ + case 1: /* Couldn't open it */ + errx(1,"can't open file"); /* So give up */ + case 2: /* Oops -- file was altered */ + rspeak(202); /* You dissolve */ + exit(1); /* File could be non-adventure */ + } /* So don't unlink it. */ + } + startup(); /* prepare for a user */ + + for (;;) { /* main command loop (label 2) */ + if (newloc < 9 && newloc != 0 && isclosing) { + rspeak(130); /* if closing leave only by */ + newloc = loc; /* main office */ + if (!panic) + clock2 = 15; + panic = TRUE; + } + rval = fdwarf(); /* dwarf stuff */ + if (rval == 99) + die(99); + +l2000: if (loc == 0) + die(99); /* label 2000 */ + kk = &stext[loc]; + if ((abb[loc] % abbnum) == 0 || kk->seekadr == 0) + kk = <ext[loc]; + if (!forced(loc) && dark()) { + if (wasdark && pct(35)) { + die(90); + goto l2000; + } + kk = &rtext[16]; + } +#if 0 +l2001: +#endif + if (toting(bear)) + rspeak(141); /* 2001 */ + speak(kk); + k = 1; + if (forced(loc)) + goto l8; + if (loc == 33 && pct(25) && !isclosing) + rspeak(8); + if (!dark()) { + abb[loc]++; + for (i = atloc[loc]; i != 0; i = links[i]) { /* 2004 */ + obj = i; + if (obj > 100) + obj -= 100; + if (obj == steps && toting(nugget)) + continue; + if (prop[obj] < 0) { + if (closed) + continue; + prop[obj] = 0; + if (obj == rug || obj == chain) + prop[obj] = 1; + tally--; + if (tally == tally2 && tally != 0) + if (limit > 35) + limit = 35; + } + ll = prop[obj]; /* 2006 */ + if (obj == steps && loc == fixed[steps]) + ll = 1; + pspeak(obj, ll); + } /* 2008 */ + goto l2012; + l2009: k = 54; /* 2009 */ + l2010: spk = k; + l2011: rspeak(spk); + } +l2012: verb = 0; /* 2012 */ + obj = 0; +l2600: checkhints(); /* to 2600-2602 */ + if (closed) { + if (prop[oyster] < 0 && toting(oyster)) + pspeak(oyster, 1); + for (i = 1; i < 100; i++) + if (toting(i) && prop[i] < 0) /* 2604 */ + prop[i] = -1 - prop[i]; + } + wasdark = dark(); /* 2605 */ + if (knfloc > 0 && knfloc != loc) + knfloc = 1; + getin(&wd1, &wd2); + if (delhit) { /* user typed a DEL */ + delhit = 0; /* reset counter */ + copystr("quit", wd1); /* pretend he's quitting */ + *wd2 = 0; + } +l2608: if ((foobar = -foobar) > 0) + foobar = 0; /* 2608 */ + /* should check here for "magic mode" */ + turns++; + if (demo && turns >= SHORT) + done(1); /* to 13000 */ + + if (verb == say && *wd2 != 0) + verb = 0; + if (verb == say) + goto l4090; + if (tally == 0 && loc >= 15 && loc != 33) + clock1--; + if (clock1 == 0) { + closing(); /* to 10000 */ + goto l19999; + } + if (clock1 < 0) + clock2--; + if (clock2 == 0) { + caveclose(); /* to 11000 */ + continue; /* back to 2 */ + } + if (prop[lamp] == 1) + limit--; + if (limit <= 30 && here(batter) && prop[batter] == 0 + && here(lamp)) { + rspeak(188); /* 12000 */ + prop[batter] = 1; + if (toting(batter)) + drop(batter, loc); + limit = limit + 2500; + lmwarn = FALSE; + goto l19999; + } + if (limit == 0) { + limit = -1; /* 12400 */ + prop[lamp] = 0; + rspeak(184); + goto l19999; + } + if (limit < 0 && loc <= 8) { + rspeak(185); /* 12600 */ + gaveup = TRUE; + done(2); /* to 20000 */ + } + if (limit <= 30) { + if (lmwarn || !here(lamp)) + goto l19999; /* 12200 */ + lmwarn = TRUE; + spk = 187; + if (place[batter] == 0) + spk = 183; + if (prop[batter] == 1) + spk = 189; + rspeak(spk); + } +l19999: k = 43; + if (liqloc(loc) == water) + k = 70; + if (weq(wd1, "enter") && + (weq(wd2, "strea") || weq(wd2, "water"))) + goto l2010; + if (weq(wd1, "enter") && *wd2 != 0) + goto l2800; + if ((!weq(wd1, "water") && !weq(wd1, "oil")) + || (!weq(wd2, "plant") && !weq(wd2, "door"))) + goto l2610; + if (at(vocab(wd2, 1, 0))) + copystr("pour", wd2); + +l2610: if (weq(wd1, "west")) + if (++iwest == 10) + rspeak(17); +l2630: i = vocab(wd1, -1, 0); + if (i == -1) { + spk = 60; /* 3000 */ + if (pct(20)) + spk = 61; + if (pct(20)) + spk = 13; + rspeak(spk); + goto l2600; + } + k = i % 1000; + kq = i / 1000 + 1; + switch (kq) { + case 1: + goto l8; + case 2: + goto l5000; + case 3: + goto l4000; + case 4: + goto l2010; + default: + bug(22); + } + +l8: + switch (march()) { + case 2: + continue; /* i.e. goto l2 */ + case 99: + die(99); + goto l2000; + default: + bug(110); + } + +l2800: copystr(wd2, wd1); + *wd2 = 0; + goto l2610; + +l4000: verb = k; + spk = actspeak[verb]; + if (*wd2 != 0 && verb != say) + goto l2800; + if (verb == say) + obj = *wd2; + if (obj != 0) + goto l4090; +#if 0 +l4080: +#endif + switch (verb) { + case 1: /* take = 8010 */ + if (atloc[loc] == 0 || links[atloc[loc]] != 0) + goto l8000; + for (i = 1; i <= 5; i++) + if (dloc[i] == loc && dflag >= 2) + goto l8000; + obj = atloc[loc]; + goto l9010; + case 2: + case 3: + case 9: /* 8000 : drop,say,wave */ + case 10: + case 16: + case 17: /* calm,rub,toss */ + case 19: + case 21: + case 28: /* find,feed,break */ + case 29: /* wake */ + l8000: printf("%s what?\n", wd1); + obj = 0; + goto l2600; + case 4: + case 6: /* 8040 open,lock */ + spk = 28; + if (here(clam)) + obj = clam; + if (here(oyster)) + obj = oyster; + if (at(door)) + obj = door; + if (at(grate)) + obj = grate; + if (obj != 0 && here(chain)) + goto l8000; + if (here(chain)) + obj = chain; + if (obj == 0) + goto l2011; + goto l9040; + case 5: + goto l2009; /* nothing */ + case 7: + goto l9070; /* on */ + case 8: + goto l9080; /* off */ + case 11: + goto l8000; /* walk */ + case 12: + goto l9120; /* kill */ + case 13: + goto l9130; /* pour */ + case 14: /* eat: 8140 */ + if (!here(food)) + goto l8000; + l8142: destroy(food); + spk = 72; + goto l2011; + case 15: + goto l9150; /* drink */ + case 18: /* quit: 8180 */ + gaveup = yes(22, 54, 54); + if (gaveup) + done(2); /* 8185 */ + goto l2012; + case 20: /* invent=8200 */ + spk = 98; + for (i = 1; i <= 100; i++) { + if (i != bear && toting(i)) { + if (spk == 98) + rspeak(99); + blklin = FALSE; + pspeak(i, -1); + blklin = TRUE; + spk = 0; + } + } + if (toting(bear)) + spk = 141; + goto l2011; + case 22: + goto l9220; /* fill */ + case 23: + goto l9230; /* blast */ + case 24: /* score: 8240 */ + scoring = TRUE; + printf("If you were to quit now, you would score"); + printf(" %d out of a possible ", score()); + printf("%d.", maxscore); + scoring = FALSE; + gaveup = yes(143, 54, 54); + if (gaveup) + done(2); + goto l2012; + case 25: /* foo: 8250 */ + k = vocab(wd1, 3, 0); + spk = 42; + if (foobar == 1 - k) + goto l8252; + if (foobar != 0) + spk = 151; + goto l2011; + l8252: foobar = k; + if (k != 4) + goto l2009; + foobar = 0; + if (place[eggs] == plac[eggs] + || (toting(eggs) && loc == plac[eggs])) + goto l2011; + if (place[eggs] == 0 && place[troll] == 0 && + prop[troll] == 0) + prop[troll] = 1; + k = 2; + if (here(eggs)) + k = 1; + if (loc == plac[eggs]) + k = 0; + move(eggs, plac[eggs]); + pspeak(eggs, k); + goto l2012; + case 26: /* brief=8260 */ + spk = 156; + abbnum = 10000; + detail = 3; + goto l2011; + case 27: /* read=8270 */ + if (here(magazine)) + obj = magazine; + if (here(tablet)) + obj = obj * 100 + tablet; + if (here(message)) + obj = obj * 100 + message; + if (closed && toting(oyster)) + obj = oyster; + if (obj > 100 || obj == 0 || dark()) + goto l8000; + goto l9270; + case 30: /* suspend=8300 */ + spk = 201; + if (demo) + goto l2011; + printf("I can suspend your adventure for you so"); + printf(" you can resume later, but\n"); + printf("you will have to wait at least"); + printf(" %d minutes before continuing.", latency); + if (!yes(200, 54, 54)) + goto l2012; + datime(&saveday, &savet); + ciao(); /* Do we quit? */ + continue; /* Maybe not */ + case 31: /* hours=8310 */ + printf("Colossal cave is closed 9am-5pm Mon "); + printf("through Fri except holidays.\n"); + goto l2012; + default: + bug(23); + } + +l4090: + switch (verb) { + case 1: /* take = 9010 */ + l9010: switch (trtake()) { + case 2011: + goto l2011; + case 9220: + goto l9220; + case 2009: + goto l2009; + case 2012: + goto l2012; + default: + bug(102); + } + l9020: case 2: /* drop = 9020 */ + switch (trdrop()) { + case 2011: + goto l2011; + case 19000: + done(3); + case 2012: + goto l2012; + default: + bug(105); + } +#if 0 + l9030: +#endif + case 3: + switch (trsay()) { + case 2012: + goto l2012; + case 2630: + goto l2630; + default: + bug(107); + } + l9040: case 4: + case 6: /* open, close */ + switch (tropen()) { + case 2011: + goto l2011; + case 2010: + goto l2010; + default: + bug(106); + } + case 5: + goto l2009; /* nothing */ + case 7: /* on 9070 */ + l9070: if (!here(lamp)) + goto l2011; + spk = 184; + if (limit < 0) + goto l2011; + prop[lamp] = 1; + rspeak(39); + if (wasdark) + goto l2000; + goto l2012; + + case 8: /* off */ + l9080: if (!here(lamp)) + goto l2011; + prop[lamp] = 0; + rspeak(40); + if (dark()) + rspeak(16); + goto l2012; + + case 9: /* wave */ + if ((!toting(obj)) && (obj != rod || !toting(rod2))) + spk = 29; + if (obj != rod || !at(fissure) || !toting(obj) || isclosing) + goto l2011; + prop[fissure] = 1 - prop[fissure]; + pspeak(fissure, 2 - prop[fissure]); + goto l2012; + case 10: + case 11: + case 18: /* calm, walk, quit */ + case 24: + case 25: + case 26: /* score, foo, brief */ + case 30: + case 31: /* suspend, hours */ + goto l2011; + l9120: case 12:/* kill */ + switch (trkill()) { + case 8000: + goto l8000; + case 8: + goto l8; + case 2011: + goto l2011; + case 2608: + goto l2608; + case 19000: + done(3); + default: + bug(112); + } + l9130: case 13:/* pour */ + if (obj == bottle || obj == 0) + obj = liq(); + if (obj == 0) + goto l8000; + if (!toting(obj)) + goto l2011; + spk = 78; + if (obj != oil && obj != water) + goto l2011; + prop[bottle] = 1; + place[obj] = 0; + spk = 77; + if (!(at(plant) || at(door))) + goto l2011; + if (at(door)) { + prop[door] = 0; /* 9132 */ + if (obj == oil) + prop[door] = 1; + spk = 113 + prop[door]; + goto l2011; + } + spk = 112; + if (obj != water) + goto l2011; + pspeak(plant, prop[plant] + 1); + prop[plant] = (prop[plant] + 2) % 6; + prop[plant2] = prop[plant] / 2; + k = null; + goto l8; + case 14: /* 9140 - eat */ + if (obj == food) + goto l8142; + if (obj == bird || obj == snake || obj == clam + || obj == oyster || obj == dwarf || obj == dragon + || obj == troll || obj == bear) + spk = 71; + goto l2011; + l9150: case 15:/* 9150 - drink */ + if (obj == 0 && liqloc(loc) != water && (liq() != water + || !here(bottle))) + goto l8000; + if (obj != 0 && obj != water) + spk = 110; + if (spk == 110 || liq() != water || !here(bottle)) + goto l2011; + prop[bottle] = 1; + place[water] = 0; + spk = 74; + goto l2011; + case 16: /* 9160: rub */ + if (obj != lamp) + spk = 76; + goto l2011; + case 17: /* 9170: throw */ + switch (trtoss()) { + case 2011: + goto l2011; + case 9020: + goto l9020; + case 9120: + goto l9120; + case 8: + goto l8; + case 9210: + goto l9210; + default: + bug(113); + } + case 19: + case 20: /* 9190: find, invent */ + if (at(obj) || (liq() == obj && at(bottle)) + || k == liqloc(loc)) + spk = 94; + for (i = 1; i <= 5; i++) + if (dloc[i] == loc && dflag >= 2 + && obj == dwarf) + spk = 94; + if (closed) + spk = 138; + if (toting(obj)) + spk = 24; + goto l2011; + l9210: case 21:/* feed */ + switch (trfeed()) { + case 2011: + goto l2011; + default: + bug(114); + } + l9220: case 22:/* fill */ + switch (trfill()) { + case 2011: + goto l2011; + case 8000: + goto l8000; + case 9020: + goto l9020; + default: + bug(115); + } + l9230: case 23:/* blast */ + if (prop[rod2] < 0 || !closed) + goto l2011; + bonus = 133; + if (loc == 115) + bonus = 134; + if (here(rod2)) + bonus = 135; + rspeak(bonus); + done(2); + l9270: case 27:/* read */ + if (dark()) + goto l5190; + if (obj == magazine) + spk = 190; + if (obj == tablet) + spk = 196; + if (obj == message) + spk = 191; + if (obj == oyster && hinted[2] && toting(oyster)) + spk = 194; + if (obj != oyster || hinted[2] || !toting(oyster) + || !closed) + goto l2011; + hinted[2] = yes(192, 193, 54); + goto l2012; +#if 0 + l9280: +#endif + case 28: /* break */ + if (obj == mirror) + spk = 148; + if (obj == vase && prop[vase] == 0) { + spk = 198; + if (toting(vase)) + drop(vase, loc); + prop[vase] = 2; + fixed[vase] = -1; + goto l2011; + } + if (obj != mirror || !closed) + goto l2011; + rspeak(197); + done(3); +#if 0 + l9290: +#endif + case 29: /* wake */ + if (obj != dwarf || !closed) + goto l2011; + rspeak(199); + done(3); + + default: + bug(24); + } + +l5000: + obj = k; + if (fixed[k] != loc && !here(k)) + goto l5100; +l5010: if (*wd2 != 0) + goto l2800; + if (verb != 0) + goto l4090; + printf("What do you want to do with the %s?\n", wd1); + goto l2600; +l5100: if (k != grate) + goto l5110; + if (loc == 1 || loc == 4 || loc == 7) + k = depression; + if (loc > 9 && loc < 15) + k = entrance; + if (k != grate) + goto l8; +l5110: if (k != dwarf) + goto l5120; + for (i = 1; i <= 5; i++) + if (dloc[i] == loc && dflag >= 2) + goto l5010; +l5120: if ((liq() == k && here(bottle)) || k == liqloc(loc)) + goto l5010; + if (obj != plant || !at(plant2) || prop[plant2] == 0) + goto l5130; + obj = plant2; + goto l5010; +l5130: if (obj != knife || knfloc != loc) + goto l5140; + knfloc = -1; + spk = 116; + goto l2011; +l5140: if (obj != rod || !here(rod2)) + goto l5190; + obj = rod2; + goto l5010; +l5190: if ((verb == find || verb == invent) && *wd2 == 0) + goto l5010; + printf("I see no %s here\n", wd1); + goto l2012; + } +} diff --git a/games/adventure/save.c b/games/adventure/save.c new file mode 100644 index 000000000..7392c695c --- /dev/null +++ b/games/adventure/save.c @@ -0,0 +1,868 @@ +/* $NetBSD: save.c,v 1.13 2012/01/08 18:16:00 dholland Exp $ */ + +/*- + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * The game adventure was originally written in Fortran by Will Crowther + * and Don Woods. It was later translated to C and enhanced by Jim + * Gillogly. This code is derived from software contributed to Berkeley + * by Jim Gillogly at The Rand Corporation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#ifndef lint +#if 0 +static char sccsid[] = "@(#)save.c 8.1 (Berkeley) 5/31/93"; +#else +__RCSID("$NetBSD: save.c,v 1.13 2012/01/08 18:16:00 dholland Exp $"); +#endif +#endif /* not lint */ + +#include +#include +#include +#include +#include +#include +#include + +#include "hdr.h" +#include "extern.h" + +struct savefile { + FILE *f; + const char *name; + bool warned; + unsigned bintextpos; + uint32_t key; + struct crcstate crc; + unsigned char pad[8]; + unsigned padpos; +}; + +#define BINTEXT_WIDTH 60 +#define FORMAT_VERSION 2 +#define FORMAT_VERSION_NOSUM 1 +static const char header[] = "Adventure save file\n"; + +//////////////////////////////////////////////////////////// +// base16 output encoding + +/* + * Map 16 plain values into 90 coded values and back. + */ + +static const char coding[90] = + "Db.GOyT]7a6zpF(c*5H9oK~0[WVAg&kR)ml,2^q-1Y3v+" + "X/=JirZL$C>_N?:}B{dfnsxU<@MQ%8|P!4h`ESt;euwIj" +; + +static int +readletter(char letter, unsigned char *ret) +{ + const char *s; + + s = strchr(coding, letter); + if (s == NULL) { + return 1; + } + *ret = (s - coding) % 16; + return 0; +} + +static char +writeletter(unsigned char nibble) +{ + unsigned code; + + assert(nibble < 16); + do { + code = (16 * (random() % 6)) + nibble; + } while (code >= 90); + return coding[code]; +} + +//////////////////////////////////////////////////////////// +// savefile + +/* + * Open a savefile. + */ +static struct savefile * +savefile_open(const char *name, bool forwrite) +{ + struct savefile *sf; + + sf = malloc(sizeof(*sf)); + if (sf == NULL) { + return NULL; + } + sf->f = fopen(name, forwrite ? "w" : "r"); + if (sf->f == NULL) { + free(sf); + fprintf(stderr, + "Hmm. The name \"%s\" appears to be magically blocked.\n", + name); + return NULL; + } + sf->name = name; + sf->warned = false; + sf->bintextpos = 0; + sf->key = 0; + crc_start(&sf->crc); + memset(sf->pad, 0, sizeof(sf->pad)); + sf->padpos = 0; + return sf; +} + +/* + * Raw read. + */ +static int +savefile_rawread(struct savefile *sf, void *data, size_t len) +{ + size_t result; + + result = fread(data, 1, len, sf->f); + if (result != len || ferror(sf->f)) { + fprintf(stderr, "Oops: error reading %s.\n", sf->name); + sf->warned = true; + return 1; + } + return 0; +} + +/* + * Raw write. + */ +static int +savefile_rawwrite(struct savefile *sf, const void *data, size_t len) +{ + size_t result; + + result = fwrite(data, 1, len, sf->f); + if (result != len || ferror(sf->f)) { + fprintf(stderr, "Oops: error writing %s.\n", sf->name); + sf->warned = true; + return 1; + } + return 0; +} + +/* + * Close a savefile. + */ +static int +savefile_close(struct savefile *sf) +{ + int ret; + + if (sf->bintextpos > 0) { + savefile_rawwrite(sf, "\n", 1); + } + + ret = 0; + if (fclose(sf->f)) { + if (!sf->warned) { + fprintf(stderr, "Oops: error on %s.\n", sf->name); + } + ret = 1; + } + free(sf); + return ret; +} + +/* + * Read encoded binary data, discarding any whitespace that appears. + */ +static int +savefile_bintextread(struct savefile *sf, void *data, size_t len) +{ + size_t pos; + unsigned char *udata; + int ch; + + udata = data; + pos = 0; + while (pos < len) { + ch = fgetc(sf->f); + if (ch == EOF || ferror(sf->f)) { + fprintf(stderr, "Oops: error reading %s.\n", sf->name); + sf->warned = true; + return 1; + } + if (ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n') { + continue; + } + udata[pos++] = ch; + } + return 0; +} + +/* + * Read binary data, decoding from text using readletter(). + */ +static int +savefile_binread(struct savefile *sf, void *data, size_t len) +{ + unsigned char buf[64]; + unsigned char *udata; + unsigned char val1, val2; + size_t pos, amt, i; + + udata = data; + pos = 0; + while (pos < len) { + amt = len - pos; + if (amt > sizeof(buf) / 2) { + amt = sizeof(buf) / 2; + } + if (savefile_bintextread(sf, buf, amt*2)) { + return 1; + } + for (i=0; ibintextpos; + if (amt > len - pos) { + amt = len - pos; + } + if (savefile_rawwrite(sf, udata + pos, amt)) { + return 1; + } + pos += amt; + sf->bintextpos += amt; + if (sf->bintextpos >= BINTEXT_WIDTH) { + savefile_rawwrite(sf, "\n", 1); + sf->bintextpos = 0; + } + } + return 0; +} + +/* + * Write binary data, encoding as text using writeletter(). + */ +static int +savefile_binwrite(struct savefile *sf, const void *data, size_t len) +{ + unsigned char buf[64]; + const unsigned char *udata; + size_t pos, bpos; + unsigned char byte; + + udata = data; + pos = 0; + bpos = 0; + while (pos < len) { + byte = udata[pos++]; + buf[bpos++] = writeletter(byte >> 4); + buf[bpos++] = writeletter(byte & 0xf); + if (bpos >= sizeof(buf)) { + if (savefile_bintextwrite(sf, buf, bpos)) { + return 1; + } + bpos = 0; + } + } + if (savefile_bintextwrite(sf, buf, bpos)) { + return 1; + } + return 0; +} + +/* + * Lightweight "encryption" for save files. This is not meant to + * be secure and wouldn't be even if we didn't write the decrypt + * key to the beginning of the save file; it's just meant to be + * enough to discourage casual cheating. + */ + +/* + * Make cheesy hash of buf[0..buflen]. Note: buf and outhash may overlap. + */ +static void +hash(const void *data, size_t datalen, unsigned char *out, size_t outlen) +{ + const unsigned char *udata; + size_t i; + uint64_t val; + const unsigned char *uval; + size_t valpos; + + udata = data; + val = 0; + for (i=0; i> 60); + val += udata[i] ^ 0xbeef; + } + + uval = (unsigned char *)&val; + valpos = 0; + for (i=0; i= sizeof(val)) { + valpos = 0; + } + } +} + +/* + * Set the "encryption" key. + */ +static void +savefile_key(struct savefile *sf, uint32_t key) +{ + sf->key = 0; + crc_start(&sf->crc); + hash(&sf->key, sizeof(sf->key), sf->pad, sizeof(sf->pad)); + sf->padpos = 0; +} + +/* + * Get an "encryption" pad byte. This forms a stream "cipher" that we + * xor with the plaintext save data. + */ +static unsigned char +savefile_getpad(struct savefile *sf) +{ + unsigned char ret; + + ret = sf->pad[sf->padpos++]; + if (sf->padpos >= sizeof(sf->pad)) { + hash(sf->pad, sizeof(sf->pad), sf->pad, sizeof(sf->pad)); + sf->padpos = 0; + } + return ret; +} + +/* + * Read "encrypted" data. + */ +static int +savefile_cread(struct savefile *sf, void *data, size_t len) +{ + char buf[64]; + unsigned char *udata; + size_t pos, amt, i; + unsigned char ch; + + udata = data; + pos = 0; + while (pos < len) { + amt = len - pos; + if (amt > sizeof(buf)) { + amt = sizeof(buf); + } + if (savefile_binread(sf, buf, amt)) { + return 1; + } + for (i=0; icrc, data, len); + return 0; +} + +/* + * Write "encrypted" data. + */ +static int +savefile_cwrite(struct savefile *sf, const void *data, size_t len) +{ + char buf[64]; + const unsigned char *udata; + size_t pos, amt, i; + unsigned char ch; + + udata = data; + pos = 0; + while (pos < len) { + amt = len - pos; + if (amt > sizeof(buf)) { + amt = sizeof(buf); + } + for (i=0; icrc, data, len); + return 0; +} + +//////////////////////////////////////////////////////////// +// compat for old save files + +struct compat_saveinfo { + void *address; + int width; +}; + +static const struct compat_saveinfo compat_savearray[] = +{ + {&abbnum, sizeof(abbnum)}, + {&attack, sizeof(attack)}, + {&blklin, sizeof(blklin)}, + {&bonus, sizeof(bonus)}, + {&chloc, sizeof(chloc)}, + {&chloc2, sizeof(chloc2)}, + {&clock1, sizeof(clock1)}, + {&clock2, sizeof(clock2)}, + {&closed, sizeof(closed)}, + {&isclosing, sizeof(isclosing)}, + {&daltloc, sizeof(daltloc)}, + {&demo, sizeof(demo)}, + {&detail, sizeof(detail)}, + {&dflag, sizeof(dflag)}, + {&dkill, sizeof(dkill)}, + {&dtotal, sizeof(dtotal)}, + {&foobar, sizeof(foobar)}, + {&gaveup, sizeof(gaveup)}, + {&holding, sizeof(holding)}, + {&iwest, sizeof(iwest)}, + {&k, sizeof(k)}, + {&k2, sizeof(k2)}, + {&knfloc, sizeof(knfloc)}, + {&kq, sizeof(kq)}, + {&latency, sizeof(latency)}, + {&limit, sizeof(limit)}, + {&lmwarn, sizeof(lmwarn)}, + {&loc, sizeof(loc)}, + {&maxdie, sizeof(maxdie)}, + {&maxscore, sizeof(maxscore)}, + {&newloc, sizeof(newloc)}, + {&numdie, sizeof(numdie)}, + {&obj, sizeof(obj)}, + {&oldloc2, sizeof(oldloc2)}, + {&oldloc, sizeof(oldloc)}, + {&panic, sizeof(panic)}, + {&saveday, sizeof(saveday)}, + {&savet, sizeof(savet)}, + {&scoring, sizeof(scoring)}, + {&spk, sizeof(spk)}, + {&stick, sizeof(stick)}, + {&tally, sizeof(tally)}, + {&tally2, sizeof(tally2)}, + {&tkk, sizeof(tkk)}, + {&turns, sizeof(turns)}, + {&verb, sizeof(verb)}, + {&wd1, sizeof(wd1)}, + {&wd2, sizeof(wd2)}, + {&wasdark, sizeof(wasdark)}, + {&yea, sizeof(yea)}, + {atloc, sizeof(atloc)}, + {dloc, sizeof(dloc)}, + {dseen, sizeof(dseen)}, + {fixed, sizeof(fixed)}, + {hinted, sizeof(hinted)}, + {links, sizeof(links)}, + {odloc, sizeof(odloc)}, + {place, sizeof(place)}, + {prop, sizeof(prop)}, + {tk, sizeof(tk)}, + + {NULL, 0} +}; + +static int +compat_restore(const char *infile) +{ + FILE *in; + const struct compat_saveinfo *p; + char *s; + long sum, cksum = 0; + int i; + struct crcstate crc; + + if ((in = fopen(infile, "rb")) == NULL) { + fprintf(stderr, + "Hmm. The file \"%s\" appears to be magically blocked.\n", + infile); + return 1; + } + fread(&sum, sizeof(sum), 1, in); /* Get the seed */ + srandom((int) sum); + for (p = compat_savearray; p->address != NULL; p++) { + fread(p->address, p->width, 1, in); + for (s = p->address, i = 0; i < p->width; i++, s++) + *s = (*s ^ random()) & 0xFF; /* Lightly decrypt */ + } + fclose(in); + + crc_start(&crc); /* See if she cheated */ + for (p = compat_savearray; p->address != NULL; p++) + crc_add(&crc, p->address, p->width); + cksum = crc_get(&crc); + if (sum != cksum) /* Tsk tsk */ + return 2; /* Altered the file */ + /* We successfully restored, so this really was a save file */ + + /* + * The above code loads these from disk even though they're + * pointers. Null them out and hope we don't crash on them + * later; that's better than having them be garbage. + */ + tkk = NULL; + wd1 = NULL; + wd2 = NULL; + + return 0; +} + +//////////////////////////////////////////////////////////// +// save + restore + +static int *const save_ints[] = { + &abbnum, + &attack, + &blklin, + &bonus, + &chloc, + &chloc2, + &clock1, + &clock2, + &closed, + &isclosing, + &daltloc, + &demo, + &detail, + &dflag, + &dkill, + &dtotal, + &foobar, + &gaveup, + &holding, + &iwest, + &k, + &k2, + &knfloc, + &kq, + &latency, + &limit, + &lmwarn, + &loc, + &maxdie, + &maxscore, + &newloc, + &numdie, + &obj, + &oldloc2, + &oldloc, + &panic, + &saveday, + &savet, + &scoring, + &spk, + &stick, + &tally, + &tally2, + &turns, + &verb, + &wasdark, + &yea, +}; +static const unsigned num_save_ints = __arraycount(save_ints); + +#define INTARRAY(sym) { sym, __arraycount(sym) } + +static const struct { + int *ptr; + unsigned num; +} save_intarrays[] = { + INTARRAY(atloc), + INTARRAY(dseen), + INTARRAY(dloc), + INTARRAY(odloc), + INTARRAY(fixed), + INTARRAY(hinted), + INTARRAY(links), + INTARRAY(place), + INTARRAY(prop), + INTARRAY(tk), +}; +static const unsigned num_save_intarrays = __arraycount(save_intarrays); + +#undef INTARRAY + +#if 0 +static const struct { + void *ptr; + size_t len; +} save_blobs[] = { + { &wd1, sizeof(wd1) }, + { &wd2, sizeof(wd2) }, + { &tkk, sizeof(tkk) }, +}; +static const unsigned num_save_blobs = __arraycount(save_blobs); +#endif + +/* + * Write out a save file. Returns nonzero on error. + */ +int +save(const char *outfile) +{ + struct savefile *sf; + struct timespec now; + uint32_t key, writeable_key; + uint32_t version; + unsigned i, j, n; + uint32_t val, sum; + + sf = savefile_open(outfile, true); + if (sf == NULL) { + return 1; + } + + if (savefile_rawwrite(sf, header, strlen(header))) { + savefile_close(sf); + return 1; + } + + version = htonl(FORMAT_VERSION); + if (savefile_binwrite(sf, &version, sizeof(version))) { + savefile_close(sf); + return 1; + } + + clock_gettime(CLOCK_REALTIME, &now); + key = (uint32_t)(now.tv_sec & 0xffffffff) ^ (uint32_t)(now.tv_nsec); + + writeable_key = htonl(key); + if (savefile_binwrite(sf, &writeable_key, sizeof(writeable_key))) { + savefile_close(sf); + return 1; + } + + /* other parts of the code may depend on us doing this here */ + srandom(key); + + savefile_key(sf, key); + + /* + * Integers + */ + for (i=0; icrc)); + if (savefile_binwrite(sf, &sum, sizeof(&sum))) { + savefile_close(sf); + return 1; + } + savefile_close(sf); + return 0; +} + +/* + * Read in a save file. Returns nonzero on error. + */ +int +restore(const char *infile) +{ + struct savefile *sf; + char buf[sizeof(header)]; + size_t headersize = strlen(header); + uint32_t version, key, sum; + unsigned i, j, n; + uint32_t val; + bool skipsum = false; + + sf = savefile_open(infile, false); + if (sf == NULL) { + return 1; + } + + if (savefile_rawread(sf, buf, headersize)) { + savefile_close(sf); + return 1; + } + buf[headersize] = 0; + if (strcmp(buf, header) != 0) { + savefile_close(sf); + fprintf(stderr, "Oh dear, that isn't one of my save files.\n"); + fprintf(stderr, + "Trying the Olde Waye; this myte notte Worke.\n"); + return compat_restore(infile); + } + + if (savefile_binread(sf, &version, sizeof(version))) { + savefile_close(sf); + return 1; + } + version = ntohl(version); + switch (version) { + case FORMAT_VERSION: + break; + case FORMAT_VERSION_NOSUM: + skipsum = true; + break; + default: + savefile_close(sf); + fprintf(stderr, + "Oh dear, that file must be from the future. I don't know" + " how to read it!\n"); + return 1; + } + + if (savefile_binread(sf, &key, sizeof(key))) { + savefile_close(sf); + return 1; + } + key = ntohl(key); + savefile_key(sf, key); + + /* other parts of the code may depend on us doing this here */ + srandom(key); + + /* + * Integers + */ + for (i=0; icrc)) { + /* Tsk tsk, altered the file */ + savefile_close(sf); + return 2; + } + savefile_close(sf); + + /* Load theoretically invalidates these */ + tkk = NULL; + wd1 = NULL; + wd2 = NULL; + + return 0; +} diff --git a/games/adventure/setup.c b/games/adventure/setup.c new file mode 100644 index 000000000..36a7c0e9c --- /dev/null +++ b/games/adventure/setup.c @@ -0,0 +1,128 @@ +/* $NetBSD: setup.c,v 1.11 2005/07/01 00:03:36 jmc Exp $ */ + +/*- + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jim Gillogly at The Rand Corporation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char copyright[] = "@(#) Copyright (c) 1991, 1993\n\ + The Regents of the University of California. All rights reserved.\n"; + +#if 0 +static char sccsid[] = "@(#)setup.c 8.1 (Berkeley) 5/31/93"; +#else +static char rcsid[] = "$NetBSD: setup.c,v 1.11 2005/07/01 00:03:36 jmc Exp $"; +#endif +#endif /* not lint */ + +/* + * Setup: keep the structure of the original Adventure port, but use an + * internal copy of the data file, serving as a sort of virtual disk. It's + * lightly encrypted to prevent casual snooping of the executable. + * + * Also do appropriate things to tabs so that bogus editors will do the right + * thing with the data file. + * + */ + +#define SIG1 " * Jim Gillogly" +#define SIG2 " * Sterday, 6 Thrimidge S.R. 1993, 15:24" + +#include +#include +#include +#include +#include "hdr.h" /* SEED lives in there; keep them coordinated. */ + +#define USAGE "Usage: setup file > data.c (file is typically glorkz)\n" + +#define YES 1 +#define NO 0 + +#define LINE 10 /* How many values do we get on a line? */ + +int main(int, char *[]); + +int +main(int argc, char *argv[]) +{ + FILE *infile; + int c, count, linestart; + + if (argc != 2) { + fprintf(stderr, USAGE); + exit(1); + } + + if ((infile = fopen(argv[1], "r")) == NULL) { + fprintf(stderr, "Can't read file %s: %s\n", argv[1], + strerror(errno)); + exit(1); + } + puts("/*\n * data.c: created by setup from the ascii data file."); + puts(SIG1); + puts(SIG2); + puts(" */"); + printf("\n\nchar data_file[] =\n{"); + srandom(SEED); + count = 0; + linestart = YES; + + while ((c = getc(infile)) != EOF) { + if (linestart && c == ' ') { /* Convert first spaces to tab */ + printf("0x%02x,", + (unsigned int)('\t' ^ random()) & 0xFF); + while ((c = getc(infile)) == ' ' && c != EOF); + /* Drop the non-whitespace character through */ + linestart = NO; + } + switch (c) { + case '\t': + linestart = NO; /* Don't need to convert spaces */ + break; + case '\n': + linestart = YES; /* Ready to convert spaces + * again */ + break; + } + if (count++ % LINE == 0) /* Finished a line? */ + printf("\n\t"); + printf("0x%02x,", (unsigned int)(c ^ random()) & 0xFF); + } + puts("\n\t0\n};"); + fclose(infile); + fflush(stdout); + if (ferror(stdout)) { + perror("error writing standard output"); + exit(1); + } + exit(0); +} diff --git a/games/adventure/subr.c b/games/adventure/subr.c new file mode 100644 index 000000000..0fd6c27ce --- /dev/null +++ b/games/adventure/subr.c @@ -0,0 +1,1057 @@ +/* $NetBSD: subr.c,v 1.13 2009/08/25 06:56:52 dholland Exp $ */ + +/*- + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * The game adventure was originally written in Fortran by Will Crowther + * and Don Woods. It was later translated to C and enhanced by Jim + * Gillogly. This code is derived from software contributed to Berkeley + * by Jim Gillogly at The Rand Corporation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#ifndef lint +#if 0 +static char sccsid[] = "@(#)subr.c 8.1 (Berkeley) 5/31/93"; +#else +__RCSID("$NetBSD: subr.c,v 1.13 2009/08/25 06:56:52 dholland Exp $"); +#endif +#endif /* not lint */ + +/* Re-coding of advent in C: subroutines from main */ + +#include +#include +#include "hdr.h" +#include "extern.h" + +static void badmove(void); +static int bitset(int, int); +static int dropper(void); +static int liq2(int); +static int mback(void); +static int specials(void); +static int trbridge(void); + +/* Statement functions */ +int +toting(int objj) +{ + if (place[objj] == -1) + return (TRUE); + else + return (FALSE); +} + +int +here(int objj) +{ + if (place[objj] == loc || toting(objj)) + return (TRUE); + else + return (FALSE); +} + +int +at(int objj) +{ + if (place[objj] == loc || fixed[objj] == loc) + return (TRUE); + else + return (FALSE); +} + +static int +liq2(int pbotl) +{ + return ((1 - pbotl) * water + (pbotl / 2) * (water + oil)); +} + +int +liq(void) +{ + int i; + i = prop[bottle]; + if (i > -1 - i) + return (liq2(i)); + else + return (liq2(-1 - i)); +} + +/* may want to clean this one up a bit */ +int +liqloc(int locc) +{ + int i, j, l; + i = cond[locc] / 2; + j = ((i * 2) % 8) - 5; + l = cond[locc] / 4; + l = l % 2; + return (liq2(j * l + 1)); +} + +static int +bitset(int l, int n) +{ + if (cond[l] & setbit[n]) + return (TRUE); + return (FALSE); +} + +int +forced(int locc) +{ + if (cond[locc] == 2) + return (TRUE); + return (FALSE); +} + +int +dark(void) +{ + if ((cond[loc] % 2) == 0 && (prop[lamp] == 0 || !here(lamp))) + return (TRUE); + return (FALSE); +} + +int +pct(int n) +{ + if (ran(100) < n) + return (TRUE); + return (FALSE); +} + + +int +fdwarf(void) +{ /* 71 */ + int i, j; + struct travlist *kk; + + if (newloc != loc && !forced(loc) && !bitset(loc, 3)) { + for (i = 1; i <= 5; i++) { + if (odloc[i] != newloc || !dseen[i]) + continue; + newloc = loc; + rspeak(2); + break; + } + } + loc = newloc; /* 74 */ + if (loc == 0 || forced(loc) || bitset(newloc, 3)) + return (2000); + if (dflag == 0) { + if (loc >= 15) + dflag = 1; + return (2000); + } + if (dflag == 1) { /* 6000 */ + if (loc < 15 || pct(95)) + return (2000); + dflag = 2; + for (i = 1; i <= 2; i++) { + j = 1 + ran(5); + if (pct(50) && saved == -1) + dloc[j] = 0; /* 6001 */ + } + for (i = 1; i <= 5; i++) { + if (dloc[i] == loc) + dloc[i] = daltloc; + odloc[i] = dloc[i]; /* 6002 */ + } + rspeak(3); + drop(axe, loc); + return (2000); + } + dtotal = attack = stick = 0; /* 6010 */ + for (i = 1; i <= 6; i++) { /* loop to 6030 */ + if (dloc[i] == 0) + continue; + j = 1; + for (kk = travel[dloc[i]]; kk != 0; kk = kk->next) { + newloc = kk->tloc; + if (newloc > 300 || newloc < 15 || newloc == odloc[i] + || (j > 1 && newloc == tk[j - 1]) || j >= 20 + || newloc == dloc[i] || forced(newloc) + || (i == 6 && bitset(newloc, 3)) + || kk->conditions == 100) + continue; + tk[j++] = newloc; + } + tk[j] = odloc[i]; /* 6016 */ + if (j >= 2) + j--; + j = 1 + ran(j); + odloc[i] = dloc[i]; + dloc[i] = tk[j]; + dseen[i] = (dseen[i] && loc >= 15) || + (dloc[i] == loc || odloc[i] == loc); + if (!dseen[i]) + continue; /* i.e. goto 6030 */ + dloc[i] = loc; + if (i == 6) { /* pirate's spotted him */ + if (loc == chloc || prop[chest] >= 0) + continue; + k = 0; + for (j = 50; j <= maxtrs; j++) { /* loop to 6020 */ + if (j == pyramid && (loc == plac[pyramid] + || loc == plac[emerald])) + goto l6020; + if (toting(j)) + goto l6022; + l6020: if (here(j)) + k = 1; + } /* 6020 */ + if (tally == tally2 + 1 && k == 0 && place[chest] == 0 + && here(lamp) && prop[lamp] == 1) + goto l6025; + if (odloc[6] != dloc[6] && pct(20)) + rspeak(127); + continue; /* to 6030 */ + l6022: rspeak(128); + if (place[message] == 0) + move(chest, chloc); + move(message, chloc2); + for (j = 50; j <= maxtrs; j++) { /* loop to 6023 */ + if (j == pyramid && (loc == plac[pyramid] + || loc == plac[emerald])) + continue; + if (at(j) && fixed[j] == 0) + carry(j, loc); + if (toting(j)) + drop(j, chloc); + } + l6024: dloc[6] = odloc[6] = chloc; + dseen[6] = FALSE; + continue; + l6025: rspeak(186); + move(chest, chloc); + move(message, chloc2); + goto l6024; + } + dtotal++; /* 6027 */ + if (odloc[i] != dloc[i]) + continue; + attack++; + if (knfloc >= 0) + knfloc = loc; + if (ran(1000) < 95 * (dflag - 2)) + stick++; + } /* 6030 */ + if (dtotal == 0) + return (2000); + if (dtotal != 1) { + printf("There are %d threatening little dwarves ", dtotal); + printf("in the room with you.\n"); + } else + rspeak(4); + if (attack == 0) + return (2000); + if (dflag == 2) + dflag = 3; + if (saved != -1) + dflag = 20; + if (attack != 1) { + printf("%d of them throw knives at you!\n", attack); + k = 6; +l82: if (stick <= 1) { /* 82 */ + rspeak(k + stick); + if (stick == 0) + return (2000); + } else + printf("%d of them get you!\n", stick); /* 83 */ + oldloc2 = loc; + return (99); + } + rspeak(5); + k = 52; + goto l82; +} + + +/* label 8 */ +int +march(void) +{ + int ll1, ll2; + + if ((tkk = travel[newloc = loc]) == 0) + bug(26); + if (k == null) + return (2); + if (k == cave) { /* 40 */ + if (loc < 8) + rspeak(57); + if (loc >= 8) + rspeak(58); + return (2); + } + if (k == look) { /* 30 */ + if (detail++ < 3) + rspeak(15); + wasdark = FALSE; + abb[loc] = 0; + return (2); + } + if (k == back) { /* 20 */ + switch (mback()) { + case 2: + return (2); + case 9: + goto l9; + default: + bug(100); + } + } + oldloc2 = oldloc; + oldloc = loc; +l9: + for (; tkk != 0; tkk = tkk->next) + if (tkk->tverb == 1 || tkk->tverb == k) + break; + if (tkk == 0) { + badmove(); + return (2); + } +l11: ll1 = tkk->conditions; /* 11 */ + ll2 = tkk->tloc; + newloc = ll1; /* newloc=conditions */ + k = newloc % 100; /* k used for prob */ + if (newloc <= 300) { + if (newloc <= 100) { /* 13 */ + if (newloc != 0 && !pct(newloc)) + goto l12; /* 14 */ + l16: newloc = ll2; /* newloc=location */ + if (newloc <= 300) + return (2); + if (newloc <= 500) + switch (specials()) { /* to 30000 */ + case 2: + return (2); + case 12: + goto l12; + case 99: + return (99); + default: + bug(101); + } + rspeak(newloc - 500); + newloc = loc; + return (2); + } + if (toting(k) || (newloc > 200 && at(k))) + goto l16; + goto l12; + } + if (prop[k] != (newloc / 100) - 3) + goto l16; /* newloc still conditions */ +l12: /* alternative to probability move */ + for (; tkk != 0; tkk = tkk->next) + if (tkk->tloc != ll2 || tkk->conditions != ll1) + break; + if (tkk == 0) + bug(25); + goto l11; +} + +/* 20 */ +static int +mback(void) +{ + struct travlist *tk2, *j; + int ll; + if (forced(k = oldloc)) + k = oldloc2; /* k=location */ + oldloc2 = oldloc; + oldloc = loc; + tk2 = 0; + if (k == loc) { + rspeak(91); + return (2); + } + for (; tkk != 0; tkk = tkk->next) { /* 21 */ + ll = tkk->tloc; + if (ll == k) { + k = tkk->tverb; /* k back to verb */ + tkk = travel[loc]; + return (9); + } + if (ll <= 300) { + j = travel[loc]; + if (forced(ll) && k == j->tloc) + tk2 = tkk; + } + } + tkk = tk2; /* 23 */ + if (tkk != 0) { + k = tkk->tverb; + tkk = travel[loc]; + return (9); + } + rspeak(140); + return (2); +} + +/* 30000 */ +static int +specials(void) +{ + switch (newloc -= 300) { + case 1: /* 30100 */ + newloc = 99 + 100 - loc; + if (holding == 0 || (holding == 1 && toting(emerald))) + return (2); + newloc = loc; + rspeak(117); + return (2); + case 2: /* 30200 */ + drop(emerald, loc); + return (12); + case 3: /* to 30300 */ + return (trbridge()); + default: + bug(29); + } +} + +/* 30300 */ +static int +trbridge(void) +{ + if (prop[troll] == 1) { + pspeak(troll, 1); + prop[troll] = 0; + move(troll2, 0); + move(troll2 + 100, 0); + move(troll, plac[troll]); + move(troll + 100, fixd[troll]); + juggle(chasm); + newloc = loc; + return (2); + } + newloc = plac[troll] + fixd[troll] - loc; /* 30310 */ + if (prop[troll] == 0) + prop[troll] = 1; + if (!toting(bear)) + return (2); + rspeak(162); + prop[chasm] = 1; + prop[troll] = 2; + drop(bear, newloc); + fixed[bear] = -1; + prop[bear] = 3; + if (prop[spices] < 0) + tally2++; + oldloc2 = newloc; + return (99); +} + +/* 20 */ +static void +badmove(void) +{ + spk = 12; + if (k >= 43 && k <= 50) + spk = 9; + if (k == 29 || k == 30) + spk = 9; + if (k == 7 || k == 36 || k == 37) + spk = 10; + if (k == 11 || k == 19) + spk = 11; + if (verb == find || verb == invent) + spk = 59; + if (k == 62 || k == 65) + spk = 42; + if (k == 17) + spk = 80; + rspeak(spk); +} + +void +bug(int n) +{ + printf("Please tell jim@rand.org that fatal bug %d happened.\n", n); + exit(1); +} + +/* 2600 &c */ +void +checkhints(void) +{ + int hint; + for (hint = 4; hint <= hintmax; hint++) { + if (hinted[hint]) + continue; + if (!bitset(loc, hint)) + hintlc[hint] = -1; + hintlc[hint]++; + if (hintlc[hint] < hints[hint][1]) + continue; + switch (hint) { + case 4: /* 40400 */ + if (prop[grate] == 0 && !here(keys)) + goto l40010; + goto l40020; + case 5: /* 40500 */ + if (here(bird) && toting(rod) && obj == bird) + goto l40010; + continue; /* i.e. goto l40030 */ + case 6: /* 40600 */ + if (here(snake) && !here(bird)) + goto l40010; + goto l40020; + case 7: /* 40700 */ + if (atloc[loc] == 0 && atloc[oldloc] == 0 + && atloc[oldloc2] == 0 && holding > 1) + goto l40010; + goto l40020; + case 8: /* 40800 */ + if (prop[emerald] != -1 && prop[pyramid] == -1) + goto l40010; + goto l40020; + case 9: + goto l40010; /* 40900 */ + default: + bug(27); + } +l40010: hintlc[hint] = 0; + if (!yes(hints[hint][3], 0, 54)) + continue; + printf("I am prepared to give you a hint, but it will "); + printf("cost you %d points.\n", hints[hint][2]); + hinted[hint] = yes(175, hints[hint][4], 54); +l40020: hintlc[hint] = 0; + } +} + +/* 9030 */ +int +trsay(void) +{ + int i; + if (*wd2 != 0) + copystr(wd2, wd1); + i = vocab(wd1, -1, 0); + if (i == 62 || i == 65 || i == 71 || i == 2025) { + *wd2 = 0; + obj = 0; + return (2630); + } + printf("\nOkay, \"%s\".\n", wd2); + return (2012); +} + +/* 9010 */ +int +trtake(void) +{ + if (toting(obj)) + return (2011); /* 9010 */ + spk = 25; + if (obj == plant && prop[plant] <= 0) + spk = 115; + if (obj == bear && prop[bear] == 1) + spk = 169; + if (obj == chain && prop[bear] != 0) + spk = 170; + if (fixed[obj] != 0) + return (2011); + if (obj == water || obj == oil) { + if (here(bottle) && liq() == obj) { + obj = bottle; + goto l9017; + } + obj = bottle; + if (toting(bottle) && prop[bottle] == 1) + return (9220); + if (prop[bottle] != 1) + spk = 105; + if (!toting(bottle)) + spk = 104; + return (2011); + } +l9017: if (holding >= 7) { + rspeak(92); + return (2012); + } + if (obj == bird) { + if (prop[bird] != 0) + goto l9014; + if (toting(rod)) { + rspeak(26); + return (2012); + } + if (!toting(cage)) { /* 9013 */ + rspeak(27); + return (2012); + } + prop[bird] = 1; /* 9015 */ + } +l9014: if ((obj == bird || obj == cage) && prop[bird] != 0) + carry(bird + cage - obj, loc); + carry(obj, loc); + k = liq(); + if (obj == bottle && k != 0) + place[k] = -1; + return (2009); +} + +/* 9021 */ +static int +dropper(void) +{ + k = liq(); + if (k == obj) + obj = bottle; + if (obj == bottle && k != 0) + place[k] = 0; + if (obj == cage && prop[bird] != 0) + drop(bird, loc); + if (obj == bird) + prop[bird] = 0; + drop(obj, loc); + return (2012); +} + +/* 9020 */ +int +trdrop(void) +{ + if (toting(rod2) && obj == rod && !toting(rod)) + obj = rod2; + if (!toting(obj)) + return (2011); + if (obj == bird && here(snake)) { + rspeak(30); + if (closed) + return (19000); + destroy(snake); + prop[snake] = 1; + return (dropper()); + } + if (obj == coins && here(vend)) { /* 9024 */ + destroy(coins); + drop(batter, loc); + pspeak(batter, 0); + return (2012); + } + if (obj == bird && at(dragon) && prop[dragon] == 0) { /* 9025 */ + rspeak(154); + destroy(bird); + prop[bird] = 0; + if (place[snake] == plac[snake]) + tally2--; + return (2012); + } + if (obj == bear && at(troll)) { /* 9026 */ + rspeak(163); + move(troll, 0); + move(troll + 100, 0); + move(troll2, plac[troll]); + move(troll2 + 100, fixd[troll]); + juggle(chasm); + prop[troll] = 2; + return (dropper()); + } + if (obj != vase || loc == plac[pillow]) { /* 9027 */ + rspeak(54); + return (dropper()); + } + prop[vase] = 2; /* 9028 */ + if (at(pillow)) + prop[vase] = 0; + pspeak(vase, prop[vase] + 1); + if (prop[vase] != 0) + fixed[vase] = -1; + return (dropper()); +} + +/* 9040 */ +int +tropen(void) +{ + if (obj == clam || obj == oyster) { + k = 0; /* 9046 */ + if (obj == oyster) + k = 1; + spk = 124 + k; + if (toting(obj)) + spk = 120 + k; + if (!toting(trident)) + spk = 122 + k; + if (verb == lock) + spk = 61; + if (spk != 124) + return (2011); + destroy(clam); + drop(oyster, loc); + drop(pearl, 105); + return (2011); + } + if (obj == door) + spk = 111; + if (obj == door && prop[door] == 1) + spk = 54; + if (obj == cage) + spk = 32; + if (obj == keys) + spk = 55; + if (obj == grate || obj == chain) + spk = 31; + if (spk != 31 || !here(keys)) + return (2011); + if (obj == chain) { + if (verb == lock) { + spk = 172; /* 9049: lock */ + if (prop[chain] != 0) + spk = 34; + if (loc != plac[chain]) + spk = 173; + if (spk != 172) + return (2011); + prop[chain] = 2; + if (toting(chain)) + drop(chain, loc); + fixed[chain] = -1; + return (2011); + } + spk = 171; + if (prop[bear] == 0) + spk = 41; + if (prop[chain] == 0) + spk = 37; + if (spk != 171) + return (2011); + prop[chain] = 0; + fixed[chain] = 0; + if (prop[bear] != 3) + prop[bear] = 2; + fixed[bear] = 2 - prop[bear]; + return (2011); + } + if (isclosing) { + k = 130; + if (!panic) + clock2 = 15; + panic = TRUE; + return (2010); + } + k = 34 + prop[grate]; /* 9043 */ + prop[grate] = 1; + if (verb == lock) + prop[grate] = 0; + k = k + 2 * prop[grate]; + return (2010); +} + +/* 9120 */ +int +trkill(void) +{ + int i; + for (i = 1; i <= 5; i++) + if (dloc[i] == loc && dflag >= 2) + break; + if (i == 6) + i = 0; + if (obj == 0) { /* 9122 */ + if (i != 0) + obj = dwarf; + if (here(snake)) + obj = obj * 100 + snake; + if (at(dragon) && prop[dragon] == 0) + obj = obj * 100 + dragon; + if (at(troll)) + obj = obj * 100 + troll; + if (here(bear) && prop[bear] == 0) + obj = obj * 100 + bear; + if (obj > 100) + return (8000); + if (obj == 0) { + if (here(bird) && verb != throw) + obj = bird; + if (here(clam) || here(oyster)) + obj = 100 * obj + clam; + if (obj > 100) + return (8000); + } + } + if (obj == bird) { /* 9124 */ + spk = 137; + if (closed) + return (2011); + destroy(bird); + prop[bird] = 0; + if (place[snake] == plac[snake]) + tally2++; + spk = 45; + } + if (obj == 0) + spk = 44; /* 9125 */ + if (obj == clam || obj == oyster) + spk = 150; + if (obj == snake) + spk = 46; + if (obj == dwarf) + spk = 49; + if (obj == dwarf && closed) + return (19000); + if (obj == dragon) + spk = 147; + if (obj == troll) + spk = 157; + if (obj == bear) + spk = 165 + (prop[bear] + 1) / 2; + if (obj != dragon || prop[dragon] != 0) + return (2011); + rspeak(49); + verb = 0; + obj = 0; + getin(&wd1, &wd2); + if (!weq(wd1, "y") && !weq(wd1, "yes")) + return (2608); + pspeak(dragon, 1); + prop[dragon] = 2; + prop[rug] = 0; + k = (plac[dragon] + fixd[dragon]) / 2; + move(dragon + 100, -1); + move(rug + 100, 0); + move(dragon, k); + move(rug, k); + for (obj = 1; obj <= 100; obj++) + if (place[obj] == plac[dragon] || place[obj] == fixd[dragon]) + move(obj, k); + loc = k; + k = null; + return (8); +} + +/* 9170: throw */ +int +trtoss(void) +{ + int i; + if (toting(rod2) && obj == rod && !toting(rod)) + obj = rod2; + if (!toting(obj)) + return (2011); + if (obj >= 50 && obj <= maxtrs && at(troll)) { + spk = 159; /* 9178 */ + drop(obj, 0); + move(troll, 0); + move(troll + 100, 0); + drop(troll2, plac[troll]); + drop(troll2 + 100, fixd[troll]); + juggle(chasm); + return (2011); + } + if (obj == food && here(bear)) { + obj = bear; /* 9177 */ + return (9210); + } + if (obj != axe) + return (9020); + for (i = 1; i <= 5; i++) { + if (dloc[i] == loc) { + spk = 48; /* 9172 */ + if (ran(3) == 0 || saved != -1) + l9175: { + rspeak(spk); + drop(axe, loc); + k = null; + return (8); + } + dseen[i] = FALSE; + dloc[i] = 0; + spk = 47; + dkill++; + if (dkill == 1) + spk = 149; + goto l9175; + } + } + spk = 152; + if (at(dragon) && prop[dragon] == 0) + goto l9175; + spk = 158; + if (at(troll)) + goto l9175; + if (here(bear) && prop[bear] == 0) { + spk = 164; + drop(axe, loc); + fixed[axe] = -1; + prop[axe] = 1; + juggle(bear); + return (2011); + } + obj = 0; + return (9120); +} + +/* 9210 */ +int +trfeed(void) +{ + if (obj == bird) { + spk = 100; + return (2011); + } + if (obj == snake || obj == dragon || obj == troll) { + spk = 102; + if (obj == dragon && prop[dragon] != 0) + spk = 110; + if (obj == troll) + spk = 182; + if (obj != snake || closed || !here(bird)) + return (2011); + spk = 101; + destroy(bird); + prop[bird] = 0; + tally2++; + return (2011); + } + if (obj == dwarf) { + if (!here(food)) + return (2011); + spk = 103; + dflag++; + return (2011); + } + if (obj == bear) { + if (prop[bear] == 0) + spk = 102; + if (prop[bear] == 3) + spk = 110; + if (!here(food)) + return (2011); + destroy(food); + prop[bear] = 1; + fixed[axe] = 0; + prop[axe] = 0; + spk = 168; + return (2011); + } + spk = 14; + return (2011); +} + +/* 9220 */ +int +trfill(void) +{ + if (obj == vase) { + spk = 29; + if (liqloc(loc) == 0) + spk = 144; + if (liqloc(loc) == 0 || !toting(vase)) + return (2011); + rspeak(145); + prop[vase] = 2; + fixed[vase] = -1; + return (9020); /* advent/10 goes to 9024 */ + } + if (obj != 0 && obj != bottle) + return (2011); + if (obj == 0 && !here(bottle)) + return (8000); + spk = 107; + if (liqloc(loc) == 0) + spk = 106; + if (liq() != 0) + spk = 105; + if (spk != 107) + return (2011); + prop[bottle] = ((cond[loc] % 4) / 2) * 2; + k = liq(); + if (toting(bottle)) + place[k] = -1; + if (k == oil) + spk = 108; + return (2011); +} + +/* 10000 */ +void +closing(void) +{ + int i; + + prop[grate] = prop[fissure] = 0; + for (i = 1; i <= 6; i++) { + dseen[i] = FALSE; + dloc[i] = 0; + } + move(troll, 0); + move(troll + 100, 0); + move(troll2, plac[troll]); + move(troll2 + 100, fixd[troll]); + juggle(chasm); + if (prop[bear] != 3) + destroy(bear); + prop[chain] = 0; + fixed[chain] = 0; + prop[axe] = 0; + fixed[axe] = 0; + rspeak(129); + clock1 = -1; + isclosing = TRUE; +} + +/* 11000 */ +void +caveclose(void) +{ + int i; + prop[bottle] = put(bottle, 115, 1); + prop[plant] = put(plant, 115, 0); + prop[oyster] = put(oyster, 115, 0); + prop[lamp] = put(lamp, 115, 0); + prop[rod] = put(rod, 115, 0); + prop[dwarf] = put(dwarf, 115, 0); + loc = 115; + oldloc = 115; + newloc = 115; + + put(grate, 116, 0); + prop[snake] = put(snake, 116, 1); + prop[bird] = put(bird, 116, 1); + prop[cage] = put(cage, 116, 0); + prop[rod2] = put(rod2, 116, 0); + prop[pillow] = put(pillow, 116, 0); + + prop[mirror] = put(mirror, 115, 0); + fixed[mirror] = 116; + + for (i = 1; i <= 100; i++) + if (toting(i)) + destroy(i); + rspeak(132); + closed = TRUE; +} diff --git a/games/adventure/vocab.c b/games/adventure/vocab.c new file mode 100644 index 000000000..1a1b7006d --- /dev/null +++ b/games/adventure/vocab.c @@ -0,0 +1,218 @@ +/* $NetBSD: vocab.c,v 1.15 2009/08/25 06:56:52 dholland Exp $ */ + +/*- + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * The game adventure was originally written in Fortran by Will Crowther + * and Don Woods. It was later translated to C and enhanced by Jim + * Gillogly. This code is derived from software contributed to Berkeley + * by Jim Gillogly at The Rand Corporation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#ifndef lint +#if 0 +static char sccsid[] = "@(#)vocab.c 8.1 (Berkeley) 5/31/93"; +#else +__RCSID("$NetBSD: vocab.c,v 1.15 2009/08/25 06:56:52 dholland Exp $"); +#endif +#endif /* not lint */ + +/* Re-coding of advent in C: data structure routines */ + +#include +#include +#include +#include "hdr.h" +#include "extern.h" + +void +destroy(int object) +{ + move(object, 0); +} + +void +juggle(int object) +{ + int i, j; + + i = place[object]; + j = fixed[object]; + move(object, i); + move(object + 100, j); +} + +void +move(int object, int where) +{ + int from; + + if (object <= 100) + from = place[object]; + else + from = fixed[object - 100]; + if (from > 0 && from <= 300) + carry(object, from); + drop(object, where); +} + +int +put(int object, int where, int pval) +{ + move(object, where); + return (-1 - pval); +} + +void +carry(int object, int where) +{ + int temp; + + if (object <= 100) { + if (place[object] == -1) + return; + place[object] = -1; + holding++; + } + if (atloc[where] == object) { + atloc[where] = links[object]; + return; + } + for (temp = atloc[where]; links[temp] != object; temp = links[temp]); + links[temp] = links[object]; +} + + +void +drop(int object, int where) +{ + if (object > 100) + fixed[object - 100] = where; + else { + if (place[object] == -1) + holding--; + place[object] = where; + } + if (where <= 0) + return; + links[object] = atloc[where]; + atloc[where] = object; +} + +/* look up or store a word */ +/* -2 for store, -1 for user word, >=0 for canned lookup */ +/* used for storing only */ +int +vocab(const char *word, int type, int value) +{ + int adr; + const char *s; + char *t; + int hash, i; + struct hashtab *h; + + for (hash = 0, s = word, i = 0; i < 5 && *s; i++) /* some kind of hash*/ + hash += *s++; /* add all chars in the word */ + hash = (hash * 3719) & 077777; /* pulled that one out of a hat */ + hash %= HTSIZE; /* put it into range of table */ + + for (adr = hash;; adr++) { /* look for entry in table */ + if (adr == HTSIZE) + adr = 0;/* wrap around */ + h = &voc[adr]; /* point at the entry */ + switch (type) { + case -2: /* fill in entry */ + if (h->val) /* already got an entry? */ + goto exitloop2; + h->val = value; + h->atab = malloc(length(word)); + if (h->atab == NULL) + err(1, NULL); + for (s = word, t = h->atab; *s;) + *t++ = *s++ ^ '='; + *t = 0 ^ '='; + /* encrypt slightly to thwart core reader */ + /* printf("Stored \"%s\" (%d ch) as entry %d\n", */ + /* word, length(word), adr); */ + return (0); /* entry unused */ + case -1: /* looking up user word */ + if (h->val == 0) + return (-1); /* not found */ + for (s = word, t = h->atab; *t ^ '=';) + if ((*s++ ^ '=') != *t++) + goto exitloop2; + if ((*s ^ '=') != *t && s - word < 5) + goto exitloop2; + /* the word matched o.k. */ + return (h->val); + default: /* looking up known word */ + if (h->val == 0) + errx(1,"Unable to find %s in vocab", word); + for (s = word, t = h->atab; *t ^ '=';) + if ((*s++ ^ '=') != *t++) + goto exitloop2; + /* the word matched o.k. */ + if (h->val / 1000 != type) + continue; + return (h->val % 1000); + } + +exitloop2: /* hashed entry does not match */ + if (adr + 1 == hash || hash == 0) + errx(1,"Hash table overflow"); + } +} + +/* print hash table (for debugging) */ +static __unused void +prht(void) +{ + int i, j, l; + char *c; + struct hashtab *h; + for (i = 0; i < HTSIZE / 10 + 1; i++) { + printf("%4d", i * 10); + for (j = 0; j < 10; j++) { + if (i * 10 + j >= HTSIZE) + break; + h = &voc[i * 10 + j]; + putchar(' '); + if (h->val == 0) { + printf("-----"); + continue; + } + for (l = 0, c = h->atab; l < 5; l++) + if ((*c ^ '=')) + putchar(*c++ ^ '='); + else + putchar(' '); + } + putchar('\n'); + } +} diff --git a/games/adventure/wizard.c b/games/adventure/wizard.c new file mode 100644 index 000000000..152915a96 --- /dev/null +++ b/games/adventure/wizard.c @@ -0,0 +1,162 @@ +/* $NetBSD: wizard.c,v 1.16 2012/10/12 15:41:10 dholland Exp $ */ + +/*- + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * The game adventure was originally written in Fortran by Will Crowther + * and Don Woods. It was later translated to C and enhanced by Jim + * Gillogly. This code is derived from software contributed to Berkeley + * by Jim Gillogly at The Rand Corporation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#ifndef lint +#if 0 +static char sccsid[] = "@(#)wizard.c 8.1 (Berkeley) 6/2/93"; +#else +__RCSID("$NetBSD: wizard.c,v 1.16 2012/10/12 15:41:10 dholland Exp $"); +#endif +#endif /* not lint */ + +/* Re-coding of advent in C: privileged operations */ + +#include +#include +#include +#include +#include "hdr.h" +#include "extern.h" + +static int wizard(void); + +void +datime(int *d, int *t) +{ + time_t tvec; + struct tm *tptr; + + time(&tvec); + tptr = localtime(&tvec); + /* day since 1977 (mod leap) */ + *d = (tptr->tm_yday + 365 * (tptr->tm_year - 77) + + (tptr->tm_year - 77) / 4 - (tptr->tm_year - 1) / 100 + + (tptr->tm_year + 299) / 400); + /* bug: this will overflow in the year 2066 AD (with 16 bit int) */ + /* it will be attributed to Wm the C's millenial celebration */ + /* and minutes since midnite */ + *t = tptr->tm_hour * 60 + tptr->tm_min; +} /* pretty painless */ + + +static char magic[6]; + +void +poof(void) +{ + strcpy(magic, DECR('d', 'w', 'a', 'r', 'f')); + latency = 45; +} + +int +Start(void) +{ + int d, t, delay; + + datime(&d, &t); + delay = (d - saveday) * 1440 + (t - savet); /* good for about a + * month */ + + if (delay >= latency) { + saved = -1; + return (FALSE); + } + printf("This adventure was suspended a mere %d minute%s ago.", + delay, delay == 1 ? "" : "s"); + if (delay <= latency / 3) { + mspeak(2); + exit(0); + } + mspeak(8); + if (!wizard()) { + mspeak(9); + exit(0); + } + saved = -1; + return (FALSE); +} + +/* not as complex as advent/10 (for now) */ +static int +wizard(void) +{ + char *word, *x; + if (!yesm(16, 0, 7)) + return (FALSE); + mspeak(17); + getin(&word, &x); + if (!weq(word, magic)) { + mspeak(20); + return (FALSE); + } + mspeak(19); + return (TRUE); +} + +void +ciao(void) +{ + char fname[80]; + size_t pos; + + printf("What would you like to call the saved version?\n"); + /* XXX - should use fgetln to avoid arbitrary limit */ + for (pos = 0; pos < sizeof(fname) - 1; pos++) { + int ch; + ch = getchar(); + if (ch == '\n' || ch == EOF) + break; + fname[pos] = ch; + } + fname[pos] = '\0'; + if (save(fname) != 0) + return; /* Save failed */ + printf("To resume, say \"adventure %s\".\n", fname); + printf("\"With these rooms I might now have been familiarly "); + printf("acquainted.\"\n"); + exit(0); +} + + +int +ran(int range) +{ + long i; + + i = rand() % range; + return (i); +} diff --git a/releasetools/nbsd_ports b/releasetools/nbsd_ports index 74478c986..db19bb0dd 100644 --- a/releasetools/nbsd_ports +++ b/releasetools/nbsd_ports @@ -68,6 +68,9 @@ 2013/12/1 12:00:00,external/mit/Makefile 2013/12/1 12:00:00,external/public-domain 2013/12/1 12:00:00,external/README +2013/12/1 12:00:00,games/adventure +2013/12/1 12:00:00,games/Makefile +2013/12/1 12:00:00,games/Makefile.inc 2013/12/1 12:00:00,gnu/dist/texinfo 2013/12/1 12:00:00,gnu/usr.bin/texinfo 2013/12/1 12:00:00,gnu/Makefile