Initial revision

git-svn-id: file:///srv/svn/joey/bsdgames-trunk@5198 a4a2c43b-8ac3-0310-8836-e0e880c912e2
This commit is contained in:
joey
2003-03-29 12:05:29 +00:00
parent 4303fb4517
commit a6166b0988
80 changed files with 26217 additions and 0 deletions

33
hack/COPYRIGHT Normal file
View File

@@ -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.

28
hack/COPYRIGHT-JF Normal file
View File

@@ -0,0 +1,28 @@
$NetBSD$
/*
* Copyright (c) 1982 Jay Fenlason <hack@gnu.org>
* 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.
*/

117
hack/alloc.c Normal file
View File

@@ -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 <hack@gnu.org>
* 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 <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: alloc.c,v 1.4 1997/10/19 16:56:47 christos Exp $");
#endif /* not lint */
#include <stdlib.h>
#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 <stdio.h>) 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 */

205
hack/config.h Normal file
View File

@@ -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 <hack@gnu.org>
* 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
* <sys/wait.h> <wait.h>
* <sys/time.h> <time.h>
* <sgtty.h> <termio.h>
* 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 <wait.h> nor <sys/wait.h> 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 */

64
hack/date.h Normal file
View File

@@ -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 <hack@gnu.org>
* 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";

76
hack/def.edog.h Normal file
View File

@@ -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 <hack@gnu.org>
* 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_ */

88
hack/def.eshk.h Normal file
View File

@@ -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 <hack@gnu.org>
* 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_ */

105
hack/def.flag.h Normal file
View File

@@ -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 <hack@gnu.org>
* 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_ */

79
hack/def.func_tab.h Normal file
View File

@@ -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 <hack@gnu.org>
* 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_ */

77
hack/def.gen.h Normal file
View File

@@ -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 <hack@gnu.org>
* 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_ */

74
hack/def.gold.h Normal file
View File

@@ -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 <hack@gnu.org>
* 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_ */

89
hack/def.mkroom.h Normal file
View File

@@ -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 <hack@gnu.org>
* 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_ */

122
hack/def.monst.h Normal file
View File

@@ -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 <hack@gnu.org>
* 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_ */

111
hack/def.obj.h Normal file
View File

@@ -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 <hack@gnu.org>
* 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_ */

123
hack/def.objclass.h Normal file
View File

@@ -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 <hack@gnu.org>
* 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_ */

351
hack/def.objects.h Normal file
View File

@@ -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 <hack@gnu.org>
* 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_ */

90
hack/def.permonst.h Normal file
View File

@@ -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 <hack@gnu.org>
* 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_ */

115
hack/def.rm.h Normal file
View File

@@ -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 <hack@gnu.org>
* 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_ */

89
hack/def.trap.h Normal file
View File

@@ -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 <hack@gnu.org>
* 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_ */

76
hack/def.wseg.h Normal file
View File

@@ -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 <hack@gnu.org>
* 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_ */

209
hack/hack.6.in Normal file
View File

@@ -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 <hack@gnu.org>
.\" 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 .

110
hack/hack.Decl.c Normal file
View File

@@ -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 <hack@gnu.org>
* 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 <sys/cdefs.h>
#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";

537
hack/hack.apply.c Normal file
View File

@@ -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 <hack@gnu.org>
* 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 <sys/cdefs.h>
#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);
}

176
hack/hack.bones.c Normal file
View File

@@ -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 <hack@gnu.org>
* 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 <sys/cdefs.h>
#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 <fcntl.h>
#include <unistd.h>
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);
}

975
hack/hack.c Normal file
View File

@@ -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 <hack@gnu.org>
* 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 <sys/cdefs.h>
#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)));
}

382
hack/hack.cmd.c Normal file
View File

@@ -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 <hack@gnu.org>
* 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 <sys/cdefs.h>
#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);
}

586
hack/hack.do.c Normal file
View File

@@ -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 <hack@gnu.org>
* 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 <sys/cdefs.h>
#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 <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
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;
}
}

385
hack/hack.do_name.c Normal file
View File

@@ -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 <hack@gnu.org>
* 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 <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: hack.do_name.c,v 1.5 2001/03/25 20:43:59 jsm Exp $");
#endif /* not lint */
#include <stdlib.h>
#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);
}

452
hack/hack.do_wear.c Normal file
View File

@@ -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 <hack@gnu.org>
* 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 <sys/cdefs.h>
#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--;
}
}

525
hack/hack.dog.c Normal file
View File

@@ -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 <hack@gnu.org>
* 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 <sys/cdefs.h>
#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);
}

559
hack/hack.eat.c Normal file
View File

@@ -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 <hack@gnu.org>
* 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 <sys/cdefs.h>
#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);
}

790
hack/hack.end.c Normal file
View File

@@ -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 <hack@gnu.org>
* 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 <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: hack.end.c,v 1.5 2001/03/25 20:44:00 jsm Exp $");
#endif /* not lint */
#include <signal.h>
#include <unistd.h>
#include <stdlib.h>
#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 */
}

403
hack/hack.engrave.c Normal file
View File

@@ -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 <hack@gnu.org>
* 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 <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: hack.engrave.c,v 1.5 2001/03/25 20:44:00 jsm Exp $");
#endif /* not lint */
#include <stdlib.h>
#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 *) &lth, 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);
}

468
hack/hack.fight.c Normal file
View File

@@ -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 <hack@gnu.org>
* 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 <sys/cdefs.h>
#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);
}

249
hack/hack.h Normal file
View File

@@ -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 <hack@gnu.org>
* 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 <stdlib.h>
#include <string.h>
#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_ */

1042
hack/hack.invent.c Normal file

File diff suppressed because it is too large Load Diff

112
hack/hack.ioctl.c Normal file
View File

@@ -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 <hack@gnu.org>
* 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 <sys/cdefs.h>
#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 <termio.h> and <sgtty.h> define the
* same constants, and the C preprocessor complains.
*/
#include <termios.h>
#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 <signal.h>
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 */

349
hack/hack.lev.c Normal file
View File

@@ -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 <hack@gnu.org>
* 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 <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: hack.lev.c,v 1.5 2001/03/25 20:44:01 jsm Exp $");
#endif /* not lint */
#include <stdlib.h>
#include <unistd.h>
#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;
}

587
hack/hack.main.c Normal file
View File

@@ -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 <hack@gnu.org>
* 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 <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: hack.main.c,v 1.7 2002/05/26 00:12:12 wiz Exp $");
#endif /* not lint */
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#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;
}
}

280
hack/hack.makemon.c Normal file
View File

@@ -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 <hack@gnu.org>
* 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 <sys/cdefs.h>
#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);
}

75
hack/hack.mfndpos.h Normal file
View File

@@ -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 <hack@gnu.org>
* 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_ */

455
hack/hack.mhitu.c Normal file
View File

@@ -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 <hack@gnu.org>
* 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 <sys/cdefs.h>
#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);
}

851
hack/hack.mklev.c Normal file
View File

@@ -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 <hack@gnu.org>
* 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 <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: hack.mklev.c,v 1.5 2001/03/25 20:44:01 jsm Exp $");
#endif /* not lint */
#include <unistd.h>
#include <stdlib.h>
#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;
}

217
hack/hack.mkmaze.c Normal file
View File

@@ -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 <hack@gnu.org>
* 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 <sys/cdefs.h>
#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;
}

227
hack/hack.mkobj.c Normal file
View File

@@ -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 <hack@gnu.org>
* 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 <sys/cdefs.h>
#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? */
}
}

368
hack/hack.mkshop.c Normal file
View File

@@ -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 <hack@gnu.org>
* 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 <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: hack.mkshop.c,v 1.7 2002/08/22 01:49:34 chuck Exp $");
#endif /* not lint */
#include <stdlib.h>
#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 */

1039
hack/hack.mon.c Normal file

File diff suppressed because it is too large Load Diff

144
hack/hack.monst.c Normal file
View File

@@ -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 <hack@gnu.org>
* 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 <sys/cdefs.h>
#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};

247
hack/hack.o_init.c Normal file
View File

@@ -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 <hack@gnu.org>
* 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 <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: hack.o_init.c,v 1.6 2001/03/25 20:44:02 jsm Exp $");
#endif /* not lint */
#include <string.h>
#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)
);
}

643
hack/hack.objnam.c Normal file
View File

@@ -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 <hack@gnu.org>
* 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 <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: hack.objnam.c,v 1.5 2001/03/25 20:44:02 jsm Exp $");
#endif /* not lint */
#include <stdlib.h>
#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);
}
}

276
hack/hack.options.c Normal file
View File

@@ -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 <hack@gnu.org>
* 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 <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: hack.options.c,v 1.5 2001/02/05 00:37:43 christos Exp $");
#endif /* not lint */
#include <stdlib.h>
#include <unistd.h>
#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=\"<options>\"' in your environment, or ",
"give the command 'o' followed by the line `<options>' while playing. ",
"Here <options> is a list of <option>s separated by commas.");
pline("%s%s%s",
"Simple (boolean) options are rest_on_space, news, time, ",
"null, tombstone, (fe)male. ",
"These can be negated by prefixing them with '!' or \"no\".");
pline("%s",
"A string option is name, as in HACKOPTIONS=\"name:Merlin-W\".");
pline("%s%s%s",
"A compound option is endgame; it is followed by a description of what ",
"parts of the scorelist you want to see. You might for example say: ",
"`endgame:own scores/5 top scores/4 around my score'.");
return;
}
pline("Bad option: %s.", opts);
pline("Type `o help<cr>' for help.");
return;
}
puts("Bad syntax in HACKOPTIONS.");
puts("Use for example:");
puts(
"HACKOPTIONS=\"!restonspace,notombstone,endgame:own/5 topscorers/4 around me\""
);
getret();
}
int
doset()
{
char buf[BUFSZ];
pline("What options do you want to set? ");
getlin(buf);
if (!buf[0] || buf[0] == '\033') {
(void) strcpy(buf, "HACKOPTIONS=");
(void) strcat(buf, flags.female ? "female," : "male,");
if (flags.standout)
(void) strcat(buf, "standout,");
if (flags.nonull)
(void) strcat(buf, "nonull,");
if (flags.nonews)
(void) strcat(buf, "nonews,");
if (flags.time)
(void) strcat(buf, "time,");
if (flags.notombstone)
(void) strcat(buf, "notombstone,");
if (flags.no_rest_on_space)
(void) strcat(buf, "!rest_on_space,");
if (flags.end_top != 5 || flags.end_around != 4 || flags.end_own) {
(void) sprintf(eos(buf), "endgame: %u topscores/%u around me",
flags.end_top, flags.end_around);
if (flags.end_own)
(void) strcat(buf, "/own scores");
} else {
char *eop = eos(buf);
if (*--eop == ',')
*eop = 0;
}
pline(buf);
} else
parseoptions(buf, FALSE);
return (0);
}

494
hack/hack.pager.c Normal file
View File

@@ -0,0 +1,494 @@
/* $NetBSD: hack.pager.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 <hack@gnu.org>
* 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 <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: hack.pager.c,v 1.6 2001/03/25 20:44:02 jsm Exp $");
#endif /* not lint */
/* This file contains the command routine dowhatis() and a pager. */
/*
* Also readmail() and doshell(), and generally the things that contact the
* outside world.
*/
#include <sys/types.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
#include "hack.h"
#include "extern.h"
int
dowhatis()
{
FILE *fp;
char bufr[BUFSZ + 6];
char *buf = &bufr[6], *ep, q;
if (!(fp = fopen(DATAFILE, "r")))
pline("Cannot open data file!");
else {
pline("Specify what? ");
q = readchar();
if (q != '\t')
while (fgets(buf, BUFSZ, fp))
if (*buf == q) {
ep = strchr(buf, '\n');
if (ep)
*ep = 0;
/* else: bad data file */
/* Expand tab 'by hand' */
if (buf[1] == '\t') {
buf = bufr;
buf[0] = q;
(void) strncpy(buf + 1, " ", 7);
}
pline(buf);
if (ep[-1] == ';') {
pline("More info? ");
if (readchar() == 'y') {
page_more(fp, 1); /* does fclose() */
return (0);
}
}
(void) fclose(fp); /* kopper@psuvax1 */
return (0);
}
pline("I've never heard of such things.");
(void) fclose(fp);
}
return (0);
}
/* make the paging of a file interruptible */
static int got_intrup;
void
intruph(n)
int n __attribute__((__unused__));
{
got_intrup++;
}
/* simple pager, also used from dohelp() */
void
page_more(fp, strip)
FILE *fp;
int strip; /* nr of chars to be stripped from each line
* (0 or 1) */
{
char *bufr, *ep;
sig_t prevsig = signal(SIGINT, intruph);
set_pager(0);
bufr = (char *) alloc((unsigned) CO);
bufr[CO - 1] = 0;
while (fgets(bufr, CO - 1, fp) && (!strip || *bufr == '\t') && !got_intrup) {
ep = strchr(bufr, '\n');
if (ep)
*ep = 0;
if (page_line(bufr + strip)) {
set_pager(2);
goto ret;
}
}
set_pager(1);
ret:
free(bufr);
(void) fclose(fp);
(void) signal(SIGINT, prevsig);
got_intrup = 0;
}
static boolean whole_screen = TRUE;
#define PAGMIN 12 /* minimum # of lines for page below level
* map */
void
set_whole_screen()
{ /* called in termcap as soon as LI is known */
whole_screen = (LI - ROWNO - 2 <= PAGMIN || !CD);
}
#ifdef NEWS
int
readnews()
{
int ret;
whole_screen = TRUE; /* force a docrt(), our first */
ret = page_file(NEWS, TRUE);
set_whole_screen();
return (ret); /* report whether we did docrt() */
}
#endif /* NEWS */
void
set_pager(mode)
int mode; /* 0: open 1: wait+close 2: close */
{
static boolean so;
if (mode == 0) {
if (!whole_screen) {
/* clear topline */
clrlin();
/* use part of screen below level map */
curs(1, ROWNO + 4);
} else {
cls();
}
so = flags.standout;
flags.standout = 1;
} else {
if (mode == 1) {
curs(1, LI);
more();
}
flags.standout = so;
if (whole_screen)
docrt();
else {
curs(1, ROWNO + 4);
cl_eos();
}
}
}
int
page_line(s) /* returns 1 if we should quit */
const char *s;
{
if (cury == LI - 1) {
if (!*s)
return (0); /* suppress blank lines at top */
putchar('\n');
cury++;
cmore("q\033");
if (morc) {
morc = 0;
return (1);
}
if (whole_screen)
cls();
else {
curs(1, ROWNO + 4);
cl_eos();
}
}
puts(s);
cury++;
return (0);
}
/*
* Flexible pager: feed it with a number of lines and it will decide
* whether these should be fed to the pager above, or displayed in a
* corner.
* Call:
* cornline(0, title or 0) : initialize
* cornline(1, text) : add text to the chain of texts
* cornline(2, morcs) : output everything and cleanup
* cornline(3, 0) : cleanup
*/
void
cornline(mode, text)
int mode;
const char *text;
{
static struct line {
struct line *next_line;
char *line_text;
} *texthead, *texttail;
static int maxlen;
static int linect;
struct line *tl;
if (mode == 0) {
texthead = 0;
maxlen = 0;
linect = 0;
if (text) {
cornline(1, text); /* title */
cornline(1, ""); /* blank line */
}
return;
}
if (mode == 1) {
int len;
if (!text)
return; /* superfluous, just to be sure */
linect++;
len = strlen(text);
if (len > maxlen)
maxlen = len;
tl = (struct line *)
alloc((unsigned) (len + sizeof(struct line) + 1));
tl->next_line = 0;
tl->line_text = (char *) (tl + 1);
(void) strcpy(tl->line_text, text);
if (!texthead)
texthead = tl;
else
texttail->next_line = tl;
texttail = tl;
return;
}
/* --- now we really do it --- */
if (mode == 2 && linect == 1) /* topline only */
pline(texthead->line_text);
else if (mode == 2) {
int curline, lth;
if (flags.toplin == 1)
more(); /* ab@unido */
remember_topl();
lth = CO - maxlen - 2; /* Use full screen width */
if (linect < LI && lth >= 10) { /* in a corner */
home();
cl_end();
flags.toplin = 0;
curline = 1;
for (tl = texthead; tl; tl = tl->next_line) {
curs(lth, curline);
if (curline > 1)
cl_end();
putsym(' ');
putstr(tl->line_text);
curline++;
}
curs(lth, curline);
cl_end();
cmore(text);
home();
cl_end();
docorner(lth, curline - 1);
} else { /* feed to pager */
set_pager(0);
for (tl = texthead; tl; tl = tl->next_line) {
if (page_line(tl->line_text)) {
set_pager(2);
goto cleanup;
}
}
if (text) {
cgetret(text);
set_pager(2);
} else
set_pager(1);
}
}
cleanup:
while ((tl = texthead) != NULL) {
texthead = tl->next_line;
free((char *) tl);
}
}
int
dohelp()
{
char c;
pline("Long or short help? ");
while (((c = readchar()) != 'l') && (c != 's') && !strchr(quitchars, c))
bell();
if (!strchr(quitchars, c))
(void) page_file((c == 'l') ? HELP : SHELP, FALSE);
return (0);
}
int
page_file(fnam, silent) /* return: 0 - cannot open fnam; 1 -
* otherwise */
const char *fnam;
boolean silent;
{
#ifdef DEF_PAGER /* this implies that UNIX is defined */
{
/* use external pager; this may give security problems */
int fd = open(fnam, O_RDONLY);
if (fd < 0) {
if (!silent)
pline("Cannot open %s.", fnam);
return (0);
}
if (child(1)) {
/*
* Now that child() does a setuid(getuid()) and a
* chdir(), we may not be able to open file fnam
* anymore, so make it stdin.
*/
(void) close(0);
if (dup(fd)) {
if (!silent)
printf("Cannot open %s as stdin.\n", fnam);
} else {
execl(catmore, "page", (char *) 0);
if (!silent)
printf("Cannot exec %s.\n", catmore);
}
exit(1);
}
(void) close(fd);
}
#else /* DEF_PAGER */
{
FILE *f; /* free after Robert Viduya */
if ((f = fopen(fnam, "r")) == (FILE *) 0) {
if (!silent) {
home();
perror(fnam);
flags.toplin = 1;
pline("Cannot open %s.", fnam);
}
return (0);
}
page_more(f, 0);
}
#endif /* DEF_PAGER */
return (1);
}
#ifdef UNIX
#ifdef SHELL
int
dosh()
{
char *str;
if (child(0)) {
if ((str = getenv("SHELL")) != NULL)
execl(str, str, (char *) 0);
else
execl("/bin/sh", "sh", (char *) 0);
pline("sh: cannot execute.");
exit(1);
}
return (0);
}
#endif /* SHELL */
#ifdef NOWAITINCLUDE
union wait { /* used only for the cast (union wait *) 0 */
int w_status;
struct {
unsigned short w_Termsig:7;
unsigned short w_Coredump:1;
unsigned short w_Retcode:8;
} w_T;
};
#else
#ifdef BSD
#include <sys/wait.h>
#else
#include <wait.h>
#endif /* BSD */
#endif /* NOWAITINCLUDE */
int
child(int wt)
{
int status;
int f;
f = fork();
if (f == 0) { /* child */
settty((char *) 0); /* also calls end_screen() */
(void) setuid(getuid());
(void) setgid(getgid());
#ifdef CHDIR
(void) chdir(getenv("HOME"));
#endif /* CHDIR */
return (1);
}
if (f == -1) { /* cannot fork */
pline("Fork failed. Try again.");
return (0);
}
/* fork succeeded; wait for child to exit */
(void) signal(SIGINT, SIG_IGN);
(void) signal(SIGQUIT, SIG_IGN);
(void) wait(&status);
gettty();
setftty();
(void) signal(SIGINT, done1);
#ifdef WIZARD
if (wizard)
(void) signal(SIGQUIT, SIG_DFL);
#endif /* WIZARD */
if (wt)
getret();
docrt();
return (0);
}
#endif /* UNIX */

466
hack/hack.potion.c Normal file
View File

@@ -0,0 +1,466 @@
/* $NetBSD: hack.potion.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 <hack@gnu.org>
* 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 <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: hack.potion.c,v 1.5 2001/03/25 20:44:02 jsm Exp $");
#endif /* not lint */
#include "hack.h"
#include "extern.h"
int
dodrink()
{
struct obj *otmp, *objs;
struct monst *mtmp;
int unkn = 0, nothing = 0;
otmp = getobj("!", "drink");
if (!otmp)
return (0);
if (!strcmp(objects[otmp->otyp].oc_descr, "smoky") && !rn2(13)) {
ghost_from_bottle();
goto use_it;
}
switch (otmp->otyp) {
case POT_RESTORE_STRENGTH:
unkn++;
pline("Wow! This makes you feel great!");
if (u.ustr < u.ustrmax) {
u.ustr = u.ustrmax;
flags.botl = 1;
}
break;
case POT_BOOZE:
unkn++;
pline("Ooph! This tastes like liquid fire!");
Confusion += d(3, 8);
/* the whiskey makes us feel better */
if (u.uhp < u.uhpmax)
losehp(-1, "bottle of whiskey");
if (!rn2(4)) {
pline("You pass out.");
multi = -rnd(15);
nomovemsg = "You awake with a headache.";
}
break;
case POT_INVISIBILITY:
if (Invis || See_invisible)
nothing++;
else {
if (!Blind)
pline("Gee! All of a sudden, you can't see yourself.");
else
pline("You feel rather airy."), unkn++;
newsym(u.ux, u.uy);
}
Invis += rn1(15, 31);
break;
case POT_FRUIT_JUICE:
pline("This tastes like fruit juice.");
lesshungry(20);
break;
case POT_HEALING:
pline("You begin to feel better.");
flags.botl = 1;
u.uhp += rnd(10);
if (u.uhp > u.uhpmax)
u.uhp = ++u.uhpmax;
if (Blind)
Blind = 1; /* see on next move */
if (Sick)
Sick = 0;
break;
case POT_PARALYSIS:
if (Levitation)
pline("You are motionlessly suspended.");
else
pline("Your feet are frozen to the floor!");
nomul(-(rn1(10, 25)));
break;
case POT_MONSTER_DETECTION:
if (!fmon) {
strange_feeling(otmp, "You feel threatened.");
return (1);
} else {
cls();
for (mtmp = fmon; mtmp; mtmp = mtmp->nmon)
if (mtmp->mx > 0)
at(mtmp->mx, mtmp->my, mtmp->data->mlet);
prme();
pline("You sense the presence of monsters.");
more();
docrt();
}
break;
case POT_OBJECT_DETECTION:
if (!fobj) {
strange_feeling(otmp, "You feel a pull downward.");
return (1);
} else {
for (objs = fobj; objs; objs = objs->nobj)
if (objs->ox != u.ux || objs->oy != u.uy)
goto outobjmap;
pline("You sense the presence of objects close nearby.");
break;
outobjmap:
cls();
for (objs = fobj; objs; objs = objs->nobj)
at(objs->ox, objs->oy, objs->olet);
prme();
pline("You sense the presence of objects.");
more();
docrt();
}
break;
case POT_SICKNESS:
pline("Yech! This stuff tastes like poison.");
if (Poison_resistance)
pline("(But in fact it was biologically contaminated orange juice.)");
losestr(rn1(4, 3));
losehp(rnd(10), "contaminated potion");
break;
case POT_CONFUSION:
if (!Confusion)
pline("Huh, What? Where am I?");
else
nothing++;
Confusion += rn1(7, 16);
break;
case POT_GAIN_STRENGTH:
pline("Wow do you feel strong!");
if (u.ustr >= 118)
break; /* > 118 is impossible */
if (u.ustr > 17)
u.ustr += rnd(118 - u.ustr);
else
u.ustr++;
if (u.ustr > u.ustrmax)
u.ustrmax = u.ustr;
flags.botl = 1;
break;
case POT_SPEED:
if (Wounded_legs) {
heal_legs();
unkn++;
break;
}
if (!(Fast & ~INTRINSIC))
pline("You are suddenly moving much faster.");
else
pline("Your legs get new energy."), unkn++;
Fast += rn1(10, 100);
break;
case POT_BLINDNESS:
if (!Blind)
pline("A cloud of darkness falls upon you.");
else
nothing++;
Blind += rn1(100, 250);
seeoff(0);
break;
case POT_GAIN_LEVEL:
pluslvl();
break;
case POT_EXTRA_HEALING:
pline("You feel much better.");
flags.botl = 1;
u.uhp += d(2, 20) + 1;
if (u.uhp > u.uhpmax)
u.uhp = (u.uhpmax += 2);
if (Blind)
Blind = 1;
if (Sick)
Sick = 0;
break;
case POT_LEVITATION:
if (!Levitation)
float_up();
else
nothing++;
Levitation += rnd(100);
u.uprops[PROP(RIN_LEVITATION)].p_tofn = float_down;
break;
default:
impossible("What a funny potion! (%u)", otmp->otyp);
return (0);
}
if (nothing) {
unkn++;
pline("You have a peculiar feeling for a moment, then it passes.");
}
if (otmp->dknown && !objects[otmp->otyp].oc_name_known) {
if (!unkn) {
objects[otmp->otyp].oc_name_known = 1;
more_experienced(0, 10);
} else if (!objects[otmp->otyp].oc_uname)
docall(otmp);
}
use_it:
useup(otmp);
return (1);
}
void
pluslvl()
{
int num;
pline("You feel more experienced.");
num = rnd(10);
u.uhpmax += num;
u.uhp += num;
if (u.ulevel < 14) {
u.uexp = newuexp() + 1;
pline("Welcome to experience level %u.", ++u.ulevel);
}
flags.botl = 1;
}
void
strange_feeling(obj, txt)
struct obj *obj;
const char *txt;
{
if (flags.beginner)
pline("You have a strange feeling for a moment, then it passes.");
else
pline(txt);
if (!objects[obj->otyp].oc_name_known && !objects[obj->otyp].oc_uname)
docall(obj);
useup(obj);
}
const char *const bottlenames[] = {
"bottle", "phial", "flagon", "carafe", "flask", "jar", "vial"
};
void
potionhit(mon, obj)
struct monst *mon;
struct obj *obj;
{
const char *botlnam = bottlenames[rn2(SIZE(bottlenames))];
boolean uclose, isyou = (mon == &youmonst);
if (isyou) {
uclose = TRUE;
pline("The %s crashes on your head and breaks into shivers.",
botlnam);
losehp(rnd(2), "thrown potion");
} else {
uclose = (dist(mon->mx, mon->my) < 3);
/* perhaps 'E' and 'a' have no head? */
pline("The %s crashes on %s's head and breaks into shivers.",
botlnam, monnam(mon));
if (rn2(5) && mon->mhp > 1)
mon->mhp--;
}
pline("The %s evaporates.", xname(obj));
if (!isyou && !rn2(3))
switch (obj->otyp) {
case POT_RESTORE_STRENGTH:
case POT_GAIN_STRENGTH:
case POT_HEALING:
case POT_EXTRA_HEALING:
if (mon->mhp < mon->mhpmax) {
mon->mhp = mon->mhpmax;
pline("%s looks sound and hale again!", Monnam(mon));
}
break;
case POT_SICKNESS:
if (mon->mhpmax > 3)
mon->mhpmax /= 2;
if (mon->mhp > 2)
mon->mhp /= 2;
break;
case POT_CONFUSION:
case POT_BOOZE:
mon->mconf = 1;
break;
case POT_INVISIBILITY:
unpmon(mon);
mon->minvis = 1;
pmon(mon);
break;
case POT_PARALYSIS:
mon->mfroz = 1;
break;
case POT_SPEED:
mon->mspeed = MFAST;
break;
case POT_BLINDNESS:
mon->mblinded |= 64 + rn2(64);
break;
/*
* case POT_GAIN_LEVEL: case POT_LEVITATION: case
* POT_FRUIT_JUICE: case POT_MONSTER_DETECTION: case
* POT_OBJECT_DETECTION: break;
*/
}
if (uclose && rn2(5))
potionbreathe(obj);
obfree(obj, Null(obj));
}
void
potionbreathe(obj)
struct obj *obj;
{
switch (obj->otyp) {
case POT_RESTORE_STRENGTH:
case POT_GAIN_STRENGTH:
if (u.ustr < u.ustrmax)
u.ustr++, flags.botl = 1;
break;
case POT_HEALING:
case POT_EXTRA_HEALING:
if (u.uhp < u.uhpmax)
u.uhp++, flags.botl = 1;
break;
case POT_SICKNESS:
if (u.uhp <= 5)
u.uhp = 1;
else
u.uhp -= 5;
flags.botl = 1;
break;
case POT_CONFUSION:
case POT_BOOZE:
if (!Confusion)
pline("You feel somewhat dizzy.");
Confusion += rnd(5);
break;
case POT_INVISIBILITY:
pline("For an instant you couldn't see your right hand.");
break;
case POT_PARALYSIS:
pline("Something seems to be holding you.");
nomul(-rnd(5));
break;
case POT_SPEED:
Fast += rnd(5);
pline("Your knees seem more flexible now.");
break;
case POT_BLINDNESS:
if (!Blind)
pline("It suddenly gets dark.");
Blind += rnd(5);
seeoff(0);
break;
/*
* case POT_GAIN_LEVEL: case POT_LEVITATION: case
* POT_FRUIT_JUICE: case POT_MONSTER_DETECTION: case
* POT_OBJECT_DETECTION: break;
*/
}
/* note: no obfree() */
}
/*
* -- rudimentary -- to do this correctly requires much more work
* -- all sharp weapons get one or more qualities derived from the potions
* -- texts on scrolls may be (partially) wiped out; do they become blank?
* -- or does their effect change, like under Confusion?
* -- all objects may be made invisible by POT_INVISIBILITY
* -- If the flask is small, can one dip a large object? Does it magically
* -- become a jug? Etc.
*/
int
dodip()
{
struct obj *potion, *obj;
if (!(obj = getobj("#", "dip")))
return (0);
if (!(potion = getobj("!", "dip into")))
return (0);
pline("Interesting...");
if (obj->otyp == ARROW || obj->otyp == DART ||
obj->otyp == CROSSBOW_BOLT) {
if (potion->otyp == POT_SICKNESS) {
useup(potion);
if (obj->spe < 7)
obj->spe++; /* %% */
}
}
return (1);
}
void
ghost_from_bottle()
{
struct monst *mtmp;
if (!(mtmp = makemon(PM_GHOST, u.ux, u.uy))) {
pline("This bottle turns out to be empty.");
return;
}
mnexto(mtmp);
pline("As you open the bottle, an enormous ghost emerges!");
pline("You are frightened to death, and unable to move.");
nomul(-3);
}

805
hack/hack.pri.c Normal file
View File

@@ -0,0 +1,805 @@
/* $NetBSD: hack.pri.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 <hack@gnu.org>
* 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 <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: hack.pri.c,v 1.7 2002/05/26 00:12:12 wiz Exp $");
#endif /* not lint */
#include "hack.h"
#include "extern.h"
xchar scrlx, scrhx, scrly, scrhy; /* corners of new area on
* screen */
void
swallowed()
{
char ulook[] = "|@|";
ulook[1] = u.usym;
cls();
curs(u.ux - 1, u.uy + 1);
fputs("/-\\", stdout);
curx = u.ux + 2;
curs(u.ux - 1, u.uy + 2);
fputs(ulook, stdout);
curx = u.ux + 2;
curs(u.ux - 1, u.uy + 3);
fputs("\\-/", stdout);
curx = u.ux + 2;
u.udispl = 1;
u.udisx = u.ux;
u.udisy = u.uy;
}
/* VARARGS1 */
boolean panicking;
void
panic(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
if (panicking++)
exit(1); /* avoid loops - this should never happen */
home();
puts(" Suddenly, the dungeon collapses.");
fputs(" ERROR: ", stdout);
vprintf(fmt, ap);
va_end(ap);
#ifdef DEBUG
#ifdef UNIX
if (!fork())
abort(); /* generate core dump */
#endif /* UNIX */
#endif /* DEBUG */
more(); /* contains a fflush() */
done("panicked");
}
void
atl(x, y, ch)
int x, y, ch;
{
struct rm *crm = &levl[x][y];
if (x < 0 || x > COLNO - 1 || y < 0 || y > ROWNO - 1) {
impossible("atl(%d,%d,%c)", x, y, ch);
return;
}
if (crm->seen && crm->scrsym == ch)
return;
crm->scrsym = ch;
crm->new = 1;
on_scr(x, y);
}
void
on_scr(x, y)
int x, y;
{
if (x < scrlx)
scrlx = x;
if (x > scrhx)
scrhx = x;
if (y < scrly)
scrly = y;
if (y > scrhy)
scrhy = y;
}
/*
* call: (x,y) - display (-1,0) - close (leave last symbol) (-1,-1)- close
* (undo last symbol) (-1,let)-open: initialize symbol (-2,let)-change let
*/
void
tmp_at(x, y)
schar x, y;
{
static schar prevx, prevy;
static char let;
if ((int) x == -2) { /* change let call */
let = y;
return;
}
if ((int) x == -1 && (int) y >= 0) { /* open or close call */
let = y;
prevx = -1;
return;
}
if (prevx >= 0 && cansee(prevx, prevy)) {
delay_output();
prl(prevx, prevy); /* in case there was a monster */
at(prevx, prevy, levl[prevx][prevy].scrsym);
}
if (x >= 0) { /* normal call */
if (cansee(x, y))
at(x, y, let);
prevx = x;
prevy = y;
} else { /* close call */
let = 0;
prevx = -1;
}
}
/* like the previous, but the symbols are first erased on completion */
void
Tmp_at(x, y)
schar x, y;
{
static char let;
static xchar cnt;
static coord tc[COLNO]; /* but watch reflecting beams! */
int xx, yy;
if ((int) x == -1) {
if (y > 0) { /* open call */
let = y;
cnt = 0;
return;
}
/* close call (do not distinguish y==0 and y==-1) */
while (cnt--) {
xx = tc[cnt].x;
yy = tc[cnt].y;
prl(xx, yy);
at(xx, yy, levl[xx][yy].scrsym);
}
cnt = let = 0; /* superfluous */
return;
}
if ((int) x == -2) { /* change let call */
let = y;
return;
}
/* normal call */
if (cansee(x, y)) {
if (cnt)
delay_output();
at(x, y, let);
tc[cnt].x = x;
tc[cnt].y = y;
if (++cnt >= COLNO)
panic("Tmp_at overflow?");
levl[x][y].new = 0; /* prevent pline-nscr erasing --- */
}
}
void
setclipped()
{
error("Hack needs a screen of size at least %d by %d.\n",
ROWNO + 2, COLNO);
}
void
at(x, y, ch)
xchar x, y;
char ch;
{
#ifndef lint
/* if xchar is unsigned, lint will complain about if(x < 0) */
if (x < 0 || x > COLNO - 1 || y < 0 || y > ROWNO - 1) {
impossible("At gets 0%o at %d %d.", ch, x, y);
return;
}
#endif /* lint */
if (!ch) {
impossible("At gets null at %d %d.", x, y);
return;
}
y += 2;
curs(x, y);
(void) putchar(ch);
curx++;
}
void
prme()
{
if (!Invisible)
at(u.ux, u.uy, u.usym);
}
int
doredraw()
{
docrt();
return (0);
}
void
docrt()
{
int x, y;
struct rm *room;
struct monst *mtmp;
if (u.uswallow) {
swallowed();
return;
}
cls();
/*
* Some ridiculous code to get display of @ and monsters (almost)
* right
*/
if (!Invisible) {
levl[(u.udisx = u.ux)][(u.udisy = u.uy)].scrsym = u.usym;
levl[u.udisx][u.udisy].seen = 1;
u.udispl = 1;
} else
u.udispl = 0;
seemons(); /* reset old positions */
for (mtmp = fmon; mtmp; mtmp = mtmp->nmon)
mtmp->mdispl = 0;
seemons(); /* force new positions to be shown */
/*
* This nonsense should disappear soon
* ---------------------------------
*/
for (y = 0; y < ROWNO; y++)
for (x = 0; x < COLNO; x++)
if ((room = &levl[x][y])->new) {
room->new = 0;
at(x, y, room->scrsym);
} else if (room->seen)
at(x, y, room->scrsym);
scrlx = COLNO;
scrly = ROWNO;
scrhx = scrhy = 0;
flags.botlx = 1;
bot();
}
void
docorner(xmin, ymax)
int xmin, ymax;
{
int x, y;
struct rm *room;
struct monst *mtmp;
if (u.uswallow) { /* Can be done more efficiently */
swallowed();
return;
}
seemons(); /* reset old positions */
for (mtmp = fmon; mtmp; mtmp = mtmp->nmon)
if (mtmp->mx >= xmin && mtmp->my < ymax)
mtmp->mdispl = 0;
seemons(); /* force new positions to be shown */
for (y = 0; y < ymax; y++) {
if (y > ROWNO && CD)
break;
curs(xmin, y + 2);
cl_end();
if (y < ROWNO) {
for (x = xmin; x < COLNO; x++) {
if ((room = &levl[x][y])->new) {
room->new = 0;
at(x, y, room->scrsym);
} else if (room->seen)
at(x, y, room->scrsym);
}
}
}
if (ymax > ROWNO) {
cornbot(xmin - 1);
if (ymax > ROWNO + 1 && CD) {
curs(1, ROWNO + 3);
cl_eos();
}
}
}
void
curs_on_u()
{
curs(u.ux, u.uy + 2);
}
void
pru()
{
if (u.udispl && (Invisible || u.udisx != u.ux || u.udisy != u.uy))
/* if(! levl[u.udisx][u.udisy].new) */
if (!vism_at(u.udisx, u.udisy))
newsym(u.udisx, u.udisy);
if (Invisible) {
u.udispl = 0;
prl(u.ux, u.uy);
} else if (!u.udispl || u.udisx != u.ux || u.udisy != u.uy) {
atl(u.ux, u.uy, u.usym);
u.udispl = 1;
u.udisx = u.ux;
u.udisy = u.uy;
}
levl[u.ux][u.uy].seen = 1;
}
#ifndef NOWORM
#include "def.wseg.h"
#endif /* NOWORM */
/* print a position that is visible for @ */
void
prl(int x, int y)
{
struct rm *room;
struct monst *mtmp;
struct obj *otmp;
if (x == u.ux && y == u.uy && (!Invisible)) {
pru();
return;
}
if (!isok(x, y))
return;
room = &levl[x][y];
if ((!room->typ) ||
(IS_ROCK(room->typ) && levl[u.ux][u.uy].typ == CORR))
return;
if ((mtmp = m_at(x, y)) && !mtmp->mhide &&
(!mtmp->minvis || See_invisible)) {
#ifndef NOWORM
if (m_atseg)
pwseg(m_atseg);
else
#endif /* NOWORM */
pmon(mtmp);
} else if ((otmp = o_at(x, y)) && room->typ != POOL)
atl(x, y, otmp->olet);
else if (mtmp && (!mtmp->minvis || See_invisible)) {
/* must be a hiding monster, but not hiding right now */
/* assume for the moment that long worms do not hide */
pmon(mtmp);
} else if (g_at(x, y) && room->typ != POOL)
atl(x, y, '$');
else if (!room->seen || room->scrsym == ' ') {
room->new = room->seen = 1;
newsym(x, y);
on_scr(x, y);
}
room->seen = 1;
}
char
news0(x, y)
xchar x, y;
{
struct obj *otmp;
struct trap *ttmp;
struct rm *room;
char tmp;
room = &levl[x][y];
if (!room->seen)
tmp = ' ';
else if (room->typ == POOL)
tmp = POOL_SYM;
else if (!Blind && (otmp = o_at(x, y)))
tmp = otmp->olet;
else if (!Blind && g_at(x, y))
tmp = '$';
else if (x == xupstair && y == yupstair)
tmp = '<';
else if (x == xdnstair && y == ydnstair)
tmp = '>';
else if ((ttmp = t_at(x, y)) && ttmp->tseen)
tmp = '^';
else
switch (room->typ) {
case SCORR:
case SDOOR:
tmp = room->scrsym; /* %% wrong after killing
* mimic ! */
break;
case HWALL:
tmp = '-';
break;
case VWALL:
tmp = '|';
break;
case LDOOR:
case DOOR:
tmp = '+';
break;
case CORR:
tmp = CORR_SYM;
break;
case ROOM:
if (room->lit || cansee(x, y) || Blind)
tmp = '.';
else
tmp = ' ';
break;
/*
case POOL:
tmp = POOL_SYM;
break;
*/
default:
tmp = ERRCHAR;
}
return (tmp);
}
void
newsym(x, y)
int x, y;
{
atl(x, y, news0(x, y));
}
/* used with wand of digging (or pick-axe): fill scrsym and force display */
/* also when a POOL evaporates */
void
mnewsym(x, y)
int x, y;
{
struct rm *room;
char newscrsym;
if (!vism_at(x, y)) {
room = &levl[x][y];
newscrsym = news0(x, y);
if (room->scrsym != newscrsym) {
room->scrsym = newscrsym;
room->seen = 0;
}
}
}
void
nosee(x, y)
int x, y;
{
struct rm *room;
if (!isok(x, y))
return;
room = &levl[x][y];
if (room->scrsym == '.' && !room->lit && !Blind) {
room->scrsym = ' ';
room->new = 1;
on_scr(x, y);
}
}
#ifndef QUEST
void
prl1(x, y)
int x, y;
{
if (u.dx) {
if (u.dy) {
prl(x - (2 * u.dx), y);
prl(x - u.dx, y);
prl(x, y);
prl(x, y - u.dy);
prl(x, y - (2 * u.dy));
} else {
prl(x, y - 1);
prl(x, y);
prl(x, y + 1);
}
} else {
prl(x - 1, y);
prl(x, y);
prl(x + 1, y);
}
}
void
nose1(x, y)
int x, y;
{
if (u.dx) {
if (u.dy) {
nosee(x, u.uy);
nosee(x, u.uy - u.dy);
nosee(x, y);
nosee(u.ux - u.dx, y);
nosee(u.ux, y);
} else {
nosee(x, y - 1);
nosee(x, y);
nosee(x, y + 1);
}
} else {
nosee(x - 1, y);
nosee(x, y);
nosee(x + 1, y);
}
}
#endif /* QUEST */
int
vism_at(x, y)
int x, y;
{
struct monst *mtmp;
return ((x == u.ux && y == u.uy && !Invisible)
? 1 :
(mtmp = m_at(x, y))
? ((Blind && Telepat) || canseemon(mtmp)) :
0);
}
#ifdef NEWSCR
void
pobj(obj)
struct obj *obj;
{
int show = (!obj->oinvis || See_invisible) &&
cansee(obj->ox, obj->oy);
if (obj->odispl) {
if (obj->odx != obj->ox || obj->ody != obj->oy || !show)
if (!vism_at(obj->odx, obj->ody)) {
newsym(obj->odx, obj->ody);
obj->odispl = 0;
}
}
if (show && !vism_at(obj->ox, obj->oy)) {
atl(obj->ox, obj->oy, obj->olet);
obj->odispl = 1;
obj->odx = obj->ox;
obj->ody = obj->oy;
}
}
#endif /* NEWSCR */
void
unpobj(obj)
struct obj *obj;
{
/*
* if(obj->odispl){ if(!vism_at(obj->odx, obj->ody)) newsym(obj->odx,
* obj->ody); obj->odispl = 0; }
*/
if (!vism_at(obj->ox, obj->oy))
newsym(obj->ox, obj->oy);
}
void
seeobjs()
{
struct obj *obj, *obj2;
for (obj = fobj; obj; obj = obj2) {
obj2 = obj->nobj;
if (obj->olet == FOOD_SYM && obj->otyp >= CORPSE
&& obj->age + 250 < moves)
delobj(obj);
}
for (obj = invent; obj; obj = obj2) {
obj2 = obj->nobj;
if (obj->olet == FOOD_SYM && obj->otyp >= CORPSE
&& obj->age + 250 < moves)
useup(obj);
}
}
void
seemons()
{
struct monst *mtmp;
for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
if (mtmp->data->mlet == ';')
mtmp->minvis = (u.ustuck != mtmp &&
levl[mtmp->mx][mtmp->my].typ == POOL);
pmon(mtmp);
#ifndef NOWORM
if (mtmp->wormno)
wormsee(mtmp->wormno);
#endif /* NOWORM */
}
}
void
pmon(mon)
struct monst *mon;
{
int show = (Blind && Telepat) || canseemon(mon);
if (mon->mdispl) {
if (mon->mdx != mon->mx || mon->mdy != mon->my || !show)
unpmon(mon);
}
if (show && !mon->mdispl) {
atl(mon->mx, mon->my,
(!mon->mappearance
|| u.uprops[PROP(RIN_PROTECTION_FROM_SHAPE_CHANGERS)].p_flgs
) ? mon->data->mlet : mon->mappearance);
mon->mdispl = 1;
mon->mdx = mon->mx;
mon->mdy = mon->my;
}
}
void
unpmon(mon)
struct monst *mon;
{
if (mon->mdispl) {
newsym(mon->mdx, mon->mdy);
mon->mdispl = 0;
}
}
void
nscr()
{
int x, y;
struct rm *room;
if (u.uswallow || u.ux == FAR || flags.nscrinh)
return;
pru();
for (y = scrly; y <= scrhy; y++)
for (x = scrlx; x <= scrhx; x++)
if ((room = &levl[x][y])->new) {
room->new = 0;
at(x, y, room->scrsym);
}
scrhx = scrhy = 0;
scrlx = COLNO;
scrly = ROWNO;
}
/* 100 suffices for bot(); no relation with COLNO */
char oldbot[100], newbot[100];
void
cornbot(lth)
int lth;
{
if (lth < (int)sizeof(oldbot)) {
oldbot[lth] = 0;
flags.botl = 1;
}
}
void
bot()
{
char *ob = oldbot, *nb = newbot;
int i;
if (flags.botlx)
*ob = 0;
flags.botl = flags.botlx = 0;
#ifdef GOLD_ON_BOTL
(void) sprintf(newbot,
"Level %-2d Gold %-5lu Hp %3d(%d) Ac %-2d Str ",
dlevel, u.ugold, u.uhp, u.uhpmax, u.uac);
#else
(void) sprintf(newbot,
"Level %-2d Hp %3d(%d) Ac %-2d Str ",
dlevel, u.uhp, u.uhpmax, u.uac);
#endif /* GOLD_ON_BOTL */
if (u.ustr > 18) {
if (u.ustr > 117)
(void) strcat(newbot, "18/**");
else
(void) sprintf(eos(newbot), "18/%02d", u.ustr - 18);
} else
(void) sprintf(eos(newbot), "%-2d ", u.ustr);
#ifdef EXP_ON_BOTL
(void) sprintf(eos(newbot), " Exp %2d/%-5lu ", u.ulevel, u.uexp);
#else
(void) sprintf(eos(newbot), " Exp %2u ", u.ulevel);
#endif /* EXP_ON_BOTL */
(void) strcat(newbot, hu_stat[u.uhs]);
if (flags.time)
(void) sprintf(eos(newbot), " %ld", moves);
if (strlen(newbot) >= COLNO) {
char *bp0, *bp1;
bp0 = bp1 = newbot;
do {
if (*bp0 != ' ' || bp0[1] != ' ' || bp0[2] != ' ')
*bp1++ = *bp0;
} while (*bp0++);
}
for (i = 1; i < COLNO; i++) {
if (*ob != *nb) {
curs(i, ROWNO + 2);
(void) putchar(*nb ? *nb : ' ');
curx++;
}
if (*ob)
ob++;
if (*nb)
nb++;
}
(void) strcpy(oldbot, newbot);
}
#ifdef WAN_PROBING
void
mstatusline(mtmp)
struct monst *mtmp;
{
pline("Status of %s: ", monnam(mtmp));
pline("Level %-2d Gold %-5lu Hp %3d(%d) Ac %-2d Dam %d",
mtmp->data->mlevel, mtmp->mgold, mtmp->mhp, mtmp->mhpmax,
mtmp->data->ac, (mtmp->data->damn + 1) * (mtmp->data->damd + 1));
}
#endif /* WAN_PROBING */
void
cls()
{
if (flags.toplin == 1)
more();
flags.toplin = 0;
clear_screen();
flags.botlx = 1;
}

647
hack/hack.read.c Normal file
View File

@@ -0,0 +1,647 @@
/* $NetBSD: hack.read.c,v 1.7 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 <hack@gnu.org>
* 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 <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: hack.read.c,v 1.7 2001/03/25 20:44:02 jsm Exp $");
#endif /* not lint */
#include <stdlib.h>
#include "hack.h"
#include "extern.h"
int
doread()
{
struct obj *scroll;
boolean confused = (Confusion != 0);
boolean known = FALSE;
scroll = getobj("?", "read");
if (!scroll)
return (0);
if (!scroll->dknown && Blind) {
pline("Being blind, you cannot read the formula on the scroll.");
return (0);
}
if (Blind)
pline("As you pronounce the formula on it, the scroll disappears.");
else
pline("As you read the scroll, it disappears.");
if (confused)
pline("Being confused, you mispronounce the magic words ... ");
switch (scroll->otyp) {
#ifdef MAIL
case SCR_MAIL:
readmail( /* scroll */ );
break;
#endif /* MAIL */
case SCR_ENCHANT_ARMOR:
{
struct obj *otmp = some_armor();
if (!otmp) {
strange_feeling(scroll, "Your skin glows then fades.");
return (1);
}
if (confused) {
pline("Your %s glows silver for a moment.",
objects[otmp->otyp].oc_name);
otmp->rustfree = 1;
break;
}
if (otmp->spe > 3 && rn2(otmp->spe)) {
pline("Your %s glows violently green for a while, then evaporates.",
objects[otmp->otyp].oc_name);
useup(otmp);
break;
}
pline("Your %s glows green for a moment.",
objects[otmp->otyp].oc_name);
otmp->cursed = 0;
otmp->spe++;
break;
}
case SCR_DESTROY_ARMOR:
if (confused) {
struct obj *otmp = some_armor();
if (!otmp) {
strange_feeling(scroll, "Your bones itch.");
return (1);
}
pline("Your %s glows purple for a moment.",
objects[otmp->otyp].oc_name);
otmp->rustfree = 0;
break;
}
if (uarm) {
pline("Your armor turns to dust and falls to the floor!");
useup(uarm);
} else if (uarmh) {
pline("Your helmet turns to dust and is blown away!");
useup(uarmh);
} else if (uarmg) {
pline("Your gloves vanish!");
useup(uarmg);
selftouch("You");
} else {
strange_feeling(scroll, "Your skin itches.");
return (1);
}
break;
case SCR_CONFUSE_MONSTER:
if (confused) {
pline("Your hands begin to glow purple.");
Confusion += rnd(100);
} else {
pline("Your hands begin to glow blue.");
u.umconf = 1;
}
break;
case SCR_SCARE_MONSTER:
{
int ct = 0;
struct monst *mtmp;
for (mtmp = fmon; mtmp; mtmp = mtmp->nmon)
if (cansee(mtmp->mx, mtmp->my)) {
if (confused)
mtmp->mflee = mtmp->mfroz =
mtmp->msleep = 0;
else
mtmp->mflee = 1;
ct++;
}
if (!ct) {
if (confused)
pline("You hear sad wailing in the distance.");
else
pline("You hear maniacal laughter in the distance.");
}
break;
}
case SCR_BLANK_PAPER:
if (confused)
pline("You see strange patterns on this scroll.");
else
pline("This scroll seems to be blank.");
break;
case SCR_REMOVE_CURSE:
{
struct obj *obj;
if (confused)
pline("You feel like you need some help.");
else
pline("You feel like someone is helping you.");
for (obj = invent; obj; obj = obj->nobj)
if (obj->owornmask)
obj->cursed = confused;
if (Punished && !confused) {
Punished = 0;
freeobj(uchain);
unpobj(uchain);
free((char *) uchain);
uball->spe = 0;
uball->owornmask &= ~W_BALL;
uchain = uball = (struct obj *) 0;
}
break;
}
case SCR_CREATE_MONSTER:
{
int cnt = 1;
if (!rn2(73))
cnt += rnd(4);
if (confused)
cnt += 12;
while (cnt--)
(void) makemon(confused ? PM_ACID_BLOB :
(struct permonst *) 0, u.ux, u.uy);
break;
}
case SCR_ENCHANT_WEAPON:
if (uwep && confused) {
pline("Your %s glows silver for a moment.",
objects[uwep->otyp].oc_name);
uwep->rustfree = 1;
} else if (!chwepon(scroll, 1)) /* tests for !uwep */
return (1);
break;
case SCR_DAMAGE_WEAPON:
if (uwep && confused) {
pline("Your %s glows purple for a moment.",
objects[uwep->otyp].oc_name);
uwep->rustfree = 0;
} else if (!chwepon(scroll, -1)) /* tests for !uwep */
return (1);
break;
case SCR_TAMING:
{
int i, j;
int bd = confused ? 5 : 1;
struct monst *mtmp;
for (i = -bd; i <= bd; i++)
for (j = -bd; j <= bd; j++)
if ((mtmp = m_at(u.ux + i, u.uy + j)) != NULL)
(void) tamedog(mtmp, (struct obj *) 0);
break;
}
case SCR_GENOCIDE:
{
char buf[BUFSZ];
struct monst *mtmp, *mtmp2;
pline("You have found a scroll of genocide!");
known = TRUE;
if (confused)
*buf = u.usym;
else
do {
pline("What monster do you want to genocide (Type the letter)? ");
getlin(buf);
} while (strlen(buf) != 1 || !monstersym(*buf));
if (!strchr(fut_geno, *buf))
charcat(fut_geno, *buf);
if (!strchr(genocided, *buf))
charcat(genocided, *buf);
else {
pline("Such monsters do not exist in this world.");
break;
}
for (mtmp = fmon; mtmp; mtmp = mtmp2) {
mtmp2 = mtmp->nmon;
if (mtmp->data->mlet == *buf)
mondead(mtmp);
}
pline("Wiped out all %c's.", *buf);
if (*buf == u.usym) {
killer = "scroll of genocide";
u.uhp = -1;
}
break;
}
case SCR_LIGHT:
if (!Blind)
known = TRUE;
litroom(!confused);
break;
case SCR_TELEPORTATION:
if (confused)
level_tele();
else {
#ifdef QUEST
int oux = u.ux, ouy = u.uy;
tele();
if (dist(oux, ouy) > 100)
known = TRUE;
#else /* QUEST */
int uroom = inroom(u.ux, u.uy);
tele();
if (uroom != inroom(u.ux, u.uy))
known = TRUE;
#endif /* QUEST */
}
break;
case SCR_GOLD_DETECTION:
/*
* Unfortunately this code has become slightly less elegant,
* now that gold and traps no longer are of the same type.
*/
if (confused) {
struct trap *ttmp;
if (!ftrap) {
strange_feeling(scroll, "Your toes stop itching.");
return (1);
} else {
for (ttmp = ftrap; ttmp; ttmp = ttmp->ntrap)
if (ttmp->tx != u.ux || ttmp->ty != u.uy)
goto outtrapmap;
/*
* only under me - no separate display
* required
*/
pline("Your toes itch!");
break;
outtrapmap:
cls();
for (ttmp = ftrap; ttmp; ttmp = ttmp->ntrap)
at(ttmp->tx, ttmp->ty, '$');
prme();
pline("You feel very greedy!");
}
} else {
struct gold *gtmp;
if (!fgold) {
strange_feeling(scroll, "You feel materially poor.");
return (1);
} else {
known = TRUE;
for (gtmp = fgold; gtmp; gtmp = gtmp->ngold)
if (gtmp->gx != u.ux || gtmp->gy != u.uy)
goto outgoldmap;
/*
* only under me - no separate display
* required
*/
pline("You notice some gold between your feet.");
break;
outgoldmap:
cls();
for (gtmp = fgold; gtmp; gtmp = gtmp->ngold)
at(gtmp->gx, gtmp->gy, '$');
prme();
pline("You feel very greedy, and sense gold!");
}
}
/* common sequel */
more();
docrt();
break;
case SCR_FOOD_DETECTION:
{
int ct = 0, ctu = 0;
struct obj *obj;
char foodsym = confused ? POTION_SYM : FOOD_SYM;
for (obj = fobj; obj; obj = obj->nobj)
if (obj->olet == FOOD_SYM) {
if (obj->ox == u.ux && obj->oy == u.uy)
ctu++;
else
ct++;
}
if (!ct && !ctu) {
strange_feeling(scroll, "Your nose twitches.");
return (1);
} else if (!ct) {
known = TRUE;
pline("You smell %s close nearby.",
confused ? "something" : "food");
} else {
known = TRUE;
cls();
for (obj = fobj; obj; obj = obj->nobj)
if (obj->olet == foodsym)
at(obj->ox, obj->oy, FOOD_SYM);
prme();
pline("Your nose tingles and you smell %s!",
confused ? "something" : "food");
more();
docrt();
}
break;
}
case SCR_IDENTIFY:
/* known = TRUE; */
if (confused)
pline("You identify this as an identify scroll.");
else
pline("This is an identify scroll.");
useup(scroll);
objects[SCR_IDENTIFY].oc_name_known = 1;
if (!confused)
while (
!ggetobj("identify", identify, rn2(5) ? 1 : rn2(5))
&& invent
);
return (1);
case SCR_MAGIC_MAPPING:
{
struct rm *lev;
int num, zx, zy;
known = TRUE;
pline("On this scroll %s a map!",
confused ? "was" : "is");
for (zy = 0; zy < ROWNO; zy++)
for (zx = 0; zx < COLNO; zx++) {
if (confused && rn2(7))
continue;
lev = &(levl[zx][zy]);
if ((num = lev->typ) == 0)
continue;
if (num == SCORR) {
lev->typ = CORR;
lev->scrsym = CORR_SYM;
} else if (num == SDOOR) {
lev->typ = DOOR;
lev->scrsym = '+';
/* do sth in doors ? */
} else if (lev->seen)
continue;
#ifndef QUEST
if (num != ROOM)
#endif /* QUEST */
{
lev->seen = lev->new = 1;
if (lev->scrsym == ' ' || !lev->scrsym)
newsym(zx, zy);
else
on_scr(zx, zy);
}
}
break;
}
case SCR_AMNESIA:
{
int zx, zy;
known = TRUE;
for (zx = 0; zx < COLNO; zx++)
for (zy = 0; zy < ROWNO; zy++)
if (!confused || rn2(7))
if (!cansee(zx, zy))
levl[zx][zy].seen = 0;
docrt();
pline("Thinking of Maud you forget everything else.");
break;
}
case SCR_FIRE:
{
int num = 0;
struct monst *mtmp;
known = TRUE;
if (confused) {
pline("The scroll catches fire and you burn your hands.");
losehp(1, "scroll of fire");
} else {
pline("The scroll erupts in a tower of flame!");
if (Fire_resistance)
pline("You are uninjured.");
else {
num = rnd(6);
u.uhpmax -= num;
losehp(num, "scroll of fire");
}
}
num = (2 * num + 1) / 3;
for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
if (dist(mtmp->mx, mtmp->my) < 3) {
mtmp->mhp -= num;
if (strchr("FY", mtmp->data->mlet))
mtmp->mhp -= 3 * num; /* this might well kill
* 'F's */
if (mtmp->mhp < 1) {
killed(mtmp);
break; /* primitive */
}
}
}
break;
}
case SCR_PUNISHMENT:
known = TRUE;
if (confused) {
pline("You feel guilty.");
break;
}
pline("You are being punished for your misbehaviour!");
if (Punished) {
pline("Your iron ball gets heavier.");
uball->owt += 15;
break;
}
Punished = INTRINSIC;
setworn(mkobj_at(CHAIN_SYM, u.ux, u.uy), W_CHAIN);
setworn(mkobj_at(BALL_SYM, u.ux, u.uy), W_BALL);
uball->spe = 1; /* special ball (see save) */
break;
default:
impossible("What weird language is this written in? (%u)",
scroll->otyp);
}
if (!objects[scroll->otyp].oc_name_known) {
if (known && !confused) {
objects[scroll->otyp].oc_name_known = 1;
more_experienced(0, 10);
} else if (!objects[scroll->otyp].oc_uname)
docall(scroll);
}
useup(scroll);
return (1);
}
int
identify(otmp) /* also called by newmail() */
struct obj *otmp;
{
objects[otmp->otyp].oc_name_known = 1;
otmp->known = otmp->dknown = 1;
prinv(otmp);
return (1);
}
void
litroom(on)
boolean on;
{
#ifndef QUEST
int num, zx, zy;
#endif
/* first produce the text (provided he is not blind) */
if (Blind)
goto do_it;
if (!on) {
if (u.uswallow || !xdnstair || levl[u.ux][u.uy].typ == CORR ||
!levl[u.ux][u.uy].lit) {
pline("It seems even darker in here than before.");
return;
} else
pline("It suddenly becomes dark in here.");
} else {
if (u.uswallow) {
pline("%s's stomach is lit.", Monnam(u.ustuck));
return;
}
if (!xdnstair) {
pline("Nothing Happens.");
return;
}
#ifdef QUEST
pline("The cave lights up around you, then fades.");
return;
#else /* QUEST */
if (levl[u.ux][u.uy].typ == CORR) {
pline("The corridor lights up around you, then fades.");
return;
} else if (levl[u.ux][u.uy].lit) {
pline("The light here seems better now.");
return;
} else
pline("The room is lit.");
#endif /* QUEST */
}
do_it:
#ifdef QUEST
return;
#else /* QUEST */
if (levl[u.ux][u.uy].lit == on)
return;
if (levl[u.ux][u.uy].typ == DOOR) {
if (IS_ROOM(levl[u.ux][u.uy + 1].typ))
zy = u.uy + 1;
else if (IS_ROOM(levl[u.ux][u.uy - 1].typ))
zy = u.uy - 1;
else
zy = u.uy;
if (IS_ROOM(levl[u.ux + 1][u.uy].typ))
zx = u.ux + 1;
else if (IS_ROOM(levl[u.ux - 1][u.uy].typ))
zx = u.ux - 1;
else
zx = u.ux;
} else {
zx = u.ux;
zy = u.uy;
}
for (seelx = u.ux; (num = levl[seelx - 1][zy].typ) != CORR && num != 0;
seelx--);
for (seehx = u.ux; (num = levl[seehx + 1][zy].typ) != CORR && num != 0;
seehx++);
for (seely = u.uy; (num = levl[zx][seely - 1].typ) != CORR && num != 0;
seely--);
for (seehy = u.uy; (num = levl[zx][seehy + 1].typ) != CORR && num != 0;
seehy++);
for (zy = seely; zy <= seehy; zy++)
for (zx = seelx; zx <= seehx; zx++) {
levl[zx][zy].lit = on;
if (!Blind && dist(zx, zy) > 2) {
if (on)
prl(zx, zy);
else
nosee(zx, zy);
}
}
if (!on)
seehx = 0;
#endif /* QUEST */
}
/* Test whether we may genocide all monsters with symbol ch */
int
monstersym(ch) /* arnold@ucsfcgl */
char ch;
{
const struct permonst *mp;
/*
* can't genocide certain monsters
*/
if (strchr("12 &:", ch))
return FALSE;
if (ch == pm_eel.mlet)
return TRUE;
for (mp = mons; mp < &mons[CMNUM + 2]; mp++)
if (mp->mlet == ch)
return TRUE;
return FALSE;
}

134
hack/hack.rip.c Normal file
View File

@@ -0,0 +1,134 @@
/* $NetBSD: hack.rip.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 <hack@gnu.org>
* 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 <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: hack.rip.c,v 1.6 2001/03/25 20:44:02 jsm Exp $");
#endif /* not lint */
#include "hack.h"
#include "extern.h"
static const char *riptop = "\
----------\n\
/ \\\n\
/ REST \\\n\
/ IN \\\n\
/ PEACE \\\n\
/ \\";
static const char *ripmid = " | %*s%*s |\n";
static const char *ripbot = "\
*| * * * | *\n\
_________)/\\\\_//(\\/(/\\)/\\//\\/|_)_______";
void
outrip()
{
char buf[BUFSZ];
cls();
curs(1, 8);
puts(riptop);
(void) strcpy(buf, plname);
buf[16] = 0;
center(6, buf);
(void) sprintf(buf, "%ld AU", u.ugold);
center(7, buf);
(void) sprintf(buf, "killed by%s",
!strncmp(killer, "the ", 4) ? "" :
!strcmp(killer, "starvation") ? "" :
strchr(vowels, *killer) ? " an" : " a");
center(8, buf);
(void) strcpy(buf, killer);
{
int i1;
if ((i1 = strlen(buf)) > 16) {
int i, i0;
i0 = i1 = 0;
for (i = 0; i <= 16; i++)
if (buf[i] == ' ')
i0 = i, i1 = i + 1;
if (!i0)
i0 = i1 = 16;
buf[i1 + 16] = 0;
buf[i0] = 0;
}
center(9, buf);
center(10, buf + i1);
}
(void) sprintf(buf, "%4d", getyear());
center(11, buf);
puts(ripbot);
getret();
}
void
center(line, text)
int line __attribute__((__unused__));
char *text;
{
int n = strlen(text) / 2;
printf(ripmid, 8 + n, text, 8 - n, "");
}

150
hack/hack.rumors.c Normal file
View File

@@ -0,0 +1,150 @@
/* $NetBSD: hack.rumors.c,v 1.4 1997/10/19 16:58:55 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 <hack@gnu.org>
* 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 <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: hack.rumors.c,v 1.4 1997/10/19 16:58:55 christos Exp $");
#endif /* not lint */
#include "hack.h" /* for RUMORFILE and BSD (strchr) */
#include "extern.h"
#define CHARSZ 8 /* number of bits in a char */
int n_rumors = 0;
int n_used_rumors = -1;
char *usedbits;
void
init_rumors(rumf)
FILE *rumf;
{
int i;
n_used_rumors = 0;
while (skipline(rumf))
n_rumors++;
rewind(rumf);
i = n_rumors / CHARSZ;
usedbits = (char *) alloc((unsigned) (i + 1));
for (; i >= 0; i--)
usedbits[i] = 0;
}
int
skipline(rumf)
FILE *rumf;
{
char line[COLNO];
while (1) {
if (!fgets(line, sizeof(line), rumf))
return (0);
if (strchr(line, '\n'))
return (1);
}
}
void
outline(rumf)
FILE *rumf;
{
char line[COLNO];
char *ep;
if (!fgets(line, sizeof(line), rumf))
return;
if ((ep = strchr(line, '\n')) != 0)
*ep = 0;
pline("This cookie has a scrap of paper inside! It reads: ");
pline(line);
}
void
outrumor()
{
int rn, i;
FILE *rumf;
if (n_rumors <= n_used_rumors ||
(rumf = fopen(RUMORFILE, "r")) == (FILE *) 0)
return;
if (n_used_rumors < 0)
init_rumors(rumf);
if (!n_rumors)
goto none;
rn = rn2(n_rumors - n_used_rumors);
i = 0;
while (rn || used(i)) {
(void) skipline(rumf);
if (!used(i))
rn--;
i++;
}
usedbits[i / CHARSZ] |= (1 << (i % CHARSZ));
n_used_rumors++;
outline(rumf);
none:
(void) fclose(rumf);
}
int
used(i)
int i;
{
return (usedbits[i / CHARSZ] & (1 << (i % CHARSZ)));
}

314
hack/hack.save.c Normal file
View File

@@ -0,0 +1,314 @@
/* $NetBSD: hack.save.c,v 1.7 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 <hack@gnu.org>
* 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 <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: hack.save.c,v 1.7 2001/03/25 20:44:02 jsm Exp $");
#endif /* not lint */
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include "hack.h"
#include "extern.h"
int
dosave()
{
if (dosave0(0)) {
settty("Be seeing you ...\n");
exit(0);
}
return (0);
}
#ifndef NOSAVEONHANGUP
void
hangup(n)
int n __attribute__((__unused__));
{
(void) dosave0(1);
exit(1);
}
#endif /* NOSAVEONHANGUP */
/* returns 1 if save successful */
int
dosave0(hu)
int hu;
{
int fd, ofd;
int tmp; /* not ! */
(void) signal(SIGHUP, SIG_IGN);
(void) signal(SIGINT, SIG_IGN);
if ((fd = creat(SAVEF, FMASK)) < 0) {
if (!hu)
pline("Cannot open save file. (Continue or Quit)");
(void) unlink(SAVEF); /* ab@unido */
return (0);
}
if (flags.moonphase == FULL_MOON) /* ut-sally!fletcher */
u.uluck--; /* and unido!ab */
savelev(fd, dlevel);
saveobjchn(fd, invent);
saveobjchn(fd, fcobj);
savemonchn(fd, fallen_down);
tmp = getuid();
bwrite(fd, (char *) &tmp, sizeof tmp);
bwrite(fd, (char *) &flags, sizeof(struct flag));
bwrite(fd, (char *) &dlevel, sizeof dlevel);
bwrite(fd, (char *) &maxdlevel, sizeof maxdlevel);
bwrite(fd, (char *) &moves, sizeof moves);
bwrite(fd, (char *) &u, sizeof(struct you));
if (u.ustuck)
bwrite(fd, (char *) &(u.ustuck->m_id), sizeof u.ustuck->m_id);
bwrite(fd, (char *) pl_character, sizeof pl_character);
bwrite(fd, (char *) genocided, sizeof genocided);
bwrite(fd, (char *) fut_geno, sizeof fut_geno);
savenames(fd);
for (tmp = 1; tmp <= maxdlevel; tmp++) {
if (tmp == dlevel || !level_exists[tmp])
continue;
glo(tmp);
if ((ofd = open(lock, O_RDONLY)) < 0) {
if (!hu)
pline("Error while saving: cannot read %s.", lock);
(void) close(fd);
(void) unlink(SAVEF);
if (!hu)
done("tricked");
return (0);
}
getlev(ofd, hackpid, tmp);
(void) close(ofd);
bwrite(fd, (char *) &tmp, sizeof tmp); /* level number */
savelev(fd, tmp); /* actual level */
(void) unlink(lock);
}
(void) close(fd);
glo(dlevel);
(void) unlink(lock); /* get rid of current level --jgm */
glo(0);
(void) unlink(lock);
return (1);
}
int
dorecover(fd)
int fd;
{
int nfd;
int tmp; /* not a ! */
unsigned mid; /* idem */
struct obj *otmp;
restoring = TRUE;
getlev(fd, 0, 0);
invent = restobjchn(fd);
for (otmp = invent; otmp; otmp = otmp->nobj)
if (otmp->owornmask)
setworn(otmp, otmp->owornmask);
fcobj = restobjchn(fd);
fallen_down = restmonchn(fd);
mread(fd, (char *) &tmp, sizeof tmp);
if (tmp != (int)getuid()) { /* strange ... */
(void) close(fd);
(void) unlink(SAVEF);
puts("Saved game was not yours.");
restoring = FALSE;
return (0);
}
mread(fd, (char *) &flags, sizeof(struct flag));
mread(fd, (char *) &dlevel, sizeof dlevel);
mread(fd, (char *) &maxdlevel, sizeof maxdlevel);
mread(fd, (char *) &moves, sizeof moves);
mread(fd, (char *) &u, sizeof(struct you));
if (u.ustuck)
mread(fd, (char *) &mid, sizeof mid);
mread(fd, (char *) pl_character, sizeof pl_character);
mread(fd, (char *) genocided, sizeof genocided);
mread(fd, (char *) fut_geno, sizeof fut_geno);
restnames(fd);
while (1) {
if (read(fd, (char *) &tmp, sizeof tmp) != sizeof tmp)
break;
getlev(fd, 0, tmp);
glo(tmp);
if ((nfd = creat(lock, FMASK)) < 0)
panic("Cannot open temp file %s!\n", lock);
savelev(nfd, tmp);
(void) close(nfd);
}
(void) lseek(fd, (off_t) 0, SEEK_SET);
getlev(fd, 0, 0);
(void) close(fd);
(void) unlink(SAVEF);
if (Punished) {
for (otmp = fobj; otmp; otmp = otmp->nobj)
if (otmp->olet == CHAIN_SYM)
goto chainfnd;
panic("Cannot find the iron chain?");
chainfnd:
uchain = otmp;
if (!uball) {
for (otmp = fobj; otmp; otmp = otmp->nobj)
if (otmp->olet == BALL_SYM && otmp->spe)
goto ballfnd;
panic("Cannot find the iron ball?");
ballfnd:
uball = otmp;
}
}
if (u.ustuck) {
struct monst *mtmp;
for (mtmp = fmon; mtmp; mtmp = mtmp->nmon)
if (mtmp->m_id == mid)
goto monfnd;
panic("Cannot find the monster ustuck.");
monfnd:
u.ustuck = mtmp;
}
#ifndef QUEST
setsee(); /* only to recompute seelx etc. - these
* weren't saved */
#endif /* QUEST */
docrt();
restoring = FALSE;
return (1);
}
struct obj *
restobjchn(fd)
int fd;
{
struct obj *otmp, *otmp2 = NULL;
struct obj *first = 0;
int xl;
while (1) {
mread(fd, (char *) &xl, sizeof(xl));
if (xl == -1)
break;
otmp = newobj(xl);
if (!first)
first = otmp;
else
otmp2->nobj = otmp;
mread(fd, (char *) otmp, (unsigned) xl + sizeof(struct obj));
if (!otmp->o_id)
otmp->o_id = flags.ident++;
otmp2 = otmp;
}
if (first && otmp2->nobj) {
impossible("Restobjchn: error reading objchn.");
otmp2->nobj = 0;
}
return (first);
}
struct monst *
restmonchn(fd)
int fd;
{
struct monst *mtmp, *mtmp2 = NULL;
struct monst *first = 0;
int xl;
struct permonst *monbegin;
long differ;
mread(fd, (char *) &monbegin, sizeof(monbegin));
differ = (const char *) (&mons[0]) - (const char *) (monbegin);
#ifdef lint
/* suppress "used before set" warning from lint */
mtmp2 = 0;
#endif /* lint */
while (1) {
mread(fd, (char *) &xl, sizeof(xl));
if (xl == -1)
break;
mtmp = newmonst(xl);
if (!first)
first = mtmp;
else
mtmp2->nmon = mtmp;
mread(fd, (char *) mtmp, (unsigned) xl + sizeof(struct monst));
if (!mtmp->m_id)
mtmp->m_id = flags.ident++;
mtmp->data = (const struct permonst *)
((const char *) mtmp->data + differ);
if (mtmp->minvent)
mtmp->minvent = restobjchn(fd);
mtmp2 = mtmp;
}
if (first && mtmp2->nmon) {
impossible("Restmonchn: error reading monchn.");
mtmp2->nmon = 0;
}
return (first);
}

216
hack/hack.search.c Normal file
View File

@@ -0,0 +1,216 @@
/* $NetBSD: hack.search.c,v 1.4 1997/10/19 16:58:59 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 <hack@gnu.org>
* 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 <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: hack.search.c,v 1.4 1997/10/19 16:58:59 christos Exp $");
#endif /* not lint */
#include "hack.h"
#include "extern.h"
int
findit()
{ /* returns number of things found */
int num;
xchar zx, zy;
struct trap *ttmp;
struct monst *mtmp;
xchar lx, hx, ly, hy;
if (u.uswallow)
return (0);
for (lx = u.ux; (num = levl[lx - 1][u.uy].typ) && num != CORR; lx--);
for (hx = u.ux; (num = levl[hx + 1][u.uy].typ) && num != CORR; hx++);
for (ly = u.uy; (num = levl[u.ux][ly - 1].typ) && num != CORR; ly--);
for (hy = u.uy; (num = levl[u.ux][hy + 1].typ) && num != CORR; hy++);
num = 0;
for (zy = ly; zy <= hy; zy++)
for (zx = lx; zx <= hx; zx++) {
if (levl[zx][zy].typ == SDOOR) {
levl[zx][zy].typ = DOOR;
atl(zx, zy, '+');
num++;
} else if (levl[zx][zy].typ == SCORR) {
levl[zx][zy].typ = CORR;
atl(zx, zy, CORR_SYM);
num++;
} else if ((ttmp = t_at(zx, zy)) != NULL) {
if (ttmp->ttyp == PIERC) {
(void) makemon(PM_PIERCER, zx, zy);
num++;
deltrap(ttmp);
} else if (!ttmp->tseen) {
ttmp->tseen = 1;
if (!vism_at(zx, zy))
atl(zx, zy, '^');
num++;
}
} else if ((mtmp = m_at(zx, zy)) != NULL)
if (mtmp->mimic) {
seemimic(mtmp);
num++;
}
}
return (num);
}
int
dosearch()
{
xchar x, y;
struct trap *trap;
struct monst *mtmp;
if (u.uswallow)
pline("What are you looking for? The exit?");
else
for (x = u.ux - 1; x < u.ux + 2; x++)
for (y = u.uy - 1; y < u.uy + 2; y++)
if (x != u.ux || y != u.uy) {
if (levl[x][y].typ == SDOOR) {
if (rn2(7))
continue;
levl[x][y].typ = DOOR;
levl[x][y].seen = 0; /* force prl */
prl(x, y);
nomul(0);
} else if (levl[x][y].typ == SCORR) {
if (rn2(7))
continue;
levl[x][y].typ = CORR;
levl[x][y].seen = 0; /* force prl */
prl(x, y);
nomul(0);
} else {
/*
* Be careful not to find
* anything in an SCORR or
* SDOOR
*/
if ((mtmp = m_at(x, y)) != NULL)
if (mtmp->mimic) {
seemimic(mtmp);
pline("You find a mimic.");
return (1);
}
for (trap = ftrap; trap; trap = trap->ntrap)
if (trap->tx == x && trap->ty == y &&
!trap->tseen && !rn2(8)) {
nomul(0);
pline("You find a%s.", traps[trap->ttyp]);
if (trap->ttyp == PIERC) {
deltrap(trap);
(void) makemon(PM_PIERCER, x, y);
return (1);
}
trap->tseen = 1;
if (!vism_at(x, y))
atl(x, y, '^');
}
}
}
return (1);
}
int
doidtrap()
{
struct trap *trap;
int x, y;
if (!getdir(1))
return (0);
x = u.ux + u.dx;
y = u.uy + u.dy;
for (trap = ftrap; trap; trap = trap->ntrap)
if (trap->tx == x && trap->ty == y && trap->tseen) {
if (u.dz)
if ((u.dz < 0) != (!xdnstair && trap->ttyp == TRAPDOOR))
continue;
pline("That is a%s.", traps[trap->ttyp]);
return (0);
}
pline("I can't see a trap there.");
return (0);
}
void
wakeup(mtmp)
struct monst *mtmp;
{
mtmp->msleep = 0;
setmangry(mtmp);
if (mtmp->mimic)
seemimic(mtmp);
}
/* NOTE: we must check if(mtmp->mimic) before calling this routine */
void
seemimic(mtmp)
struct monst *mtmp;
{
mtmp->mimic = 0;
mtmp->mappearance = 0;
unpmon(mtmp);
pmon(mtmp);
}

77
hack/hack.sh Normal file
View File

@@ -0,0 +1,77 @@
#!/bin/sh
# $NetBSD: hack.sh,v 1.2 1995/03/23 08:31:30 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 <hack@gnu.org>
# 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.
#
HACKDIR=/usr/games/lib/hackdir
HACK=$HACKDIR/hack
MAXNROFPLAYERS=4
cd $HACKDIR
case $1 in
-s*)
exec $HACK $@
;;
*)
exec $HACK $@ $MAXNROFPLAYERS
;;
esac

1168
hack/hack.shk.c Normal file

File diff suppressed because it is too large Load Diff

230
hack/hack.shknam.c Normal file
View File

@@ -0,0 +1,230 @@
/* $NetBSD: hack.shknam.c,v 1.5 2001/03/25 20:44:03 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 <hack@gnu.org>
* 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 <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: hack.shknam.c,v 1.5 2001/03/25 20:44:03 jsm Exp $");
#endif /* not lint */
#include "hack.h"
#include "extern.h"
const char *const shkliquors[] = {
/* Ukraine */
"Njezjin", "Tsjernigof", "Gomel", "Ossipewsk", "Gorlowka",
/* N. Russia */
"Konosja", "Weliki Oestjoeg", "Syktywkar", "Sablja",
"Narodnaja", "Kyzyl",
/* Silezie */
"Walbrzych", "Swidnica", "Klodzko", "Raciborz", "Gliwice",
"Brzeg", "Krnov", "Hradec Kralove",
/* Schweiz */
"Leuk", "Brig", "Brienz", "Thun", "Sarnen", "Burglen", "Elm",
"Flims", "Vals", "Schuls", "Zum Loch",
0
};
const char *const shkbooks[] = {
/* Eire */
"Skibbereen", "Kanturk", "Rath Luirc", "Ennistymon", "Lahinch",
"Loughrea", "Croagh", "Maumakeogh", "Ballyjamesduff",
"Kinnegad", "Lugnaquillia", "Enniscorthy", "Gweebarra",
"Kittamagh", "Nenagh", "Sneem", "Ballingeary", "Kilgarvan",
"Cahersiveen", "Glenbeigh", "Kilmihil", "Kiltamagh",
"Droichead Atha", "Inniscrone", "Clonegal", "Lisnaskea",
"Culdaff", "Dunfanaghy", "Inishbofin", "Kesh",
0
};
const char *const shkarmors[] = {
/* Turquie */
"Demirci", "Kalecik", "Boyabai", "Yildizeli", "Gaziantep",
"Siirt", "Akhalataki", "Tirebolu", "Aksaray", "Ermenak",
"Iskenderun", "Kadirli", "Siverek", "Pervari", "Malasgirt",
"Bayburt", "Ayancik", "Zonguldak", "Balya", "Tefenni",
"Artvin", "Kars", "Makharadze", "Malazgirt", "Midyat",
"Birecik", "Kirikkale", "Alaca", "Polatli", "Nallihan",
0
};
const char *const shkwands[] = {
/* Wales */
"Yr Wyddgrug", "Trallwng", "Mallwyd", "Pontarfynach",
"Rhaeader", "Llandrindod", "Llanfair-ym-muallt",
"Y-Fenni", "Measteg", "Rhydaman", "Beddgelert",
"Curig", "Llanrwst", "Llanerchymedd", "Caergybi",
/* Scotland */
"Nairn", "Turriff", "Inverurie", "Braemar", "Lochnagar",
"Kerloch", "Beinn a Ghlo", "Drumnadrochit", "Morven",
"Uist", "Storr", "Sgurr na Ciche", "Cannich", "Gairloch",
"Kyleakin", "Dunvegan",
0
};
const char *const shkrings[] = {
/* Hollandse familienamen */
"Feyfer", "Flugi", "Gheel", "Havic", "Haynin", "Hoboken",
"Imbyze", "Juyn", "Kinsky", "Massis", "Matray", "Moy",
"Olycan", "Sadelin", "Svaving", "Tapper", "Terwen", "Wirix",
"Ypey",
/* Skandinaviske navne */
"Rastegaisa", "Varjag Njarga", "Kautekeino", "Abisko",
"Enontekis", "Rovaniemi", "Avasaksa", "Haparanda",
"Lulea", "Gellivare", "Oeloe", "Kajaani", "Fauske",
0
};
const char *const shkfoods[] = {
/* Indonesia */
"Djasinga", "Tjibarusa", "Tjiwidej", "Pengalengan",
"Bandjar", "Parbalingga", "Bojolali", "Sarangan",
"Ngebel", "Djombang", "Ardjawinangun", "Berbek",
"Papar", "Baliga", "Tjisolok", "Siboga", "Banjoewangi",
"Trenggalek", "Karangkobar", "Njalindoeng", "Pasawahan",
"Pameunpeuk", "Patjitan", "Kediri", "Pemboeang", "Tringanoe",
"Makin", "Tipor", "Semai", "Berhala", "Tegal", "Samoe",
0
};
const char *const shkweapons[] = {
/* Perigord */
"Voulgezac", "Rouffiac", "Lerignac", "Touverac", "Guizengeard",
"Melac", "Neuvicq", "Vanzac", "Picq", "Urignac", "Corignac",
"Fleac", "Lonzac", "Vergt", "Queyssac", "Liorac", "Echourgnac",
"Cazelon", "Eypau", "Carignan", "Monbazillac", "Jonzac",
"Pons", "Jumilhac", "Fenouilledes", "Laguiolet", "Saujon",
"Eymoutiers", "Eygurande", "Eauze", "Labouheyre",
0
};
const char *const shkgeneral[] = {
/* Suriname */
"Hebiwerie", "Possogroenoe", "Asidonhopo", "Manlobbi",
"Adjama", "Pakka Pakka", "Kabalebo", "Wonotobo",
"Akalapi", "Sipaliwini",
/* Greenland */
"Annootok", "Upernavik", "Angmagssalik",
/* N. Canada */
"Aklavik", "Inuvik", "Tuktoyaktuk",
"Chicoutimi", "Ouiatchouane", "Chibougamau",
"Matagami", "Kipawa", "Kinojevis",
"Abitibi", "Maganasipi",
/* Iceland */
"Akureyri", "Kopasker", "Budereyri", "Akranes", "Bordeyri",
"Holmavik",
0
};
const struct shk_nx {
char x;
const char *const *xn;
} shk_nx[] = {
{
POTION_SYM, shkliquors
},
{
SCROLL_SYM, shkbooks
},
{
ARMOR_SYM, shkarmors
},
{
WAND_SYM, shkwands
},
{
RING_SYM, shkrings
},
{
FOOD_SYM, shkfoods
},
{
WEAPON_SYM, shkweapons
},
{
0, shkgeneral
}
};
void
findname(nampt, let)
char *nampt;
char let;
{
const struct shk_nx *p = shk_nx;
const char *const *q;
int i;
while (p->x && p->x != let)
p++;
q = p->xn;
for (i = 0; i < dlevel; i++)
if (!q[i]) {
/* Not enough names, try general name */
if (let)
findname(nampt, 0);
else
(void) strcpy(nampt, "Dirk");
return;
}
(void) strncpy(nampt, q[i], PL_NSIZ);
nampt[PL_NSIZ - 1] = 0;
}

284
hack/hack.steal.c Normal file
View File

@@ -0,0 +1,284 @@
/* $NetBSD: hack.steal.c,v 1.4 1997/10/19 16:59:04 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 <hack@gnu.org>
* 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 <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: hack.steal.c,v 1.4 1997/10/19 16:59:04 christos Exp $");
#endif /* not lint */
#include <stdlib.h>
#include "hack.h"
#include "extern.h"
long /* actually returns something that fits in an
* int */
somegold()
{
return ((u.ugold < 100) ? u.ugold :
(u.ugold > 10000) ? rnd(10000) : rnd((int) u.ugold));
}
void
stealgold(mtmp)
struct monst *mtmp;
{
struct gold *gold = g_at(u.ux, u.uy);
long tmp;
if (gold && (!u.ugold || gold->amount > u.ugold || !rn2(5))) {
mtmp->mgold += gold->amount;
freegold(gold);
if (Invisible)
newsym(u.ux, u.uy);
pline("%s quickly snatches some gold from between your feet!",
Monnam(mtmp));
if (!u.ugold || !rn2(5)) {
rloc(mtmp);
mtmp->mflee = 1;
}
} else if (u.ugold) {
u.ugold -= (tmp = somegold());
pline("Your purse feels lighter.");
mtmp->mgold += tmp;
rloc(mtmp);
mtmp->mflee = 1;
flags.botl = 1;
}
}
/* steal armor after he finishes taking it off */
unsigned stealoid; /* object to be stolen */
unsigned stealmid; /* monster doing the stealing */
int
stealarm()
{
struct monst *mtmp;
struct obj *otmp;
for (otmp = invent; otmp; otmp = otmp->nobj)
if (otmp->o_id == stealoid) {
for (mtmp = fmon; mtmp; mtmp = mtmp->nmon)
if (mtmp->m_id == stealmid) {
if (dist(mtmp->mx, mtmp->my) < 3) {
freeinv(otmp);
pline("%s steals %s!", Monnam(mtmp), doname(otmp));
mpickobj(mtmp, otmp);
mtmp->mflee = 1;
rloc(mtmp);
}
break;
}
break;
}
stealoid = 0;
return 0;
}
/* returns 1 when something was stolen */
/* (or at least, when N should flee now) */
/* avoid stealing the object stealoid */
int
steal(mtmp)
struct monst *mtmp;
{
struct obj *otmp;
int tmp;
int named = 0;
if (!invent) {
if (Blind)
pline("Somebody tries to rob you, but finds nothing to steal.");
else
pline("%s tries to rob you, but she finds nothing to steal!",
Monnam(mtmp));
return (1); /* let her flee */
}
tmp = 0;
for (otmp = invent; otmp; otmp = otmp->nobj)
if (otmp != uarm2)
tmp += ((otmp->owornmask & (W_ARMOR | W_RING)) ? 5 : 1);
tmp = rn2(tmp);
for (otmp = invent; otmp; otmp = otmp->nobj)
if (otmp != uarm2)
if ((tmp -= ((otmp->owornmask & (W_ARMOR | W_RING)) ? 5 : 1))
< 0)
break;
if (!otmp) {
impossible("Steal fails!");
return (0);
}
if (otmp->o_id == stealoid)
return (0);
if ((otmp->owornmask & (W_ARMOR | W_RING))) {
switch (otmp->olet) {
case RING_SYM:
ringoff(otmp);
break;
case ARMOR_SYM:
if (multi < 0 || otmp == uarms) {
setworn((struct obj *) 0, otmp->owornmask & W_ARMOR);
break;
} {
int curssv = otmp->cursed;
otmp->cursed = 0;
stop_occupation();
pline("%s seduces you and %s off your %s.",
Amonnam(mtmp, Blind ? "gentle" : "beautiful"),
otmp->cursed ? "helps you to take"
: "you start taking",
(otmp == uarmg) ? "gloves" :
(otmp == uarmh) ? "helmet" : "armor");
named++;
(void) armoroff(otmp);
otmp->cursed = curssv;
if (multi < 0) {
/*
multi = 0;
nomovemsg = 0;
afternmv = 0;
*/
stealoid = otmp->o_id;
stealmid = mtmp->m_id;
afternmv = stealarm;
return (0);
}
break;
}
default:
impossible("Tried to steal a strange worn thing.");
}
} else if (otmp == uwep)
setuwep((struct obj *) 0);
if (otmp->olet == CHAIN_SYM) {
impossible("How come you are carrying that chain?");
}
if (Punished && otmp == uball) {
Punished = 0;
freeobj(uchain);
free((char *) uchain);
uchain = (struct obj *) 0;
uball->spe = 0;
uball = (struct obj *) 0; /* superfluous */
}
freeinv(otmp);
pline("%s stole %s.", named ? "She" : Monnam(mtmp), doname(otmp));
mpickobj(mtmp, otmp);
return ((multi < 0) ? 0 : 1);
}
void
mpickobj(mtmp, otmp)
struct monst *mtmp;
struct obj *otmp;
{
otmp->nobj = mtmp->minvent;
mtmp->minvent = otmp;
}
int
stealamulet(mtmp)
struct monst *mtmp;
{
struct obj *otmp;
for (otmp = invent; otmp; otmp = otmp->nobj) {
if (otmp->olet == AMULET_SYM) {
/* might be an imitation one */
if (otmp == uwep)
setuwep((struct obj *) 0);
freeinv(otmp);
mpickobj(mtmp, otmp);
pline("%s stole %s!", Monnam(mtmp), doname(otmp));
return (1);
}
}
return (0);
}
/* release the objects the killed animal has stolen */
void
relobj(mtmp, show)
struct monst *mtmp;
int show;
{
struct obj *otmp, *otmp2;
for (otmp = mtmp->minvent; otmp; otmp = otmp2) {
otmp->ox = mtmp->mx;
otmp->oy = mtmp->my;
otmp2 = otmp->nobj;
otmp->nobj = fobj;
fobj = otmp;
stackobj(fobj);
if (show & cansee(mtmp->mx, mtmp->my))
atl(otmp->ox, otmp->oy, otmp->olet);
}
mtmp->minvent = (struct obj *) 0;
if (mtmp->mgold || mtmp->data->mlet == 'L') {
long tmp;
tmp = (mtmp->mgold > 10000) ? 10000 : mtmp->mgold;
mkgold((long) (tmp + d(dlevel, 30)), mtmp->mx, mtmp->my);
if (show & cansee(mtmp->mx, mtmp->my))
atl(mtmp->mx, mtmp->my, '$');
}
}

355
hack/hack.termcap.c Normal file
View File

@@ -0,0 +1,355 @@
/* $NetBSD: hack.termcap.c,v 1.11 2001/11/02 18:27:00 christos Exp $ */
/* For Linux: still using old termcap interface from version 1.9. */
/*
* 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 <hack@gnu.org>
* 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 <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: hack.termcap.c,v 1.11 2001/11/02 18:27:00 christos Exp $");
#endif /* not lint */
#include <string.h>
#include <termios.h>
#include <termcap.h>
#include <stdlib.h>
#include <unistd.h>
#include "hack.h"
#include "extern.h"
#include "def.flag.h" /* for flags.nonull */
static char tbuf[512];
static char *HO, *CL, *CE, *UP, *CM, *ND, *XD, *BC, *SO, *SE, *TI, *TE;
static char *VS, *VE;
static int SG;
static char PC = '\0';
char *CD; /* tested in pri.c: docorner() */
int CO, LI; /* used in pri.c and whatis.c */
void
startup()
{
char *term;
char *tptr;
char *tbufptr, *pc;
tptr = (char *) alloc(1024);
tbufptr = tbuf;
if (!(term = getenv("TERM")))
error("Can't get TERM.");
if (!strncmp(term, "5620", 4))
flags.nonull = 1; /* this should be a termcap flag */
if (tgetent(tptr, term) < 1)
error("Unknown terminal type: %s.", term);
if ((pc = tgetstr("pc", &tbufptr)) != NULL)
PC = *pc;
if (!(BC = tgetstr("bc", &tbufptr))) {
if (!tgetflag("bs"))
error("Terminal must backspace.");
BC = tbufptr;
tbufptr += 2;
*BC = '\b';
}
HO = tgetstr("ho", &tbufptr);
CO = tgetnum("co");
LI = tgetnum("li");
if (CO < COLNO || LI < ROWNO + 2)
setclipped();
if (!(CL = tgetstr("cl", &tbufptr)))
error("Hack needs CL.");
ND = tgetstr("nd", &tbufptr);
if (tgetflag("os"))
error("Hack can't have OS.");
CE = tgetstr("ce", &tbufptr);
UP = tgetstr("up", &tbufptr);
/*
* It seems that xd is no longer supported, and we should use a
* linefeed instead; unfortunately this requires resetting CRMOD, and
* many output routines will have to be modified slightly. Let's
* leave that till the next release.
*/
XD = tgetstr("xd", &tbufptr);
/* not: XD = tgetstr("do", &tbufptr); */
if (!(CM = tgetstr("cm", &tbufptr))) {
if (!UP && !HO)
error("Hack needs CM or UP or HO.");
printf("Playing hack on terminals without cm is suspect...\n");
getret();
}
SO = tgetstr("so", &tbufptr);
SE = tgetstr("se", &tbufptr);
SG = tgetnum("sg"); /* -1: not fnd; else # of spaces left by so */
if (!SO || !SE || (SG > 0))
SO = SE = 0;
CD = tgetstr("cd", &tbufptr);
set_whole_screen(); /* uses LI and CD */
if (tbufptr - tbuf > (int)sizeof(tbuf))
error("TERMCAP entry too big...\n");
free(tptr);
}
void
start_screen()
{
xputs(TI);
xputs(VS);
}
void
end_screen()
{
xputs(VE);
xputs(TE);
}
/* Cursor movements */
void
curs(x, y)
int x, y; /* not xchar: perhaps xchar is unsigned and
* curx-x would be unsigned as well */
{
if (y == cury && x == curx)
return;
if (!ND && (curx != x || x <= 3)) { /* Extremely primitive */
cmov(x, y); /* bunker!wtm */
return;
}
if (abs(cury - y) <= 3 && abs(curx - x) <= 3)
nocmov(x, y);
else if ((x <= 3 && abs(cury - y) <= 3) || (!CM && x < abs(curx - x))) {
(void) putchar('\r');
curx = 1;
nocmov(x, y);
} else if (!CM) {
nocmov(x, y);
} else
cmov(x, y);
}
void
nocmov(x, y)
int x, y;
{
if (cury > y) {
if (UP) {
while (cury > y) { /* Go up. */
xputs(UP);
cury--;
}
} else if (CM) {
cmov(x, y);
} else if (HO) {
home();
curs(x, y);
} /* else impossible("..."); */
} else if (cury < y) {
if (XD) {
while (cury < y) {
xputs(XD);
cury++;
}
} else if (CM) {
cmov(x, y);
} else {
while (cury < y) {
xputc('\n');
curx = 1;
cury++;
}
}
}
if (curx < x) { /* Go to the right. */
if (!ND)
cmov(x, y);
else /* bah */
/* should instead print what is there already */
while (curx < x) {
xputs(ND);
curx++;
}
} else if (curx > x) {
while (curx > x) { /* Go to the left. */
xputs(BC);
curx--;
}
}
}
void
cmov(x, y)
int x, y;
{
xputs(tgoto(CM, x - 1, y - 1));
cury = y;
curx = x;
}
int
xputc(c)
char c;
{
return (fputc(c, stdout));
}
void
xputs(s)
char *s;
{
tputs(s, 1, xputc);
}
void
cl_end()
{
if (CE)
xputs(CE);
else { /* no-CE fix - free after Harold Rynes */
/*
* this looks terrible, especially on a slow terminal but is
* better than nothing
*/
int cx = curx, cy = cury;
while (curx < COLNO) {
xputc(' ');
curx++;
}
curs(cx, cy);
}
}
void
clear_screen()
{
xputs(CL);
curx = cury = 1;
}
void
home()
{
if (HO)
xputs(HO);
else if (CM)
xputs(tgoto(CM, 0, 0));
else
curs(1, 1); /* using UP ... */
curx = cury = 1;
}
void
standoutbeg()
{
if (SO)
xputs(SO);
}
void
standoutend()
{
if (SE)
xputs(SE);
}
void
backsp()
{
xputs(BC);
curx--;
}
void
bell()
{
(void) putchar('\007'); /* curx does not change */
(void) fflush(stdout);
}
void
delay_output()
{
/* delay 50 ms - could also use a 'nap'-system call */
/* or the usleep call like this :-) */
usleep(50000);
}
void
cl_eos()
{ /* free after Robert Viduya *//* must only be
* called with curx = 1 */
if (CD)
xputs(CD);
else {
int cx = curx, cy = cury;
while (cury <= LI - 2) {
cl_end();
xputc('\n');
curx = 1;
cury++;
}
cl_end();
curs(cx, cy);
}
}

134
hack/hack.timeout.c Normal file
View File

@@ -0,0 +1,134 @@
/* $NetBSD: hack.timeout.c,v 1.5 2001/03/25 20:44:03 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 <hack@gnu.org>
* 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 <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: hack.timeout.c,v 1.5 2001/03/25 20:44:03 jsm Exp $");
#endif /* not lint */
#include "hack.h"
#include "extern.h"
void
timeout()
{
struct prop *upp;
if (Stoned)
stoned_dialogue();
for (upp = u.uprops; upp < u.uprops + SIZE(u.uprops); upp++)
if ((upp->p_flgs & TIMEOUT) && !--upp->p_flgs) {
if (upp->p_tofn)
(*upp->p_tofn) ();
else
switch (upp - u.uprops) {
case STONED:
killer = "cockatrice";
done("died");
break;
case SICK:
pline("You die because of food poisoning.");
killer = u.usick_cause;
done("died");
break;
case FAST:
pline("You feel yourself slowing down.");
break;
case CONFUSION:
pline("You feel less confused now.");
break;
case BLIND:
pline("You can see again.");
setsee();
break;
case INVIS:
on_scr(u.ux, u.uy);
pline("You are no longer invisible.");
break;
case WOUNDED_LEGS:
heal_legs();
break;
}
}
}
/* He is being petrified - dialogue by inmet!tower */
const char *const stoned_texts[] = {
"You are slowing down.",/* 5 */
"Your limbs are stiffening.", /* 4 */
"Your limbs have turned to stone.", /* 3 */
"You have turned to stone.", /* 2 */
"You are a statue." /* 1 */
};
void
stoned_dialogue()
{
long i = (Stoned & TIMEOUT);
if (i > 0 && i <= SIZE(stoned_texts))
pline(stoned_texts[SIZE(stoned_texts) - i]);
if (i == 5)
Fast = 0;
if (i == 3)
nomul(-3);
}

306
hack/hack.topl.c Normal file
View File

@@ -0,0 +1,306 @@
/* $NetBSD: hack.topl.c,v 1.6 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 <hack@gnu.org>
* 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 <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: hack.topl.c,v 1.6 2002/05/26 00:12:12 wiz Exp $");
#endif /* not lint */
#include <stdlib.h>
#include "hack.h"
#include "extern.h"
char toplines[BUFSZ];
xchar tlx, tly; /* set by pline; used by addtopl */
struct topl {
struct topl *next_topl;
char *topl_text;
} *old_toplines, *last_redone_topl;
#define OTLMAX 20 /* max nr of old toplines remembered */
int
doredotopl()
{
if (last_redone_topl)
last_redone_topl = last_redone_topl->next_topl;
if (!last_redone_topl)
last_redone_topl = old_toplines;
if (last_redone_topl) {
(void) strcpy(toplines, last_redone_topl->topl_text);
}
redotoplin();
return (0);
}
void
redotoplin()
{
home();
if (strchr(toplines, '\n'))
cl_end();
putstr(toplines);
cl_end();
tlx = curx;
tly = cury;
flags.toplin = 1;
if (tly > 1)
more();
}
void
remember_topl()
{
struct topl *tl;
int cnt = OTLMAX;
if (last_redone_topl &&
!strcmp(toplines, last_redone_topl->topl_text))
return;
if (old_toplines &&
!strcmp(toplines, old_toplines->topl_text))
return;
last_redone_topl = 0;
tl = (struct topl *)
alloc((unsigned) (strlen(toplines) + sizeof(struct topl) + 1));
tl->next_topl = old_toplines;
tl->topl_text = (char *) (tl + 1);
(void) strcpy(tl->topl_text, toplines);
old_toplines = tl;
while (cnt && tl) {
cnt--;
tl = tl->next_topl;
}
if (tl && tl->next_topl) {
free((char *) tl->next_topl);
tl->next_topl = 0;
}
}
void
addtopl(s)
const char *s;
{
curs(tlx, tly);
if (tlx + (int)strlen(s) > CO)
putsym('\n');
putstr(s);
tlx = curx;
tly = cury;
flags.toplin = 1;
}
void
xmore(s)
const char *s; /* allowed chars besides space/return */
{
if (flags.toplin) {
curs(tlx, tly);
if (tlx + 8 > CO)
putsym('\n'), tly++;
}
if (flags.standout)
standoutbeg();
putstr("--More--");
if (flags.standout)
standoutend();
xwaitforspace(s);
if (flags.toplin && tly > 1) {
home();
cl_end();
docorner(1, tly - 1);
}
flags.toplin = 0;
}
void
more()
{
xmore("");
}
void
cmore(s)
const char *s;
{
xmore(s);
}
void
clrlin()
{
if (flags.toplin) {
home();
cl_end();
if (tly > 1)
docorner(1, tly - 1);
remember_topl();
}
flags.toplin = 0;
}
void
pline(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
vpline(fmt, ap);
va_end(ap);
}
void
vpline(line, ap)
const char *line;
va_list ap;
{
char pbuf[BUFSZ];
char *bp = pbuf, *tl;
int n, n0;
if (!line || !*line)
return;
if (!strchr(line, '%'))
(void) strcpy(pbuf, line);
else
(void) vsprintf(pbuf, line, ap);
if (flags.toplin == 1 && !strcmp(pbuf, toplines))
return;
nscr(); /* %% */
/* If there is room on the line, print message on same line */
/* But messages like "You die..." deserve their own line */
n0 = strlen(bp);
if (flags.toplin == 1 && tly == 1 &&
n0 + (int)strlen(toplines) + 3 < CO - 8 && /* leave room for
* --More-- */
strncmp(bp, "You ", 4)) {
(void) strcat(toplines, " ");
(void) strcat(toplines, bp);
tlx += 2;
addtopl(bp);
return;
}
if (flags.toplin == 1)
more();
remember_topl();
toplines[0] = 0;
while (n0) {
if (n0 >= CO) {
/* look for appropriate cut point */
n0 = 0;
for (n = 0; n < CO; n++)
if (bp[n] == ' ')
n0 = n;
if (!n0)
for (n = 0; n < CO - 1; n++)
if (!letter(bp[n]))
n0 = n;
if (!n0)
n0 = CO - 2;
}
(void) strncpy((tl = eos(toplines)), bp, n0);
tl[n0] = 0;
bp += n0;
/* remove trailing spaces, but leave one */
while (n0 > 1 && tl[n0 - 1] == ' ' && tl[n0 - 2] == ' ')
tl[--n0] = 0;
n0 = strlen(bp);
if (n0 && tl[0])
(void) strcat(tl, "\n");
}
redotoplin();
}
void
putsym(c)
char c;
{
switch (c) {
case '\b':
backsp();
return;
case '\n':
curx = 1;
cury++;
if (cury > tly)
tly = cury;
break;
default:
if (curx == CO)
putsym('\n'); /* 1 <= curx <= CO; avoid CO */
else
curx++;
}
(void) putchar(c);
}
void
putstr(s)
const char *s;
{
while (*s)
putsym(*s++);
}

113
hack/hack.track.c Normal file
View File

@@ -0,0 +1,113 @@
/* $NetBSD: hack.track.c,v 1.4 1997/10/19 16:59:11 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 <hack@gnu.org>
* 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 <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: hack.track.c,v 1.4 1997/10/19 16:59:11 christos Exp $");
#endif /* not lint */
#include "hack.h"
#include "extern.h"
#define UTSZ 50
coord utrack[UTSZ];
int utcnt = 0;
int utpnt = 0;
void
initrack()
{
utcnt = utpnt = 0;
}
/* add to track */
void
settrack()
{
if (utcnt < UTSZ)
utcnt++;
if (utpnt == UTSZ)
utpnt = 0;
utrack[utpnt].x = u.ux;
utrack[utpnt].y = u.uy;
utpnt++;
}
coord *
gettrack(x, y)
int x, y;
{
int i, cnt, dist;
coord tc;
cnt = utcnt;
for (i = utpnt - 1; cnt--; i--) {
if (i == -1)
i = UTSZ - 1;
tc = utrack[i];
dist = (x - tc.x) * (x - tc.x) + (y - tc.y) * (y - tc.y);
if (dist < 3)
return (dist ? &(utrack[i]) : 0);
}
return (0);
}

553
hack/hack.trap.c Normal file
View File

@@ -0,0 +1,553 @@
/* $NetBSD: hack.trap.c,v 1.6 2001/03/25 20:44:03 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 <hack@gnu.org>
* 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 <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: hack.trap.c,v 1.6 2001/03/25 20:44:03 jsm Exp $");
#endif /* not lint */
#include <stdlib.h>
#include "hack.h"
#include "extern.h"
#include "def.mkroom.h"
const char vowels[] = "aeiou";
const char *const traps[] = {
" bear trap",
"n arrow trap",
" dart trap",
" trapdoor",
" teleportation trap",
" pit",
" sleeping gas trap",
" piercer",
" mimic"
};
struct trap *
maketrap(x, y, typ)
int x, y, typ;
{
struct trap *ttmp;
ttmp = newtrap();
ttmp->ttyp = typ;
ttmp->tseen = 0;
ttmp->once = 0;
ttmp->tx = x;
ttmp->ty = y;
ttmp->ntrap = ftrap;
ftrap = ttmp;
return (ttmp);
}
void
dotrap(trap)
struct trap *trap;
{
int ttype = trap->ttyp;
nomul(0);
if (trap->tseen && !rn2(5) && ttype != PIT)
pline("You escape a%s.", traps[ttype]);
else {
trap->tseen = 1;
switch (ttype) {
case SLP_GAS_TRAP:
pline("A cloud of gas puts you to sleep!");
nomul(-rnd(25));
break;
case BEAR_TRAP:
if (Levitation) {
pline("You float over a bear trap.");
break;
}
u.utrap = 4 + rn2(4);
u.utraptype = TT_BEARTRAP;
pline("A bear trap closes on your foot!");
break;
case PIERC:
deltrap(trap);
if (makemon(PM_PIERCER, u.ux, u.uy)) {
pline("A piercer suddenly drops from the ceiling!");
if (uarmh)
pline("Its blow glances off your helmet.");
else
(void) thitu(3, d(4, 6), "falling piercer");
}
break;
case ARROW_TRAP:
pline("An arrow shoots out at you!");
if (!thitu(8, rnd(6), "arrow")) {
mksobj_at(ARROW, u.ux, u.uy);
fobj->quan = 1;
}
break;
case TRAPDOOR:
if (!xdnstair) {
pline("A trap door in the ceiling opens and a rock falls on your head!");
if (uarmh)
pline("Fortunately, you are wearing a helmet!");
losehp(uarmh ? 2 : d(2, 10), "falling rock");
mksobj_at(ROCK, u.ux, u.uy);
fobj->quan = 1;
stackobj(fobj);
if (Invisible)
newsym(u.ux, u.uy);
} else {
int newlevel = dlevel + 1;
while (!rn2(4) && newlevel < 29)
newlevel++;
pline("A trap door opens up under you!");
if (Levitation || u.ustuck) {
pline("For some reason you don't fall in.");
break;
}
goto_level(newlevel, FALSE);
}
break;
case DART_TRAP:
pline("A little dart shoots out at you!");
if (thitu(7, rnd(3), "little dart")) {
if (!rn2(6))
poisoned("dart", "poison dart");
} else {
mksobj_at(DART, u.ux, u.uy);
fobj->quan = 1;
}
break;
case TELEP_TRAP:
if (trap->once) {
deltrap(trap);
newsym(u.ux, u.uy);
vtele();
} else {
newsym(u.ux, u.uy);
tele();
}
break;
case PIT:
if (Levitation) {
pline("A pit opens up under you!");
pline("You don't fall in!");
break;
}
pline("You fall into a pit!");
u.utrap = rn1(6, 2);
u.utraptype = TT_PIT;
losehp(rnd(6), "fall into a pit");
selftouch("Falling, you");
break;
default:
impossible("You hit a trap of type %u", trap->ttyp);
}
}
}
int
mintrap(mtmp)
struct monst *mtmp;
{
struct trap *trap = t_at(mtmp->mx, mtmp->my);
int wasintrap = mtmp->mtrapped;
if (!trap) {
mtmp->mtrapped = 0; /* perhaps teleported? */
} else if (wasintrap) {
if (!rn2(40))
mtmp->mtrapped = 0;
} else {
int tt = trap->ttyp;
int in_sight = cansee(mtmp->mx, mtmp->my);
if (mtmp->mtrapseen & (1 << tt)) {
/* he has been in such a trap - perhaps he escapes */
if (rn2(4))
return (0);
}
mtmp->mtrapseen |= (1 << tt);
switch (tt) {
case BEAR_TRAP:
if (strchr(mlarge, mtmp->data->mlet)) {
if (in_sight)
pline("%s is caught in a bear trap!",
Monnam(mtmp));
else if (mtmp->data->mlet == 'o')
pline("You hear the roaring of an angry bear!");
mtmp->mtrapped = 1;
}
break;
case PIT:
/* there should be a mtmp/data -> floating */
if (!strchr("EywBfk'& ", mtmp->data->mlet)) { /* ab */
mtmp->mtrapped = 1;
if (in_sight)
pline("%s falls in a pit!", Monnam(mtmp));
}
break;
case SLP_GAS_TRAP:
if (!mtmp->msleep && !mtmp->mfroz) {
mtmp->msleep = 1;
if (in_sight)
pline("%s suddenly falls asleep!",
Monnam(mtmp));
}
break;
case TELEP_TRAP:
rloc(mtmp);
if (in_sight && !cansee(mtmp->mx, mtmp->my))
pline("%s suddenly disappears!",
Monnam(mtmp));
break;
case ARROW_TRAP:
if (in_sight) {
pline("%s is hit by an arrow!",
Monnam(mtmp));
}
mtmp->mhp -= 3;
break;
case DART_TRAP:
if (in_sight) {
pline("%s is hit by a dart!",
Monnam(mtmp));
}
mtmp->mhp -= 2;
/* not mondied here !! */
break;
case TRAPDOOR:
if (!xdnstair) {
mtmp->mhp -= 10;
if (in_sight)
pline("A trap door in the ceiling opens and a rock hits %s!", monnam(mtmp));
break;
}
if (mtmp->data->mlet != 'w') {
fall_down(mtmp);
if (in_sight)
pline("Suddenly, %s disappears out of sight.", monnam(mtmp));
return (2); /* no longer on this level */
}
break;
case PIERC:
break;
default:
impossible("Some monster encountered a strange trap.");
}
}
return (mtmp->mtrapped);
}
void
selftouch(arg)
const char *arg;
{
if (uwep && uwep->otyp == DEAD_COCKATRICE) {
pline("%s touch the dead cockatrice.", arg);
pline("You turn to stone.");
killer = objects[uwep->otyp].oc_name;
done("died");
}
}
void
float_up()
{
if (u.utrap) {
if (u.utraptype == TT_PIT) {
u.utrap = 0;
pline("You float up, out of the pit!");
} else {
pline("You float up, only your leg is still stuck.");
}
} else
pline("You start to float in the air!");
}
void
float_down()
{
struct trap *trap;
pline("You float gently to the ground.");
if ((trap = t_at(u.ux, u.uy)) != NULL)
switch (trap->ttyp) {
case PIERC:
break;
case TRAPDOOR:
if (!xdnstair || u.ustuck)
break;
/* fall into next case */
default:
dotrap(trap);
}
pickup(1);
}
void
vtele()
{
struct mkroom *croom;
for (croom = &rooms[0]; croom->hx >= 0; croom++)
if (croom->rtype == VAULT) {
int x, y;
x = rn2(2) ? croom->lx : croom->hx;
y = rn2(2) ? croom->ly : croom->hy;
if (teleok(x, y)) {
teleds(x, y);
return;
}
}
tele();
}
void
tele()
{
coord cc;
int nux, nuy;
if (Teleport_control) {
pline("To what position do you want to be teleported?");
cc = getpos(1, "the desired position"); /* 1: force valid */
/*
* possible extensions: introduce a small error if magic
* power is low; allow transfer to solid rock
*/
if (teleok(cc.x, cc.y)) {
teleds(cc.x, cc.y);
return;
}
pline("Sorry ...");
}
do {
nux = rnd(COLNO - 1);
nuy = rn2(ROWNO);
} while (!teleok(nux, nuy));
teleds(nux, nuy);
}
void
teleds(nux, nuy)
int nux, nuy;
{
if (Punished)
unplacebc();
unsee();
u.utrap = 0;
u.ustuck = 0;
u.ux = nux;
u.uy = nuy;
setsee();
if (Punished)
placebc(1);
if (u.uswallow) {
u.uswldtim = u.uswallow = 0;
docrt();
}
nomul(0);
if (levl[nux][nuy].typ == POOL && !Levitation)
drown();
(void) inshop();
pickup(1);
if (!Blind)
read_engr_at(u.ux, u.uy);
}
int
teleok(x, y)
int x, y;
{ /* might throw him into a POOL */
return (isok(x, y) && !IS_ROCK(levl[x][y].typ) && !m_at(x, y) &&
!sobj_at(ENORMOUS_ROCK, x, y) && !t_at(x, y)
);
/* Note: gold is permitted (because of vaults) */
}
int
dotele()
{
if (
#ifdef WIZARD
!wizard &&
#endif /* WIZARD */
(!Teleportation || u.ulevel < 6 ||
(pl_character[0] != 'W' && u.ulevel < 10))) {
pline("You are not able to teleport at will.");
return (0);
}
if (u.uhunger <= 100 || u.ustr < 6) {
pline("You miss the strength for a teleport spell.");
return (1);
}
tele();
morehungry(100);
return (1);
}
void
placebc(attach)
int attach;
{
if (!uchain || !uball) {
impossible("Where are your chain and ball??");
return;
}
uball->ox = uchain->ox = u.ux;
uball->oy = uchain->oy = u.uy;
if (attach) {
uchain->nobj = fobj;
fobj = uchain;
if (!carried(uball)) {
uball->nobj = fobj;
fobj = uball;
}
}
}
void
unplacebc()
{
if (!carried(uball)) {
freeobj(uball);
unpobj(uball);
}
freeobj(uchain);
unpobj(uchain);
}
void
level_tele()
{
int newlevel;
if (Teleport_control) {
char buf[BUFSZ];
do {
pline("To what level do you want to teleport? [type a number] ");
getlin(buf);
} while (!digit(buf[0]) && (buf[0] != '-' || !digit(buf[1])));
newlevel = atoi(buf);
} else {
newlevel = 5 + rn2(20); /* 5 - 24 */
if (dlevel == newlevel) {
if (!xdnstair)
newlevel--;
else
newlevel++;
}
}
if (newlevel >= 30) {
if (newlevel > MAXLEVEL)
newlevel = MAXLEVEL;
pline("You arrive at the center of the earth ...");
pline("Unfortunately it is here that hell is located.");
if (Fire_resistance) {
pline("But the fire doesn't seem to harm you.");
} else {
pline("You burn to a crisp.");
dlevel = maxdlevel = newlevel;
killer = "visit to the hell";
done("burned");
}
}
if (newlevel < 0) {
newlevel = 0;
pline("You are now high above the clouds ...");
if (Levitation) {
pline("You float gently down to earth.");
done("escaped");
}
pline("Unfortunately, you don't know how to fly.");
pline("You fall down a few thousand feet and break your neck.");
dlevel = 0;
killer = "fall";
done("died");
}
goto_level(newlevel, FALSE); /* calls done("escaped") if
* newlevel==0 */
}
void
drown()
{
pline("You fall into a pool!");
pline("You can't swim!");
if (rn2(3) < u.uluck + 2) {
/* most scrolls become unreadable */
struct obj *obj;
for (obj = invent; obj; obj = obj->nobj)
if (obj->olet == SCROLL_SYM && rn2(12) > u.uluck)
obj->otyp = SCR_BLANK_PAPER;
/* we should perhaps merge these scrolls ? */
pline("You attempt a teleport spell."); /* utcsri!carroll */
(void) dotele();
if (levl[u.ux][u.uy].typ != POOL)
return;
}
pline("You drown ...");
killer = "pool of water";
done("drowned");
}

391
hack/hack.tty.c Normal file
View File

@@ -0,0 +1,391 @@
/* $NetBSD: hack.tty.c,v 1.10 2002/05/26 00:12:12 wiz Exp $ */
/*-
* Copyright (c) 1988, 1993
* The Regents of the University of California. 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)hack.tty.c 8.1 (Berkeley) 5/31/93";
#else
__RCSID("$NetBSD: hack.tty.c,v 1.10 2002/05/26 00:12:12 wiz Exp $");
#endif
#endif /* not lint */
/*
* 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 <hack@gnu.org>
* 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.
*/
/* hack.tty.c - version 1.0.3 */
/*
* With thanks to the people who sent code for SYSV - hpscdi!jon,
* arnold@ucsf-cgl, wcs@bo95b, cbcephus!pds and others.
*/
#include <termios.h>
#include <termcap.h>
#include "hack.h"
#include "extern.h"
/*
* Some systems may have getchar() return EOF for various reasons, and
* we should not quit before seeing at least NR_OF_EOFS consecutive EOFs.
*/
#ifndef BSD
#define NR_OF_EOFS 20
#endif /* BSD */
static char erase_char, kill_char;
static boolean settty_needed = FALSE;
struct termios inittyb, curttyb;
/*
* Get initial state of terminal, set ospeed (for termcap routines)
* and switch off tab expansion if necessary.
* Called by startup() in termcap.c and after returning from ! or ^Z
*/
void
gettty()
{
if (tcgetattr(0, &inittyb) < 0)
perror("Hack (gettty)");
curttyb = inittyb;
ospeed = cfgetospeed(&inittyb);
erase_char = inittyb.c_cc[VERASE];
kill_char = inittyb.c_cc[VKILL];
getioctls();
/* do not expand tabs - they might be needed inside a cm sequence */
if (curttyb.c_oflag & OXTABS) {
curttyb.c_oflag &= ~OXTABS;
setctty();
}
settty_needed = TRUE;
}
/* reset terminal to original state */
void
settty(s)
const char *s;
{
clear_screen();
end_screen();
if (s)
printf("%s", s);
(void) fflush(stdout);
if (tcsetattr(0, TCSADRAIN, &inittyb) < 0)
perror("Hack (settty)");
flags.echo = (inittyb.c_lflag & ECHO) ? ON : OFF;
flags.cbreak = (inittyb.c_lflag & ICANON) ? OFF : ON;
setioctls();
}
void
setctty()
{
if (tcsetattr(0, TCSADRAIN, &curttyb) < 0)
perror("Hack (setctty)");
}
void
setftty()
{
int change = 0;
flags.cbreak = ON;
flags.echo = OFF;
/* Should use (ECHO|CRMOD) here instead of ECHO */
if (curttyb.c_lflag & ECHO) {
curttyb.c_lflag &= ~ECHO;
change++;
}
if (curttyb.c_lflag & ICANON) {
curttyb.c_lflag &= ~ICANON;
/* be satisfied with one character; no timeout */
curttyb.c_cc[VMIN] = 1;
curttyb.c_cc[VTIME] = 0;
change++;
}
if (change) {
setctty();
}
start_screen();
}
/* fatal error */
/* VARARGS1 */
void
error(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
if (settty_needed)
settty((char *) 0);
vprintf(fmt, ap);
va_end(ap);
putchar('\n');
exit(1);
}
/*
* Read a line closed with '\n' into the array char bufp[BUFSZ].
* (The '\n' is not stored. The string is closed with a '\0'.)
* Reading can be interrupted by an escape ('\033') - now the
* resulting string is "\033".
*/
void
getlin(bufp)
char *bufp;
{
char *obufp = bufp;
int c;
flags.toplin = 2; /* nonempty, no --More-- required */
for (;;) {
(void) fflush(stdout);
if ((c = getchar()) == EOF) {
*bufp = 0;
return;
}
if (c == '\033') {
*obufp = c;
obufp[1] = 0;
return;
}
if (c == erase_char || c == '\b') {
if (bufp != obufp) {
bufp--;
putstr("\b \b"); /* putsym converts \b */
} else
bell();
} else if (c == '\n') {
*bufp = 0;
return;
} else if (' ' <= c && c < '\177') {
/*
* avoid isprint() - some people don't have it ' ' is
* not always a printing char
*/
*bufp = c;
bufp[1] = 0;
putstr(bufp);
if (bufp - obufp < BUFSZ - 1 && bufp - obufp < COLNO)
bufp++;
} else if (c == kill_char || c == '\177') { /* Robert Viduya */
/* this test last - @ might be the kill_char */
while (bufp != obufp) {
bufp--;
putstr("\b \b");
}
} else
bell();
}
}
void
getret()
{
cgetret("");
}
void
cgetret(s)
const char *s;
{
putsym('\n');
if (flags.standout)
standoutbeg();
putstr("Hit ");
putstr(flags.cbreak ? "space" : "return");
putstr(" to continue: ");
if (flags.standout)
standoutend();
xwaitforspace(s);
}
char morc; /* tell the outside world what char he used */
void
xwaitforspace(s)
const char *s; /* chars allowed besides space or return */
{
int c;
morc = 0;
while ((c = readchar()) != '\n') {
if (flags.cbreak) {
if (c == ' ')
break;
if (s && strchr(s, c)) {
morc = c;
break;
}
bell();
}
}
}
char *
parse()
{
static char inputline[COLNO];
int foo;
flags.move = 1;
if (!Invisible)
curs_on_u();
else
home();
while ((foo = readchar()) >= '0' && foo <= '9')
multi = 10 * multi + foo - '0';
if (multi) {
multi--;
save_cm = inputline;
}
inputline[0] = foo;
inputline[1] = 0;
if (foo == 'f' || foo == 'F') {
inputline[1] = getchar();
#ifdef QUEST
if (inputline[1] == foo)
inputline[2] = getchar();
else
#endif /* QUEST */
inputline[2] = 0;
}
if (foo == 'm' || foo == 'M') {
inputline[1] = getchar();
inputline[2] = 0;
}
clrlin();
return (inputline);
}
char
readchar()
{
int sym;
(void) fflush(stdout);
if ((sym = getchar()) == EOF)
#ifdef NR_OF_EOFS
{ /*
* Some SYSV systems seem to return EOFs for various reasons
* (?like when one hits break or for interrupted systemcalls?),
* and we must see several before we quit.
*/
int cnt = NR_OF_EOFS;
while (cnt--) {
clearerr(stdin); /* omit if clearerr is
* undefined */
if ((sym = getchar()) != EOF)
goto noteof;
}
end_of_input();
noteof: ;
}
#else
end_of_input();
#endif /* NR_OF_EOFS */
if (flags.toplin == 1)
flags.toplin = 2;
return ((char) sym);
}
void
end_of_input()
{
settty("End of input?\n");
clearlocks();
exit(0);
}

447
hack/hack.u_init.c Normal file
View File

@@ -0,0 +1,447 @@
/* $NetBSD: hack.u_init.c,v 1.6 2001/03/25 20:44:03 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 <hack@gnu.org>
* 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 <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: hack.u_init.c,v 1.6 2001/03/25 20:44:03 jsm Exp $");
#endif /* not lint */
#include <ctype.h>
#include <signal.h>
#include <stdlib.h>
#include "hack.h"
#include "extern.h"
#define Strcpy (void) strcpy
#define Strcat (void) strcat
#define UNDEF_TYP 0
#define UNDEF_SPE '\177'
struct you zerou;
char pl_character[PL_CSIZ];
const char *(roles[]) = { /* must all have distinct first letter */
/* roles[4] may be changed to -woman */
"Tourist", "Speleologist", "Fighter", "Knight",
"Cave-man", "Wizard"
};
#define NR_OF_ROLES SIZE(roles)
char rolesyms[NR_OF_ROLES + 1]; /* filled by u_init() */
struct trobj {
uchar trotyp;
schar trspe;
char trolet;
Bitfield(trquan, 6);
Bitfield(trknown, 1);
};
#ifdef WIZARD
struct trobj Extra_objs[] = {
{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0}
};
#endif /* WIZARD */
struct trobj Cave_man[] = {
{MACE, 1, WEAPON_SYM, 1, 1},
{BOW, 1, WEAPON_SYM, 1, 1},
{ARROW, 0, WEAPON_SYM, 25, 1}, /* quan is variable */
{LEATHER_ARMOR, 0, ARMOR_SYM, 1, 1},
{0, 0, 0, 0, 0}
};
struct trobj Fighter[] = {
{TWO_HANDED_SWORD, 0, WEAPON_SYM, 1, 1},
{RING_MAIL, 0, ARMOR_SYM, 1, 1},
{0, 0, 0, 0, 0}
};
struct trobj Knight[] = {
{LONG_SWORD, 0, WEAPON_SYM, 1, 1},
{SPEAR, 2, WEAPON_SYM, 1, 1},
{RING_MAIL, 1, ARMOR_SYM, 1, 1},
{HELMET, 0, ARMOR_SYM, 1, 1},
{SHIELD, 0, ARMOR_SYM, 1, 1},
{PAIR_OF_GLOVES, 0, ARMOR_SYM, 1, 1},
{0, 0, 0, 0, 0}
};
struct trobj Speleologist[] = {
{STUDDED_LEATHER_ARMOR, 0, ARMOR_SYM, 1, 1},
{UNDEF_TYP, 0, POTION_SYM, 2, 0},
{FOOD_RATION, 0, FOOD_SYM, 3, 1},
{PICK_AXE, UNDEF_SPE, TOOL_SYM, 1, 0},
{ICE_BOX, 0, TOOL_SYM, 1, 0},
{0, 0, 0, 0, 0}
};
struct trobj Tinopener[] = {
{CAN_OPENER, 0, TOOL_SYM, 1, 1},
{0, 0, 0, 0, 0}
};
struct trobj Tourist[] = {
{UNDEF_TYP, 0, FOOD_SYM, 10, 1},
{POT_EXTRA_HEALING, 0, POTION_SYM, 2, 0},
{EXPENSIVE_CAMERA, 0, TOOL_SYM, 1, 1},
{DART, 2, WEAPON_SYM, 25, 1}, /* quan is variable */
{0, 0, 0, 0, 0}
};
struct trobj Wizard[] = {
{ELVEN_CLOAK, 0, ARMOR_SYM, 1, 1},
{UNDEF_TYP, UNDEF_SPE, WAND_SYM, 2, 0},
{UNDEF_TYP, UNDEF_SPE, RING_SYM, 2, 0},
{UNDEF_TYP, UNDEF_SPE, POTION_SYM, 2, 0},
{UNDEF_TYP, UNDEF_SPE, SCROLL_SYM, 3, 0},
{0, 0, 0, 0, 0}
};
void
u_init()
{
int i;
char exper = 'y', pc;
if (flags.female) /* should have been set in HACKOPTIONS */
roles[4] = "Cave-woman";
for (i = 0; i < NR_OF_ROLES; i++)
rolesyms[i] = roles[i][0];
rolesyms[i] = 0;
if ((pc = pl_character[0]) != '\0') {
if (islower(pc))
pc = toupper(pc);
if ((i = role_index(pc)) >= 0)
goto got_suffix; /* implies experienced */
printf("\nUnknown role: %c\n", pc);
pl_character[0] = pc = 0;
}
printf("\nAre you an experienced player? [ny] ");
while (!strchr("ynYN \n\004", (exper = readchar())))
bell();
if (exper == '\004') /* Give him an opportunity to get out */
end_of_input();
printf("%c\n", exper); /* echo */
if (strchr("Nn \n", exper)) {
exper = 0;
goto beginner;
}
printf("\nTell me what kind of character you are:\n");
printf("Are you");
for (i = 0; i < NR_OF_ROLES; i++) {
printf(" a %s", roles[i]);
if (i == 2) /* %% */
printf(",\n\t");
else if (i < NR_OF_ROLES - 2)
printf(",");
else if (i == NR_OF_ROLES - 2)
printf(" or");
}
printf("? [%s] ", rolesyms);
while ((pc = readchar()) != '\0') {
if (islower(pc))
pc = toupper(pc);
if ((i = role_index(pc)) >= 0) {
printf("%c\n", pc); /* echo */
(void) fflush(stdout); /* should be seen */
break;
}
if (pc == '\n')
break;
if (pc == '\004') /* Give him the opportunity to get
* out */
end_of_input();
bell();
}
if (pc == '\n')
pc = 0;
beginner:
if (!pc) {
printf("\nI'll choose a character for you.\n");
i = rn2(NR_OF_ROLES);
pc = rolesyms[i];
printf("This game you will be a%s %s.\n",
exper ? "n experienced" : "",
roles[i]);
getret();
/* give him some feedback in case mklev takes much time */
(void) putchar('\n');
(void) fflush(stdout);
}
#if 0
/*
* Given the above code, I can't see why this would ever change
* anything; it does core pretty well, though. - cmh 4/20/93
*/
if (exper) {
roles[i][0] = pc;
}
#endif
got_suffix:
(void) strncpy(pl_character, roles[i], PL_CSIZ - 1);
pl_character[PL_CSIZ - 1] = 0;
flags.beginner = 1;
u = zerou;
u.usym = '@';
u.ulevel = 1;
init_uhunger();
#ifdef QUEST
u.uhorizon = 6;
#endif /* QUEST */
uarm = uarm2 = uarmh = uarms = uarmg = uwep = uball = uchain =
uleft = uright = 0;
switch (pc) {
case 'c':
case 'C':
Cave_man[2].trquan = 12 + rnd(9) * rnd(9);
u.uhp = u.uhpmax = 16;
u.ustr = u.ustrmax = 18;
ini_inv(Cave_man);
break;
case 't':
case 'T':
Tourist[3].trquan = 20 + rnd(20);
u.ugold = u.ugold0 = rnd(1000);
u.uhp = u.uhpmax = 10;
u.ustr = u.ustrmax = 8;
ini_inv(Tourist);
if (!rn2(25))
ini_inv(Tinopener);
break;
case 'w':
case 'W':
for (i = 1; i <= 4; i++)
if (!rn2(5))
Wizard[i].trquan += rn2(3) - 1;
u.uhp = u.uhpmax = 15;
u.ustr = u.ustrmax = 16;
ini_inv(Wizard);
break;
case 's':
case 'S':
Fast = INTRINSIC;
Stealth = INTRINSIC;
u.uhp = u.uhpmax = 12;
u.ustr = u.ustrmax = 10;
ini_inv(Speleologist);
if (!rn2(10))
ini_inv(Tinopener);
break;
case 'k':
case 'K':
u.uhp = u.uhpmax = 12;
u.ustr = u.ustrmax = 10;
ini_inv(Knight);
break;
case 'f':
case 'F':
u.uhp = u.uhpmax = 14;
u.ustr = u.ustrmax = 17;
ini_inv(Fighter);
break;
default: /* impossible */
u.uhp = u.uhpmax = 12;
u.ustr = u.ustrmax = 16;
}
find_ac();
if (!rn2(20)) {
int d = rn2(7) - 2; /* biased variation */
u.ustr += d;
u.ustrmax += d;
}
#ifdef WIZARD
if (wizard)
wiz_inv();
#endif /* WIZARD */
/* make sure he can carry all he has - especially for T's */
while (inv_weight() > 0 && u.ustr < 118)
u.ustr++, u.ustrmax++;
}
void
ini_inv(trop)
struct trobj *trop;
{
struct obj *obj;
while (trop->trolet) {
obj = mkobj(trop->trolet);
obj->known = trop->trknown;
/* not obj->dknown = 1; - let him look at it at least once */
obj->cursed = 0;
if (obj->olet == WEAPON_SYM) {
obj->quan = trop->trquan;
trop->trquan = 1;
}
if (trop->trspe != UNDEF_SPE)
obj->spe = trop->trspe;
if (trop->trotyp != UNDEF_TYP)
obj->otyp = trop->trotyp;
else if (obj->otyp == WAN_WISHING) /* gitpyr!robert */
obj->otyp = WAN_DEATH;
obj->owt = weight(obj); /* defined after setting otyp+quan */
obj = addinv(obj);
if (obj->olet == ARMOR_SYM) {
switch (obj->otyp) {
case SHIELD:
if (!uarms)
setworn(obj, W_ARMS);
break;
case HELMET:
if (!uarmh)
setworn(obj, W_ARMH);
break;
case PAIR_OF_GLOVES:
if (!uarmg)
setworn(obj, W_ARMG);
break;
case ELVEN_CLOAK:
if (!uarm2)
setworn(obj, W_ARM);
break;
default:
if (!uarm)
setworn(obj, W_ARM);
}
}
if (obj->olet == WEAPON_SYM)
if (!uwep)
setuwep(obj);
#ifndef PYRAMID_BUG
if (--trop->trquan)
continue; /* make a similar object */
#else
if (trop->trquan) { /* check if zero first */
--trop->trquan;
if (trop->trquan)
continue; /* make a similar object */
}
#endif /* PYRAMID_BUG */
trop++;
}
}
#ifdef WIZARD
void
wiz_inv()
{
struct trobj *trop = &Extra_objs[0];
char *ep = getenv("INVENT");
int type;
while (ep && *ep) {
type = atoi(ep);
ep = strchr(ep, ',');
if (ep)
while (*ep == ',' || *ep == ' ')
ep++;
if (type <= 0 || type > NROFOBJECTS)
continue;
trop->trotyp = type;
trop->trolet = objects[type].oc_olet;
trop->trspe = 4;
trop->trknown = 1;
trop->trquan = 1;
ini_inv(trop);
}
/* give him a wand of wishing by default */
trop->trotyp = WAN_WISHING;
trop->trolet = WAND_SYM;
trop->trspe = 20;
trop->trknown = 1;
trop->trquan = 1;
ini_inv(trop);
}
#endif /* WIZARD */
void
plnamesuffix()
{
char *p;
if ((p = strrchr(plname, '-')) != NULL) {
*p = 0;
pl_character[0] = p[1];
pl_character[1] = 0;
if (!plname[0]) {
askname();
plnamesuffix();
}
}
}
int
role_index(pc)
char pc;
{ /* must be called only from u_init() */
/* so that rolesyms[] is defined */
char *cp;
if ((cp = strchr(rolesyms, pc)) != NULL)
return (cp - rolesyms);
return (-1);
}

533
hack/hack.unix.c Normal file
View File

@@ -0,0 +1,533 @@
/* $NetBSD: hack.unix.c,v 1.8 2001/03/25 20:44:03 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 <hack@gnu.org>
* 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 <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: hack.unix.c,v 1.8 2001/03/25 20:44:03 jsm Exp $");
#endif /* not lint */
/* This file collects some Unix dependencies; hack.pager.c contains some more */
/*
* The time is used for:
* - seed for random()
* - year on tombstone and yymmdd in record file
* - phase of the moon (various monsters react to NEW_MOON or FULL_MOON)
* - night and midnight (the undead are dangerous at midnight)
* - determination of what files are "very old"
*/
#include <errno.h>
#include <sys/types.h> /* for time_t and stat */
#include <sys/stat.h>
#ifdef BSD
#include <sys/time.h>
#else
#include <time.h>
#endif /* BSD */
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <fcntl.h>
#include "hack.h" /* mainly for strchr() which depends on BSD */
#include "extern.h"
extern int locknum;
void
setrandom()
{
(void) srandom((int) time((time_t *) 0));
}
struct tm *
getlt()
{
time_t date;
(void) time(&date);
return (localtime(&date));
}
int
getyear()
{
return (1900 + getlt()->tm_year);
}
char *
getdate()
{
static char datestr[7];
struct tm *lt = getlt();
(void) sprintf(datestr, "%02d%02d%02d",
lt->tm_year % 100, lt->tm_mon + 1, lt->tm_mday);
return (datestr);
}
int
phase_of_the_moon()
{ /* 0-7, with 0: new, 4: full *//* moon
* period: 29.5306 days */
/* year: 365.2422 days */
struct tm *lt = getlt();
int epact, diy, golden;
diy = lt->tm_yday;
golden = (lt->tm_year % 19) + 1;
epact = (11 * golden + 18) % 30;
if ((epact == 25 && golden > 11) || epact == 24)
epact++;
return ((((((diy + epact) * 6) + 11) % 177) / 22) & 7);
}
int
night()
{
int hour = getlt()->tm_hour;
return (hour < 6 || hour > 21);
}
int
midnight()
{
return (getlt()->tm_hour == 0);
}
struct stat buf, hbuf;
void
gethdate(name)
char *name;
{
#if 0
/* old version - for people short of space */
char *np;
if(stat(name, &hbuf))
error("Cannot get status of %s.",
(np = strrchr(name, '/')) ? np+1 : name);
#else
/* version using PATH from: seismo!gregc@ucsf-cgl.ARPA (Greg Couch) */
/*
* The problem with #include <sys/param.h> is that this include file
* does not exist on all systems, and moreover, that it sometimes includes
* <sys/types.h> again, so that the compiler sees these typedefs twice.
*/
#define MAXPATHLEN 1024
const char *np, *path;
char filename[MAXPATHLEN + 1];
if (strchr(name, '/') != NULL || (path = getenv("PATH")) == NULL)
path = "";
for (;;) {
if ((np = strchr(path, ':')) == NULL)
np = path + strlen(path); /* point to end str */
if (np - path <= 1) /* %% */
(void) strcpy(filename, name);
else {
(void) strncpy(filename, path, np - path);
filename[np - path] = '/';
(void) strcpy(filename + (np - path) + 1, name);
}
if (stat(filename, &hbuf) == 0)
return;
if (*np == '\0')
break;
path = np + 1;
}
error("Cannot get status of %s.",
(np = strrchr(name, '/')) ? np + 1 : name);
#endif
}
int
uptodate(int fd)
{
if (fstat(fd, &buf)) {
pline("Cannot get status of saved level? ");
return (0);
}
if (buf.st_mtime < hbuf.st_mtime) {
pline("Saved level is out of date. ");
return (0);
}
return (1);
}
/* see whether we should throw away this xlock file */
int
veryold(fd)
int fd;
{
int i;
time_t date;
if (fstat(fd, &buf))
return (0); /* cannot get status */
if (buf.st_size != sizeof(int))
return (0); /* not an xlock file */
(void) time(&date);
if (date - buf.st_mtime < 3L * 24L * 60L * 60L) { /* recent */
int lockedpid; /* should be the same size as
* hackpid */
if (read(fd, (char *) &lockedpid, sizeof(lockedpid)) !=
sizeof(lockedpid))
/* strange ... */
return (0);
/*
* From: Rick Adams <seismo!rick> This will work on
* 4.1cbsd, 4.2bsd and system 3? & 5. It will do nothing
* on V7 or 4.1bsd.
*/
if (!(kill(lockedpid, 0) == -1 && errno == ESRCH))
return (0);
}
(void) close(fd);
for (i = 1; i <= MAXLEVEL; i++) { /* try to remove all */
glo(i);
(void) unlink(lock);
}
glo(0);
if (unlink(lock))
return (0); /* cannot remove it */
return (1); /* success! */
}
void
getlock()
{
int i = 0, fd;
(void) fflush(stdout);
/* we ignore QUIT and INT at this point */
if (link(HLOCK, LLOCK) == -1) {
int errnosv = errno;
perror(HLOCK);
printf("Cannot link %s to %s\n", LLOCK, HLOCK);
switch (errnosv) {
case ENOENT:
printf("Perhaps there is no (empty) file %s ?\n", HLOCK);
break;
case EACCES:
printf("It seems you don't have write permission here.\n");
break;
case EEXIST:
printf("(Try again or rm %s.)\n", LLOCK);
break;
default:
printf("I don't know what is wrong.");
}
getret();
error("%s", "");
/* NOTREACHED */
}
regularize(lock);
glo(0);
if (locknum > 25)
locknum = 25;
do {
if (locknum)
lock[0] = 'a' + i++;
if ((fd = open(lock, O_RDONLY)) == -1) {
if (errno == ENOENT)
goto gotlock; /* no such file */
perror(lock);
(void) unlink(LLOCK);
error("Cannot open %s", lock);
}
if (veryold(fd))/* if true, this closes fd and unlinks lock */
goto gotlock;
(void) close(fd);
} while (i < locknum);
(void) unlink(LLOCK);
error(locknum ? "Too many hacks running now."
: "There is a game in progress under your name.");
gotlock:
fd = creat(lock, FMASK);
if (unlink(LLOCK) == -1)
error("Cannot unlink %s.", LLOCK);
if (fd == -1) {
error("cannot creat lock file.");
} else {
if (write(fd, (char *) &hackpid, sizeof(hackpid))
!= sizeof(hackpid)) {
error("cannot write lock");
}
if (close(fd) == -1) {
error("cannot close lock");
}
}
}
#ifdef MAIL
/*
* Notify user when new mail has arrived. [Idea from Merlyn Leroy, but
* I don't know the details of his implementation.]
* { Later note: he disliked my calling a general mailreader and felt that
* hack should do the paging itself. But when I get mail, I want to put it
* in some folder, reply, etc. - it would be unreasonable to put all these
* functions in hack. }
* The mail daemon '2' is at present not a real monster, but only a visual
* effect. Thus, makemon() is superfluous. This might become otherwise,
* however. The motion of '2' is less restrained than usual: diagonal moves
* from a DOOR are possible. He might also use SDOOR's. Also, '2' is visible
* in a ROOM, even when you are Blind.
* Its path should be longer when you are Telepat-hic and Blind.
*
* Interesting side effects:
* - You can get rich by sending yourself a lot of mail and selling
* it to the shopkeeper. Unfortunately mail isn't very valuable.
* - You might die in case '2' comes along at a critical moment during
* a fight and delivers a scroll the weight of which causes you to
* collapse.
*
* Possible extensions:
* - Open the file MAIL and do fstat instead of stat for efficiency.
* (But sh uses stat, so this cannot be too bad.)
* - Examine the mail and produce a scroll of mail called "From somebody".
* - Invoke MAILREADER in such a way that only this single letter is read.
*
* - Make him lose his mail when a Nymph steals the letter.
* - Do something to the text when the scroll is enchanted or cancelled.
*/
#include "def.mkroom.h"
static struct stat omstat, nmstat;
static char *mailbox;
static long laststattime;
void
getmailstatus()
{
if (!(mailbox = getenv("MAIL")))
return;
if (stat(mailbox, &omstat)) {
#ifdef PERMANENT_MAILBOX
pline("Cannot get status of MAIL=%s .", mailbox);
mailbox = 0;
#else
omstat.st_mtime = 0;
#endif /* PERMANENT_MAILBOX */
}
}
void
ckmailstatus()
{
if (!mailbox
#ifdef MAILCKFREQ
|| moves < laststattime + MAILCKFREQ
#endif /* MAILCKFREQ */
)
return;
laststattime = moves;
if (stat(mailbox, &nmstat)) {
#ifdef PERMANENT_MAILBOX
pline("Cannot get status of MAIL=%s anymore.", mailbox);
mailbox = 0;
#else
nmstat.st_mtime = 0;
#endif /* PERMANENT_MAILBOX */
} else if (nmstat.st_mtime > omstat.st_mtime) {
if (nmstat.st_size)
newmail();
getmailstatus();/* might be too late ... */
}
}
void
newmail()
{
/* produce a scroll of mail */
struct obj *obj;
struct monst *md;
obj = mksobj(SCR_MAIL);
if (md = makemon(&pm_mail_daemon, u.ux, u.uy)) /* always succeeds */
mdrush(md, 0);
pline("\"Hello, %s! I have some mail for you.\"", plname);
if (md) {
if (dist(md->mx, md->my) > 2)
pline("\"Catch!\"");
more();
/* let him disappear again */
mdrush(md, 1);
mondead(md);
}
obj = addinv(obj);
(void) identify(obj); /* set known and do prinv() */
}
/* make md run through the cave */
void
mdrush(md, away)
struct monst *md;
boolean away;
{
int uroom = inroom(u.ux, u.uy);
if (uroom >= 0) {
int tmp = rooms[uroom].fdoor;
int cnt = rooms[uroom].doorct;
int fx = u.ux, fy = u.uy;
while (cnt--) {
if (dist(fx, fy) < dist(doors[tmp].x, doors[tmp].y)) {
fx = doors[tmp].x;
fy = doors[tmp].y;
}
tmp++;
}
tmp_at(-1, md->data->mlet); /* open call */
if (away) { /* interchange origin and destination */
unpmon(md);
tmp = fx;
fx = md->mx;
md->mx = tmp;
tmp = fy;
fy = md->my;
md->my = tmp;
}
while (fx != md->mx || fy != md->my) {
int dx, dy, nfx = fx, nfy = fy, d1,
d2;
tmp_at(fx, fy);
d1 = DIST(fx, fy, md->mx, md->my);
for (dx = -1; dx <= 1; dx++)
for (dy = -1; dy <= 1; dy++)
if (dx || dy) {
d2 = DIST(fx + dx, fy + dy, md->mx, md->my);
if (d2 < d1) {
d1 = d2;
nfx = fx + dx;
nfy = fy + dy;
}
}
if (nfx != fx || nfy != fy) {
fx = nfx;
fy = nfy;
} else {
if (!away) {
md->mx = fx;
md->my = fy;
}
break;
}
}
tmp_at(-1, -1); /* close call */
}
if (!away)
pmon(md);
}
void
readmail()
{
#ifdef DEF_MAILREADER /* This implies that UNIX is defined */
char *mr = 0;
more();
if (!(mr = getenv("MAILREADER")))
mr = DEF_MAILREADER;
if (child(1)) {
execl(mr, mr, (char *) 0);
exit(1);
}
#else /* DEF_MAILREADER */
(void) page_file(mailbox, FALSE);
#endif /* DEF_MAILREADER */
/*
* get new stat; not entirely correct: there is a small time window
* where we do not see new mail
*/
getmailstatus();
}
#endif /* MAIL */
void
regularize(s) /* normalize file name - we don't like ..'s
* or /'s */
char *s;
{
char *lp;
while ((lp = strchr(s, '.')) || (lp = strchr(s, '/')))
*lp = '_';
}

377
hack/hack.vault.c Normal file
View File

@@ -0,0 +1,377 @@
/* $NetBSD: hack.vault.c,v 1.5 2001/03/25 20:44:03 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 <hack@gnu.org>
* 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 <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: hack.vault.c,v 1.5 2001/03/25 20:44:03 jsm Exp $");
#endif /* not lint */
#include "hack.h"
#include "extern.h"
#ifdef QUEST
void
setgd( /* mtmp */ )
{ /* struct monst *mtmp; */
}
int
gd_move() {
return (2);
}
void
gddead()
{
}
void
replgd(mtmp, mtmp2)
struct monst *mtmp, *mtmp2;
{
}
void
invault()
{
}
#else
#include "def.mkroom.h"
#define FCSIZ (ROWNO+COLNO)
struct fakecorridor {
xchar fx, fy, ftyp;
};
struct egd {
int fcbeg, fcend; /* fcend: first unused pos */
xchar gdx, gdy; /* goal of guard's walk */
unsigned gddone:1;
struct fakecorridor fakecorr[FCSIZ];
};
static const struct permonst pm_guard =
{"guard", '@', 12, 12, -1, 4, 10, sizeof(struct egd)};
static struct monst *guard;
static int gdlevel;
#define EGD ((struct egd *)(&(guard->mextra[0])))
static void restfakecorr __P((void));
static int goldincorridor __P((void));
static void
restfakecorr()
{
int fcx, fcy, fcbeg;
struct rm *crm;
while ((fcbeg = EGD->fcbeg) < EGD->fcend) {
fcx = EGD->fakecorr[fcbeg].fx;
fcy = EGD->fakecorr[fcbeg].fy;
if ((u.ux == fcx && u.uy == fcy) || cansee(fcx, fcy) ||
m_at(fcx, fcy))
return;
crm = &levl[fcx][fcy];
crm->typ = EGD->fakecorr[fcbeg].ftyp;
if (!crm->typ)
crm->seen = 0;
newsym(fcx, fcy);
EGD->fcbeg++;
}
/* it seems he left the corridor - let the guard disappear */
mondead(guard);
guard = 0;
}
static int
goldincorridor()
{
int fci;
for (fci = EGD->fcbeg; fci < EGD->fcend; fci++)
if (g_at(EGD->fakecorr[fci].fx, EGD->fakecorr[fci].fy))
return (1);
return (0);
}
void
setgd()
{
struct monst *mtmp;
for (mtmp = fmon; mtmp; mtmp = mtmp->nmon)
if (mtmp->isgd) {
guard = mtmp;
gdlevel = dlevel;
return;
}
guard = 0;
}
void
invault()
{
int tmp = inroom(u.ux, u.uy);
if (tmp < 0 || rooms[tmp].rtype != VAULT) {
u.uinvault = 0;
return;
}
if (++u.uinvault % 50 == 0 && (!guard || gdlevel != dlevel)) {
char buf[BUFSZ];
int x, y, dd, gx, gy;
/* first find the goal for the guard */
for (dd = 1; (dd < ROWNO || dd < COLNO); dd++) {
for (y = u.uy - dd; y <= u.uy + dd; y++) {
if (y < 0 || y > ROWNO - 1)
continue;
for (x = u.ux - dd; x <= u.ux + dd; x++) {
if (y != u.uy - dd && y != u.uy + dd && x != u.ux - dd)
x = u.ux + dd;
if (x < 0 || x > COLNO - 1)
continue;
if (levl[x][y].typ == CORR)
goto fnd;
}
}
}
impossible("Not a single corridor on this level??");
tele();
return;
fnd:
gx = x;
gy = y;
/* next find a good place for a door in the wall */
x = u.ux;
y = u.uy;
while (levl[x][y].typ == ROOM) {
int dx, dy;
dx = (gx > x) ? 1 : (gx < x) ? -1 : 0;
dy = (gy > y) ? 1 : (gy < y) ? -1 : 0;
if (abs(gx - x) >= abs(gy - y))
x += dx;
else
y += dy;
}
/* make something interesting happen */
if (!(guard = makemon(&pm_guard, x, y)))
return;
guard->isgd = guard->mpeaceful = 1;
EGD->gddone = 0;
gdlevel = dlevel;
if (!cansee(guard->mx, guard->my)) {
mondead(guard);
guard = 0;
return;
}
pline("Suddenly one of the Vault's guards enters!");
pmon(guard);
do {
pline("\"Hello stranger, who are you?\" - ");
getlin(buf);
} while (!letter(buf[0]));
if (!strcmp(buf, "Croesus") || !strcmp(buf, "Kroisos")) {
pline("\"Oh, yes - of course. Sorry to have disturbed you.\"");
mondead(guard);
guard = 0;
return;
}
clrlin();
pline("\"I don't know you.\"");
if (!u.ugold)
pline("\"Please follow me.\"");
else {
pline("\"Most likely all that gold was stolen from this vault.\"");
pline("\"Please drop your gold (say d$ ) and follow me.\"");
}
EGD->gdx = gx;
EGD->gdy = gy;
EGD->fcbeg = 0;
EGD->fakecorr[0].fx = x;
EGD->fakecorr[0].fy = y;
EGD->fakecorr[0].ftyp = levl[x][y].typ;
levl[x][y].typ = DOOR;
EGD->fcend = 1;
}
}
int
gd_move()
{
int x, y, dx, dy, gx, gy, nx, ny, typ;
struct fakecorridor *fcp;
struct rm *crm;
if (!guard || gdlevel != dlevel) {
impossible("Where is the guard?");
return (2); /* died */
}
if (u.ugold || goldincorridor())
return (0); /* didnt move */
if (dist(guard->mx, guard->my) > 1 || EGD->gddone) {
restfakecorr();
return (0); /* didnt move */
}
x = guard->mx;
y = guard->my;
/* look around (hor & vert only) for accessible places */
for (nx = x - 1; nx <= x + 1; nx++)
for (ny = y - 1; ny <= y + 1; ny++) {
if (nx == x || ny == y)
if (nx != x || ny != y)
if (isok(nx, ny))
if (!IS_WALL(typ = (crm = &levl[nx][ny])->typ) && typ != POOL) {
int i;
for (i = EGD->fcbeg; i < EGD->fcend; i++)
if (EGD->fakecorr[i].fx == nx &&
EGD->fakecorr[i].fy == ny)
goto nextnxy;
if ((i = inroom(nx, ny)) >= 0 && rooms[i].rtype == VAULT)
goto nextnxy;
/*
* seems we found a
* good place to
* leave him alone
*/
EGD->gddone = 1;
if (ACCESSIBLE(typ))
goto newpos;
crm->typ = (typ == SCORR) ? CORR : DOOR;
goto proceed;
}
nextnxy: ;
}
nx = x;
ny = y;
gx = EGD->gdx;
gy = EGD->gdy;
dx = (gx > x) ? 1 : (gx < x) ? -1 : 0;
dy = (gy > y) ? 1 : (gy < y) ? -1 : 0;
if (abs(gx - x) >= abs(gy - y))
nx += dx;
else
ny += dy;
while ((typ = (crm = &levl[nx][ny])->typ) != 0) {
/*
* in view of the above we must have IS_WALL(typ) or typ ==
* POOL
*/
/* must be a wall here */
if (isok(nx + nx - x, ny + ny - y) && typ != POOL &&
ZAP_POS(levl[nx + nx - x][ny + ny - y].typ)) {
crm->typ = DOOR;
goto proceed;
}
if (dy && nx != x) {
nx = x;
ny = y + dy;
continue;
}
if (dx && ny != y) {
ny = y;
nx = x + dx;
dy = 0;
continue;
}
/* I don't like this, but ... */
crm->typ = DOOR;
goto proceed;
}
crm->typ = CORR;
proceed:
if (cansee(nx, ny)) {
mnewsym(nx, ny);
prl(nx, ny);
}
fcp = &(EGD->fakecorr[EGD->fcend]);
if (EGD->fcend++ == FCSIZ)
panic("fakecorr overflow");
fcp->fx = nx;
fcp->fy = ny;
fcp->ftyp = typ;
newpos:
if (EGD->gddone)
nx = ny = 0;
guard->mx = nx;
guard->my = ny;
pmon(guard);
restfakecorr();
return (1);
}
void
gddead()
{
guard = 0;
}
void
replgd(mtmp, mtmp2)
struct monst *mtmp, *mtmp2;
{
if (mtmp == guard)
guard = mtmp2;
}
#endif /* QUEST */

84
hack/hack.version.c Normal file
View File

@@ -0,0 +1,84 @@
/* $NetBSD: hack.version.c,v 1.4 1997/10/19 16:59: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 <hack@gnu.org>
* 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 <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: hack.version.c,v 1.4 1997/10/19 16:59:25 christos Exp $");
#endif /* not lint */
#include "date.h"
#include "hack.h"
#include "extern.h"
int
doversion()
{
pline("%s 1.0.3 - last edit %s.", (
#ifdef QUEST
"Quest"
#else
"Hack"
#endif /* QUEST */
), datestring);
return (0);
}

173
hack/hack.wield.c Normal file
View File

@@ -0,0 +1,173 @@
/* $NetBSD: hack.wield.c,v 1.5 2001/03/25 20:44:03 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 <hack@gnu.org>
* 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 <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: hack.wield.c,v 1.5 2001/03/25 20:44:03 jsm Exp $");
#endif /* not lint */
#include "hack.h"
#include "extern.h"
void
setuwep(obj)
struct obj *obj;
{
setworn(obj, W_WEP);
}
int
dowield()
{
struct obj *wep;
int res = 0;
multi = 0;
if (!(wep = getobj("#-)", "wield"))) /* nothing */
;
else if (uwep == wep)
pline("You are already wielding that!");
else if (uwep && uwep->cursed)
pline("The %s welded to your hand!",
aobjnam(uwep, "are"));
else if (wep == &zeroobj) {
if (uwep == 0) {
pline("You are already empty handed.");
} else {
setuwep((struct obj *) 0);
res++;
pline("You are empty handed.");
}
} else if (uarms && wep->otyp == TWO_HANDED_SWORD)
pline("You cannot wield a two-handed sword and wear a shield.");
else if (wep->owornmask & (W_ARMOR | W_RING))
pline("You cannot wield that!");
else {
setuwep(wep);
res++;
if (uwep->cursed)
pline("The %s %s to your hand!",
aobjnam(uwep, "weld"),
(uwep->quan == 1) ? "itself" : "themselves"); /* a3 */
else
prinv(uwep);
}
return (res);
}
void
corrode_weapon()
{
if (!uwep || uwep->olet != WEAPON_SYM)
return; /* %% */
if (uwep->rustfree)
pline("Your %s not affected.", aobjnam(uwep, "are"));
else {
pline("Your %s!", aobjnam(uwep, "corrode"));
uwep->spe--;
}
}
int
chwepon(otmp, amount)
struct obj *otmp;
int amount;
{
const char *color = (amount < 0) ? "black" : "green";
const char *time;
if (!uwep || uwep->olet != WEAPON_SYM) {
strange_feeling(otmp,
(amount > 0) ? "Your hands twitch."
: "Your hands itch.");
return (0);
}
if (uwep->otyp == WORM_TOOTH && amount > 0) {
uwep->otyp = CRYSKNIFE;
pline("Your weapon seems sharper now.");
uwep->cursed = 0;
return (1);
}
if (uwep->otyp == CRYSKNIFE && amount < 0) {
uwep->otyp = WORM_TOOTH;
pline("Your weapon looks duller now.");
return (1);
}
/* there is a (soft) upper limit to uwep->spe */
if (amount > 0 && uwep->spe > 5 && rn2(3)) {
pline("Your %s violently green for a while and then evaporate%s.",
aobjnam(uwep, "glow"), plur(uwep->quan));
while (uwep) /* let all of them disappear */
/* note: uwep->quan = 1 is nogood if unpaid */
useup(uwep);
return (1);
}
if (!rn2(6))
amount *= 2;
time = (amount * amount == 1) ? "moment" : "while";
pline("Your %s %s for a %s.",
aobjnam(uwep, "glow"), color, time);
uwep->spe += amount;
if (amount > 0)
uwep->cursed = 0;
return (1);
}

280
hack/hack.wizard.c Normal file
View File

@@ -0,0 +1,280 @@
/* $NetBSD: hack.wizard.c,v 1.5 2001/03/25 20:44:04 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 <hack@gnu.org>
* 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 <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: hack.wizard.c,v 1.5 2001/03/25 20:44:04 jsm Exp $");
#endif /* not lint */
/* wizard code - inspired by rogue code from Merlyn Leroy (digi-g!brian) */
#include "hack.h"
#include "extern.h"
#define WIZSHOT 6 /* one chance in WIZSHOT that wizard will try
* magic */
#define BOLT_LIM 8 /* from this distance D and 1 will try to hit
* you */
const char wizapp[] = "@DNPTUVXcemntx";
/* If he has found the Amulet, make the wizard appear after some time */
void
amulet()
{
struct obj *otmp;
struct monst *mtmp;
if (!flags.made_amulet || !flags.no_of_wizards)
return;
/* find wizard, and wake him if necessary */
for (mtmp = fmon; mtmp; mtmp = mtmp->nmon)
if (mtmp->data->mlet == '1' && mtmp->msleep && !rn2(40))
for (otmp = invent; otmp; otmp = otmp->nobj)
if (otmp->olet == AMULET_SYM && !otmp->spe) {
mtmp->msleep = 0;
if (dist(mtmp->mx, mtmp->my) > 2)
pline(
"You get the creepy feeling that somebody noticed your taking the Amulet."
);
return;
}
}
int
wiz_hit(mtmp)
struct monst *mtmp;
{
/* if we have stolen or found the amulet, we disappear */
if (mtmp->minvent && mtmp->minvent->olet == AMULET_SYM &&
mtmp->minvent->spe == 0) {
/* vanish -- very primitive */
fall_down(mtmp);
return (1);
}
/* if it is lying around someplace, we teleport to it */
if (!carrying(AMULET_OF_YENDOR)) {
struct obj *otmp;
for (otmp = fobj; otmp; otmp = otmp->nobj)
if (otmp->olet == AMULET_SYM && !otmp->spe) {
if ((u.ux != otmp->ox || u.uy != otmp->oy) &&
!m_at(otmp->ox, otmp->oy)) {
/* teleport to it and pick it up */
mtmp->mx = otmp->ox;
mtmp->my = otmp->oy;
freeobj(otmp);
mpickobj(mtmp, otmp);
pmon(mtmp);
return (0);
}
goto hithim;
}
return (0); /* we don't know where it is */
}
hithim:
if (rn2(2)) { /* hit - perhaps steal */
/*
* if hit 1/20 chance of stealing amulet & vanish - amulet is
* on level 26 again.
*/
if (hitu(mtmp, d(mtmp->data->damn, mtmp->data->damd))
&& !rn2(20) && stealamulet(mtmp))
(void)0;
} else
inrange(mtmp); /* try magic */
return (0);
}
void
inrange(mtmp)
struct monst *mtmp;
{
schar tx, ty;
/* do nothing if cancelled (but make '1' say something) */
if (mtmp->data->mlet != '1' && mtmp->mcan)
return;
/* spit fire only when both in a room or both in a corridor */
if (inroom(u.ux, u.uy) != inroom(mtmp->mx, mtmp->my))
return;
tx = u.ux - mtmp->mx;
ty = u.uy - mtmp->my;
if ((!tx && abs(ty) < BOLT_LIM) || (!ty && abs(tx) < BOLT_LIM)
|| (abs(tx) == abs(ty) && abs(tx) < BOLT_LIM)) {
switch (mtmp->data->mlet) {
case 'D':
/* spit fire in the direction of @ (not nec. hitting) */
buzz(-1, mtmp->mx, mtmp->my, sgn(tx), sgn(ty));
break;
case '1':
if (rn2(WIZSHOT))
break;
/*
* if you zapped wizard with wand of cancellation, he
* has to shake off the effects before he can throw
* spells successfully. 1/2 the time they fail
* anyway
*/
if (mtmp->mcan || rn2(2)) {
if (canseemon(mtmp))
pline("%s makes a gesture, then curses.",
Monnam(mtmp));
else
pline("You hear mumbled cursing.");
if (!rn2(3)) {
mtmp->mspeed = 0;
mtmp->minvis = 0;
}
if (!rn2(3))
mtmp->mcan = 0;
} else {
if (canseemon(mtmp)) {
if (!rn2(6) && !Invis) {
pline("%s hypnotizes you.", Monnam(mtmp));
nomul(rn2(3) + 3);
break;
} else
pline("%s chants an incantation.",
Monnam(mtmp));
} else
pline("You hear a mumbled incantation.");
switch (rn2(Invis ? 5 : 6)) {
case 0:
/*
* create a nasty monster from a deep
* level
*/
/*
* (for the moment, 'nasty' is not
* implemented)
*/
(void) makemon((struct permonst *) 0, u.ux, u.uy);
break;
case 1:
pline("\"Destroy the thief, my pets!\"");
aggravate(); /* aggravate all the
* monsters */
/* fall into next case */
case 2:
if (flags.no_of_wizards == 1 && rnd(5) == 0)
/*
* if only 1 wizard, clone
* himself
*/
clonewiz(mtmp);
break;
case 3:
if (mtmp->mspeed == MSLOW)
mtmp->mspeed = 0;
else
mtmp->mspeed = MFAST;
break;
case 4:
mtmp->minvis = 1;
break;
case 5:
/* Only if not Invisible */
pline("You hear a clap of thunder!");
/*
* shoot a bolt of fire or cold, or a
* sleep ray
*/
buzz(-rnd(3), mtmp->mx, mtmp->my, sgn(tx), sgn(ty));
break;
}
}
}
if (u.uhp < 1)
done_in_by(mtmp);
}
}
void
aggravate()
{
struct monst *mtmp;
for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
mtmp->msleep = 0;
if (mtmp->mfroz && !rn2(5))
mtmp->mfroz = 0;
}
}
void
clonewiz(mtmp)
struct monst *mtmp;
{
struct monst *mtmp2;
if ((mtmp2 = makemon(PM_WIZARD, mtmp->mx, mtmp->my)) != NULL) {
flags.no_of_wizards = 2;
unpmon(mtmp2);
mtmp2->mappearance = wizapp[rn2(sizeof(wizapp) - 1)];
pmon(mtmp);
}
}

292
hack/hack.worm.c Normal file
View File

@@ -0,0 +1,292 @@
/* $NetBSD: hack.worm.c,v 1.4 1997/10/19 16:59:30 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 <hack@gnu.org>
* 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 <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: hack.worm.c,v 1.4 1997/10/19 16:59:30 christos Exp $");
#endif /* not lint */
#include <stdlib.h>
#include "hack.h"
#include "extern.h"
#ifndef NOWORM
#include "def.wseg.h"
struct wseg *wsegs[32]; /* linked list, tail first */
struct wseg *wheads[32];
long wgrowtime[32];
int
getwn(mtmp)
struct monst *mtmp;
{
int tmp;
for (tmp = 1; tmp < 32; tmp++)
if (!wsegs[tmp]) {
mtmp->wormno = tmp;
return (1);
}
return (0); /* level infested with worms */
}
/* called to initialize a worm unless cut in half */
void
initworm(mtmp)
struct monst *mtmp;
{
struct wseg *wtmp;
int tmp = mtmp->wormno;
if (!tmp)
return;
wheads[tmp] = wsegs[tmp] = wtmp = newseg();
wgrowtime[tmp] = 0;
wtmp->wx = mtmp->mx;
wtmp->wy = mtmp->my;
/* wtmp->wdispl = 0; */
wtmp->nseg = 0;
}
void
worm_move(mtmp)
struct monst *mtmp;
{
struct wseg *wtmp, *whd = NULL;
int tmp = mtmp->wormno;
wtmp = newseg();
wtmp->wx = mtmp->mx;
wtmp->wy = mtmp->my;
wtmp->nseg = 0;
/* wtmp->wdispl = 0; */
(whd = wheads[tmp])->nseg = wtmp;
wheads[tmp] = wtmp;
if (cansee(whd->wx, whd->wy)) {
unpmon(mtmp);
atl(whd->wx, whd->wy, '~');
whd->wdispl = 1;
} else
whd->wdispl = 0;
if (wgrowtime[tmp] <= moves) {
if (!wgrowtime[tmp])
wgrowtime[tmp] = moves + rnd(5);
else
wgrowtime[tmp] += 2 + rnd(15);
mtmp->mhpmax += 3;
mtmp->mhp += 3;
return;
}
whd = wsegs[tmp];
wsegs[tmp] = whd->nseg;
remseg(whd);
}
void
worm_nomove(mtmp)
struct monst *mtmp;
{
int tmp;
struct wseg *wtmp;
tmp = mtmp->wormno;
wtmp = wsegs[tmp];
if (wtmp == wheads[tmp])
return;
if (wtmp == 0 || wtmp->nseg == 0)
panic("worm_nomove?");
wsegs[tmp] = wtmp->nseg;
remseg(wtmp);
mtmp->mhp -= 3; /* mhpmax not changed ! */
}
void
wormdead(mtmp)
struct monst *mtmp;
{
int tmp = mtmp->wormno;
struct wseg *wtmp, *wtmp2;
if (!tmp)
return;
mtmp->wormno = 0;
for (wtmp = wsegs[tmp]; wtmp; wtmp = wtmp2) {
wtmp2 = wtmp->nseg;
remseg(wtmp);
}
wsegs[tmp] = 0;
}
void
wormhit(mtmp)
struct monst *mtmp;
{
int tmp = mtmp->wormno;
struct wseg *wtmp;
if (!tmp)
return; /* worm without tail */
for (wtmp = wsegs[tmp]; wtmp; wtmp = wtmp->nseg)
(void) hitu(mtmp, 1);
}
void
wormsee(tmp)
unsigned tmp;
{
struct wseg *wtmp = wsegs[tmp];
if (!wtmp)
panic("wormsee: wtmp==0");
for (; wtmp->nseg; wtmp = wtmp->nseg)
if (!cansee(wtmp->wx, wtmp->wy) && wtmp->wdispl) {
newsym(wtmp->wx, wtmp->wy);
wtmp->wdispl = 0;
}
}
void
pwseg(wtmp)
struct wseg *wtmp;
{
if (!wtmp->wdispl) {
atl(wtmp->wx, wtmp->wy, '~');
wtmp->wdispl = 1;
}
}
void
cutworm(mtmp, x, y, weptyp)
struct monst *mtmp;
xchar x, y;
uchar weptyp; /* uwep->otyp or 0 */
{
struct wseg *wtmp, *wtmp2;
struct monst *mtmp2;
int tmp, tmp2;
if (mtmp->mx == x && mtmp->my == y)
return; /* hit headon */
/* cutting goes best with axe or sword */
tmp = rnd(20);
if (weptyp == LONG_SWORD || weptyp == TWO_HANDED_SWORD ||
weptyp == AXE)
tmp += 5;
if (tmp < 12)
return;
/* if tail then worm just loses a tail segment */
tmp = mtmp->wormno;
wtmp = wsegs[tmp];
if (wtmp->wx == x && wtmp->wy == y) {
wsegs[tmp] = wtmp->nseg;
remseg(wtmp);
return;
}
/* cut the worm in two halves */
mtmp2 = newmonst(0);
*mtmp2 = *mtmp;
mtmp2->mxlth = mtmp2->mnamelth = 0;
/* sometimes the tail end dies */
if (rn2(3) || !getwn(mtmp2)) {
monfree(mtmp2);
tmp2 = 0;
} else {
tmp2 = mtmp2->wormno;
wsegs[tmp2] = wsegs[tmp];
wgrowtime[tmp2] = 0;
}
do {
if (wtmp->nseg->wx == x && wtmp->nseg->wy == y) {
if (tmp2)
wheads[tmp2] = wtmp;
wsegs[tmp] = wtmp->nseg->nseg;
remseg(wtmp->nseg);
wtmp->nseg = 0;
if (tmp2) {
pline("You cut the worm in half.");
mtmp2->mhpmax = mtmp2->mhp =
d(mtmp2->data->mlevel, 8);
mtmp2->mx = wtmp->wx;
mtmp2->my = wtmp->wy;
mtmp2->nmon = fmon;
fmon = mtmp2;
pmon(mtmp2);
} else {
pline("You cut off part of the worm's tail.");
remseg(wtmp);
}
mtmp->mhp /= 2;
return;
}
wtmp2 = wtmp->nseg;
if (!tmp2)
remseg(wtmp);
wtmp = wtmp2;
} while (wtmp->nseg);
panic("Cannot find worm segment");
}
void
remseg(wtmp)
struct wseg *wtmp;
{
if (wtmp->wdispl)
newsym(wtmp->wx, wtmp->wy);
free((char *) wtmp);
}
#endif /* NOWORM */

160
hack/hack.worn.c Normal file
View File

@@ -0,0 +1,160 @@
/* $NetBSD: hack.worn.c,v 1.4 1997/10/19 16:59:32 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 <hack@gnu.org>
* 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 <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: hack.worn.c,v 1.4 1997/10/19 16:59:32 christos Exp $");
#endif /* not lint */
#include "hack.h"
#include "extern.h"
struct worn {
long w_mask;
struct obj **w_obj;
} worn[] = {
{
W_ARM, &uarm
},
{
W_ARM2, &uarm2
},
{
W_ARMH, &uarmh
},
{
W_ARMS, &uarms
},
{
W_ARMG, &uarmg
},
{
W_RINGL, &uleft
},
{
W_RINGR, &uright
},
{
W_WEP, &uwep
},
{
W_BALL, &uball
},
{
W_CHAIN, &uchain
},
{
0, 0
}
};
void
setworn(obj, mask)
struct obj *obj;
long mask;
{
struct worn *wp;
struct obj *oobj;
for (wp = worn; wp->w_mask; wp++)
if (wp->w_mask & mask) {
oobj = *(wp->w_obj);
if (oobj && !(oobj->owornmask & wp->w_mask))
impossible("Setworn: mask = %ld.", wp->w_mask);
if (oobj)
oobj->owornmask &= ~wp->w_mask;
if (obj && oobj && wp->w_mask == W_ARM) {
if (uarm2) {
impossible("Setworn: uarm2 set?");
} else
setworn(uarm, W_ARM2);
}
*(wp->w_obj) = obj;
if (obj)
obj->owornmask |= wp->w_mask;
}
if (uarm2 && !uarm) {
uarm = uarm2;
uarm2 = 0;
uarm->owornmask ^= (W_ARM | W_ARM2);
}
}
/* called e.g. when obj is destroyed */
void
setnotworn(obj)
struct obj *obj;
{
struct worn *wp;
for (wp = worn; wp->w_mask; wp++)
if (obj == *(wp->w_obj)) {
*(wp->w_obj) = 0;
obj->owornmask &= ~wp->w_mask;
}
if (uarm2 && !uarm) {
uarm = uarm2;
uarm2 = 0;
uarm->owornmask ^= (W_ARM | W_ARM2);
}
}

761
hack/hack.zap.c Normal file
View File

@@ -0,0 +1,761 @@
/* $NetBSD: hack.zap.c,v 1.5 2001/03/25 20:44:04 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 <hack@gnu.org>
* 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 <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: hack.zap.c,v 1.5 2001/03/25 20:44:04 jsm Exp $");
#endif /* not lint */
#include "hack.h"
#include "extern.h"
const char *const fl[] = {
"magic missile",
"bolt of fire",
"sleep ray",
"bolt of cold",
"death ray"
};
/* Routines for IMMEDIATE wands. */
/* bhitm: monster mtmp was hit by the effect of wand otmp */
void
bhitm(mtmp, otmp)
struct monst *mtmp;
struct obj *otmp;
{
wakeup(mtmp);
switch (otmp->otyp) {
case WAN_STRIKING:
if (u.uswallow || rnd(20) < 10 + mtmp->data->ac) {
int tmp = d(2, 12);
hit("wand", mtmp, exclam(tmp));
mtmp->mhp -= tmp;
if (mtmp->mhp < 1)
killed(mtmp);
} else
miss("wand", mtmp);
break;
case WAN_SLOW_MONSTER:
mtmp->mspeed = MSLOW;
break;
case WAN_SPEED_MONSTER:
mtmp->mspeed = MFAST;
break;
case WAN_UNDEAD_TURNING:
if (strchr(UNDEAD, mtmp->data->mlet)) {
mtmp->mhp -= rnd(8);
if (mtmp->mhp < 1)
killed(mtmp);
else
mtmp->mflee = 1;
}
break;
case WAN_POLYMORPH:
if (newcham(mtmp, &mons[rn2(CMNUM)]))
objects[otmp->otyp].oc_name_known = 1;
break;
case WAN_CANCELLATION:
mtmp->mcan = 1;
break;
case WAN_TELEPORTATION:
rloc(mtmp);
break;
case WAN_MAKE_INVISIBLE:
mtmp->minvis = 1;
break;
#ifdef WAN_PROBING
case WAN_PROBING:
mstatusline(mtmp);
break;
#endif /* WAN_PROBING */
default:
impossible("What an interesting wand (%u)", otmp->otyp);
}
}
int
bhito(obj, otmp) /* object obj was hit by the effect of wand
* otmp */
struct obj *obj, *otmp; /* returns TRUE if sth was done */
{
int res = TRUE;
if (obj == uball || obj == uchain)
res = FALSE;
else
switch (otmp->otyp) {
case WAN_POLYMORPH:
/*
* preserve symbol and quantity, but turn rocks into
* gems
*/
mkobj_at((obj->otyp == ROCK || obj->otyp == ENORMOUS_ROCK)
? GEM_SYM : obj->olet,
obj->ox, obj->oy)->quan = obj->quan;
delobj(obj);
break;
case WAN_STRIKING:
if (obj->otyp == ENORMOUS_ROCK)
fracture_rock(obj);
else
res = FALSE;
break;
case WAN_CANCELLATION:
if (obj->spe && obj->olet != AMULET_SYM) {
obj->known = 0;
obj->spe = 0;
}
break;
case WAN_TELEPORTATION:
rloco(obj);
break;
case WAN_MAKE_INVISIBLE:
obj->oinvis = 1;
break;
case WAN_UNDEAD_TURNING:
res = revive(obj);
break;
case WAN_SLOW_MONSTER: /* no effect on objects */
case WAN_SPEED_MONSTER:
#ifdef WAN_PROBING
case WAN_PROBING:
#endif /* WAN_PROBING */
res = FALSE;
break;
default:
impossible("What an interesting wand (%u)", otmp->otyp);
}
return (res);
}
int
dozap()
{
struct obj *obj;
xchar zx, zy;
obj = getobj("/", "zap");
if (!obj)
return (0);
if (obj->spe < 0 || (obj->spe == 0 && rn2(121))) {
pline("Nothing Happens.");
return (1);
}
if (obj->spe == 0)
pline("You wrest one more spell from the worn-out wand.");
if (!(objects[obj->otyp].bits & NODIR) && !getdir(1))
return (1); /* make him pay for knowing !NODIR */
obj->spe--;
if (objects[obj->otyp].bits & IMMEDIATE) {
if (u.uswallow)
bhitm(u.ustuck, obj);
else if (u.dz) {
if (u.dz > 0) {
struct obj *otmp = o_at(u.ux, u.uy);
if (otmp)
(void) bhito(otmp, obj);
}
} else
(void) bhit(u.dx, u.dy, rn1(8, 6), 0, bhitm, bhito, obj);
} else {
switch (obj->otyp) {
case WAN_LIGHT:
litroom(TRUE);
break;
case WAN_SECRET_DOOR_DETECTION:
if (!findit())
return (1);
break;
case WAN_CREATE_MONSTER:
{
int cnt = 1;
if (!rn2(23))
cnt += rn2(7) + 1;
while (cnt--)
(void) makemon((struct permonst *) 0, u.ux, u.uy);
}
break;
case WAN_WISHING:
{
char buf[BUFSZ];
struct obj *otmp;
if (u.uluck + rn2(5) < 0) {
pline("Unfortunately, nothing happens.");
break;
}
pline("You may wish for an object. What do you want? ");
getlin(buf);
if (buf[0] == '\033')
buf[0] = 0;
otmp = readobjnam(buf);
otmp = addinv(otmp);
prinv(otmp);
break;
}
case WAN_DIGGING:
/*
* Original effect (approximately): from CORR: dig
* until we pierce a wall from ROOM: piece wall and
* dig until we reach an ACCESSIBLE place. Currently:
* dig for digdepth positions; also down on request
* of Lennart Augustsson.
*/
{
struct rm *room;
int digdepth;
if (u.uswallow) {
struct monst *mtmp = u.ustuck;
pline("You pierce %s's stomach wall!",
monnam(mtmp));
mtmp->mhp = 1; /* almost dead */
unstuck(mtmp);
mnexto(mtmp);
break;
}
if (u.dz) {
if (u.dz < 0) {
pline("You loosen a rock from the ceiling.");
pline("It falls on your head!");
losehp(1, "falling rock");
mksobj_at(ROCK, u.ux, u.uy);
fobj->quan = 1;
stackobj(fobj);
if (Invisible)
newsym(u.ux, u.uy);
} else {
dighole();
}
break;
}
zx = u.ux + u.dx;
zy = u.uy + u.dy;
digdepth = 8 + rn2(18);
Tmp_at(-1, '*'); /* open call */
while (--digdepth >= 0) {
if (!isok(zx, zy))
break;
room = &levl[zx][zy];
Tmp_at(zx, zy);
if (!xdnstair) {
if (zx < 3 || zx > COLNO - 3 ||
zy < 3 || zy > ROWNO - 3)
break;
if (room->typ == HWALL ||
room->typ == VWALL) {
room->typ = ROOM;
break;
}
} else if (room->typ == HWALL || room->typ == VWALL ||
room->typ == SDOOR || room->typ == LDOOR) {
room->typ = DOOR;
digdepth -= 2;
} else if (room->typ == SCORR || !room->typ) {
room->typ = CORR;
digdepth--;
}
mnewsym(zx, zy);
zx += u.dx;
zy += u.dy;
}
mnewsym(zx, zy); /* not always necessary */
Tmp_at(-1, -1); /* closing call */
break;
}
default:
buzz((int) obj->otyp - WAN_MAGIC_MISSILE,
u.ux, u.uy, u.dx, u.dy);
break;
}
if (!objects[obj->otyp].oc_name_known) {
objects[obj->otyp].oc_name_known = 1;
more_experienced(0, 10);
}
}
return (1);
}
const char *
exclam(force)
int force;
{
/* force == 0 occurs e.g. with sleep ray */
/*
* note that large force is usual with wands so that !! would require
* information about hand/weapon/wand
*/
return ((force < 0) ? "?" : (force <= 4) ? "." : "!");
}
void
hit(str, mtmp, force)
const char *str;
struct monst *mtmp;
const char *force; /* usually either "." or "!" */
{
if (!cansee(mtmp->mx, mtmp->my))
pline("The %s hits it.", str);
else
pline("The %s hits %s%s", str, monnam(mtmp), force);
}
void
miss(str, mtmp)
const char *str;
struct monst *mtmp;
{
if (!cansee(mtmp->mx, mtmp->my))
pline("The %s misses it.", str);
else
pline("The %s misses %s.", str, monnam(mtmp));
}
/*
* bhit: called when a weapon is thrown (sym = obj->olet) or when an
* IMMEDIATE wand is zapped (sym = 0); the weapon falls down at end of range
* or when a monster is hit; the monster is returned, and bhitpos is set to
* the final position of the weapon thrown; the ray of a wand may affect
* several objects and monsters on its path - for each of these an argument
* function is called.
*/
/* check !u.uswallow before calling bhit() */
struct monst *
bhit(ddx, ddy, range, sym, fhitm, fhito, obj)
int ddx, ddy, range; /* direction and range */
char sym; /* symbol displayed on path */
/* fns called when mon/obj hit */
void (*fhitm) __P((struct monst *, struct obj *));
int (*fhito) __P((struct obj *, struct obj *));
struct obj *obj; /* 2nd arg to fhitm/fhito */
{
struct monst *mtmp;
struct obj *otmp;
int typ;
bhitpos.x = u.ux;
bhitpos.y = u.uy;
if (sym)
tmp_at(-1, sym);/* open call */
while (range-- > 0) {
bhitpos.x += ddx;
bhitpos.y += ddy;
typ = levl[bhitpos.x][bhitpos.y].typ;
if ((mtmp = m_at(bhitpos.x, bhitpos.y)) != NULL) {
if (sym) {
tmp_at(-1, -1); /* close call */
return (mtmp);
}
(*fhitm) (mtmp, obj);
range -= 3;
}
if (fhito && (otmp = o_at(bhitpos.x, bhitpos.y))) {
if ((*fhito) (otmp, obj))
range--;
}
if (!ZAP_POS(typ)) {
bhitpos.x -= ddx;
bhitpos.y -= ddy;
break;
}
if (sym)
tmp_at(bhitpos.x, bhitpos.y);
}
/* leave last symbol unless in a pool */
if (sym)
tmp_at(-1, (levl[bhitpos.x][bhitpos.y].typ == POOL) ? -1 : 0);
return (0);
}
struct monst *
boomhit(int dx, int dy)
{
int i, ct;
struct monst *mtmp;
char sym = ')';
bhitpos.x = u.ux;
bhitpos.y = u.uy;
for (i = 0; i < 8; i++)
if (xdir[i] == dx && ydir[i] == dy)
break;
tmp_at(-1, sym); /* open call */
for (ct = 0; ct < 10; ct++) {
if (i == 8)
i = 0;
sym = ')' + '(' - sym;
tmp_at(-2, sym);/* change let call */
dx = xdir[i];
dy = ydir[i];
bhitpos.x += dx;
bhitpos.y += dy;
if ((mtmp = m_at(bhitpos.x, bhitpos.y)) != NULL) {
tmp_at(-1, -1);
return (mtmp);
}
if (!ZAP_POS(levl[bhitpos.x][bhitpos.y].typ)) {
bhitpos.x -= dx;
bhitpos.y -= dy;
break;
}
if (bhitpos.x == u.ux && bhitpos.y == u.uy) { /* ct == 9 */
if (rn2(20) >= 10 + u.ulevel) { /* we hit ourselves */
(void) thitu(10, rnd(10), "boomerang");
break;
} else {/* we catch it */
tmp_at(-1, -1);
pline("Skillfully, you catch the boomerang.");
return (&youmonst);
}
}
tmp_at(bhitpos.x, bhitpos.y);
if (ct % 5 != 0)
i++;
}
tmp_at(-1, -1); /* do not leave last symbol */
return (0);
}
char
dirlet(dx, dy)
int dx, dy;
{
return
(dx == dy) ? '\\' : (dx && dy) ? '/' : dx ? '-' : '|';
}
/* type == -1: monster spitting fire at you */
/* type == -1,-2,-3: bolts sent out by wizard */
/* called with dx = dy = 0 with vertical bolts */
void
buzz(type, sx, sy, dx, dy)
int type;
xchar sx, sy;
int dx, dy;
{
int abstype = abs(type);
const char *fltxt = (type == -1) ? "blaze of fire" : fl[abstype];
struct rm *lev;
xchar range;
struct monst *mon;
if (u.uswallow) {
int tmp;
if (type < 0)
return;
tmp = zhit(u.ustuck, type);
pline("The %s rips into %s%s",
fltxt, monnam(u.ustuck), exclam(tmp));
return;
}
if (type < 0)
pru();
range = rn1(7, 7);
Tmp_at(-1, dirlet(dx, dy)); /* open call */
while (range-- > 0) {
sx += dx;
sy += dy;
if ((lev = &levl[sx][sy])->typ)
Tmp_at(sx, sy);
else {
int bounce = 0;
if (cansee(sx - dx, sy - dy))
pline("The %s bounces!", fltxt);
if (ZAP_POS(levl[sx][sy - dy].typ))
bounce = 1;
if (ZAP_POS(levl[sx - dx][sy].typ)) {
if (!bounce || rn2(2))
bounce = 2;
}
switch (bounce) {
case 0:
dx = -dx;
dy = -dy;
continue;
case 1:
dy = -dy;
sx -= dx;
break;
case 2:
dx = -dx;
sy -= dy;
break;
}
Tmp_at(-2, dirlet(dx, dy));
continue;
}
if (lev->typ == POOL && abstype == 1 /* fire */ ) {
range -= 3;
lev->typ = ROOM;
if (cansee(sx, sy)) {
mnewsym(sx, sy);
pline("The water evaporates.");
} else
pline("You hear a hissing sound.");
}
if ((mon = m_at(sx, sy)) &&
(type != -1 || mon->data->mlet != 'D')) {
wakeup(mon);
if (rnd(20) < 18 + mon->data->ac) {
int tmp = zhit(mon, abstype);
if (mon->mhp < 1) {
if (type < 0) {
if (cansee(mon->mx, mon->my))
pline("%s is killed by the %s!",
Monnam(mon), fltxt);
mondied(mon);
} else
killed(mon);
} else
hit(fltxt, mon, exclam(tmp));
range -= 2;
} else
miss(fltxt, mon);
} else if (sx == u.ux && sy == u.uy) {
nomul(0);
if (rnd(20) < 18 + u.uac) {
int dam = 0;
range -= 2;
pline("The %s hits you!", fltxt);
switch (abstype) {
case 0:
dam = d(2, 6);
break;
case 1:
if (Fire_resistance)
pline("You don't feel hot!");
else
dam = d(6, 6);
if (!rn2(3))
burn_scrolls();
break;
case 2:
nomul(-rnd(25)); /* sleep ray */
break;
case 3:
if (Cold_resistance)
pline("You don't feel cold!");
else
dam = d(6, 6);
break;
case 4:
u.uhp = -1;
}
losehp(dam, fltxt);
} else
pline("The %s whizzes by you!", fltxt);
stop_occupation();
}
if (!ZAP_POS(lev->typ)) {
int bounce = 0, rmn;
if (cansee(sx, sy))
pline("The %s bounces!", fltxt);
range--;
if (!dx || !dy || !rn2(20)) {
dx = -dx;
dy = -dy;
} else {
if (ZAP_POS(rmn = levl[sx][sy - dy].typ) &&
(IS_ROOM(rmn) || ZAP_POS(levl[sx + dx][sy - dy].typ)))
bounce = 1;
if (ZAP_POS(rmn = levl[sx - dx][sy].typ) &&
(IS_ROOM(rmn) || ZAP_POS(levl[sx - dx][sy + dy].typ)))
if (!bounce || rn2(2))
bounce = 2;
switch (bounce) {
case 0:
dy = -dy;
dx = -dx;
break;
case 1:
dy = -dy;
break;
case 2:
dx = -dx;
break;
}
Tmp_at(-2, dirlet(dx, dy));
}
}
}
Tmp_at(-1, -1);
}
int
zhit(mon, type) /* returns damage to mon */
struct monst *mon;
int type;
{
int tmp = 0;
switch (type) {
case 0: /* magic missile */
tmp = d(2, 6);
break;
case -1: /* Dragon blazing fire */
case 1: /* fire */
if (strchr("Dg", mon->data->mlet))
break;
tmp = d(6, 6);
if (strchr("YF", mon->data->mlet))
tmp += 7;
break;
case 2: /* sleep */
mon->mfroz = 1;
break;
case 3: /* cold */
if (strchr("YFgf", mon->data->mlet))
break;
tmp = d(6, 6);
if (mon->data->mlet == 'D')
tmp += 7;
break;
case 4: /* death */
if (strchr(UNDEAD, mon->data->mlet))
break;
tmp = mon->mhp + 1;
break;
}
mon->mhp -= tmp;
return (tmp);
}
#define CORPSE_I_TO_C(otyp) (char) ((otyp >= DEAD_ACID_BLOB)\
? 'a' + (otyp - DEAD_ACID_BLOB)\
: '@' + (otyp - DEAD_HUMAN))
int
revive(obj)
struct obj *obj;
{
struct monst *mtmp = NULL;
if (obj->olet == FOOD_SYM && obj->otyp > CORPSE) {
/* do not (yet) revive shopkeepers */
/*
* Note: this might conceivably produce two monsters at the
* same position - strange, but harmless
*/
mtmp = mkmon_at(CORPSE_I_TO_C(obj->otyp), obj->ox, obj->oy);
delobj(obj);
}
return (!!mtmp); /* TRUE if some monster created */
}
void
rloco(obj)
struct obj *obj;
{
int tx, ty, otx, oty;
otx = obj->ox;
oty = obj->oy;
do {
tx = rn1(COLNO - 3, 2);
ty = rn2(ROWNO);
} while (!goodpos(tx, ty));
obj->ox = tx;
obj->oy = ty;
if (cansee(otx, oty))
newsym(otx, oty);
}
void
fracture_rock(obj) /* fractured by pick-axe or wand of striking */
struct obj *obj; /* no texts here! */
{
/* unpobj(obj); */
obj->otyp = ROCK;
obj->quan = 7 + rn2(60);
obj->owt = weight(obj);
obj->olet = WEAPON_SYM;
if (cansee(obj->ox, obj->oy))
prl(obj->ox, obj->oy);
}
void
burn_scrolls()
{
struct obj *obj, *obj2;
int cnt = 0;
for (obj = invent; obj; obj = obj2) {
obj2 = obj->nobj;
if (obj->olet == SCROLL_SYM) {
cnt++;
useup(obj);
}
}
if (cnt > 1) {
pline("Your scrolls catch fire!");
losehp(cnt, "burning scrolls");
} else if (cnt) {
pline("Your scroll catches fire!");
losehp(1, "burning scroll");
}
}

338
hack/makedefs.c Normal file
View File

@@ -0,0 +1,338 @@
/* $NetBSD: makedefs.c,v 1.7 2001/03/25 20:44:04 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 <hack@gnu.org>
* 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 lint
static const char rcsid[] __attribute__((__unused__)) =
"$NetBSD: makedefs.c,v 1.7 2001/03/25 20:44:04 jsm Exp $";
#endif /* not lint */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
/* construct definitions of object constants */
#define LINSZ 1000
#define STRSZ 40
int fd;
char string[STRSZ];
static void readline(void);
static char nextchar(void);
static int skipuntil(const char *);
static int getentry(void);
static void capitalize(char *);
static int letter(int);
static int digit(int);
int main(int, char **);
int
main(argc, argv)
int argc;
char **argv;
{
int i = 0;
int propct = 0;
char *sp;
if (argc != 2) {
(void) fprintf(stderr, "usage: makedefs file\n");
exit(1);
}
if ((fd = open(argv[1], O_RDONLY)) < 0) {
perror(argv[1]);
exit(1);
}
skipuntil("objects[] = {");
while (getentry()) {
if (!*string) {
i++;
continue;
}
for (sp = string; *sp; sp++)
if (*sp == ' ' || *sp == '\t' || *sp == '-')
*sp = '_';
if (!strncmp(string, "RIN_", 4)) {
capitalize(string + 4);
printf("#define %s u.uprops[%d].p_flgs\n",
string + 4, propct++);
}
for (sp = string; *sp; sp++)
capitalize(sp);
/* avoid trouble with stupid C preprocessors */
if (!strncmp(string, "WORTHLESS_PIECE_OF_", 19))
printf("/* #define %s %d */\n", string, i);
else
printf("#define %s %d\n", string, i);
i++;
}
printf("\n#define CORPSE DEAD_HUMAN\n");
printf("#define LAST_GEM (JADE+1)\n");
printf("#define LAST_RING %d\n", propct);
printf("#define NROFOBJECTS %d\n", i - 1);
fflush(stdout);
if (ferror(stdout)) {
perror("standard output");
exit(1);
}
exit(0);
}
char line[LINSZ], *lp = line, *lp0 = line, *lpe = line;
int eof;
static void
readline()
{
int n = read(fd, lp0, (line + LINSZ) - lp0);
if (n < 0) {
printf("Input error.\n");
exit(1);
}
if (n == 0)
eof++;
lpe = lp0 + n;
}
static char
nextchar()
{
if (lp == lpe) {
readline();
lp = lp0;
}
return ((lp == lpe) ? 0 : *lp++);
}
static int
skipuntil(s)
const char *s;
{
const char *sp0;
char *sp1;
loop:
while (*s != nextchar())
if (eof) {
printf("Cannot skipuntil %s\n", s);
exit(1);
}
if ((int)strlen(s) > lpe - lp + 1) {
char *lp1, *lp2;
lp2 = lp;
lp1 = lp = lp0;
while (lp2 != lpe)
*lp1++ = *lp2++;
lp2 = lp0; /* save value */
lp0 = lp1;
readline();
lp0 = lp2;
if ((int)strlen(s) > lpe - lp + 1) {
printf("error in skipuntil");
exit(1);
}
}
sp0 = s + 1;
sp1 = lp;
while (*sp0 && *sp0 == *sp1)
sp0++, sp1++;
if (!*sp0) {
lp = sp1;
return (1);
}
goto loop;
}
static int
getentry()
{
int inbraces = 0, inparens = 0, stringseen = 0, commaseen = 0;
int prefix = 0;
char ch;
#define NSZ 10
char identif[NSZ], *ip;
string[0] = string[4] = 0;
/*
* read until {...} or XXX(...) followed by , skip comment and
* #define lines deliver 0 on failure
*/
while (1) {
ch = nextchar();
swi:
if (letter(ch)) {
ip = identif;
do {
if (ip < identif + NSZ - 1)
*ip++ = ch;
ch = nextchar();
} while (letter(ch) || digit(ch));
*ip = 0;
while (ch == ' ' || ch == '\t')
ch = nextchar();
if (ch == '(' && !inparens && !stringseen)
if (!strcmp(identif, "WAND") ||
!strcmp(identif, "RING") ||
!strcmp(identif, "POTION") ||
!strcmp(identif, "SCROLL"))
(void) strncpy(string, identif, 3),
string[3] = '_',
prefix = 4;
}
switch (ch) {
case '/':
/* watch for comment */
if ((ch = nextchar()) == '*')
skipuntil("*/");
goto swi;
case '{':
inbraces++;
continue;
case '(':
inparens++;
continue;
case '}':
inbraces--;
if (inbraces < 0)
return (0);
continue;
case ')':
inparens--;
if (inparens < 0) {
printf("too many ) ?");
exit(1);
}
continue;
case '\n':
/* watch for #define at begin of line */
if ((ch = nextchar()) == '#') {
char pch;
/* skip until '\n' not preceded by '\\' */
do {
pch = ch;
ch = nextchar();
} while (ch != '\n' || pch == '\\');
continue;
}
goto swi;
case ',':
if (!inparens && !inbraces) {
if (prefix && !string[prefix])
string[0] = 0;
if (stringseen)
return (1);
printf("unexpected ,\n");
exit(1);
}
commaseen++;
continue;
case '\'':
if ((ch = nextchar()) == '\\')
ch = nextchar();
if (nextchar() != '\'') {
printf("strange character denotation?\n");
exit(1);
}
continue;
case '"':
{
char *sp = string + prefix;
char pch;
int store = (inbraces || inparens)
&& !stringseen++ && !commaseen;
do {
pch = ch;
ch = nextchar();
if (store && sp < string + STRSZ)
*sp++ = ch;
} while (ch != '"' || pch == '\\');
if (store)
*--sp = 0;
continue;
}
}
}
}
static void
capitalize(sp)
char *sp;
{
if ('a' <= *sp && *sp <= 'z')
*sp += 'A' - 'a';
}
static int
letter(ch)
char ch;
{
return (('a' <= ch && ch <= 'z') ||
('A' <= ch && ch <= 'Z'));
}
static int
digit(ch)
char ch;
{
return ('0' <= ch && ch <= '9');
}

105
hack/rnd.c Normal file
View File

@@ -0,0 +1,105 @@
/* $NetBSD: rnd.c,v 1.4 1997/10/19 16:59:39 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 <hack@gnu.org>
* 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 <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: rnd.c,v 1.4 1997/10/19 16:59:39 christos Exp $");
#endif /* not lint */
#include <stdlib.h>
#include "hack.h"
#include "extern.h"
#define RND(x) ((random()>>3) % x)
int
rn1(x, y)
int x, y;
{
return (RND(x) + y);
}
int
rn2(x)
int x;
{
return (RND(x));
}
int
rnd(x)
int x;
{
return (RND(x) + 1);
}
int
d(n, x)
int n, x;
{
int tmp = n;
while (n--)
tmp += RND(x);
return (tmp);
}