Пример #1
0
static void teleds(Short nux, Short nuy)
{
  if (Punished) unplacebc();
  unsee();
  you.utrap = 0;
  you.ustuck = 0;
  you.ux = nux;
  you.uy = nuy;
  setsee();
  if (Punished) placebc(true);
  if (you.uswallow) {
    you.uswallowedtime = you.uswallow = 0;
    //    refresh(); //docrt();
  }
  move_visible_window(you.ux, you.uy, true);
  refresh();
  nomul(0);
  if (get_cell_type(floor_info[nux][nuy]) == POOL && !Levitation)
    drown();
  inshop();
  pickup(true);
  if (!Blind) read_engr_at(you.ux,you.uy);
}
Пример #2
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);
}
Пример #3
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);
	}
}