Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP
Path: utzoo!mnetor!uunet!tektronix!tekgen!tekred!games-request
From: games-request@tekred.TEK.COM
Newsgroups: comp.sources.games
Subject: v03i010: NetHack2.2 - display oriented dungeons and dragons, Part10/20
Message-ID: <1896@tekred.TEK.COM>
Date: Wed, 2-Dec-87 12:01:13 EST
Article-I.D.: tekred.1896
Posted: Wed Dec 2 12:01:13 1987
Date-Received: Sun, 6-Dec-87 05:07:34 EST
Sender: billr@tekred.TEK.COM
Lines: 2346
Approved: billr@tekred.TEK.COM
Submitted by: mike@genat.UUCP (Mike Stephenson)
Comp.sources.games: Volume 3, Issue 10
Archive-name: nethack2.2/Part10
#! /bin/sh
# This is a shell archive. Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file". To overwrite existing
# files, type "sh file -c". You can also feed this as standard input via
# unshar, or by typing "sh lev.c <<'END_OF_lev.c'
X/* SCCS Id: @(#)lev.c 2.1 87/10/19
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
X
X#include
X#include "hack.h"
X#include "mkroom.h"
Xextern struct monst *restmonchn();
Xextern struct obj *restobjchn();
Xextern struct obj *billobjs;
Xextern char *itoa();
Xextern char SAVEF[];
Xextern int hackpid;
Xextern xchar dlevel;
Xextern char nul[];
X
X#ifndef NOWORM
X#include "wseg.h"
Xextern struct wseg *wsegs[32], *wheads[32];
Xextern long wgrowtime[32];
X#endif
X
X#ifdef DGK
Xstruct finfo fileinfo[MAXLEVEL+1];
Xlong bytes_counted;
Xint count_only;
X#else
Xboolean level_exists[MAXLEVEL+1];
X#endif
X
X#ifdef DGK
Xsavelev(fd, lev, mode)
Xint fd, mode;
Xxchar lev;
X{
X if (mode & COUNT) {
X count_only = TRUE;
X bytes_counted = 0;
X savelev0(fd, lev);
X while (bytes_counted > freediskspace(levels))
X if (!swapout_oldest())
X return FALSE;
X }
X if (mode & WRITE) {
X count_only = FALSE;
X bytes_counted = 0;
X savelev0(fd, lev);
X }
X fileinfo[lev].where = ACTIVE;
X fileinfo[lev].time = moves;
X fileinfo[lev].size = bytes_counted;
X return TRUE;
X}
X
Xsavelev0(fd,lev)
X#else
Xsavelev(fd,lev)
X#endif
Xint fd;
Xxchar lev;
X{
X#ifndef NOWORM
X register struct wseg *wtmp, *wtmp2;
X register tmp;
X#endif
X
X if(fd < 0) panic("Save on bad file!"); /* impossible */
X#ifndef DGK
X if(lev >= 0 && lev <= MAXLEVEL)
X level_exists[lev] = TRUE;
X#endif
X bwrite(fd,(char *) &hackpid,sizeof(hackpid));
X bwrite(fd,(char *) &lev,sizeof(lev));
X bwrite(fd,(char *) levl,sizeof(levl));
X#ifdef GRAPHICS
X bwrite(fd, (char *) &showsyms, sizeof(struct symbols));
X#endif
X bwrite(fd,(char *) &moves,sizeof(long));
X bwrite(fd,(char *) &xupstair,sizeof(xupstair));
X bwrite(fd,(char *) &yupstair,sizeof(yupstair));
X bwrite(fd,(char *) &xdnstair,sizeof(xdnstair));
X bwrite(fd,(char *) &ydnstair,sizeof(ydnstair));
X savemonchn(fd, fmon);
X savegoldchn(fd, fgold);
X savetrapchn(fd, ftrap);
X saveobjchn(fd, fobj);
X saveobjchn(fd, billobjs);
X billobjs = 0;
X save_engravings(fd);
X#ifndef QUEST
X bwrite(fd,(char *) rooms,sizeof(rooms));
X bwrite(fd,(char *) doors,sizeof(doors));
X#endif
X#ifdef DGK
X if (!count_only)
X#endif
X {
X fgold = 0;
X ftrap = 0;
X fmon = 0;
X fobj = 0;
X }
X#ifndef NOWORM
X bwrite(fd,(char *) wsegs,sizeof(wsegs));
X for(tmp=1; tmp<32; tmp++){
X for(wtmp = wsegs[tmp]; wtmp; wtmp = wtmp2){
X wtmp2 = wtmp->nseg;
X bwrite(fd,(char *) wtmp,sizeof(struct wseg));
X }
X#ifdef DGK
X if (!count_only)
X#endif
X wsegs[tmp] = 0;
X }
X bwrite(fd,(char *) wgrowtime,sizeof(wgrowtime));
X#endif /* NOWORM /**/
X#ifdef DGK
X if (count_only) return(0);
X#endif
X billobjs = 0;
X fgold = 0;
X ftrap = 0;
X fmon = 0;
X fobj = 0;
X}
X
Xbwrite(fd,loc,num)
Xregister fd;
Xregister char *loc;
Xregister unsigned num;
X{
X#ifdef DGK
X bytes_counted += num;
X if (!count_only)
X#endif
X/* lint wants the 3rd arg of write to be an int; lint -p an unsigned */
X if(write(fd, loc, (int) num) != num)
X panic("cannot write %u bytes to file #%d", num, fd);
X}
X
Xsaveobjchn(fd,otmp)
Xregister fd;
Xregister struct obj *otmp;
X{
X register struct obj *otmp2;
X unsigned xl;
X int minusone = -1;
X
X while(otmp) {
X otmp2 = otmp->nobj;
X xl = otmp->onamelth;
X bwrite(fd, (char *) &xl, sizeof(int));
X bwrite(fd, (char *) otmp, xl + sizeof(struct obj));
X#ifdef DGK
X if (!count_only)
X#endif
X free((char *) otmp);
X otmp = otmp2;
X }
X bwrite(fd, (char *) &minusone, sizeof(int));
X}
X
X#ifdef MSDOS
X/* We don't want to save any pointers in any files, so convert
X * the pointers to indices before writing the monsters to disk -dgk
X */
Xsavemonchn(fd,mtmp)
Xregister fd;
Xregister struct monst *mtmp;
X{
X register struct monst *mtmp2;
X unsigned xl;
X int minusone = -1;
X struct permonst *permonstp;
X int monsindex;
X extern struct permonst li_dog, dog, la_dog;
X#ifdef KAA
X int mi;
X extern struct permonst hell_hound;
X# ifdef HARD
X extern struct permonst d_lord, d_prince;
X# endif
X# ifdef KJSMODS
X extern struct permonst pm_guard, pm_ghost, pm_eel;
X# endif
X#endif /* KAA /**/
X
X while(mtmp) {
X mtmp2 = mtmp->nmon;
X xl = mtmp->mxlth + mtmp->mnamelth;
X bwrite(fd, (char *) &xl, sizeof(int));
X /* store an index where the pointer used to be */
X permonstp = mtmp->data;
X if (permonstp == &li_dog)
X monsindex = mi = -1; /* fake index */
X else if (permonstp == &dog)
X monsindex = --mi; /* fake index */
X else if (permonstp == &la_dog)
X monsindex = --mi; /* fake index */
X#ifdef KAA
X else if (permonstp == &hell_hound)
X monsindex = --mi; /* fake index */
X# ifdef HARD
X else if (permonstp == &d_lord)
X monsindex = --mi; /* fake index */
X
X else if (permonstp == &d_prince)
X monsindex = --mi; /* fake index */
X# endif
X# ifdef KJSMODS
X else if (permonstp == &pm_guard)
X monsindex = -mi; /* fake index */
X
X else if (permonstp == &pm_ghost)
X monsindex = -mi; /* fake index */
X
X else if (permonstp == &pm_eel)
X monsindex = -mi; /* fake index */
X# endif
X#endif
X else
X monsindex = permonstp - &mons[0];
X *((int *)&mtmp->data) = monsindex;
X bwrite(fd, (char *) mtmp, xl + sizeof(struct monst));
X mtmp->data = permonstp; /* restore the pointer */
X if(mtmp->minvent) saveobjchn(fd,mtmp->minvent);
X#ifdef DGK
X if (!count_only)
X#endif
X free((char *) mtmp);
X mtmp = mtmp2;
X }
X bwrite(fd, (char *) &minusone, sizeof(int));
X}
X#else
X
Xsavemonchn(fd,mtmp)
Xregister fd;
Xregister struct monst *mtmp;
X{
X register struct monst *mtmp2;
X unsigned xl;
X int minusone = -1;
X struct permonst *monbegin = &mons[0];
X
X bwrite(fd, (char *) &monbegin, sizeof(monbegin));
X
X while(mtmp) {
X mtmp2 = mtmp->nmon;
X xl = mtmp->mxlth + mtmp->mnamelth;
X bwrite(fd, (char *) &xl, sizeof(int));
X bwrite(fd, (char *) mtmp, xl + sizeof(struct monst));
X if(mtmp->minvent) saveobjchn(fd,mtmp->minvent);
X free((char *) mtmp);
X mtmp = mtmp2;
X }
X bwrite(fd, (char *) &minusone, sizeof(int));
X}
X#endif
X
Xsavegoldchn(fd,gold)
Xregister fd;
Xregister struct gold *gold;
X{
X register struct gold *gold2;
X while(gold) {
X gold2 = gold->ngold;
X bwrite(fd, (char *) gold, sizeof(struct gold));
X#ifdef DGK
X if (!count_only)
X#endif
X free((char *) gold);
X gold = gold2;
X }
X bwrite(fd, nul, sizeof(struct gold));
X}
X
Xsavetrapchn(fd,trap)
Xregister fd;
Xregister struct trap *trap;
X{
X register struct trap *trap2;
X while(trap) {
X trap2 = trap->ntrap;
X bwrite(fd, (char *) trap, sizeof(struct trap));
X#ifdef DGK
X if (!count_only)
X#endif
X free((char *) trap);
X trap = trap2;
X }
X bwrite(fd, nul, sizeof(struct trap));
X}
X
Xgetlev(fd,pid,lev)
Xint fd,pid;
Xxchar lev;
X{
X register struct gold *gold;
X register struct trap *trap;
X#ifndef NOWORM
X register struct wseg *wtmp;
X#endif
X register tmp;
X long omoves;
X int hpid;
X xchar dlvl;
X#ifdef GRAPHICS
X struct symbols osymbol;
X int x, y, up, dn, lt, rt;
X uchar osym, nsym;
X#endif
X
X#ifdef MSDOS
X setmode(fd,O_BINARY);
X#endif
X /* First some sanity checks */
X mread(fd, (char *) &hpid, sizeof(hpid));
X mread(fd, (char *) &dlvl, sizeof(dlvl));
X if((pid && pid != hpid) || (lev && dlvl != lev)) {
X pline("Strange, this map is not as I remember it.");
X pline("Somebody is trying some trickery here ...");
X pline("This game is void ...");
X done("tricked");
X }
X
X fgold = 0;
X ftrap = 0;
X mread(fd, (char *) levl, sizeof(levl));
X#ifdef GRAPHICS
X /* Corners are poorly implemented. They only exist in the
X * scrsym field of each dungeon element. So we have to go
X * through the previous level, looking for scrsym with the
X * old corner values, checking to make sure that they are
X * where corners should be, then replace them with the scrsym
X * of the new GRAPHICS character set. Ugly.
X */
X mread(fd, (char *) &osymbol, sizeof(osymbol));
X if (memcmp((char *) &osymbol, (char *) &showsyms, sizeof (struct symbols))) {
X for (x = 0; x < COLNO; x++)
X for (y = 0; y < ROWNO; y++) {
X osym = levl[x][y].scrsym;
X nsym = 0;
X switch (levl[x][y].typ) {
X case 0:
X case SCORR:
X break;
X case ROOM:
X if (osym == osymbol.room)
X nsym = showsyms.room;
X break;
X case DOOR:
X if (osym == osymbol.door)
X nsym = showsyms.door;
X break;
X case CORR:
X if (osym == osymbol.corr)
X nsym = showsyms.corr;
X break;
X case VWALL:
X if (osym == osymbol.vwall)
X nsym = showsyms.vwall;
X break;
X case SDOOR:
X if (osym == osymbol.vwall)
X nsym = showsyms.vwall;
X else if (osym == osymbol.hwall)
X nsym = showsyms.hwall;
X break;
X /* Now the ugly stuff */
X case HWALL:
X up = (y > 0) ? levl[x][y-1].typ : 0;
X dn = (y < ROWNO-1) ?levl[x][y+1].typ : 0;
X lt = (x > 0) ? levl[x-1][y].typ : 0;
X rt = (x < COLNO-1) ?levl[x+1][y].typ : 0;
X up = up && (up == VWALL || up == DOOR
X || up == SDOOR);
X dn = dn && (dn == VWALL || dn == DOOR
X || dn == SDOOR);
X lt = lt && (lt == HWALL || lt == DOOR
X || lt == SDOOR);
X rt = rt && (rt == HWALL || rt == DOOR
X || rt == SDOOR);
X if (rt && dn && osym == osymbol.tlcorn)
X nsym = showsyms.tlcorn;
X else if (lt && dn && osym == osymbol.trcorn)
X nsym = showsyms.trcorn;
X else if (rt && up && osym == osymbol.blcorn)
X nsym = showsyms.blcorn;
X else if (lt && up && osym == osymbol.brcorn)
X nsym = showsyms.brcorn;
X else if (osym == osymbol.hwall)
X nsym = showsyms.hwall;
X break;
X default:
X break;
X }
X if (nsym)
X levl[x][y].scrsym = nsym;
X }
X }
X#endif
X mread(fd, (char *)&omoves, sizeof(omoves));
X mread(fd, (char *)&xupstair, sizeof(xupstair));
X mread(fd, (char *)&yupstair, sizeof(yupstair));
X mread(fd, (char *)&xdnstair, sizeof(xdnstair));
X mread(fd, (char *)&ydnstair, sizeof(ydnstair));
X
X fmon = restmonchn(fd);
X
X /* regenerate animals while on another level */
X { long tmoves = (moves > omoves) ? moves-omoves : 0;
X register struct monst *mtmp, *mtmp2;
X extern char genocided[];
X
X for(mtmp = fmon; mtmp; mtmp = mtmp2) {
X long newhp; /* tmoves may be very large */
X
X mtmp2 = mtmp->nmon;
X if(index(genocided, mtmp->data->mlet)) {
X mondead(mtmp);
X continue;
X }
X
X if(mtmp->mtame && tmoves > 250) {
X mtmp->mtame = 0;
X mtmp->mpeaceful = 0;
X }
X
X /* restore shape changers - Maarten Jan Huisjes */
X if (mtmp->data->mlet == ':' && !Protection_from_shape_changers
X && !mtmp->cham)
X mtmp->cham = 1;
X else if(mtmp->cham && Protection_from_shape_changers) {
X mtmp->cham = 0;
X (void) newcham(mtmp, PM_CHAMELEON);
X }
X
X newhp = mtmp->mhp +
X (index(MREGEN, mtmp->data->mlet) ? tmoves : tmoves/20);
X if(newhp > mtmp->mhpmax)
X mtmp->mhp = mtmp->mhpmax;
X else
X mtmp->mhp = newhp;
X }
X }
X
X setgd();
X gold = newgold();
X mread(fd, (char *)gold, sizeof(struct gold));
X while(gold->gx) {
X gold->ngold = fgold;
X fgold = gold;
X gold = newgold();
X mread(fd, (char *)gold, sizeof(struct gold));
X }
X free((char *) gold);
X trap = newtrap();
X mread(fd, (char *)trap, sizeof(struct trap));
X while(trap->tx) {
X trap->ntrap = ftrap;
X ftrap = trap;
X trap = newtrap();
X mread(fd, (char *)trap, sizeof(struct trap));
X }
X free((char *) trap);
X fobj = restobjchn(fd);
X billobjs = restobjchn(fd);
X rest_engravings(fd);
X#ifndef QUEST
X mread(fd, (char *)rooms, sizeof(rooms));
X mread(fd, (char *)doors, sizeof(doors));
X#endif
X#ifndef NOWORM
X mread(fd, (char *)wsegs, sizeof(wsegs));
X for(tmp = 1; tmp < 32; tmp++) if(wsegs[tmp]){
X wheads[tmp] = wsegs[tmp] = wtmp = newseg();
X while(1) {
X mread(fd, (char *)wtmp, sizeof(struct wseg));
X if(!wtmp->nseg) break;
X wheads[tmp]->nseg = wtmp = newseg();
X wheads[tmp] = wtmp;
X }
X }
X mread(fd, (char *)wgrowtime, sizeof(wgrowtime));
X#endif
X}
X
Xmread(fd, buf, len)
Xregister fd;
Xregister char *buf;
Xregister unsigned len;
X{
X register int rlen;
X extern boolean restoring;
X
X rlen = read(fd, buf, (int) len);
X if(rlen != len){
X pline("Read %d instead of %u bytes.\n", rlen, len);
X if(restoring) {
X (void) unlink(SAVEF);
X error("Error restoring old game.");
X }
X panic("Error reading level file.");
X }
X}
X
Xmklev()
X{
X extern boolean in_mklev;
X
X if(getbones()) return;
X
X in_mklev = TRUE;
X makelevel();
X in_mklev = FALSE;
X}
X
X#ifdef DGK
Xswapin_file(lev) {
X char to[PATHLEN], from[PATHLEN];
X
X sprintf(from, "%s%s", permbones, alllevels);
X sprintf(to, "%s%s", levels, alllevels);
X name_file(from, lev);
X name_file(to, lev);
X while (fileinfo[lev].size > freediskspace(to))
X if (!swapout_oldest())
X return FALSE;
X#ifdef WIZARD
X if (wizard) {
X pline("Swapping in `%s'", from);
X fflush(stdout);
X }
X#endif
X copyfile(from, to);
X (void) unlink(from);
X fileinfo[lev].where = ACTIVE;
X return TRUE;
X}
X
X
Xswapout_oldest() {
X char to[PATHLEN], from[PATHLEN];
X int i, oldest;
X long oldtime;
X
X if (!ramdisk)
X return FALSE;
X for (i = 1, oldtime = 0, oldest = 0; i <= maxdlevel; i++)
X if (fileinfo[i].where == ACTIVE
X && (!oldtime || fileinfo[i].time < oldtime)) {
X oldest = i;
X oldtime = fileinfo[i].time;
X }
X if (!oldest)
X return FALSE;
X sprintf(from, "%s%s", levels, alllevels);
X sprintf(to, "%s%s", permbones, alllevels);
X name_file(from, oldest);
X name_file(to, oldest);
X#ifdef WIZARD
X if (wizard) {
X pline("Swapping out `%s'.", from);
X fflush(stdout);
X }
X#endif
X copyfile(from, to);
X unlink(from);
X fileinfo[oldest].where = SWAPPED;
X return TRUE;
X}
X
Xcopyfile(from, to)
Xchar *from, *to;
X{
X char buf[BUFSIZ];
X int nfrom, nto, fdfrom, fdto;
X
X if ((fdfrom = open(from, O_RDONLY | O_BINARY | O_CREAT, FMASK)) < 0)
X panic("Can't copy from %s !?", from);
X if ((fdto = open(to, O_WRONLY | O_BINARY | O_CREAT, FMASK)) < 0)
X panic("Can't copy to %s", to);
X do {
X nfrom = read(fdfrom, buf, BUFSIZ);
X nto = write(fdto, buf, nfrom);
X if (nto != nfrom)
X panic("Copyfile failed!");
X } while (nfrom == BUFSIZ);
X close(fdfrom);
X close(fdto);
X}
X#endif
END_OF_lev.c
if test 13452 -ne `wc -c mhitu.c <<'END_OF_mhitu.c'
X/* SCCS Id: @(#)mhitu.c 2.1 87/10/18
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
X
X#include "hack.h"
Xextern struct monst *makemon();
Xextern struct obj *carrying();
X#ifdef KAA
Xextern char pl_character[];
X#endif
X
X/*
X * mhitu: monster hits you
X * returns 1 if monster dies (e.g. 'y', 'F'), 0 otherwise
X */
Xmhitu(mtmp)
Xregister struct monst *mtmp;
X{
X register struct permonst *mdat = mtmp->data;
X register int tmp, ctmp;
X
X nomul(0);
X
X /* If swallowed, can only be affected by hissers and by u.ustuck */
X if(u.uswallow) {
X if(mtmp != u.ustuck) {
X if(mdat->mlet == 'c' && !rn2(13)) {
X pline("Outside, you hear %s's hissing!",
X monnam(mtmp));
X pline("%s gets turned to stone!",
X Monnam(u.ustuck));
X pline("And the same fate befalls you.");
X done_in_by(mtmp);
X /* "notreached": not return(1); */
X }
X return(0);
X }
X switch(mdat->mlet) { /* now mtmp == u.ustuck */
X case ',':
X youswld(mtmp, (u.uac > 0) ? u.uac+4 : 4,
X 5, Monnam(mtmp));
X break;
X case '\'':
X youswld(mtmp,rnd(6),7,Monnam(mtmp));
X break;
X case 'P':
X youswld(mtmp,d(2,4),12,Monnam(mtmp));
X break;
X default:
X /* This is not impossible! */
X#ifdef DGKMOD
X /* If the swallowing monster changes into a monster
X * that is not capable of swallowing you, you get
X * regurgitated - dgk
X */
X pline("You get regurgitated!");
X u.ux = mtmp->mx;
X u.uy = mtmp->my;
X u.uswallow = 0;
X u.ustuck = 0;
X mnexto(mtmp);
X setsee();
X docrt();
X break;
X#else
X pline("The mysterious monster totally digests you.");
X u.uhp = 0;
X#endif /* DGKMOD /**/
X }
X if(u.uhp < 1) done_in_by(mtmp);
X return(0);
X }
X
X if(mdat->mlet == 'c' && Stoned)
X return(0);
X
X /* make eels visible the moment they hit/miss us */
X if(mdat->mlet == ';' && mtmp->minvis && cansee(mtmp->mx,mtmp->my)){
X mtmp->minvis = 0;
X pmon(mtmp);
X }
X if(!index("1&DuxynNF",mdat->mlet))
X tmp = hitu(mtmp,d(mdat->damn,mdat->damd));
X else
X tmp = 0;
X if(index(UNDEAD, mdat->mlet) && midnight())
X tmp += hitu(mtmp,d(mdat->damn,mdat->damd));
X
X ctmp = tmp && !mtmp->mcan &&
X (!uarm || objects[uarm->otyp].a_can < rnd(3) || !rn2(50));
X switch(mdat->mlet) {
X case '1':
X if(wiz_hit(mtmp)) return(1); /* he disappeared */
X break;
X case '&':
X demon_hit(mtmp);
X break;
X case ',':
X if(tmp) justswld(mtmp,Monnam(mtmp));
X break;
X case '\'':
X if (tmp) justswld(mtmp,Monnam(mtmp));
X break;
X case ';':
X if(ctmp) {
X if(!u.ustuck && !rn2(10)) {
X pline("%s swings itself around you!",
X Monnam(mtmp));
X u.ustuck = mtmp;
X } else if(u.ustuck == mtmp &&
X levl[mtmp->mx][mtmp->my].typ == POOL) {
X pline("%s drowns you ...", Monnam(mtmp));
X done("drowned");
X }
X }
X break;
X case 'A':
X if(ctmp && rn2(2)) {
X if(Poison_resistance)
X pline("The sting doesn't seem to affect you.");
X else {
X pline("You feel weaker!");
X losestr(1);
X }
X }
X break;
X case 'C':
X (void) hitu(mtmp,rnd(6));
X break;
X case 'c':
X if(!rn2(5)) {
X if (mtmp->mcan)
X pline("You hear a cough from %s!", monnam(mtmp));
X else {
X pline("You hear %s's hissing!", monnam(mtmp));
X if(!rn2(20) || (flags.moonphase == NEW_MOON
X && !carrying(DEAD_LIZARD) && u.usym != 'c')) {
X Stoned = 5;
X /* pline("You get turned to stone!"); */
X /* done_in_by(mtmp); */
X }
X }
X }
X break;
X case 'D':
X if(rn2(6) || mtmp->mcan) {
X (void) hitu(mtmp,d(3,10));
X (void) hitu(mtmp,rnd(8));
X (void) hitu(mtmp,rnd(8));
X break;
X }
X kludge("%s breathes fire!",Monnam(mtmp));
X buzz(-1,mtmp->mx,mtmp->my,u.ux-mtmp->mx,u.uy-mtmp->my);
X break;
X case 'd':
X (void) hitu(mtmp,d(2, (flags.moonphase == FULL_MOON) ? 3 : 4));
X break;
X case 'e':
X (void) hitu(mtmp,d(3,6));
X break;
X case 'F':
X if(mtmp->mcan) break;
X kludge("%s explodes!", Monnam(mtmp));
X if(Cold_resistance) pline("You don't seem affected by it.");
X else {
X xchar dn;
X if(17-(u.ulevel/2) > rnd(20)) {
X pline("You get blasted!");
X dn = 6;
X } else {
X pline("You duck the blast...");
X dn = 3;
X }
X losehp_m(d(dn,6), mtmp);
X }
X mondead(mtmp);
X return(1);
X case 'g':
X if(ctmp && multi >= 0 && !rn2(3)) {
X /* fix so we don't know what hit us when blind KAA */
X if (Blind)
X pline("You are frozen by its juices!");
X else
X pline("You are frozen by %s's juices!",monnam(mtmp));
X nomul(-rnd(10));
X }
X break;
X case 'h':
X if(ctmp && multi >= 0 && !rn2(5)) {
X nomul(-rnd(10));
X if (Blind)
X pline("You are put to sleep by its bite!");
X else
X pline("You are put to sleep by %s's bite!",monnam(mtmp));
X }
X break;
X case 'j':
X tmp = hitu(mtmp,rnd(3));
X tmp &= hitu(mtmp,rnd(3));
X if(tmp){
X (void) hitu(mtmp,rnd(4));
X (void) hitu(mtmp,rnd(4));
X }
X break;
X case 'k':
X if((hitu(mtmp,rnd(4)) || !rn2(3)) && ctmp){
X poisoned("bee's sting",mdat->mname);
X }
X break;
X case 'L':
X#ifdef KAA
X if (u.usym=='L') break;
X#endif
X if(!mtmp->mcan && tmp) stealgold(mtmp);
X break;
X case 'N':
X#ifdef KAA
X if (u.usym=='N') {
X if (mtmp->minvent)
X pline("%s brags about the goods some dungeon explorer provided.",
X Monnam(mtmp));
X else
X pline("%s makes some remarks about how difficult theft is lately.",
X Monnam(mtmp));
X rloc(mtmp);
X } else
X#endif
X if(mtmp->mcan && !Blind) {
X pline("%s tries to seduce you, but you seem not interested.",
X Amonnam(mtmp, "plain"));
X if(rn2(3)) rloc(mtmp);
X } else if(steal(mtmp)) {
X rloc(mtmp);
X mtmp->mflee = 1;
X }
X break;
X case 'n':
X if(!uwep
X#ifdef KAA
X && u.usym == '@'
X#endif
X && !uarm && !uarmh && !uarms && !uarmg) {
X pline("%s hits! (I hope you don't mind)",
X Monnam(mtmp));
X u.uhp += rnd(7);
X if(!rn2(7)) u.uhpmax++;
X if(u.uhp > u.uhpmax) u.uhp = u.uhpmax;
X flags.botl = 1;
X if(!rn2(50)) rloc(mtmp);
X } else {
X#ifdef KAA
X if (pl_character[0] == 'H' && u.usym == '@') {
X if (!(moves % 5))
X pline("Doc, I can't help you unless you cooperate.");
X } else {
X#endif
X (void) hitu(mtmp,d(2,6));
X (void) hitu(mtmp,d(2,6));
X#ifdef KAA
X }
X#endif
X }
X break;
X case 'o':
X tmp = hitu(mtmp,rnd(6));
X if(hitu(mtmp,rnd(6)) && tmp && /* hits with both paws */
X !u.ustuck && rn2(2)) {
X u.ustuck = mtmp;
X kludge("%s has grabbed you!", Monnam(mtmp));
X losehp_m(d(2,8), mtmp);
X } else if(u.ustuck == mtmp) {
X losehp_m(d(2,8), mtmp);
X pline("You are being crushed.");
X }
X break;
X case 'P':
X if(ctmp && !rn2(4))
X justswld(mtmp,Monnam(mtmp));
X else
X (void) hitu(mtmp,d(2,4));
X break;
X case 'Q':
X#ifdef KAA
X if(ctmp) {
X pline("Your position suddenly seems very uncertain!");
X tele();
X }
X#else
X (void) hitu(mtmp,rnd(2));
X (void) hitu(mtmp,rnd(2));
X#endif
X break;
X case 'R':
X if(ctmp && uarmh && !uarmh->rustfree &&
X (int) uarmh->spe >= -1) {
X pline("Your helmet rusts!");
X uarmh->spe--;
X } else
X if(ctmp && uarm && !uarm->rustfree && /* Mike Newton */
X uarm->otyp < STUDDED_LEATHER_ARMOR &&
X (int) uarm->spe >= -1) {
X pline("Your armor rusts!");
X uarm->spe--;
X }
X break;
X case 'S':
X if(ctmp && !rn2(8)) {
X poisoned("snake's bite",mdat->mname);
X }
X break;
X case 's':
X if(ctmp && !rn2(8)) {
X#ifdef SPIDERS
X poisoned("giant spider's bite",mdat->mname);
X#else
X poisoned("scorpion's sting",mdat->mname);
X#endif
X }
X (void) hitu(mtmp,rnd(8));
X (void) hitu(mtmp,rnd(8));
X break;
X case 'T':
X (void) hitu(mtmp,rnd(6));
X (void) hitu(mtmp,rnd(6));
X break;
X case 't':
X if(!rn2(5)) rloc(mtmp);
X break;
X case 'u':
X mtmp->mflee = 1;
X break;
X case 'U':
X (void) hitu(mtmp,d(3,4));
X (void) hitu(mtmp,d(3,4));
X break;
X case 'v':
X if(ctmp && !u.ustuck) u.ustuck = mtmp;
X break;
X case 'V':
X if(tmp) losehp_m(4, mtmp);
X if(ctmp) losexp();
X break;
X case 'W':
X if(ctmp) losexp();
X break;
X#ifndef NOWORM
X case 'w':
X if(tmp) wormhit(mtmp);
X#endif
X break;
X case 'X':
X (void) hitu(mtmp,rnd(5));
X (void) hitu(mtmp,rnd(5));
X (void) hitu(mtmp,rnd(5));
X break;
X case 'x':
X { register long side = rn2(2) ? RIGHT_SIDE : LEFT_SIDE;
X#ifdef KAA
X if (mtmp->mcan)
X pline("%s nuzzles against your %s leg!",
X Monnam(mtmp), (side==RIGHT_SIDE)?"right":"left");
X else {
X#endif
X pline("%s pricks your %s leg!",
X Monnam(mtmp), (side==RIGHT_SIDE)?"right":"left");
X set_wounded_legs(side, rnd(50));
X losehp_m(2, mtmp);
X#ifdef KAA
X }
X#endif
X break;
X }
X case 'y':
X if(mtmp->mcan) break;
X mondead(mtmp);
X if(!Blind && (u.usym != 'y')) {
X pline("You are blinded by a blast of light!");
X Blinded = d(4,12);
X seeoff(0);
X }
X return(1);
X case 'Y':
X (void) hitu(mtmp,rnd(6));
X break;
X#ifdef RPH
X case '8':
X if (canseemon(mtmp) && !mtmp->mcan) {
X
X pline ("You look upon %s.", monnam(mtmp));
X pline ("You turn to stone.");
X done_in_by(mtmp);
X }
X (void) hitu(mtmp,d(2,6));
X (void) hitu(mtmp,d(2,6));
X break;
X#endif
X }
X if(u.uhp < 1) done_in_by(mtmp);
X return(0);
X}
X
Xhitu(mtmp,dam)
Xregister struct monst *mtmp;
Xregister dam;
X{
X register tmp, res;
X
X nomul(0);
X if (mtmp->mfroz || mtmp->mhp <= 0) return(0);
X /* If you are a 'a' or 'E' the monster might not get a second hit */
X if(u.uswallow) return(0);
X
X if(mtmp->mhide && mtmp->mundetected) {
X mtmp->mundetected = 0;
X if(!Blind) {
X register struct obj *obj;
X extern char * Xmonnam();
X if(obj = o_at(mtmp->mx,mtmp->my))
X pline("%s was hidden under %s!",
X Xmonnam(mtmp), doname(obj));
X }
X }
X
X tmp = u.uac;
X /* give people with Ac = -10 at least some vulnerability */
X if(tmp < 0) {
X dam += tmp; /* decrease damage */
X if(dam <= 0) dam = 1;
X tmp = -rn2(-tmp);
X }
X tmp += mtmp->data->mlevel;
X if(multi < 0) tmp += 4;
X if((Invis && mtmp->data->mlet != 'I') || !mtmp->mcansee) tmp -= 2;
X if(mtmp->mtrapped) tmp -= 2;
X if(tmp <= rnd(20)) {
X if(Blind) pline("It misses.");
X else pline("%s misses.",Monnam(mtmp));
X res = 0;
X } else {
X if(Blind) pline("It hits!");
X else pline("%s hits!",Monnam(mtmp));
X if (u.usym == 'a' && !rn2(4)) {
X pline("%s is splashed by your acid!",Monnam(mtmp));
X mtmp->mhp -= rnd(10);
X if(mtmp->mhp <= 0) {
X pline("%s dies!",Monnam(mtmp));
X xkilled(mtmp,0);
X }
X }
X losehp_m(dam, mtmp);
X res = 1;
X }
X stop_occupation();
X if(u.usym=='E' && mtmp->mcansee && rn2(2)) {
X pline("%s is frozen by your gaze!",Monnam(mtmp));
X mtmp->mfroz = 1;
X }
X return(res);
X}
X
X#define Athome (Inhell && !mtmp->cham)
X
X#ifdef HARD
Xdemon_talk(mtmp) /* returns 1 if we pay him off. */
Xregister struct monst *mtmp;
X{
X char *xmonnam(), *Xmonnam();
X int demand, offer;
X
X if(uwep && !strcmp(ONAME(uwep), "Excalibur")) {
X
X pline("%s looks very angry.", Xmonnam(mtmp, 1));
X mtmp->mpeaceful = mtmp->mtame = 0;
X return(0);
X }
X if(!strcmp(mtmp->data->mname, "demon")) { /* not for regular '&'s */
X
X pline("%s mutters something about awful working conditions.",
X Xmonnam(mtmp, 1));
X return(0);
X }
X
X /* Slight advantage given. */
X if(!strcmp(mtmp->data->mname, "demon prince") && mtmp->minvis) {
X
X if (!Blind) pline("%s appears before you.", Xmonnam(mtmp, 1));
X mtmp->minvis = 0;
X pmon(mtmp);
X }
X if(u.usym == '&') { /* Won't blackmail their own. */
X
X pline("%s says, 'Good hunting %s.' and vanishes",
X Xmonnam(mtmp, 1), flags.female ? "Sister" : "Brother");
X rloc(mtmp);
X return(1);
X }
X demand = (u.ugold * (rnd(80) + 20 * Athome)) / 100;
X if(!demand) { /* you have no gold */
X mtmp->mpeaceful = 0;
X return(0);
X } else {
X char buf[80];
X
X pline("%s demands %d Zorkmids for safe passage.",
X Xmonnam(mtmp, 1), demand);
X pline("how many will you offer him?");
X getlin(buf);
X sscanf(buf, "%d", &offer);
X
X if(offer >= u.ugold) {
X pline("You give %s all your gold.", xmonnam(mtmp, 0));
X offer = u.ugold;
X } else pline("You give %s %d Zorkmids.", xmonnam(mtmp, 0), offer);
X u.ugold -= offer;
X
X if(offer >= demand) {
X pline("%s vanishes laughing about cowardly mortals.",
X Xmonnam(mtmp));
X } else {
X if(rnd(40) > (demand - offer)) {
X pline("%s scowls at you menacingly, then vanishes.",
X Xmonnam(mtmp));
X } else {
X pline("%s gets angry...", Xmonnam(mtmp));
X mtmp->mpeaceful = 0;
X return(0);
X }
X }
X }
X mondead(mtmp);
X return(1);
X}
X#endif
X
Xdemon_hit(mtmp)
Xregister struct monst *mtmp;
X{
X register struct obj *otmp;
X int onum, nobj = 0,
X ml = mtmp->data->mlevel;
X
X if(!mtmp->cham && !mtmp->mcan && !rn2(13)) {
X (void) makemon(PM_DEMON,u.ux,u.uy);
X } else {
X switch((!mtmp->mcan) ? rn2(ml - 5 - !Athome) : 0) {
X#ifdef HARD
X case 12:
X case 11:
X case 10:
X case 9: /* the wiz */
X (void) hitu(mtmp, 1);
X pline("Oh no, he's using the touch of death!");
X if (rn2(ml) > 12) {
X
X if(Confusion)
X pline("You have an out of body experience.");
X else {
X killer = "touch of death";
X done("died");
X }
X } else pline("Lucky for you, it didn't work!");
X break;
X case 8: /* demon princes */
X (void) hitu(mtmp, 1);
X if(!destroy_arm()) pline("Your skin itches.");
X break;
X case 7:
X (void) hitu(mtmp, 1);
X for (otmp = invent; otmp; otmp = otmp->nobj) nobj++;
X onum = rn2(nobj);
X for(otmp = invent; onum != 0; onum--) otmp = otmp->nobj;
X otmp->cursed++;
X break;
X case 6: /* demon lords */
X (void) hitu(mtmp, 1);
X pline("You suddenly feel weaker!");
X losestr(rnd(ml - 6));
X break;
X case 5:
X (void) hitu(mtmp, 1);
X if (Confusion) pline("Hey, that tickles!");
X else pline("Huh, What? Where am I?");
X HConfusion += rn1(7, 16);
X break;
X#endif /* HARD /**/
X default: /* demons and chamelons as demons */
X (void) hitu(mtmp,d(2,5 + Athome));
X (void) hitu(mtmp,d(2,5 + Athome));
X (void) hitu(mtmp,rnd(2 + Athome));
X (void) hitu(mtmp,rnd(2 + Athome));
X (void) hitu(mtmp,rn1(4,1 + Athome));
X break;
X }
X }
X return(0);
X}
END_OF_mhitu.c
if test 13637 -ne `wc -c options.c <<'END_OF_options.c'
X/* SCCS Id: @(#)options.c 2.0 87/09/14
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
X
X#include "config.h"
X#include "hack.h"
Xextern char *eos();
X#ifdef SORTING
Xstatic boolean set_order;
X#endif
X
Xinitoptions()
X{
X register char *opts;
X extern char *getenv();
X
X flags.time = flags.nonews = flags.notombstone = flags.end_own =
X flags.standout = flags.nonull = FALSE;
X flags.no_rest_on_space = TRUE;
X flags.invlet_constant = TRUE;
X flags.end_top = 5;
X flags.end_around = 4;
X flags.female = FALSE; /* players are usually male */
X#ifdef SORTING
X flags.sortpack = TRUE;
X#endif
X#ifdef SAFE_ATTACK
X flags.confirm = TRUE;
X#endif
X#ifdef DGKMOD
X flags.silent = flags.pickup = TRUE;
X#endif
X#ifdef DGK
X flags.IBMBIOS = flags.DECRainbow = flags.rawio = FALSE;
X read_config_file();
X#endif
X#ifdef HACKOPTIONS
X if(opts = getenv("HACKOPTIONS"))
X parseoptions(opts,TRUE);
X#endif
X}
X
Xparseoptions(opts, from_env)
Xregister char *opts;
Xboolean from_env;
X{
X register char *op,*op2;
X unsigned num;
X boolean negated;
X
X if(op = index(opts, ',')) {
X *op++ = 0;
X parseoptions(op, from_env);
X }
X if(op = index(opts, ' ')) {
X op2 = op;
X while(*op++)
X if(*op != ' ') *op2++ = *op;
X }
X if(!*opts) return;
X negated = FALSE;
X while((*opts == '!') || !strncmp(opts, "no", 2)) {
X if(*opts == '!') opts++; else opts += 2;
X negated = !negated;
X }
X
X#ifndef DGK
X if(!strncmp(opts,"standout",4)) {
X flags.standout = !negated;
X return;
X }
X
X if(!strncmp(opts,"null",4)) {
X flags.nonull = negated;
X return;
X }
X
X if(!strncmp(opts,"tombstone",4)) {
X flags.notombstone = negated;
X return;
X }
X
X if(!strncmp(opts,"news",4)) {
X flags.nonews = negated;
X return;
X }
X#endif
X
X#ifdef SAFE_ATTACK
X if (!strncmp(opts, "conf", 4)) {
X flags.confirm = !negated;
X return;
X }
X
X#endif
X#ifdef DGKMOD
X if (!strncmp(opts, "sile", 4)) {
X flags.silent = !negated;
X return;
X }
X
X if (!strncmp(opts, "pick", 4)) {
X flags.pickup = !negated;
X return;
X }
X#endif
X#ifdef DGK
X if (!strncmp(opts, "IBMB", 4)) {
X flags.IBMBIOS = !negated;
X return;
X }
X
X if (!strncmp(opts, "rawi", 4)) {
X if (from_env)
X flags.rawio = !negated;
X else
X pline("'rawio' only settable from %s.", configfile);
X return;
X }
X
X if (!strncmp(opts, "DECR", 4)) {
X flags.DECRainbow = !negated;
X return;
X }
X#endif
X
X#ifdef SORTING
X if (!strncmp(opts, "sort", 4)) {
X flags.sortpack = !negated;
X return;
X }
X
X /*
X * the order to list the pack
X */
X if (!strncmp(opts,"packorder",4)) {
X register char *sp, *tmp;
X extern char inv_order[];
X int tmpend;
X
X op = index(opts,':');
X if(!op) goto bad;
X op++; /* skip : */
X
X /* Missing characters in new order are filled in at the end
X * from inv_order.
X */
X for (sp = op; *sp; sp++)
X if (!index(inv_order, *sp))
X goto bad; /* bad char in order */
X else if (index(sp + 1, *sp))
X goto bad; /* dup char in order */
X tmp = (char *) alloc(strlen(inv_order) + 1);
X (void) strcpy(tmp, op);
X for (sp = inv_order, tmpend = strlen(tmp); *sp; sp++)
X if (!index(tmp, *sp)) {
X tmp[tmpend++] = *sp;
X tmp[tmpend] = 0;
X }
X (void) strcpy(inv_order, tmp);
X free(tmp);
X set_order = TRUE;
X return;
X }
X#endif
X
X if(!strncmp(opts,"time",4)) {
X flags.time = !negated;
X flags.botl = 1;
X return;
X }
X
X if(!strncmp(opts,"restonspace",4)) {
X flags.no_rest_on_space = negated;
X return;
X }
X
X if(!strncmp(opts,"fixinv",4)) {
X flags.invlet_constant = !negated;
X if(!from_env && flags.invlet_constant) reassign ();
X return;
X }
X
X if(!strncmp(opts,"male",4)) {
X#ifdef KAA
X if(!from_env && flags.female != negated)
X pline("That is not anatomically possible.");
X else
X#endif
X flags.female = negated;
X return;
X }
X if(!strncmp(opts,"female",6)) {
X#ifdef KAA
X if(!from_env && flags.female == negated)
X pline("That is not anatomically possible.");
X else
X#endif
X flags.female = !negated;
X return;
X }
X
X /* name:string */
X if(!strncmp(opts,"name",4)) {
X extern char plname[PL_NSIZ];
X if(!from_env) {
X#ifdef DGK
X pline("'name' only settable from %s.", configfile);
X#else
X pline("The playername can be set only from HACKOPTIONS.");
X#endif
X return;
X }
X op = index(opts,':');
X if(!op) goto bad;
X nmcpy(plname, op+1, sizeof(plname)-1);
X return;
X }
X
X#ifdef GRAPHICS
X /* graphics:string */
X if(!strncmp(opts,"graphics",4)) {
X if(!from_env) {
X#ifdef DGK
X pline("'graphics' only settable from %s.", configfile);
X#else
X pline("The graphics string can be set only from HACKOPTIONS.");
X#endif
X return;
X }
X op = index(opts,':');
X if(!op)
X goto bad;
X else
X opts = op + 1;
X/*
X * You could have problems here if you configure FOUNTAINS, SPIDERS or NEWCLASS
X * in or out and forget to change the tail entries in your graphics string.
X */
X#define SETPCHAR(f, n) showsyms.f = (strlen(opts) > n) ? opts[n] : defsyms.f
X SETPCHAR(stone, 0);
X SETPCHAR(vwall, 1);
X SETPCHAR(hwall, 2);
X SETPCHAR(tlcorn, 3);
X SETPCHAR(trcorn, 4);
X SETPCHAR(blcorn, 5);
X SETPCHAR(brcorn, 6);
X SETPCHAR(door, 7);
X SETPCHAR(room, 8);
X SETPCHAR(corr, 9);
X SETPCHAR(upstair, 10);
X SETPCHAR(dnstair, 11);
X SETPCHAR(trap, 12);
X#ifdef FOUNTAINS
X SETPCHAR(pool, 13);
X SETPCHAR(fountain, 14);
X#endif
X#ifdef NEWCLASS
X SETPCHAR(throne, 15);
X#endif
X#ifdef SPIDERS
X SETPCHAR(web, 16);
X#endif
X#undef SETPCHAR
X return;
X }
X#endif /* GRAPHICS */
X
X /* endgame:5t[op] 5a[round] o[wn] */
X if(!strncmp(opts,"endgame",3)) {
X op = index(opts,':');
X if(!op) goto bad;
X op++;
X while(*op) {
X num = 1;
X if(digit(*op)) {
X num = atoi(op);
X while(digit(*op)) op++;
X } else
X if(*op == '!') {
X negated = !negated;
X op++;
X }
X switch(*op) {
X case 't':
X flags.end_top = num;
X break;
X case 'a':
X flags.end_around = num;
X break;
X case 'o':
X flags.end_own = !negated;
X break;
X default:
X goto bad;
X }
X while(letter(*++op)) ;
X if(*op == '/') op++;
X }
X return;
X }
X#ifdef DOGNAME
X if(!strncmp(opts, "dogname", 3)) {
X extern char dogname[];
X op = index(opts, ':');
X if (!op) goto bad;
X nmcpy(dogname, ++op, 62);
X return;
X }
X#endif /* DOGNAME */
Xbad:
X if(!from_env) {
X if(!strncmp(opts, "help", 4)) {
X option_help();
X return;
X }
X pline("Bad option: %s. Type `O help' for help.", opts);
X return;
X }
X#ifdef DGK
X printf("Bad syntax in OPTIONS in %s.", configfile);
X#else
X puts("Bad syntax in HACKOPTIONS.");
X puts("Use for example:");
X puts(
X"HACKOPTIONS=\"!restonspace,notombstone,endgame:own/5 topscorers/4 around me\""
X );
X#endif
X getret();
X}
X
Xdoset()
X{
X char buf[BUFSZ];
X#ifdef SORTING
X extern char inv_order[];
X#endif
X
X pline("What options do you want to set? ");
X getlin(buf);
X if(!buf[0] || buf[0] == '\033') {
X#ifdef DGK
X (void) strcpy(buf,"OPTIONS=");
X#else
X (void) strcpy(buf,"HACKOPTIONS=");
X (void) strcat(buf, flags.female ? "female," : "male,");
X if(flags.standout) (void) strcat(buf,"standout,");
X if(flags.nonull) (void) strcat(buf,"nonull,");
X if(flags.nonews) (void) strcat(buf,"nonews,");
X if(flags.notombstone) (void) strcat(buf,"notombstone,");
X if(flags.no_rest_on_space) (void) strcat(buf,"!rest_on_space,");
X#endif
X#ifdef SORTING
X if (flags.sortpack) (void) strcat(buf,"sortpack,");
X if (set_order){
X (void) strcat(buf, "packorder: ");
X (void) strcat(buf, inv_order);
X (void) strcat(buf, ",");
X }
X#endif
X#ifdef SAFE_ATTACK
X if (flags.confirm) (void) strcat(buf,"confirm,");
X#endif
X#ifdef DGKMOD
X if (flags.pickup) (void) strcat(buf,"pickup,");
X if (flags.silent) (void) strcat(buf,"silent,");
X#endif
X#ifdef DGK
X if (flags.rawio) (void) strcat(buf,"rawio,");
X if (flags.IBMBIOS) (void) strcat(buf,"IBMBIOS,");
X if (flags.DECRainbow) (void) strcat(buf,"DECRainbow,");
X#endif
X if(flags.time) (void) strcat(buf,"time,");
X if(flags.end_top != 5 || flags.end_around != 4 || flags.end_own){
X (void) sprintf(eos(buf), "endgame: %u topscores/%u around me",
X flags.end_top, flags.end_around);
X if(flags.end_own) (void) strcat(buf, "/own scores");
X } else {
X register char *eop = eos(buf);
X if(*--eop == ',') *eop = 0;
X }
X pline(buf);
X } else
X parseoptions(buf, FALSE);
X
X return(0);
X}
X
X#ifdef DGKMOD
Xdotogglepickup() {
X flags.pickup = !flags.pickup;
X pline("Pickup: %s.", flags.pickup ? "ON" : "OFF");
X return (0);
X}
X#endif
X
Xnmcpy(dest, source, maxlen)
X char *dest, *source;
X int maxlen;
X{
X char *cs, *cd;
X int count;
X
X cd = dest;
X cs = source;
X for(count = 1; count < maxlen; count++) {
X if(*cs == ',') break;
X *cd++ = *cs++;
X }
X *cd = 0;
X}
X
X#ifdef SORTING
Xchar *packorder =
X# ifdef SPELLS
X "\")[%?+/=!(*0";
X# else
X "\")[%?/=!(*0";
X# endif
X#endif
X#define Page_line(x) if(page_line(x)) goto quit
X
Xoption_help() {
X char buf[BUFSZ];
X
X set_pager(0);
X (void) sprintf(buf, " Net%s Options Help:",
X#ifndef QUEST
X "Hack");
X#else
X "Quest);
X#endif
X if(page_line("") || page_line(buf) || page_line("")) goto quit;
X
X#ifdef DGK
X (void) sprintf(buf, "To set options use OPTIONS= in %s", configfile);
X Page_line(buf);
X#else
X Page_line("To set options use `HACKOPTIONS=\"\"' in your environment");
X#endif
X
X Page_line("or give the command \"O\" followed by the line while playing.");
X Page_line("Here is a list of options separated by commas.");
X Page_line("");
X
X#ifdef DGK
X Page_line("Boolean options are confirm, pickup, rawio, silent, sortpack, time, IBMBIOS,")
X Page_line("and DECRainbow. These can be negated by prefixing them with '!' or \"no\".");
X#else
X Page_line("Boolean options are rest_on_space, news, time, null tombstone, and (fe)male,");
X Page_line("These can be negated by prefixing them with '!' or \"no\".");
X#endif
X Page_line("");
X
X Page_line("The compound options are `name', (eg. name:Merlin-W,),");
X#ifdef DOGNAME
X Page_line("`dogname', the name of your (first) dog (eg. dogname:Fang,),");
X#endif
X
X#ifdef SORTING
X Page_line("`packorder'; the order that items should appear in your pack");
X (void)sprintf(buf, "(the default is: packorder:%s ), ", packorder);
X Page_line(buf);
X#endif
X
X#ifdef GRAPHICS
X Page_line("`endgame', and `graphics'.");
X#else
X Page_line("and `endgame'.");
X#endif
X Page_line("");
X
X Page_line("The `endgame' option is followed by a description of which parts of");
X Page_line("the scorelist you wish to see. You might for example say:");
X Page_line("");
X Page_line("\"endgame:own scores/5 top scores/4 around my score\".");
X
X set_pager(1);
X return;
Xquit:
X set_pager(2);
X return;
X}
END_OF_options.c
if test 10336 -ne `wc -c potion.c <<'END_OF_potion.c'
X/* SCCS Id: @(#)potion.c 2.1 87/09/29
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
X
X#include "hack.h"
Xextern int float_down();
Xextern char *nomovemsg;
Xextern struct monst youmonst;
Xextern struct monst *makemon();
Xchar *hcolor();
X#ifdef KAA
Xchar *xname();
Xextern char pl_character[];
X#endif
X#ifdef FOUNTAINS
Xextern int drinkfountain();
Xextern int dipfountain();
X#endif
X
Xint nothing, unkn;
X
Xdodrink() {
X register struct obj *otmp;
X register int retval;
X
X#ifdef FOUNTAINS
X
X /* Is there something to drink here, i.e., a fountain? */
X if (IS_FOUNTAIN(levl[u.ux][u.uy].typ)) {
X pline("Drink from the fountain? [ny] ");
X if(readchar() == 'y') {
X (void) drinkfountain();
X return(0);
X }
X }
X
X#endif /* FOUNTAINS /**/
X
X nothing = unkn = 0;
X otmp = getobj("!", "drink");
X if(!otmp) return(0);
X if(!strcmp(objects[otmp->otyp].oc_descr, "smoky") && !rn2(13)) {
X ghost_from_bottle();
X goto use_it;
X }
X if((retval = peffects(otmp)) >= 0) return(retval);
X
X if(nothing) {
X unkn++;
X pline("You have a %s feeling for a moment, then it passes.",
X Hallucination ? "normal" : "peculiar");
X }
X if(otmp->dknown && !objects[otmp->otyp].oc_name_known) {
X if(!unkn) {
X objects[otmp->otyp].oc_name_known = 1;
X more_experienced(0,10);
X } else if(!objects[otmp->otyp].oc_uname)
X docall(otmp);
X }
Xuse_it:
X useup(otmp);
X return(1);
X}
X
Xpeffects(otmp)
X register struct obj *otmp;
X{
X register struct obj *objs;
X register struct monst *mtmp;
X
X switch(otmp->otyp){
X case POT_RESTORE_STRENGTH:
X#ifdef SPELLS
X case SPE_RESTORE_STRENGTH:
X#endif
X unkn++;
X pline("Wow! This makes you feel great!");
X if(u.ustr < u.ustrmax) {
X u.ustr = u.ustrmax;
X flags.botl = 1;
X }
X break;
X#ifdef KAA
X case POT_HALLUCINATION:
X if (Hallucination) nothing++;
X else pline("Oh wow! Everything looks so cosmic!");
X Hallucination += rn1(100,750);
X setsee();
X break;
X case POT_HOLY_WATER:
X unkn++;
X if(index("VWZ&",u.usym)) {
X pline("This burns like acid!");
X /* should never kill you, but... */
X losehp(d(2,6), "potion of holy water");
X } else {
X pline("You feel full of awe.");
X if (Sick) Sick=0;
X if (HConfusion) HConfusion=0;
X }
X#else
X case POT_HOLY_WATER:
X case POT_HALLUCINATION:
X#endif
X break;
X case POT_BOOZE:
X unkn++;
X pline("Ooph! This tastes like liquid fire!");
X HConfusion += d(3,8);
X /* the whiskey makes us feel better */
X if(u.uhp < u.uhpmax) losehp(-1, "bottle of whiskey");
X if(!rn2(4)) {
X pline("You pass out.");
X multi = -rnd(15);
X nomovemsg = "You awake with a headache.";
X }
X break;
X case POT_INVISIBILITY:
X#ifdef SPELLS
X case SPE_INVISIBILITY:
X#endif
X if(Invis || See_invisible)
X nothing++;
X else {
X if(!Blind)
X pline("Gee! All of a sudden, you can't see yourself.");
X else
X pline("You feel rather airy."), unkn++;
X newsym(u.ux,u.uy);
X }
X HInvis += rn1(15,31);
X break;
X case POT_FRUIT_JUICE:
X pline("This tastes like fruit juice.");
X lesshungry(20);
X break;
X case POT_HEALING:
X pline("You begin to feel better.");
X healup(rnd(10), 1, 1, 1);
X break;
X case POT_PARALYSIS:
X if(Levitation)
X pline("You are motionlessly suspended.");
X else
X pline("Your feet are frozen to the floor!");
X nomul(-(rn1(10,25)));
X break;
X case POT_MONSTER_DETECTION:
X#ifdef SPELLS
X case SPE_DETECT_MONSTERS:
X#endif
X if(!fmon) {
X strange_feeling(otmp, "You feel threatened.");
X return(1);
X } else {
X cls();
X for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
X if(mtmp->mx > 0)
X at(mtmp->mx,mtmp->my,Hallucination ? rndmonsym() :
X mtmp->data->mlet);
X prme();
X pline("You sense the presence of monsters.");
X more();
X docrt();
X }
X break;
X case POT_OBJECT_DETECTION:
X#ifdef SPELLS
X case SPE_DETECT_TREASURE:
X#endif
X if(!fobj) {
X strange_feeling(otmp, "You feel a pull downward.");
X return(1);
X } else {
X for(objs = fobj; objs; objs = objs->nobj)
X if(objs->ox != u.ux || objs->oy != u.uy)
X goto outobjmap;
X pline("You sense the presence of objects close nearby.");
X break;
X outobjmap:
X cls();
X for(objs = fobj; objs; objs = objs->nobj)
X at(objs->ox,objs->oy,Hallucination ? rndobjsym()
X : objs->olet);
X
X /* monster possessions added by GAN 12/16/86 */
X for(mtmp = fmon ; mtmp ; mtmp = mtmp->nmon)
X if(mtmp->minvent)
X for(objs = mtmp->minvent; objs ;
X objs = objs->nobj)
X at(mtmp->mx,mtmp->my,objs->olet);
X prme();
X pline("You sense the presence of objects.");
X more();
X docrt();
X }
X break;
X case POT_SICKNESS:
X pline("Yech! This stuff tastes like poison.");
X if(Poison_resistance)
X pline("(But in fact it was biologically contaminated orange juice.)");
X#ifdef KAA
X if (pl_character[0] == 'H')
X pline("Fortunately you have been immunized!");
X else {
X#endif
X losestr((Poison_resistance) ? 1 : rn1(4,3));
X if(!Poison_resistance)
X losehp(rnd(10), "contaminated potion");
X#ifdef KAA
X }
X#endif
X if(Hallucination) {
X pline("You are shocked back to your senses!");
X Hallucination=1;
X }
X break;
X case POT_CONFUSION:
X if(!Confusion)
X if (Hallucination) {
X pline("What a trippy feeling!");
X unkn++;
X } else
X pline("Huh, What? Where am I?");
X else nothing++;
X HConfusion += rn1(7,16);
X break;
X case POT_GAIN_STRENGTH:
X pline("Wow do you feel strong!");
X gainstr(0);
X break;
X case POT_SPEED:
X if(Wounded_legs) {
X heal_legs();
X unkn++;
X break;
X } /* and fall through */
X#ifdef SPELLS
X case SPE_HASTE_SELF:
X#endif
X if(!(Fast & ~INTRINSIC))
X pline("You are suddenly moving much faster.");
X else
X pline("Your legs get new energy."), unkn++;
X Fast += rn1(10,100);
X break;
X case POT_BLINDNESS:
X if(!Blind)
X if (Hallucination)
X pline("Bummer! Everything is dark! Help!");
X else
X pline("A cloud of darkness falls upon you.");
X else nothing++;
X Blinded += rn1(100,250);
X seeoff(0);
X break;
X case POT_GAIN_LEVEL:
X pluslvl();
X break;
X case POT_EXTRA_HEALING:
X pline("You feel much better.");
X healup(d(2,20)+1, 2, 1, 1);
X if(Hallucination) Hallucination = 1;
X break;
X case POT_LEVITATION:
X#ifdef SPELLS
X case SPE_LEVITATION:
X#endif
X if(!Levitation)
X float_up();
X else
X nothing++;
X Levitation += rnd(100);
X u.uprops[PROP(RIN_LEVITATION)].p_tofn = float_down;
X break;
X case POT_GAIN_ENERGY: /* M. Stephenson */
X#ifdef SPELLS
X { register int num;
X if(Confusion) {
X pline("You feel feverish.");
X unkn++;
X } else
X pline("Magical energies course through your body.");
X num = rnd(5) + 1;
X u.uenmax += num;
X u.uen += num;
X flags.botl = 1;
X break;
X }
X#else
X pline("This potion tastes weird!");
X break;
X#endif
X default:
X impossible("What a funny potion! (%u)", otmp->otyp);
X return(0);
X }
X return(-1);
X}
X
Xhealup(nhp, nxtra, curesick, cureblind)
X int nhp, nxtra;
X register boolean curesick, cureblind;
X{
X#ifdef KAA
X if (u.mtimedone & nhp) {
X u.mh += rnd(nhp);
X if (u.mh > u.mhmax) u.mh = (u.mhmax + nxtra);
X }
X#endif
X if(nhp) {
X u.uhp += nhp;
X if(u.uhp > u.uhpmax) u.uhp = (u.uhpmax += nxtra);
X }
X if(Blind && cureblind) Blinded = 1; /* see on next move */
X if(Sick && curesick) Sick = 0;
X flags.botl = 1;
X return;
X}
X
Xpluslvl()
X{
X register num;
X
X pline("You feel more experienced.");
X num = rnd(10);
X u.uhpmax += num;
X u.uhp += num;
X#ifdef SPELLS
X num = rnd(u.ulevel/2+1) + 1; /* M. Stephenson */
X u.uenmax += num;
X u.uen += num;
X#endif
X if(u.ulevel < 14) {
X extern long newuexp();
X
X u.uexp = newuexp()+1;
X pline("Welcome to experience level %u.", ++u.ulevel);
X }
X flags.botl = 1;
X}
X
Xstrange_feeling(obj,txt)
Xregister struct obj *obj;
Xregister char *txt;
X{
X if(flags.beginner)
X pline("You have a %s feeling for a moment, then it passes.",
X Hallucination ? "normal" : "strange");
X else
X pline(txt);
X if(!objects[obj->otyp].oc_name_known && !objects[obj->otyp].oc_uname)
X docall(obj);
X useup(obj);
X}
X
Xchar *bottlenames[] = {
X "bottle", "phial", "flagon", "carafe", "flask", "jar", "vial"
X};
X
Xpotionhit(mon, obj)
Xregister struct monst *mon;
Xregister struct obj *obj;
X{
X extern char *xname();
X register char *botlnam = bottlenames[rn2(SIZE(bottlenames))];
X boolean uclose, isyou = (mon == &youmonst);
X
X if(isyou) {
X uclose = TRUE;
X pline("The %s crashes on your head and breaks into shivers.",
X botlnam);
X losehp(rnd(2), "thrown potion");
X } else {
X uclose = (dist(mon->mx,mon->my) < 3);
X /* perhaps 'E' and 'a' have no head? */
X pline("The %s crashes on %s's head and breaks into shivers.",
X botlnam, monnam(mon));
X if(rn2(5) && mon->mhp > 1)
X mon->mhp--;
X }
X pline("The %s evaporates.", xname(obj));
X
X#ifdef KAA
X if(!isyou) switch (obj->otyp) {
X#else
X if(!isyou && !rn2(3)) switch(obj->otyp) {
X#endif
X
X case POT_RESTORE_STRENGTH:
X case POT_GAIN_STRENGTH:
X case POT_HEALING:
X case POT_EXTRA_HEALING:
X if(mon->mhp < mon->mhpmax) {
X mon->mhp = mon->mhpmax;
X pline("%s looks sound and hale again!", Monnam(mon));
X }
X break;
X case POT_SICKNESS:
X if((mon->mhpmax > 3) && !resist(mon, '!', 0, NOTELL))
X mon->mhpmax /= 2;
X if((mon->mhp > 2) && !resist(mon, '!', 0, NOTELL))
X mon->mhp /= 2;
X#ifdef KAA
X pline("%s looks rather ill.", Monnam(mon));
X#endif
X break;
X case POT_CONFUSION:
X case POT_BOOZE:
X if(!resist(mon, '!', 0, NOTELL)) mon->mconf = 1;
X break;
X case POT_INVISIBILITY:
X unpmon(mon);
X mon->minvis = 1;
X pmon(mon);
X break;
X case POT_PARALYSIS:
X mon->mfroz = 1;
X break;
X case POT_SPEED:
X mon->mspeed = MFAST;
X break;
X case POT_BLINDNESS:
X mon->mblinded |= 64 + rn2(32) +
X rn2(32) * !resist(mon, '!', 0, NOTELL);
X break;
X#ifdef KAA
X case POT_HOLY_WATER:
X if (index("ZVW &", mon->data->mlet)) {
X pline("%s shrieks in pain!", Monnam(mon));
X mon->mhp -= d(2,6);
X if (mon->mhp <1) killed(mon);
X }
X break;
X#endif
X/*
X case POT_GAIN_LEVEL:
X case POT_LEVITATION:
X case POT_FRUIT_JUICE:
X case POT_MONSTER_DETECTION:
X case POT_OBJECT_DETECTION:
X break;
X*/
X }
X if(uclose && rn2(5))
X potionbreathe(obj);
X obfree(obj, Null(obj));
X}
X
Xpotionbreathe(obj)
Xregister struct obj *obj;
X{
X switch(obj->otyp) {
X case POT_RESTORE_STRENGTH:
X case POT_GAIN_STRENGTH:
X if(u.ustr < u.ustrmax) u.ustr++, flags.botl = 1;
X break;
X case POT_HEALING:
X case POT_EXTRA_HEALING:
X if(u.uhp < u.uhpmax) u.uhp++, flags.botl = 1;
X break;
X case POT_SICKNESS:
X if(u.uhp <= 5) u.uhp = 1; else u.uhp -= 5;
X flags.botl = 1;
X break;
X case POT_HALLUCINATION:
X#ifdef KAA
X pline("You have a vision for a moment.");
X break;
X#endif
X case POT_CONFUSION:
X case POT_BOOZE:
X if(!Confusion)
X pline("You feel somewhat dizzy.");
X HConfusion += rnd(5);
X break;
X case POT_INVISIBILITY:
X pline("For an instant you could see through yourself!");
X break;
X case POT_PARALYSIS:
X pline("Something seems to be holding you.");
X nomul(-rnd(5));
X break;
X case POT_SPEED:
X Fast += rnd(5);
X pline("Your knees seem more flexible now.");
X break;
X case POT_BLINDNESS:
X if(!Blind) pline("It suddenly gets dark.");
X Blinded += rnd(5);
X seeoff(0);
X break;
X/*
X case POT_GAIN_LEVEL:
X case POT_LEVITATION:
X case POT_FRUIT_JUICE:
X case POT_MONSTER_DETECTION:
X case POT_OBJECT_DETECTION:
X break;
X*/
X }
X /* note: no obfree() */
X}
X
X/*
X * -- rudimentary -- to do this correctly requires much more work
X * -- all sharp weapons get one or more qualities derived from the potions
X * -- texts on scrolls may be (partially) wiped out; do they become blank?
X * -- or does their effect change, like under Confusion?
X * -- all objects may be made invisible by POT_INVISIBILITY
X * -- If the flask is small, can one dip a large object? Does it magically
X * -- become a jug? Etc.
X */
Xdodip(){
X register struct obj *potion, *obj;
X#ifdef KAA
X char *tmp;
X#endif
X
X if(!(obj = getobj("#", "dip")))
X return(0);
X#ifdef FOUNTAINS
X /* Is there something to dip into here, i.e., a fountain? */
X if (levl[u.ux][u.uy].typ == FOUNTAIN) {
X pline("Dip it in the fountain? [ny] ");
X if(readchar() == 'y') {
X dipfountain(obj);
X return(1);
X }
X }
X#endif
X if(!(potion = getobj("!", "dip into")))
X return(0);
X#ifndef KAA
X pline("Interesting...");
X#else
X if(potion->otyp == POT_HOLY_WATER) {
X if (obj->cursed) {
X obj->cursed=0;
X pline("Your %s %s.", aobjnam(obj,"softly glow"),
X Hallucination ? hcolor() : "amber");
X poof: useup(potion);
X return(1);
X } else if(obj->otyp >= ARROW && obj->otyp <= SPEAR) {
X obj->dknown=1;
X tmp = Hallucination ? hcolor() : "light blue";
X /* dknown for weapons is meaningless, so it's free to be reused. */
X pline("Your %s with a%s %s aura.", aobjnam(obj,"softly glow"),
X index("aeiou",*tmp) ? "n" : "", tmp);
X goto poof;
X }
X }
X#endif
X if(obj->otyp == ARROW || obj->otyp == DART ||
X obj->otyp == CROSSBOW_BOLT || obj->otyp == SHURIKEN) {
X if(potion->otyp == POT_SICKNESS) {
X char buf[BUFSZ];
X useup(potion);
X if(obj->spe < 7) obj->spe++; /* %% */
X sprintf(buf, xname(potion));
X pline("The %s forms a coating on the %s.",
X buf, xname(obj));
X }
X }
X#ifdef HARD
X else if (!rn2(4)) useup(potion);
X#endif
X#ifdef KAA
X pline("Interesting...");
X#endif
X return(1);
X}
X
Xghost_from_bottle(){
X extern struct permonst pm_ghost;
X register struct monst *mtmp;
X
X if(!(mtmp = makemon(PM_GHOST,u.ux,u.uy))){
X pline("This bottle turns out to be empty.");
X return;
X }
X mnexto(mtmp);
X pline("As you open the bottle, an enormous ghost emerges!");
X pline("You are frightened to death, and unable to move.");
X nomul(-3);
X}
X
Xgainstr(inc)
Xregister int inc;
X{
X if (inc) u.ustr++;
X else {
X if (u.ustr < 18) u.ustr += (rn2(4) ? 1 : rnd(6) );
X else if (u.ustr < 103) u.ustr += rnd(10);
X else u.ustr++;
X }
X
X if(u.ustr > 118) u.ustr = 118;
X if(u.ustr > u.ustrmax) u.ustrmax = u.ustr;
X flags.botl = 1;
X}
END_OF_potion.c
if test 13547 -ne `wc -c