diff --git a/hack/COPYRIGHT b/hack/COPYRIGHT new file mode 100644 index 0000000..74b7ecf --- /dev/null +++ b/hack/COPYRIGHT @@ -0,0 +1,33 @@ +$NetBSD: COPYRIGHT,v 1.2 1995/03/23 08:29:05 cgd Exp $ + +Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica, +Amsterdam +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. + +- 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. + +- Neither the name of the Stichting Centrum voor Wiskunde en +Informatica, 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER +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. diff --git a/hack/COPYRIGHT-JF b/hack/COPYRIGHT-JF new file mode 100644 index 0000000..c967f8f --- /dev/null +++ b/hack/COPYRIGHT-JF @@ -0,0 +1,28 @@ +$NetBSD$ + +/* + * Copyright (c) 1982 Jay Fenlason + * 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. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``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. + */ diff --git a/hack/alloc.c b/hack/alloc.c new file mode 100644 index 0000000..41ebb2f --- /dev/null +++ b/hack/alloc.c @@ -0,0 +1,117 @@ +/* $NetBSD: alloc.c,v 1.4 1997/10/19 16:56:47 christos Exp $ */ + +/* + * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica, + * Amsterdam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - 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. + * + * - Neither the name of the Stichting Centrum voor Wiskunde en + * Informatica, 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER + * 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. + */ + +/* + * Copyright (c) 1982 Jay Fenlason + * 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. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``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 +#ifndef lint +__RCSID("$NetBSD: alloc.c,v 1.4 1997/10/19 16:56:47 christos Exp $"); +#endif /* not lint */ + +#include +#include "hack.h" +#include "extern.h" + +#ifdef LINT + +/* + a ridiculous definition, suppressing + "possible pointer alignment problem" for (long *) malloc() + "enlarg defined but never used" + "ftell defined (in ) but never used" + from lint +*/ +long * +alloc(n) + unsigned n; +{ + long dummy = ftell(stderr); + if (n) + dummy = 0; /* make sure arg is used */ + return (&dummy); +} + +#else + +long * +alloc(lth) + unsigned lth; +{ + char *ptr; + + if (!(ptr = malloc(lth))) + panic("Cannot get %d bytes", lth); + return ((long *) ptr); +} + +long * +enlarge(ptr, lth) + char *ptr; + unsigned lth; +{ + char *nptr; + + if (!(nptr = realloc(ptr, lth))) + panic("Cannot reallocate %d bytes", lth); + return ((long *) nptr); +} + +#endif /* LINT */ diff --git a/hack/config.h b/hack/config.h new file mode 100644 index 0000000..235a62a --- /dev/null +++ b/hack/config.h @@ -0,0 +1,205 @@ +/* $NetBSD: config.h,v 1.6 2001/01/16 02:50:28 cgd Exp $ */ + +/* + * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica, + * Amsterdam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - 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. + * + * - Neither the name of the Stichting Centrum voor Wiskunde en + * Informatica, 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER + * 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. + */ + +/* + * Copyright (c) 1982 Jay Fenlason + * 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. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``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 "pathnames.h" + +#ifndef CONFIG /* make sure the compiler doesnt see the typedefs twice */ + +#define CONFIG +#define UNIX /* delete if no fork(), exec() available */ +#define CHDIR /* delete if no chdir() available */ + +/* + * Some include files are in a different place under SYSV + * BSD SYSV + * + * + * + * Some routines are called differently + * index strchr + * rindex strrchr + * Also, the code for suspend and various ioctls is only given for BSD4.2 + * (I do not have access to a SYSV system.) + */ +#define BSD /* delete this line on System V */ + +/* #define STUPID */ /* avoid some complicated expressions if + your C compiler chokes on them */ +/* #define PYRAMID_BUG */ /* avoid a bug on the Pyramid */ +/* #define NOWAITINCLUDE */ /* neither nor exists */ + +#define WIZARD "bruno" /* the person allowed to use the -D option */ +#define RECORD "record"/* the file containing the list of topscorers */ +#define NEWS "news" /* the file containing the latest hack news */ +#define HELP "help" /* the file containing a description of the commands */ +#define SHELP "hh" /* abbreviated form of the same */ +#define RUMORFILE "rumors" /* a file with fortune cookies */ +#define DATAFILE "data" /* a file giving the meaning of symbols used */ +#define FMASK 0660 /* file creation mask */ +#define HLOCK "perm" /* an empty file used for locking purposes */ +#define LLOCK "safelock" /* link to previous */ + +#ifdef UNIX +/* + * Define DEF_PAGER as your default pager, e.g. "/bin/cat" or "/usr/ucb/more" + * If defined, it can be overridden by the environment variable PAGER. + * Hack will use its internal pager if DEF_PAGER is not defined. + * (This might be preferable for security reasons.) + * #define DEF_PAGER ".../mydir/mypager" + */ + +/* + * If you define MAIL, then the player will be notified of new mail + * when it arrives. If you also define DEF_MAILREADER then this will + * be the default mail reader, and can be overridden by the environment + * variable MAILREADER; otherwise an internal pager will be used. + * A stat system call is done on the mailbox every MAILCKFREQ moves. + */ +/* #define MAIL */ +#define DEF_MAILREADER _PATH_MAIL /* or e.g. /bin/mail */ +#define MAILCKFREQ 100 + + +#define SHELL /* do not delete the '!' command */ + +#ifdef BSD +#define SUSPEND /* let ^Z suspend the game */ +#endif /* BSD */ +#endif /* UNIX */ + +#ifdef CHDIR +/* + * If you define HACKDIR, then this will be the default playground; + * otherwise it will be the current directory. + */ +#ifdef QUEST +#define HACKDIR _PATH_QUEST +#else /* QUEST */ +#define HACKDIR _PATH_HACK +#endif /* QUEST */ + +/* + * Some system administrators are stupid enough to make Hack suid root + * or suid daemon, where daemon has other powers besides that of reading or + * writing Hack files. In such cases one should be careful with chdir's + * since the user might create files in a directory of his choice. + * Of course SECURE is meaningful only if HACKDIR is defined. + */ +#define SECURE /* do setuid(getuid()) after chdir() */ + +/* + * If it is desirable to limit the number of people that can play Hack + * simultaneously, define HACKDIR, SECURE and MAX_NR_OF_PLAYERS. + * #define MAX_NR_OF_PLAYERS 100 + */ +#endif /* CHDIR */ + +/* size of terminal screen is (at least) (ROWNO+2) by COLNO */ +#define COLNO 80 +#define ROWNO 22 + +/* + * small signed integers (8 bits suffice) + * typedef char schar; + * will do when you have signed characters; otherwise use + * typedef short int schar; + * + * Use short chars anyway to avoid warnings. + */ +#if 1 +typedef short int schar; +#else +typedef char schar; +#endif + +/* + * small unsigned integers (8 bits suffice - but 7 bits do not) + * - these are usually object types; be careful with inequalities! - + * typedef unsigned char uchar; + * will be satisfactory if you have an "unsigned char" type; otherwise use + * typedef unsigned short int uchar; + */ +typedef unsigned char uchar; + +/* + * small integers in the range 0 - 127, usually coordinates + * although they are nonnegative they must not be declared unsigned + * since otherwise comparisons with signed quantities are done incorrectly + */ +typedef schar xchar; +typedef xchar boolean; /* 0 or 1 */ +#define TRUE 1 +#define FALSE 0 + +/* + * Declaration of bitfields in various structs; if your C compiler + * doesnt handle bitfields well, e.g., if it is unable to initialize + * structs containing bitfields, then you might use + * #define Bitfield(x,n) uchar x + * since the bitfields used never have more than 7 bits. (Most have 1 bit.) + */ +#define Bitfield(x,n) unsigned x:n + +#define SIZE(x) (int)(sizeof(x) / sizeof(x[0])) + +#endif /* CONFIG */ diff --git a/hack/date.h b/hack/date.h new file mode 100644 index 0000000..ebe120a --- /dev/null +++ b/hack/date.h @@ -0,0 +1,64 @@ +/* $NetBSD: date.h,v 1.4 2001/03/25 20:43:58 jsm Exp $ */ + +/* + * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica, + * Amsterdam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - 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. + * + * - Neither the name of the Stichting Centrum voor Wiskunde en + * Informatica, 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER + * 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. + */ + +/* + * Copyright (c) 1982 Jay Fenlason + * 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. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``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. + */ + +const char datestring[] = "Tue Jul 23 1985"; diff --git a/hack/def.edog.h b/hack/def.edog.h new file mode 100644 index 0000000..dc8b314 --- /dev/null +++ b/hack/def.edog.h @@ -0,0 +1,76 @@ +/* $NetBSD: def.edog.h,v 1.4 1997/10/19 16:56:51 christos Exp $ */ + +/* + * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica, + * Amsterdam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - 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. + * + * - Neither the name of the Stichting Centrum voor Wiskunde en + * Informatica, 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER + * 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. + */ + +/* + * Copyright (c) 1982 Jay Fenlason + * 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. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``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. + */ + +#ifndef _DEF_EDOG_H_ +#define _DEF_EDOG_H_ +struct edog { + long hungrytime; /* at this time dog gets hungry */ + long eattime; /* dog is eating */ + long droptime; /* moment dog dropped object */ + unsigned dropdist; /* dist of drpped obj from @ */ + unsigned apport; /* amount of training */ + long whistletime; /* last time he whistled */ +}; +#define EDOG(mp) ((struct edog *)(&(mp->mextra[0]))) + +#endif /* _DEF_EDOG_H_ */ diff --git a/hack/def.eshk.h b/hack/def.eshk.h new file mode 100644 index 0000000..1094884 --- /dev/null +++ b/hack/def.eshk.h @@ -0,0 +1,88 @@ +/* $NetBSD: def.eshk.h,v 1.4 1997/10/19 16:56:53 christos Exp $ */ + +/* + * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica, + * Amsterdam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - 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. + * + * - Neither the name of the Stichting Centrum voor Wiskunde en + * Informatica, 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER + * 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. + */ + +/* + * Copyright (c) 1982 Jay Fenlason + * 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. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``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. + */ + +#ifndef _DEF_ESHK_H_ +#define _DEF_ESHK_H_ + +#define BILLSZ 200 +struct bill_x { + unsigned bo_id; + unsigned useup:1; + unsigned bquan:7; + unsigned price; /* price per unit */ +}; + +struct eshk { + long int robbed; /* amount stolen by most recent customer */ + boolean following; /* following customer since he owes us sth */ + schar shoproom; /* index in rooms; set by inshop() */ + coord shk; /* usual position shopkeeper */ + coord shd; /* position shop door */ + int shoplevel; /* level of his shop */ + int billct; + struct bill_x bill[BILLSZ]; + int visitct; /* nr of visits by most recent customer */ + char customer[PL_NSIZ]; /* most recent customer */ + char shknam[PL_NSIZ]; +}; +#endif /* _DEF_ESHK_H_ */ diff --git a/hack/def.flag.h b/hack/def.flag.h new file mode 100644 index 0000000..d59ded9 --- /dev/null +++ b/hack/def.flag.h @@ -0,0 +1,105 @@ +/* $NetBSD: def.flag.h,v 1.4 1997/10/19 16:56:56 christos Exp $ */ + +/* + * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica, + * Amsterdam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - 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. + * + * - Neither the name of the Stichting Centrum voor Wiskunde en + * Informatica, 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER + * 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. + */ + +/* + * Copyright (c) 1982 Jay Fenlason + * 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. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``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. + */ + +#ifndef _DEF_FLAG_H_ +#define _DEF_FLAG_H_ +struct flag { + unsigned ident; /* social security number for each monster */ + unsigned debug:1; /* in debugging mode */ +#define wizard flags.debug + unsigned toplin:2; /* a top line (message) has been printed */ + /* 0: top line empty; 2: no --More-- reqd. */ + unsigned cbreak:1; /* in cbreak mode, rogue format */ + unsigned standout:1; /* use standout for --More-- */ + unsigned nonull:1; /* avoid sending nulls to the terminal */ + unsigned time:1; /* display elapsed 'time' */ + unsigned nonews:1; /* suppress news printing */ + unsigned notombstone:1; + unsigned end_top, end_around; /* describe desired score list */ + unsigned end_own:1; /* idem (list all own scores) */ + unsigned no_rest_on_space:1; /* spaces are ignored */ + unsigned beginner:1; + unsigned female:1; + unsigned invlet_constant:1; /* let objects keep their + inventory symbol */ + unsigned move:1; + unsigned mv:1; + unsigned run:3; /* 0: h (etc), 1: H (etc), 2: fh (etc) */ + /* 3: FH, 4: ff+, 5: ff-, 6: FF+, 7: FF- */ + unsigned nopick:1; /* do not pickup objects */ + unsigned echo:1; /* 1 to echo characters */ + unsigned botl:1; /* partially redo status line */ + unsigned botlx:1; /* print an entirely new bottom line */ + unsigned nscrinh:1; /* inhibit nscr() in pline(); */ + unsigned made_amulet:1; + unsigned no_of_wizards:2;/* 0, 1 or 2 (wizard and his shadow) */ + /* reset from 2 to 1, but never to 0 */ + unsigned moonphase:3; +#define NEW_MOON 0 +#define FULL_MOON 4 + +}; + +extern struct flag flags; + +#endif /* _DEF_FLAG_H_ */ diff --git a/hack/def.func_tab.h b/hack/def.func_tab.h new file mode 100644 index 0000000..123f902 --- /dev/null +++ b/hack/def.func_tab.h @@ -0,0 +1,79 @@ +/* $NetBSD: def.func_tab.h,v 1.5 2001/03/25 20:43:58 jsm Exp $ */ + +/* + * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica, + * Amsterdam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - 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. + * + * - Neither the name of the Stichting Centrum voor Wiskunde en + * Informatica, 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER + * 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. + */ + +/* + * Copyright (c) 1982 Jay Fenlason + * 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. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``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. + */ + +#ifndef _DEF_FUNC_TAB_H_ +#define _DEF_FUNC_TAB_H_ +struct func_tab { + char f_char; + int (*f_funct) __P((void)); +}; + +extern const struct func_tab cmdlist[]; + +struct ext_func_tab { + const char *ef_txt; + int (*ef_funct) __P((void)); +}; + +extern const struct ext_func_tab extcmdlist[]; +#endif /* _DEF_FUNC_TAB_H_ */ diff --git a/hack/def.gen.h b/hack/def.gen.h new file mode 100644 index 0000000..907522d --- /dev/null +++ b/hack/def.gen.h @@ -0,0 +1,77 @@ +/* $NetBSD: def.gen.h,v 1.4 1997/10/19 16:57:01 christos Exp $ */ + +/* + * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica, + * Amsterdam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - 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. + * + * - Neither the name of the Stichting Centrum voor Wiskunde en + * Informatica, 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER + * 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. + */ + +/* + * Copyright (c) 1982 Jay Fenlason + * 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. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``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. + */ + +#ifndef _DEF_GEN_H_ +#define _DEF_GEN_H_ +struct gen { + struct gen *ngen; + xchar gx,gy; + unsigned gflag; /* 037: trap type; 040: SEEN flag */ + /* 0100: ONCE only */ +#define TRAPTYPE 037 +#define SEEN 040 +#define ONCE 0100 +}; +extern struct gen *fgold, *ftrap; +#define newgen() (struct gen *) alloc(sizeof(struct gen)) +#endif /* _DEF_GEN_H_ */ diff --git a/hack/def.gold.h b/hack/def.gold.h new file mode 100644 index 0000000..91fc193 --- /dev/null +++ b/hack/def.gold.h @@ -0,0 +1,74 @@ +/* $NetBSD: def.gold.h,v 1.4 1997/10/19 16:57:03 christos Exp $ */ + +/* + * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica, + * Amsterdam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - 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. + * + * - Neither the name of the Stichting Centrum voor Wiskunde en + * Informatica, 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER + * 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. + */ + +/* + * Copyright (c) 1982 Jay Fenlason + * 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. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``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. + */ + +#ifndef _DEF_GOLD_H_ +#define _DEF_GOLD_H_ +struct gold { + struct gold *ngold; + xchar gx,gy; + long amount; +}; + +#define newgold() (struct gold *) alloc(sizeof(struct gold)) +extern struct gold *fgold; +#endif /* _DEF_GOLD_H_ */ diff --git a/hack/def.mkroom.h b/hack/def.mkroom.h new file mode 100644 index 0000000..bf5145f --- /dev/null +++ b/hack/def.mkroom.h @@ -0,0 +1,89 @@ +/* $NetBSD: def.mkroom.h,v 1.4 1997/10/19 16:57:05 christos Exp $ */ + +/* + * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica, + * Amsterdam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - 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. + * + * - Neither the name of the Stichting Centrum voor Wiskunde en + * Informatica, 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER + * 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. + */ + +/* + * Copyright (c) 1982 Jay Fenlason + * 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. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``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. + */ + +#ifndef _DEF_MKROOM_H_ +#define _DEF_MKROOM_H_ +struct mkroom { + schar lx,hx,ly,hy; /* usually xchar, but hx may be -1 */ + schar rtype,rlit,doorct,fdoor; +}; + +#define MAXNROFROOMS 15 +extern struct mkroom rooms[MAXNROFROOMS+1]; + +#define DOORMAX 100 +extern coord doors[DOORMAX]; + +/* various values of rtype */ +/* 0: ordinary room; 8-15: various shops */ +/* Note: some code assumes that >= 8 means shop, so be careful when adding + new roomtypes */ +#define SWAMP 3 +#define VAULT 4 +#define BEEHIVE 5 +#define MORGUE 6 +#define ZOO 7 +#define SHOPBASE 8 +#define WANDSHOP 9 +#define GENERAL 15 +#endif /* _DEF_MKROOM_H_ */ diff --git a/hack/def.monst.h b/hack/def.monst.h new file mode 100644 index 0000000..c22d44d --- /dev/null +++ b/hack/def.monst.h @@ -0,0 +1,122 @@ +/* $NetBSD: def.monst.h,v 1.6 2001/03/25 20:43:58 jsm Exp $ */ + +/* + * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica, + * Amsterdam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - 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. + * + * - Neither the name of the Stichting Centrum voor Wiskunde en + * Informatica, 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER + * 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. + */ + +/* + * Copyright (c) 1982 Jay Fenlason + * 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. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``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. + */ + +#ifndef _DEF_MONST_H_ +#define _DEF_MONST_H_ +struct monst { + struct monst *nmon; + const struct permonst *data; + unsigned m_id; + xchar mx,my; + xchar mdx,mdy; /* if mdispl then pos where last displayed */ +#define MTSZ 4 + coord mtrack[MTSZ]; /* monster track */ + schar mhp,mhpmax; + char mappearance; /* nonzero for undetected 'M's and for '1's */ + Bitfield(mimic,1); /* undetected mimic */ + Bitfield(mdispl,1); /* mdx,mdy valid */ + Bitfield(minvis,1); /* invisible */ + Bitfield(cham,1); /* shape-changer */ + Bitfield(mhide,1); /* hides beneath objects */ + Bitfield(mundetected,1); /* not seen in present hiding place */ + Bitfield(mspeed,2); + Bitfield(msleep,1); + Bitfield(mfroz,1); + Bitfield(mconf,1); + Bitfield(mflee,1); /* fleeing */ + Bitfield(mfleetim,7); /* timeout for mflee */ + Bitfield(mcan,1); /* has been cancelled */ + Bitfield(mtame,1); /* implies peaceful */ + Bitfield(mpeaceful,1); /* does not attack unprovoked */ + Bitfield(isshk,1); /* is shopkeeper */ + Bitfield(isgd,1); /* is guard */ + Bitfield(mcansee,1); /* cansee 1, temp.blinded 0, blind 0 */ + Bitfield(mblinded,7); /* cansee 0, temp.blinded n, blind 0 */ + Bitfield(mtrapped,1); /* trapped in a pit or bear trap */ + Bitfield(mnamelth,6); /* length of name (following mxlth) */ +#ifndef NOWORM + Bitfield(wormno,5); /* at most 31 worms on any level */ +#endif /* NOWORM */ + unsigned mtrapseen; /* bitmap of traps we've been trapped in */ + long mlstmv; /* prevent two moves at once */ + struct obj *minvent; + long mgold; + unsigned mxlth; /* length of following data */ + /* in order to prevent alignment problems mextra should + be (or follow) a long int */ + long mextra[1]; /* monster dependent info */ +}; + +#define newmonst(xl) (struct monst *) alloc((unsigned)(xl) + sizeof(struct monst)) + +extern struct monst *fmon; +extern struct monst *fallen_down; + +/* these are in mspeed */ +#define MSLOW 1 /* slow monster */ +#define MFAST 2 /* speeded monster */ + +#define NAME(mtmp) (((char *) mtmp->mextra) + mtmp->mxlth) +#define MREGEN "TVi1" +#define UNDEAD "ZVW " +#endif /* _DEF_MONST_H_ */ diff --git a/hack/def.obj.h b/hack/def.obj.h new file mode 100644 index 0000000..4b86aec --- /dev/null +++ b/hack/def.obj.h @@ -0,0 +1,111 @@ +/* $NetBSD: def.obj.h,v 1.4 1997/10/19 16:57:09 christos Exp $ */ + +/* + * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica, + * Amsterdam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - 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. + * + * - Neither the name of the Stichting Centrum voor Wiskunde en + * Informatica, 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER + * 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. + */ + +/* + * Copyright (c) 1982 Jay Fenlason + * 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. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``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. + */ + +#ifndef _DEF_OBJ_H_ +#define _DEF_OBJ_H_ +struct obj { + struct obj *nobj; + unsigned o_id; + unsigned o_cnt_id; /* id of container object is in */ + xchar ox,oy; + xchar odx,ody; + uchar otyp; + uchar owt; + uchar quan; /* use oextra for tmp gold objects */ + schar spe; /* quality of weapon, armor or ring (+ or -) + number of charges for wand ( >= -1 ) + special for uball and amulet %% BAH */ + char olet; + char invlet; + Bitfield(oinvis,1); /* not yet implemented */ + Bitfield(odispl,1); + Bitfield(known,1); /* exact nature known */ + Bitfield(dknown,1); /* color or text known */ + Bitfield(cursed,1); + Bitfield(unpaid,1); /* on some bill */ + Bitfield(rustfree,1); + Bitfield(onamelth,6); + long age; /* creation date */ + long owornmask; +#define W_ARM 01L +#define W_ARM2 02L +#define W_ARMH 04L +#define W_ARMS 010L +#define W_ARMG 020L +#define W_ARMOR (W_ARM | W_ARM2 | W_ARMH | W_ARMS | W_ARMG) +#define W_RINGL 010000L /* make W_RINGL = RING_LEFT (see uprop) */ +#define W_RINGR 020000L +#define W_RING (W_RINGL | W_RINGR) +#define W_WEP 01000L +#define W_BALL 02000L +#define W_CHAIN 04000L + long oextra[1]; /* used for name of ordinary objects - length + is flexible; amount for tmp gold objects */ +}; + +extern struct obj *fobj; + +#define newobj(xl) (struct obj *) alloc((unsigned)(xl) + sizeof(struct obj)) +#define ONAME(otmp) ((char *) otmp->oextra) +#define OGOLD(otmp) (otmp->oextra[0]) +#endif /* _DEF_OBJ_H_ */ diff --git a/hack/def.objclass.h b/hack/def.objclass.h new file mode 100644 index 0000000..5641384 --- /dev/null +++ b/hack/def.objclass.h @@ -0,0 +1,123 @@ +/* $NetBSD: def.objclass.h,v 1.5 2001/03/25 20:43:58 jsm Exp $ */ + +/* + * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica, + * Amsterdam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - 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. + * + * - Neither the name of the Stichting Centrum voor Wiskunde en + * Informatica, 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER + * 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. + */ + +/* + * Copyright (c) 1982 Jay Fenlason + * 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. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``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. + */ + +#ifndef _DEF_OBJCLASS_H_ +#define _DEF_OBJCLASS_H_ +/* definition of a class of objects */ + +struct objclass { + const char *oc_name; /* actual name */ + const char *oc_descr; /* description when name unknown */ + char *oc_uname; /* called by user */ + Bitfield(oc_name_known,1); + Bitfield(oc_merge,1); /* merge otherwise equal objects */ + char oc_olet; + schar oc_prob; /* probability for mkobj() */ + schar oc_delay; /* delay when using such an object */ + uchar oc_weight; + schar oc_oc1, oc_oc2; + int oc_oi; +#define nutrition oc_oi /* for foods */ +#define a_ac oc_oc1 /* for armors - only used in ARM_BONUS */ +#define ARM_BONUS(obj) ((10 - objects[obj->otyp].a_ac) + obj->spe) +#define a_can oc_oc2 /* for armors */ +#define bits oc_oc1 /* for wands and rings */ + /* wands */ +#define NODIR 1 +#define IMMEDIATE 2 +#define RAY 4 + /* rings */ +#define SPEC 1 /* +n is meaningful */ +#define wldam oc_oc1 /* for weapons and PICK_AXE */ +#define wsdam oc_oc2 /* for weapons and PICK_AXE */ +#define g_val oc_oi /* for gems: value on exit */ +}; + +extern struct objclass objects[]; + +/* definitions of all object-symbols */ + +#define ILLOBJ_SYM '\\' +#define AMULET_SYM '"' +#define FOOD_SYM '%' +#define WEAPON_SYM ')' +#define TOOL_SYM '(' +#define BALL_SYM '0' +#define CHAIN_SYM '_' +#define ROCK_SYM '`' +#define ARMOR_SYM '[' +#define POTION_SYM '!' +#define SCROLL_SYM '?' +#define WAND_SYM '/' +#define RING_SYM '=' +#define GEM_SYM '*' +/* Other places with explicit knowledge of object symbols: + * ....shk.c: char shtypes[] = "=/)%?!["; + * mklev.c: "=/)%?![<>" + * hack.mkobj.c: char mkobjstr[] = "))[[!!!!????%%%%/=**"; + * hack.apply.c: otmp = getobj("0#%", "put in"); + * hack.eat.c: otmp = getobj("%", "eat"); + * hack.invent.c: if(index("!%?[)=*(0/\"", sym)){ + * hack.invent.c: || index("%?!*",otmp->olet))){ + */ +#endif /* _DEF_OBJCLASS_H_ */ diff --git a/hack/def.objects.h b/hack/def.objects.h new file mode 100644 index 0000000..87dc1d6 --- /dev/null +++ b/hack/def.objects.h @@ -0,0 +1,351 @@ +/* $NetBSD: def.objects.h,v 1.5 2001/03/25 20:43:58 jsm Exp $ */ + +/* + * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica, + * Amsterdam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - 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. + * + * - Neither the name of the Stichting Centrum voor Wiskunde en + * Informatica, 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER + * 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. + */ + +/* + * Copyright (c) 1982 Jay Fenlason + * 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. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``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. + */ + +#ifndef _DEF_OBJECTS_H_ +#define _DEF_OBJECTS_H_ +/* objects have letter " % ) ( 0 _ ` [ ! ? / = * */ +#include "config.h" +#include "def.objclass.h" + +struct objclass objects[] = { + + { "strange object", NULL, NULL, 1, 0, + ILLOBJ_SYM, 0, 0, 0, 0, 0, 0 }, + { "amulet of Yendor", NULL, NULL, 1, 0, + AMULET_SYM, 100, 0, 2, 0, 0, 0 }, + +#define FOOD(name,prob,delay,weight,nutrition) { name, NULL, NULL, 1, 1,\ + FOOD_SYM, prob, delay, weight, 0, 0, nutrition } + +/* dog eats foods 0-4 but prefers 1 above 0,2,3,4 */ +/* food 4 can be read */ +/* food 5 improves your vision */ +/* food 6 makes you stronger (like Popeye) */ +/* foods CORPSE up to CORPSE+52 are cadavers */ + + FOOD("food ration", 50, 5, 4, 800), + FOOD("tripe ration", 20, 1, 2, 200), + FOOD("pancake", 3, 1, 1, 200), + FOOD("dead lizard", 3, 0, 1, 40), + FOOD("fortune cookie", 7, 0, 1, 40), + FOOD("carrot", 2, 0, 1, 50), + FOOD("tin", 7, 0, 1, 0), + FOOD("orange", 1, 0, 1, 80), + FOOD("apple", 1, 0, 1, 50), + FOOD("pear", 1, 0, 1, 50), + FOOD("melon", 1, 0, 1, 100), + FOOD("banana", 1, 0, 1, 80), + FOOD("candy bar", 1, 0, 1, 100), + FOOD("egg", 1, 0, 1, 80), + FOOD("clove of garlic", 1, 0, 1, 40), + FOOD("lump of royal jelly", 0, 0, 1, 200), + + FOOD("dead human", 0, 4, 40, 400), + FOOD("dead giant ant", 0, 1, 3, 30), + FOOD("dead giant bat", 0, 1, 3, 30), + FOOD("dead centaur", 0, 5, 50, 500), + FOOD("dead dragon", 0, 15, 150, 1500), + FOOD("dead floating eye", 0, 1, 1, 10), + FOOD("dead freezing sphere", 0, 1, 1, 10), + FOOD("dead gnome", 0, 1, 10, 100), + FOOD("dead hobgoblin", 0, 2, 20, 200), + FOOD("dead stalker", 0, 4, 40, 400), + FOOD("dead jackal", 0, 1, 10, 100), + FOOD("dead kobold", 0, 1, 10, 100), + FOOD("dead leprechaun", 0, 4, 40, 400), + FOOD("dead mimic", 0, 4, 40, 400), + FOOD("dead nymph", 0, 4, 40, 400), + FOOD("dead orc", 0, 2, 20, 200), + FOOD("dead purple worm", 0, 7, 70, 700), + FOOD("dead quasit", 0, 2, 20, 200), + FOOD("dead rust monster", 0, 5, 50, 500), + FOOD("dead snake", 0, 1, 10, 100), + FOOD("dead troll", 0, 4, 40, 400), + FOOD("dead umber hulk", 0, 5, 50, 500), + FOOD("dead vampire", 0, 4, 40, 400), + FOOD("dead wraith", 0, 1, 1, 10), + FOOD("dead xorn", 0, 7, 70, 700), + FOOD("dead yeti", 0, 7, 70, 700), + FOOD("dead zombie", 0, 1, 3, 30), + FOOD("dead acid blob", 0, 1, 3, 30), + FOOD("dead giant beetle", 0, 1, 1, 10), + FOOD("dead cockatrice", 0, 1, 3, 30), + FOOD("dead dog", 0, 2, 20, 200), + FOOD("dead ettin", 0, 1, 3, 30), + FOOD("dead fog cloud", 0, 1, 1, 10), + FOOD("dead gelatinous cube", 0, 1, 10, 100), + FOOD("dead homunculus", 0, 2, 20, 200), + FOOD("dead imp", 0, 1, 1, 10), + FOOD("dead jaguar", 0, 3, 30, 300), + FOOD("dead killer bee", 0, 1, 1, 10), + FOOD("dead leocrotta", 0, 5, 50, 500), + FOOD("dead minotaur", 0, 7, 70, 700), + FOOD("dead nurse", 0, 4, 40, 400), + FOOD("dead owlbear", 0, 7, 70, 700), + FOOD("dead piercer", 0, 2, 20, 200), + FOOD("dead quivering blob", 0, 1, 10, 100), + FOOD("dead giant rat", 0, 1, 3, 30), + FOOD("dead giant scorpion", 0, 1, 10, 100), + FOOD("dead tengu", 0, 3, 30, 300), + FOOD("dead unicorn", 0, 3, 30, 300), + FOOD("dead violet fungi", 0, 1, 10, 100), + FOOD("dead long worm", 0, 5, 50, 500), +/* %% wt of long worm should be proportional to its length */ + FOOD("dead xan", 0, 3, 30, 300), + FOOD("dead yellow light", 0, 1, 1, 10), + FOOD("dead zruty", 0, 6, 60, 600), + +/* weapons ... - ROCK come several at a time */ +/* weapons ... - (ROCK-1) are shot using idem+(BOW-ARROW) */ +/* weapons AXE, SWORD, THSWORD are good for worm-cutting */ +/* weapons (PICK-)AXE, DAGGER, CRYSKNIFE are good for tin-opening */ +#define WEAPON(name,prob,wt,ldam,sdam) { name, NULL, NULL, 1, 0 /*%%*/,\ + WEAPON_SYM, prob, 0, wt, ldam, sdam, 0 } + + WEAPON("arrow", 7, 0, 6, 6), + WEAPON("sling bullet", 7, 0, 4, 6), + WEAPON("crossbow bolt", 7, 0, 4, 6), + WEAPON("dart", 7, 0, 3, 2), + WEAPON("rock", 6, 1, 3, 3), + WEAPON("boomerang", 2, 3, 9, 9), + WEAPON("mace", 9, 3, 6, 7), + WEAPON("axe", 6, 3, 6, 4), + WEAPON("flail", 6, 3, 6, 5), + WEAPON("long sword", 8, 3, 8, 12), + WEAPON("two handed sword", 6, 4, 12, 6), + WEAPON("dagger", 6, 3, 4, 3), + WEAPON("worm tooth", 0, 4, 2, 2), + WEAPON("crysknife", 0, 3, 10, 10), + WEAPON("spear", 6, 3, 6, 8), + WEAPON("bow", 6, 3, 4, 6), + WEAPON("sling", 5, 3, 6, 6), + WEAPON("crossbow", 6, 3, 4, 6), + + { "whistle", "whistle", NULL, 0, 0, + TOOL_SYM, 90, 0, 2, 0, 0, 0 }, + { "magic whistle", "whistle", NULL, 0, 0, + TOOL_SYM, 10, 0, 2, 0, 0, 0 }, + { "expensive camera", NULL, NULL, 1, 1, + TOOL_SYM, 0, 0, 3, 0, 0, 0 }, + { "ice box", "large box", NULL, 0, 0, + TOOL_SYM, 0, 0, 40, 0, 0, 0 }, + { "pick-axe", NULL, NULL, 1, 1, + TOOL_SYM, 0, 0, 5, 6, 3, 0 }, + { "can opener", NULL, NULL, 1, 1, + TOOL_SYM, 0, 0, 1, 0, 0, 0 }, + { "heavy iron ball", NULL, NULL, 1, 0, + BALL_SYM, 100, 0, 20, 0, 0, 0 }, + { "iron chain", NULL, NULL, 1, 0, + CHAIN_SYM, 100, 0, 20, 0, 0, 0 }, + { "enormous rock", NULL, NULL, 1, 0, + ROCK_SYM, 100, 0, 200 /* > MAX_CARR_CAP */, 0, 0, 0 }, + +#define ARMOR(name,prob,delay,ac,can) { name, NULL, NULL, 1, 0,\ + ARMOR_SYM, prob, delay, 8, ac, can, 0 } + ARMOR("helmet", 3, 1, 9, 0), + ARMOR("plate mail", 5, 5, 3, 2), + ARMOR("splint mail", 8, 5, 4, 1), + ARMOR("banded mail", 10, 5, 4, 0), + ARMOR("chain mail", 10, 5, 5, 1), + ARMOR("scale mail", 10, 5, 6, 0), + ARMOR("ring mail", 15, 5, 7, 0), + /* the armors below do not rust */ + ARMOR("studded leather armor", 13, 3, 7, 1), + ARMOR("leather armor", 17, 3, 8, 0), + ARMOR("elven cloak", 5, 0, 9, 3), + ARMOR("shield", 3, 0, 9, 0), + ARMOR("pair of gloves", 1, 1, 9, 0), + +#define POTION(name,color) { name, color, NULL, 0, 1,\ + POTION_SYM, 0, 0, 2, 0, 0, 0 } + + POTION("restore strength", "orange"), + POTION("booze", "bubbly"), + POTION("invisibility", "glowing"), + POTION("fruit juice", "smoky"), + POTION("healing", "pink"), + POTION("paralysis", "puce"), + POTION("monster detection", "purple"), + POTION("object detection", "yellow"), + POTION("sickness", "white"), + POTION("confusion", "swirly"), + POTION("gain strength", "purple-red"), + POTION("speed", "ruby"), + POTION("blindness", "dark green"), + POTION("gain level", "emerald"), + POTION("extra healing", "sky blue"), + POTION("levitation", "brown"), + POTION(NULL, "brilliant blue"), + POTION(NULL, "clear"), + POTION(NULL, "magenta"), + POTION(NULL, "ebony"), + +#define SCROLL(name,text,prob) { name, text, NULL, 0, 1,\ + SCROLL_SYM, prob, 0, 3, 0, 0, 0 } + SCROLL("mail", "KIRJE", 0), + SCROLL("enchant armor", "ZELGO MER", 6), + SCROLL("destroy armor", "JUYED AWK YACC", 5), + SCROLL("confuse monster", "NR 9", 5), + SCROLL("scare monster", "XIXAXA XOXAXA XUXAXA", 4), + SCROLL("blank paper", "READ ME", 3), + SCROLL("remove curse", "PRATYAVAYAH", 6), + SCROLL("enchant weapon", "DAIYEN FOOELS", 6), + SCROLL("damage weapon", "HACKEM MUCHE", 5), + SCROLL("create monster", "LEP GEX VEN ZEA", 5), + SCROLL("taming", "PRIRUTSENIE", 1), + SCROLL("genocide", "ELBIB YLOH",2), + SCROLL("light", "VERR YED HORRE", 10), + SCROLL("teleportation", "VENZAR BORGAVVE", 5), + SCROLL("gold detection", "THARR", 4), + SCROLL("food detection", "YUM YUM", 1), + SCROLL("identify", "KERNOD WEL", 18), + SCROLL("magic mapping", "ELAM EBOW", 5), + SCROLL("amnesia", "DUAM XNAHT", 3), + SCROLL("fire", "ANDOVA BEGARIN", 5), + SCROLL("punishment", "VE FORBRYDERNE", 1), + SCROLL(NULL, "VELOX NEB", 0), + SCROLL(NULL, "FOOBIE BLETCH", 0), + SCROLL(NULL, "TEMOV", 0), + SCROLL(NULL, "GARVEN DEH", 0), + +#define WAND(name,metal,prob,flags) { name, metal, NULL, 0, 0,\ + WAND_SYM, prob, 0, 3, flags, 0, 0 } + + WAND("light", "iridium", 10, NODIR), + WAND("secret door detection", "tin", 5, NODIR), + WAND("create monster", "platinum", 5, NODIR), + WAND("wishing", "glass", 1, NODIR), + WAND("striking", "zinc", 9, IMMEDIATE), + WAND("slow monster", "balsa", 5, IMMEDIATE), + WAND("speed monster", "copper", 5, IMMEDIATE), + WAND("undead turning", "silver", 5, IMMEDIATE), + WAND("polymorph", "brass", 5, IMMEDIATE), + WAND("cancellation", "maple", 5, IMMEDIATE), + WAND("teleportation", "pine", 5, IMMEDIATE), + WAND("make invisible", "marble", 9, IMMEDIATE), + WAND("digging", "iron", 5, RAY), + WAND("magic missile", "aluminium", 10, RAY), + WAND("fire", "steel", 5, RAY), + WAND("sleep", "curved", 5, RAY), + WAND("cold", "short", 5, RAY), + WAND("death", "long", 1, RAY), + WAND(NULL, "oak", 0, 0), + WAND(NULL, "ebony", 0, 0), + WAND(NULL, "runed", 0, 0), + +#define RING(name,stone,spec) { name, stone, NULL, 0, 0,\ + RING_SYM, 0, 0, 1, spec, 0, 0 } + + RING("adornment", "engagement", 0), + RING("teleportation", "wooden", 0), + RING("regeneration", "black onyx", 0), + RING("searching", "topaz", 0), + RING("see invisible", "pearl", 0), + RING("stealth", "sapphire", 0), + RING("levitation", "moonstone", 0), + RING("poison resistance", "agate", 0), + RING("aggravate monster", "tiger eye", 0), + RING("hunger", "shining", 0), + RING("fire resistance", "gold", 0), + RING("cold resistance", "copper", 0), + RING("protection from shape changers", "diamond", 0), + RING("conflict", "jade", 0), + RING("gain strength", "ruby", SPEC), + RING("increase damage", "silver", SPEC), + RING("protection", "granite", SPEC), + RING("warning", "wire", 0), + RING("teleport control", "iron", 0), + RING(NULL, "ivory", 0), + RING(NULL, "blackened", 0), + +/* gems ************************************************************/ +#define GEM(name,color,prob,gval) { name, color, NULL, 0, 1,\ + GEM_SYM, prob, 0, 1, 0, 0, gval } + GEM("diamond", "blue", 1, 4000), + GEM("ruby", "red", 1, 3500), + GEM("sapphire", "blue", 1, 3000), + GEM("emerald", "green", 1, 2500), + GEM("turquoise", "green", 1, 2000), + GEM("aquamarine", "blue", 1, 1500), + GEM("tourmaline", "green", 1, 1000), + GEM("topaz", "yellow", 1, 900), + GEM("opal", "yellow", 1, 800), + GEM("garnet", "dark", 1, 700), + GEM("amethyst", "violet", 2, 650), + GEM("agate", "green", 2, 600), + GEM("onyx", "white", 2, 550), + GEM("jasper", "yellowish brown", 2, 500), + GEM("jade", "green", 2, 450), + GEM("worthless piece of blue glass", "blue", 20, 0), + GEM("worthless piece of red glass", "red", 20, 0), + GEM("worthless piece of yellow glass", "yellow", 20, 0), + GEM("worthless piece of green glass", "green", 20, 0), + { NULL, NULL, NULL, 0, 0, ILLOBJ_SYM, 0, 0, 0, 0, 0, 0 } +}; + +const char obj_symbols[] = { + ILLOBJ_SYM, AMULET_SYM, FOOD_SYM, WEAPON_SYM, TOOL_SYM, + BALL_SYM, CHAIN_SYM, ROCK_SYM, ARMOR_SYM, POTION_SYM, SCROLL_SYM, + WAND_SYM, RING_SYM, GEM_SYM, 0 }; +int bases[sizeof(obj_symbols)]; +#endif /* _DEF_OBJECTS_H_ */ diff --git a/hack/def.permonst.h b/hack/def.permonst.h new file mode 100644 index 0000000..4870297 --- /dev/null +++ b/hack/def.permonst.h @@ -0,0 +1,90 @@ +/* $NetBSD: def.permonst.h,v 1.5 2001/03/25 20:43:58 jsm Exp $ */ + +/* + * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica, + * Amsterdam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - 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. + * + * - Neither the name of the Stichting Centrum voor Wiskunde en + * Informatica, 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER + * 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. + */ + +/* + * Copyright (c) 1982 Jay Fenlason + * 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. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``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. + */ + +#ifndef _DEF_PERMONST_H_ +#define _DEF_PERMONST_H_ +struct permonst { + const char *mname; + char mlet; + schar mlevel,mmove,ac,damn,damd; + unsigned pxlth; +}; + +extern const struct permonst mons[]; +#define PM_ACID_BLOB &mons[7] +#define PM_ZOMBIE &mons[13] +#define PM_PIERCER &mons[17] +#define PM_KILLER_BEE &mons[26] +#define PM_WRAITH &mons[33] +#define PM_MIMIC &mons[37] +#define PM_VAMPIRE &mons[43] +#define PM_CHAMELEON &mons[47] +#define PM_DEMON &mons[54] +#define PM_MINOTAUR &mons[55] /* last in mons array */ +#define PM_SHK &mons[56] /* very last */ +#define PM_GHOST &pm_ghost +#define PM_EEL &pm_eel +#define PM_WIZARD &pm_wizard +#define CMNUM 55 /* number of common monsters */ + +#endif /* _DEF_PERMONST_H_ */ diff --git a/hack/def.rm.h b/hack/def.rm.h new file mode 100644 index 0000000..76090f9 --- /dev/null +++ b/hack/def.rm.h @@ -0,0 +1,115 @@ +/* $NetBSD: def.rm.h,v 1.5 2001/01/16 02:50:28 cgd Exp $ */ + +/* + * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica, + * Amsterdam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - 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. + * + * - Neither the name of the Stichting Centrum voor Wiskunde en + * Informatica, 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER + * 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. + */ + +/* + * Copyright (c) 1982 Jay Fenlason + * 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. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``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. + */ + +#ifndef _DEF_RM_H_ +#define _DEF_RM_H_ +/* Level location types */ +#define HWALL 1 +#define VWALL 2 +#define SDOOR 3 +#define SCORR 4 +#define LDOOR 5 +#define POOL 6 /* not yet fully implemented */ + /* this should in fact be a bit like lit */ +#define DOOR 7 +#define CORR 8 +#define ROOM 9 +#define STAIRS 10 + +/* + * Avoid using the level types in inequalities: + * these types are subject to change. + * Instead, use one of the macros below. + */ +#define IS_WALL(typ) ((typ) <= VWALL) +#define IS_ROCK(typ) ((typ) < POOL) /* absolutely nonaccessible */ +#define ACCESSIBLE(typ) ((typ) >= DOOR) /* good position */ +#define IS_ROOM(typ) ((typ) >= ROOM) /* ROOM or STAIRS */ +#define ZAP_POS(typ) ((typ) > DOOR) + +/* + * A few of the associated symbols are not hardwired. + */ +#ifdef QUEST +#define CORR_SYM ':' +#else +#define CORR_SYM '#' +#endif /* QUEST */ +#define POOL_SYM '}' + +#define ERRCHAR '{' + +/* + * The structure describing a coordinate position. + * Before adding fields, remember that this will significantly affect + * the size of temporary files and save files. + */ +struct rm { + char scrsym; + unsigned typ:5; + unsigned new:1; + unsigned seen:1; + unsigned lit:1; +}; +extern struct rm levl[COLNO][ROWNO]; +#endif /* _DEF_RM_H_ */ diff --git a/hack/def.trap.h b/hack/def.trap.h new file mode 100644 index 0000000..1a43618 --- /dev/null +++ b/hack/def.trap.h @@ -0,0 +1,89 @@ +/* $NetBSD: def.trap.h,v 1.4 1997/10/19 16:57:23 christos Exp $ */ + +/* + * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica, + * Amsterdam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - 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. + * + * - Neither the name of the Stichting Centrum voor Wiskunde en + * Informatica, 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER + * 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. + */ + +/* + * Copyright (c) 1982 Jay Fenlason + * 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. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``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. + */ + +#ifndef _DEF_TRAP_H_ +#define _DEF_TRAP_H_ +struct trap { + struct trap *ntrap; + xchar tx,ty; + unsigned ttyp:5; + unsigned tseen:1; + unsigned once:1; +}; + +extern struct trap *ftrap; +#define newtrap() (struct trap *) alloc(sizeof(struct trap)) + +/* various kinds of traps */ +#define BEAR_TRAP 0 +#define ARROW_TRAP 1 +#define DART_TRAP 2 +#define TRAPDOOR 3 +#define TELEP_TRAP 4 +#define PIT 5 +#define SLP_GAS_TRAP 6 +#define PIERC 7 +#define MIMIC 8 /* used only in mklev.c */ +#define TRAPNUM 9 /* if not less than 32, change sizeof(ttyp) */ + /* see also mtrapseen (bit map) */ +#endif /* _DEF_TRAP_H_ */ diff --git a/hack/def.wseg.h b/hack/def.wseg.h new file mode 100644 index 0000000..f829c97 --- /dev/null +++ b/hack/def.wseg.h @@ -0,0 +1,76 @@ +/* $NetBSD: def.wseg.h,v 1.4 1997/10/19 16:57:25 christos Exp $ */ + +/* + * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica, + * Amsterdam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - 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. + * + * - Neither the name of the Stichting Centrum voor Wiskunde en + * Informatica, 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER + * 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. + */ + +/* + * Copyright (c) 1982 Jay Fenlason + * 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. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``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. + */ + +#ifndef _DEF_WSEG_H_ +#define _DEF_WSEG_H_ +#ifndef NOWORM +/* worm structure */ +struct wseg { + struct wseg *nseg; + xchar wx,wy; + unsigned wdispl:1; +}; + +#define newseg() (struct wseg *) alloc(sizeof(struct wseg)) +#endif /* NOWORM */ +#endif /* _DEF_WSEG_H_ */ diff --git a/hack/hack.6.in b/hack/hack.6.in new file mode 100644 index 0000000..f7894e2 --- /dev/null +++ b/hack/hack.6.in @@ -0,0 +1,209 @@ +.\" $NetBSD: hack.6,v 1.11 2003/02/25 10:34:45 wiz Exp $ -*- nroff -*- +.\" +.\" Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica, +.\" Amsterdam +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions are +.\" met: +.\" +.\" - Redistributions of source code must retain the above copyright notice, +.\" this list of conditions and the following disclaimer. +.\" +.\" - 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. +.\" +.\" - Neither the name of the Stichting Centrum voor Wiskunde en +.\" Informatica, 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER +.\" 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. +.\" +.\" +.\" Copyright (c) 1982 Jay Fenlason +.\" 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. +.\" 3. The name of the author may not be used to endorse or promote products +.\" derived from this software without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED ``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. +.\" +.Dd March 31, 1985 +.Dt HACK 6 +.Os +.Sh NAME +.Nm hack +.Nd exploring The Dungeons of Doom +.Sh SYNOPSIS +.Nm +.Op Fl d Ar directory +.Op Fl n +.Op Fl u Ar playername +.Nm +.Op Fl d Ar directory +.Op Fl s +.Op Fl X +.Op Ar playername ... +.Sh DESCRIPTION +.Nm +is a display oriented dungeons \*[Am] dragons-like game. +Both display and command structure resemble rogue. +(For a game with the same structure but entirely different display - +a real cave instead of dull rectangles - try Quest.) +.Pp +To get started you really only need to know two commands. +The command +.Ic ? +will give you a list of the available commands and the command +.Ic / +will identify the things you see on the screen. +.Pp +To win the game (as opposed to merely playing to beat other people high +scores) you must locate the Amulet of Yendor which is somewhere below +the 20th level of the dungeon and get it out. +Nobody has achieved this yet and if somebody does, he will probably go +down in history as a hero among heroes. +.Pp +When the game ends, either by your death, when you quit, or if you escape +from the caves, +.Nm +will give you (a fragment of) the list of top scorers. +The scoring is based on many aspects of your behavior but a rough estimate +is obtained by taking the amount of gold you've found in the cave plus four +times your (real) experience. +Precious stones may be worth a lot of gold when brought to the exit. +There is a 10% penalty for getting yourself killed. +.Pp +The administration of the game is kept in the directory specified with the +.Fl d +option, or, if no such option is given, in the directory specified by +the environment variable +.Ev HACKDIR , +or, if no such variable exists, in the current directory. +This same directory contains several auxiliary files such as lockfiles and +the list of topscorers and a subdirectory +.Pa save +where games are saved. +The game administrator may however choose to install hack with a fixed +playing ground, usually +.Pa @hack_dir@ . +.Pp +The +.Fl n +option suppresses printing of the news. +.Pp +The +.Fl u +.Ar playername +option supplies the answer to the question "Who are you?". +When +.Ar playername +has as suffix one of +.Em -T , +.Em -S , +.Em -K , +.Em -F , +.Em -C , +or +.Em -W , +then this supplies the answer to the question "What kind of character ... ?". +.Pp +The +.Fl s +option will print out the list of your scores. +It may be followed by arguments +.Fl X +where X is one of the letters C, F, K, S, T, W to print the scores of +Cavemen, Fighters, Knights, Speleologists, Tourists or Wizards. +It may also be followed by one or more player names to print the scores of the +players mentioned. +.Sh AUTHORS +Jay Fenlason (+ Kenny Woodland, Mike Thome and Jon Payne) wrote the +original hack, very much like rogue (but full of bugs). +.br +Andries Brouwer continuously deformed their sources into the current +version - in fact an entirely different game. +.Sh FILES +.Bl -tag -width 24n -compact +.It Pa hack +The hack program. +.It Pa data, rumors +Data files used by hack. +.It Pa help, hh +Help data files. +.It Pa record +The list of topscorers. +.It Pa save +A subdirectory containing the saved games. +.It Pa bones_dd +Descriptions of the ghost and belongings of a deceased adventurer. +.It Pa xlock.dd +Description of a dungeon level. +.It Pa safelock +Lock file for xlock. +.It Pa record_lock +Lock file for record. +.El +.Sh ENVIRONMENT +.Bl -tag -width 24n -compact +.It Ev USER No or Ev LOGNAME +Your login name. +.It Ev HOME +Your home directory. +.It Ev SHELL +Your shell. +.It Ev TERM +The type of your terminal. +.It Ev HACKPAGER, PAGER +Pager used instead of default pager. +.It Ev MAIL +Mailbox file. +.It Ev MAILREADER +Reader used instead of default (probably +.Pa /usr/bin/mail ) . +.It Ev HACKDIR +Playground. +.It Ev HACKOPTIONS +String predefining several hack options (see help file). +.El +.Pp +Several other environment variables are used in debugging (wizard) mode, +like +.Ev GENOCIDED , +.Ev INVENT , +.Ev MAGIC +and +.Ev SHOPTYPE . +.Sh BUGS +Probably infinite. +Mail complaints to mcvax!aeb . diff --git a/hack/hack.Decl.c b/hack/hack.Decl.c new file mode 100644 index 0000000..b06ca85 --- /dev/null +++ b/hack/hack.Decl.c @@ -0,0 +1,110 @@ +/* $NetBSD: hack.Decl.c,v 1.5 2001/03/25 20:43:59 jsm Exp $ */ + +/* + * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica, + * Amsterdam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - 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. + * + * - Neither the name of the Stichting Centrum voor Wiskunde en + * Informatica, 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER + * 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. + */ + +/* + * Copyright (c) 1982 Jay Fenlason + * 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. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``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 +#ifndef lint +__RCSID("$NetBSD: hack.Decl.c,v 1.5 2001/03/25 20:43:59 jsm Exp $"); +#endif /* not lint */ + +#include "hack.h" +char nul[40]; /* contains zeros */ +char plname[PL_NSIZ];/* player name */ +char lock[PL_NSIZ + 4] = "1lock"; /* long enough for login name + * .99 */ + +boolean in_mklev, restoring; + +struct rm levl[COLNO][ROWNO]; /* level map */ +#ifndef QUEST +#include "def.mkroom.h" +struct mkroom rooms[MAXNROFROOMS + 1]; +coord doors[DOORMAX]; +#endif /* QUEST */ +struct monst *fmon = 0; +struct trap *ftrap = 0; +struct gold *fgold = 0; +struct obj *fobj = 0, *fcobj = 0, *invent = 0, *uwep = 0, *uarm = 0, *uarm2 = 0, + *uarmh = 0, *uarms = 0, *uarmg = 0, *uright = 0, *uleft = 0, + *uchain = 0, *uball = 0; +struct flag flags; +struct you u; +struct monst youmonst; /* dummy; used as return value for boomhit */ + +xchar dlevel = 1; +xchar xupstair, yupstair, xdnstair, ydnstair; +char *save_cm = 0; +const char *killer, *nomovemsg; + +long moves = 1; +long wailmsg = 0; + +int multi = 0; +char genocided[60]; +char fut_geno[60]; + +xchar curx, cury; +xchar seelx, seehx, seely, seehy; /* corners of lit room */ + +coord bhitpos; + +const char quitchars[] = " \r\n\033"; diff --git a/hack/hack.apply.c b/hack/hack.apply.c new file mode 100644 index 0000000..2036d87 --- /dev/null +++ b/hack/hack.apply.c @@ -0,0 +1,537 @@ +/* $NetBSD: hack.apply.c,v 1.6 2001/03/25 20:43:59 jsm Exp $ */ + +/* + * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica, + * Amsterdam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - 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. + * + * - Neither the name of the Stichting Centrum voor Wiskunde en + * Informatica, 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER + * 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. + */ + +/* + * Copyright (c) 1982 Jay Fenlason + * 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. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``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 +#ifndef lint +__RCSID("$NetBSD: hack.apply.c,v 1.6 2001/03/25 20:43:59 jsm Exp $"); +#endif /* not lint */ + +#include "hack.h" +#include "extern.h" +#include "def.edog.h" +#include "def.mkroom.h" + +static void use_camera __P((struct obj *)); +static int in_ice_box __P((struct obj *)); +static int ck_ice_box __P((struct obj *)); +static int out_ice_box __P((struct obj *)); +static void use_ice_box __P((struct obj *)); +static struct monst *bchit __P((int, int , int , int)); +static void use_whistle __P((struct obj *)); +static void use_magic_whistle __P((struct obj *)); +static int dig __P((void)); +static int use_pick_axe __P((struct obj *)); + +int +doapply() +{ + struct obj *obj; + int res = 1; + + obj = getobj("(", "use or apply"); + if (!obj) + return (0); + + switch (obj->otyp) { + case EXPENSIVE_CAMERA: + use_camera(obj); + break; + case ICE_BOX: + use_ice_box(obj); + break; + case PICK_AXE: + res = use_pick_axe(obj); + break; + + case MAGIC_WHISTLE: + if (pl_character[0] == 'W' || u.ulevel > 9) { + use_magic_whistle(obj); + break; + } + /* fall into next case */ + case WHISTLE: + use_whistle(obj); + break; + + case CAN_OPENER: + if (!carrying(TIN)) { + pline("You have no can to open."); + goto xit; + } + pline("You cannot open a tin without eating its contents."); + pline("In order to eat, use the 'e' command."); + if (obj != uwep) + pline("Opening the tin will be much easier if you wield the can-opener."); + goto xit; + + default: + pline("Sorry, I don't know how to use that."); +xit: + nomul(0); + return (0); + } + nomul(0); + return (res); +} + +/* ARGSUSED */ +static void +use_camera(obj) /* */ + struct obj *obj __attribute__((__unused__)); +{ + struct monst *mtmp; + if (!getdir(1)) { /* ask: in what direction? */ + flags.move = multi = 0; + return; + } + if (u.uswallow) { + pline("You take a picture of %s's stomach.", monnam(u.ustuck)); + return; + } + if (u.dz) { + pline("You take a picture of the %s.", + (u.dz > 0) ? "floor" : "ceiling"); + return; + } + if ((mtmp = bchit(u.dx, u.dy, COLNO, '!')) != NULL) { + if (mtmp->msleep) { + mtmp->msleep = 0; + pline("The flash awakens %s.", monnam(mtmp)); /* a3 */ + } else if (mtmp->data->mlet != 'y') + if (mtmp->mcansee || mtmp->mblinded) { + int tmp = dist(mtmp->mx, mtmp->my); + int tmp2; + if (cansee(mtmp->mx, mtmp->my)) + pline("%s is blinded by the flash!", Monnam(mtmp)); + setmangry(mtmp); + if (tmp < 9 && !mtmp->isshk && rn2(4)) { + mtmp->mflee = 1; + if (rn2(4)) + mtmp->mfleetim = rnd(100); + } + if (tmp < 3) + mtmp->mcansee = mtmp->mblinded = 0; + else { + tmp2 = mtmp->mblinded; + tmp2 += rnd(1 + 50 / tmp); + if (tmp2 > 127) + tmp2 = 127; + mtmp->mblinded = tmp2; + mtmp->mcansee = 0; + } + } + } +} + +static +struct obj *current_ice_box;/* a local variable of use_ice_box, to be + * used by its local procedures in/ck_ice_box */ +static int +in_ice_box(obj) + struct obj *obj; +{ + if (obj == current_ice_box || + (Punished && (obj == uball || obj == uchain))) { + pline("You must be kidding."); + return (0); + } + if (obj->owornmask & (W_ARMOR | W_RING)) { + pline("You cannot refrigerate something you are wearing."); + return (0); + } + if (obj->owt + current_ice_box->owt > 70) { + pline("It won't fit."); + return (1); /* be careful! */ + } + if (obj == uwep) { + if (uwep->cursed) { + pline("Your weapon is welded to your hand!"); + return (0); + } + setuwep((struct obj *) 0); + } + current_ice_box->owt += obj->owt; + freeinv(obj); + obj->o_cnt_id = current_ice_box->o_id; + obj->nobj = fcobj; + fcobj = obj; + obj->age = moves - obj->age; /* actual age */ + return (1); +} + +static int +ck_ice_box(obj) + struct obj *obj; +{ + return (obj->o_cnt_id == current_ice_box->o_id); +} + +static int +out_ice_box(obj) + struct obj *obj; +{ + struct obj *otmp; + if (obj == fcobj) + fcobj = fcobj->nobj; + else { + for (otmp = fcobj; otmp->nobj != obj; otmp = otmp->nobj) + if (!otmp->nobj) + panic("out_ice_box"); + otmp->nobj = obj->nobj; + } + current_ice_box->owt -= obj->owt; + obj->age = moves - obj->age; /* simulated point of time */ + (void) addinv(obj); + return 0; +} + +static void +use_ice_box(obj) + struct obj *obj; +{ + int cnt = 0; + struct obj *otmp; + current_ice_box = obj; /* for use by in/out_ice_box */ + for (otmp = fcobj; otmp; otmp = otmp->nobj) + if (otmp->o_cnt_id == obj->o_id) + cnt++; + if (!cnt) + pline("Your ice-box is empty."); + else { + pline("Do you want to take something out of the ice-box? [yn] "); + if (readchar() == 'y') + if (askchain(fcobj, (char *) 0, 0, out_ice_box, ck_ice_box, 0)) + return; + pline("That was all. Do you wish to put something in? [yn] "); + if (readchar() != 'y') + return; + } + /* call getobj: 0: allow cnt; #: allow all types; %: expect food */ + otmp = getobj("0#%", "put in"); + if (!otmp || !in_ice_box(otmp)) + flags.move = multi = 0; +} + +static struct monst * +bchit(ddx, ddy, range, sym) + int ddx, ddy, range; + char sym; +{ + struct monst *mtmp = (struct monst *) 0; + int bchx = u.ux, bchy = u.uy; + + if (sym) + Tmp_at(-1, sym);/* open call */ + while (range--) { + bchx += ddx; + bchy += ddy; + if ((mtmp = m_at(bchx, bchy)) != NULL) + break; + if (!ZAP_POS(levl[bchx][bchy].typ)) { + bchx -= ddx; + bchy -= ddy; + break; + } + if (sym) + Tmp_at(bchx, bchy); + } + if (sym) + Tmp_at(-1, -1); + return (mtmp); +} + +/* ARGSUSED */ +static void +use_whistle(obj) + struct obj *obj __attribute__((__unused__)); +{ + struct monst *mtmp = fmon; + pline("You produce a high whistling sound."); + while (mtmp) { + if (dist(mtmp->mx, mtmp->my) < u.ulevel * 20) { + if (mtmp->msleep) + mtmp->msleep = 0; + if (mtmp->mtame) + EDOG(mtmp)->whistletime = moves; + } + mtmp = mtmp->nmon; + } +} + +/* ARGSUSED */ +static void +use_magic_whistle(obj) + struct obj *obj __attribute__((__unused__)); +{ + struct monst *mtmp = fmon; + pline("You produce a strange whistling sound."); + while (mtmp) { + if (mtmp->mtame) + mnexto(mtmp); + mtmp = mtmp->nmon; + } +} + +static int dig_effort; /* effort expended on current pos */ +static uchar dig_level; +static coord dig_pos; +static boolean dig_down; + +static int +dig() +{ + struct rm *lev; + int dpx = dig_pos.x, dpy = dig_pos.y; + + /* perhaps a nymph stole his pick-axe while he was busy digging */ + /* or perhaps he teleported away */ + if (u.uswallow || !uwep || uwep->otyp != PICK_AXE || + dig_level != dlevel || + ((dig_down && (dpx != u.ux || dpy != u.uy)) || + (!dig_down && dist(dpx, dpy) > 2))) + return (0); + + dig_effort += 10 + abon() + uwep->spe + rn2(5); + if (dig_down) { + if (!xdnstair) { + pline("The floor here seems too hard to dig in."); + return (0); + } + if (dig_effort > 250) { + dighole(); + return (0); /* done with digging */ + } + if (dig_effort > 50) { + struct trap *ttmp = t_at(dpx, dpy); + + if (!ttmp) { + ttmp = maketrap(dpx, dpy, PIT); + ttmp->tseen = 1; + pline("You have dug a pit."); + u.utrap = rn1(4, 2); + u.utraptype = TT_PIT; + return (0); + } + } + } else if (dig_effort > 100) { + const char *digtxt; + struct obj *obj; + + lev = &levl[dpx][dpy]; + if ((obj = sobj_at(ENORMOUS_ROCK, dpx, dpy)) != NULL) { + fracture_rock(obj); + digtxt = "The rock falls apart."; + } else if (!lev->typ || lev->typ == SCORR) { + lev->typ = CORR; + digtxt = "You succeeded in cutting away some rock."; + } else if (lev->typ == HWALL || lev->typ == VWALL + || lev->typ == SDOOR) { + lev->typ = xdnstair ? DOOR : ROOM; + digtxt = "You just made an opening in the wall."; + } else + digtxt = "Now what exactly was it that you were digging in?"; + mnewsym(dpx, dpy); + prl(dpx, dpy); + pline(digtxt); /* after mnewsym & prl */ + return (0); + } else { + if (IS_WALL(levl[dpx][dpy].typ)) { + int rno = inroom(dpx, dpy); + + if (rno >= 0 && rooms[rno].rtype >= 8) { + pline("This wall seems too hard to dig into."); + return (0); + } + } + pline("You hit the rock with all your might."); + } + return (1); +} + +/* When will hole be finished? Very rough indication used by shopkeeper. */ +int +holetime() +{ + return ((occupation == dig) ? (250 - dig_effort) / 20 : -1); +} + +void +dighole() +{ + struct trap *ttmp = t_at(u.ux, u.uy); + + if (!xdnstair) { + pline("The floor here seems too hard to dig in."); + } else { + if (ttmp) + ttmp->ttyp = TRAPDOOR; + else + ttmp = maketrap(u.ux, u.uy, TRAPDOOR); + ttmp->tseen = 1; + pline("You've made a hole in the floor."); + if (!u.ustuck) { + if (inshop()) + shopdig(1); + pline("You fall through ..."); + if (u.utraptype == TT_PIT) { + u.utrap = 0; + u.utraptype = 0; + } + goto_level(dlevel + 1, FALSE); + } + } +} + +static int +use_pick_axe(obj) + struct obj *obj; +{ + char dirsyms[12]; + char *dsp = dirsyms, *sdp = sdir; + struct monst *mtmp; + struct rm *lev; + int rx, ry, res = 0; + + if (obj != uwep) { + if (uwep && uwep->cursed) { + /* Andreas Bormann - ihnp4!decvax!mcvax!unido!ab */ + pline("Since your weapon is welded to your hand,"); + pline("you cannot use that pick-axe."); + return (0); + } + pline("You now wield %s.", doname(obj)); + setuwep(obj); + res = 1; + } + while (*sdp) { + (void) movecmd(*sdp); /* sets u.dx and u.dy and u.dz */ + rx = u.ux + u.dx; + ry = u.uy + u.dy; + if (u.dz > 0 || (u.dz == 0 && isok(rx, ry) && + (IS_ROCK(levl[rx][ry].typ) + || sobj_at(ENORMOUS_ROCK, rx, ry)))) + *dsp++ = *sdp; + sdp++; + } + *dsp = 0; + pline("In what direction do you want to dig? [%s] ", dirsyms); + if (!getdir(0)) /* no txt */ + return (res); + if (u.uswallow && attack(u.ustuck)) /* return(1) */ + ; + else if (u.dz < 0) + pline("You cannot reach the ceiling."); + else if (u.dz == 0) { + if (Confusion) + confdir(); + rx = u.ux + u.dx; + ry = u.uy + u.dy; + if ((mtmp = m_at(rx, ry)) && attack(mtmp)) + return (1); + if (!isok(rx, ry)) { + pline("Clash!"); + return (1); + } + lev = &levl[rx][ry]; + if (lev->typ == DOOR) + pline("Your %s against the door.", + aobjnam(obj, "clang")); + else if (!IS_ROCK(lev->typ) + && !sobj_at(ENORMOUS_ROCK, rx, ry)) { + /* ACCESSIBLE or POOL */ + pline("You swing your %s through thin air.", + aobjnam(obj, (char *) 0)); + } else { + if (dig_pos.x != rx || dig_pos.y != ry + || dig_level != dlevel || dig_down) { + dig_down = FALSE; + dig_pos.x = rx; + dig_pos.y = ry; + dig_level = dlevel; + dig_effort = 0; + pline("You start digging."); + } else + pline("You continue digging."); + occupation = dig; + occtxt = "digging"; + } + } else if (Levitation) { + pline("You cannot reach the floor."); + } else { + if (dig_pos.x != u.ux || dig_pos.y != u.uy + || dig_level != dlevel || !dig_down) { + dig_down = TRUE; + dig_pos.x = u.ux; + dig_pos.y = u.uy; + dig_level = dlevel; + dig_effort = 0; + pline("You start digging in the floor."); + if (inshop()) + shopdig(0); + } else + pline("You continue digging in the floor."); + occupation = dig; + occtxt = "digging"; + } + return (1); +} diff --git a/hack/hack.bones.c b/hack/hack.bones.c new file mode 100644 index 0000000..0273508 --- /dev/null +++ b/hack/hack.bones.c @@ -0,0 +1,176 @@ +/* $NetBSD: hack.bones.c,v 1.5 2001/03/25 20:43:59 jsm Exp $ */ + +/* + * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica, + * Amsterdam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - 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. + * + * - Neither the name of the Stichting Centrum voor Wiskunde en + * Informatica, 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER + * 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. + */ + +/* + * Copyright (c) 1982 Jay Fenlason + * 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. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``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 +#ifndef lint +__RCSID("$NetBSD: hack.bones.c,v 1.5 2001/03/25 20:43:59 jsm Exp $"); +#endif /* not lint */ + +#include "hack.h" +#include "extern.h" +#include +#include + +char bones[] = "bones_xx"; + +/* save bones and possessions of a deceased adventurer */ +void +savebones() +{ + int fd; + struct obj *otmp; + struct trap *ttmp; + struct monst *mtmp; + + if (dlevel <= 0 || dlevel > MAXLEVEL) + return; + if (!rn2(1 + dlevel / 2)) + return; /* not so many ghosts on low levels */ + bones[6] = '0' + (dlevel / 10); + bones[7] = '0' + (dlevel % 10); + if ((fd = open(bones, O_RDONLY)) >= 0) { + (void) close(fd); + return; + } + /* drop everything; the corpse's possessions are usually cursed */ + otmp = invent; + while (otmp) { + otmp->ox = u.ux; + otmp->oy = u.uy; + otmp->age = 0; /* very long ago */ + otmp->owornmask = 0; + if (rn2(5)) + otmp->cursed = 1; + if (!otmp->nobj) { + otmp->nobj = fobj; + fobj = invent; + invent = 0; /* superfluous */ + break; + } + otmp = otmp->nobj; + } + if (!(mtmp = makemon(PM_GHOST, u.ux, u.uy))) + return; + mtmp->mx = u.ux; + mtmp->my = u.uy; + mtmp->msleep = 1; + (void) strcpy((char *) mtmp->mextra, plname); + mkgold(somegold() + d(dlevel, 30), u.ux, u.uy); + for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) { + mtmp->m_id = 0; + if (mtmp->mtame) { + mtmp->mtame = 0; + mtmp->mpeaceful = 0; + } + mtmp->mlstmv = 0; + if (mtmp->mdispl) + unpmon(mtmp); + } + for (ttmp = ftrap; ttmp; ttmp = ttmp->ntrap) + ttmp->tseen = 0; + for (otmp = fobj; otmp; otmp = otmp->nobj) { + otmp->o_id = 0; + /* otmp->o_cnt_id = 0; - superfluous */ + otmp->onamelth = 0; + otmp->known = 0; + otmp->invlet = 0; + if (otmp->olet == AMULET_SYM && !otmp->spe) { + otmp->spe = -1; /* no longer the actual amulet */ + otmp->cursed = 1; /* flag as gotten from a + * ghost */ + } + } + if ((fd = creat(bones, FMASK)) < 0) + return; + savelev(fd, dlevel); + (void) close(fd); +} + +int +getbones() +{ + int fd, x, y, ok; + + if (rn2(3)) + return (0); /* only once in three times do we find bones */ + bones[6] = '0' + dlevel / 10; + bones[7] = '0' + dlevel % 10; + if ((fd = open(bones, O_RDONLY)) < 0) + return (0); + if ((ok = uptodate(fd)) != 0) { + getlev(fd, 0, dlevel); + for (x = 0; x < COLNO; x++) + for (y = 0; y < ROWNO; y++) + levl[x][y].seen = levl[x][y].new = 0; + } + (void) close(fd); +#ifdef WIZARD + if (!wizard) /* duvel!frans: don't remove bones while + * debugging */ +#endif /* WiZARD */ + if (unlink(bones) < 0) { + pline("Cannot unlink %s .", bones); + return (0); + } + return (ok); +} diff --git a/hack/hack.c b/hack/hack.c new file mode 100644 index 0000000..06a0bc8 --- /dev/null +++ b/hack/hack.c @@ -0,0 +1,975 @@ +/* $NetBSD: hack.c,v 1.5 2001/03/25 20:43:59 jsm Exp $ */ + +/* + * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica, + * Amsterdam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - 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. + * + * - Neither the name of the Stichting Centrum voor Wiskunde en + * Informatica, 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER + * 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. + */ + +/* + * Copyright (c) 1982 Jay Fenlason + * 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. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``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 +#ifndef lint +__RCSID("$NetBSD: hack.c,v 1.5 2001/03/25 20:43:59 jsm Exp $"); +#endif /* not lint */ + +#include "hack.h" +#include "extern.h" + +/* + * called on movement: 1. when throwing ball+chain far away 2. when + * teleporting 3. when walking out of a lit room + */ +void +unsee() +{ + int x, y; + struct rm *lev; + + /* + if(u.udispl){ + u.udispl = 0; + newsym(u.udisx, u.udisy); + } + */ +#ifndef QUEST + if (seehx) { + seehx = 0; + } else +#endif /* QUEST */ + for (x = u.ux - 1; x < u.ux + 2; x++) + for (y = u.uy - 1; y < u.uy + 2; y++) { + if (!isok(x, y)) + continue; + lev = &levl[x][y]; + if (!lev->lit && lev->scrsym == '.') { + lev->scrsym = ' '; + lev->new = 1; + on_scr(x, y); + } + } +} + +/* + * called: in hack.eat.c: seeoff(0) - blind after eating rotten food in + * hack.mon.c: seeoff(0) - blinded by a yellow light in hack.mon.c: seeoff(1) + * - swallowed in hack.do.c: seeoff(0) - blind after drinking potion in + * hack.do.c: seeoff(1) - go up or down the stairs in hack.trap.c:seeoff(1) + * - fall through trapdoor + */ +void +seeoff(mode) + int mode; /* 1 to redo @, 0 to leave them *//* 1 means + * misc movement, 0 means blindness */ +{ + int x, y; + struct rm *lev; + + if (u.udispl && mode) { + u.udispl = 0; + levl[u.udisx][u.udisy].scrsym = news0(u.udisx, u.udisy); + } +#ifndef QUEST + if (seehx) { + seehx = 0; + } else +#endif /* QUEST */ + if (!mode) { + for (x = u.ux - 1; x < u.ux + 2; x++) + for (y = u.uy - 1; y < u.uy + 2; y++) { + if (!isok(x, y)) + continue; + lev = &levl[x][y]; + if (!lev->lit && lev->scrsym == '.') + lev->seen = 0; + } + } +} + +void +domove() +{ + xchar oldx, oldy; + struct monst *mtmp = NULL; + struct rm *tmpr, *ust; + struct trap *trap = NULL; + struct obj *otmp = NULL; + + u_wipe_engr(rnd(5)); + + if (inv_weight() > 0) { + pline("You collapse under your load."); + nomul(0); + return; + } + if (u.uswallow) { + u.dx = u.dy = 0; + u.ux = u.ustuck->mx; + u.uy = u.ustuck->my; + } else { + if (Confusion) { + do { + confdir(); + } while (!isok(u.ux + u.dx, u.uy + u.dy) || + IS_ROCK(levl[u.ux + u.dx][u.uy + u.dy].typ)); + } + if (!isok(u.ux + u.dx, u.uy + u.dy)) { + nomul(0); + return; + } + } + + ust = &levl[u.ux][u.uy]; + oldx = u.ux; + oldy = u.uy; + if (!u.uswallow && (trap = t_at(u.ux + u.dx, u.uy + u.dy)) && trap->tseen) + nomul(0); + if (u.ustuck && !u.uswallow && (u.ux + u.dx != u.ustuck->mx || + u.uy + u.dy != u.ustuck->my)) { + if (dist(u.ustuck->mx, u.ustuck->my) > 2) { + /* perhaps it fled (or was teleported or ... ) */ + u.ustuck = 0; + } else { + if (Blind) + pline("You cannot escape from it!"); + else + pline("You cannot escape from %s!", + monnam(u.ustuck)); + nomul(0); + return; + } + } + if (u.uswallow || (mtmp = m_at(u.ux + u.dx, u.uy + u.dy))) { + /* attack monster */ + + nomul(0); + gethungry(); + if (multi < 0) + return; /* we just fainted */ + + /* try to attack; note that it might evade */ + if (attack(u.uswallow ? u.ustuck : mtmp)) + return; + } + /* not attacking an animal, so we try to move */ + if (u.utrap) { + if (u.utraptype == TT_PIT) { + pline("You are still in a pit."); + u.utrap--; + } else { + pline("You are caught in a beartrap."); + if ((u.dx && u.dy) || !rn2(5)) + u.utrap--; + } + return; + } + tmpr = &levl[u.ux + u.dx][u.uy + u.dy]; + if (IS_ROCK(tmpr->typ) || + (u.dx && u.dy && (tmpr->typ == DOOR || ust->typ == DOOR))) { + flags.move = 0; + nomul(0); + return; + } + while ((otmp = sobj_at(ENORMOUS_ROCK, u.ux + u.dx, u.uy + u.dy)) != NULL){ + xchar rx = u.ux + 2 * u.dx, ry = u.uy + 2 * u.dy; + struct trap *ttmp; + nomul(0); + if (isok(rx, ry) && !IS_ROCK(levl[rx][ry].typ) && + (levl[rx][ry].typ != DOOR || !(u.dx && u.dy)) && + !sobj_at(ENORMOUS_ROCK, rx, ry)) { + if (m_at(rx, ry)) { + pline("You hear a monster behind the rock."); + pline("Perhaps that's why you cannot move it."); + goto cannot_push; + } + if ((ttmp = t_at(rx, ry)) != NULL) + switch (ttmp->ttyp) { + case PIT: + pline("You push the rock into a pit!"); + deltrap(ttmp); + delobj(otmp); + pline("It completely fills the pit!"); + continue; + case TELEP_TRAP: + pline("You push the rock and suddenly it disappears!"); + delobj(otmp); + continue; + } + if (levl[rx][ry].typ == POOL) { + levl[rx][ry].typ = ROOM; + mnewsym(rx, ry); + prl(rx, ry); + pline("You push the rock into the water."); + pline("Now you can cross the water!"); + delobj(otmp); + continue; + } + otmp->ox = rx; + otmp->oy = ry; + /* pobj(otmp); */ + if (cansee(rx, ry)) + atl(rx, ry, otmp->olet); + if (Invisible) + newsym(u.ux + u.dx, u.uy + u.dy); + + { + static long lastmovetime; + /* + * note: this var contains garbage initially + * and after a restore + */ + if (moves > lastmovetime + 2 || moves < lastmovetime) + pline("With great effort you move the enormous rock."); + lastmovetime = moves; + } + } else { + pline("You try to move the enormous rock, but in vain."); + cannot_push: + if ((!invent || inv_weight() + 90 <= 0) && + (!u.dx || !u.dy || (IS_ROCK(levl[u.ux][u.uy + u.dy].typ) + && IS_ROCK(levl[u.ux + u.dx][u.uy].typ)))) { + pline("However, you can squeeze yourself into a small opening."); + break; + } else + return; + } + } + if (u.dx && u.dy && IS_ROCK(levl[u.ux][u.uy + u.dy].typ) && + IS_ROCK(levl[u.ux + u.dx][u.uy].typ) && + invent && inv_weight() + 40 > 0) { + pline("You are carrying too much to get through."); + nomul(0); + return; + } + if (Punished && + DIST(u.ux + u.dx, u.uy + u.dy, uchain->ox, uchain->oy) > 2) { + if (carried(uball)) { + movobj(uchain, u.ux, u.uy); + goto nodrag; + } + if (DIST(u.ux + u.dx, u.uy + u.dy, uball->ox, uball->oy) < 3) { + /* leave ball, move chain under/over ball */ + movobj(uchain, uball->ox, uball->oy); + goto nodrag; + } + if (inv_weight() + (int) uball->owt / 2 > 0) { + pline("You cannot %sdrag the heavy iron ball.", + invent ? "carry all that and also " : ""); + nomul(0); + return; + } + movobj(uball, uchain->ox, uchain->oy); + unpobj(uball); /* BAH %% */ + uchain->ox = u.ux; + uchain->oy = u.uy; + nomul(-2); + nomovemsg = ""; +nodrag: ; + } + u.ux += u.dx; + u.uy += u.dy; + if (flags.run) { + if (tmpr->typ == DOOR || + (xupstair == u.ux && yupstair == u.uy) || + (xdnstair == u.ux && ydnstair == u.uy)) + nomul(0); + } + if (tmpr->typ == POOL && !Levitation) + drown(); /* not necessarily fatal */ + + /* + if(u.udispl) { + u.udispl = 0; + newsym(oldx,oldy); + } + */ + if (!Blind) { +#ifdef QUEST + setsee(); +#else + if (ust->lit) { + if (tmpr->lit) { + if (tmpr->typ == DOOR) + prl1(u.ux + u.dx, u.uy + u.dy); + else if (ust->typ == DOOR) + nose1(oldx - u.dx, oldy - u.dy); + } else { + unsee(); + prl1(u.ux + u.dx, u.uy + u.dy); + } + } else { + if (tmpr->lit) + setsee(); + else { + prl1(u.ux + u.dx, u.uy + u.dy); + if (tmpr->typ == DOOR) { + if (u.dy) { + prl(u.ux - 1, u.uy); + prl(u.ux + 1, u.uy); + } else { + prl(u.ux, u.uy - 1); + prl(u.ux, u.uy + 1); + } + } + } + nose1(oldx - u.dx, oldy - u.dy); + } +#endif /* QUEST */ + } else { + pru(); + } + if (!flags.nopick) + pickup(1); + if (trap) + dotrap(trap); /* fall into pit, arrow trap, etc. */ + (void) inshop(); + if (!Blind) + read_engr_at(u.ux, u.uy); +} + +void +movobj(obj, ox, oy) + struct obj *obj; + int ox, oy; +{ + /* Some dirty programming to get display right */ + freeobj(obj); + unpobj(obj); + obj->nobj = fobj; + fobj = obj; + obj->ox = ox; + obj->oy = oy; +} + +int +dopickup() +{ + if (!g_at(u.ux, u.uy) && !o_at(u.ux, u.uy)) { + pline("There is nothing here to pick up."); + return (0); + } + if (Levitation) { + pline("You cannot reach the floor."); + return (1); + } + pickup(0); + return (1); +} + +void +pickup(int all) +{ + struct gold *gold; + struct obj *obj, *obj2; + int wt; + + if (Levitation) + return; + while ((gold = g_at(u.ux, u.uy)) != NULL) { + pline("%ld gold piece%s.", gold->amount, plur(gold->amount)); + u.ugold += gold->amount; + flags.botl = 1; + freegold(gold); + if (flags.run) + nomul(0); + if (Invisible) + newsym(u.ux, u.uy); + } + + /* check for more than one object */ + if (!all) { + int ct = 0; + + for (obj = fobj; obj; obj = obj->nobj) + if (obj->ox == u.ux && obj->oy == u.uy) + if (!Punished || obj != uchain) + ct++; + if (ct < 2) + all++; + else + pline("There are several objects here."); + } + for (obj = fobj; obj; obj = obj2) { + obj2 = obj->nobj; /* perhaps obj will be picked up */ + if (obj->ox == u.ux && obj->oy == u.uy) { + if (flags.run) + nomul(0); + + /* do not pick up uchain */ + if (Punished && obj == uchain) + continue; + + if (!all) { + char c; + + pline("Pick up %s ? [ynaq]", doname(obj)); + while (!strchr("ynaq ", (c = readchar()))) + bell(); + if (c == 'q') + return; + if (c == 'n') + continue; + if (c == 'a') + all = 1; + } + if (obj->otyp == DEAD_COCKATRICE && !uarmg) { + pline("Touching the dead cockatrice is a fatal mistake."); + pline("You turn to stone."); + killer = "cockatrice cadaver"; + done("died"); + } + if (obj->otyp == SCR_SCARE_MONSTER) { + if (!obj->spe) + obj->spe = 1; + else { + /* + * Note: perhaps the 1st pickup + * failed: you cannot carry anymore, + * and so we never dropped it - let's + * assume that treading on it twice + * also destroys the scroll + */ + pline("The scroll turns to dust as you pick it up."); + delobj(obj); + continue; + } + } + wt = inv_weight() + obj->owt; + if (wt > 0) { + if (obj->quan > 1) { + /* see how many we can lift */ + int savequan = obj->quan; + int iw = inv_weight(); + int qq; + for (qq = 1; qq < savequan; qq++) { + obj->quan = qq; + if (iw + weight(obj) > 0) + break; + } + obj->quan = savequan; + qq--; + /* we can carry qq of them */ + if (!qq) + goto too_heavy; + pline("You can only carry %s of the %s lying here.", + (qq == 1) ? "one" : "some", + doname(obj)); + (void) splitobj(obj, qq); + /* + * note: obj2 is set already, so + * we'll never encounter the other + * half; if it should be otherwise + * then write obj2 = + * splitobj(obj,qq); + */ + goto lift_some; + } + too_heavy: + pline("There %s %s here, but %s.", + (obj->quan == 1) ? "is" : "are", + doname(obj), + !invent ? "it is too heavy for you to lift" + : "you cannot carry anymore"); + break; + } + lift_some: + if (inv_cnt() >= 52) { + pline("Your knapsack cannot accomodate anymore items."); + break; + } + if (wt > -5) + pline("You have a little trouble lifting"); + freeobj(obj); + if (Invisible) + newsym(u.ux, u.uy); + addtobill(obj); /* sets obj->unpaid if necessary */ + { + int pickquan = obj->quan; + int mergquan; + if (!Blind) + obj->dknown = 1; /* this is done by + * prinv(), but addinv() + * needs it already for + * merging */ + obj = addinv(obj); /* might merge it with + * other objects */ + mergquan = obj->quan; + obj->quan = pickquan; /* to fool prinv() */ + prinv(obj); + obj->quan = mergquan; + } + } + } +} + +/* stop running if we see something interesting */ +/* turn around a corner if that is the only way we can proceed */ +/* do not turn left or right twice */ +void +lookaround() +{ + int x, y, i, x0 = 0, y0 = 0, m0 = 0, i0 = 9; + int corrct = 0, noturn = 0; + struct monst *mtmp; + if (Blind || flags.run == 0) + return; + if (flags.run == 1 && levl[u.ux][u.uy].typ == ROOM) + return; +#ifdef QUEST + if (u.ux0 == u.ux + u.dx && u.uy0 == u.uy + u.dy) + goto stop; +#endif /* QUEST */ + for (x = u.ux - 1; x <= u.ux + 1; x++) + for (y = u.uy - 1; y <= u.uy + 1; y++) { + if (x == u.ux && y == u.uy) + continue; + if (!levl[x][y].typ) + continue; + if ((mtmp = m_at(x, y)) && !mtmp->mimic && + (!mtmp->minvis || See_invisible)) { + if (!mtmp->mtame || (x == u.ux + u.dx && y == u.uy + u.dy)) + goto stop; + } else + mtmp = 0; /* invisible M cannot + * influence us */ + if (x == u.ux - u.dx && y == u.uy - u.dy) + continue; + switch (levl[x][y].scrsym) { + case '|': + case '-': + case '.': + case ' ': + break; + case '+': + if (x != u.ux && y != u.uy) + break; + if (flags.run != 1) + goto stop; + /* fall into next case */ + case CORR_SYM: + corr: + if (flags.run == 1 || flags.run == 3) { + i = DIST(x, y, u.ux + u.dx, u.uy + u.dy); + if (i > 2) + break; + if (corrct == 1 && DIST(x, y, x0, y0) != 1) + noturn = 1; + if (i < i0) { + i0 = i; + x0 = x; + y0 = y; + m0 = mtmp ? 1 : 0; + } + } + corrct++; + break; + case '^': + if (flags.run == 1) + goto corr; /* if you must */ + if (x == u.ux + u.dx && y == u.uy + u.dy) + goto stop; + break; + default: /* e.g. objects or trap or stairs */ + if (flags.run == 1) + goto corr; + if (mtmp) + break; /* d */ + stop: + nomul(0); + return; + } + } +#ifdef QUEST + if (corrct > 0 && (flags.run == 4 || flags.run == 5)) + goto stop; +#endif /* QUEST */ + if (corrct > 1 && flags.run == 2) + goto stop; + if ((flags.run == 1 || flags.run == 3) && !noturn && !m0 && i0 && + (corrct == 1 || (corrct == 2 && i0 == 1))) { + /* make sure that we do not turn too far */ + if (i0 == 2) { + if (u.dx == y0 - u.uy && u.dy == u.ux - x0) + i = 2; /* straight turn right */ + else + i = -2; /* straight turn left */ + } else if (u.dx && u.dy) { + if ((u.dx == u.dy && y0 == u.uy) || + (u.dx != u.dy && y0 != u.uy)) + i = -1; /* half turn left */ + else + i = 1; /* half turn right */ + } else { + if ((x0 - u.ux == y0 - u.uy && !u.dy) || + (x0 - u.ux != y0 - u.uy && u.dy)) + i = 1; /* half turn right */ + else + i = -1; /* half turn left */ + } + i += u.last_str_turn; + if (i <= 2 && i >= -2) { + u.last_str_turn = i; + u.dx = x0 - u.ux, u.dy = y0 - u.uy; + } + } +} + +/* something like lookaround, but we are not running */ +/* react only to monsters that might hit us */ +int +monster_nearby() +{ + int x, y; + struct monst *mtmp; + if (!Blind) + for (x = u.ux - 1; x <= u.ux + 1; x++) + for (y = u.uy - 1; y <= u.uy + 1; y++) { + if (x == u.ux && y == u.uy) + continue; + if ((mtmp = m_at(x, y)) && !mtmp->mimic && !mtmp->mtame && + !mtmp->mpeaceful && !strchr("Ea", mtmp->data->mlet) && + !mtmp->mfroz && !mtmp->msleep && /* aplvax!jcn */ + (!mtmp->minvis || See_invisible)) + return (1); + } + return (0); +} + +#ifdef QUEST +int +cansee(x, y) + xchar x, y; +{ + int dx, dy, adx, ady, sdx, sdy, dmax, d; + if (Blind) + return (0); + if (!isok(x, y)) + return (0); + d = dist(x, y); + if (d < 3) + return (1); + if (d > u.uhorizon * u.uhorizon) + return (0); + if (!levl[x][y].lit) + return (0); + dx = x - u.ux; + adx = abs(dx); + sdx = sgn(dx); + dy = y - u.uy; + ady = abs(dy); + sdy = sgn(dy); + if (dx == 0 || dy == 0 || adx == ady) { + dmax = (dx == 0) ? ady : adx; + for (d = 1; d <= dmax; d++) + if (!rroom(sdx * d, sdy * d)) + return (0); + return (1); + } else if (ady > adx) { + for (d = 1; d <= ady; d++) { + if (!rroom(sdx * ((d * adx) / ady), sdy * d) || + !rroom(sdx * ((d * adx - 1) / ady + 1), sdy * d)) + return (0); + } + return (1); + } else { + for (d = 1; d <= adx; d++) { + if (!rroom(sdx * d, sdy * ((d * ady) / adx)) || + !rroom(sdx * d, sdy * ((d * ady - 1) / adx + 1))) + return (0); + } + return (1); + } +} + +int +rroom(x, y) + int x, y; +{ + return (IS_ROOM(levl[u.ux + x][u.uy + y].typ)); +} + +#else + +int +cansee(x, y) + xchar x, y; +{ + if (Blind || u.uswallow) + return (0); + if (dist(x, y) < 3) + return (1); + if (levl[x][y].lit && seelx <= x && x <= seehx && seely <= y && + y <= seehy) + return (1); + return (0); +} +#endif /* QUEST */ + +int +sgn(a) + int a; +{ + return ((a > 0) ? 1 : (a == 0) ? 0 : -1); +} + +#ifdef QUEST +void +setsee() +{ + int x, y; + + if (Blind) { + pru(); + return; + } + for (y = u.uy - u.uhorizon; y <= u.uy + u.uhorizon; y++) + for (x = u.ux - u.uhorizon; x <= u.ux + u.uhorizon; x++) { + if (cansee(x, y)) + prl(x, y); + } +} + +#else + +void +setsee() +{ + int x, y; + + if (Blind) { + pru(); + return; + } + if (!levl[u.ux][u.uy].lit) { + seelx = u.ux - 1; + seehx = u.ux + 1; + seely = u.uy - 1; + seehy = u.uy + 1; + } else { + for (seelx = u.ux; levl[seelx - 1][u.uy].lit; seelx--); + for (seehx = u.ux; levl[seehx + 1][u.uy].lit; seehx++); + for (seely = u.uy; levl[u.ux][seely - 1].lit; seely--); + for (seehy = u.uy; levl[u.ux][seehy + 1].lit; seehy++); + } + for (y = seely; y <= seehy; y++) + for (x = seelx; x <= seehx; x++) { + prl(x, y); + } + if (!levl[u.ux][u.uy].lit) + seehx = 0; /* seems necessary elsewhere */ + else { + if (seely == u.uy) + for (x = u.ux - 1; x <= u.ux + 1; x++) + prl(x, seely - 1); + if (seehy == u.uy) + for (x = u.ux - 1; x <= u.ux + 1; x++) + prl(x, seehy + 1); + if (seelx == u.ux) + for (y = u.uy - 1; y <= u.uy + 1; y++) + prl(seelx - 1, y); + if (seehx == u.ux) + for (y = u.uy - 1; y <= u.uy + 1; y++) + prl(seehx + 1, y); + } +} +#endif /* QUEST */ + +void +nomul(nval) + int nval; +{ + if (multi < 0) + return; + multi = nval; + flags.mv = flags.run = 0; +} + +int +abon() +{ + if (u.ustr == 3) + return (-3); + else if (u.ustr < 6) + return (-2); + else if (u.ustr < 8) + return (-1); + else if (u.ustr < 17) + return (0); + else if (u.ustr < 69) + return (1); /* up to 18/50 */ + else if (u.ustr < 118) + return (2); + else + return (3); +} + +int +dbon() +{ + if (u.ustr < 6) + return (-1); + else if (u.ustr < 16) + return (0); + else if (u.ustr < 18) + return (1); + else if (u.ustr == 18) + return (2); /* up to 18 */ + else if (u.ustr < 94) + return (3); /* up to 18/75 */ + else if (u.ustr < 109) + return (4); /* up to 18/90 */ + else if (u.ustr < 118) + return (5); /* up to 18/99 */ + else + return (6); +} + +void +losestr(num) /* may kill you; cause may be poison or */ + int num; /* monster like 'A' */ +{ + u.ustr -= num; + while (u.ustr < 3) { + u.ustr++; + u.uhp -= 6; + u.uhpmax -= 6; + } + flags.botl = 1; +} + +void +losehp(n, knam) + int n; + const char *knam; +{ + u.uhp -= n; + if (u.uhp > u.uhpmax) + u.uhpmax = u.uhp; /* perhaps n was negative */ + flags.botl = 1; + if (u.uhp < 1) { + killer = knam; /* the thing that killed you */ + done("died"); + } +} + +void +losehp_m(n, mtmp) + int n; + struct monst *mtmp; +{ + u.uhp -= n; + flags.botl = 1; + if (u.uhp < 1) + done_in_by(mtmp); +} + +void +losexp() +{ /* hit by V or W */ + int num; + + if (u.ulevel > 1) + pline("Goodbye level %u.", u.ulevel--); + else + u.uhp = -1; + num = rnd(10); + u.uhp -= num; + u.uhpmax -= num; + u.uexp = newuexp(); + flags.botl = 1; +} + +int +inv_weight() +{ + struct obj *otmp = invent; + int wt = (u.ugold + 500) / 1000; + int carrcap; + if (Levitation) /* pugh@cornell */ + carrcap = MAX_CARR_CAP; + else { + carrcap = 5 * (((u.ustr > 18) ? 20 : u.ustr) + u.ulevel); + if (carrcap > MAX_CARR_CAP) + carrcap = MAX_CARR_CAP; + if (Wounded_legs & LEFT_SIDE) + carrcap -= 10; + if (Wounded_legs & RIGHT_SIDE) + carrcap -= 10; + } + while (otmp) { + wt += otmp->owt; + otmp = otmp->nobj; + } + return (wt - carrcap); +} + +int +inv_cnt() +{ + struct obj *otmp = invent; + int ct = 0; + while (otmp) { + ct++; + otmp = otmp->nobj; + } + return (ct); +} + +long +newuexp() +{ + return (10 * (1L << (u.ulevel - 1))); +} diff --git a/hack/hack.cmd.c b/hack/hack.cmd.c new file mode 100644 index 0000000..5329c1e --- /dev/null +++ b/hack/hack.cmd.c @@ -0,0 +1,382 @@ +/* $NetBSD: hack.cmd.c,v 1.6 2001/03/25 20:43:59 jsm Exp $ */ + +/* + * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica, + * Amsterdam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - 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. + * + * - Neither the name of the Stichting Centrum voor Wiskunde en + * Informatica, 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER + * 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. + */ + +/* + * Copyright (c) 1982 Jay Fenlason + * 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. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``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 +#ifndef lint +__RCSID("$NetBSD: hack.cmd.c,v 1.6 2001/03/25 20:43:59 jsm Exp $"); +#endif /* not lint */ + +#include "hack.h" +#include "extern.h" +#include "def.func_tab.h" + +const struct func_tab cmdlist[] = { + { '\020', doredotopl }, + { '\022', doredraw }, + { '\024', dotele }, +#ifdef SUSPEND + { '\032', dosuspend }, +#endif /* SUSPEND */ + { 'a', doapply }, + /* 'A' : UNUSED */ + /* 'b', 'B' : go sw */ + { 'c', ddocall }, + { 'C', do_mname }, + { 'd', dodrop }, + { 'D', doddrop }, + { 'e', doeat }, + { 'E', doengrave }, + /* 'f', 'F' : multiple go (might become 'fight') */ + /* 'g', 'G' : UNUSED */ + /* 'h', 'H' : go west */ + { 'I', dotypeinv }, /* Robert Viduya */ + { 'i', ddoinv }, + /* 'j', 'J', 'k', 'K', 'l', 'L', 'm', 'M', 'n', 'N' : move commands */ + /* 'o', doopen, */ + { 'O', doset }, + { 'p', dopay }, + { 'P', dowearring }, + { 'q', dodrink }, + { 'Q', dodone }, + { 'r', doread }, + { 'R', doremring }, + { 's', dosearch }, + { 'S', dosave }, + { 't', dothrow }, + { 'T', doremarm }, + /* 'u', 'U' : go ne */ + { 'v', doversion }, + /* 'V' : UNUSED */ + { 'w', dowield }, + { 'W', doweararm }, + /* 'x', 'X' : UNUSED */ + /* 'y', 'Y' : go nw */ + { 'z', dozap }, + /* 'Z' : UNUSED */ + { '<', doup }, + { '>', dodown }, + { '/', dowhatis }, + { '?', dohelp }, +#ifdef SHELL + { '!', dosh }, +#endif /* SHELL */ + { '.', donull }, + { ' ', donull }, + { ',', dopickup }, + { ':', dolook }, + { '^', doidtrap }, + { '\\', dodiscovered }, /* Robert Viduya */ + { WEAPON_SYM, doprwep }, + { ARMOR_SYM, doprarm }, + { RING_SYM, doprring }, + { '$', doprgold }, + { '#', doextcmd }, + { 0, 0 } +}; + +const struct ext_func_tab extcmdlist[] = { + { "dip", dodip }, + { "pray", dopray }, + { (char *) 0, donull } +}; + +void +rhack(cmd) + const char *cmd; +{ + const struct func_tab *tlist = cmdlist; + boolean firsttime = FALSE; + int res; + + if (!cmd) { + firsttime = TRUE; + flags.nopick = 0; + cmd = parse(); + } + if (!*cmd || (*cmd & 0377) == 0377 || + (flags.no_rest_on_space && *cmd == ' ')) { + bell(); + flags.move = 0; + return; /* probably we just had an interrupt */ + } + if (movecmd(*cmd)) { +walk: + if (multi) + flags.mv = 1; + domove(); + return; + } + if (movecmd(lowc(*cmd))) { + flags.run = 1; +rush: + if (firsttime) { + if (!multi) + multi = COLNO; + u.last_str_turn = 0; + } + flags.mv = 1; +#ifdef QUEST + if (flags.run >= 4) + finddir(); + if (firsttime) { + u.ux0 = u.ux + u.dx; + u.uy0 = u.uy + u.dy; + } +#endif /* QUEST */ + domove(); + return; + } + if ((*cmd == 'f' && movecmd(cmd[1])) || movecmd(unctrl(*cmd))) { + flags.run = 2; + goto rush; + } + if (*cmd == 'F' && movecmd(lowc(cmd[1]))) { + flags.run = 3; + goto rush; + } + if (*cmd == 'm' && movecmd(cmd[1])) { + flags.run = 0; + flags.nopick = 1; + goto walk; + } + if (*cmd == 'M' && movecmd(lowc(cmd[1]))) { + flags.run = 1; + flags.nopick = 1; + goto rush; + } +#ifdef QUEST + if (*cmd == cmd[1] && (*cmd == 'f' || *cmd == 'F')) { + flags.run = 4; + if (*cmd == 'F') + flags.run += 2; + if (cmd[2] == '-') + flags.run += 1; + goto rush; + } +#endif /* QUEST */ + while (tlist->f_char) { + if (*cmd == tlist->f_char) { + res = (*(tlist->f_funct)) (); + if (!res) { + flags.move = 0; + multi = 0; + } + return; + } + tlist++; + } + { + char expcmd[10]; + char *cp = expcmd; + while (*cmd && cp - expcmd < (int)sizeof(expcmd) - 2) { + if (*cmd >= 040 && *cmd < 0177) + *cp++ = *cmd++; + else { + *cp++ = '^'; + *cp++ = *cmd++ ^ 0100; + } + } + *cp++ = 0; + pline("Unknown command '%s'.", expcmd); + } + multi = flags.move = 0; +} + +int +doextcmd() +{ /* here after # - now read a full-word + * command */ + char buf[BUFSZ]; + const struct ext_func_tab *efp = extcmdlist; + + pline("# "); + getlin(buf); + clrlin(); + if (buf[0] == '\033') + return (0); + while (efp->ef_txt) { + if (!strcmp(efp->ef_txt, buf)) + return ((*(efp->ef_funct)) ()); + efp++; + } + pline("%s: unknown command.", buf); + return (0); +} + +char +lowc(sym) + char sym; +{ + return ((sym >= 'A' && sym <= 'Z') ? sym + 'a' - 'A' : sym); +} + +char +unctrl(sym) + char sym; +{ + return ((sym >= ('A' & 037) && sym <= ('Z' & 037)) ? sym + 0140 : sym); +} + +/* 'rogue'-like direction commands */ +char sdir[] = "hykulnjb><"; +schar xdir[10] = {-1, -1, 0, 1, 1, 1, 0, -1, 0, 0}; +schar ydir[10] = {0, -1, -1, -1, 0, 1, 1, 1, 0, 0}; +schar zdir[10] = {0, 0, 0, 0, 0, 0, 0, 0, 1, -1}; + +int +movecmd(sym) /* also sets u.dz, but returns false for <> */ + char sym; +{ + char *dp; + + u.dz = 0; + if (!(dp = strchr(sdir, sym))) + return (0); + u.dx = xdir[dp - sdir]; + u.dy = ydir[dp - sdir]; + u.dz = zdir[dp - sdir]; + return (!u.dz); +} + +int +getdir(s) + boolean s; +{ + char dirsym; + + if (s) + pline("In what direction?"); + dirsym = readchar(); + if (!movecmd(dirsym) && !u.dz) { + if (!strchr(quitchars, dirsym)) + pline("What a strange direction!"); + return (0); + } + if (Confusion && !u.dz) + confdir(); + return (1); +} + +void +confdir() +{ + int x = rn2(8); + u.dx = xdir[x]; + u.dy = ydir[x]; +} + +#ifdef QUEST +int +finddir() +{ + int i, ui = u.di; + for (i = 0; i <= 8; i++) { + if (flags.run & 1) + ui++; + else + ui += 7; + ui %= 8; + if (i == 8) { + pline("Not near a wall."); + flags.move = multi = 0; + return (0); + } + if (!isroom(u.ux + xdir[ui], u.uy + ydir[ui])) + break; + } + for (i = 0; i <= 8; i++) { + if (flags.run & 1) + ui += 7; + else + ui++; + ui %= 8; + if (i == 8) { + pline("Not near a room."); + flags.move = multi = 0; + return (0); + } + if (isroom(u.ux + xdir[ui], u.uy + ydir[ui])) + break; + } + u.di = ui; + u.dx = xdir[ui]; + u.dy = ydir[ui]; + return 0; +} + +int +isroom(x, y) + int x, y; +{ /* what about POOL? */ + return (isok(x, y) && (levl[x][y].typ == ROOM || + (levl[x][y].typ >= LDOOR && flags.run >= 6))); +} +#endif /* QUEST */ + +int +isok(x, y) + int x, y; +{ + /* x corresponds to curx, so x==1 is the first column. Ach. %% */ + return (x >= 1 && x <= COLNO - 1 && y >= 0 && y <= ROWNO - 1); +} diff --git a/hack/hack.do.c b/hack/hack.do.c new file mode 100644 index 0000000..907e6de --- /dev/null +++ b/hack/hack.do.c @@ -0,0 +1,586 @@ +/* $NetBSD: hack.do.c,v 1.5 2001/03/25 20:43:59 jsm Exp $ */ + +/* + * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica, + * Amsterdam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - 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. + * + * - Neither the name of the Stichting Centrum voor Wiskunde en + * Informatica, 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER + * 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. + */ + +/* + * Copyright (c) 1982 Jay Fenlason + * 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. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``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 +#ifndef lint +__RCSID("$NetBSD: hack.do.c,v 1.5 2001/03/25 20:43:59 jsm Exp $"); +#endif /* not lint */ + +/* Contains code for 'd', 'D' (drop), '>', '<' (up, down) and 't' (throw) */ + +#include "hack.h" +#include "extern.h" +#include +#include +#include + + +static int drop __P((struct obj *)); + +int +dodrop() +{ + return (drop(getobj("0$#", "drop"))); +} + +static int +drop(obj) + struct obj *obj; +{ + if (!obj) + return (0); + if (obj->olet == '$') { /* pseudo object */ + long amount = OGOLD(obj); + + if (amount == 0) + pline("You didn't drop any gold pieces."); + else { + mkgold(amount, u.ux, u.uy); + pline("You dropped %ld gold piece%s.", + amount, plur(amount)); + if (Invisible) + newsym(u.ux, u.uy); + } + free((char *) obj); + return (1); + } + if (obj->owornmask & (W_ARMOR | W_RING)) { + pline("You cannot drop something you are wearing."); + return (0); + } + if (obj == uwep) { + if (uwep->cursed) { + pline("Your weapon is welded to your hand!"); + return (0); + } + setuwep((struct obj *) 0); + } + pline("You dropped %s.", doname(obj)); + dropx(obj); + return (1); +} + +/* Called in several places - should not produce texts */ +void +dropx(obj) + struct obj *obj; +{ + freeinv(obj); + dropy(obj); +} + +void +dropy(obj) + struct obj *obj; +{ + if (obj->otyp == CRYSKNIFE) + obj->otyp = WORM_TOOTH; + obj->ox = u.ux; + obj->oy = u.uy; + obj->nobj = fobj; + fobj = obj; + if (Invisible) + newsym(u.ux, u.uy); + subfrombill(obj); + stackobj(obj); +} + +/* drop several things */ +int +doddrop() +{ + return (ggetobj("drop", drop, 0)); +} + +int +dodown() +{ + if (u.ux != xdnstair || u.uy != ydnstair) { + pline("You can't go down here."); + return (0); + } + if (u.ustuck) { + pline("You are being held, and cannot go down."); + return (1); + } + if (Levitation) { + pline("You're floating high above the stairs."); + return (0); + } + goto_level(dlevel + 1, TRUE); + return (1); +} + +int +doup() +{ + if (u.ux != xupstair || u.uy != yupstair) { + pline("You can't go up here."); + return (0); + } + if (u.ustuck) { + pline("You are being held, and cannot go up."); + return (1); + } + if (!Levitation && inv_weight() + 5 > 0) { + pline("Your load is too heavy to climb the stairs."); + return (1); + } + goto_level(dlevel - 1, TRUE); + return (1); +} + +void +goto_level(newlevel, at_stairs) + int newlevel; + boolean at_stairs; +{ + int fd; + boolean up = (newlevel < dlevel); + + if (newlevel <= 0) + done("escaped");/* in fact < 0 is impossible */ + if (newlevel > MAXLEVEL) + newlevel = MAXLEVEL; /* strange ... */ + if (newlevel == dlevel) + return; /* this can happen */ + + glo(dlevel); + fd = creat(lock, FMASK); + if (fd < 0) { + /* + * This is not quite impossible: e.g., we may have + * exceeded our quota. If that is the case then we + * cannot leave this level, and cannot save either. + * Another possibility is that the directory was not + * writable. + */ + pline("A mysterious force prevents you from going %s.", + up ? "up" : "down"); + return; + } + if (Punished) + unplacebc(); + u.utrap = 0; /* needed in level_tele */ + u.ustuck = 0; /* idem */ + keepdogs(); + seeoff(1); + if (u.uswallow) /* idem */ + u.uswldtim = u.uswallow = 0; + flags.nscrinh = 1; + u.ux = FAR; /* hack */ + (void) inshop(); /* probably was a trapdoor */ + + savelev(fd, dlevel); + (void) close(fd); + + dlevel = newlevel; + if (maxdlevel < dlevel) + maxdlevel = dlevel; + glo(dlevel); + + if (!level_exists[dlevel]) + mklev(); + else { + if ((fd = open(lock, O_RDONLY)) < 0) { + pline("Cannot open %s .", lock); + pline("Probably someone removed it."); + done("tricked"); + } + getlev(fd, hackpid, dlevel); + (void) close(fd); + } + + if (at_stairs) { + if (up) { + u.ux = xdnstair; + u.uy = ydnstair; + if (!u.ux) { /* entering a maze from below? */ + u.ux = xupstair; /* this will confuse the + * player! */ + u.uy = yupstair; + } + if (Punished && !Levitation) { + pline("With great effort you climb the stairs."); + placebc(1); + } + } else { + u.ux = xupstair; + u.uy = yupstair; + if (inv_weight() + 5 > 0 || Punished) { + pline("You fall down the stairs."); /* %% */ + losehp(rnd(3), "fall"); + if (Punished) { + if (uwep != uball && rn2(3)) { + pline("... and are hit by the iron ball."); + losehp(rnd(20), "iron ball"); + } + placebc(1); + } + selftouch("Falling, you"); + } + } + { + struct monst *mtmp = m_at(u.ux, u.uy); + if (mtmp) + mnexto(mtmp); + } + } else { /* trapdoor or level_tele */ + do { + u.ux = rnd(COLNO - 1); + u.uy = rn2(ROWNO); + } while (levl[u.ux][u.uy].typ != ROOM || + m_at(u.ux, u.uy)); + if (Punished) { + if (uwep != uball && !up /* %% */ && rn2(5)) { + pline("The iron ball falls on your head."); + losehp(rnd(25), "iron ball"); + } + placebc(1); + } + selftouch("Falling, you"); + } + (void) inshop(); + initrack(); + + losedogs(); + { + struct monst *mtmp; + if ((mtmp = m_at(u.ux, u.uy)) != NULL) + mnexto(mtmp); /* riv05!a3 */ + } + flags.nscrinh = 0; + setsee(); + seeobjs(); /* make old cadavers disappear - riv05!a3 */ + docrt(); + pickup(1); + read_engr_at(u.ux, u.uy); +} + +int +donull() +{ + return (1); /* Do nothing, but let other things happen */ +} + +int +dopray() +{ + nomovemsg = "You finished your prayer."; + nomul(-3); + return (1); +} + +int +dothrow() +{ + struct obj *obj; + struct monst *mon; + int tmp; + + obj = getobj("#)", "throw"); /* it is also possible to throw food */ + /* (or jewels, or iron balls ... ) */ + if (!obj || !getdir(1)) /* ask "in what direction?" */ + return (0); + if (obj->owornmask & (W_ARMOR | W_RING)) { + pline("You can't throw something you are wearing."); + return (0); + } + u_wipe_engr(2); + + if (obj == uwep) { + if (obj->cursed) { + pline("Your weapon is welded to your hand."); + return (1); + } + if (obj->quan > 1) + setuwep(splitobj(obj, 1)); + else + setuwep((struct obj *) 0); + } else if (obj->quan > 1) + (void) splitobj(obj, 1); + freeinv(obj); + if (u.uswallow) { + mon = u.ustuck; + bhitpos.x = mon->mx; + bhitpos.y = mon->my; + } else if (u.dz) { + if (u.dz < 0) { + pline("%s hits the ceiling, then falls back on top of your head.", + Doname(obj)); /* note: obj->quan == 1 */ + if (obj->olet == POTION_SYM) + potionhit(&youmonst, obj); + else { + if (uarmh) + pline("Fortunately, you are wearing a helmet!"); + losehp(uarmh ? 1 : rnd((int) (obj->owt)), "falling object"); + dropy(obj); + } + } else { + pline("%s hits the floor.", Doname(obj)); + if (obj->otyp == EXPENSIVE_CAMERA) { + pline("It is shattered in a thousand pieces!"); + obfree(obj, Null(obj)); + } else if (obj->otyp == EGG) { + pline("\"Splash!\""); + obfree(obj, Null(obj)); + } else if (obj->olet == POTION_SYM) { + pline("The flask breaks, and you smell a peculiar odor ..."); + potionbreathe(obj); + obfree(obj, Null(obj)); + } else { + dropy(obj); + } + } + return (1); + } else if (obj->otyp == BOOMERANG) { + mon = boomhit(u.dx, u.dy); + if (mon == &youmonst) { /* the thing was caught */ + (void) addinv(obj); + return (1); + } + } else { + if (obj->otyp == PICK_AXE && shkcatch(obj)) + return (1); + + mon = bhit(u.dx, u.dy, (obj->otyp == ICE_BOX) ? 1 : + (!Punished || obj != uball) ? 8 : !u.ustuck ? 5 : 1, + obj->olet, + (void (*) __P((struct monst *, struct obj *))) 0, + (int (*) __P((struct obj *, struct obj *))) 0, obj); + } + if (mon) { + /* awake monster if sleeping */ + wakeup(mon); + + if (obj->olet == WEAPON_SYM) { + tmp = -1 + u.ulevel + mon->data->ac + abon(); + if (obj->otyp < ROCK) { + if (!uwep || + uwep->otyp != obj->otyp + (BOW - ARROW)) + tmp -= 4; + else { + tmp += uwep->spe; + } + } else if (obj->otyp == BOOMERANG) + tmp += 4; + tmp += obj->spe; + if (u.uswallow || tmp >= rnd(20)) { + if (hmon(mon, obj, 1) == TRUE) { + /* mon still alive */ +#ifndef NOWORM + cutworm(mon, bhitpos.x, bhitpos.y, obj->otyp); +#endif /* NOWORM */ + } else + mon = 0; + /* weapons thrown disappear sometimes */ + if (obj->otyp < BOOMERANG && rn2(3)) { + /* check bill; free */ + obfree(obj, (struct obj *) 0); + return (1); + } + } else + miss(objects[obj->otyp].oc_name, mon); + } else if (obj->otyp == HEAVY_IRON_BALL) { + tmp = -1 + u.ulevel + mon->data->ac + abon(); + if (!Punished || obj != uball) + tmp += 2; + if (u.utrap) + tmp -= 2; + if (u.uswallow || tmp >= rnd(20)) { + if (hmon(mon, obj, 1) == FALSE) + mon = 0; /* he died */ + } else + miss("iron ball", mon); + } else if (obj->olet == POTION_SYM && u.ulevel > rn2(15)) { + potionhit(mon, obj); + return (1); + } else { + if (cansee(bhitpos.x, bhitpos.y)) + pline("You miss %s.", monnam(mon)); + else + pline("You miss it."); + if (obj->olet == FOOD_SYM && mon->data->mlet == 'd') + if (tamedog(mon, obj)) + return (1); + if (obj->olet == GEM_SYM && mon->data->mlet == 'u' && + !mon->mtame) { + if (obj->dknown && objects[obj->otyp].oc_name_known) { + if (objects[obj->otyp].g_val > 0) { + u.uluck += 5; + goto valuable; + } else { + pline("%s is not interested in your junk.", + Monnam(mon)); + } + } else { /* value unknown to @ */ + u.uluck++; + valuable: + if (u.uluck > LUCKMAX) /* dan@ut-ngp */ + u.uluck = LUCKMAX; + pline("%s graciously accepts your gift.", + Monnam(mon)); + mpickobj(mon, obj); + rloc(mon); + return (1); + } + } + } + } + /* the code following might become part of dropy() */ + if (obj->otyp == CRYSKNIFE) + obj->otyp = WORM_TOOTH; + obj->ox = bhitpos.x; + obj->oy = bhitpos.y; + obj->nobj = fobj; + fobj = obj; + /* prevent him from throwing articles to the exit and escaping */ + /* subfrombill(obj); */ + stackobj(obj); + if (Punished && obj == uball && + (bhitpos.x != u.ux || bhitpos.y != u.uy)) { + freeobj(uchain); + unpobj(uchain); + if (u.utrap) { + if (u.utraptype == TT_PIT) + pline("The ball pulls you out of the pit!"); + else { + long side = + rn2(3) ? LEFT_SIDE : RIGHT_SIDE; + pline("The ball pulls you out of the bear trap."); + pline("Your %s leg is severely damaged.", + (side == LEFT_SIDE) ? "left" : "right"); + set_wounded_legs(side, 500 + rn2(1000)); + losehp(2, "thrown ball"); + } + u.utrap = 0; + } + unsee(); + uchain->nobj = fobj; + fobj = uchain; + u.ux = uchain->ox = bhitpos.x - u.dx; + u.uy = uchain->oy = bhitpos.y - u.dy; + setsee(); + (void) inshop(); + } + if (cansee(bhitpos.x, bhitpos.y)) + prl(bhitpos.x, bhitpos.y); + return (1); +} + +/* split obj so that it gets size num */ +/* remainder is put in the object structure delivered by this call */ +struct obj * +splitobj(obj, num) + struct obj *obj; + int num; +{ + struct obj *otmp; + otmp = newobj(0); + *otmp = *obj; /* copies whole structure */ + otmp->o_id = flags.ident++; + otmp->onamelth = 0; + obj->quan = num; + obj->owt = weight(obj); + otmp->quan -= num; + otmp->owt = weight(otmp); /* -= obj->owt ? */ + obj->nobj = otmp; + if (obj->unpaid) + splitbill(obj, otmp); + return (otmp); +} + +void +more_experienced(exp, rexp) + int exp, rexp; +{ + u.uexp += exp; + u.urexp += 4 * exp + rexp; + if (exp) + flags.botl = 1; + if (u.urexp >= ((pl_character[0] == 'W') ? 1000 : 2000)) + flags.beginner = 0; +} + +void +set_wounded_legs(side, timex) + long side; + int timex; +{ + if (!Wounded_legs || (Wounded_legs & TIMEOUT)) + Wounded_legs |= side + timex; + else + Wounded_legs |= side; +} + +void +heal_legs() +{ + if (Wounded_legs) { + if ((Wounded_legs & BOTH_SIDES) == BOTH_SIDES) + pline("Your legs feel somewhat better."); + else + pline("Your leg feels somewhat better."); + Wounded_legs = 0; + } +} diff --git a/hack/hack.do_name.c b/hack/hack.do_name.c new file mode 100644 index 0000000..3cdf9c7 --- /dev/null +++ b/hack/hack.do_name.c @@ -0,0 +1,385 @@ +/* $NetBSD: hack.do_name.c,v 1.5 2001/03/25 20:43:59 jsm Exp $ */ + +/* + * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica, + * Amsterdam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - 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. + * + * - Neither the name of the Stichting Centrum voor Wiskunde en + * Informatica, 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER + * 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. + */ + +/* + * Copyright (c) 1982 Jay Fenlason + * 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. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``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 +#ifndef lint +__RCSID("$NetBSD: hack.do_name.c,v 1.5 2001/03/25 20:43:59 jsm Exp $"); +#endif /* not lint */ + +#include +#include "hack.h" +#include "extern.h" + +coord +getpos(force, goal) + int force; + const char *goal; +{ + int cx, cy, i, c; + coord cc; + pline("(For instructions type a ?)"); + cx = u.ux; + cy = u.uy; + curs(cx, cy + 2); + while ((c = readchar()) != '.') { + for (i = 0; i < 8; i++) + if (sdir[i] == c) { + if (1 <= cx + xdir[i] && cx + xdir[i] <= COLNO) + cx += xdir[i]; + if (0 <= cy + ydir[i] && cy + ydir[i] <= ROWNO - 1) + cy += ydir[i]; + goto nxtc; + } + if (c == '?') { + pline("Use [hjkl] to move the cursor to %s.", goal); + pline("Type a . when you are at the right place."); + } else { + pline("Unknown direction: '%s' (%s).", + visctrl(c), + force ? "use hjkl or ." : "aborted"); + if (force) + goto nxtc; + cc.x = -1; + cc.y = 0; + return (cc); + } +nxtc: ; + curs(cx, cy + 2); + } + cc.x = cx; + cc.y = cy; + return (cc); +} + +int +do_mname() +{ + char buf[BUFSZ]; + coord cc; + int cx, cy, lth, i; + struct monst *mtmp, *mtmp2; + cc = getpos(0, "the monster you want to name"); + cx = cc.x; + cy = cc.y; + if (cx < 0) + return (0); + mtmp = m_at(cx, cy); + if (!mtmp) { + if (cx == u.ux && cy == u.uy) + pline("This ugly monster is called %s and cannot be renamed.", + plname); + else + pline("There is no monster there."); + return (1); + } + if (mtmp->mimic) { + pline("I see no monster there."); + return (1); + } + if (!cansee(cx, cy)) { + pline("I cannot see a monster there."); + return (1); + } + pline("What do you want to call %s? ", lmonnam(mtmp)); + getlin(buf); + clrlin(); + if (!*buf || *buf == '\033') + return (1); + lth = strlen(buf) + 1; + if (lth > 63) { + buf[62] = 0; + lth = 63; + } + mtmp2 = newmonst(mtmp->mxlth + lth); + *mtmp2 = *mtmp; + for (i = 0; (unsigned)i < mtmp->mxlth; i++) + ((char *) mtmp2->mextra)[i] = ((char *) mtmp->mextra)[i]; + mtmp2->mnamelth = lth; + (void) strcpy(NAME(mtmp2), buf); + replmon(mtmp, mtmp2); + return (1); +} + +/* + * This routine changes the address of obj . Be careful not to call it + * when there might be pointers around in unknown places. For now: only + * when obj is in the inventory. + */ +void +do_oname(obj) + struct obj *obj; +{ + struct obj *otmp, *otmp2; + int lth; + char buf[BUFSZ]; + pline("What do you want to name %s? ", doname(obj)); + getlin(buf); + clrlin(); + if (!*buf || *buf == '\033') + return; + lth = strlen(buf) + 1; + if (lth > 63) { + buf[62] = 0; + lth = 63; + } + otmp2 = newobj(lth); + *otmp2 = *obj; + otmp2->onamelth = lth; + (void) strcpy(ONAME(otmp2), buf); + + setworn((struct obj *) 0, obj->owornmask); + setworn(otmp2, otmp2->owornmask); + + /* + * do freeinv(obj); etc. by hand in order to preserve the position of + * this object in the inventory + */ + if (obj == invent) + invent = otmp2; + else + for (otmp = invent;; otmp = otmp->nobj) { + if (!otmp) + panic("Do_oname: cannot find obj."); + if (otmp->nobj == obj) { + otmp->nobj = otmp2; + break; + } + } +#if 0 + obfree(obj, otmp2); /* now unnecessary: no pointers on bill */ +#endif + free((char *) obj); /* let us hope nobody else saved a pointer */ +} + +int +ddocall() +{ + struct obj *obj; + + pline("Do you want to name an individual object? [ny] "); + switch (readchar()) { + case '\033': + break; + case 'y': + obj = getobj("#", "name"); + if (obj) + do_oname(obj); + break; + default: + obj = getobj("?!=/", "call"); + if (obj) + docall(obj); + } + return (0); +} + +void +docall(obj) + struct obj *obj; +{ + char buf[BUFSZ]; + struct obj otemp; + char **str1; + char *str; + + otemp = *obj; + otemp.quan = 1; + otemp.onamelth = 0; + str = xname(&otemp); + pline("Call %s %s: ", strchr(vowels, *str) ? "an" : "a", str); + getlin(buf); + clrlin(); + if (!*buf || *buf == '\033') + return; + str = newstring(strlen(buf) + 1); + (void) strcpy(str, buf); + str1 = &(objects[obj->otyp].oc_uname); + if (*str1) + free(*str1); + *str1 = str; +} + +const char *const ghostnames[] = {/* these names should have length < PL_NSIZ */ + "adri", "andries", "andreas", "bert", "david", "dirk", "emile", + "frans", "fred", "greg", "hether", "jay", "john", "jon", "kay", + "kenny", "maud", "michiel", "mike", "peter", "robert", "ron", + "tom", "wilmar" +}; + +char * +xmonnam(mtmp, vb) + struct monst *mtmp; + int vb; +{ + static char buf[BUFSZ]; /* %% */ + if (mtmp->mnamelth && !vb) { + (void) strcpy(buf, NAME(mtmp)); + return (buf); + } + switch (mtmp->data->mlet) { + case ' ': + { + const char *gn = (char *) mtmp->mextra; + if (!*gn) { /* might also look in scorefile */ + gn = ghostnames[rn2(SIZE(ghostnames))]; + if (!rn2(2)) + (void) + strcpy((char *) mtmp->mextra, !rn2(5) ? plname : gn); + } + (void) sprintf(buf, "%s's ghost", gn); + } + break; + case '@': + if (mtmp->isshk) { + (void) strcpy(buf, shkname(mtmp)); + break; + } + /* fall into next case */ + default: + (void) sprintf(buf, "the %s%s", + mtmp->minvis ? "invisible " : "", + mtmp->data->mname); + } + if (vb && mtmp->mnamelth) { + (void) strcat(buf, " called "); + (void) strcat(buf, NAME(mtmp)); + } + return (buf); +} + +char * +lmonnam(mtmp) + struct monst *mtmp; +{ + return (xmonnam(mtmp, 1)); +} + +char * +monnam(mtmp) + struct monst *mtmp; +{ + return (xmonnam(mtmp, 0)); +} + +char * +Monnam(mtmp) + struct monst *mtmp; +{ + char *bp = monnam(mtmp); + if ('a' <= *bp && *bp <= 'z') + *bp += ('A' - 'a'); + return (bp); +} + +char * +amonnam(mtmp, adj) + struct monst *mtmp; + const char *adj; +{ + char *bp = monnam(mtmp); + static char buf[BUFSZ]; /* %% */ + + if (!strncmp(bp, "the ", 4)) + bp += 4; + (void) sprintf(buf, "the %s %s", adj, bp); + return (buf); +} + +char * +Amonnam(mtmp, adj) + struct monst *mtmp; + const char *adj; +{ + char *bp = amonnam(mtmp, adj); + + *bp = 'T'; + return (bp); +} + +char * +Xmonnam(mtmp) + struct monst *mtmp; +{ + char *bp = Monnam(mtmp); + if (!strncmp(bp, "The ", 4)) { + bp += 2; + *bp = 'A'; + } + return (bp); +} + +char * +visctrl(c) + char c; +{ + static char ccc[3]; + if (c < 040) { + ccc[0] = '^'; + ccc[1] = c + 0100; + ccc[2] = 0; + } else { + ccc[0] = c; + ccc[1] = 0; + } + return (ccc); +} diff --git a/hack/hack.do_wear.c b/hack/hack.do_wear.c new file mode 100644 index 0000000..f273dfe --- /dev/null +++ b/hack/hack.do_wear.c @@ -0,0 +1,452 @@ +/* $NetBSD: hack.do_wear.c,v 1.4 1997/10/19 16:57:48 christos Exp $ */ + +/* + * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica, + * Amsterdam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - 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. + * + * - Neither the name of the Stichting Centrum voor Wiskunde en + * Informatica, 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER + * 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. + */ + +/* + * Copyright (c) 1982 Jay Fenlason + * 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. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``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 +#ifndef lint +__RCSID("$NetBSD: hack.do_wear.c,v 1.4 1997/10/19 16:57:48 christos Exp $"); +#endif /* not lint */ + +#include "hack.h" +#include "extern.h" + +void +off_msg(otmp) + struct obj *otmp; +{ + pline("You were wearing %s.", doname(otmp)); +} + +int +doremarm() +{ + struct obj *otmp; + if (!uarm && !uarmh && !uarms && !uarmg) { + pline("Not wearing any armor."); + return (0); + } + otmp = (!uarmh && !uarms && !uarmg) ? uarm : + (!uarms && !uarm && !uarmg) ? uarmh : + (!uarmh && !uarm && !uarmg) ? uarms : + (!uarmh && !uarm && !uarms) ? uarmg : + getobj("[", "take off"); + if (!otmp) + return (0); + if (!(otmp->owornmask & (W_ARMOR - W_ARM2))) { + pline("You can't take that off."); + return (0); + } + if (otmp == uarmg && uwep && uwep->cursed) { /* myers@uwmacc */ + pline("You seem not able to take off the gloves while holding your weapon."); + return (0); + } + (void) armoroff(otmp); + return (1); +} + +int +doremring() +{ + if (!uleft && !uright) { + pline("Not wearing any ring."); + return (0); + } + if (!uleft) + return (dorr(uright)); + if (!uright) + return (dorr(uleft)); + if (uleft && uright) + while (1) { + char answer; + + pline("What ring, Right or Left? [ rl?]"); + if (strchr(quitchars, (answer = readchar()))) + return (0); + switch (answer) { + case 'l': + case 'L': + return (dorr(uleft)); + case 'r': + case 'R': + return (dorr(uright)); + case '?': + (void) doprring(); + /* might look at morc here %% */ + } + } + /* NOTREACHED */ + return (0); +} + +int +dorr(otmp) + struct obj *otmp; +{ + if (cursed(otmp)) + return (0); + ringoff(otmp); + off_msg(otmp); + return (1); +} + +int +cursed(otmp) + struct obj *otmp; +{ + if (otmp->cursed) { + pline("You can't. It appears to be cursed."); + return (1); + } + return (0); +} + +int +armoroff(otmp) + struct obj *otmp; +{ + int delay = -objects[otmp->otyp].oc_delay; + if (cursed(otmp)) + return (0); + setworn((struct obj *) 0, otmp->owornmask & W_ARMOR); + if (delay) { + nomul(delay); + switch (otmp->otyp) { + case HELMET: + nomovemsg = "You finished taking off your helmet."; + break; + case PAIR_OF_GLOVES: + nomovemsg = "You finished taking off your gloves"; + break; + default: + nomovemsg = "You finished taking off your suit."; + } + } else { + off_msg(otmp); + } + return (1); +} + +int +doweararm() +{ + struct obj *otmp; + int delay; + int err = 0; + long mask = 0; + + otmp = getobj("[", "wear"); + if (!otmp) + return (0); + if (otmp->owornmask & W_ARMOR) { + pline("You are already wearing that!"); + return (0); + } + if (otmp->otyp == HELMET) { + if (uarmh) { + pline("You are already wearing a helmet."); + err++; + } else + mask = W_ARMH; + } else if (otmp->otyp == SHIELD) { + if (uarms) + pline("You are already wearing a shield."), err++; + if (uwep && uwep->otyp == TWO_HANDED_SWORD) + pline("You cannot wear a shield and wield a two-handed sword."), err++; + if (!err) + mask = W_ARMS; + } else if (otmp->otyp == PAIR_OF_GLOVES) { + if (uarmg) { + pline("You are already wearing gloves."); + err++; + } else if (uwep && uwep->cursed) { + pline("You cannot wear gloves over your weapon."); + err++; + } else + mask = W_ARMG; + } else { + if (uarm) { + if (otmp->otyp != ELVEN_CLOAK || uarm2) { + pline("You are already wearing some armor."); + err++; + } + } + if (!err) + mask = W_ARM; + } + if (otmp == uwep && uwep->cursed) { + if (!err++) + pline("%s is welded to your hand.", Doname(uwep)); + } + if (err) + return (0); + setworn(otmp, mask); + if (otmp == uwep) + setuwep((struct obj *) 0); + delay = -objects[otmp->otyp].oc_delay; + if (delay) { + nomul(delay); + nomovemsg = "You finished your dressing manoeuvre."; + } + otmp->known = 1; + return (1); +} + +int +dowearring() +{ + struct obj *otmp; + long mask = 0; + long oldprop; + + if (uleft && uright) { + pline("There are no more ring-fingers to fill."); + return (0); + } + otmp = getobj("=", "wear"); + if (!otmp) + return (0); + if (otmp->owornmask & W_RING) { + pline("You are already wearing that!"); + return (0); + } + if (otmp == uleft || otmp == uright) { + pline("You are already wearing that."); + return (0); + } + if (otmp == uwep && uwep->cursed) { + pline("%s is welded to your hand.", Doname(uwep)); + return (0); + } + if (uleft) + mask = RIGHT_RING; + else if (uright) + mask = LEFT_RING; + else + do { + char answer; + + pline("What ring-finger, Right or Left? "); + if (strchr(quitchars, (answer = readchar()))) + return (0); + switch (answer) { + case 'l': + case 'L': + mask = LEFT_RING; + break; + case 'r': + case 'R': + mask = RIGHT_RING; + break; + } + } while (!mask); + setworn(otmp, mask); + if (otmp == uwep) + setuwep((struct obj *) 0); + oldprop = u.uprops[PROP(otmp->otyp)].p_flgs; + u.uprops[PROP(otmp->otyp)].p_flgs |= mask; + switch (otmp->otyp) { + case RIN_LEVITATION: + if (!oldprop) + float_up(); + break; + case RIN_PROTECTION_FROM_SHAPE_CHANGERS: + rescham(); + break; + case RIN_GAIN_STRENGTH: + u.ustr += otmp->spe; + u.ustrmax += otmp->spe; + if (u.ustr > 118) + u.ustr = 118; + if (u.ustrmax > 118) + u.ustrmax = 118; + flags.botl = 1; + break; + case RIN_INCREASE_DAMAGE: + u.udaminc += otmp->spe; + break; + } + prinv(otmp); + return (1); +} + +void +ringoff(obj) + struct obj *obj; +{ + long mask; + mask = obj->owornmask & W_RING; + setworn((struct obj *) 0, obj->owornmask); + if (!(u.uprops[PROP(obj->otyp)].p_flgs & mask)) + impossible("Strange... I didnt know you had that ring."); + u.uprops[PROP(obj->otyp)].p_flgs &= ~mask; + switch (obj->otyp) { + case RIN_FIRE_RESISTANCE: + /* Bad luck if the player is in hell... --jgm */ + if (!Fire_resistance && dlevel >= 30) { + pline("The flames of Hell burn you to a crisp."); + killer = "stupidity in hell"; + done("burned"); + } + break; + case RIN_LEVITATION: + if (!Levitation) { /* no longer floating */ + float_down(); + } + break; + case RIN_GAIN_STRENGTH: + u.ustr -= obj->spe; + u.ustrmax -= obj->spe; + if (u.ustr > 118) + u.ustr = 118; + if (u.ustrmax > 118) + u.ustrmax = 118; + flags.botl = 1; + break; + case RIN_INCREASE_DAMAGE: + u.udaminc -= obj->spe; + break; + } +} + +void +find_ac() +{ + int uac = 10; + if (uarm) + uac -= ARM_BONUS(uarm); + if (uarm2) + uac -= ARM_BONUS(uarm2); + if (uarmh) + uac -= ARM_BONUS(uarmh); + if (uarms) + uac -= ARM_BONUS(uarms); + if (uarmg) + uac -= ARM_BONUS(uarmg); + if (uleft && uleft->otyp == RIN_PROTECTION) + uac -= uleft->spe; + if (uright && uright->otyp == RIN_PROTECTION) + uac -= uright->spe; + if (uac != u.uac) { + u.uac = uac; + flags.botl = 1; + } +} + +void +glibr() +{ + struct obj *otmp; + int xfl = 0; + if (!uarmg) + if (uleft || uright) { + /* Note: at present also cursed rings fall off */ + pline("Your %s off your fingers.", + (uleft && uright) ? "rings slip" : "ring slips"); + xfl++; + if ((otmp = uleft) != Null(obj)) { + ringoff(uleft); + dropx(otmp); + } + if ((otmp = uright) != Null(obj)) { + ringoff(uright); + dropx(otmp); + } + } + if ((otmp = uwep) != Null(obj)) { + /* Note: at present also cursed weapons fall */ + setuwep((struct obj *) 0); + dropx(otmp); + pline("Your weapon %sslips from your hands.", + xfl ? "also " : ""); + } +} + +struct obj * +some_armor() +{ + struct obj *otmph = uarm; + if (uarmh && (!otmph || !rn2(4))) + otmph = uarmh; + if (uarmg && (!otmph || !rn2(4))) + otmph = uarmg; + if (uarms && (!otmph || !rn2(4))) + otmph = uarms; + return (otmph); +} + +void +corrode_armor() +{ + struct obj *otmph = some_armor(); + if (otmph) { + if (otmph->rustfree || + otmph->otyp == ELVEN_CLOAK || + otmph->otyp == LEATHER_ARMOR || + otmph->otyp == STUDDED_LEATHER_ARMOR) { + pline("Your %s not affected!", + aobjnam(otmph, "are")); + return; + } + pline("Your %s!", aobjnam(otmph, "corrode")); + otmph->spe--; + } +} diff --git a/hack/hack.dog.c b/hack/hack.dog.c new file mode 100644 index 0000000..4dd6ec3 --- /dev/null +++ b/hack/hack.dog.c @@ -0,0 +1,525 @@ +/* $NetBSD: hack.dog.c,v 1.5 2001/03/25 20:43:59 jsm Exp $ */ + +/* + * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica, + * Amsterdam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - 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. + * + * - Neither the name of the Stichting Centrum voor Wiskunde en + * Informatica, 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER + * 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. + */ + +/* + * Copyright (c) 1982 Jay Fenlason + * 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. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``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 +#ifndef lint +__RCSID("$NetBSD: hack.dog.c,v 1.5 2001/03/25 20:43:59 jsm Exp $"); +#endif /* not lint */ + +#include "hack.h" +#include "extern.h" +#include "hack.mfndpos.h" +#include "def.edog.h" +#include "def.mkroom.h" + +const struct permonst li_dog = +{"little dog", 'd', 2, 18, 6, 1, 6, sizeof(struct edog)}; +const struct permonst dog = +{"dog", 'd', 4, 16, 5, 1, 6, sizeof(struct edog)}; +const struct permonst la_dog = +{"large dog", 'd', 6, 15, 4, 2, 4, sizeof(struct edog)}; + + +void +makedog() +{ + struct monst *mtmp = makemon(&li_dog, u.ux, u.uy); + if (!mtmp) + return; /* dogs were genocided */ + initedog(mtmp); +} + +void +initedog(mtmp) + struct monst *mtmp; +{ + mtmp->mtame = mtmp->mpeaceful = 1; + EDOG(mtmp)->hungrytime = 1000 + moves; + EDOG(mtmp)->eattime = 0; + EDOG(mtmp)->droptime = 0; + EDOG(mtmp)->dropdist = 10000; + EDOG(mtmp)->apport = 10; + EDOG(mtmp)->whistletime = 0; +} + +/* attach the monsters that went down (or up) together with @ */ +struct monst *mydogs = 0; +struct monst *fallen_down = 0;/* monsters that fell through a trapdoor */ +/* they will appear on the next level @ goes to, even if he goes up! */ + +void +losedogs() +{ + struct monst *mtmp; + while ((mtmp = mydogs) != NULL) { + mydogs = mtmp->nmon; + mtmp->nmon = fmon; + fmon = mtmp; + mnexto(mtmp); + } + while ((mtmp = fallen_down) != NULL) { + fallen_down = mtmp->nmon; + mtmp->nmon = fmon; + fmon = mtmp; + rloc(mtmp); + } +} + +void +keepdogs() +{ + struct monst *mtmp; + for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) + if (dist(mtmp->mx, mtmp->my) < 3 && follower(mtmp) + && !mtmp->msleep && !mtmp->mfroz) { + relmon(mtmp); + mtmp->nmon = mydogs; + mydogs = mtmp; + unpmon(mtmp); + keepdogs(); /* we destroyed the link, so use + * recursion */ + return; /* (admittedly somewhat primitive) */ + } +} + +void +fall_down(mtmp) + struct monst *mtmp; +{ + relmon(mtmp); + mtmp->nmon = fallen_down; + fallen_down = mtmp; + unpmon(mtmp); + mtmp->mtame = 0; +} + +/* return quality of food; the lower the better */ +#define DOGFOOD 0 +#define CADAVER 1 +#define ACCFOOD 2 +#define MANFOOD 3 +#define APPORT 4 +#define POISON 5 +#define UNDEF 6 +int +dogfood(obj) + struct obj *obj; +{ + switch (obj->olet) { + case FOOD_SYM: + return ( + (obj->otyp == TRIPE_RATION) ? DOGFOOD : + (obj->otyp < CARROT) ? ACCFOOD : + (obj->otyp < CORPSE) ? MANFOOD : + (poisonous(obj) || obj->age + 50 <= moves || + obj->otyp == DEAD_COCKATRICE) + ? POISON : CADAVER + ); + default: + if (!obj->cursed) + return (APPORT); + /* fall into next case */ + case BALL_SYM: + case CHAIN_SYM: + case ROCK_SYM: + return (UNDEF); + } +} + +/* return 0 (no move), 1 (move) or 2 (dead) */ +int +dog_move(struct monst *mtmp, int after) +{ + int nx, ny, omx, omy, appr, nearer, j; + int udist, chi = 0, i, whappr; + struct monst *mtmp2; + const struct permonst *mdat = mtmp->data; + struct edog *edog = EDOG(mtmp); + struct obj *obj; + struct trap *trap; + xchar cnt, chcnt, nix, niy; + schar dogroom, uroom; + xchar gx = 0, gy = 0, gtyp, otyp; /* current goal */ + coord poss[9]; + int info[9]; +#define GDIST(x,y) ((x-gx)*(x-gx) + (y-gy)*(y-gy)) +#define DDIST(x,y) ((x-omx)*(x-omx) + (y-omy)*(y-omy)) + + if (moves <= edog->eattime) + return (0); /* dog is still eating */ + omx = mtmp->mx; + omy = mtmp->my; + whappr = (moves - EDOG(mtmp)->whistletime < 5); + if (moves > edog->hungrytime + 500 && !mtmp->mconf) { + mtmp->mconf = 1; + mtmp->mhpmax /= 3; + if (mtmp->mhp > mtmp->mhpmax) + mtmp->mhp = mtmp->mhpmax; + if (cansee(omx, omy)) + pline("%s is confused from hunger.", Monnam(mtmp)); + else + pline("You feel worried about %s.", monnam(mtmp)); + } else if (moves > edog->hungrytime + 750 || mtmp->mhp < 1) { + if (cansee(omx, omy)) + pline("%s dies from hunger.", Monnam(mtmp)); + else + pline("You have a sad feeling for a moment, then it passes."); + mondied(mtmp); + return (2); + } + dogroom = inroom(omx, omy); + uroom = inroom(u.ux, u.uy); + udist = dist(omx, omy); + + /* maybe we tamed him while being swallowed --jgm */ + if (!udist) + return (0); + + /* if we are carrying sth then we drop it (perhaps near @) */ + /* Note: if apport == 1 then our behaviour is independent of udist */ + if (mtmp->minvent) { + if (!rn2(udist) || !rn2((int) edog->apport)) + if ((unsigned)rn2(10) < edog->apport) { + relobj(mtmp, (int) mtmp->minvis); + if (edog->apport > 1) + edog->apport--; + edog->dropdist = udist; /* hpscdi!jon */ + edog->droptime = moves; + } + } else { + if ((obj = o_at(omx, omy)) != NULL) + if (!strchr("0_", obj->olet)) { + if ((otyp = dogfood(obj)) <= CADAVER) { + nix = omx; + niy = omy; + goto eatobj; + } + if (obj->owt < 10 * mtmp->data->mlevel) + if ((unsigned)rn2(20) < edog->apport + 3) + if (rn2(udist) || !rn2((int) edog->apport)) { + freeobj(obj); + unpobj(obj); + /* + * if(levl[omx][omy].s + * crsym == + * obj->olet) + * newsym(omx,omy); + */ + mpickobj(mtmp, obj); + } + } + } + + /* first we look for food */ + gtyp = UNDEF; /* no goal as yet */ +#ifdef LINT + gx = gy = 0; /* suppress 'used before set' message */ +#endif /* LINT */ + for (obj = fobj; obj; obj = obj->nobj) { + otyp = dogfood(obj); + if (otyp > gtyp || otyp == UNDEF) + continue; + if (inroom(obj->ox, obj->oy) != dogroom) + continue; + if (otyp < MANFOOD && + (dogroom >= 0 || DDIST(obj->ox, obj->oy) < 10)) { + if (otyp < gtyp || (otyp == gtyp && + DDIST(obj->ox, obj->oy) < DDIST(gx, gy))) { + gx = obj->ox; + gy = obj->oy; + gtyp = otyp; + } + } else if (gtyp == UNDEF && dogroom >= 0 && + uroom == dogroom && + !mtmp->minvent && edog->apport > (unsigned)rn2(8)) { + gx = obj->ox; + gy = obj->oy; + gtyp = APPORT; + } + } + if (gtyp == UNDEF || + (gtyp != DOGFOOD && gtyp != APPORT && moves < edog->hungrytime)) { + if (dogroom < 0 || dogroom == uroom) { + gx = u.ux; + gy = u.uy; +#ifndef QUEST + } else { + int tmp = rooms[dogroom].fdoor; + cnt = rooms[dogroom].doorct; + + gx = gy = FAR; /* random, far away */ + while (cnt--) { + if (dist(gx, gy) > + dist(doors[tmp].x, doors[tmp].y)) { + gx = doors[tmp].x; + gy = doors[tmp].y; + } + tmp++; + } + /* here gx == FAR e.g. when dog is in a vault */ + if (gx == FAR || (gx == omx && gy == omy)) { + gx = u.ux; + gy = u.uy; + } +#endif /* QUEST */ + } + appr = (udist >= 9) ? 1 : (mtmp->mflee) ? -1 : 0; + if (after && udist <= 4 && gx == u.ux && gy == u.uy) + return (0); + if (udist > 1) { + if (!IS_ROOM(levl[u.ux][u.uy].typ) || !rn2(4) || + whappr || + (mtmp->minvent && rn2((int) edog->apport))) + appr = 1; + } + /* if you have dog food he'll follow you more closely */ + if (appr == 0) { + obj = invent; + while (obj) { + if (obj->otyp == TRIPE_RATION) { + appr = 1; + break; + } + obj = obj->nobj; + } + } + } else + appr = 1; /* gtyp != UNDEF */ + if (mtmp->mconf) + appr = 0; + + if (gx == u.ux && gy == u.uy && (dogroom != uroom || dogroom < 0)) { + coord *cp; + cp = gettrack(omx, omy); + if (cp) { + gx = cp->x; + gy = cp->y; + } + } + nix = omx; + niy = omy; + cnt = mfndpos(mtmp, poss, info, ALLOW_M | ALLOW_TRAPS); + chcnt = 0; + chi = -1; + for (i = 0; i < cnt; i++) { + nx = poss[i].x; + ny = poss[i].y; + if (info[i] & ALLOW_M) { + mtmp2 = m_at(nx, ny); + if (mtmp2->data->mlevel >= mdat->mlevel + 2 || + mtmp2->data->mlet == 'c') + continue; + if (after) + return (0); /* hit only once each move */ + + if (hitmm(mtmp, mtmp2) == 1 && rn2(4) && + mtmp2->mlstmv != moves && + hitmm(mtmp2, mtmp) == 2) + return (2); + return (0); + } + /* dog avoids traps */ + /* but perhaps we have to pass a trap in order to follow @ */ + if ((info[i] & ALLOW_TRAPS) && (trap = t_at(nx, ny))) { + if (!trap->tseen && rn2(40)) + continue; + if (rn2(10)) + continue; + } + /* dog eschewes cursed objects */ + /* but likes dog food */ + obj = fobj; + while (obj) { + if (obj->ox != nx || obj->oy != ny) + goto nextobj; + if (obj->cursed) + goto nxti; + if (obj->olet == FOOD_SYM && + (otyp = dogfood(obj)) < MANFOOD && + (otyp < ACCFOOD || edog->hungrytime <= moves)) { + /* + * Note: our dog likes the food so much that + * he might eat it even when it conceals a + * cursed object + */ + nix = nx; + niy = ny; + chi = i; + eatobj: + edog->eattime = + moves + obj->quan * objects[obj->otyp].oc_delay; + if (edog->hungrytime < moves) + edog->hungrytime = moves; + edog->hungrytime += + 5 * obj->quan * objects[obj->otyp].nutrition; + mtmp->mconf = 0; + if (cansee(nix, niy)) + pline("%s ate %s.", Monnam(mtmp), doname(obj)); + /* perhaps this was a reward */ + if (otyp != CADAVER) + edog->apport += 200 / (edog->dropdist + moves - edog->droptime); + delobj(obj); + goto newdogpos; + } + nextobj: + obj = obj->nobj; + } + + for (j = 0; j < MTSZ && j < cnt - 1; j++) + if (nx == mtmp->mtrack[j].x && ny == mtmp->mtrack[j].y) + if (rn2(4 * (cnt - j))) + goto nxti; + + /* + * Some stupid C compilers cannot compute the whole + * expression at once. + */ + nearer = GDIST(nx, ny); + nearer -= GDIST(nix, niy); + nearer *= appr; + if ((nearer == 0 && !rn2(++chcnt)) || nearer < 0 || + (nearer > 0 && !whappr && + ((omx == nix && omy == niy && !rn2(3)) + || !rn2(12)) + )) { + nix = nx; + niy = ny; + if (nearer < 0) + chcnt = 0; + chi = i; + } +nxti: ; + } +newdogpos: + if (nix != omx || niy != omy) { + if (info[chi] & ALLOW_U) { + (void) hitu(mtmp, d(mdat->damn, mdat->damd) + 1); + return (0); + } + mtmp->mx = nix; + mtmp->my = niy; + for (j = MTSZ - 1; j > 0; j--) + mtmp->mtrack[j] = mtmp->mtrack[j - 1]; + mtmp->mtrack[0].x = omx; + mtmp->mtrack[0].y = omy; + } + if (mintrap(mtmp) == 2) /* he died */ + return (2); + pmon(mtmp); + return (1); +} + +/* return roomnumber or -1 */ +int +inroom(x, y) + xchar x, y; +{ +#ifndef QUEST + struct mkroom *croom = &rooms[0]; + while (croom->hx >= 0) { + if (croom->hx >= x - 1 && croom->lx <= x + 1 && + croom->hy >= y - 1 && croom->ly <= y + 1) + return (croom - rooms); + croom++; + } +#endif /* QUEST */ + return (-1); /* not in room or on door */ +} + +int +tamedog(mtmp, obj) + struct monst *mtmp; + struct obj *obj; +{ + struct monst *mtmp2; + + if (flags.moonphase == FULL_MOON && night() && rn2(6)) + return (0); + + /* If we cannot tame him, at least he's no longer afraid. */ + mtmp->mflee = 0; + mtmp->mfleetim = 0; + if (mtmp->mtame || mtmp->mfroz || +#ifndef NOWORM + mtmp->wormno || +#endif /* NOWORM */ + mtmp->isshk || mtmp->isgd || strchr(" &@12", mtmp->data->mlet)) + return (0); /* no tame long worms? */ + if (obj) { + if (dogfood(obj) >= MANFOOD) + return (0); + if (cansee(mtmp->mx, mtmp->my)) { + pline("%s devours the %s.", Monnam(mtmp), + objects[obj->otyp].oc_name); + } + obfree(obj, (struct obj *) 0); + } + mtmp2 = newmonst(sizeof(struct edog) + mtmp->mnamelth); + *mtmp2 = *mtmp; + mtmp2->mxlth = sizeof(struct edog); + if (mtmp->mnamelth) + (void) strcpy(NAME(mtmp2), NAME(mtmp)); + initedog(mtmp2); + replmon(mtmp, mtmp2); + return (1); +} diff --git a/hack/hack.eat.c b/hack/hack.eat.c new file mode 100644 index 0000000..6fce735 --- /dev/null +++ b/hack/hack.eat.c @@ -0,0 +1,559 @@ +/* $NetBSD: hack.eat.c,v 1.5 2001/03/25 20:44:00 jsm Exp $ */ + +/* + * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica, + * Amsterdam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - 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. + * + * - Neither the name of the Stichting Centrum voor Wiskunde en + * Informatica, 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER + * 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. + */ + +/* + * Copyright (c) 1982 Jay Fenlason + * 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. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``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 +#ifndef lint +__RCSID("$NetBSD: hack.eat.c,v 1.5 2001/03/25 20:44:00 jsm Exp $"); +#endif /* not lint */ + +#include "hack.h" +#include "extern.h" +char POISONOUS[] = "ADKSVabhks"; + +/* hunger texts used on bottom line (each 8 chars long) */ +#define SATIATED 0 +#define NOT_HUNGRY 1 +#define HUNGRY 2 +#define WEAK 3 +#define FAINTING 4 +#define FAINTED 5 +#define STARVED 6 + +const char *const hu_stat[] = { + "Satiated", + " ", + "Hungry ", + "Weak ", + "Fainting", + "Fainted ", + "Starved " +}; + +void +init_uhunger() +{ + u.uhunger = 900; + u.uhs = NOT_HUNGRY; +} + +#define TTSZ SIZE(tintxts) +const struct { + const char *txt; + int nut; +} tintxts[] = { + { "It contains first quality peaches - what a surprise!", 40 }, + { "It contains salmon - not bad!", 60 }, + { "It contains apple juice - perhaps not what you hoped for.", 20 }, + { "It contains some nondescript substance, tasting awfully.", 500 }, + { "It contains rotten meat. You vomit.", -50 }, + { "It turns out to be empty.", 0 } +}; + +static struct { + struct obj *tin; + int usedtime, reqtime; +} tin; + +int +opentin() +{ + int r; + + if (!carried(tin.tin)) /* perhaps it was stolen? */ + return (0); /* %% probably we should use tinoid */ + if (tin.usedtime++ >= 50) { + pline("You give up your attempt to open the tin."); + return (0); + } + if (tin.usedtime < tin.reqtime) + return (1); /* still busy */ + + pline("You succeed in opening the tin."); + useup(tin.tin); + r = rn2(2 * TTSZ); + if (r < TTSZ) { + pline(tintxts[r].txt); + lesshungry(tintxts[r].nut); + if (r == 1) { /* SALMON */ + Glib = rnd(15); + pline("Eating salmon made your fingers very slippery."); + } + } else { + pline("It contains spinach - this makes you feel like Popeye!"); + lesshungry(600); + if (u.ustr < 118) + u.ustr += rnd(((u.ustr < 17) ? 19 : 118) - u.ustr); + if (u.ustr > u.ustrmax) + u.ustrmax = u.ustr; + flags.botl = 1; + } + return (0); +} + +int +Meatdone() +{ + u.usym = '@'; + prme(); + return 0; +} + +int +doeat() +{ + struct obj *otmp; + struct objclass *ftmp; + int tmp; + + /* Is there some food (probably a heavy corpse) here on the ground? */ + if (!Levitation) + for (otmp = fobj; otmp; otmp = otmp->nobj) { + if (otmp->ox == u.ux && otmp->oy == u.uy && + otmp->olet == FOOD_SYM) { + pline("There %s %s here; eat %s? [ny] ", + (otmp->quan == 1) ? "is" : "are", + doname(otmp), + (otmp->quan == 1) ? "it" : "one"); + if (readchar() == 'y') { + if (otmp->quan != 1) + (void) splitobj(otmp, 1); + freeobj(otmp); + otmp = addinv(otmp); + addtobill(otmp); + goto gotit; + } + } + } + otmp = getobj("%", "eat"); + if (!otmp) + return (0); +gotit: + if (otmp->otyp == TIN) { + if (uwep) { + switch (uwep->otyp) { + case CAN_OPENER: + tmp = 1; + break; + case DAGGER: + case CRYSKNIFE: + tmp = 3; + break; + case PICK_AXE: + case AXE: + tmp = 6; + break; + default: + goto no_opener; + } + pline("Using your %s you try to open the tin.", + aobjnam(uwep, (char *) 0)); + } else { + no_opener: + pline("It is not so easy to open this tin."); + if (Glib) { + pline("The tin slips out of your hands."); + if (otmp->quan > 1) { + struct obj *obj; + + obj = splitobj(otmp, 1); + if (otmp == uwep) + setuwep(obj); + } + dropx(otmp); + return (1); + } + tmp = 10 + rn2(1 + 500 / ((int) (u.ulevel + u.ustr))); + } + tin.reqtime = tmp; + tin.usedtime = 0; + tin.tin = otmp; + occupation = opentin; + occtxt = "opening the tin"; + return (1); + } + ftmp = &objects[otmp->otyp]; + multi = -ftmp->oc_delay; + if (otmp->otyp >= CORPSE && eatcorpse(otmp)) + goto eatx; + if (!rn2(7) && otmp->otyp != FORTUNE_COOKIE) { + pline("Blecch! Rotten food!"); + if (!rn2(4)) { + pline("You feel rather light headed."); + Confusion += d(2, 4); + } else if (!rn2(4) && !Blind) { + pline("Everything suddenly goes dark."); + Blind = d(2, 10); + seeoff(0); + } else if (!rn2(3)) { + if (Blind) + pline("The world spins and you slap against the floor."); + else + pline("The world spins and goes dark."); + nomul(-rnd(10)); + nomovemsg = "You are conscious again."; + } + lesshungry(ftmp->nutrition / 4); + } else { + if (u.uhunger >= 1500) { + pline("You choke over your food."); + pline("You die..."); + killer = ftmp->oc_name; + done("choked"); + } + switch (otmp->otyp) { + case FOOD_RATION: + if (u.uhunger <= 200) + pline("That food really hit the spot!"); + else if (u.uhunger <= 700) + pline("That satiated your stomach!"); + else { + pline("You're having a hard time getting all that food down."); + multi -= 2; + } + lesshungry(ftmp->nutrition); + if (multi < 0) + nomovemsg = "You finished your meal."; + break; + case TRIPE_RATION: + pline("Yak - dog food!"); + more_experienced(1, 0); + flags.botl = 1; + if (rn2(2)) { + pline("You vomit."); + morehungry(20); + if (Sick) { + Sick = 0; /* David Neves */ + pline("What a relief!"); + } + } else + lesshungry(ftmp->nutrition); + break; + default: + if (otmp->otyp >= CORPSE) + pline("That %s tasted terrible!", ftmp->oc_name); + else + pline("That %s was delicious!", ftmp->oc_name); + lesshungry(ftmp->nutrition); + if (otmp->otyp == DEAD_LIZARD && (Confusion > 2)) + Confusion = 2; + else +#ifdef QUEST + if (otmp->otyp == CARROT && !Blind) { + u.uhorizon++; + setsee(); + pline("Your vision improves."); + } else +#endif /* QUEST */ + if (otmp->otyp == FORTUNE_COOKIE) { + if (Blind) { + pline("This cookie has a scrap of paper inside!"); + pline("What a pity, that you cannot read it!"); + } else + outrumor(); + } else if (otmp->otyp == LUMP_OF_ROYAL_JELLY) { + /* This stuff seems to be VERY healthy! */ + if (u.ustrmax < 118) + u.ustrmax++; + if (u.ustr < u.ustrmax) + u.ustr++; + u.uhp += rnd(20); + if (u.uhp > u.uhpmax) { + if (!rn2(17)) + u.uhpmax++; + u.uhp = u.uhpmax; + } + heal_legs(); + } + break; + } + } +eatx: + if (multi < 0 && !nomovemsg) { + static char msgbuf[BUFSZ]; + (void) sprintf(msgbuf, "You finished eating the %s.", + ftmp->oc_name); + nomovemsg = msgbuf; + } + useup(otmp); + return (1); +} + +/* called in hack.main.c */ +void +gethungry() +{ + --u.uhunger; + if (moves % 2) { + if (Regeneration) + u.uhunger--; + if (Hunger) + u.uhunger--; + /* + * a3: if(Hunger & LEFT_RING) u.uhunger--; if(Hunger & + * RIGHT_RING) u.uhunger--; etc. + */ + } + if (moves % 20 == 0) { /* jimt@asgb */ + if (uleft) + u.uhunger--; + if (uright) + u.uhunger--; + } + newuhs(TRUE); +} + +/* called after vomiting and after performing feats of magic */ +void +morehungry(num) + int num; +{ + u.uhunger -= num; + newuhs(TRUE); +} + +/* called after eating something (and after drinking fruit juice) */ +void +lesshungry(num) + int num; +{ + u.uhunger += num; + newuhs(FALSE); +} + +int +unfaint() +{ + u.uhs = FAINTING; + flags.botl = 1; + return 0; +} + +void +newuhs(incr) + boolean incr; +{ + int newhs, h = u.uhunger; + + newhs = (h > 1000) ? SATIATED : + (h > 150) ? NOT_HUNGRY : + (h > 50) ? HUNGRY : + (h > 0) ? WEAK : FAINTING; + + if (newhs == FAINTING) { + if (u.uhs == FAINTED) + newhs = FAINTED; + if (u.uhs <= WEAK || rn2(20 - u.uhunger / 10) >= 19) { + if (u.uhs != FAINTED && multi >= 0 /* %% */ ) { + pline("You faint from lack of food."); + nomul(-10 + (u.uhunger / 10)); + nomovemsg = "You regain consciousness."; + afternmv = unfaint; + newhs = FAINTED; + } + } else if (u.uhunger < -(int) (200 + 25 * u.ulevel)) { + u.uhs = STARVED; + flags.botl = 1; + bot(); + pline("You die from starvation."); + done("starved"); + } + } + if (newhs != u.uhs) { + if (newhs >= WEAK && u.uhs < WEAK) + losestr(1); /* this may kill you -- see below */ + else if (newhs < WEAK && u.uhs >= WEAK && u.ustr < u.ustrmax) + losestr(-1); + switch (newhs) { + case HUNGRY: + pline((!incr) ? "You only feel hungry now." : + (u.uhunger < 145) ? "You feel hungry." : + "You are beginning to feel hungry."); + break; + case WEAK: + pline((!incr) ? "You feel weak now." : + (u.uhunger < 45) ? "You feel weak." : + "You are beginning to feel weak."); + break; + } + u.uhs = newhs; + flags.botl = 1; + if (u.uhp < 1) { + pline("You die from hunger and exhaustion."); + killer = "exhaustion"; + done("starved"); + } + } +} + +#define CORPSE_I_TO_C(otyp) (char) ((otyp >= DEAD_ACID_BLOB)\ + ? 'a' + (otyp - DEAD_ACID_BLOB)\ + : '@' + (otyp - DEAD_HUMAN)) +int +poisonous(otmp) + struct obj *otmp; +{ + return (strchr(POISONOUS, CORPSE_I_TO_C(otmp->otyp)) != 0); +} + +/* returns 1 if some text was printed */ +int +eatcorpse(otmp) + struct obj *otmp; +{ + char let = CORPSE_I_TO_C(otmp->otyp); + int tp = 0; + if (let != 'a' && moves > otmp->age + 50 + rn2(100)) { + tp++; + pline("Ulch -- that meat was tainted!"); + pline("You get very sick."); + Sick = 10 + rn2(10); + u.usick_cause = objects[otmp->otyp].oc_name; + } else if (strchr(POISONOUS, let) && rn2(5)) { + tp++; + pline("Ecch -- that must have been poisonous!"); + if (!Poison_resistance) { + losestr(rnd(4)); + losehp(rnd(15), "poisonous corpse"); + } else + pline("You don't seem affected by the poison."); + } else if (strchr("ELNOPQRUuxz", let) && rn2(5)) { + tp++; + pline("You feel sick."); + losehp(rnd(8), "cadaver"); + } + switch (let) { + case 'L': + case 'N': + case 't': + Teleportation |= INTRINSIC; + break; + case 'W': + pluslvl(); + break; + case 'n': + u.uhp = u.uhpmax; + flags.botl = 1; + /* fall into next case */ + case '@': + pline("You cannibal! You will be sorry for this!"); + /* not tp++; */ + /* fall into next case */ + case 'd': + Aggravate_monster |= INTRINSIC; + break; + case 'I': + if (!Invis) { + Invis = 50 + rn2(100); + if (!See_invisible) + newsym(u.ux, u.uy); + } else { + Invis |= INTRINSIC; + See_invisible |= INTRINSIC; + } + /* fall into next case */ + case 'y': +#ifdef QUEST + u.uhorizon++; +#endif /* QUEST */ + /* fall into next case */ + case 'B': + Confusion = 50; + break; + case 'D': + Fire_resistance |= INTRINSIC; + break; + case 'E': + Telepat |= INTRINSIC; + break; + case 'F': + case 'Y': + Cold_resistance |= INTRINSIC; + break; + case 'k': + case 's': + Poison_resistance |= INTRINSIC; + break; + case 'c': + pline("You turn to stone."); + killer = "dead cockatrice"; + done("died"); + /* NOTREACHED */ + case 'a': + if (Stoned) { + pline("What a pity - you just destroyed a future piece of art!"); + tp++; + Stoned = 0; + } + break; + case 'M': + pline("You cannot resist the temptation to mimic a treasure chest."); + tp++; + nomul(-30); + afternmv = Meatdone; + nomovemsg = "You now again prefer mimicking a human."; + u.usym = '$'; + prme(); + break; + } + return (tp); +} diff --git a/hack/hack.end.c b/hack/hack.end.c new file mode 100644 index 0000000..26cfb52 --- /dev/null +++ b/hack/hack.end.c @@ -0,0 +1,790 @@ +/* $NetBSD: hack.end.c,v 1.5 2001/03/25 20:44:00 jsm Exp $ */ + +/* + * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica, + * Amsterdam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - 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. + * + * - Neither the name of the Stichting Centrum voor Wiskunde en + * Informatica, 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER + * 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. + */ + +/* + * Copyright (c) 1982 Jay Fenlason + * 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. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``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 +#ifndef lint +__RCSID("$NetBSD: hack.end.c,v 1.5 2001/03/25 20:44:00 jsm Exp $"); +#endif /* not lint */ + +#include +#include +#include +#include "hack.h" +#include "extern.h" +#define Sprintf (void) sprintf + +xchar maxdlevel = 1; + +int +dodone() +{ + done1(0); + return 0; +} + + +/*ARGSUSED*/ +void +done1(n) + int n __attribute__((__unused__)); +{ + (void) signal(SIGINT, SIG_IGN); + pline("Really quit?"); + if (readchar() != 'y') { + (void) signal(SIGINT, done1); + clrlin(); + (void) fflush(stdout); + if (multi > 0) + nomul(0); + return; + } + done("quit"); + /* NOTREACHED */ +} + +int done_stopprint; +int done_hup; + +/*ARGSUSED*/ +void +done_intr(n) + int n __attribute__((__unused__)); +{ + done_stopprint++; + (void) signal(SIGINT, SIG_IGN); + (void) signal(SIGQUIT, SIG_IGN); +} + +void +done_hangup(n) + int n; +{ + done_hup++; + (void) signal(SIGHUP, SIG_IGN); + done_intr(n); +} + +void +done_in_by(mtmp) + struct monst *mtmp; +{ + static char buf[BUFSZ]; + pline("You die ..."); + if (mtmp->data->mlet == ' ') { + Sprintf(buf, "the ghost of %s", (char *) mtmp->mextra); + killer = buf; + } else if (mtmp->mnamelth) { + Sprintf(buf, "%s called %s", + mtmp->data->mname, NAME(mtmp)); + killer = buf; + } else if (mtmp->minvis) { + Sprintf(buf, "invisible %s", mtmp->data->mname); + killer = buf; + } else + killer = mtmp->data->mname; + done("died"); +} + +/* + * called with arg "died", "drowned", "escaped", "quit", "choked", + * "panicked", "burned", "starved" or "tricked" + */ +/* Be careful not to call panic from here! */ +void +done(st1) + const char *st1; +{ + +#ifdef WIZARD + if (wizard && *st1 == 'd') { + u.uswldtim = 0; + if (u.uhpmax < 0) + u.uhpmax = 100; /* arbitrary */ + u.uhp = u.uhpmax; + pline("For some reason you are still alive."); + flags.move = 0; + if (multi > 0) + multi = 0; + else + multi = -1; + flags.botl = 1; + return; + } +#endif /* WIZARD */ + (void) signal(SIGINT, done_intr); + (void) signal(SIGQUIT, done_intr); + (void) signal(SIGHUP, done_hangup); + if (*st1 == 'q' && u.uhp < 1) { + st1 = "died"; + killer = "quit while already on Charon's boat"; + } + if (*st1 == 's') + killer = "starvation"; + else if (*st1 == 'd' && st1[1] == 'r') + killer = "drowning"; + else if (*st1 == 'p') + killer = "panic"; + else if (*st1 == 't') + killer = "trickery"; + else if (!strchr("bcd", *st1)) + killer = st1; + paybill(); + clearlocks(); + if (flags.toplin == 1) + more(); + if (strchr("bcds", *st1)) { +#ifdef WIZARD + if (!wizard) +#endif /* WIZARD */ + savebones(); + if (!flags.notombstone) + outrip(); + } + if (*st1 == 'c') + killer = st1; /* after outrip() */ + settty((char *) 0); /* does a clear_screen() */ + if (!done_stopprint) + printf("Goodbye %s %s...\n\n", pl_character, plname); + { + long int tmp; + tmp = u.ugold - u.ugold0; + if (tmp < 0) + tmp = 0; + if (*st1 == 'd' || *st1 == 'b') + tmp -= tmp / 10; + u.urexp += tmp; + u.urexp += 50 * maxdlevel; + if (maxdlevel > 20) + u.urexp += 1000 * ((maxdlevel > 30) ? 10 : maxdlevel - 20); + } + if (*st1 == 'e') { + struct monst *mtmp; + struct obj *otmp; + int i; + unsigned worthlessct = 0; + boolean has_amulet = FALSE; + + killer = st1; + keepdogs(); + mtmp = mydogs; + if (mtmp) { + if (!done_stopprint) + printf("You"); + while (mtmp) { + if (!done_stopprint) + printf(" and %s", monnam(mtmp)); + if (mtmp->mtame) + u.urexp += mtmp->mhp; + mtmp = mtmp->nmon; + } + if (!done_stopprint) + printf("\nescaped from the dungeon with %ld points,\n", + u.urexp); + } else if (!done_stopprint) + printf("You escaped from the dungeon with %ld points,\n", + u.urexp); + for (otmp = invent; otmp; otmp = otmp->nobj) { + if (otmp->olet == GEM_SYM) { + objects[otmp->otyp].oc_name_known = 1; + i = otmp->quan * objects[otmp->otyp].g_val; + if (i == 0) { + worthlessct += otmp->quan; + continue; + } + u.urexp += i; + if (!done_stopprint) + printf("\t%s (worth %d Zorkmids),\n", + doname(otmp), i); + } else if (otmp->olet == AMULET_SYM) { + otmp->known = 1; + i = (otmp->spe < 0) ? 2 : 5000; + u.urexp += i; + if (!done_stopprint) + printf("\t%s (worth %d Zorkmids),\n", + doname(otmp), i); + if (otmp->spe >= 0) { + has_amulet = TRUE; + killer = "escaped (with amulet)"; + } + } + } + if (worthlessct) + if (!done_stopprint) + printf("\t%u worthless piece%s of coloured glass,\n", + worthlessct, plur(worthlessct)); + if (has_amulet) + u.urexp *= 2; + } else if (!done_stopprint) + printf("You %s on dungeon level %d with %ld points,\n", + st1, dlevel, u.urexp); + if (!done_stopprint) + printf("and %ld piece%s of gold, after %ld move%s.\n", + u.ugold, plur(u.ugold), moves, plur(moves)); + if (!done_stopprint) + printf("You were level %u with a maximum of %d hit points when you %s.\n", + u.ulevel, u.uhpmax, st1); + if (*st1 == 'e' && !done_stopprint) { + getret(); /* all those pieces of coloured glass ... */ + cls(); + } +#ifdef WIZARD + if (!wizard) +#endif /* WIZARD */ + topten(); + if (done_stopprint) + printf("\n\n"); + exit(0); +} + +#define newttentry() (struct toptenentry *) alloc(sizeof(struct toptenentry)) +#define NAMSZ 8 +#define DTHSZ 40 +#define PERSMAX 1 +#define POINTSMIN 1 /* must be > 0 */ +#define ENTRYMAX 100 /* must be >= 10 */ +#define PERS_IS_UID /* delete for PERSMAX per name; now per uid */ +struct toptenentry { + struct toptenentry *tt_next; + long int points; + int level, maxlvl, hp, maxhp; + int uid; + char plchar; + char sex; + char name[NAMSZ + 1]; + char death[DTHSZ + 1]; + char date[7];/* yymmdd */ +} *tt_head; + +void +topten() +{ + int uid = getuid(); + int rank, rank0 = -1, rank1 = 0; + int occ_cnt = PERSMAX; + struct toptenentry *t0, *t1, *tprev; + const char *recfile = RECORD; + const char *reclock = "record_lock"; + int sleepct = 300; + FILE *rfile; + int flg = 0; +#define HUP if(!done_hup) + while (link(recfile, reclock) == -1) { + HUP perror(reclock); + if (!sleepct--) { + HUP puts("I give up. Sorry."); + HUP puts("Perhaps there is an old record_lock around?"); + return; + } + HUP printf("Waiting for access to record file. (%d)\n", + sleepct); + HUP(void) fflush(stdout); + sleep(1); + } + if (!(rfile = fopen(recfile, "r"))) { + HUP puts("Cannot open record file!"); + goto unlock; + } + HUP(void) putchar('\n'); + + /* create a new 'topten' entry */ + t0 = newttentry(); + t0->level = dlevel; + t0->maxlvl = maxdlevel; + t0->hp = u.uhp; + t0->maxhp = u.uhpmax; + t0->points = u.urexp; + t0->plchar = pl_character[0]; + t0->sex = (flags.female ? 'F' : 'M'); + t0->uid = uid; + (void) strncpy(t0->name, plname, NAMSZ); + (t0->name)[NAMSZ] = 0; + (void) strncpy(t0->death, killer, DTHSZ); + (t0->death)[DTHSZ] = 0; + (void) strcpy(t0->date, getdate()); + + /* assure minimum number of points */ + if (t0->points < POINTSMIN) + t0->points = 0; + + t1 = tt_head = newttentry(); + tprev = 0; + /* rank0: -1 undefined, 0 not_on_list, n n_th on list */ + for (rank = 1;;) { + if (fscanf(rfile, "%6s %d %d %d %d %d %ld %c%c %[^,],%[^\n]", + t1->date, &t1->uid, + &t1->level, &t1->maxlvl, + &t1->hp, &t1->maxhp, &t1->points, + &t1->plchar, &t1->sex, t1->name, t1->death) != 11 + || t1->points < POINTSMIN) + t1->points = 0; + if (rank0 < 0 && t1->points < t0->points) { + rank0 = rank++; + if (tprev == 0) + tt_head = t0; + else + tprev->tt_next = t0; + t0->tt_next = t1; + occ_cnt--; + flg++; /* ask for a rewrite */ + } else + tprev = t1; + if (t1->points == 0) + break; + if ( +#ifdef PERS_IS_UID + t1->uid == t0->uid && +#else + strncmp(t1->name, t0->name, NAMSZ) == 0 && +#endif /* PERS_IS_UID */ + t1->plchar == t0->plchar && --occ_cnt <= 0) { + if (rank0 < 0) { + rank0 = 0; + rank1 = rank; + HUP printf("You didn't beat your previous score of %ld points.\n\n", + t1->points); + } + if (occ_cnt < 0) { + flg++; + continue; + } + } + if (rank <= ENTRYMAX) { + t1 = t1->tt_next = newttentry(); + rank++; + } + if (rank > ENTRYMAX) { + t1->points = 0; + break; + } + } + if (flg) { /* rewrite record file */ + (void) fclose(rfile); + if (!(rfile = fopen(recfile, "w"))) { + HUP puts("Cannot write record file\n"); + goto unlock; + } + if (!done_stopprint) + if (rank0 > 0) { + if (rank0 <= 10) + puts("You made the top ten list!\n"); + else + printf("You reached the %d%s place on the top %d list.\n\n", + rank0, ordin(rank0), ENTRYMAX); + } + } + if (rank0 == 0) + rank0 = rank1; + if (rank0 <= 0) + rank0 = rank; + if (!done_stopprint) + outheader(); + t1 = tt_head; + for (rank = 1; t1->points != 0; rank++, t1 = t1->tt_next) { + if (flg) + fprintf(rfile, "%6s %d %d %d %d %d %ld %c%c %s,%s\n", + t1->date, t1->uid, + t1->level, t1->maxlvl, + t1->hp, t1->maxhp, t1->points, + t1->plchar, t1->sex, t1->name, t1->death); + if (done_stopprint) + continue; + if (rank > (int)flags.end_top && + (rank < rank0 - (int)flags.end_around || rank > rank0 + (int)flags.end_around) + && (!flags.end_own || +#ifdef PERS_IS_UID + t1->uid != t0->uid)) +#else + strncmp(t1->name, t0->name, NAMSZ))) +#endif /* PERS_IS_UID */ + continue; + if (rank == rank0 - (int)flags.end_around && + rank0 > (int)(flags.end_top + flags.end_around + 1) && + !flags.end_own) + (void) putchar('\n'); + if (rank != rank0) + (void) outentry(rank, t1, 0); + else if (!rank1) + (void) outentry(rank, t1, 1); + else { + int t0lth = outentry(0, t0, -1); + int t1lth = outentry(rank, t1, t0lth); + if (t1lth > t0lth) + t0lth = t1lth; + (void) outentry(0, t0, t0lth); + } + } + if (rank0 >= rank) + if (!done_stopprint) + (void) outentry(0, t0, 1); + (void) fclose(rfile); +unlock: + (void) unlink(reclock); +} + +void +outheader() +{ + char linebuf[BUFSZ]; + char *bp; + (void) strcpy(linebuf, "Number Points Name"); + bp = eos(linebuf); + while (bp < linebuf + COLNO - 9) + *bp++ = ' '; + (void) strcpy(bp, "Hp [max]"); + puts(linebuf); +} + +/* so>0: standout line; so=0: ordinary line; so<0: no output, return lth */ +int +outentry(int rank, struct toptenentry *t1, int so) +{ + boolean quit = FALSE, killed = FALSE, starv = FALSE; + char linebuf[BUFSZ]; + linebuf[0] = 0; + if (rank) + Sprintf(eos(linebuf), "%3d", rank); + else + Sprintf(eos(linebuf), " "); + Sprintf(eos(linebuf), " %6ld %8s", t1->points, t1->name); + if (t1->plchar == 'X') + Sprintf(eos(linebuf), " "); + else + Sprintf(eos(linebuf), "-%c ", t1->plchar); + if (!strncmp("escaped", t1->death, 7)) { + if (!strcmp(" (with amulet)", t1->death + 7)) + Sprintf(eos(linebuf), "escaped the dungeon with amulet"); + else + Sprintf(eos(linebuf), "escaped the dungeon [max level %d]", + t1->maxlvl); + } else { + if (!strncmp(t1->death, "quit", 4)) { + quit = TRUE; + if (t1->maxhp < 3 * t1->hp && t1->maxlvl < 4) + Sprintf(eos(linebuf), "cravenly gave up"); + else + Sprintf(eos(linebuf), "quit"); + } else if (!strcmp(t1->death, "choked")) + Sprintf(eos(linebuf), "choked on %s food", + (t1->sex == 'F') ? "her" : "his"); + else if (!strncmp(t1->death, "starv", 5)) + Sprintf(eos(linebuf), "starved to death"), starv = TRUE; + else + Sprintf(eos(linebuf), "was killed"), killed = TRUE; + Sprintf(eos(linebuf), " on%s level %d", + (killed || starv) ? "" : " dungeon", t1->level); + if (t1->maxlvl != t1->level) + Sprintf(eos(linebuf), " [max %d]", t1->maxlvl); + if (quit && t1->death[4]) + Sprintf(eos(linebuf), t1->death + 4); + } + if (killed) + Sprintf(eos(linebuf), " by %s%s", + (!strncmp(t1->death, "trick", 5) || !strncmp(t1->death, "the ", 4)) + ? "" : + strchr(vowels, *t1->death) ? "an " : "a ", + t1->death); + Sprintf(eos(linebuf), "."); + if (t1->maxhp) { + char *bp = eos(linebuf); + char hpbuf[10]; + int hppos; + Sprintf(hpbuf, (t1->hp > 0) ? itoa(t1->hp) : "-"); + hppos = COLNO - 7 - strlen(hpbuf); + if (bp <= linebuf + hppos) { + while (bp < linebuf + hppos) + *bp++ = ' '; + (void) strcpy(bp, hpbuf); + Sprintf(eos(bp), " [%d]", t1->maxhp); + } + } + if (so == 0) + puts(linebuf); + else if (so > 0) { + char *bp = eos(linebuf); + if (so >= COLNO) + so = COLNO - 1; + while (bp < linebuf + so) + *bp++ = ' '; + *bp = 0; + standoutbeg(); + fputs(linebuf, stdout); + standoutend(); + (void) putchar('\n'); + } + return (strlen(linebuf)); +} + +char * +itoa(a) + int a; +{ + static char buf[12]; + Sprintf(buf, "%d", a); + return (buf); +} + +const char * +ordin(n) + int n; +{ + int d = n % 10; + return ((d == 0 || d > 3 || n / 10 == 1) ? "th" : (d == 1) ? "st" : + (d == 2) ? "nd" : "rd"); +} + +void +clearlocks() +{ + int x; + (void) signal(SIGHUP, SIG_IGN); + for (x = maxdlevel; x >= 0; x--) { + glo(x); + (void) unlink(lock); /* not all levels need be present */ + } +} + +#ifdef NOSAVEONHANGUP +/*ARGSUSED*/ +void +hangup(n) + int n; +{ + (void) signal(SIGINT, SIG_IGN); + clearlocks(); + exit(1); +} +#endif /* NOSAVEONHANGUP */ + +char * +eos(s) + char *s; +{ + while (*s) + s++; + return (s); +} + +/* it is the callers responsibility to check that there is room for c */ +void +charcat(s, c) + char *s, c; +{ + while (*s) + s++; + *s++ = c; + *s = 0; +} + +/* + * Called with args from main if argc >= 0. In this case, list scores as + * requested. Otherwise, find scores for the current player (and list them + * if argc == -1). + */ +void +prscore(argc, argv) + int argc; + char **argv; +{ + char **players = NULL; + int playerct; + int rank; + struct toptenentry *t1, *t2; + const char *recfile = RECORD; + FILE *rfile; + int flg = 0; + int i; +#ifdef nonsense + long total_score = 0L; + char totchars[10]; + int totcharct = 0; +#endif /* nonsense */ + int outflg = (argc >= -1); +#ifdef PERS_IS_UID + int uid = -1; +#else + char *player0; +#endif /* PERS_IS_UID */ + + if (!(rfile = fopen(recfile, "r"))) { + puts("Cannot open record file!"); + return; + } + if (argc > 1 && !strncmp(argv[1], "-s", 2)) { + if (!argv[1][2]) { + argc--; + argv++; + } else if (!argv[1][3] && strchr("CFKSTWX", argv[1][2])) { + argv[1]++; + argv[1][0] = '-'; + } else + argv[1] += 2; + } + if (argc <= 1) { +#ifdef PERS_IS_UID + uid = getuid(); + playerct = 0; +#else + player0 = plname; + if (!*player0) + player0 = "hackplayer"; + playerct = 1; + players = &player0; +#endif /* PERS_IS_UID */ + } else { + playerct = --argc; + players = ++argv; + } + if (outflg) + putchar('\n'); + + t1 = tt_head = newttentry(); + for (rank = 1;; rank++) { + if (fscanf(rfile, "%6s %d %d %d %d %d %ld %c%c %[^,],%[^\n]", + t1->date, &t1->uid, + &t1->level, &t1->maxlvl, + &t1->hp, &t1->maxhp, &t1->points, + &t1->plchar, &t1->sex, t1->name, t1->death) != 11) + t1->points = 0; + if (t1->points == 0) + break; +#ifdef PERS_IS_UID + if (!playerct && t1->uid == uid) + flg++; + else +#endif /* PERS_IS_UID */ + for (i = 0; i < playerct; i++) { + if (strcmp(players[i], "all") == 0 || + strncmp(t1->name, players[i], NAMSZ) == 0 || + (players[i][0] == '-' && + players[i][1] == t1->plchar && + players[i][2] == 0) || + (digit(players[i][0]) && rank <= atoi(players[i]))) + flg++; + } + t1 = t1->tt_next = newttentry(); + } + (void) fclose(rfile); + if (!flg) { + if (outflg) { + printf("Cannot find any entries for "); + if (playerct < 1) + printf("you.\n"); + else { + if (playerct > 1) + printf("any of "); + for (i = 0; i < playerct; i++) + printf("%s%s", players[i], (i < playerct - 1) ? ", " : ".\n"); + printf("Call is: %s -s [playernames]\n", hname); + } + } + return; + } + if (outflg) + outheader(); + t1 = tt_head; + for (rank = 1; t1->points != 0; rank++, t1 = t2) { + t2 = t1->tt_next; +#ifdef PERS_IS_UID + if (!playerct && t1->uid == uid) + goto outwithit; + else +#endif /* PERS_IS_UID */ + for (i = 0; i < playerct; i++) { + if (strcmp(players[i], "all") == 0 || + strncmp(t1->name, players[i], NAMSZ) == 0 || + (players[i][0] == '-' && + players[i][1] == t1->plchar && + players[i][2] == 0) || + (digit(players[i][0]) && rank <= atoi(players[i]))) { + outwithit: + if (outflg) + (void) outentry(rank, t1, 0); +#ifdef nonsense + total_score += t1->points; + if (totcharct < sizeof(totchars) - 1) + totchars[totcharct++] = t1->plchar; +#endif /* nonsense */ + break; + } + } + free((char *) t1); + } +#ifdef nonsense + totchars[totcharct] = 0; + + /* + * We would like to determine whether he is experienced. However, the + * information collected here only tells about the scores/roles that + * got into the topten (top 100?). We should maintain a .hacklog or + * something in his home directory. + */ + flags.beginner = (total_score < 6000); + for (i = 0; i < 6; i++) + if (!strchr(totchars, "CFKSTWX"[i])) { + flags.beginner = 1; + if (!pl_character[0]) + pl_character[0] = "CFKSTWX"[i]; + break; + } +#endif /* nonsense */ +} diff --git a/hack/hack.engrave.c b/hack/hack.engrave.c new file mode 100644 index 0000000..89d8105 --- /dev/null +++ b/hack/hack.engrave.c @@ -0,0 +1,403 @@ +/* $NetBSD: hack.engrave.c,v 1.5 2001/03/25 20:44:00 jsm Exp $ */ + +/* + * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica, + * Amsterdam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - 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. + * + * - Neither the name of the Stichting Centrum voor Wiskunde en + * Informatica, 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER + * 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. + */ + +/* + * Copyright (c) 1982 Jay Fenlason + * 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. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``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 +#ifndef lint +__RCSID("$NetBSD: hack.engrave.c,v 1.5 2001/03/25 20:44:00 jsm Exp $"); +#endif /* not lint */ + +#include +#include "hack.h" +#include "extern.h" + +struct engr { + struct engr *nxt_engr; + char *engr_txt; + xchar engr_x, engr_y; + unsigned engr_lth; /* for save & restore; not length of + * text */ + long engr_time; /* moment engraving was (will be) + * finished */ + xchar engr_type; +#define DUST 1 +#define ENGRAVE 2 +#define BURN 3 +} *head_engr; + +struct engr * +engr_at(x, y) + xchar x, y; +{ + struct engr *ep = head_engr; + while (ep) { + if (x == ep->engr_x && y == ep->engr_y) + return (ep); + ep = ep->nxt_engr; + } + return ((struct engr *) 0); +} + +int +sengr_at(s, x, y) + const char *s; + xchar x, y; +{ + struct engr *ep = engr_at(x, y); + char *t; + int n; + if (ep && ep->engr_time <= moves) { + t = ep->engr_txt; + /* + if(!strcmp(s,t)) return(1); + */ + n = strlen(s); + while (*t) { + if (!strncmp(s, t, n)) + return (1); + t++; + } + } + return (0); +} + +void +u_wipe_engr(cnt) + int cnt; +{ + if (!u.uswallow && !Levitation) + wipe_engr_at(u.ux, u.uy, cnt); +} + +void +wipe_engr_at(x, y, cnt) + xchar x, y, cnt; +{ + struct engr *ep = engr_at(x, y); + int lth, pos; + char ch; + if (ep) { + if ((ep->engr_type != DUST) || Levitation) { + cnt = rn2(1 + 50 / (cnt + 1)) ? 0 : 1; + } + lth = strlen(ep->engr_txt); + if (lth && cnt > 0) { + while (cnt--) { + pos = rn2(lth); + if ((ch = ep->engr_txt[pos]) == ' ') + continue; + ep->engr_txt[pos] = (ch != '?') ? '?' : ' '; + } + } + while (lth && ep->engr_txt[lth - 1] == ' ') + ep->engr_txt[--lth] = 0; + while (ep->engr_txt[0] == ' ') + ep->engr_txt++; + if (!ep->engr_txt[0]) + del_engr(ep); + } +} + +void +read_engr_at(x, y) + int x, y; +{ + struct engr *ep = engr_at(x, y); + if (ep && ep->engr_txt[0]) { + switch (ep->engr_type) { + case DUST: + pline("Something is written here in the dust."); + break; + case ENGRAVE: + pline("Something is engraved here on the floor."); + break; + case BURN: + pline("Some text has been burned here in the floor."); + break; + default: + impossible("Something is written in a very strange way."); + } + pline("You read: \"%s\".", ep->engr_txt); + } +} + +void +make_engr_at(x, y, s) + int x, y; + const char *s; +{ + struct engr *ep; + + if ((ep = engr_at(x, y)) != NULL) + del_engr(ep); + ep = (struct engr *) + alloc((unsigned) (sizeof(struct engr) + strlen(s) + 1)); + ep->nxt_engr = head_engr; + head_engr = ep; + ep->engr_x = x; + ep->engr_y = y; + ep->engr_txt = (char *) (ep + 1); + (void) strcpy(ep->engr_txt, s); + ep->engr_time = 0; + ep->engr_type = DUST; + ep->engr_lth = strlen(s) + 1; +} + +int +doengrave() +{ + int len; + char *sp; + struct engr *ep, *oep = engr_at(u.ux, u.uy); + char buf[BUFSZ]; + xchar type; + int spct; /* number of leading spaces */ + struct obj *otmp; + multi = 0; + + if (u.uswallow) { + pline("You're joking. Hahaha!"); /* riv05!a3 */ + return (0); + } + /* one may write with finger, weapon or wand */ + otmp = getobj("#-)/", "write with"); + if (!otmp) + return (0); + + if (otmp == &zeroobj) + otmp = 0; + if (otmp && otmp->otyp == WAN_FIRE && otmp->spe) { + type = BURN; + otmp->spe--; + } else { + /* first wield otmp */ + if (otmp != uwep) { + if (uwep && uwep->cursed) { + /* Andreas Bormann */ + pline("Since your weapon is welded to your hand,"); + pline("you use the %s.", aobjnam(uwep, (char *) 0)); + otmp = uwep; + } else { + if (!otmp) + pline("You are now empty-handed."); + else if (otmp->cursed) + pline("The %s %s to your hand!", + aobjnam(otmp, "weld"), + (otmp->quan == 1) ? "itself" : "themselves"); + else + pline("You now wield %s.", doname(otmp)); + setuwep(otmp); + } + } + if (!otmp) + type = DUST; + else if (otmp->otyp == DAGGER || otmp->otyp == TWO_HANDED_SWORD || + otmp->otyp == CRYSKNIFE || + otmp->otyp == LONG_SWORD || otmp->otyp == AXE) { + type = ENGRAVE; + if ((int) otmp->spe <= -3) { + type = DUST; + pline("Your %s too dull for engraving.", + aobjnam(otmp, "are")); + if (oep && oep->engr_type != DUST) + return (1); + } + } else + type = DUST; + } + if (Levitation && type != BURN) { /* riv05!a3 */ + pline("You can't reach the floor!"); + return (1); + } + if (oep && oep->engr_type == DUST) { + pline("You wipe out the message that was written here."); + del_engr(oep); + oep = 0; + } + if (type == DUST && oep) { + pline("You cannot wipe out the message that is %s in the rock.", + (oep->engr_type == BURN) ? "burned" : "engraved"); + return (1); + } + pline("What do you want to %s on the floor here? ", + (type == ENGRAVE) ? "engrave" : (type == BURN) ? "burn" : "write"); + getlin(buf); + clrlin(); + spct = 0; + sp = buf; + while (*sp == ' ') + spct++, sp++; + len = strlen(sp); + if (!len || *buf == '\033') { + if (type == BURN) + otmp->spe++; + return (0); + } + switch (type) { + case DUST: + case BURN: + if (len > 15) { + multi = -(len / 10); + nomovemsg = "You finished writing."; + } + break; + case ENGRAVE: /* here otmp != 0 */ + { + int len2 = (otmp->spe + 3) * 2 + 1; + + pline("Your %s dull.", aobjnam(otmp, "get")); + if (len2 < len) { + len = len2; + sp[len] = 0; + otmp->spe = -3; + nomovemsg = "You cannot engrave more."; + } else { + otmp->spe -= len / 2; + nomovemsg = "You finished engraving."; + } + multi = -len; + } + break; + } + if (oep) + len += strlen(oep->engr_txt) + spct; + ep = (struct engr *) alloc((unsigned) (sizeof(struct engr) + len + 1)); + ep->nxt_engr = head_engr; + head_engr = ep; + ep->engr_x = u.ux; + ep->engr_y = u.uy; + sp = (char *) (ep + 1); /* (char *)ep + sizeof(struct engr) */ + ep->engr_txt = sp; + if (oep) { + (void) strcpy(sp, oep->engr_txt); + (void) strcat(sp, buf); + del_engr(oep); + } else + (void) strcpy(sp, buf); + ep->engr_lth = len + 1; + ep->engr_type = type; + ep->engr_time = moves - multi; + + /* kludge to protect pline against excessively long texts */ + if (len > BUFSZ - 20) + sp[BUFSZ - 20] = 0; + + return (1); +} + +void +save_engravings(fd) + int fd; +{ + struct engr *ep = head_engr; + while (ep) { + if (!ep->engr_lth || !ep->engr_txt[0]) { + ep = ep->nxt_engr; + continue; + } + bwrite(fd, (char *) &(ep->engr_lth), sizeof(ep->engr_lth)); + bwrite(fd, (char *) ep, sizeof(struct engr) + ep->engr_lth); + ep = ep->nxt_engr; + } + bwrite(fd, (char *) nul, sizeof(unsigned)); + head_engr = 0; +} + +void +rest_engravings(fd) + int fd; +{ + struct engr *ep; + unsigned lth; + head_engr = 0; + while (1) { + mread(fd, (char *) <h, sizeof(unsigned)); + if (lth == 0) + return; + ep = (struct engr *) alloc(sizeof(struct engr) + lth); + mread(fd, (char *) ep, sizeof(struct engr) + lth); + ep->nxt_engr = head_engr; + ep->engr_txt = (char *) (ep + 1); /* Andreas Bormann */ + head_engr = ep; + } +} + +void +del_engr(ep) + struct engr *ep; +{ + struct engr *ept; + if (ep == head_engr) + head_engr = ep->nxt_engr; + else { + for (ept = head_engr; ept; ept = ept->nxt_engr) { + if (ept->nxt_engr == ep) { + ept->nxt_engr = ep->nxt_engr; + goto fnd; + } + } + impossible("Error in del_engr?"); + return; +fnd: ; + } + free((char *) ep); +} diff --git a/hack/hack.fight.c b/hack/hack.fight.c new file mode 100644 index 0000000..7d16031 --- /dev/null +++ b/hack/hack.fight.c @@ -0,0 +1,468 @@ +/* $NetBSD: hack.fight.c,v 1.5 2001/03/25 20:44:00 jsm Exp $ */ + +/* + * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica, + * Amsterdam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - 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. + * + * - Neither the name of the Stichting Centrum voor Wiskunde en + * Informatica, 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER + * 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. + */ + +/* + * Copyright (c) 1982 Jay Fenlason + * 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. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``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 +#ifndef lint +__RCSID("$NetBSD: hack.fight.c,v 1.5 2001/03/25 20:44:00 jsm Exp $"); +#endif /* not lint */ + +#include "hack.h" +#include "extern.h" + +static boolean far_noise; +static long noisetime; + +/* hitmm returns 0 (miss), 1 (hit), or 2 (kill) */ +int +hitmm(magr, mdef) + struct monst *magr, *mdef; +{ + const struct permonst *pa = magr->data, *pd = mdef->data; + int hit; + schar tmp; + boolean vis; + if (strchr("Eauy", pa->mlet)) + return (0); + if (magr->mfroz) + return (0); /* riv05!a3 */ + tmp = pd->ac + pa->mlevel; + if (mdef->mconf || mdef->mfroz || mdef->msleep) { + tmp += 4; + if (mdef->msleep) + mdef->msleep = 0; + } + hit = (tmp > rnd(20)); + if (hit) + mdef->msleep = 0; + vis = (cansee(magr->mx, magr->my) && cansee(mdef->mx, mdef->my)); + if (vis) { + char buf[BUFSZ]; + if (mdef->mimic) + seemimic(mdef); + if (magr->mimic) + seemimic(magr); + (void) sprintf(buf, "%s %s", Monnam(magr), + hit ? "hits" : "misses"); + pline("%s %s.", buf, monnam(mdef)); + } else { + boolean far = (dist(magr->mx, magr->my) > 15); + if (far != far_noise || moves - noisetime > 10) { + far_noise = far; + noisetime = moves; + pline("You hear some noises%s.", + far ? " in the distance" : ""); + } + } + if (hit) { + if (magr->data->mlet == 'c' && !magr->cham) { + magr->mhpmax += 3; + if (vis) + pline("%s is turned to stone!", Monnam(mdef)); + else if (mdef->mtame) + pline("You have a peculiarly sad feeling for a moment, then it passes."); + monstone(mdef); + hit = 2; + } else if ((mdef->mhp -= d(pa->damn, pa->damd)) < 1) { + magr->mhpmax += 1 + rn2(pd->mlevel + 1); + if (magr->mtame && magr->mhpmax > 8 * pa->mlevel) { + if (pa == &li_dog) + magr->data = pa = &dog; + else if (pa == &dog) + magr->data = pa = &la_dog; + } + if (vis) + pline("%s is killed!", Monnam(mdef)); + else if (mdef->mtame) + pline("You have a sad feeling for a moment, then it passes."); + mondied(mdef); + hit = 2; + } + } + return (hit); +} + +/* drop (perhaps) a cadaver and remove monster */ +void +mondied(mdef) + struct monst *mdef; +{ + const struct permonst *pd = mdef->data; + if (letter(pd->mlet) && rn2(3)) { + (void) mkobj_at(pd->mlet, mdef->mx, mdef->my); + if (cansee(mdef->mx, mdef->my)) { + unpmon(mdef); + atl(mdef->mx, mdef->my, fobj->olet); + } + stackobj(fobj); + } + mondead(mdef); +} + +/* drop a rock and remove monster */ +void +monstone(mdef) + struct monst *mdef; +{ + if (strchr(mlarge, mdef->data->mlet)) + mksobj_at(ENORMOUS_ROCK, mdef->mx, mdef->my); + else + mksobj_at(ROCK, mdef->mx, mdef->my); + if (cansee(mdef->mx, mdef->my)) { + unpmon(mdef); + atl(mdef->mx, mdef->my, fobj->olet); + } + mondead(mdef); +} + + +int +fightm(mtmp) + struct monst *mtmp; +{ + struct monst *mon; + for (mon = fmon; mon; mon = mon->nmon) + if (mon != mtmp) { + if (DIST(mon->mx, mon->my, mtmp->mx, mtmp->my) < 3) + if (rn2(4)) + return (hitmm(mtmp, mon)); + } + return (-1); +} + +/* u is hit by sth, but not a monster */ +int +thitu(tlev, dam, name) + int tlev, dam; + const char *name; +{ + char buf[BUFSZ]; + setan(name, buf); + if (u.uac + tlev <= rnd(20)) { + if (Blind) + pline("It misses."); + else + pline("You are almost hit by %s!", buf); + return (0); + } else { + if (Blind) + pline("You are hit!"); + else + pline("You are hit by %s!", buf); + losehp(dam, name); + return (1); + } +} + +char mlarge[] = "bCDdegIlmnoPSsTUwY',&"; + +boolean +hmon(mon, obj, thrown) /* return TRUE if mon still alive */ + struct monst *mon; + struct obj *obj; + int thrown; +{ + int tmp; + boolean hittxt = FALSE; + + if (!obj) { + tmp = rnd(2); /* attack with bare hands */ + if (mon->data->mlet == 'c' && !uarmg) { + pline("You hit the cockatrice with your bare hands."); + pline("You turn to stone ..."); + done_in_by(mon); + } + } else if (obj->olet == WEAPON_SYM || obj->otyp == PICK_AXE) { + if (obj == uwep && (obj->otyp > SPEAR || obj->otyp < BOOMERANG)) + tmp = rnd(2); + else { + if (strchr(mlarge, mon->data->mlet)) { + tmp = rnd(objects[obj->otyp].wldam); + if (obj->otyp == TWO_HANDED_SWORD) + tmp += d(2, 6); + else if (obj->otyp == FLAIL) + tmp += rnd(4); + } else { + tmp = rnd(objects[obj->otyp].wsdam); + } + tmp += obj->spe; + if (!thrown && obj == uwep && obj->otyp == BOOMERANG + && !rn2(3)) { + pline("As you hit %s, the boomerang breaks into splinters.", + monnam(mon)); + freeinv(obj); + setworn((struct obj *) 0, obj->owornmask); + obfree(obj, (struct obj *) 0); + tmp++; + } + } + if (mon->data->mlet == 'O' && obj->otyp == TWO_HANDED_SWORD && + !strcmp(ONAME(obj), "Orcrist")) + tmp += rnd(10); + } else + switch (obj->otyp) { + case HEAVY_IRON_BALL: + tmp = rnd(25); + break; + case EXPENSIVE_CAMERA: + pline("You succeed in destroying your camera. Congratulations!"); + freeinv(obj); + if (obj->owornmask) + setworn((struct obj *) 0, obj->owornmask); + obfree(obj, (struct obj *) 0); + return (TRUE); + case DEAD_COCKATRICE: + pline("You hit %s with the cockatrice corpse.", + monnam(mon)); + if (mon->data->mlet == 'c') { + tmp = 1; + hittxt = TRUE; + break; + } + pline("%s is turned to stone!", Monnam(mon)); + killed(mon); + return (FALSE); + case CLOVE_OF_GARLIC: /* no effect against demons */ + if (strchr(UNDEAD, mon->data->mlet)) + mon->mflee = 1; + tmp = 1; + break; + default: + /* non-weapons can damage because of their weight */ + /* (but not too much) */ + tmp = obj->owt / 10; + if (tmp < 1) + tmp = 1; + else + tmp = rnd(tmp); + if (tmp > 6) + tmp = 6; + } + + /****** NOTE: perhaps obj is undefined!! (if !thrown && BOOMERANG) */ + + tmp += u.udaminc + dbon(); + if (u.uswallow) { + if ((tmp -= u.uswldtim) <= 0) { + pline("Your arms are no longer able to hit."); + return (TRUE); + } + } + if (tmp < 1) + tmp = 1; + mon->mhp -= tmp; + if (mon->mhp < 1) { + killed(mon); + return (FALSE); + } + if (mon->mtame && (!mon->mflee || mon->mfleetim)) { + mon->mflee = 1; /* Rick Richardson */ + mon->mfleetim += 10 * rnd(tmp); + } + if (!hittxt) { + if (thrown) + /* this assumes that we cannot throw plural things */ + hit(xname(obj) /* or: objects[obj->otyp].oc_name */ , + mon, exclam(tmp)); + else if (Blind) + pline("You hit it."); + else + pline("You hit %s%s", monnam(mon), exclam(tmp)); + } + if (u.umconf && !thrown) { + if (!Blind) { + pline("Your hands stop glowing blue."); + if (!mon->mfroz && !mon->msleep) + pline("%s appears confused.", Monnam(mon)); + } + mon->mconf = 1; + u.umconf = 0; + } + return (TRUE); /* mon still alive */ +} + +/* try to attack; return FALSE if monster evaded */ +/* u.dx and u.dy must be set */ +int +attack(mtmp) + struct monst *mtmp; +{ + schar tmp; + boolean malive = TRUE; + const struct permonst *mdat; + mdat = mtmp->data; + + u_wipe_engr(3); /* andrew@orca: prevent unlimited pick-axe + * attacks */ + + if (mdat->mlet == 'L' && !mtmp->mfroz && !mtmp->msleep && + !mtmp->mconf && mtmp->mcansee && !rn2(7) && + (m_move(mtmp, 0) == 2 /* he died */ || /* he moved: */ + mtmp->mx != u.ux + u.dx || mtmp->my != u.uy + u.dy)) + return (FALSE); + + if (mtmp->mimic) { + if (!u.ustuck && !mtmp->mflee) + u.ustuck = mtmp; + switch (levl[u.ux + u.dx][u.uy + u.dy].scrsym) { + case '+': + pline("The door actually was a Mimic."); + break; + case '$': + pline("The chest was a Mimic!"); + break; + default: + pline("Wait! That's a Mimic!"); + } + wakeup(mtmp); /* clears mtmp->mimic */ + return (TRUE); + } + wakeup(mtmp); + + if (mtmp->mhide && mtmp->mundetected) { + struct obj *obj; + + mtmp->mundetected = 0; + if ((obj = o_at(mtmp->mx, mtmp->my)) && !Blind) + pline("Wait! There's a %s hiding under %s!", + mdat->mname, doname(obj)); + return (TRUE); + } + tmp = u.uluck + u.ulevel + mdat->ac + abon(); + if (uwep) { + if (uwep->olet == WEAPON_SYM || uwep->otyp == PICK_AXE) + tmp += uwep->spe; + if (uwep->otyp == TWO_HANDED_SWORD) + tmp -= 1; + else if (uwep->otyp == DAGGER) + tmp += 2; + else if (uwep->otyp == CRYSKNIFE) + tmp += 3; + else if (uwep->otyp == SPEAR && + strchr("XDne", mdat->mlet)) + tmp += 2; + } + if (mtmp->msleep) { + mtmp->msleep = 0; + tmp += 2; + } + if (mtmp->mfroz) { + tmp += 4; + if (!rn2(10)) + mtmp->mfroz = 0; + } + if (mtmp->mflee) + tmp += 2; + if (u.utrap) + tmp -= 3; + + /* with a lot of luggage, your agility diminishes */ + tmp -= (inv_weight() + 40) / 20; + + if (tmp <= rnd(20) && !u.uswallow) { + if (Blind) + pline("You miss it."); + else + pline("You miss %s.", monnam(mtmp)); + } else { + /* we hit the monster; be careful: it might die! */ + + if ((malive = hmon(mtmp, uwep, 0)) == TRUE) { + /* monster still alive */ + if (!rn2(25) && mtmp->mhp < mtmp->mhpmax / 2) { + mtmp->mflee = 1; + if (!rn2(3)) + mtmp->mfleetim = rnd(100); + if (u.ustuck == mtmp && !u.uswallow) + u.ustuck = 0; + } +#ifndef NOWORM + if (mtmp->wormno) + cutworm(mtmp, u.ux + u.dx, u.uy + u.dy, + uwep ? uwep->otyp : 0); +#endif /* NOWORM */ + } + if (mdat->mlet == 'a') { + if (rn2(2)) { + pline("You are splashed by the blob's acid!"); + losehp_m(rnd(6), mtmp); + if (!rn2(30)) + corrode_armor(); + } + if (!rn2(6)) + corrode_weapon(); + } + } + if (malive && mdat->mlet == 'E' && canseemon(mtmp) + && !mtmp->mcan && rn2(3)) { + if (mtmp->mcansee) { + pline("You are frozen by the floating eye's gaze!"); + nomul((u.ulevel > 6 || rn2(4)) ? rn1(20, -21) : -200); + } else { + pline("The blinded floating eye cannot defend itself."); + if (!rn2(500)) + if ((int) u.uluck > LUCKMIN) + u.uluck--; + } + } + return (TRUE); +} diff --git a/hack/hack.h b/hack/hack.h new file mode 100644 index 0000000..5110f3f --- /dev/null +++ b/hack/hack.h @@ -0,0 +1,249 @@ +/* $NetBSD: hack.h,v 1.8 2001/03/25 20:44:00 jsm Exp $ */ + +/* + * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica, + * Amsterdam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - 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. + * + * - Neither the name of the Stichting Centrum voor Wiskunde en + * Informatica, 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER + * 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. + */ + +/* + * Copyright (c) 1982 Jay Fenlason + * 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. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``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. + */ + +#ifndef _HACK_H_ +#define _HACK_H_ + +#include "config.h" +#include +#include + +#ifndef BSD +#define index strchr +#define rindex strrchr +#endif /* BSD */ + +#define Null(type) ((struct type *) 0) + +#include "def.objclass.h" + +typedef struct { + xchar x,y; +} coord; + +#include "def.monst.h" /* uses coord */ +#include "def.gold.h" +#include "def.trap.h" +#include "def.obj.h" +#include "def.flag.h" + +#define plur(x) (((x) == 1) ? "" : "s") + +#define BUFSZ 256 /* for getlin buffers */ +#define PL_NSIZ 32 /* name of player, ghost, shopkeeper */ + +#include "def.rm.h" +#include "def.permonst.h" + +#define newstring(x) (char *) alloc((unsigned)(x)) +#include "hack.onames.h" + +#define ON 1 +#define OFF 0 + +struct prop { +#define TIMEOUT 007777 /* mask */ +#define LEFT_RING W_RINGL /* 010000L */ +#define RIGHT_RING W_RINGR /* 020000L */ +#define INTRINSIC 040000L +#define LEFT_SIDE LEFT_RING +#define RIGHT_SIDE RIGHT_RING +#define BOTH_SIDES (LEFT_SIDE | RIGHT_SIDE) + long p_flgs; + void (*p_tofn) __P((void)); /* called after timeout */ +}; + +struct you { + xchar ux, uy; + schar dx, dy, dz; /* direction of move (or zap or ... ) */ +#ifdef QUEST + schar di; /* direction of FF */ + xchar ux0, uy0; /* initial position FF */ +#endif /* QUEST */ + xchar udisx, udisy; /* last display pos */ + char usym; /* usually '@' */ + schar uluck; +#define LUCKMAX 10 /* on moonlit nights 11 */ +#define LUCKMIN (-10) + int last_str_turn:3; /* 0: none, 1: half turn, 2: full turn */ + /* +: turn right, -: turn left */ + unsigned udispl:1; /* @ on display */ + unsigned ulevel:4; /* 1 - 14 */ +#ifdef QUEST + unsigned uhorizon:7; +#endif /* QUEST */ + unsigned utrap:3; /* trap timeout */ + unsigned utraptype:1; /* defined if utrap nonzero */ +#define TT_BEARTRAP 0 +#define TT_PIT 1 + unsigned uinshop:6; /* used only in shk.c - (roomno+1) of shop */ + + +/* perhaps these #define's should also be generated by makedefs */ +#define TELEPAT LAST_RING /* not a ring */ +#define Telepat u.uprops[TELEPAT].p_flgs +#define FAST (LAST_RING+1) /* not a ring */ +#define Fast u.uprops[FAST].p_flgs +#define CONFUSION (LAST_RING+2) /* not a ring */ +#define Confusion u.uprops[CONFUSION].p_flgs +#define INVIS (LAST_RING+3) /* not a ring */ +#define Invis u.uprops[INVIS].p_flgs +#define Invisible (Invis && !See_invisible) +#define GLIB (LAST_RING+4) /* not a ring */ +#define Glib u.uprops[GLIB].p_flgs +#define PUNISHED (LAST_RING+5) /* not a ring */ +#define Punished u.uprops[PUNISHED].p_flgs +#define SICK (LAST_RING+6) /* not a ring */ +#define Sick u.uprops[SICK].p_flgs +#define BLIND (LAST_RING+7) /* not a ring */ +#define Blind u.uprops[BLIND].p_flgs +#define WOUNDED_LEGS (LAST_RING+8) /* not a ring */ +#define Wounded_legs u.uprops[WOUNDED_LEGS].p_flgs +#define STONED (LAST_RING+9) /* not a ring */ +#define Stoned u.uprops[STONED].p_flgs +#define PROP(x) (x-RIN_ADORNMENT) /* convert ring to index in uprops */ + unsigned umconf:1; + const char *usick_cause; + struct prop uprops[LAST_RING+10]; + + unsigned uswallow:1; /* set if swallowed by a monster */ + unsigned uswldtim:4; /* time you have been swallowed */ + unsigned uhs:3; /* hunger state - see hack.eat.c */ + schar ustr,ustrmax; + schar udaminc; + schar uac; + int uhp,uhpmax; + long int ugold,ugold0,uexp,urexp; + int uhunger; /* refd only in eat.c and shk.c */ + int uinvault; + struct monst *ustuck; + int nr_killed[CMNUM+2]; /* used for experience bookkeeping */ +}; + +#define DIST(x1,y1,x2,y2) (((x1)-(x2))*((x1)-(x2)) + ((y1)-(y2))*((y1)-(y2))) + +#define PL_CSIZ 20 /* sizeof pl_character */ +#define MAX_CARR_CAP 120 /* so that boulders can be heavier */ +#define MAXLEVEL 40 +#define FAR (COLNO+2) /* position outside screen */ + +extern boolean in_mklev; +extern boolean level_exists[]; +extern boolean restoring; +extern char *CD; +extern const char *catmore; +extern char *hname; +extern const char *const hu_stat[]; /* in eat.c */ +extern const char *nomovemsg; +extern const char *occtxt; +extern char *save_cm; +extern const char *killer; +extern const char *const traps[]; +extern char SAVEF[]; +extern char fut_geno[60]; /* idem */ +extern char genocided[60]; /* defined in Decl.c */ +extern char lock[]; +extern char mlarge[]; +extern char morc; +extern char nul[]; +extern char plname[PL_NSIZ], pl_character[PL_CSIZ]; +extern const char quitchars[]; +extern char sdir[]; /* defined in hack.c */ +extern const char shtypes[]; /* = "=/)%?!["; 8 types: 7 specialized, 1 mixed */ +extern const char vowels[]; +extern coord bhitpos; /* place where thrown weapon falls to the ground */ +extern int (*afternmv) __P((void)); +extern int (*occupation) __P((void)); +extern int CO, LI; /* usually COLNO and ROWNO+2 */ +extern int bases[]; +extern int doorindex; +extern int hackpid; +extern int multi; +extern int nroom; +extern long moves; +extern long wailmsg; +extern schar xdir[], ydir[]; /* idem */ +extern struct monst *mydogs; +extern struct monst youmonst; +extern struct obj *billobjs; +extern struct obj *invent, *uwep, *uarm, *uarm2, *uarmh, *uarms, *uarmg; +extern struct obj *uleft, *uright, *fcobj; +extern struct obj *uball; /* defined if PUNISHED */ +extern struct obj *uchain; /* defined iff PUNISHED */ +extern struct obj zeroobj; +extern const struct permonst li_dog, dog, la_dog; +extern const struct permonst pm_eel; +extern const struct permonst pm_ghost; +extern const struct permonst pm_mail_daemon; +extern const struct permonst pm_wizard; +#ifndef NOWORM +extern long wgrowtime[32]; +extern struct wseg *m_atseg; +extern struct wseg *wsegs[32], *wheads[32]; +#endif +extern struct you u; +extern xchar curx, cury; /* cursor location on screen */ +extern xchar dlevel, maxdlevel; /* dungeon level */ +extern xchar seehx,seelx,seehy,seely; /* where to see*/ +extern xchar xdnstair, ydnstair, xupstair, yupstair; /* stairs up and down. */ +#endif /* _HACK_H_ */ diff --git a/hack/hack.invent.c b/hack/hack.invent.c new file mode 100644 index 0000000..a60cfe6 --- /dev/null +++ b/hack/hack.invent.c @@ -0,0 +1,1042 @@ +/* $NetBSD: hack.invent.c,v 1.7 2001/03/25 20:44:00 jsm Exp $ */ + +/* + * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica, + * Amsterdam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - 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. + * + * - Neither the name of the Stichting Centrum voor Wiskunde en + * Informatica, 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER + * 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. + */ + +/* + * Copyright (c) 1982 Jay Fenlason + * 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. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``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 +#ifndef lint +__RCSID("$NetBSD: hack.invent.c,v 1.7 2001/03/25 20:44:00 jsm Exp $"); +#endif /* not lint */ + +#include +#include "hack.h" +#include "extern.h" + +#ifndef NOWORM +#include "def.wseg.h" +#endif /* NOWORM */ + +#define NOINVSYM '#' + +static int lastinvnr = 51; /* 0 ... 51 */ + +static void assigninvlet __P((struct obj *)); +static char *xprname __P((struct obj *, char)); + +static void +assigninvlet(otmp) + struct obj *otmp; +{ + boolean inuse[52]; + int i; + struct obj *obj; + + for (i = 0; i < 52; i++) + inuse[i] = FALSE; + for (obj = invent; obj; obj = obj->nobj) + if (obj != otmp) { + i = obj->invlet; + if ('a' <= i && i <= 'z') + inuse[i - 'a'] = TRUE; + else if ('A' <= i && i <= 'Z') + inuse[i - 'A' + 26] = TRUE; + if (i == otmp->invlet) + otmp->invlet = 0; + } + if ((i = otmp->invlet) && + (('a' <= i && i <= 'z') || ('A' <= i && i <= 'Z'))) + return; + for (i = lastinvnr + 1; i != lastinvnr; i++) { + if (i == 52) { + i = -1; + continue; + } + if (!inuse[i]) + break; + } + otmp->invlet = (inuse[i] ? NOINVSYM : + (i < 26) ? ('a' + i) : ('A' + i - 26)); + lastinvnr = i; +} + +struct obj * +addinv(obj) + struct obj *obj; +{ + struct obj *otmp; + + /* merge or attach to end of chain */ + if (!invent) { + invent = obj; + otmp = 0; + } else + for (otmp = invent; /* otmp */ ; otmp = otmp->nobj) { + if (merged(otmp, obj, 0)) + return (otmp); + if (!otmp->nobj) { + otmp->nobj = obj; + break; + } + } + obj->nobj = 0; + + if (flags.invlet_constant) { + assigninvlet(obj); + /* + * The ordering of the chain is nowhere significant + * so in case you prefer some other order than the + * historical one, change the code below. + */ + if (otmp) { /* find proper place in chain */ + otmp->nobj = 0; + if ((invent->invlet ^ 040) > (obj->invlet ^ 040)) { + obj->nobj = invent; + invent = obj; + } else + for (otmp = invent;; otmp = otmp->nobj) { + if (!otmp->nobj || + (otmp->nobj->invlet ^ 040) > (obj->invlet ^ 040)) { + obj->nobj = otmp->nobj; + otmp->nobj = obj; + break; + } + } + } + } + return (obj); +} + +void +useup(obj) + struct obj *obj; +{ + if (obj->quan > 1) { + obj->quan--; + obj->owt = weight(obj); + } else { + setnotworn(obj); + freeinv(obj); + obfree(obj, (struct obj *) 0); + } +} + +void +freeinv(obj) + struct obj *obj; +{ + struct obj *otmp; + + if (obj == invent) + invent = invent->nobj; + else { + for (otmp = invent; otmp->nobj != obj; otmp = otmp->nobj) + if (!otmp->nobj) + panic("freeinv"); + otmp->nobj = obj->nobj; + } +} + +/* destroy object in fobj chain (if unpaid, it remains on the bill) */ +void +delobj(obj) + struct obj *obj; +{ + freeobj(obj); + unpobj(obj); + obfree(obj, (struct obj *) 0); +} + +/* unlink obj from chain starting with fobj */ +void +freeobj(obj) + struct obj *obj; +{ + struct obj *otmp; + + if (obj == fobj) + fobj = fobj->nobj; + else { + for (otmp = fobj; otmp->nobj != obj; otmp = otmp->nobj) + if (!otmp) + panic("error in freeobj"); + otmp->nobj = obj->nobj; + } +} + +/* Note: freegold throws away its argument! */ +void +freegold(gold) + struct gold *gold; +{ + struct gold *gtmp; + + if (gold == fgold) + fgold = gold->ngold; + else { + for (gtmp = fgold; gtmp->ngold != gold; gtmp = gtmp->ngold) + if (!gtmp) + panic("error in freegold"); + gtmp->ngold = gold->ngold; + } + free((char *) gold); +} + +void +deltrap(trap) + struct trap *trap; +{ + struct trap *ttmp; + + if (trap == ftrap) + ftrap = ftrap->ntrap; + else { + for (ttmp = ftrap; ttmp->ntrap != trap; ttmp = ttmp->ntrap); + ttmp->ntrap = trap->ntrap; + } + free((char *) trap); +} + +struct wseg *m_atseg; + +struct monst * +m_at(x, y) + int x, y; +{ + struct monst *mtmp; +#ifndef NOWORM + struct wseg *wtmp; +#endif /* NOWORM */ + + m_atseg = 0; + for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) { + if (mtmp->mx == x && mtmp->my == y) + return (mtmp); +#ifndef NOWORM + if (mtmp->wormno) { + for (wtmp = wsegs[mtmp->wormno]; wtmp; wtmp = wtmp->nseg) + if (wtmp->wx == x && wtmp->wy == y) { + m_atseg = wtmp; + return (mtmp); + } + } +#endif /* NOWORM */ + } + return (0); +} + +struct obj * +o_at(x, y) + int x, y; +{ + struct obj *otmp; + + for (otmp = fobj; otmp; otmp = otmp->nobj) + if (otmp->ox == x && otmp->oy == y) + return (otmp); + return (0); +} + +struct obj * +sobj_at(n, x, y) + int n, x, y; +{ + struct obj *otmp; + + for (otmp = fobj; otmp; otmp = otmp->nobj) + if (otmp->ox == x && otmp->oy == y && otmp->otyp == n) + return (otmp); + return (0); +} + +int +carried(obj) + struct obj *obj; +{ + struct obj *otmp; + for (otmp = invent; otmp; otmp = otmp->nobj) + if (otmp == obj) + return (1); + return (0); +} + +int +carrying(type) + int type; +{ + struct obj *otmp; + + for (otmp = invent; otmp; otmp = otmp->nobj) + if (otmp->otyp == type) + return (TRUE); + return (FALSE); +} + +struct obj * +o_on(id, objchn) + unsigned int id; + struct obj *objchn; +{ + while (objchn) { + if (objchn->o_id == id) + return (objchn); + objchn = objchn->nobj; + } + return ((struct obj *) 0); +} + +struct trap * +t_at(x, y) + int x, y; +{ + struct trap *trap = ftrap; + while (trap) { + if (trap->tx == x && trap->ty == y) + return (trap); + trap = trap->ntrap; + } + return (0); +} + +struct gold * +g_at(x, y) + int x, y; +{ + struct gold *gold = fgold; + while (gold) { + if (gold->gx == x && gold->gy == y) + return (gold); + gold = gold->ngold; + } + return (0); +} + +/* make dummy object structure containing gold - for temporary use only */ +struct obj * +mkgoldobj(q) + long q; +{ + struct obj *otmp; + + otmp = newobj(0); + /* should set o_id etc. but otmp will be freed soon */ + otmp->olet = '$'; + u.ugold -= q; + OGOLD(otmp) = q; + flags.botl = 1; + return (otmp); +} + +/* + * getobj returns: + * struct obj *xxx: object to do something with. + * (struct obj *) 0 error return: no object. + * &zeroobj explicitly no object (as in w-). + */ +struct obj * +getobj(let, word) + const char *let, *word; +{ + struct obj *otmp; + char ilet, ilet1, ilet2; + char buf[BUFSZ]; + char lets[BUFSZ]; + int foo = 0, foo2; + char *bp = buf; + xchar allowcnt = 0; /* 0, 1 or 2 */ + boolean allowgold = FALSE; + boolean allowall = FALSE; + boolean allownone = FALSE; + xchar foox = 0; + long cnt; + + if (*let == '0') + let++, allowcnt = 1; + if (*let == '$') + let++, allowgold = TRUE; + if (*let == '#') + let++, allowall = TRUE; + if (*let == '-') + let++, allownone = TRUE; + if (allownone) + *bp++ = '-'; + if (allowgold) + *bp++ = '$'; + if (bp > buf && bp[-1] == '-') + *bp++ = ' '; + + ilet = 'a'; + for (otmp = invent; otmp; otmp = otmp->nobj) { + if (!*let || strchr(let, otmp->olet)) { + bp[foo++] = flags.invlet_constant ? otmp->invlet : ilet; + + /* ugly check: remove inappropriate things */ + if ((!strcmp(word, "take off") && + !(otmp->owornmask & (W_ARMOR - W_ARM2))) + || (!strcmp(word, "wear") && + (otmp->owornmask & (W_ARMOR | W_RING))) + || (!strcmp(word, "wield") && + (otmp->owornmask & W_WEP))) { + foo--; + foox++; + } + } + if (ilet == 'z') + ilet = 'A'; + else + ilet++; + } + bp[foo] = 0; + if (foo == 0 && bp > buf && bp[-1] == ' ') + *--bp = 0; + (void) strcpy(lets, bp);/* necessary since we destroy buf */ + if (foo > 5) { /* compactify string */ + foo = foo2 = 1; + ilet2 = bp[0]; + ilet1 = bp[1]; + while ((ilet = bp[++foo2] = bp[++foo]) != '\0') { + if (ilet == ilet1 + 1) { + if (ilet1 == ilet2 + 1) + bp[foo2 - 1] = ilet1 = '-'; + else if (ilet2 == '-') { + bp[--foo2] = ++ilet1; + continue; + } + } + ilet2 = ilet1; + ilet1 = ilet; + } + } + if (!foo && !allowall && !allowgold && !allownone) { + pline("You don't have anything %sto %s.", + foox ? "else " : "", word); + return (0); + } + for (;;) { + if (!buf[0]) + pline("What do you want to %s [*]? ", word); + else + pline("What do you want to %s [%s or ?*]? ", + word, buf); + + cnt = 0; + ilet = readchar(); + while (digit(ilet) && allowcnt) { + if (cnt < 100000000) + cnt = 10 * cnt + (ilet - '0'); + else + cnt = 999999999; + allowcnt = 2; /* signal presence of cnt */ + ilet = readchar(); + } + if (digit(ilet)) { + pline("No count allowed with this command."); + continue; + } + if (strchr(quitchars, ilet)) + return ((struct obj *) 0); + if (ilet == '-') { + return (allownone ? &zeroobj : (struct obj *) 0); + } + if (ilet == '$') { + if (!allowgold) { + pline("You cannot %s gold.", word); + continue; + } + if (!(allowcnt == 2 && cnt < u.ugold)) + cnt = u.ugold; + return (mkgoldobj(cnt)); + } + if (ilet == '?') { + doinv(lets); + if (!(ilet = morc)) + continue; + /* he typed a letter (not a space) to more() */ + } else if (ilet == '*') { + doinv((char *) 0); + if (!(ilet = morc)) + continue; + /* ... */ + } + if (flags.invlet_constant) { + for (otmp = invent; otmp; otmp = otmp->nobj) + if (otmp->invlet == ilet) + break; + } else { + if (ilet >= 'A' && ilet <= 'Z') + ilet += 'z' - 'A' + 1; + ilet -= 'a'; + for (otmp = invent; otmp && ilet; + ilet--, otmp = otmp->nobj); + } + if (!otmp) { + pline("You don't have that object."); + continue; + } + if (cnt < 0 || otmp->quan < cnt) { + pline("You don't have that many! [You have %u]" + ,otmp->quan); + continue; + } + break; + } + if (!allowall && let && !strchr(let, otmp->olet)) { + pline("That is a silly thing to %s.", word); + return (0); + } + if (allowcnt == 2) { /* cnt given */ + if (cnt == 0) + return (0); + if (cnt != otmp->quan) { + struct obj *obj; + obj = splitobj(otmp, (int) cnt); + if (otmp == uwep) + setuwep(obj); + } + } + return (otmp); +} + +int +ckunpaid(otmp) + struct obj *otmp; +{ + return (otmp->unpaid); +} + +/* interactive version of getobj - used for Drop and Identify */ +/* return the number of times fn was called successfully */ +int +ggetobj(word, fn, max) + const char *word; + int (*fn) __P((struct obj *)); + int max; +{ + char buf[BUFSZ]; + char *ip; + char sym; + int oletct = 0, iletct = 0; + boolean allflag = FALSE; + char olets[20], ilets[20]; + int (*ckfn) __P((struct obj *)) = + (int (*) __P((struct obj *))) 0; + xchar allowgold = (u.ugold && !strcmp(word, "drop")) ? 1 : 0; /* BAH */ + if (!invent && !allowgold) { + pline("You have nothing to %s.", word); + return (0); + } else { + struct obj *otmp = invent; + int uflg = 0; + + if (allowgold) + ilets[iletct++] = '$'; + ilets[iletct] = 0; + while (otmp) { + if (!strchr(ilets, otmp->olet)) { + ilets[iletct++] = otmp->olet; + ilets[iletct] = 0; + } + if (otmp->unpaid) + uflg = 1; + otmp = otmp->nobj; + } + ilets[iletct++] = ' '; + if (uflg) + ilets[iletct++] = 'u'; + if (invent) + ilets[iletct++] = 'a'; + ilets[iletct] = 0; + } + pline("What kinds of thing do you want to %s? [%s] ", + word, ilets); + getlin(buf); + if (buf[0] == '\033') { + clrlin(); + return (0); + } + ip = buf; + olets[0] = 0; + while ((sym = *ip++) != '\0') { + if (sym == ' ') + continue; + if (sym == '$') { + if (allowgold == 1) + (*fn) (mkgoldobj(u.ugold)); + else if (!u.ugold) + pline("You have no gold."); + allowgold = 2; + } else if (sym == 'a' || sym == 'A') + allflag = TRUE; + else if (sym == 'u' || sym == 'U') + ckfn = ckunpaid; + else if (strchr("!%?[()=*/\"0", sym)) { + if (!strchr(olets, sym)) { + olets[oletct++] = sym; + olets[oletct] = 0; + } + } else + pline("You don't have any %c's.", sym); + } + if (allowgold == 2 && !oletct) + return (1); /* he dropped gold (or at least tried to) */ + else + return (askchain(invent, olets, allflag, fn, ckfn, max)); +} + +/* + * Walk through the chain starting at objchn and ask for all objects + * with olet in olets (if nonNULL) and satisfying ckfn (if nonNULL) + * whether the action in question (i.e., fn) has to be performed. + * If allflag then no questions are asked. Max gives the max nr of + * objects to be treated. Return the number of objects treated. + */ +int +askchain(objchn, olets, allflag, fn, ckfn, max) + struct obj *objchn; + char *olets; + int allflag; + int (*fn) __P((struct obj *)); + int (*ckfn) __P((struct obj *)); + int max; +{ + struct obj *otmp, *otmp2; + char sym, ilet; + int cnt = 0; + ilet = 'a' - 1; + for (otmp = objchn; otmp; otmp = otmp2) { + if (ilet == 'z') + ilet = 'A'; + else + ilet++; + otmp2 = otmp->nobj; + if (olets && *olets && !strchr(olets, otmp->olet)) + continue; + if (ckfn && !(*ckfn) (otmp)) + continue; + if (!allflag) { + pline(xprname(otmp, ilet)); + addtopl(" [nyaq]? "); + sym = readchar(); + } else + sym = 'y'; + + switch (sym) { + case 'a': + allflag = 1; + case 'y': + cnt += (*fn) (otmp); + if (--max == 0) + goto ret; + case 'n': + default: + break; + case 'q': + goto ret; + } + } + pline(cnt ? "That was all." : "No applicable objects."); +ret: + return (cnt); +} + +char +obj_to_let(obj) /* should of course only be called for things + * in invent */ + struct obj *obj; +{ + struct obj *otmp; + char ilet; + + if (flags.invlet_constant) + return (obj->invlet); + ilet = 'a'; + for (otmp = invent; otmp && otmp != obj; otmp = otmp->nobj) + if (++ilet > 'z') + ilet = 'A'; + return (otmp ? ilet : NOINVSYM); +} + +void +prinv(obj) + struct obj *obj; +{ + pline(xprname(obj, obj_to_let(obj))); +} + +static char * +xprname(obj, let) + struct obj *obj; + char let; +{ + static char li[BUFSZ]; + + (void) sprintf(li, "%c - %s.", + flags.invlet_constant ? obj->invlet : let, + doname(obj)); + return (li); +} + +int +ddoinv() +{ + doinv((char *) 0); + return (0); +} + +/* called with 0 or "": all objects in inventory */ +/* otherwise: all objects with (serial) letter in lets */ +void +doinv(lets) + char *lets; +{ + struct obj *otmp; + char ilet; + int ct = 0; + char any[BUFSZ]; + + morc = 0; /* just to be sure */ + + if (!invent) { + pline("Not carrying anything."); + return; + } + cornline(0, (char *) 0); + ilet = 'a'; + for (otmp = invent; otmp; otmp = otmp->nobj) { + if (flags.invlet_constant) + ilet = otmp->invlet; + if (!lets || !*lets || strchr(lets, ilet)) { + cornline(1, xprname(otmp, ilet)); + any[ct++] = ilet; + } + if (!flags.invlet_constant) + if (++ilet > 'z') + ilet = 'A'; + } + any[ct] = 0; + cornline(2, any); +} + +int +dotypeinv() +{ /* free after Robert Viduya */ + /* Changed to one type only, so he doesnt have to type cr */ + char c, ilet; + char stuff[BUFSZ]; + int stct; + struct obj *otmp; + boolean billx = inshop() && doinvbill(0); + boolean unpd = FALSE; + + if (!invent && !u.ugold && !billx) { + pline("You aren't carrying anything."); + return (0); + } + stct = 0; + if (u.ugold) + stuff[stct++] = '$'; + stuff[stct] = 0; + for (otmp = invent; otmp; otmp = otmp->nobj) { + if (!strchr(stuff, otmp->olet)) { + stuff[stct++] = otmp->olet; + stuff[stct] = 0; + } + if (otmp->unpaid) + unpd = TRUE; + } + if (unpd) + stuff[stct++] = 'u'; + if (billx) + stuff[stct++] = 'x'; + stuff[stct] = 0; + + if (stct > 1) { + pline("What type of object [%s] do you want an inventory of? ", + stuff); + c = readchar(); + if (strchr(quitchars, c)) + return (0); + } else + c = stuff[0]; + + if (c == '$') + return (doprgold()); + + if (c == 'x' || c == 'X') { + if (billx) + (void) doinvbill(1); + else + pline("No used-up objects on the shopping bill."); + return (0); + } + if ((c == 'u' || c == 'U') && !unpd) { + pline("You are not carrying any unpaid objects."); + return (0); + } + stct = 0; + ilet = 'a'; + for (otmp = invent; otmp; otmp = otmp->nobj) { + if (flags.invlet_constant) + ilet = otmp->invlet; + if (c == otmp->olet || (c == 'u' && otmp->unpaid)) + stuff[stct++] = ilet; + if (!flags.invlet_constant) + if (++ilet > 'z') + ilet = 'A'; + } + stuff[stct] = '\0'; + if (stct == 0) + pline("You have no such objects."); + else + doinv(stuff); + + return (0); +} + +/* look at what is here */ +int +dolook() +{ + struct obj *otmp = NULL, *otmp0 = NULL; + struct gold *gold = NULL; + const char *verb = Blind ? "feel" : "see"; + int ct = 0; + + if (!u.uswallow) { + if (Blind) { + pline("You try to feel what is lying here on the floor."); + if (Levitation) { /* ab@unido */ + pline("You cannot reach the floor!"); + return (1); + } + } + otmp0 = o_at(u.ux, u.uy); + gold = g_at(u.ux, u.uy); + } + if (u.uswallow || (!otmp0 && !gold)) { + pline("You %s no objects here.", verb); + return (!!Blind); + } + cornline(0, "Things that are here:"); + for (otmp = otmp0; otmp; otmp = otmp->nobj) { + if (otmp->ox == u.ux && otmp->oy == u.uy) { + ct++; + cornline(1, doname(otmp)); + if (Blind && otmp->otyp == DEAD_COCKATRICE && !uarmg) { + pline("Touching the dead cockatrice is a fatal mistake ..."); + pline("You die ..."); + killer = "dead cockatrice"; + done("died"); + } + } + } + + if (gold) { + char gbuf[30]; + + (void) sprintf(gbuf, "%ld gold piece%s", + gold->amount, plur(gold->amount)); + if (!ct++) + pline("You %s here %s.", verb, gbuf); + else + cornline(1, gbuf); + } + if (ct == 1 && !gold) { + pline("You %s here %s.", verb, doname(otmp0)); + cornline(3, (char *) 0); + } + if (ct > 1) + cornline(2, (char *) 0); + return (!!Blind); +} + +void +stackobj(obj) + struct obj *obj; +{ + struct obj *otmp = fobj; + for (otmp = fobj; otmp; otmp = otmp->nobj) + if (otmp != obj) + if (otmp->ox == obj->ox && otmp->oy == obj->oy && + merged(obj, otmp, 1)) + return; +} + +/* merge obj with otmp and delete obj if types agree */ +int +merged(otmp, obj, lose) + struct obj *otmp, *obj; + int lose; +{ + if (obj->otyp == otmp->otyp && + obj->unpaid == otmp->unpaid && + obj->spe == otmp->spe && + obj->dknown == otmp->dknown && + obj->cursed == otmp->cursed && + (strchr("%*?!", obj->olet) || + (obj->known == otmp->known && + (obj->olet == WEAPON_SYM && obj->otyp < BOOMERANG)))) { + otmp->quan += obj->quan; + otmp->owt += obj->owt; + if (lose) + freeobj(obj); + obfree(obj, otmp); /* free(obj), bill->otmp */ + return (1); + } else + return (0); +} + +static long goldcounted; +/* + * Gold is no longer displayed; in fact, when you have a lot of money, + * it may take a while before you have counted it all. + * [Bug: d$ and pickup still tell you how much it was.] + */ +int +countgold() +{ + if ((goldcounted += 100 * (u.ulevel + 1)) >= u.ugold) { + long eps = 0; + if (!rn2(2)) + eps = rnd((int) (u.ugold / 100 + 1)); + pline("You probably have about %ld gold pieces.", + u.ugold + eps); + return (0); /* done */ + } + return (1); /* continue */ +} + +int +doprgold() +{ + if (!u.ugold) + pline("You do not carry any gold."); + else if (u.ugold <= 500) + pline("You are carrying %ld gold pieces.", u.ugold); + else { + pline("You sit down in order to count your gold pieces."); + goldcounted = 500; + occupation = countgold; + occtxt = "counting your gold"; + } + return (1); +} + +/* --- end of gold counting section --- */ +int +doprwep() +{ + if (!uwep) + pline("You are empty handed."); + else + prinv(uwep); + return (0); +} + +int +doprarm() +{ + if (!uarm && !uarmg && !uarms && !uarmh) + pline("You are not wearing any armor."); + else { + char lets[6]; + int ct = 0; + + if (uarm) + lets[ct++] = obj_to_let(uarm); + if (uarm2) + lets[ct++] = obj_to_let(uarm2); + if (uarmh) + lets[ct++] = obj_to_let(uarmh); + if (uarms) + lets[ct++] = obj_to_let(uarms); + if (uarmg) + lets[ct++] = obj_to_let(uarmg); + lets[ct] = 0; + doinv(lets); + } + return (0); +} + +int +doprring() +{ + if (!uleft && !uright) + pline("You are not wearing any rings."); + else { + char lets[3]; + int ct = 0; + + if (uleft) + lets[ct++] = obj_to_let(uleft); + if (uright) + lets[ct++] = obj_to_let(uright); + lets[ct] = 0; + doinv(lets); + } + return (0); +} + +int +digit(c) + char c; +{ + return (c >= '0' && c <= '9'); +} diff --git a/hack/hack.ioctl.c b/hack/hack.ioctl.c new file mode 100644 index 0000000..3cb4939 --- /dev/null +++ b/hack/hack.ioctl.c @@ -0,0 +1,112 @@ +/* $NetBSD: hack.ioctl.c,v 1.6 1997/10/19 16:58:07 christos Exp $ */ + +/* + * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica, + * Amsterdam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - 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. + * + * - Neither the name of the Stichting Centrum voor Wiskunde en + * Informatica, 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER + * 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. + */ + +/* + * Copyright (c) 1982 Jay Fenlason + * 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. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``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 +#ifndef lint +__RCSID("$NetBSD: hack.ioctl.c,v 1.6 1997/10/19 16:58:07 christos Exp $"); +#endif /* not lint */ + +/* + * This cannot be part of hack.tty.c (as it was earlier) since on some + * systems (e.g. MUNIX) the include files and define the + * same constants, and the C preprocessor complains. + */ +#include +#include "hack.h" +#include "extern.h" +struct termios termios; + +void +getioctls() +{ + (void) tcgetattr(fileno(stdin), &termios); +} + +void +setioctls() +{ + (void) tcsetattr(fileno(stdin), TCSADRAIN, &termios); +} + +#ifdef SUSPEND /* implies BSD */ +#include +int +dosuspend() +{ +#ifdef SIGTSTP + if (signal(SIGTSTP, SIG_IGN) == SIG_DFL) { + settty((char *) 0); + (void) signal(SIGTSTP, SIG_DFL); + (void) kill(0, SIGTSTP); + gettty(); + setftty(); + docrt(); + } else { + pline("I don't think your shell has job control."); + } +#else /* SIGTSTP */ + pline("Sorry, it seems we have no SIGTSTP here. Try ! or S."); +#endif /* SIGTSTP */ + return (0); +} +#endif /* SUSPEND */ diff --git a/hack/hack.lev.c b/hack/hack.lev.c new file mode 100644 index 0000000..062e3e1 --- /dev/null +++ b/hack/hack.lev.c @@ -0,0 +1,349 @@ +/* $NetBSD: hack.lev.c,v 1.5 2001/03/25 20:44:01 jsm Exp $ */ + +/* + * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica, + * Amsterdam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - 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. + * + * - Neither the name of the Stichting Centrum voor Wiskunde en + * Informatica, 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER + * 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. + */ + +/* + * Copyright (c) 1982 Jay Fenlason + * 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. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``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 +#ifndef lint +__RCSID("$NetBSD: hack.lev.c,v 1.5 2001/03/25 20:44:01 jsm Exp $"); +#endif /* not lint */ + +#include +#include +#include "hack.h" +#include "extern.h" +#include "def.mkroom.h" + +#ifndef NOWORM +#include "def.wseg.h" +#endif /* NOWORM */ + +boolean level_exists[MAXLEVEL + 1]; + +void +savelev(fd, lev) + int fd; + xchar lev; +{ +#ifndef NOWORM + struct wseg *wtmp, *wtmp2; + int tmp; +#endif /* NOWORM */ + + if (fd < 0) + panic("Save on bad file!"); /* impossible */ + if (lev >= 0 && lev <= MAXLEVEL) + level_exists[lev] = TRUE; + + bwrite(fd, (char *) &hackpid, sizeof(hackpid)); + bwrite(fd, (char *) &lev, sizeof(lev)); + bwrite(fd, (char *) levl, sizeof(levl)); + bwrite(fd, (char *) &moves, sizeof(long)); + bwrite(fd, (char *) &xupstair, sizeof(xupstair)); + bwrite(fd, (char *) &yupstair, sizeof(yupstair)); + bwrite(fd, (char *) &xdnstair, sizeof(xdnstair)); + bwrite(fd, (char *) &ydnstair, sizeof(ydnstair)); + savemonchn(fd, fmon); + savegoldchn(fd, fgold); + savetrapchn(fd, ftrap); + saveobjchn(fd, fobj); + saveobjchn(fd, billobjs); + billobjs = 0; + save_engravings(fd); +#ifndef QUEST + bwrite(fd, (char *) rooms, sizeof(rooms)); + bwrite(fd, (char *) doors, sizeof(doors)); +#endif /* QUEST */ + fgold = 0; + ftrap = 0; + fmon = 0; + fobj = 0; +#ifndef NOWORM + bwrite(fd, (char *) wsegs, sizeof(wsegs)); + for (tmp = 1; tmp < 32; tmp++) { + for (wtmp = wsegs[tmp]; wtmp; wtmp = wtmp2) { + wtmp2 = wtmp->nseg; + bwrite(fd, (char *) wtmp, sizeof(struct wseg)); + } + wsegs[tmp] = 0; + } + bwrite(fd, (char *) wgrowtime, sizeof(wgrowtime)); +#endif /* NOWORM */ +} + +void +bwrite(fd, loc, num) + int fd; + const void *loc; + unsigned num; +{ + if (write(fd, loc, num) != (ssize_t)num) + panic("cannot write %u bytes to file #%d", num, fd); +} + +void +saveobjchn(fd, otmp) + int fd; + struct obj *otmp; +{ + struct obj *otmp2; + unsigned xl; + int minusone = -1; + + while (otmp) { + otmp2 = otmp->nobj; + xl = otmp->onamelth; + bwrite(fd, (char *) &xl, sizeof(int)); + bwrite(fd, (char *) otmp, xl + sizeof(struct obj)); + free((char *) otmp); + otmp = otmp2; + } + bwrite(fd, (char *) &minusone, sizeof(int)); +} + +void +savemonchn(fd, mtmp) + int fd; + struct monst *mtmp; +{ + struct monst *mtmp2; + unsigned xl; + int minusone = -1; + const struct permonst *monbegin = &mons[0]; + + bwrite(fd, &monbegin, sizeof(monbegin)); + + while (mtmp) { + mtmp2 = mtmp->nmon; + xl = mtmp->mxlth + mtmp->mnamelth; + bwrite(fd, (char *) &xl, sizeof(int)); + bwrite(fd, (char *) mtmp, xl + sizeof(struct monst)); + if (mtmp->minvent) + saveobjchn(fd, mtmp->minvent); + free((char *) mtmp); + mtmp = mtmp2; + } + bwrite(fd, (char *) &minusone, sizeof(int)); +} + +void +savegoldchn(fd, gold) + int fd; + struct gold *gold; +{ + struct gold *gold2; + while (gold) { + gold2 = gold->ngold; + bwrite(fd, (char *) gold, sizeof(struct gold)); + free((char *) gold); + gold = gold2; + } + bwrite(fd, nul, sizeof(struct gold)); +} + +void +savetrapchn(fd, trap) + int fd; + struct trap *trap; +{ + struct trap *trap2; + while (trap) { + trap2 = trap->ntrap; + bwrite(fd, (char *) trap, sizeof(struct trap)); + free((char *) trap); + trap = trap2; + } + bwrite(fd, nul, sizeof(struct trap)); +} + +void +getlev(fd, pid, lev) + int fd, pid; + xchar lev; +{ + struct gold *gold; + struct trap *trap; +#ifndef NOWORM + struct wseg *wtmp; +#endif /* NOWORM */ + int tmp; + long omoves; + int hpid; + xchar dlvl; + + /* First some sanity checks */ + mread(fd, (char *) &hpid, sizeof(hpid)); + mread(fd, (char *) &dlvl, sizeof(dlvl)); + if ((pid && pid != hpid) || (lev && dlvl != lev)) { + pline("Strange, this map is not as I remember it."); + pline("Somebody is trying some trickery here ..."); + pline("This game is void ..."); + done("tricked"); + } + fgold = 0; + ftrap = 0; + mread(fd, (char *) levl, sizeof(levl)); + mread(fd, (char *) &omoves, sizeof(omoves)); + mread(fd, (char *) &xupstair, sizeof(xupstair)); + mread(fd, (char *) &yupstair, sizeof(yupstair)); + mread(fd, (char *) &xdnstair, sizeof(xdnstair)); + mread(fd, (char *) &ydnstair, sizeof(ydnstair)); + + fmon = restmonchn(fd); + + /* regenerate animals while on another level */ + { + long tmoves = (moves > omoves) ? moves - omoves : 0; + struct monst *mtmp, *mtmp2; + + for (mtmp = fmon; mtmp; mtmp = mtmp2) { + long newhp; /* tmoves may be very large */ + + mtmp2 = mtmp->nmon; + if (strchr(genocided, mtmp->data->mlet)) { + mondead(mtmp); + continue; + } + if (mtmp->mtame && tmoves > 250) { + mtmp->mtame = 0; + mtmp->mpeaceful = 0; + } + newhp = mtmp->mhp + + (strchr(MREGEN, mtmp->data->mlet) ? tmoves : tmoves / 20); + if (newhp > mtmp->mhpmax) + mtmp->mhp = mtmp->mhpmax; + else + mtmp->mhp = newhp; + } + } + + setgd(); + gold = newgold(); + mread(fd, (char *) gold, sizeof(struct gold)); + while (gold->gx) { + gold->ngold = fgold; + fgold = gold; + gold = newgold(); + mread(fd, (char *) gold, sizeof(struct gold)); + } + free((char *) gold); + trap = newtrap(); + mread(fd, (char *) trap, sizeof(struct trap)); + while (trap->tx) { + trap->ntrap = ftrap; + ftrap = trap; + trap = newtrap(); + mread(fd, (char *) trap, sizeof(struct trap)); + } + free((char *) trap); + fobj = restobjchn(fd); + billobjs = restobjchn(fd); + rest_engravings(fd); +#ifndef QUEST + mread(fd, (char *) rooms, sizeof(rooms)); + mread(fd, (char *) doors, sizeof(doors)); +#endif /* QUEST */ +#ifndef NOWORM + mread(fd, (char *) wsegs, sizeof(wsegs)); + for (tmp = 1; tmp < 32; tmp++) + if (wsegs[tmp]) { + wheads[tmp] = wsegs[tmp] = wtmp = newseg(); + while (1) { + mread(fd, (char *) wtmp, sizeof(struct wseg)); + if (!wtmp->nseg) + break; + wheads[tmp]->nseg = wtmp = newseg(); + wheads[tmp] = wtmp; + } + } + mread(fd, (char *) wgrowtime, sizeof(wgrowtime)); +#endif /* NOWORM */ +} + +void +mread(fd, buf, len) + int fd; + char *buf; + unsigned len; +{ + int rlen; + + rlen = read(fd, buf, (int) len); + if (rlen != (int)len) { + pline("Read %d instead of %u bytes.\n", rlen, len); + if (restoring) { + (void) unlink(SAVEF); + error("Error restoring old game."); + } + panic("Error reading level file."); + } +} + +void +mklev() +{ + if (getbones()) + return; + + in_mklev = TRUE; + makelevel(); + in_mklev = FALSE; +} diff --git a/hack/hack.main.c b/hack/hack.main.c new file mode 100644 index 0000000..6315087 --- /dev/null +++ b/hack/hack.main.c @@ -0,0 +1,587 @@ +/* $NetBSD: hack.main.c,v 1.7 2002/05/26 00:12:12 wiz Exp $ */ + +/* + * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica, + * Amsterdam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - 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. + * + * - Neither the name of the Stichting Centrum voor Wiskunde en + * Informatica, 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER + * 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. + */ + +/* + * Copyright (c) 1982 Jay Fenlason + * 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. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``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 +#ifndef lint +__RCSID("$NetBSD: hack.main.c,v 1.7 2002/05/26 00:12:12 wiz Exp $"); +#endif /* not lint */ + +#include +#include +#include +#include +#include "hack.h" +#include "extern.h" + +#ifdef QUEST +#define gamename "quest" +#else +#define gamename "hack" +#endif + +int (*afternmv) __P((void)); +int (*occupation) __P((void)); +const char *occtxt; /* defined when occupation != NULL */ + +int hackpid; /* current pid */ +int locknum; /* max num of players */ +#ifdef DEF_PAGER +const char *catmore; /* default pager */ +#endif +char SAVEF[PL_NSIZ + 11] = "save/"; /* save/99999player */ +char *hname; /* name of the game (argv[0] of call) */ +char obuf[BUFSIZ]; /* BUFSIZ is defined in stdio.h */ + +int main __P((int, char *[])); +static void chdirx __P((const char *, boolean)); + +int +main(argc, argv) + int argc; + char *argv[]; +{ + int fd; +#ifdef CHDIR + char *dir; +#endif + + /* Check for dirty tricks with closed fds 0, 1, 2 */ + fd = open("/dev/null", O_RDONLY); + if (fd < 3) + exit(1); + close(fd); + + hname = argv[0]; + hackpid = getpid(); + +#ifdef CHDIR /* otherwise no chdir() */ + /* + * See if we must change directory to the playground. + * (Perhaps hack runs suid and playground is inaccessible + * for the player.) + * The environment variable HACKDIR is overridden by a + * -d command line option (must be the first option given) + */ + + dir = getenv("HACKDIR"); + if (argc > 1 && !strncmp(argv[1], "-d", 2)) { + argc--; + argv++; + dir = argv[0] + 2; + if (*dir == '=' || *dir == ':') + dir++; + if (!*dir && argc > 1) { + argc--; + argv++; + dir = argv[0]; + } + if (!*dir) + error("Flag -d must be followed by a directory name."); + } +#endif + + /* + * Who am i? Algorithm: 1. Use name as specified in HACKOPTIONS + * 2. Use $USER or $LOGNAME (if 1. fails) + * 3. Use getlogin() (if 2. fails) + * The resulting name is overridden by command line options. + * If everything fails, or if the resulting name is some generic + * account like "games", "play", "player", "hack" then eventually + * we'll ask him. + * Note that we trust him here; it is possible to play under + * somebody else's name. + */ + { + char *s; + + initoptions(); + if (!*plname && (s = getenv("USER"))) + (void) strncpy(plname, s, sizeof(plname) - 1); + if (!*plname && (s = getenv("LOGNAME"))) + (void) strncpy(plname, s, sizeof(plname) - 1); + if (!*plname && (s = getlogin())) + (void) strncpy(plname, s, sizeof(plname) - 1); + } + + /* + * Now we know the directory containing 'record' and + * may do a prscore(). + */ + if (argc > 1 && !strncmp(argv[1], "-s", 2)) { +#ifdef CHDIR + chdirx(dir, 0); +#endif + prscore(argc, argv); + exit(0); + } + /* + * It seems he really wants to play. + * Remember tty modes, to be restored on exit. + */ + gettty(); + setbuf(stdout, obuf); + setrandom(); + startup(); + cls(); + u.uhp = 1; /* prevent RIP on early quits */ + u.ux = FAR; /* prevent nscr() */ + (void) signal(SIGHUP, hangup); + + /* + * Find the creation date of this game, + * so as to avoid restoring outdated savefiles. + */ + gethdate(hname); + + /* + * We cannot do chdir earlier, otherwise gethdate will fail. + */ +#ifdef CHDIR + chdirx(dir, 1); +#endif + + /* + * Process options. + */ + while (argc > 1 && argv[1][0] == '-') { + argv++; + argc--; + switch (argv[0][1]) { +#ifdef WIZARD + case 'D': + /* if(!strcmp(getlogin(), WIZARD)) */ + wizard = TRUE; + /* + * else printf("Sorry.\n"); + */ + break; +#endif +#ifdef NEWS + case 'n': + flags.nonews = TRUE; + break; +#endif + case 'u': + if (argv[0][2]) + (void) strncpy(plname, argv[0] + 2, sizeof(plname) - 1); + else if (argc > 1) { + argc--; + argv++; + (void) strncpy(plname, argv[0], sizeof(plname) - 1); + } else + printf("Player name expected after -u\n"); + break; + default: + /* allow -T for Tourist, etc. */ + (void) strncpy(pl_character, argv[0] + 1, + sizeof(pl_character) - 1); + + /* printf("Unknown option: %s\n", *argv); */ + } + } + + if (argc > 1) + locknum = atoi(argv[1]); +#ifdef MAX_NR_OF_PLAYERS + if (!locknum || locknum > MAX_NR_OF_PLAYERS) + locknum = MAX_NR_OF_PLAYERS; +#endif +#ifdef DEF_PAGER + if (((catmore = getenv("HACKPAGER")) == NULL && + (catmore = getenv("PAGER")) == NULL) || + catmore[0] == '\0') + catmore = DEF_PAGER; +#endif +#ifdef MAIL + getmailstatus(); +#endif +#ifdef WIZARD + if (wizard) + (void) strcpy(plname, "wizard"); + else +#endif + if (!*plname || !strncmp(plname, "player", 4) + || !strncmp(plname, "games", 4)) + askname(); + plnamesuffix(); /* strip suffix from name; calls askname() */ + /* again if suffix was whole name */ + /* accepts any suffix */ +#ifdef WIZARD + if (!wizard) { +#endif + /* + * check for multiple games under the same name + * (if !locknum) or check max nr of players (otherwise) + */ + (void) signal(SIGQUIT, SIG_IGN); + (void) signal(SIGINT, SIG_IGN); + if (!locknum) + (void) strcpy(lock, plname); + getlock(); /* sets lock if locknum != 0 */ +#ifdef WIZARD + } else { + char *sfoo; + (void) strcpy(lock, plname); + if ((sfoo = getenv("MAGIC")) != NULL) + while (*sfoo) { + switch (*sfoo++) { + case 'n': + (void) srandom(*sfoo++); + break; + } + } + if ((sfoo = getenv("GENOCIDED")) != NULL) { + if (*sfoo == '!') { + const struct permonst *pm = mons; + char *gp = genocided; + + while (pm < mons + CMNUM + 2) { + if (!strchr(sfoo, pm->mlet)) + *gp++ = pm->mlet; + pm++; + } + *gp = 0; + } else + (void) strcpy(genocided, sfoo); + (void) strcpy(fut_geno, genocided); + } + } +#endif + setftty(); + (void) sprintf(SAVEF, "save/%d%s", getuid(), plname); + regularize(SAVEF + 5); /* avoid . or / in name */ + if ((fd = open(SAVEF, O_RDONLY)) >= 0 && + (uptodate(fd) || unlink(SAVEF) == 666)) { + (void) signal(SIGINT, done1); + pline("Restoring old save file..."); + (void) fflush(stdout); + if (!dorecover(fd)) + goto not_recovered; + pline("Hello %s, welcome to %s!", plname, gamename); + flags.move = 0; + } else { +not_recovered: + fobj = fcobj = invent = 0; + fmon = fallen_down = 0; + ftrap = 0; + fgold = 0; + flags.ident = 1; + init_objects(); + u_init(); + + (void) signal(SIGINT, done1); + mklev(); + u.ux = xupstair; + u.uy = yupstair; + (void) inshop(); + setsee(); + flags.botlx = 1; + makedog(); + { + struct monst *mtmp; + if ((mtmp = m_at(u.ux, u.uy)) != NULL) + mnexto(mtmp); /* riv05!a3 */ + } + seemons(); +#ifdef NEWS + if (flags.nonews || !readnews()) + /* after reading news we did docrt() already */ +#endif + docrt(); + + /* give welcome message before pickup messages */ + pline("Hello %s, welcome to %s!", plname, gamename); + + pickup(1); + read_engr_at(u.ux, u.uy); + flags.move = 1; + } + + flags.moonphase = phase_of_the_moon(); + if (flags.moonphase == FULL_MOON) { + pline("You are lucky! Full moon tonight."); + u.uluck++; + } else if (flags.moonphase == NEW_MOON) { + pline("Be careful! New moon tonight."); + } + initrack(); + + for (;;) { + if (flags.move) { /* actual time passed */ + + settrack(); + + if (moves % 2 == 0 || + (!(Fast & ~INTRINSIC) && (!Fast || rn2(3)))) { + movemon(); + if (!rn2(70)) + (void) makemon((struct permonst *) 0, 0, 0); + } + if (Glib) + glibr(); + timeout(); + ++moves; + if (flags.time) + flags.botl = 1; + if (u.uhp < 1) { + pline("You die..."); + done("died"); + } + if (u.uhp * 10 < u.uhpmax && moves - wailmsg > 50) { + wailmsg = moves; + if (u.uhp == 1) + pline("You hear the wailing of the Banshee..."); + else + pline("You hear the howling of the CwnAnnwn..."); + } + if (u.uhp < u.uhpmax) { + if (u.ulevel > 9) { + if (Regeneration || !(moves % 3)) { + flags.botl = 1; + u.uhp += rnd((int) u.ulevel - 9); + if (u.uhp > u.uhpmax) + u.uhp = u.uhpmax; + } + } else if (Regeneration || + (!(moves % (22 - u.ulevel * 2)))) { + flags.botl = 1; + u.uhp++; + } + } + if (Teleportation && !rn2(85)) + tele(); + if (Searching && multi >= 0) + (void) dosearch(); + gethungry(); + invault(); + amulet(); + } + if (multi < 0) { + if (!++multi) { + pline(nomovemsg ? nomovemsg : + "You can move again."); + nomovemsg = 0; + if (afternmv) + (*afternmv) (); + afternmv = 0; + } + } + find_ac(); +#ifndef QUEST + if (!flags.mv || Blind) +#endif + { + seeobjs(); + seemons(); + nscr(); + } + if (flags.botl || flags.botlx) + bot(); + + flags.move = 1; + + if (multi >= 0 && occupation) { + if (monster_nearby()) + stop_occupation(); + else if ((*occupation) () == 0) + occupation = 0; + continue; + } + if (multi > 0) { +#ifdef QUEST + if (flags.run >= 4) + finddir(); +#endif + lookaround(); + if (!multi) { /* lookaround may clear multi */ + flags.move = 0; + continue; + } + if (flags.mv) { + if (multi < COLNO && !--multi) + flags.mv = flags.run = 0; + domove(); + } else { + --multi; + rhack(save_cm); + } + } else if (multi == 0) { +#ifdef MAIL + ckmailstatus(); +#endif + rhack((char *) 0); + } + if (multi && multi % 7 == 0) + (void) fflush(stdout); + } +} + +void +glo(foo) + int foo; +{ + /* construct the string xlock.n */ + char *tf; + + tf = lock; + while (*tf && *tf != '.') + tf++; + (void) sprintf(tf, ".%d", foo); +} + +/* + * plname is filled either by an option (-u Player or -uPlayer) or + * explicitly (-w implies wizard) or by askname. + * It may still contain a suffix denoting pl_character. + */ +void +askname() +{ + int c, ct; + printf("\nWho are you? "); + (void) fflush(stdout); + ct = 0; + while ((c = getchar()) != '\n') { + if (c == EOF) + error("End of input\n"); + /* some people get confused when their erase char is not ^H */ + if (c == '\010') { + if (ct) + ct--; + continue; + } + if (c != '-') + if (c < 'A' || (c > 'Z' && c < 'a') || c > 'z') + c = '_'; + if ((size_t)ct < sizeof(plname) - 1) + plname[ct++] = c; + } + plname[ct] = 0; + if (ct == 0) + askname(); +} + +/* VARARGS1 */ +void +impossible(const char *s, ...) +{ + va_list ap; + + va_start(ap, s); + vpline(s, ap); + va_end(ap); + pline("Program in disorder - perhaps you'd better Quit."); +} + +#ifdef CHDIR +static void +chdirx(dir, wr) + const char *dir; + boolean wr; +{ + +#ifdef SECURE + if (dir /* User specified directory? */ +#ifdef HACKDIR + && strcmp(dir, HACKDIR) /* and not the default? */ +#endif + ) { + (void) setuid(getuid()); /* Ron Wessels */ + (void) setregid(getgid(), getgid()); + } +#endif + +#ifdef HACKDIR + if (dir == NULL) + dir = HACKDIR; +#endif + + if (dir && chdir(dir) < 0) { + perror(dir); + error("Cannot chdir to %s.", dir); + } + /* warn the player if he cannot write the record file */ + /* perhaps we should also test whether . is writable */ + /* unfortunately the access systemcall is worthless */ + if (wr) { + int fd; + + if (dir == NULL) + dir = "."; + if ((fd = open(RECORD, O_RDWR)) < 0) { + printf("Warning: cannot write %s/%s", dir, RECORD); + getret(); + } else + (void) close(fd); + } +} +#endif + +void +stop_occupation() +{ + if (occupation) { + pline("You stop %s.", occtxt); + occupation = 0; + } +} diff --git a/hack/hack.makemon.c b/hack/hack.makemon.c new file mode 100644 index 0000000..126e252 --- /dev/null +++ b/hack/hack.makemon.c @@ -0,0 +1,280 @@ +/* $NetBSD: hack.makemon.c,v 1.5 2001/03/25 20:44:01 jsm Exp $ */ + +/* + * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica, + * Amsterdam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - 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. + * + * - Neither the name of the Stichting Centrum voor Wiskunde en + * Informatica, 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER + * 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. + */ + +/* + * Copyright (c) 1982 Jay Fenlason + * 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. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``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 +#ifndef lint +__RCSID("$NetBSD: hack.makemon.c,v 1.5 2001/03/25 20:44:01 jsm Exp $"); +#endif /* not lint */ + +#include "hack.h" +#include "extern.h" + +struct monst zeromonst; + +/* + * called with [x,y] = coordinates; + * [0,0] means anyplace + * [u.ux,u.uy] means: call mnexto (if !in_mklev) + * + * In case we make an Orc or killer bee, we make an entire horde (swarm); + * note that in this case we return only one of them (the one at [x,y]). + */ +struct monst * +makemon(const struct permonst *ptr, int x, int y) +{ + struct monst *mtmp; + int tmp, ct; + boolean anything = (!ptr); + + if (x != 0 || y != 0) + if (m_at(x, y)) + return ((struct monst *) 0); + if (ptr) { + if (strchr(fut_geno, ptr->mlet)) + return ((struct monst *) 0); + } else { + ct = CMNUM - strlen(fut_geno); + if (strchr(fut_geno, 'm')) + ct++; /* make only 1 minotaur */ + if (strchr(fut_geno, '@')) + ct++; + if (ct <= 0) + return (0); /* no more monsters! */ + tmp = rn2(ct * dlevel / 24 + 7); + if (tmp < dlevel - 4) + tmp = rn2(ct * dlevel / 24 + 12); + if (tmp >= ct) + tmp = rn1(ct - ct / 2, ct / 2); + for (ct = 0; ct < CMNUM; ct++) { + ptr = &mons[ct]; + if (strchr(fut_geno, ptr->mlet)) + continue; + if (!tmp--) + goto gotmon; + } + panic("makemon?"); + } +gotmon: + mtmp = newmonst(ptr->pxlth); + *mtmp = zeromonst; /* clear all entries in structure */ + for (ct = 0; ct < (int)ptr->pxlth; ct++) + ((char *) &(mtmp->mextra[0]))[ct] = 0; + mtmp->nmon = fmon; + fmon = mtmp; + mtmp->m_id = flags.ident++; + mtmp->data = ptr; + mtmp->mxlth = ptr->pxlth; + if (ptr->mlet == 'D') + mtmp->mhpmax = mtmp->mhp = 80; + else if (!ptr->mlevel) + mtmp->mhpmax = mtmp->mhp = rnd(4); + else + mtmp->mhpmax = mtmp->mhp = d(ptr->mlevel, 8); + mtmp->mx = x; + mtmp->my = y; + mtmp->mcansee = 1; + if (ptr->mlet == 'M') { + mtmp->mimic = 1; + mtmp->mappearance = ']'; + } + if (!in_mklev) { + if (x == u.ux && y == u.uy && ptr->mlet != ' ') + mnexto(mtmp); + if (x == 0 && y == 0) + rloc(mtmp); + } + if (ptr->mlet == 's' || ptr->mlet == 'S') { + mtmp->mhide = mtmp->mundetected = 1; + if (in_mklev) + if (mtmp->mx && mtmp->my) + (void) mkobj_at(0, mtmp->mx, mtmp->my); + } + if (ptr->mlet == ':') { + mtmp->cham = 1; + (void) newcham(mtmp, &mons[dlevel + 14 + rn2(CMNUM - 14 - dlevel)]); + } + if (ptr->mlet == 'I' || ptr->mlet == ';') + mtmp->minvis = 1; + if (ptr->mlet == 'L' || ptr->mlet == 'N' + || (in_mklev && strchr("&w;", ptr->mlet) && rn2(5)) + ) + mtmp->msleep = 1; + +#ifndef NOWORM + if (ptr->mlet == 'w' && getwn(mtmp)) + initworm(mtmp); +#endif /* NOWORM */ + + if (anything) + if (ptr->mlet == 'O' || ptr->mlet == 'k') { + coord mm; + int cnt = rnd(10); + mm.x = x; + mm.y = y; + while (cnt--) { + mm = enexto(mm.x, mm.y); + (void) makemon(ptr, mm.x, mm.y); + } + } + return (mtmp); +} + +coord +enexto(xx, yy) + xchar xx, yy; +{ + xchar x, y; + coord foo[15], *tfoo; + int range; + + tfoo = foo; + range = 1; + do { /* full kludge action. */ + for (x = xx - range; x <= xx + range; x++) + if (goodpos(x, yy - range)) { + tfoo->x = x; + tfoo++->y = yy - range; + if (tfoo == &foo[15]) + goto foofull; + } + for (x = xx - range; x <= xx + range; x++) + if (goodpos(x, yy + range)) { + tfoo->x = x; + tfoo++->y = yy + range; + if (tfoo == &foo[15]) + goto foofull; + } + for (y = yy + 1 - range; y < yy + range; y++) + if (goodpos(xx - range, y)) { + tfoo->x = xx - range; + tfoo++->y = y; + if (tfoo == &foo[15]) + goto foofull; + } + for (y = yy + 1 - range; y < yy + range; y++) + if (goodpos(xx + range, y)) { + tfoo->x = xx + range; + tfoo++->y = y; + if (tfoo == &foo[15]) + goto foofull; + } + range++; + } while (tfoo == foo); +foofull: + return (foo[rn2(tfoo - foo)]); +} + +int +goodpos(int x, int y) +{ /* used only in mnexto and rloc */ + return ( + !(x < 1 || x > COLNO - 2 || y < 1 || y > ROWNO - 2 || + m_at(x, y) || !ACCESSIBLE(levl[x][y].typ) + || (x == u.ux && y == u.uy) + || sobj_at(ENORMOUS_ROCK, x, y) + )); +} + +void +rloc(mtmp) + struct monst *mtmp; +{ + int tx, ty; + char ch = mtmp->data->mlet; + +#ifndef NOWORM + if (ch == 'w' && mtmp->mx) + return; /* do not relocate worms */ +#endif /* NOWORM */ + do { + tx = rn1(COLNO - 3, 2); + ty = rn2(ROWNO); + } while (!goodpos(tx, ty)); + mtmp->mx = tx; + mtmp->my = ty; + if (u.ustuck == mtmp) { + if (u.uswallow) { + u.ux = tx; + u.uy = ty; + docrt(); + } else + u.ustuck = 0; + } + pmon(mtmp); +} + +struct monst * +mkmon_at(let, x, y) + char let; + int x, y; +{ + int ct; + const struct permonst *ptr; + + for (ct = 0; ct < CMNUM; ct++) { + ptr = &mons[ct]; + if (ptr->mlet == let) + return (makemon(ptr, x, y)); + } + return (0); +} diff --git a/hack/hack.mfndpos.h b/hack/hack.mfndpos.h new file mode 100644 index 0000000..1f8775e --- /dev/null +++ b/hack/hack.mfndpos.h @@ -0,0 +1,75 @@ +/* $NetBSD: hack.mfndpos.h,v 1.4 1997/10/19 16:58:19 christos Exp $ */ + +/* + * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica, + * Amsterdam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - 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. + * + * - Neither the name of the Stichting Centrum voor Wiskunde en + * Informatica, 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER + * 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. + */ + +/* + * Copyright (c) 1982 Jay Fenlason + * 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. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``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. + */ + +#ifndef _HACK_MFNDPOS_H_ +#define _HACK_MFNDPOS_H_ +#define ALLOW_TRAPS 0777 +#define ALLOW_U 01000 +#define ALLOW_M 02000 +#define ALLOW_TM 04000 +#define ALLOW_ALL (ALLOW_U | ALLOW_M | ALLOW_TM | ALLOW_TRAPS) +#define ALLOW_SSM 010000 +#define ALLOW_ROCK 020000 +#define NOTONL 040000 +#define NOGARLIC 0100000 +#endif /* _HACK_MFNDPOS_H_ */ diff --git a/hack/hack.mhitu.c b/hack/hack.mhitu.c new file mode 100644 index 0000000..bf1319c --- /dev/null +++ b/hack/hack.mhitu.c @@ -0,0 +1,455 @@ +/* $NetBSD: hack.mhitu.c,v 1.5 2001/03/25 20:44:01 jsm Exp $ */ + +/* + * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica, + * Amsterdam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - 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. + * + * - Neither the name of the Stichting Centrum voor Wiskunde en + * Informatica, 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER + * 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. + */ + +/* + * Copyright (c) 1982 Jay Fenlason + * 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. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``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 +#ifndef lint +__RCSID("$NetBSD: hack.mhitu.c,v 1.5 2001/03/25 20:44:01 jsm Exp $"); +#endif /* not lint */ + +#include "hack.h" +#include "extern.h" + +/* + * mhitu: monster hits you + * returns 1 if monster dies (e.g. 'y', 'F'), 0 otherwise + */ +int +mhitu(mtmp) + struct monst *mtmp; +{ + const struct permonst *mdat = mtmp->data; + int tmp, ctmp; + + nomul(0); + + /* If swallowed, can only be affected by hissers and by u.ustuck */ + if (u.uswallow) { + if (mtmp != u.ustuck) { + if (mdat->mlet == 'c' && !rn2(13)) { + pline("Outside, you hear %s's hissing!", + monnam(mtmp)); + pline("%s gets turned to stone!", + Monnam(u.ustuck)); + pline("And the same fate befalls you."); + done_in_by(mtmp); + /* "notreached": not return(1); */ + } + return (0); + } + switch (mdat->mlet) { /* now mtmp == u.ustuck */ + case ',': + youswld(mtmp, (u.uac > 0) ? u.uac + 4 : 4, + 5, "The trapper"); + break; + case '\'': + youswld(mtmp, rnd(6), 7, "The lurker above"); + break; + case 'P': + youswld(mtmp, d(2, 4), 12, "The purple worm"); + break; + default: + /* This is not impossible! */ + pline("The mysterious monster totally digests you."); + u.uhp = 0; + } + if (u.uhp < 1) + done_in_by(mtmp); + return (0); + } + if (mdat->mlet == 'c' && Stoned) + return (0); + + /* make eels visible the moment they hit/miss us */ + if (mdat->mlet == ';' && mtmp->minvis && cansee(mtmp->mx, mtmp->my)) { + mtmp->minvis = 0; + pmon(mtmp); + } + if (!strchr("1&DuxynNF", mdat->mlet)) + tmp = hitu(mtmp, d(mdat->damn, mdat->damd)); + else + tmp = 0; + if (strchr(UNDEAD, mdat->mlet) && midnight()) + tmp += hitu(mtmp, d(mdat->damn, mdat->damd)); + + ctmp = tmp && !mtmp->mcan && + (!uarm || objects[uarm->otyp].a_can < rnd(3) || !rn2(50)); + switch (mdat->mlet) { + case '1': + if (wiz_hit(mtmp)) + return (1); /* he disappeared */ + break; + case '&': + if (!mtmp->cham && !mtmp->mcan && !rn2(13)) { + (void) makemon(PM_DEMON, u.ux, u.uy); + } else { + (void) hitu(mtmp, d(2, 6)); + (void) hitu(mtmp, d(2, 6)); + (void) hitu(mtmp, rnd(3)); + (void) hitu(mtmp, rnd(3)); + (void) hitu(mtmp, rn1(4, 2)); + } + break; + case ',': + if (tmp) + justswld(mtmp, "The trapper"); + break; + case '\'': + if (tmp) + justswld(mtmp, "The lurker above"); + break; + case ';': + if (ctmp) { + if (!u.ustuck && !rn2(10)) { + pline("%s swings itself around you!", + Monnam(mtmp)); + u.ustuck = mtmp; + } else if (u.ustuck == mtmp && + levl[mtmp->mx][mtmp->my].typ == POOL) { + pline("%s drowns you ...", Monnam(mtmp)); + done("drowned"); + } + } + break; + case 'A': + if (ctmp && rn2(2)) { + if (Poison_resistance) + pline("The sting doesn't seem to affect you."); + else { + pline("You feel weaker!"); + losestr(1); + } + } + break; + case 'C': + (void) hitu(mtmp, rnd(6)); + break; + case 'c': + if (!rn2(5)) { + pline("You hear %s's hissing!", monnam(mtmp)); + if (ctmp || !rn2(20) || (flags.moonphase == NEW_MOON + && !carrying(DEAD_LIZARD))) { + Stoned = 5; + /* pline("You get turned to stone!"); */ + /* done_in_by(mtmp); */ + } + } + break; + case 'D': + if (rn2(6) || mtmp->mcan) { + (void) hitu(mtmp, d(3, 10)); + (void) hitu(mtmp, rnd(8)); + (void) hitu(mtmp, rnd(8)); + break; + } + kludge("%s breathes fire!", "The dragon"); + buzz(-1, mtmp->mx, mtmp->my, u.ux - mtmp->mx, u.uy - mtmp->my); + break; + case 'd': + (void) hitu(mtmp, d(2, (flags.moonphase == FULL_MOON) ? 3 : 4)); + break; + case 'e': + (void) hitu(mtmp, d(3, 6)); + break; + case 'F': + if (mtmp->mcan) + break; + kludge("%s explodes!", "The freezing sphere"); + if (Cold_resistance) + pline("You don't seem affected by it."); + else { + xchar dn; + if (17 - (u.ulevel / 2) > rnd(20)) { + pline("You get blasted!"); + dn = 6; + } else { + pline("You duck the blast..."); + dn = 3; + } + losehp_m(d(dn, 6), mtmp); + } + mondead(mtmp); + return (1); + case 'g': + if (ctmp && multi >= 0 && !rn2(3)) { + kludge("You are frozen by %ss juices", "the cube'"); + nomul(-rnd(10)); + } + break; + case 'h': + if (ctmp && multi >= 0 && !rn2(5)) { + nomul(-rnd(10)); + kludge("You are put to sleep by %ss bite!", + "the homunculus'"); + } + break; + case 'j': + tmp = hitu(mtmp, rnd(3)); + tmp &= hitu(mtmp, rnd(3)); + if (tmp) { + (void) hitu(mtmp, rnd(4)); + (void) hitu(mtmp, rnd(4)); + } + break; + case 'k': + if ((hitu(mtmp, rnd(4)) || !rn2(3)) && ctmp) { + poisoned("bee's sting", mdat->mname); + } + break; + case 'L': + if (tmp) + stealgold(mtmp); + break; + case 'N': + if (mtmp->mcan && !Blind) { + pline("%s tries to seduce you, but you seem not interested.", + Amonnam(mtmp, "plain")); + if (rn2(3)) + rloc(mtmp); + } else if (steal(mtmp)) { + rloc(mtmp); + mtmp->mflee = 1; + } + break; + case 'n': + if (!uwep && !uarm && !uarmh && !uarms && !uarmg) { + pline("%s hits! (I hope you don't mind)", + Monnam(mtmp)); + u.uhp += rnd(7); + if (!rn2(7)) + u.uhpmax++; + if (u.uhp > u.uhpmax) + u.uhp = u.uhpmax; + flags.botl = 1; + if (!rn2(50)) + rloc(mtmp); + } else { + (void) hitu(mtmp, d(2, 6)); + (void) hitu(mtmp, d(2, 6)); + } + break; + case 'o': + tmp = hitu(mtmp, rnd(6)); + if (hitu(mtmp, rnd(6)) && tmp && /* hits with both paws */ + !u.ustuck && rn2(2)) { + u.ustuck = mtmp; + kludge("%s has grabbed you!", "The owlbear"); + u.uhp -= d(2, 8); + } else if (u.ustuck == mtmp) { + u.uhp -= d(2, 8); + pline("You are being crushed."); + } + break; + case 'P': + if (ctmp && !rn2(4)) + justswld(mtmp, "The purple worm"); + else + (void) hitu(mtmp, d(2, 4)); + break; + case 'Q': + (void) hitu(mtmp, rnd(2)); + (void) hitu(mtmp, rnd(2)); + break; + case 'R': + if (tmp && uarmh && !uarmh->rustfree && + (int) uarmh->spe >= -1) { + pline("Your helmet rusts!"); + uarmh->spe--; + } else if (ctmp && uarm && !uarm->rustfree && /* Mike Newton */ + uarm->otyp < STUDDED_LEATHER_ARMOR && + (int) uarm->spe >= -1) { + pline("Your armor rusts!"); + uarm->spe--; + } + break; + case 'S': + if (ctmp && !rn2(8)) { + poisoned("snake's bite", mdat->mname); + } + break; + case 's': + if (tmp && !rn2(8)) { + poisoned("scorpion's sting", mdat->mname); + } + (void) hitu(mtmp, rnd(8)); + (void) hitu(mtmp, rnd(8)); + break; + case 'T': + (void) hitu(mtmp, rnd(6)); + (void) hitu(mtmp, rnd(6)); + break; + case 't': + if (!rn2(5)) + rloc(mtmp); + break; + case 'u': + mtmp->mflee = 1; + break; + case 'U': + (void) hitu(mtmp, d(3, 4)); + (void) hitu(mtmp, d(3, 4)); + break; + case 'v': + if (ctmp && !u.ustuck) + u.ustuck = mtmp; + break; + case 'V': + if (tmp) + u.uhp -= 4; + if (ctmp) + losexp(); + break; + case 'W': + if (ctmp) + losexp(); + break; +#ifndef NOWORM + case 'w': + if (tmp) + wormhit(mtmp); +#endif /* NOWORM */ + break; + case 'X': + (void) hitu(mtmp, rnd(5)); + (void) hitu(mtmp, rnd(5)); + (void) hitu(mtmp, rnd(5)); + break; + case 'x': + { + long side = rn2(2) ? RIGHT_SIDE : LEFT_SIDE; + pline("%s pricks in your %s leg!", + Monnam(mtmp), (side == RIGHT_SIDE) ? "right" : "left"); + set_wounded_legs(side, rnd(50)); + losehp_m(2, mtmp); + break; + } + case 'y': + if (mtmp->mcan) + break; + mondead(mtmp); + if (!Blind) { + pline("You are blinded by a blast of light!"); + Blind = d(4, 12); + seeoff(0); + } + return (1); + case 'Y': + (void) hitu(mtmp, rnd(6)); + break; + } + if (u.uhp < 1) + done_in_by(mtmp); + return (0); +} + +int +hitu(mtmp, dam) + struct monst *mtmp; + int dam; +{ + int tmp, res; + + nomul(0); + if (u.uswallow) + return (0); + + if (mtmp->mhide && mtmp->mundetected) { + mtmp->mundetected = 0; + if (!Blind) { + struct obj *obj; + if ((obj = o_at(mtmp->mx, mtmp->my)) != NULL) + pline("%s was hidden under %s!", + Xmonnam(mtmp), doname(obj)); + } + } + tmp = u.uac; + /* give people with Ac = -10 at least some vulnerability */ + if (tmp < 0) { + dam += tmp; /* decrease damage */ + if (dam <= 0) + dam = 1; + tmp = -rn2(-tmp); + } + tmp += mtmp->data->mlevel; + if (multi < 0) + tmp += 4; + if ((Invis && mtmp->data->mlet != 'I') || !mtmp->mcansee) + tmp -= 2; + if (mtmp->mtrapped) + tmp -= 2; + if (tmp <= rnd(20)) { + if (Blind) + pline("It misses."); + else + pline("%s misses.", Monnam(mtmp)); + res = 0; + } else { + if (Blind) + pline("It hits!"); + else + pline("%s hits!", Monnam(mtmp)); + losehp_m(dam, mtmp); + res = 1; + } + stop_occupation(); + return (res); +} diff --git a/hack/hack.mklev.c b/hack/hack.mklev.c new file mode 100644 index 0000000..dd66638 --- /dev/null +++ b/hack/hack.mklev.c @@ -0,0 +1,851 @@ +/* $NetBSD: hack.mklev.c,v 1.5 2001/03/25 20:44:01 jsm Exp $ */ + +/* + * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica, + * Amsterdam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - 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. + * + * - Neither the name of the Stichting Centrum voor Wiskunde en + * Informatica, 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER + * 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. + */ + +/* + * Copyright (c) 1982 Jay Fenlason + * 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. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``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 +#ifndef lint +__RCSID("$NetBSD: hack.mklev.c,v 1.5 2001/03/25 20:44:01 jsm Exp $"); +#endif /* not lint */ + +#include +#include +#include "hack.h" +#include "extern.h" + +#define somex() ((random()%(croom->hx-croom->lx+1))+croom->lx) +#define somey() ((random()%(croom->hy-croom->ly+1))+croom->ly) + +#include "def.mkroom.h" +#define XLIM 4 /* define minimum required space around a + * room */ +#define YLIM 3 +boolean secret; /* TRUE while making a vault: increase + * [XY]LIM */ +int smeq[MAXNROFROOMS + 1]; +int doorindex; +struct rm zerorm; +schar nxcor; +boolean goldseen; +int nroom; + +/* Definitions used by makerooms() and addrs() */ +#define MAXRS 50 /* max lth of temp rectangle table - + * arbitrary */ +struct rectangle { + xchar rlx, rly, rhx, rhy; +} rs[MAXRS + 1]; +int rscnt, rsmax; /* 0..rscnt-1: currently under consideration */ +/* rscnt..rsmax: discarded */ + +void +makelevel() +{ + struct mkroom *croom, *troom; + unsigned tryct; + int x, y; + + nroom = 0; + doorindex = 0; + rooms[0].hx = -1; /* in case we are in a maze */ + + for (x = 0; x < COLNO; x++) + for (y = 0; y < ROWNO; y++) + levl[x][y] = zerorm; + + oinit(); /* assign level dependent obj probabilities */ + + if (dlevel >= rn1(3, 26)) { /* there might be several mazes */ + makemaz(); + return; + } + /* construct the rooms */ + nroom = 0; + secret = FALSE; + (void) makerooms(); + + /* construct stairs (up and down in different rooms if possible) */ + croom = &rooms[rn2(nroom)]; + xdnstair = somex(); + ydnstair = somey(); + levl[xdnstair][ydnstair].scrsym = '>'; + levl[xdnstair][ydnstair].typ = STAIRS; + if (nroom > 1) { + troom = croom; + croom = &rooms[rn2(nroom - 1)]; + if (croom >= troom) + croom++; + } + xupstair = somex(); /* %% < and > might be in the same place */ + yupstair = somey(); + levl[xupstair][yupstair].scrsym = '<'; + levl[xupstair][yupstair].typ = STAIRS; + + /* for each room: put things inside */ + for (croom = rooms; croom->hx > 0; croom++) { + + /* put a sleeping monster inside */ + /* + * Note: monster may be on the stairs. This cannot be + * avoided: maybe the player fell through a trapdoor while a + * monster was on the stairs. Conclusion: we have to check + * for monsters on the stairs anyway. + */ + if (!rn2(3)) + (void) + makemon((struct permonst *) 0, somex(), somey()); + + /* put traps and mimics inside */ + goldseen = FALSE; + while (!rn2(8 - (dlevel / 6))) + mktrap(0, 0, croom); + if (!goldseen && !rn2(3)) + mkgold(0L, somex(), somey()); + if (!rn2(3)) { + (void) mkobj_at(0, somex(), somey()); + tryct = 0; + while (!rn2(5)) { + if (++tryct > 100) { + printf("tryct overflow4\n"); + break; + } + (void) mkobj_at(0, somex(), somey()); + } + } + } + + qsort((char *) rooms, nroom, sizeof(struct mkroom), comp); + makecorridors(); + make_niches(); + + /* make a secret treasure vault, not connected to the rest */ + if (nroom <= (2 * MAXNROFROOMS / 3)) + if (rn2(3)) { + troom = &rooms[nroom]; + secret = TRUE; + if (makerooms()) { + troom->rtype = VAULT; /* treasure vault */ + for (x = troom->lx; x <= troom->hx; x++) + for (y = troom->ly; y <= troom->hy; y++) + mkgold((long) (rnd(dlevel * 100) + 50), x, y); + if (!rn2(3)) + makevtele(); + } + } +#ifndef QUEST +#ifdef WIZARD + if (wizard && getenv("SHOPTYPE")) + mkshop(); + else +#endif /* WIZARD */ + if (dlevel > 1 && dlevel < 20 && rn2(dlevel) < 3) + mkshop(); + else if (dlevel > 6 && !rn2(7)) + mkzoo(ZOO); + else if (dlevel > 9 && !rn2(5)) + mkzoo(BEEHIVE); + else if (dlevel > 11 && !rn2(6)) + mkzoo(MORGUE); + else if (dlevel > 18 && !rn2(6)) + mkswamp(); +#endif /* QUEST */ +} + +int +makerooms() +{ + struct rectangle *rsp; + int lx, ly, hx, hy, lowx, lowy, hix, hiy, dx, dy; + int tryct = 0, xlim, ylim; + + /* init */ + xlim = XLIM + secret; + ylim = YLIM + secret; + if (nroom == 0) { + rsp = rs; + rsp->rlx = rsp->rly = 0; + rsp->rhx = COLNO - 1; + rsp->rhy = ROWNO - 1; + rsmax = 1; + } + rscnt = rsmax; + + /* make rooms until satisfied */ + while (rscnt > 0 && nroom < MAXNROFROOMS - 1) { + if (!secret && nroom > (MAXNROFROOMS / 3) && + !rn2((MAXNROFROOMS - nroom) * (MAXNROFROOMS - nroom))) + return (0); + + /* pick a rectangle */ + rsp = &rs[rn2(rscnt)]; + hx = rsp->rhx; + hy = rsp->rhy; + lx = rsp->rlx; + ly = rsp->rly; + + /* find size of room */ + if (secret) + dx = dy = 1; + else { + dx = 2 + rn2((hx - lx - 8 > 20) ? 12 : 8); + dy = 2 + rn2(4); + if (dx * dy > 50) + dy = 50 / dx; + } + + /* look whether our room will fit */ + if (hx - lx < dx + dx / 2 + 2 * xlim || hy - ly < dy + dy / 3 + 2 * ylim) { + /* no, too small */ + /* maybe we throw this area out */ + if (secret || !rn2(MAXNROFROOMS + 1 - nroom - tryct)) { + rscnt--; + rs[rsmax] = *rsp; + *rsp = rs[rscnt]; + rs[rscnt] = rs[rsmax]; + tryct = 0; + } else + tryct++; + continue; + } + lowx = lx + xlim + rn2(hx - lx - dx - 2 * xlim + 1); + lowy = ly + ylim + rn2(hy - ly - dy - 2 * ylim + 1); + hix = lowx + dx; + hiy = lowy + dy; + + if (maker(lowx, dx, lowy, dy)) { + if (secret) + return (1); + addrs(lowx - 1, lowy - 1, hix + 1, hiy + 1); + tryct = 0; + } else if (tryct++ > 100) + break; + } + return (0); /* failed to make vault - very strange */ +} + +void +addrs(lowx, lowy, hix, hiy) + int lowx, lowy, hix, hiy; +{ + struct rectangle *rsp; + int lx, ly, hx, hy, xlim, ylim; + boolean discarded; + + xlim = XLIM + secret; + ylim = YLIM + secret; + + /* walk down since rscnt and rsmax change */ + for (rsp = &rs[rsmax - 1]; rsp >= rs; rsp--) { + + if ((lx = rsp->rlx) > hix || (ly = rsp->rly) > hiy || + (hx = rsp->rhx) < lowx || (hy = rsp->rhy) < lowy) + continue; + if ((discarded = (rsp >= &rs[rscnt]))) { + *rsp = rs[--rsmax]; + } else { + rsmax--; + rscnt--; + *rsp = rs[rscnt]; + if (rscnt != rsmax) + rs[rscnt] = rs[rsmax]; + } + if (lowy - ly > 2 * ylim + 4) + addrsx(lx, ly, hx, lowy - 2, discarded); + if (lowx - lx > 2 * xlim + 4) + addrsx(lx, ly, lowx - 2, hy, discarded); + if (hy - hiy > 2 * ylim + 4) + addrsx(lx, hiy + 2, hx, hy, discarded); + if (hx - hix > 2 * xlim + 4) + addrsx(hix + 2, ly, hx, hy, discarded); + } +} + +void +addrsx(lx, ly, hx, hy, discarded) + int lx, ly, hx, hy; + boolean discarded; /* piece of a discarded area */ +{ + struct rectangle *rsp; + + /* check inclusions */ + for (rsp = rs; rsp < &rs[rsmax]; rsp++) { + if (lx >= rsp->rlx && hx <= rsp->rhx && + ly >= rsp->rly && hy <= rsp->rhy) + return; + } + + /* make a new entry */ + if (rsmax >= MAXRS) { +#ifdef WIZARD + if (wizard) + pline("MAXRS may be too small."); +#endif /* WIZARD */ + return; + } + rsmax++; + if (!discarded) { + *rsp = rs[rscnt]; + rsp = &rs[rscnt]; + rscnt++; + } + rsp->rlx = lx; + rsp->rly = ly; + rsp->rhx = hx; + rsp->rhy = hy; +} + +int +comp(vx, vy) + const void *vx, *vy; +{ + const struct mkroom *x = vx, *y = vy; + if (x->lx < y->lx) + return (-1); + return (x->lx > y->lx); +} + +coord +finddpos(int xl, int yl, int xh, int yh) +{ + coord ff; + int x, y; + + x = (xl == xh) ? xl : (xl + rn2(xh - xl + 1)); + y = (yl == yh) ? yl : (yl + rn2(yh - yl + 1)); + if (okdoor(x, y)) + goto gotit; + + for (x = xl; x <= xh; x++) + for (y = yl; y <= yh; y++) + if (okdoor(x, y)) + goto gotit; + + for (x = xl; x <= xh; x++) + for (y = yl; y <= yh; y++) + if (levl[x][y].typ == DOOR || levl[x][y].typ == SDOOR) + goto gotit; + /* cannot find something reasonable -- strange */ + x = xl; + y = yh; +gotit: + ff.x = x; + ff.y = y; + return (ff); +} + +/* see whether it is allowable to create a door at [x,y] */ +int +okdoor(x, y) + int x, y; +{ + if (levl[x - 1][y].typ == DOOR || levl[x + 1][y].typ == DOOR || + levl[x][y + 1].typ == DOOR || levl[x][y - 1].typ == DOOR || + levl[x - 1][y].typ == SDOOR || levl[x + 1][y].typ == SDOOR || + levl[x][y - 1].typ == SDOOR || levl[x][y + 1].typ == SDOOR || + (levl[x][y].typ != HWALL && levl[x][y].typ != VWALL) || + doorindex >= DOORMAX) + return (0); + return (1); +} + +void +dodoor(x, y, aroom) + int x, y; + struct mkroom *aroom; +{ + if (doorindex >= DOORMAX) { + impossible("DOORMAX exceeded?"); + return; + } + if (!okdoor(x, y) && nxcor) + return; + dosdoor(x, y, aroom, rn2(8) ? DOOR : SDOOR); +} + +void +dosdoor(x, y, aroom, type) + int x, y; + struct mkroom *aroom; + int type; +{ + struct mkroom *broom; + int tmp; + + if (!IS_WALL(levl[x][y].typ)) /* avoid SDOORs with '+' as scrsym */ + type = DOOR; + levl[x][y].typ = type; + if (type == DOOR) + levl[x][y].scrsym = '+'; + aroom->doorct++; + broom = aroom + 1; + if (broom->hx < 0) + tmp = doorindex; + else + for (tmp = doorindex; tmp > broom->fdoor; tmp--) + doors[tmp] = doors[tmp - 1]; + doorindex++; + doors[tmp].x = x; + doors[tmp].y = y; + for (; broom->hx >= 0; broom++) + broom->fdoor++; +} + +/* Only called from makerooms() */ +int +maker(lowx, ddx, lowy, ddy) + schar lowx, ddx, lowy, ddy; +{ + struct mkroom *croom; + int x, y, hix = lowx + ddx, hiy = lowy + ddy; + int xlim = XLIM + secret, ylim = YLIM + secret; + + if (nroom >= MAXNROFROOMS) + return (0); + if (lowx < XLIM) + lowx = XLIM; + if (lowy < YLIM) + lowy = YLIM; + if (hix > COLNO - XLIM - 1) + hix = COLNO - XLIM - 1; + if (hiy > ROWNO - YLIM - 1) + hiy = ROWNO - YLIM - 1; +chk: + if (hix <= lowx || hiy <= lowy) + return (0); + + /* check area around room (and make room smaller if necessary) */ + for (x = lowx - xlim; x <= hix + xlim; x++) { + for (y = lowy - ylim; y <= hiy + ylim; y++) { + if (levl[x][y].typ) { +#ifdef WIZARD + if (wizard && !secret) + pline("Strange area [%d,%d] in maker().", x, y); +#endif /* WIZARD */ + if (!rn2(3)) + return (0); + if (x < lowx) + lowx = x + xlim + 1; + else + hix = x - xlim - 1; + if (y < lowy) + lowy = y + ylim + 1; + else + hiy = y - ylim - 1; + goto chk; + } + } + } + + croom = &rooms[nroom]; + + /* on low levels the room is lit (usually) */ + /* secret vaults are always lit */ + if ((rnd(dlevel) < 10 && rn2(77)) || (ddx == 1 && ddy == 1)) { + for (x = lowx - 1; x <= hix + 1; x++) + for (y = lowy - 1; y <= hiy + 1; y++) + levl[x][y].lit = 1; + croom->rlit = 1; + } else + croom->rlit = 0; + croom->lx = lowx; + croom->hx = hix; + croom->ly = lowy; + croom->hy = hiy; + croom->rtype = croom->doorct = croom->fdoor = 0; + + for (x = lowx - 1; x <= hix + 1; x++) + for (y = lowy - 1; y <= hiy + 1; y += (hiy - lowy + 2)) { + levl[x][y].scrsym = '-'; + levl[x][y].typ = HWALL; + } + for (x = lowx - 1; x <= hix + 1; x += (hix - lowx + 2)) + for (y = lowy; y <= hiy; y++) { + levl[x][y].scrsym = '|'; + levl[x][y].typ = VWALL; + } + for (x = lowx; x <= hix; x++) + for (y = lowy; y <= hiy; y++) { + levl[x][y].scrsym = '.'; + levl[x][y].typ = ROOM; + } + + smeq[nroom] = nroom; + croom++; + croom->hx = -1; + nroom++; + return (1); +} + +void +makecorridors() +{ + int a, b; + + nxcor = 0; + for (a = 0; a < nroom - 1; a++) + join(a, a + 1); + for (a = 0; a < nroom - 2; a++) + if (smeq[a] != smeq[a + 2]) + join(a, a + 2); + for (a = 0; a < nroom; a++) + for (b = 0; b < nroom; b++) + if (smeq[a] != smeq[b]) + join(a, b); + if (nroom > 2) + for (nxcor = rn2(nroom) + 4; nxcor; nxcor--) { + a = rn2(nroom); + b = rn2(nroom - 2); + if (b >= a) + b += 2; + join(a, b); + } +} + +void +join(a, b) + int a, b; +{ + coord cc, tt; + int tx, ty, xx, yy; + struct rm *crm; + struct mkroom *croom, *troom; + int dx, dy, dix, diy, cct; + + croom = &rooms[a]; + troom = &rooms[b]; + + /* + * find positions cc and tt for doors in croom and troom and + * direction for a corridor between them + */ + + if (troom->hx < 0 || croom->hx < 0 || doorindex >= DOORMAX) + return; + if (troom->lx > croom->hx) { + dx = 1; + dy = 0; + xx = croom->hx + 1; + tx = troom->lx - 1; + cc = finddpos(xx, croom->ly, xx, croom->hy); + tt = finddpos(tx, troom->ly, tx, troom->hy); + } else if (troom->hy < croom->ly) { + dy = -1; + dx = 0; + yy = croom->ly - 1; + cc = finddpos(croom->lx, yy, croom->hx, yy); + ty = troom->hy + 1; + tt = finddpos(troom->lx, ty, troom->hx, ty); + } else if (troom->hx < croom->lx) { + dx = -1; + dy = 0; + xx = croom->lx - 1; + tx = troom->hx + 1; + cc = finddpos(xx, croom->ly, xx, croom->hy); + tt = finddpos(tx, troom->ly, tx, troom->hy); + } else { + dy = 1; + dx = 0; + yy = croom->hy + 1; + ty = troom->ly - 1; + cc = finddpos(croom->lx, yy, croom->hx, yy); + tt = finddpos(troom->lx, ty, troom->hx, ty); + } + xx = cc.x; + yy = cc.y; + tx = tt.x - dx; + ty = tt.y - dy; + if (nxcor && levl[xx + dx][yy + dy].typ) + return; + dodoor(xx, yy, croom); + + cct = 0; + while (xx != tx || yy != ty) { + xx += dx; + yy += dy; + + /* loop: dig corridor at [xx,yy] and find new [xx,yy] */ + if (cct++ > 500 || (nxcor && !rn2(35))) + return; + + if (xx == COLNO - 1 || xx == 0 || yy == 0 || yy == ROWNO - 1) + return; /* impossible */ + + crm = &levl[xx][yy]; + if (!(crm->typ)) { + if (rn2(100)) { + crm->typ = CORR; + crm->scrsym = CORR_SYM; + if (nxcor && !rn2(50)) + (void) mkobj_at(ROCK_SYM, xx, yy); + } else { + crm->typ = SCORR; + crm->scrsym = ' '; + } + } else if (crm->typ != CORR && crm->typ != SCORR) { + /* strange ... */ + return; + } + /* find next corridor position */ + dix = abs(xx - tx); + diy = abs(yy - ty); + + /* do we have to change direction ? */ + if (dy && dix > diy) { + int ddx = (xx > tx) ? -1 : 1; + + crm = &levl[xx + ddx][yy]; + if (!crm->typ || crm->typ == CORR || crm->typ == SCORR) { + dx = ddx; + dy = 0; + continue; + } + } else if (dx && diy > dix) { + int ddy = (yy > ty) ? -1 : 1; + + crm = &levl[xx][yy + ddy]; + if (!crm->typ || crm->typ == CORR || crm->typ == SCORR) { + dy = ddy; + dx = 0; + continue; + } + } + /* continue straight on? */ + crm = &levl[xx + dx][yy + dy]; + if (!crm->typ || crm->typ == CORR || crm->typ == SCORR) + continue; + + /* no, what must we do now?? */ + if (dx) { + dx = 0; + dy = (ty < yy) ? -1 : 1; + crm = &levl[xx + dx][yy + dy]; + if (!crm->typ || crm->typ == CORR || crm->typ == SCORR) + continue; + dy = -dy; + continue; + } else { + dy = 0; + dx = (tx < xx) ? -1 : 1; + crm = &levl[xx + dx][yy + dy]; + if (!crm->typ || crm->typ == CORR || crm->typ == SCORR) + continue; + dx = -dx; + continue; + } + } + + /* we succeeded in digging the corridor */ + dodoor(tt.x, tt.y, troom); + + if (smeq[a] < smeq[b]) + smeq[b] = smeq[a]; + else + smeq[a] = smeq[b]; +} + +void +make_niches() +{ + int ct = rnd(nroom / 2 + 1); + while (ct--) + makeniche(FALSE); +} + +void +makevtele() +{ + makeniche(TRUE); +} + +void +makeniche(with_trap) + boolean with_trap; +{ + struct mkroom *aroom; + struct rm *rm; + int vct = 8; + coord dd; + int dy, xx, yy; + struct trap *ttmp; + + if (doorindex < DOORMAX) + while (vct--) { + aroom = &rooms[rn2(nroom - 1)]; + if (aroom->rtype != 0) + continue; /* not an ordinary room */ + if (aroom->doorct == 1 && rn2(5)) + continue; + if (rn2(2)) { + dy = 1; + dd = finddpos(aroom->lx, aroom->hy + 1, aroom->hx, aroom->hy + 1); + } else { + dy = -1; + dd = finddpos(aroom->lx, aroom->ly - 1, aroom->hx, aroom->ly - 1); + } + xx = dd.x; + yy = dd.y; + if ((rm = &levl[xx][yy + dy])->typ) + continue; + if (with_trap || !rn2(4)) { + rm->typ = SCORR; + rm->scrsym = ' '; + if (with_trap) { + ttmp = maketrap(xx, yy + dy, TELEP_TRAP); + ttmp->once = 1; + make_engr_at(xx, yy - dy, "ad ae?ar um"); + } + dosdoor(xx, yy, aroom, SDOOR); + } else { + rm->typ = CORR; + rm->scrsym = CORR_SYM; + if (rn2(7)) + dosdoor(xx, yy, aroom, rn2(5) ? SDOOR : DOOR); + else { + mksobj_at(SCR_TELEPORTATION, xx, yy + dy); + if (!rn2(3)) + (void) mkobj_at(0, xx, yy + dy); + } + } + return; + } +} + +/* make a trap somewhere (in croom if mazeflag = 0) */ +void +mktrap(num, mazeflag, croom) + int num, mazeflag; + struct mkroom *croom; +{ + struct trap *ttmp; + int kind, nopierc, nomimic, fakedoor, fakegold, tryct = 0; + xchar mx, my; + + if (!num || num >= TRAPNUM) { + nopierc = (dlevel < 4) ? 1 : 0; + nomimic = (dlevel < 9 || goldseen) ? 1 : 0; + if (strchr(fut_geno, 'M')) + nomimic = 1; + kind = rn2(TRAPNUM - nopierc - nomimic); + /* note: PIERC = 7, MIMIC = 8, TRAPNUM = 9 */ + } else + kind = num; + + if (kind == MIMIC) { + struct monst *mtmp; + + fakedoor = (!rn2(3) && !mazeflag); + fakegold = (!fakedoor && !rn2(2)); + if (fakegold) + goldseen = TRUE; + do { + if (++tryct > 200) + return; + if (fakedoor) { + /* note: fakedoor maybe on actual door */ + if (rn2(2)) { + if (rn2(2)) + mx = croom->hx + 1; + else + mx = croom->lx - 1; + my = somey(); + } else { + if (rn2(2)) + my = croom->hy + 1; + else + my = croom->ly - 1; + mx = somex(); + } + } else if (mazeflag) { + coord mm; + mm = mazexy(); + mx = mm.x; + my = mm.y; + } else { + mx = somex(); + my = somey(); + } + } while (m_at(mx, my) || levl[mx][my].typ == STAIRS); + if ((mtmp = makemon(PM_MIMIC, mx, my)) != NULL) { + mtmp->mimic = 1; + mtmp->mappearance = + fakegold ? '$' : fakedoor ? '+' : + (mazeflag && rn2(2)) ? AMULET_SYM : + "=/)%?![<>"[rn2(9)]; + } + return; + } + do { + if (++tryct > 200) + return; + if (mazeflag) { + coord mm; + mm = mazexy(); + mx = mm.x; + my = mm.y; + } else { + mx = somex(); + my = somey(); + } + } while (t_at(mx, my) || levl[mx][my].typ == STAIRS); + ttmp = maketrap(mx, my, kind); + if (mazeflag && !rn2(10) && ttmp->ttyp < PIERC) + ttmp->tseen = 1; +} diff --git a/hack/hack.mkmaze.c b/hack/hack.mkmaze.c new file mode 100644 index 0000000..aa70c1f --- /dev/null +++ b/hack/hack.mkmaze.c @@ -0,0 +1,217 @@ +/* $NetBSD: hack.mkmaze.c,v 1.5 2001/03/25 20:44:01 jsm Exp $ */ + +/* + * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica, + * Amsterdam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - 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. + * + * - Neither the name of the Stichting Centrum voor Wiskunde en + * Informatica, 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER + * 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. + */ + +/* + * Copyright (c) 1982 Jay Fenlason + * 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. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``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 +#ifndef lint +__RCSID("$NetBSD: hack.mkmaze.c,v 1.5 2001/03/25 20:44:01 jsm Exp $"); +#endif /* not lint */ + +#include "hack.h" +#include "extern.h" +#include "def.mkroom.h" /* not really used */ +const struct permonst hell_hound = +{"hell hound", 'd', 12, 14, 2, 3, 6, 0}; + +void +makemaz() +{ + int x, y; + int zx, zy; + coord mm; + boolean al = (dlevel >= 30 && !flags.made_amulet); + + for (x = 2; x < COLNO - 1; x++) + for (y = 2; y < ROWNO - 1; y++) + levl[x][y].typ = (x % 2 && y % 2) ? 0 : HWALL; + if (al) { + struct monst *mtmp; + + zx = 2 * (COLNO / 4) - 1; + zy = 2 * (ROWNO / 4) - 1; + for (x = zx - 2; x < zx + 4; x++) + for (y = zy - 2; y <= zy + 2; y++) { + levl[x][y].typ = + (y == zy - 2 || y == zy + 2 || x == zx - 2 || x == zx + 3) ? POOL : + (y == zy - 1 || y == zy + 1 || x == zx - 1 || x == zx + 2) ? HWALL : + ROOM; + } + (void) mkobj_at(AMULET_SYM, zx, zy); + flags.made_amulet = 1; + walkfrom(zx + 4, zy); + if ((mtmp = makemon(&hell_hound, zx, zy)) != NULL) + mtmp->msleep = 1; + if ((mtmp = makemon(PM_WIZARD, zx + 1, zy)) != NULL) { + mtmp->msleep = 1; + flags.no_of_wizards = 1; + } + } else { + mm = mazexy(); + zx = mm.x; + zy = mm.y; + walkfrom(zx, zy); + (void) mksobj_at(WAN_WISHING, zx, zy); + (void) mkobj_at(ROCK_SYM, zx, zy); /* put a rock on top of + * it */ + } + + for (x = 2; x < COLNO - 1; x++) + for (y = 2; y < ROWNO - 1; y++) { + switch (levl[x][y].typ) { + case HWALL: + levl[x][y].scrsym = '-'; + break; + case ROOM: + levl[x][y].scrsym = '.'; + break; + } + } + for (x = rn1(8, 11); x; x--) { + mm = mazexy(); + (void) mkobj_at(rn2(2) ? GEM_SYM : 0, mm.x, mm.y); + } + for (x = rn1(10, 2); x; x--) { + mm = mazexy(); + (void) mkobj_at(ROCK_SYM, mm.x, mm.y); + } + mm = mazexy(); + (void) makemon(PM_MINOTAUR, mm.x, mm.y); + for (x = rn1(5, 7); x; x--) { + mm = mazexy(); + (void) makemon((struct permonst *) 0, mm.x, mm.y); + } + for (x = rn1(6, 7); x; x--) { + mm = mazexy(); + mkgold(0L, mm.x, mm.y); + } + for (x = rn1(6, 7); x; x--) + mktrap(0, 1, (struct mkroom *) 0); + mm = mazexy(); + levl[(xupstair = mm.x)][(yupstair = mm.y)].scrsym = '<'; + levl[xupstair][yupstair].typ = STAIRS; + xdnstair = ydnstair = 0; +} + +void +walkfrom(x, y) + int x, y; +{ + int q, a, dir; + int dirs[4]; + levl[x][y].typ = ROOM; + while (1) { + q = 0; + for (a = 0; a < 4; a++) + if (okay(x, y, a)) + dirs[q++] = a; + if (!q) + return; + dir = dirs[rn2(q)]; + move(&x, &y, dir); + levl[x][y].typ = ROOM; + move(&x, &y, dir); + walkfrom(x, y); + } +} + +void +move(x, y, dir) + int *x, *y; + int dir; +{ + switch (dir) { + case 0: + --(*y); + break; + case 1: + (*x)++; + break; + case 2: + (*y)++; + break; + case 3: + --(*x); + break; + } +} + +int +okay(x, y, dir) + int x, y; + int dir; +{ + move(&x, &y, dir); + move(&x, &y, dir); + if (x < 3 || y < 3 || x > COLNO - 3 || y > ROWNO - 3 || levl[x][y].typ != 0) + return (0); + else + return (1); +} + +coord +mazexy() +{ + coord mm; + mm.x = 3 + 2 * rn2(COLNO / 2 - 2); + mm.y = 3 + 2 * rn2(ROWNO / 2 - 2); + return mm; +} diff --git a/hack/hack.mkobj.c b/hack/hack.mkobj.c new file mode 100644 index 0000000..10ad24c --- /dev/null +++ b/hack/hack.mkobj.c @@ -0,0 +1,227 @@ +/* $NetBSD: hack.mkobj.c,v 1.5 2001/03/25 20:44:01 jsm Exp $ */ + +/* + * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica, + * Amsterdam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - 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. + * + * - Neither the name of the Stichting Centrum voor Wiskunde en + * Informatica, 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER + * 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. + */ + +/* + * Copyright (c) 1982 Jay Fenlason + * 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. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``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 +#ifndef lint +__RCSID("$NetBSD: hack.mkobj.c,v 1.5 2001/03/25 20:44:01 jsm Exp $"); +#endif /* not lint */ + +#include "hack.h" +#include "extern.h" + +char mkobjstr[] = "))[[!!!!????%%%%/=**))[[!!!!????%%%%/=**(%"; + +struct obj * +mkobj_at(let, x, y) + int let, x, y; +{ + struct obj *otmp = mkobj(let); + otmp->ox = x; + otmp->oy = y; + otmp->nobj = fobj; + fobj = otmp; + return (otmp); +} + +void +mksobj_at(otyp, x, y) + int otyp, x, y; +{ + struct obj *otmp = mksobj(otyp); + otmp->ox = x; + otmp->oy = y; + otmp->nobj = fobj; + fobj = otmp; +} + +struct obj * +mkobj(let) + int let; +{ + if (!let) + let = mkobjstr[rn2(sizeof(mkobjstr) - 1)]; + return ( + mksobj( + letter(let) ? + CORPSE + ((let > 'Z') ? (let - 'a' + 'Z' - '@' + 1) : (let - '@')) + : probtype(let) + ) + ); +} + + +struct obj zeroobj; + +struct obj * +mksobj(otyp) + int otyp; +{ + struct obj *otmp; + char let = objects[otyp].oc_olet; + + otmp = newobj(0); + *otmp = zeroobj; + otmp->age = moves; + otmp->o_id = flags.ident++; + otmp->quan = 1; + otmp->olet = let; + otmp->otyp = otyp; + otmp->dknown = strchr("/=!?*", let) ? 0 : 1; + switch (let) { + case WEAPON_SYM: + otmp->quan = (otmp->otyp <= ROCK) ? rn1(6, 6) : 1; + if (!rn2(11)) + otmp->spe = rnd(3); + else if (!rn2(10)) { + otmp->cursed = 1; + otmp->spe = -rnd(3); + } + break; + case FOOD_SYM: + if (otmp->otyp >= CORPSE) + break; +#ifdef NOT_YET_IMPLEMENTED + /* if tins are to be identified, need to adapt doname() etc */ + if (otmp->otyp == TIN) + otmp->spe = rnd(...); +#endif /* NOT_YET_IMPLEMENTED */ + /* fall into next case */ + case GEM_SYM: + otmp->quan = rn2(6) ? 1 : 2; + case TOOL_SYM: + case CHAIN_SYM: + case BALL_SYM: + case ROCK_SYM: + case POTION_SYM: + case SCROLL_SYM: + case AMULET_SYM: + break; + case ARMOR_SYM: + if (!rn2(8)) + otmp->cursed = 1; + if (!rn2(10)) + otmp->spe = rnd(3); + else if (!rn2(9)) { + otmp->spe = -rnd(3); + otmp->cursed = 1; + } + break; + case WAND_SYM: + if (otmp->otyp == WAN_WISHING) + otmp->spe = 3; + else + otmp->spe = rn1(5, + (objects[otmp->otyp].bits & NODIR) ? 11 : 4); + break; + case RING_SYM: + if (objects[otmp->otyp].bits & SPEC) { + if (!rn2(3)) { + otmp->cursed = 1; + otmp->spe = -rnd(2); + } else + otmp->spe = rnd(2); + } else if (otmp->otyp == RIN_TELEPORTATION || + otmp->otyp == RIN_AGGRAVATE_MONSTER || + otmp->otyp == RIN_HUNGER || !rn2(9)) + otmp->cursed = 1; + break; + default: + panic("impossible mkobj"); + } + otmp->owt = weight(otmp); + return (otmp); +} + +int +letter(c) + int c; +{ + return (('@' <= c && c <= 'Z') || ('a' <= c && c <= 'z')); +} + +int +weight(obj) + struct obj *obj; +{ + int wt = objects[obj->otyp].oc_weight; + return (wt ? wt * obj->quan : (obj->quan + 1) / 2); +} + +void +mkgold(long num, int x, int y) +{ + struct gold *gold; + long amount = (num ? num : 1 + (rnd(dlevel + 2) * rnd(30))); + + if ((gold = g_at(x, y)) != NULL) + gold->amount += amount; + else { + gold = newgold(); + gold->ngold = fgold; + gold->gx = x; + gold->gy = y; + gold->amount = amount; + fgold = gold; + /* do sth with display? */ + } +} diff --git a/hack/hack.mkshop.c b/hack/hack.mkshop.c new file mode 100644 index 0000000..8706a08 --- /dev/null +++ b/hack/hack.mkshop.c @@ -0,0 +1,368 @@ +/* $NetBSD: hack.mkshop.c,v 1.7 2002/08/22 01:49:34 chuck Exp $ */ + +/* + * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica, + * Amsterdam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - 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. + * + * - Neither the name of the Stichting Centrum voor Wiskunde en + * Informatica, 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER + * 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. + */ + +/* + * Copyright (c) 1982 Jay Fenlason + * 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. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``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 +#ifndef lint +__RCSID("$NetBSD: hack.mkshop.c,v 1.7 2002/08/22 01:49:34 chuck Exp $"); +#endif /* not lint */ + +#include +#ifndef QUEST +#include "hack.h" +#include "extern.h" +#include "def.mkroom.h" +#include "def.eshk.h" +#define ESHK ((struct eshk *)(&(shk->mextra[0]))) +const schar shprobs[] = {3, 3, 5, 5, 10, 10, 14, 50}; /* their probabilities */ + +void +mkshop() +{ + struct mkroom *sroom; + int sh, sx, sy, i = -1; + char let; + int roomno; + struct monst *shk; +#ifdef WIZARD + /* first determine shoptype */ + if (wizard) { + char *ep = getenv("SHOPTYPE"); + if (ep) { + if (*ep == 'z' || *ep == 'Z') { + mkzoo(ZOO); + return; + } + if (*ep == 'm' || *ep == 'M') { + mkzoo(MORGUE); + return; + } + if (*ep == 'b' || *ep == 'B') { + mkzoo(BEEHIVE); + return; + } + if (*ep == 's' || *ep == 'S') { + mkswamp(); + return; + } + for (i = 0; shtypes[i]; i++) + if (*ep == shtypes[i]) + break; + goto gottype; + } + } +gottype: +#endif /* WIZARD */ + for (sroom = &rooms[0], roomno = 0;; sroom++, roomno++) { + if (sroom->hx < 0) + return; + if (sroom - rooms >= nroom) { + pline("rooms not closed by -1?"); + return; + } + if (sroom->rtype) + continue; + if (!sroom->rlit || has_dnstairs(sroom) || has_upstairs(sroom)) + continue; + if ( +#ifdef WIZARD + (wizard && getenv("SHOPTYPE") && sroom->doorct != 0) || +#endif /* WIZARD */ + sroom->doorct == 1) + break; + } + + if (i < 0) { /* shoptype not yet determined */ + int j; + + for (j = rn2(100), i = 0; (j -= shprobs[i]) >= 0; i++) + if (!shtypes[i]) + break; /* superfluous */ + if (isbig(sroom) && i + SHOPBASE == WANDSHOP) + i = GENERAL - SHOPBASE; + } + sroom->rtype = i + SHOPBASE; + let = shtypes[i]; + sh = sroom->fdoor; + sx = doors[sh].x; + sy = doors[sh].y; + if (sx == sroom->lx - 1) + sx++; + else if (sx == sroom->hx + 1) + sx--; + else if (sy == sroom->ly - 1) + sy++; + else if (sy == sroom->hy + 1) + sy--; + else { +#ifdef WIZARD + /* This is said to happen sometimes, but I've never seen it. */ + if (wizard) { + int j = sroom->doorct; + + pline("Where is shopdoor?"); + pline("Room at (%d,%d),(%d,%d).", sroom->lx, sroom->ly, + sroom->hx, sroom->hy); + pline("doormax=%d doorct=%d fdoor=%d", + doorindex, sroom->doorct, sh); + while (j--) { + pline("door [%d,%d]", doors[sh].x, doors[sh].y); + sh++; + } + more(); + } +#endif /* WIZARD */ + return; + } + if (!(shk = makemon(PM_SHK, sx, sy))) + return; + shk->isshk = shk->mpeaceful = 1; + shk->msleep = 0; + shk->mtrapseen = ~0; /* we know all the traps already */ + ESHK->shoproom = roomno; + ESHK->shoplevel = dlevel; + ESHK->shd = doors[sh]; + ESHK->shk.x = sx; + ESHK->shk.y = sy; + ESHK->robbed = 0; + ESHK->visitct = 0; + ESHK->following = 0; + shk->mgold = 1000 + 30 * rnd(100); /* initial capital */ + ESHK->billct = 0; + findname(ESHK->shknam, let); + for (sx = sroom->lx; sx <= sroom->hx; sx++) + for (sy = sroom->ly; sy <= sroom->hy; sy++) { + struct monst *mtmp; + if ((sx == sroom->lx && doors[sh].x == sx - 1) || + (sx == sroom->hx && doors[sh].x == sx + 1) || + (sy == sroom->ly && doors[sh].y == sy - 1) || + (sy == sroom->hy && doors[sh].y == sy + 1)) + continue; + if (rn2(100) < dlevel && !m_at(sx, sy) && + (mtmp = makemon(PM_MIMIC, sx, sy))) { + mtmp->mimic = 1; + mtmp->mappearance = + (let && rn2(10) < dlevel) ? let : ']'; + continue; + } + (void) mkobj_at(let, sx, sy); + } +} + +void +mkzoo(type) + int type; +{ + struct mkroom *sroom; + struct monst *mon; + int sh, sx, sy, i; + int goldlim = 500 * dlevel; + int moct = 0; + + i = nroom; + for (sroom = &rooms[rn2(nroom)];; sroom++) { + if (sroom == &rooms[nroom]) + sroom = &rooms[0]; + if (!i-- || sroom->hx < 0) + return; + if (sroom->rtype) + continue; + if (type == MORGUE && sroom->rlit) + continue; + if (has_upstairs(sroom) || (has_dnstairs(sroom) && rn2(3))) + continue; + if (sroom->doorct == 1 || !rn2(5)) + break; + } + sroom->rtype = type; + sh = sroom->fdoor; + for (sx = sroom->lx; sx <= sroom->hx; sx++) + for (sy = sroom->ly; sy <= sroom->hy; sy++) { + if ((sx == sroom->lx && doors[sh].x == sx - 1) || + (sx == sroom->hx && doors[sh].x == sx + 1) || + (sy == sroom->ly && doors[sh].y == sy - 1) || + (sy == sroom->hy && doors[sh].y == sy + 1)) + continue; + mon = makemon( + (type == MORGUE) ? morguemon() : + (type == BEEHIVE) ? PM_KILLER_BEE : (struct permonst *) 0, + sx, sy); + if (mon) + mon->msleep = 1; + switch (type) { + case ZOO: + i = sq(dist2(sx, sy, doors[sh].x, doors[sh].y)); + if (i >= goldlim) + i = 5 * dlevel; + goldlim -= i; + mkgold((long) (10 + rn2(i)), sx, sy); + break; + case MORGUE: + /* + * Usually there is one dead body in the + * morgue + */ + if (!moct && rn2(3)) { + mksobj_at(CORPSE, sx, sy); + moct++; + } + break; + case BEEHIVE: + if (!rn2(3)) + mksobj_at(LUMP_OF_ROYAL_JELLY, sx, sy); + break; + } + } +} + +const struct permonst * +morguemon() +{ + int i = rn2(100), hd = rn2(dlevel); + + if (hd > 10 && i < 10) + return (PM_DEMON); + if (hd > 8 && i > 85) + return (PM_VAMPIRE); + return ((i < 40) ? PM_GHOST : (i < 60) ? PM_WRAITH : PM_ZOMBIE); +} + +void +mkswamp() +{ /* Michiel Huisjes & Fred de Wilde */ + struct mkroom *sroom; + int sx, sy, i, eelct = 0; + + for (i = 0; i < 5; i++) { /* 5 tries */ + sroom = &rooms[rn2(nroom)]; + if (sroom->hx < 0 || sroom->rtype || + has_upstairs(sroom) || has_dnstairs(sroom)) + continue; + + /* satisfied; make a swamp */ + sroom->rtype = SWAMP; + for (sx = sroom->lx; sx <= sroom->hx; sx++) + for (sy = sroom->ly; sy <= sroom->hy; sy++) + if ((sx + sy) % 2 && !o_at(sx, sy) && !t_at(sx, sy) + && !m_at(sx, sy) && !nexttodoor(sx, sy)) { + levl[sx][sy].typ = POOL; + levl[sx][sy].scrsym = POOL_SYM; + if (!eelct || !rn2(4)) { + (void) makemon(PM_EEL, sx, sy); + eelct++; + } + } + } +} + +int +nexttodoor(sx, sy) + int sx, sy; +{ + int dx, dy; + struct rm *lev; + for (dx = -1; dx <= 1; dx++) + for (dy = -1; dy <= 1; dy++) + if ((lev = &levl[sx + dx][sy + dy])->typ == DOOR || + lev->typ == SDOOR || lev->typ == LDOOR) + return (1); + return (0); +} + +int +has_dnstairs(sroom) + struct mkroom *sroom; +{ + return (sroom->lx <= xdnstair && xdnstair <= sroom->hx && + sroom->ly <= ydnstair && ydnstair <= sroom->hy); +} + +int +has_upstairs(sroom) + struct mkroom *sroom; +{ + return (sroom->lx <= xupstair && xupstair <= sroom->hx && + sroom->ly <= yupstair && yupstair <= sroom->hy); +} + +int +isbig(sroom) + struct mkroom *sroom; +{ + int area = (sroom->hx - sroom->lx) * (sroom->hy - sroom->ly); + return (area > 20); +} + +int +dist2(x0, y0, x1, y1) + int x0, y0, x1, y1; +{ + return ((x0 - x1) * (x0 - x1) + (y0 - y1) * (y0 - y1)); +} + +int +sq(a) + int a; +{ + return (a * a); +} +#endif /* QUEST */ diff --git a/hack/hack.mon.c b/hack/hack.mon.c new file mode 100644 index 0000000..bad4437 --- /dev/null +++ b/hack/hack.mon.c @@ -0,0 +1,1039 @@ +/* $NetBSD: hack.mon.c,v 1.5 2001/03/25 20:44:01 jsm Exp $ */ + +/* + * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica, + * Amsterdam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - 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. + * + * - Neither the name of the Stichting Centrum voor Wiskunde en + * Informatica, 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER + * 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. + */ + +/* + * Copyright (c) 1982 Jay Fenlason + * 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. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``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 +#ifndef lint +__RCSID("$NetBSD: hack.mon.c,v 1.5 2001/03/25 20:44:01 jsm Exp $"); +#endif /* not lint */ + +#include +#include "hack.h" +#include "extern.h" +#include "hack.mfndpos.h" + +#ifndef NULL +#define NULL (char *) 0 +#endif + +int warnlevel; /* used by movemon and dochugw */ +long lastwarntime; +int lastwarnlev; +const char *const warnings[] = { + "white", "pink", "red", "ruby", "purple", "black" +}; + +void +movemon() +{ + struct monst *mtmp; + int fr; + + warnlevel = 0; + + while (1) { + /* find a monster that we haven't treated yet */ + /* + * note that mtmp or mtmp->nmon might get killed while mtmp + * moves, so we cannot just walk down the chain (even new + * monsters might get created!) + */ + for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) + if (mtmp->mlstmv < moves) + goto next_mon; + /* treated all monsters */ + break; + +next_mon: + mtmp->mlstmv = moves; + + /* most monsters drown in pools */ + { + boolean inpool, iseel; + + inpool = (levl[mtmp->mx][mtmp->my].typ == POOL); + iseel = (mtmp->data->mlet == ';'); + if (inpool && !iseel) { + if (cansee(mtmp->mx, mtmp->my)) + pline("%s drowns.", Monnam(mtmp)); + mondead(mtmp); + continue; + } + /* but eels have a difficult time outside */ + if (iseel && !inpool) { + if (mtmp->mhp > 1) + mtmp->mhp--; + mtmp->mflee = 1; + mtmp->mfleetim += 2; + } + } + if (mtmp->mblinded && !--mtmp->mblinded) + mtmp->mcansee = 1; + if (mtmp->mfleetim && !--mtmp->mfleetim) + mtmp->mflee = 0; + if (mtmp->mimic) + continue; + if (mtmp->mspeed != MSLOW || !(moves % 2)) { + /* continue if the monster died fighting */ + fr = -1; + if (Conflict && cansee(mtmp->mx, mtmp->my) + && (fr = fightm(mtmp)) == 2) + continue; + if (fr < 0 && dochugw(mtmp)) + continue; + } + if (mtmp->mspeed == MFAST && dochugw(mtmp)) + continue; + } + + warnlevel -= u.ulevel; + if (warnlevel >= SIZE(warnings)) + warnlevel = SIZE(warnings) - 1; + if (warnlevel >= 0) + if (warnlevel > lastwarnlev || moves > lastwarntime + 5) { + const char *rr; + switch (Warning & (LEFT_RING | RIGHT_RING)) { + case LEFT_RING: + rr = "Your left ring glows"; + break; + case RIGHT_RING: + rr = "Your right ring glows"; + break; + case LEFT_RING | RIGHT_RING: + rr = "Both your rings glow"; + break; + default: + rr = "Your fingertips glow"; + break; + } + pline("%s %s!", rr, warnings[warnlevel]); + lastwarntime = moves; + lastwarnlev = warnlevel; + } + dmonsfree(); /* remove all dead monsters */ +} + +void +justswld(mtmp, name) + struct monst *mtmp; + const char *name; +{ + + mtmp->mx = u.ux; + mtmp->my = u.uy; + u.ustuck = mtmp; + pmon(mtmp); + kludge("%s swallows you!", name); + more(); + seeoff(1); + u.uswallow = 1; + u.uswldtim = 0; + swallowed(); +} + +void +youswld(mtmp, dam, die, name) + struct monst *mtmp; + int dam, die; + const char *name; +{ + if (mtmp != u.ustuck) + return; + kludge("%s digests you!", name); + u.uhp -= dam; + if ((int)u.uswldtim++ >= die) { /* a3 */ + pline("It totally digests you!"); + u.uhp = -1; + } + if (u.uhp < 1) + done_in_by(mtmp); +#if 0 + flags.botlx = 1; /* should we show status line ? */ +#endif +} + +int +dochugw(mtmp) + struct monst *mtmp; +{ + int x = mtmp->mx; + int y = mtmp->my; + int d = dochug(mtmp); + int dd; + if (!d) /* monster still alive */ + if (Warning) + if (!mtmp->mpeaceful) + if (mtmp->data->mlevel > warnlevel) + if ((dd = dist(mtmp->mx, mtmp->my)) < dist(x, y)) + if (dd < 100) + if (!canseemon(mtmp)) + warnlevel = mtmp->data->mlevel; + return (d); +} + +/* returns 1 if monster died moving, 0 otherwise */ +int +dochug(mtmp) + struct monst *mtmp; +{ + const struct permonst *mdat; + int tmp = 0, nearby, scared; + + if (mtmp->cham && !rn2(6)) + (void) newcham(mtmp, &mons[dlevel + 14 + rn2(CMNUM - 14 - dlevel)]); + mdat = mtmp->data; + if (mdat->mlevel < 0) + panic("bad monster %c (%d)", mdat->mlet, mdat->mlevel); + + /* regenerate monsters */ + if ((!(moves % 20) || strchr(MREGEN, mdat->mlet)) && + mtmp->mhp < mtmp->mhpmax) + mtmp->mhp++; + + if (mtmp->mfroz) + return (0); /* frozen monsters don't do anything */ + + if (mtmp->msleep) { + /* wake up, or get out of here. */ + /* ettins are hard to surprise */ + /* Nymphs and Leprechauns do not easily wake up */ + if (cansee(mtmp->mx, mtmp->my) && + (!Stealth || (mdat->mlet == 'e' && rn2(10))) && + (!strchr("NL", mdat->mlet) || !rn2(50)) && + (Aggravate_monster || strchr("d1", mdat->mlet) + || (!rn2(7) && !mtmp->mimic))) + mtmp->msleep = 0; + else + return (0); + } + /* not frozen or sleeping: wipe out texts written in the dust */ + wipe_engr_at(mtmp->mx, mtmp->my, 1); + + /* confused monsters get unconfused with small probability */ + if (mtmp->mconf && !rn2(50)) + mtmp->mconf = 0; + + /* some monsters teleport */ + if (mtmp->mflee && strchr("tNL", mdat->mlet) && !rn2(40)) { + rloc(mtmp); + return (0); + } + if (mdat->mmove < rnd(6)) + return (0); + + /* fleeing monsters might regain courage */ + if (mtmp->mflee && !mtmp->mfleetim + && mtmp->mhp == mtmp->mhpmax && !rn2(25)) + mtmp->mflee = 0; + + nearby = (dist(mtmp->mx, mtmp->my) < 3); + scared = (nearby && (sengr_at("Elbereth", u.ux, u.uy) || + sobj_at(SCR_SCARE_MONSTER, u.ux, u.uy))); + if (scared && !mtmp->mflee) { + mtmp->mflee = 1; + mtmp->mfleetim = (rn2(7) ? rnd(10) : rnd(100)); + } + if (!nearby || + mtmp->mflee || + mtmp->mconf || + (mtmp->minvis && !rn2(3)) || + (strchr("BIuy", mdat->mlet) && !rn2(4)) || + (mdat->mlet == 'L' && !u.ugold && (mtmp->mgold || rn2(2))) || + (!mtmp->mcansee && !rn2(4)) || + mtmp->mpeaceful + ) { + tmp = m_move(mtmp, 0); /* 2: monster died moving */ + if (tmp == 2 || (tmp && mdat->mmove <= 12)) + return (tmp == 2); + } + if (!strchr("Ea", mdat->mlet) && nearby && + !mtmp->mpeaceful && u.uhp > 0 && !scared) { + if (mhitu(mtmp)) + return (1); /* monster died (e.g. 'y' or 'F') */ + } + /* extra movement for fast monsters */ + if (mdat->mmove - 12 > rnd(12)) + tmp = m_move(mtmp, 1); + return (tmp == 2); +} + +int +m_move(struct monst *mtmp, int after) +{ + struct monst *mtmp2; + int nx, ny, omx, omy, appr, nearer, cnt, i, j; + xchar gx, gy, nix, niy, chcnt; + schar chi; + boolean likegold = 0, likegems = 0, likeobjs = 0; + char msym = mtmp->data->mlet; + schar mmoved = 0; /* not strictly nec.: chi >= 0 will + * do */ + coord poss[9]; + int info[9]; + + if (mtmp->mfroz || mtmp->msleep) + return (0); + if (mtmp->mtrapped) { + i = mintrap(mtmp); + if (i == 2) + return (2); /* he died */ + if (i == 1) + return (0); /* still in trap, so didnt move */ + } + if (mtmp->mhide && o_at(mtmp->mx, mtmp->my) && rn2(10)) + return (0); /* do not leave hiding place */ + +#ifndef NOWORM + if (mtmp->wormno) + goto not_special; +#endif /* NOWORM */ + + /* my dog gets a special treatment */ + if (mtmp->mtame) { + return (dog_move(mtmp, after)); + } + /* likewise for shopkeeper */ + if (mtmp->isshk) { + mmoved = shk_move(mtmp); + if (mmoved >= 0) + goto postmov; + mmoved = 0; /* follow player outside shop */ + } + /* and for the guard */ + if (mtmp->isgd) { + mmoved = gd_move(); + goto postmov; + } + /* + * teleport if that lies in our nature ('t') or when badly wounded + * ('1') + */ + if ((msym == 't' && !rn2(5)) + || (msym == '1' && (mtmp->mhp < 7 || (!xdnstair && !rn2(5)) + || levl[u.ux][u.uy].typ == STAIRS))) { + if (mtmp->mhp < 7 || (msym == 't' && rn2(2))) + rloc(mtmp); + else + mnexto(mtmp); + mmoved = 1; + goto postmov; + } + /* spit fire ('D') or use a wand ('1') when appropriate */ + if (strchr("D1", msym)) + inrange(mtmp); + + if (msym == 'U' && !mtmp->mcan && canseemon(mtmp) && + mtmp->mcansee && rn2(5)) { + if (!Confusion) + pline("%s's gaze has confused you!", Monnam(mtmp)); + else + pline("You are getting more and more confused."); + if (rn2(3)) + mtmp->mcan = 1; + Confusion += d(3, 4); /* timeout */ + } +not_special: + if (!mtmp->mflee && u.uswallow && u.ustuck != mtmp) + return (1); + appr = 1; + if (mtmp->mflee) + appr = -1; + if (mtmp->mconf || Invis || !mtmp->mcansee || + (strchr("BIy", msym) && !rn2(3))) + appr = 0; + omx = mtmp->mx; + omy = mtmp->my; + gx = u.ux; + gy = u.uy; + if (msym == 'L' && appr == 1 && mtmp->mgold > u.ugold) + appr = -1; + + /* + * random criterion for 'smell' or track finding ability should use + * mtmp->msmell or sth + */ + if (msym == '@' || + ('a' <= msym && msym <= 'z')) { + coord *cp; + schar mroom; + mroom = inroom(omx, omy); + if (mroom < 0 || mroom != inroom(u.ux, u.uy)) { + cp = gettrack(omx, omy); + if (cp) { + gx = cp->x; + gy = cp->y; + } + } + } + /* look for gold or jewels nearby */ + likegold = (strchr("LOD", msym) != NULL); + likegems = (strchr("ODu", msym) != NULL); + likeobjs = mtmp->mhide; +#define SRCHRADIUS 25 + { + xchar mind = SRCHRADIUS; /* not too far away */ + int dd; + if (likegold) { + struct gold *gold; + for (gold = fgold; gold; gold = gold->ngold) + if ((dd = DIST(omx, omy, gold->gx, gold->gy)) < mind) { + mind = dd; + gx = gold->gx; + gy = gold->gy; + } + } + if (likegems || likeobjs) { + struct obj *otmp; + for (otmp = fobj; otmp; otmp = otmp->nobj) + if (likeobjs || otmp->olet == GEM_SYM) + if (msym != 'u' || + objects[otmp->otyp].g_val != 0) + if ((dd = DIST(omx, omy, otmp->ox, otmp->oy)) < mind) { + mind = dd; + gx = otmp->ox; + gy = otmp->oy; + } + } + if (mind < SRCHRADIUS && appr == -1) { + if (dist(omx, omy) < 10) { + gx = u.ux; + gy = u.uy; + } else + appr = 1; + } + } + nix = omx; + niy = omy; + cnt = mfndpos(mtmp, poss, info, + msym == 'u' ? NOTONL : + (msym == '@' || msym == '1') ? (ALLOW_SSM | ALLOW_TRAPS) : + strchr(UNDEAD, msym) ? NOGARLIC : ALLOW_TRAPS); + /* ALLOW_ROCK for some monsters ? */ + chcnt = 0; + chi = -1; + for (i = 0; i < cnt; i++) { + nx = poss[i].x; + ny = poss[i].y; + for (j = 0; j < MTSZ && j < cnt - 1; j++) + if (nx == mtmp->mtrack[j].x && ny == mtmp->mtrack[j].y) + if (rn2(4 * (cnt - j))) + goto nxti; +#ifdef STUPID + /* some stupid compilers think that this is too complicated */ + { + int d1 = DIST(nx, ny, gx, gy); + int d2 = DIST(nix, niy, gx, gy); + nearer = (d1 < d2); + } +#else + nearer = (DIST(nx, ny, gx, gy) < DIST(nix, niy, gx, gy)); +#endif /* STUPID */ + if ((appr == 1 && nearer) || (appr == -1 && !nearer) || + !mmoved || + (!appr && !rn2(++chcnt))) { + nix = nx; + niy = ny; + chi = i; + mmoved = 1; + } +nxti: ; + } + if (mmoved) { + if (info[chi] & ALLOW_M) { + mtmp2 = m_at(nix, niy); + if (hitmm(mtmp, mtmp2) == 1 && rn2(4) && + hitmm(mtmp2, mtmp) == 2) + return (2); + return (0); + } + if (info[chi] & ALLOW_U) { + (void) hitu(mtmp, d(mtmp->data->damn, mtmp->data->damd) + 1); + return (0); + } + mtmp->mx = nix; + mtmp->my = niy; + for (j = MTSZ - 1; j > 0; j--) + mtmp->mtrack[j] = mtmp->mtrack[j - 1]; + mtmp->mtrack[0].x = omx; + mtmp->mtrack[0].y = omy; +#ifndef NOWORM + if (mtmp->wormno) + worm_move(mtmp); +#endif /* NOWORM */ + } else { + if (msym == 'u' && rn2(2)) { + rloc(mtmp); + return (0); + } +#ifndef NOWORM + if (mtmp->wormno) + worm_nomove(mtmp); +#endif /* NOWORM */ + } +postmov: + if (mmoved == 1) { + if (mintrap(mtmp) == 2) /* he died */ + return (2); + if (likegold) + mpickgold(mtmp); + if (likegems) + mpickgems(mtmp); + if (mtmp->mhide) + mtmp->mundetected = 1; + } + pmon(mtmp); + return (mmoved); +} + +void +mpickgold(mtmp) + struct monst *mtmp; +{ + struct gold *gold; + while ((gold = g_at(mtmp->mx, mtmp->my)) != NULL) { + mtmp->mgold += gold->amount; + freegold(gold); + if (levl[mtmp->mx][mtmp->my].scrsym == '$') + newsym(mtmp->mx, mtmp->my); + } +} + +void +mpickgems(mtmp) + struct monst *mtmp; +{ + struct obj *otmp; + for (otmp = fobj; otmp; otmp = otmp->nobj) + if (otmp->olet == GEM_SYM) + if (otmp->ox == mtmp->mx && otmp->oy == mtmp->my) + if (mtmp->data->mlet != 'u' || objects[otmp->otyp].g_val != 0) { + freeobj(otmp); + mpickobj(mtmp, otmp); + if (levl[mtmp->mx][mtmp->my].scrsym == GEM_SYM) + newsym(mtmp->mx, mtmp->my); /* %% */ + return; /* pick only one object */ + } +} + +/* return number of acceptable neighbour positions */ +int +mfndpos(mon, poss, info, flag) + struct monst *mon; + coord poss[9]; + int info[9], flag; +{ + int x, y, nx, ny, cnt = 0, ntyp; + struct monst *mtmp; + int nowtyp; + boolean pool; + + x = mon->mx; + y = mon->my; + nowtyp = levl[x][y].typ; + + pool = (mon->data->mlet == ';'); +nexttry: /* eels prefer the water, but if there is no + * water nearby, they will crawl over land */ + if (mon->mconf) { + flag |= ALLOW_ALL; + flag &= ~NOTONL; + } + for (nx = x - 1; nx <= x + 1; nx++) + for (ny = y - 1; ny <= y + 1; ny++) + if (nx != x || ny != y) + if (isok(nx, ny)) + if (!IS_ROCK(ntyp = levl[nx][ny].typ)) + if (!(nx != x && ny != y && (nowtyp == DOOR || ntyp == DOOR))) + if ((ntyp == POOL) == pool) { + info[cnt] = 0; + if (nx == u.ux && ny == u.uy) { + if (!(flag & ALLOW_U)) + continue; + info[cnt] = ALLOW_U; + } else if ((mtmp = m_at(nx, ny)) != NULL) { + if (!(flag & ALLOW_M)) + continue; + info[cnt] = ALLOW_M; + if (mtmp->mtame) { + if (!(flag & ALLOW_TM)) + continue; + info[cnt] |= ALLOW_TM; + } + } + if (sobj_at(CLOVE_OF_GARLIC, nx, ny)) { + if (flag & NOGARLIC) + continue; + info[cnt] |= NOGARLIC; + } + if (sobj_at(SCR_SCARE_MONSTER, nx, ny) || + (!mon->mpeaceful && sengr_at("Elbereth", nx, ny))) { + if (!(flag & ALLOW_SSM)) + continue; + info[cnt] |= ALLOW_SSM; + } + if (sobj_at(ENORMOUS_ROCK, nx, ny)) { + if (!(flag & ALLOW_ROCK)) + continue; + info[cnt] |= ALLOW_ROCK; + } + if (!Invis && online(nx, ny)) { + if (flag & NOTONL) + continue; + info[cnt] |= NOTONL; + } + /* + * we cannot + * avoid + * traps of + * an unknown + * kind + */ + { + struct trap *ttmp = t_at(nx, ny); + int tt; + if (ttmp) { + tt = 1 << ttmp->ttyp; + if (mon->mtrapseen & tt) { + if (!(flag & tt)) + continue; + info[cnt] |= tt; + } + } + } + poss[cnt].x = nx; + poss[cnt].y = ny; + cnt++; + } + if (!cnt && pool && nowtyp != POOL) { + pool = FALSE; + goto nexttry; + } + return (cnt); +} + +int +dist(x, y) + int x, y; +{ + return ((x - u.ux) * (x - u.ux) + (y - u.uy) * (y - u.uy)); +} + +void +poisoned(string, pname) + const char *string, *pname; +{ + int i; + + if (Blind) + pline("It was poisoned."); + else + pline("The %s was poisoned!", string); + if (Poison_resistance) { + pline("The poison doesn't seem to affect you."); + return; + } + i = rn2(10); + if (i == 0) { + u.uhp = -1; + pline("I am afraid the poison was deadly ..."); + } else if (i <= 5) { + losestr(rn1(3, 3)); + } else { + losehp(rn1(10, 6), pname); + } + if (u.uhp < 1) { + killer = pname; + done("died"); + } +} + +void +mondead(mtmp) + struct monst *mtmp; +{ + relobj(mtmp, 1); + unpmon(mtmp); + relmon(mtmp); + unstuck(mtmp); + if (mtmp->isshk) + shkdead(mtmp); + if (mtmp->isgd) + gddead(); +#ifndef NOWORM + if (mtmp->wormno) + wormdead(mtmp); +#endif /* NOWORM */ + monfree(mtmp); +} + +/* called when monster is moved to larger structure */ +void +replmon(mtmp, mtmp2) + struct monst *mtmp, *mtmp2; +{ + relmon(mtmp); + monfree(mtmp); + mtmp2->nmon = fmon; + fmon = mtmp2; + if (u.ustuck == mtmp) + u.ustuck = mtmp2; + if (mtmp2->isshk) + replshk(mtmp, mtmp2); + if (mtmp2->isgd) + replgd(mtmp, mtmp2); +} + +void +relmon(mon) + struct monst *mon; +{ + struct monst *mtmp; + + if (mon == fmon) + fmon = fmon->nmon; + else { + for (mtmp = fmon; mtmp->nmon != mon; mtmp = mtmp->nmon); + mtmp->nmon = mon->nmon; + } +} + +/* + * we do not free monsters immediately, in order to have their name available + * shortly after their demise + */ +struct monst *fdmon; /* chain of dead monsters, need not to be + * saved */ + +void +monfree(mtmp) + struct monst *mtmp; +{ + mtmp->nmon = fdmon; + fdmon = mtmp; +} + +void +dmonsfree() +{ + struct monst *mtmp; + while ((mtmp = fdmon) != NULL) { + fdmon = mtmp->nmon; + free((char *) mtmp); + } +} + +void +unstuck(mtmp) + struct monst *mtmp; +{ + if (u.ustuck == mtmp) { + if (u.uswallow) { + u.ux = mtmp->mx; + u.uy = mtmp->my; + u.uswallow = 0; + setsee(); + docrt(); + } + u.ustuck = 0; + } +} + +void +killed(mtmp) + struct monst *mtmp; +{ +#ifdef lint +#define NEW_SCORING +#endif /* lint */ + int tmp, nk, x, y; + const struct permonst *mdat; + + if (mtmp->cham) + mtmp->data = PM_CHAMELEON; + mdat = mtmp->data; + if (Blind) + pline("You destroy it!"); + else { + pline("You destroy %s!", + mtmp->mtame ? amonnam(mtmp, "poor") : monnam(mtmp)); + } + if (u.umconf) { + if (!Blind) + pline("Your hands stop glowing blue."); + u.umconf = 0; + } + /* count killed monsters */ +#define MAXMONNO 100 + nk = 1; /* in case we cannot find it in mons */ + tmp = mdat - mons; /* strchr in mons array (if not 'd', '@', ...) */ + if (tmp >= 0 && tmp < CMNUM + 2) { + u.nr_killed[tmp]++; + if ((nk = u.nr_killed[tmp]) > MAXMONNO && + !strchr(fut_geno, mdat->mlet)) + charcat(fut_geno, mdat->mlet); + } + /* punish bad behaviour */ + if (mdat->mlet == '@') + Telepat = 0, u.uluck -= 2; + if (mtmp->mpeaceful || mtmp->mtame) + u.uluck--; + if (mdat->mlet == 'u') + u.uluck -= 5; + if ((int) u.uluck < LUCKMIN) + u.uluck = LUCKMIN; + + /* give experience points */ + tmp = 1 + mdat->mlevel * mdat->mlevel; + if (mdat->ac < 3) + tmp += 2 * (7 - mdat->ac); + if (strchr("AcsSDXaeRTVWU&In:P", mdat->mlet)) + tmp += 2 * mdat->mlevel; + if (strchr("DeV&P", mdat->mlet)) + tmp += (7 * mdat->mlevel); + if (mdat->mlevel > 6) + tmp += 50; + if (mdat->mlet == ';') + tmp += 1000; + +#ifdef NEW_SCORING + /* + * ------- recent addition: make nr of points decrease when this is + * not the first of this kind + */ + { + int ul = u.ulevel; + int ml = mdat->mlevel; + + if (ul < 14) /* points are given based on present and + * future level */ + for (tmp2 = 0; !tmp2 || ul + tmp2 <= ml; tmp2++) + if (u.uexp + 1 + (tmp + ((tmp2 <= 0) ? 0 : 4 << (tmp2 - 1))) / nk + >= 10 * pow((unsigned) (ul - 1))) + if (++ul == 14) + break; + + tmp2 = ml - ul - 1; + tmp = (tmp + ((tmp2 < 0) ? 0 : 4 << tmp2)) / nk; + if (!tmp) + tmp = 1; + } + /* note: ul is not necessarily the future value of u.ulevel */ + /* ------- end of recent valuation change ------- */ +#endif /* NEW_SCORING */ + + more_experienced(tmp, 0); + flags.botl = 1; + while (u.ulevel < 14 && u.uexp >= newuexp()) { + pline("Welcome to experience level %u.", ++u.ulevel); + tmp = rnd(10); + if (tmp < 3) + tmp = rnd(10); + u.uhpmax += tmp; + u.uhp += tmp; + flags.botl = 1; + } + + /* dispose of monster and make cadaver */ + x = mtmp->mx; + y = mtmp->my; + mondead(mtmp); + tmp = mdat->mlet; + if (tmp == 'm') { /* he killed a minotaur, give him a wand of + * digging */ + /* note: the dead minotaur will be on top of it! */ + mksobj_at(WAN_DIGGING, x, y); + /* if(cansee(x,y)) atl(x,y,fobj->olet); */ + stackobj(fobj); + } else +#ifndef NOWORM + if (tmp == 'w') { + mksobj_at(WORM_TOOTH, x, y); + stackobj(fobj); + } else +#endif /* NOWORM */ + if (!letter(tmp) || (!strchr("mw", tmp) && !rn2(3))) + tmp = 0; + + if (ACCESSIBLE(levl[x][y].typ)) /* might be mimic in wall or dead eel */ + if (x != u.ux || y != u.uy) /* might be here after + * swallowed */ + if (strchr("NTVm&", mdat->mlet) || rn2(5)) { + struct obj *obj2 = mkobj_at(tmp, x, y); + if (cansee(x, y)) + atl(x, y, obj2->olet); + stackobj(obj2); + } +} + +void +kludge(const char *str, const char *arg) +{ + if (Blind) { + if (*str == '%') + pline(str, "It"); + else + pline(str, "it"); + } else + pline(str, arg); +} + +void +rescham() +{ /* force all chameleons to become normal */ + struct monst *mtmp; + + for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) + if (mtmp->cham) { + mtmp->cham = 0; + (void) newcham(mtmp, PM_CHAMELEON); + } +} + +int +newcham(mtmp, mdat) /* make a chameleon look like a new monster */ +/* returns 1 if the monster actually changed */ + struct monst *mtmp; + const struct permonst *mdat; +{ + int mhp, hpn, hpd; + + if (mdat == mtmp->data) + return (0); /* still the same monster */ +#ifndef NOWORM + if (mtmp->wormno) + wormdead(mtmp); /* throw tail away */ +#endif /* NOWORM */ + if (u.ustuck == mtmp) { + if (u.uswallow) { + u.uswallow = 0; + u.uswldtim = 0; + mnexto(mtmp); + docrt(); + prme(); + } + u.ustuck = 0; + } + hpn = mtmp->mhp; + hpd = (mtmp->data->mlevel) * 8; + if (!hpd) + hpd = 4; + mtmp->data = mdat; + mhp = (mdat->mlevel) * 8; + /* new hp: same fraction of max as before */ + mtmp->mhp = 2 + (hpn * mhp) / hpd; + hpn = mtmp->mhpmax; + mtmp->mhpmax = 2 + (hpn * mhp) / hpd; + mtmp->minvis = (mdat->mlet == 'I') ? 1 : 0; +#ifndef NOWORM + if (mdat->mlet == 'w' && getwn(mtmp)) + initworm(mtmp); + /* perhaps we should clear mtmp->mtame here? */ +#endif /* NOWORM */ + unpmon(mtmp); /* necessary for 'I' and to force pmon */ + pmon(mtmp); + return (1); +} + +void +mnexto(mtmp) /* Make monster mtmp next to you (if + * possible) */ + struct monst *mtmp; +{ + coord mm; + mm = enexto(u.ux, u.uy); + mtmp->mx = mm.x; + mtmp->my = mm.y; + pmon(mtmp); +} + +int +ishuman(mtmp) + struct monst *mtmp; +{ + return (mtmp->data->mlet == '@'); +} + +void +setmangry(mtmp) + struct monst *mtmp; +{ + if (!mtmp->mpeaceful) + return; + if (mtmp->mtame) + return; + mtmp->mpeaceful = 0; + if (ishuman(mtmp)) + pline("%s gets angry!", Monnam(mtmp)); +} + +/* + * not one hundred procent correct: now a snake may hide under an invisible + * object + */ +int +canseemon(mtmp) + struct monst *mtmp; +{ + return ((!mtmp->minvis || See_invisible) + && (!mtmp->mhide || !o_at(mtmp->mx, mtmp->my)) + && cansee(mtmp->mx, mtmp->my)); +} diff --git a/hack/hack.monst.c b/hack/hack.monst.c new file mode 100644 index 0000000..46f7313 --- /dev/null +++ b/hack/hack.monst.c @@ -0,0 +1,144 @@ +/* $NetBSD: hack.monst.c,v 1.5 2001/03/25 20:44:02 jsm Exp $ */ + +/* + * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica, + * Amsterdam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - 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. + * + * - Neither the name of the Stichting Centrum voor Wiskunde en + * Informatica, 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER + * 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. + */ + +/* + * Copyright (c) 1982 Jay Fenlason + * 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. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``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 +#ifndef lint +__RCSID("$NetBSD: hack.monst.c,v 1.5 2001/03/25 20:44:02 jsm Exp $"); +#endif /* not lint */ + +#include "hack.h" +#include "extern.h" +#include "def.eshk.h" + +const struct permonst mons[CMNUM + 2] = { + {"bat", 'B', 1, 22, 8, 1, 4, 0}, + {"gnome", 'G', 1, 6, 5, 1, 6, 0}, + {"hobgoblin", 'H', 1, 9, 5, 1, 8, 0}, + {"jackal", 'J', 0, 12, 7, 1, 2, 0}, + {"kobold", 'K', 1, 6, 7, 1, 4, 0}, + {"leprechaun", 'L', 5, 15, 8, 1, 2, 0}, + {"giant rat", 'r', 0, 12, 7, 1, 3, 0}, + {"acid blob", 'a', 2, 3, 8, 0, 0, 0}, + {"floating eye", 'E', 2, 1, 9, 0, 0, 0}, + {"homunculus", 'h', 2, 6, 6, 1, 3, 0}, + {"imp", 'i', 2, 6, 2, 1, 4, 0}, + {"orc", 'O', 2, 9, 6, 1, 8, 0}, + {"yellow light", 'y', 3, 15, 0, 0, 0, 0}, + {"zombie", 'Z', 2, 6, 8, 1, 8, 0}, + {"giant ant", 'A', 3, 18, 3, 1, 6, 0}, + {"fog cloud", 'f', 3, 1, 0, 1, 6, 0}, + {"nymph", 'N', 6, 12, 9, 1, 2, 0}, + {"piercer", 'p', 3, 1, 3, 2, 6, 0}, + {"quasit", 'Q', 3, 15, 3, 1, 4, 0}, + {"quivering blob", 'q', 3, 1, 8, 1, 8, 0}, + {"violet fungi", 'v', 3, 1, 7, 1, 4, 0}, + {"giant beetle", 'b', 4, 6, 4, 3, 4, 0}, + {"centaur", 'C', 4, 18, 4, 1, 6, 0}, + {"cockatrice", 'c', 4, 6, 6, 1, 3, 0}, + {"gelatinous cube", 'g', 4, 6, 8, 2, 4, 0}, + {"jaguar", 'j', 4, 15, 6, 1, 8, 0}, + {"killer bee", 'k', 4, 14, 4, 2, 4, 0}, + {"snake", 'S', 4, 15, 3, 1, 6, 0}, + {"freezing sphere", 'F', 2, 13, 4, 0, 0, 0}, + {"owlbear", 'o', 5, 12, 5, 2, 6, 0}, + {"rust monster", 'R', 10, 18, 3, 0, 0, 0}, + {"scorpion", 's', 5, 15, 3, 1, 4, 0}, + {"tengu", 't', 5, 13, 5, 1, 7, 0}, + {"wraith", 'W', 5, 12, 5, 1, 6, 0}, +#ifdef NOWORM + {"wumpus", 'w', 8, 3, 2, 3, 6, 0}, +#else + {"long worm", 'w', 8, 3, 5, 1, 4, 0}, +#endif /* NOWORM */ + {"large dog", 'd', 6, 15, 4, 2, 4, 0}, + {"leocrotta", 'l', 6, 18, 4, 3, 6, 0}, + {"mimic", 'M', 7, 3, 7, 3, 4, 0}, + {"troll", 'T', 7, 12, 4, 2, 7, 0}, + {"unicorn", 'u', 8, 24, 5, 1, 10, 0}, + {"yeti", 'Y', 5, 15, 6, 1, 6, 0}, + {"stalker", 'I', 8, 12, 3, 4, 4, 0}, + {"umber hulk", 'U', 9, 6, 2, 2, 10, 0}, + {"vampire", 'V', 8, 12, 1, 1, 6, 0}, + {"xorn", 'X', 8, 9, -2, 4, 6, 0}, + {"xan", 'x', 7, 18, -2, 2, 4, 0}, + {"zruty", 'z', 9, 8, 3, 3, 6, 0}, + {"chameleon", ':', 6, 5, 6, 4, 2, 0}, + {"dragon", 'D', 10, 9, -1, 3, 8, 0}, + {"ettin", 'e', 10, 12, 3, 2, 8, 0}, + {"lurker above", '\'', 10, 3, 3, 0, 0, 0}, + {"nurse", 'n', 11, 6, 0, 1, 3, 0}, + {"trapper", ',', 12, 3, 3, 0, 0, 0}, + {"purple worm", 'P', 15, 9, 6, 2, 8, 0}, + {"demon", '&', 10, 12, -4, 1, 4, 0}, + {"minotaur", 'm', 15, 15, 6, 4, 10, 0}, + {"shopkeeper", '@', 12, 18, 0, 4, 8, sizeof(struct eshk)} +}; + +const struct permonst pm_ghost = {"ghost", ' ', 10, 3, -5, 1, 1, sizeof(plname)}; +const struct permonst pm_wizard = { + "wizard of Yendor", '1', 15, 12, -2, 1, 12, 0 +}; +#ifdef MAIL +const struct permonst pm_mail_daemon = {"mail daemon", '2', 100, 1, 10, 0, 0, 0}; +#endif /* MAIL */ +const struct permonst pm_eel = {"giant eel", ';', 15, 6, -3, 3, 6, 0}; diff --git a/hack/hack.o_init.c b/hack/hack.o_init.c new file mode 100644 index 0000000..7df09fd --- /dev/null +++ b/hack/hack.o_init.c @@ -0,0 +1,247 @@ +/* $NetBSD: hack.o_init.c,v 1.6 2001/03/25 20:44:02 jsm Exp $ */ + +/* + * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica, + * Amsterdam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - 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. + * + * - Neither the name of the Stichting Centrum voor Wiskunde en + * Informatica, 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER + * 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. + */ + +/* + * Copyright (c) 1982 Jay Fenlason + * 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. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``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 +#ifndef lint +__RCSID("$NetBSD: hack.o_init.c,v 1.6 2001/03/25 20:44:02 jsm Exp $"); +#endif /* not lint */ + +#include +#include "hack.h" +#include "extern.h" +#include "def.objects.h" +#include "hack.onames.h" /* for LAST_GEM */ + +int +letindex(let) + char let; +{ + int i = 0; + char ch; + while ((ch = obj_symbols[i++]) != 0) + if (ch == let) + return (i); + return (0); +} + +void +init_objects() +{ + int i, j, first, last, sum, end; + char let; + const char *tmp; + /* + * init base; if probs given check that they add up to 100, otherwise + * compute probs; shuffle descriptions + */ + end = SIZE(objects); + first = 0; + while (first < end) { + let = objects[first].oc_olet; + last = first + 1; + while (last < end && objects[last].oc_olet == let + && objects[last].oc_name != NULL) + last++; + i = letindex(let); + if ((!i && let != ILLOBJ_SYM) || bases[i] != 0) + error("initialization error"); + bases[i] = first; + + if (let == GEM_SYM) + setgemprobs(); +check: + sum = 0; + for (j = first; j < last; j++) + sum += objects[j].oc_prob; + if (sum == 0) { + for (j = first; j < last; j++) + objects[j].oc_prob = (100 + j - first) / (last - first); + goto check; + } + if (sum != 100) + error("init-prob error for %c", let); + + if (objects[first].oc_descr != NULL && let != TOOL_SYM) { + /* shuffle, also some additional descriptions */ + while (last < end && objects[last].oc_olet == let) + last++; + j = last; + while (--j > first) { + i = first + rn2(j + 1 - first); + tmp = objects[j].oc_descr; + objects[j].oc_descr = objects[i].oc_descr; + objects[i].oc_descr = tmp; + } + } + first = last; + } +} + +int +probtype(let) + char let; +{ + int i = bases[letindex(let)]; + int prob = rn2(100); + while ((prob -= objects[i].oc_prob) >= 0) + i++; + if (objects[i].oc_olet != let || !objects[i].oc_name) + panic("probtype(%c) error, i=%d", let, i); + return (i); +} + +void +setgemprobs() +{ + int j, first; + + first = bases[letindex(GEM_SYM)]; + + for (j = 0; j < 9 - dlevel / 3; j++) + objects[first + j].oc_prob = 0; + first += j; + if (first >= LAST_GEM || first >= SIZE(objects) || + objects[first].oc_olet != GEM_SYM || + objects[first].oc_name == NULL) + printf("Not enough gems? - first=%d j=%d LAST_GEM=%d\n", + first, j, LAST_GEM); + for (j = first; j < LAST_GEM; j++) + objects[j].oc_prob = (20 + j - first) / (LAST_GEM - first); +} + +void +oinit() +{ /* level dependent initialization */ + setgemprobs(); +} + +void +savenames(fd) + int fd; +{ + int i; + unsigned len; + bwrite(fd, (char *) bases, sizeof bases); + bwrite(fd, (char *) objects, sizeof objects); + /* + * as long as we use only one version of Hack/Quest we need not save + * oc_name and oc_descr, but we must save oc_uname for all objects + */ + for (i = 0; i < SIZE(objects); i++) { + if (objects[i].oc_uname) { + len = strlen(objects[i].oc_uname) + 1; + bwrite(fd, (char *) &len, sizeof len); + bwrite(fd, objects[i].oc_uname, len); + } + } +} + +void +restnames(fd) + int fd; +{ + int i; + unsigned len; + mread(fd, (char *) bases, sizeof bases); + mread(fd, (char *) objects, sizeof objects); + for (i = 0; i < SIZE(objects); i++) + if (objects[i].oc_uname) { + mread(fd, (char *) &len, sizeof len); + objects[i].oc_uname = (char *) alloc(len); + mread(fd, objects[i].oc_uname, len); + } +} + +int +dodiscovered() +{ /* free after Robert Viduya */ + int i, end; + int ct = 0; + + cornline(0, "Discoveries"); + + end = SIZE(objects); + for (i = 0; i < end; i++) { + if (interesting_to_discover(i)) { + ct++; + cornline(1, typename(i)); + } + } + if (ct == 0) { + pline("You haven't discovered anything yet..."); + cornline(3, (char *) 0); + } else + cornline(2, (char *) 0); + + return (0); +} + +int +interesting_to_discover(i) + int i; +{ + return ( + objects[i].oc_uname != NULL || + (objects[i].oc_name_known && objects[i].oc_descr != NULL) + ); +} diff --git a/hack/hack.objnam.c b/hack/hack.objnam.c new file mode 100644 index 0000000..7d1fd2c --- /dev/null +++ b/hack/hack.objnam.c @@ -0,0 +1,643 @@ +/* $NetBSD: hack.objnam.c,v 1.5 2001/03/25 20:44:02 jsm Exp $ */ + +/* + * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica, + * Amsterdam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - 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. + * + * - Neither the name of the Stichting Centrum voor Wiskunde en + * Informatica, 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER + * 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. + */ + +/* + * Copyright (c) 1982 Jay Fenlason + * 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. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``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 +#ifndef lint +__RCSID("$NetBSD: hack.objnam.c,v 1.5 2001/03/25 20:44:02 jsm Exp $"); +#endif /* not lint */ + +#include +#include "hack.h" +#include "extern.h" +#define Sprintf (void) sprintf +#define Strcat (void) strcat +#define Strcpy (void) strcpy +#define PREFIX 15 + +char * +strprepend(s, pref) + char *s, *pref; +{ + int i = strlen(pref); + if (i > PREFIX) { + pline("WARNING: prefix too short."); + return (s); + } + s -= i; + (void) strncpy(s, pref, i); /* do not copy trailing 0 */ + return (s); +} + +char * +sitoa(a) + int a; +{ + static char buf[13]; + Sprintf(buf, (a < 0) ? "%d" : "+%d", a); + return (buf); +} + +char * +typename(otyp) + int otyp; +{ + static char buf[BUFSZ]; + struct objclass *ocl = &objects[otyp]; + const char *an = ocl->oc_name; + const char *dn = ocl->oc_descr; + char *un = ocl->oc_uname; + int nn = ocl->oc_name_known; + switch (ocl->oc_olet) { + case POTION_SYM: + Strcpy(buf, "potion"); + break; + case SCROLL_SYM: + Strcpy(buf, "scroll"); + break; + case WAND_SYM: + Strcpy(buf, "wand"); + break; + case RING_SYM: + Strcpy(buf, "ring"); + break; + default: + if (nn) { + Strcpy(buf, an); + if (otyp >= TURQUOISE && otyp <= JADE) + Strcat(buf, " stone"); + if (un) + Sprintf(eos(buf), " called %s", un); + if (dn) + Sprintf(eos(buf), " (%s)", dn); + } else { + Strcpy(buf, dn ? dn : an); + if (ocl->oc_olet == GEM_SYM) + Strcat(buf, " gem"); + if (un) + Sprintf(eos(buf), " called %s", un); + } + return (buf); + } + /* here for ring/scroll/potion/wand */ + if (nn) + Sprintf(eos(buf), " of %s", an); + if (un) + Sprintf(eos(buf), " called %s", un); + if (dn) + Sprintf(eos(buf), " (%s)", dn); + return (buf); +} + +char * +xname(obj) + struct obj *obj; +{ + static char bufr[BUFSZ]; + char *buf = &(bufr[PREFIX]); /* leave room for "17 -3 " */ + int nn = objects[obj->otyp].oc_name_known; + const char *an = objects[obj->otyp].oc_name; + const char *dn = objects[obj->otyp].oc_descr; + char *un = objects[obj->otyp].oc_uname; + int pl = (obj->quan != 1); + if (!obj->dknown && !Blind) + obj->dknown = 1;/* %% doesnt belong here */ + switch (obj->olet) { + case AMULET_SYM: + Strcpy(buf, (obj->spe < 0 && obj->known) + ? "cheap plastic imitation of the " : ""); + Strcat(buf, "Amulet of Yendor"); + break; + case TOOL_SYM: + if (!nn) { + Strcpy(buf, dn); + break; + } + Strcpy(buf, an); + break; + case FOOD_SYM: + if (obj->otyp == DEAD_HOMUNCULUS && pl) { + pl = 0; + Strcpy(buf, "dead homunculi"); + break; + } + /* fungis ? */ + /* fall into next case */ + case WEAPON_SYM: + if (obj->otyp == WORM_TOOTH && pl) { + pl = 0; + Strcpy(buf, "worm teeth"); + break; + } + if (obj->otyp == CRYSKNIFE && pl) { + pl = 0; + Strcpy(buf, "crysknives"); + break; + } + /* fall into next case */ + case ARMOR_SYM: + case CHAIN_SYM: + case ROCK_SYM: + Strcpy(buf, an); + break; + case BALL_SYM: + Sprintf(buf, "%sheavy iron ball", + (obj->owt > objects[obj->otyp].oc_weight) ? "very " : ""); + break; + case POTION_SYM: + if (nn || un || !obj->dknown) { + Strcpy(buf, "potion"); + if (pl) { + pl = 0; + Strcat(buf, "s"); + } + if (!obj->dknown) + break; + if (un) { + Strcat(buf, " called "); + Strcat(buf, un); + } else { + Strcat(buf, " of "); + Strcat(buf, an); + } + } else { + Strcpy(buf, dn); + Strcat(buf, " potion"); + } + break; + case SCROLL_SYM: + Strcpy(buf, "scroll"); + if (pl) { + pl = 0; + Strcat(buf, "s"); + } + if (!obj->dknown) + break; + if (nn) { + Strcat(buf, " of "); + Strcat(buf, an); + } else if (un) { + Strcat(buf, " called "); + Strcat(buf, un); + } else { + Strcat(buf, " labeled "); + Strcat(buf, dn); + } + break; + case WAND_SYM: + if (!obj->dknown) + Sprintf(buf, "wand"); + else if (nn) + Sprintf(buf, "wand of %s", an); + else if (un) + Sprintf(buf, "wand called %s", un); + else + Sprintf(buf, "%s wand", dn); + break; + case RING_SYM: + if (!obj->dknown) + Sprintf(buf, "ring"); + else if (nn) + Sprintf(buf, "ring of %s", an); + else if (un) + Sprintf(buf, "ring called %s", un); + else + Sprintf(buf, "%s ring", dn); + break; + case GEM_SYM: + if (!obj->dknown) { + Strcpy(buf, "gem"); + break; + } + if (!nn) { + Sprintf(buf, "%s gem", dn); + break; + } + Strcpy(buf, an); + if (obj->otyp >= TURQUOISE && obj->otyp <= JADE) + Strcat(buf, " stone"); + break; + default: + Sprintf(buf, "glorkum %c (0%o) %u %d", + obj->olet, obj->olet, obj->otyp, obj->spe); + } + if (pl) { + char *p; + + for (p = buf; *p; p++) { + if (!strncmp(" of ", p, 4)) { + /* pieces of, cloves of, lumps of */ + int c1, c2 = 's'; + + do { + c1 = c2; + c2 = *p; + *p++ = c1; + } while (c1); + goto nopl; + } + } + p = eos(buf) - 1; + if (*p == 's' || *p == 'z' || *p == 'x' || + (*p == 'h' && p[-1] == 's')) + Strcat(buf, "es"); /* boxes */ + else if (*p == 'y' && !strchr(vowels, p[-1])) + Strcpy(p, "ies"); /* rubies, zruties */ + else + Strcat(buf, "s"); + } +nopl: + if (obj->onamelth) { + Strcat(buf, " named "); + Strcat(buf, ONAME(obj)); + } + return (buf); +} + +char * +doname(obj) + struct obj *obj; +{ + char prefix[PREFIX]; + char *bp = xname(obj); + if (obj->quan != 1) + Sprintf(prefix, "%u ", obj->quan); + else + Strcpy(prefix, "a "); + switch (obj->olet) { + case AMULET_SYM: + if (strncmp(bp, "cheap ", 6)) + Strcpy(prefix, "the "); + break; + case ARMOR_SYM: + if (obj->owornmask & W_ARMOR) + Strcat(bp, " (being worn)"); + /* fall into next case */ + case WEAPON_SYM: + if (obj->known) { + Strcat(prefix, sitoa(obj->spe)); + Strcat(prefix, " "); + } + break; + case WAND_SYM: + if (obj->known) + Sprintf(eos(bp), " (%d)", obj->spe); + break; + case RING_SYM: + if (obj->owornmask & W_RINGR) + Strcat(bp, " (on right hand)"); + if (obj->owornmask & W_RINGL) + Strcat(bp, " (on left hand)"); + if (obj->known && (objects[obj->otyp].bits & SPEC)) { + Strcat(prefix, sitoa(obj->spe)); + Strcat(prefix, " "); + } + break; + } + if (obj->owornmask & W_WEP) + Strcat(bp, " (weapon in hand)"); + if (obj->unpaid) + Strcat(bp, " (unpaid)"); + if (!strcmp(prefix, "a ") && strchr(vowels, *bp)) + Strcpy(prefix, "an "); + bp = strprepend(bp, prefix); + return (bp); +} + +/* used only in hack.fight.c (thitu) */ +void +setan(const char *str, char *buf) +{ + if (strchr(vowels, *str)) + Sprintf(buf, "an %s", str); + else + Sprintf(buf, "a %s", str); +} + +char * +aobjnam(otmp, verb) + struct obj *otmp; + const char *verb; +{ + char *bp = xname(otmp); + char prefix[PREFIX]; + if (otmp->quan != 1) { + Sprintf(prefix, "%u ", otmp->quan); + bp = strprepend(bp, prefix); + } + if (verb) { + /* verb is given in plural (i.e., without trailing s) */ + Strcat(bp, " "); + if (otmp->quan != 1) + Strcat(bp, verb); + else if (!strcmp(verb, "are")) + Strcat(bp, "is"); + else { + Strcat(bp, verb); + Strcat(bp, "s"); + } + } + return (bp); +} + +char * +Doname(obj) + struct obj *obj; +{ + char *s = doname(obj); + + if ('a' <= *s && *s <= 'z') + *s -= ('a' - 'A'); + return (s); +} + +const char *const wrp[] = {"wand", "ring", "potion", "scroll", "gem"}; +const char wrpsym[] = {WAND_SYM, RING_SYM, POTION_SYM, SCROLL_SYM, GEM_SYM}; + +struct obj * +readobjnam(bp) + char *bp; +{ + char *p; + int i; + int cnt, spe, spesgn, typ, heavy; + char let; + char *un, *dn, *an; + /* int the = 0; char *oname = 0; */ + cnt = spe = spesgn = typ = heavy = 0; + let = 0; + an = dn = un = 0; + for (p = bp; *p; p++) + if ('A' <= *p && *p <= 'Z') + *p += 'a' - 'A'; + if (!strncmp(bp, "the ", 4)) { + /* the = 1; */ + bp += 4; + } else if (!strncmp(bp, "an ", 3)) { + cnt = 1; + bp += 3; + } else if (!strncmp(bp, "a ", 2)) { + cnt = 1; + bp += 2; + } + if (!cnt && digit(*bp)) { + cnt = atoi(bp); + while (digit(*bp)) + bp++; + while (*bp == ' ') + bp++; + } + if (!cnt) + cnt = 1; /* %% what with "gems" etc. ? */ + + if (*bp == '+' || *bp == '-') { + spesgn = (*bp++ == '+') ? 1 : -1; + spe = atoi(bp); + while (digit(*bp)) + bp++; + while (*bp == ' ') + bp++; + } else { + p = strrchr(bp, '('); + if (p) { + if (p > bp && p[-1] == ' ') + p[-1] = 0; + else + *p = 0; + p++; + spe = atoi(p); + while (digit(*p)) + p++; + if (strcmp(p, ")")) + spe = 0; + else + spesgn = 1; + } + } + /* + * now we have the actual name, as delivered by xname, say green + * potions called whisky scrolls labeled "QWERTY" egg dead zruties + * fortune cookies very heavy iron ball named hoei wand of wishing + * elven cloak + */ + for (p = bp; *p; p++) + if (!strncmp(p, " named ", 7)) { + *p = 0; + /* oname = p+7; */ + } + for (p = bp; *p; p++) + if (!strncmp(p, " called ", 8)) { + *p = 0; + un = p + 8; + } + for (p = bp; *p; p++) + if (!strncmp(p, " labeled ", 9)) { + *p = 0; + dn = p + 9; + } + /* first change to singular if necessary */ + if (cnt != 1) { + /* find "cloves of garlic", "worthless pieces of blue glass" */ + for (p = bp; *p; p++) + if (!strncmp(p, "s of ", 5)) { + while ((*p = p[1]) != '\0') + p++; + goto sing; + } + /* remove -s or -es (boxes) or -ies (rubies, zruties) */ + p = eos(bp); + if (p[-1] == 's') { + if (p[-2] == 'e') { + if (p[-3] == 'i') { + if (!strcmp(p - 7, "cookies")) + goto mins; + Strcpy(p - 3, "y"); + goto sing; + } + /* note: cloves / knives from clove / knife */ + if (!strcmp(p - 6, "knives")) { + Strcpy(p - 3, "fe"); + goto sing; + } + /* note: nurses, axes but boxes */ + if (!strcmp(p - 5, "boxes")) { + p[-2] = 0; + goto sing; + } + } + mins: + p[-1] = 0; + } else { + if (!strcmp(p - 9, "homunculi")) { + Strcpy(p - 1, "us"); /* !! makes string + * longer */ + goto sing; + } + if (!strcmp(p - 5, "teeth")) { + Strcpy(p - 5, "tooth"); + goto sing; + } + /* here we cannot find the plural suffix */ + } + } +sing: + if (!strcmp(bp, "amulet of yendor")) { + typ = AMULET_OF_YENDOR; + goto typfnd; + } + p = eos(bp); + if (!strcmp(p - 5, " mail")) { /* Note: ring mail is not a ring ! */ + let = ARMOR_SYM; + an = bp; + goto srch; + } + for (i = 0; i < (int)sizeof(wrpsym); i++) { + int j = strlen(wrp[i]); + if (!strncmp(bp, wrp[i], j)) { + let = wrpsym[i]; + bp += j; + if (!strncmp(bp, " of ", 4)) + an = bp + 4; + /* else if(*bp) ?? */ + goto srch; + } + if (!strcmp(p - j, wrp[i])) { + let = wrpsym[i]; + p -= j; + *p = 0; + if (p[-1] == ' ') + p[-1] = 0; + dn = bp; + goto srch; + } + } + if (!strcmp(p - 6, " stone")) { + p[-6] = 0; + let = GEM_SYM; + an = bp; + goto srch; + } + if (!strcmp(bp, "very heavy iron ball")) { + heavy = 1; + typ = HEAVY_IRON_BALL; + goto typfnd; + } + an = bp; +srch: + if (!an && !dn && !un) + goto any; + i = 1; + if (let) + i = bases[letindex(let)]; + while (i <= NROFOBJECTS && (!let || objects[i].oc_olet == let)) { + const char *zn = objects[i].oc_name; + + if (!zn) + goto nxti; + if (an && strcmp(an, zn)) + goto nxti; + if (dn && (!(zn = objects[i].oc_descr) || strcmp(dn, zn))) + goto nxti; + if (un && (!(zn = objects[i].oc_uname) || strcmp(un, zn))) + goto nxti; + typ = i; + goto typfnd; +nxti: + i++; + } +any: + if (!let) + let = wrpsym[rn2(sizeof(wrpsym))]; + typ = probtype(let); +typfnd: + { + struct obj *otmp; + let = objects[typ].oc_olet; + otmp = mksobj(typ); + if (heavy) + otmp->owt += 15; + if (cnt > 0 && strchr("%?!*)", let) && + (cnt < 4 || (let == WEAPON_SYM && typ <= ROCK && cnt < 20))) + otmp->quan = cnt; + + if (spe > 3 && spe > otmp->spe) + spe = 0; + else if (let == WAND_SYM) + spe = otmp->spe; + if (spe == 3 && u.uluck < 0) + spesgn = -1; + if (let != WAND_SYM && spesgn == -1) + spe = -spe; + if (let == BALL_SYM) + spe = 0; + else if (let == AMULET_SYM) + spe = -1; + else if (typ == WAN_WISHING && rn2(10)) + spe = (rn2(10) ? -1 : 0); + otmp->spe = spe; + + if (spesgn == -1) + otmp->cursed = 1; + + return (otmp); + } +} diff --git a/hack/hack.options.c b/hack/hack.options.c new file mode 100644 index 0000000..8d29603 --- /dev/null +++ b/hack/hack.options.c @@ -0,0 +1,276 @@ +/* $NetBSD: hack.options.c,v 1.5 2001/02/05 00:37:43 christos Exp $ */ + +/* + * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica, + * Amsterdam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - 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. + * + * - Neither the name of the Stichting Centrum voor Wiskunde en + * Informatica, 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER + * 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. + */ + +/* + * Copyright (c) 1982 Jay Fenlason + * 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. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``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 +#ifndef lint +__RCSID("$NetBSD: hack.options.c,v 1.5 2001/02/05 00:37:43 christos Exp $"); +#endif /* not lint */ + +#include +#include +#include "hack.h" +#include "extern.h" + +void +initoptions() +{ + char *opts; + + flags.time = flags.nonews = flags.notombstone = flags.end_own = + flags.standout = flags.nonull = FALSE; + flags.no_rest_on_space = TRUE; + flags.invlet_constant = TRUE; + flags.end_top = 5; + flags.end_around = 4; + flags.female = FALSE; /* players are usually male */ + + if ((opts = getenv("HACKOPTIONS")) != NULL) + parseoptions(opts, TRUE); +} + +void +parseoptions(opts, from_env) + char *opts; + boolean from_env; +{ + char *op, *op2; + unsigned num; + boolean negated; + + if ((op = strchr(opts, ',')) != NULL) { + *op++ = 0; + parseoptions(op, from_env); + } + if ((op = strchr(opts, ' ')) != NULL) { + op2 = op; + while (*op++) + if (*op != ' ') + *op2++ = *op; + } + if (!*opts) + return; + negated = FALSE; + while ((*opts == '!') || !strncmp(opts, "no", 2)) { + if (*opts == '!') + opts++; + else + opts += 2; + negated = !negated; + } + + if (!strncmp(opts, "standout", 8)) { + flags.standout = !negated; + return; + } + if (!strncmp(opts, "null", 3)) { + flags.nonull = negated; + return; + } + if (!strncmp(opts, "tombstone", 4)) { + flags.notombstone = negated; + return; + } + if (!strncmp(opts, "news", 4)) { + flags.nonews = negated; + return; + } + if (!strncmp(opts, "time", 4)) { + flags.time = !negated; + flags.botl = 1; + return; + } + if (!strncmp(opts, "restonspace", 4)) { + flags.no_rest_on_space = negated; + return; + } + if (!strncmp(opts, "fixinv", 4)) { + if (from_env) + flags.invlet_constant = !negated; + else + pline("The fixinvlet option must be in HACKOPTIONS."); + return; + } + if (!strncmp(opts, "male", 4)) { + flags.female = negated; + return; + } + if (!strncmp(opts, "female", 6)) { + flags.female = !negated; + return; + } + /* name:string */ + if (!strncmp(opts, "name", 4)) { + if (!from_env) { + pline("The playername can be set only from HACKOPTIONS."); + return; + } + op = strchr(opts, ':'); + if (!op) + goto bad; + (void) strncpy(plname, op + 1, sizeof(plname) - 1); + return; + } + /* endgame:5t[op] 5a[round] o[wn] */ + if (!strncmp(opts, "endgame", 3)) { + op = strchr(opts, ':'); + if (!op) + goto bad; + op++; + while (*op) { + num = 1; + if (digit(*op)) { + num = atoi(op); + while (digit(*op)) + op++; + } else if (*op == '!') { + negated = !negated; + op++; + } + switch (*op) { + case 't': + flags.end_top = num; + break; + case 'a': + flags.end_around = num; + break; + case 'o': + flags.end_own = !negated; + break; + default: + goto bad; + } + while (letter(*++op)); + if (*op == '/') + op++; + } + return; + } +bad: + if (!from_env) { + if (!strncmp(opts, "help", 4)) { + pline("%s%s%s", + "To set options use `HACKOPTIONS=\"\"' in your environment, or ", + "give the command 'o' followed by the line `' while playing. ", + "Here is a list of