Пример #1
0
void
rloc(struct monst *mtmp)
{
	int tx, ty;
	char ch = mtmp->data->mlet;

#ifndef NOWORM
	if (ch == 'w' && mtmp->mx)	/* do not relocate worms */
		return;
#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);
}
Пример #2
0
/* 0: open  1: wait+close  2: close */
void
set_pager(int mode)
{
	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();
		}
	}
}
Пример #3
0
void morewhat(FILE *fp)
{
    char bufr[BUFSZ];
    char *ep;

    pline("More info? ");
    
    if(readchar() != 'y') {
        return;
    }

    cls();

    while((fgets(bufr, BUFSZ, fp) != 0) && (*bufr == '\t')) {
        ep = index(bufr, '\n');
    
        if(ep == NULL) {
            break;
        }

        *ep = 0;

        puts(bufr + 1);
    }

    more();
    docrt();
}
Пример #4
0
void mondead(struct monst *mtmp)
{
    relobj(mtmp, 1);
    unpmon(mtmp);
    relmon(mtmp);

    if(u.ustuck == mtmp) {
        u.ustuck = 0;
        
        if(u.uswallow != 0) {
            u.uswallow = 0;
            setsee();
            docrt();
        }
    }

    if(mtmp->isshk != 0) {
        shkdead();
    }

    if(mtmp->isgd != 0) {
        gddead();
    }

#ifndef NOWORM
    if(mtmp->wormno) {
        wormdead(mtmp);
    }
#endif

    monfree(mtmp);
}
Пример #5
0
static void
winch()
{
    int oldLI = LI, oldCO = CO, i;
    register struct WinDesc *cw;

    getwindowsz();
    if((oldLI != LI || oldCO != CO) && ttyDisplay) {
	ttyDisplay->rows = LI;
	ttyDisplay->cols = CO;

	cw = wins[BASE_WINDOW];
	cw->rows = ttyDisplay->rows;
	cw->cols = ttyDisplay->cols;

	if(flags.window_inited) {
	    cw = wins[WIN_MESSAGE];
	    cw->curx = cw->cury = 0;

	    tty_destroy_nhwindow(WIN_STATUS);
	    WIN_STATUS = tty_create_nhwindow(NHW_STATUS);

	    if(u.ux) {
#ifdef CLIPPING
		if(CO < COLNO || LI < ROWNO+3) {
		    setclipped();
		    tty_cliparound(u.ux, u.uy);
		} else {
		    clipping = FALSE;
		    clipx = clipy = 0;
		}
#endif
		i = ttyDisplay->toplin;
		ttyDisplay->toplin = 0;
		docrt();
		bot();
		ttyDisplay->toplin = i;
		flush_screen(1);
		if(i) {
		    addtopl(toplines);
		} else
		    for(i=WIN_INVEN; i < MAXWIN; i++)
			if(wins[i] && wins[i]->active) {
			    /* cop-out */
			    addtopl("Press Return to continue: ");
			    break;
			}
		(void) fflush(stdout);
		if(i < 2) flush_screen(1);
	    }
	}
    }
}
Пример #6
0
void
newgame()
{

	fobj = invent = level.buriedobjlist = migrating_objs = (struct obj *)0;
	fmon = migrating_mons = (struct monst *)0;
	ftrap = 0;
	flags.ident = 1;

	if(wiz1_level.dlevel == 0) init_dungeons();
	init_objects();		/* must be before u_init() */
	u_init();
	init_artifacts();	/* must be after u_init() */

#ifndef NO_SIGNAL
	(void) signal(SIGINT, (SIG_RET_TYPE) done1);
#endif
#ifdef NEWS
	if(flags.news) display_file(NEWS, FALSE);
#endif
#ifdef MULDGN
	load_qtlist();	/* load up the quest text info */
	quest_init();
	if(flags.legacy && moves == 1) com_pager(1);
#endif
	mklev();
	u_on_upstairs();
	check_special_room(FALSE);
	vision_reset();		/* set up internals for level (after mklev) */

	flags.botlx = 1;

	/* Move the monster from under you or else
	 * makedog() will fail when it calls makemon().
	 * 			- ucsfcgl!kneller
	 */
	if(MON_AT(u.ux, u.uy)) mnexto(m_at(u.ux, u.uy));

#ifdef CLIPPING
	cliparound(u.ux, u.uy);
#endif
	(void) makedog();
	docrt();

#ifdef INSURANCE
	save_currentstate();
#endif
	return;
}
Пример #7
0
/* 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 <stdio.h>
#include "config.h"
#ifdef BSD
#include	<sgtty.h>
struct ltchars ltc, ltc0;
#else
#include	<termio.h>	/* also includes part of <sgtty.h> */
struct termio termio;
#endif BSD

getioctls() {
#ifdef BSD
	(void) ioctl(fileno(stdin), TIOCGLTC, (char *) &ltc);
	(void) ioctl(fileno(stdin), TIOCSLTC, (char *) &ltc0);
#else
	(void) ioctl(fileno(stdin), TCGETA, &termio);
#endif BSD
}

setioctls() {
#ifdef BSD
	(void) ioctl(fileno(stdin), TIOCSLTC, (char *) &ltc);
#else
	(void) ioctl(fileno(stdin), TCSETA, &termio);
#endif BSD
}

#ifdef SUSPEND		/* implies BSD */
dosuspend() {
#include	<signal.h>
#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);
}
Пример #8
0
int
child(int wt)
{
	int status;
	int f;
	char *home;
	gid_t gid;

	f = fork();
	if(f == 0){		/* child */
		settty((char *) 0);		/* also calls end_screen() */
		/* revoke privs */
		gid = getgid();
		setresgid(gid, gid, gid);
#ifdef CHDIR
		home = getenv("HOME");
		if (home == NULL || *home == '\0')
			home = "/";
		(void) chdir(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);
}
Пример #9
0
void rloc(struct monst *mtmp)
{
    int tx;
    int ty;
    char ch = mtmp->data->mlet;

#ifndef NOWORM
    if((ch == 'w') && (mtmp->mx)) {
        /* Do not relocate worms */
        return;
    }
#endif

    tx = rn1(COLNO - 3, 2);
    ty = rn2(ROWNO);

    while(goodpos(tx, ty) == 0) {
        tx = rn1(COLNO - 3, 2);
        ty = rn2(ROWNO);
    }

    mtmp->mx = tx;
    mtmp->my = ty;

    if(u.ustuck == mtmp) {
        if(u.uswallow != 0) {
            u.ux = tx;
            u.uy = ty;
            docrt();
        }
        else {
            u.ustuck = 0;
        }
    }

    pmon(mtmp);
}
Пример #10
0
bool dorecover (void)
{
    char savefile [PATH_MAX];
    snprintf (ArrayBlock(savefile), HACK_SAVEFILE, getenv("HOME"));
    int fd = open (savefile, O_RDONLY);
    if (fd < 0)
	return false;
    mread (fd, &_u, sizeof(struct you));
    if (_u.maxdlevel < 1 || _u.maxdlevel > MAXLEVEL) {
	close (fd);
	you_dtor();
	return false;
    }
    invent = restobjchn (fd);
    for (struct obj* o = invent; o; o = o->nobj)
	if (o->owornmask)
	    setworn (o, o->owornmask);
    fcobj = restobjchn (fd);
    fallen_down = restmonchn (fd);
    mread (fd, &_wflags, sizeof(struct worldflag));
    mread (fd, pl_character, sizeof pl_character);
    restnames (fd);
    restgenocided (fd);
    for (unsigned i = 0; i < _u.maxdlevel; ++i) {
	level_dtor (&_levels[i]);
	getlev (fd, &_levels[i]);
    }
    if (_u.dlevel < 1 || _u.dlevel > _u.maxdlevel)
	_u.dlevel = _u.maxdlevel;
    _level = &_levels[_u.dlevel-1];
    setsee();	// only to recompute seelx etc. - these weren't saved
    docrt();
    close (fd);
    unlink (savefile);
    return true;
}
Пример #11
0
bool
child(bool wt)
{
	int status;
	int f;

	f = fork();
	if (f == 0) {		/* child */
		settty(NULL);	/* also calls end_screen() */
		/* revoke */
		setgid(getgid());
#ifdef CHDIR
		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 */
	signal(SIGINT, SIG_IGN);
	signal(SIGQUIT, SIG_IGN);
	wait(&status);
	gettty();
	setftty();
	signal(SIGINT, done1);
#ifdef WIZARD
	if (wizard)
		signal(SIGQUIT, SIG_DFL);
#endif /* WIZARD */
	if (wt)
		getret();
	docrt();
	return (0);
}
Пример #12
0
void
newgame()
{
	int i;

#ifdef MFLOPPY
	gameDiskPrompt();
#endif

	flags.ident = 1;

	for (i = 0; i < NUMMONS; i++)
		mvitals[i].mvflags = mons[i].geno & G_NOCORPSE;

	init_objects();		/* must be before u_init() */

	flags.pantheon = -1;	/* role_init() will reset this */
	role_init();		/* must be before init_dungeons(), u_init(),
				 * and init_artifacts() */

	init_dungeons();	/* must be before u_init() to avoid rndmonst()
				 * creating odd monsters for any tins and eggs
				 * in hero's initial inventory */
	init_artifacts();	/* before u_init() in case $WIZKIT specifies
				 * any artifacts */
	u_init();

#ifndef NO_SIGNAL
	(void) signal(SIGINT, (SIG_RET_TYPE) done1);
#endif
#ifdef NEWS
	if(iflags.news) display_file(NEWS, FALSE);
#endif
	load_qtlist();	/* load up the quest text info */
/*	quest_init();*/	/* Now part of role_init() */

	mklev();
	u_on_upstairs();
	vision_reset();		/* set up internals for level (after mklev) */
	check_special_room(FALSE);

	flags.botlx = 1;

	/* Move the monster from under you or else
	 * makedog() will fail when it calls makemon().
	 *			- ucsfcgl!kneller
	 */
	if(MON_AT(u.ux, u.uy)) mnexto(m_at(u.ux, u.uy));
	(void) makedog();
	docrt();

	if (flags.legacy) {
		flush_screen(1);
		com_pager(1);
	}

#ifdef INSURANCE
	save_currentstate();
#endif
	program_state.something_worth_saving++;	/* useful data now exists */

#if defined(RECORD_REALTIME) || defined(REALTIME_ON_BOTL)

        /* Start the timer here */
        realtime_data.realtime = (time_t)0L;

#if defined(BSD) && !defined(POSIX_TYPES)
        (void) time((long *)&realtime_data.restoretime);
#else
        (void) time(&realtime_data.restoretime);
#endif

#endif /* RECORD_REALTIME || REALTIME_ON_BOTL */

	/* Success! */
	welcome(TRUE);
	return;
}
Пример #13
0
int
main(int argc, char *argv[])
{
	int fd;
#ifdef CHDIR
	char *dir;
#endif

	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")))
			strncpy(plname, s, sizeof(plname) - 1);
		if (!*plname && (s = getenv("LOGNAME")))
			strncpy(plname, s, sizeof(plname) - 1);
		if (!*plname && (s = getlogin()))
			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);
	umask(007);
	setrandom();
	startup();
	cls();
	u.uhp = 1;		/* prevent RIP on early quits */
	u.ux = FAR;		/* prevent nscr() */
	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':
			wizard = TRUE;
			break;
#endif
#ifdef NEWS
		case 'n':
			flags.nonews = TRUE;
			break;
#endif
		case 'u':
			if (argv[0][2])
				strncpy(plname, argv[0] + 2, sizeof(plname) - 1);
			else if (argc > 1) {
				argc--;
				argv++;
				strncpy(plname, argv[0], sizeof(plname) - 1);
			} else
				printf("Player name expected after -u\n");
			break;
		default:
			/* allow -T for Tourist, etc. */
			strncpy(pl_character, argv[0] + 1,
			    sizeof(pl_character) - 1);
		}
	}

	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")) && !(catmore = getenv("PAGER")))
		catmore = DEF_PAGER;
#endif
#ifdef MAIL
	getmailstatus();
#endif
#ifdef WIZARD
	if (wizard)
		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)
		 */
		signal(SIGQUIT, SIG_IGN);
		signal(SIGINT, SIG_IGN);
		if (!locknum)
			strcpy(lock, plname);
		getlock();	/* sets lock if locknum != 0 */
#ifdef WIZARD
	} else {
		char *sfoo;
		strcpy(lock, plname);
		if ((sfoo = getenv("MAGIC")))
			while (*sfoo) {
				switch (*sfoo++) {
				case 'n':
					srandom(*sfoo++);
					break;
				}
			}
		if ((sfoo = getenv("GENOCIDED")) != NULL) {
			if (*sfoo == '!') {
				struct permonst *pm = mons;
				char *gp = genocided;

				while (pm < mons + CMNUM + 2) {
					if (!strchr(sfoo, pm->mlet))
						*gp++ = pm->mlet;
					pm++;
				}
				*gp = 0;
			} else
				strncpy(genocided, sfoo, sizeof(genocided) - 1);
			strcpy(fut_geno, genocided);
		}
	}
#endif
	setftty();
	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)) {
		signal(SIGINT, done1);
		pline("Restoring old save file...");
		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();

		signal(SIGINT, done1);
		mklev();
		u.ux = xupstair;
		u.uy = yupstair;
		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))
					makemon(NULL, 0, 0);
			}
			if (Glib)
				glibr();
			p_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)
				dosearch();
			gethungry();
			invault();
			amulet();
		}
		if (multi < 0) {
			if (!++multi) {
				pline("%s", nomovemsg ? nomovemsg :
				      "You can move again.");
				nomovemsg = 0;
				if (afternmv)
					(*afternmv)();
				afternmv = NULL;
			}
		}
		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 = NULL;
			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(NULL);
		}
		if (multi && multi % 7 == 0)
			fflush(stdout);
	}
}
Пример #14
0
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);
}
Пример #15
0
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(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)))
			(void) tamedog(mtmp, NULL);
		break;
	    }
	case SCR_GENOCIDE:
	    {	extern char genocided[], fut_geno[];
		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;
		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);
	}
Пример #16
0
void
goto_level(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[(int)dlevel])
		mklev();
	else {
		extern int hackpid;

		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[(int)u.ux][(int)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)))
		  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);
}
Пример #17
0
int
dorecover(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, &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, &flags, sizeof(struct flag));
	mread(fd, &dlevel, sizeof dlevel);
	mread(fd, &maxdlevel, sizeof maxdlevel);
	mread(fd, &moves, sizeof moves);
	mread(fd, &u, sizeof(struct you));
	if (u.ustuck)
		mread(fd, &mid, sizeof mid);
	mread(fd, pl_character, sizeof pl_character);
	mread(fd, genocided, sizeof genocided);
	mread(fd, fut_geno, sizeof fut_geno);
	restnames(fd);
	while (1) {
		if (read(fd, &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);
}