Esempio n. 1
0
/* returns 1 if save successful */
static int
dosave0(int hu)
{
	int		fd, ofd;
	int             tmp;	/* not ! */

	(void) signal(SIGHUP, SIG_IGN);
	(void) signal(SIGINT, SIG_IGN);
	if ((fd = creat(SAVEF, FMASK)) < 0) {
		if (!hu)
			pline("Cannot open save file. (Continue or Quit)");
		(void) unlink(SAVEF);	/* ab@unido */
		return (0);
	}
	if (flags.moonphase == FULL_MOON)	/* ut-sally!fletcher */
		u.uluck--;	/* and unido!ab */
	savelev(fd, dlevel);
	saveobjchn(fd, invent);
	saveobjchn(fd, fcobj);
	savemonchn(fd, fallen_down);
	tmp = getuid();
	bwrite(fd, &tmp, sizeof tmp);
	bwrite(fd, &flags, sizeof(struct flag));
	bwrite(fd, &dlevel, sizeof dlevel);
	bwrite(fd, &maxdlevel, sizeof maxdlevel);
	bwrite(fd, &moves, sizeof moves);
	bwrite(fd, &u, sizeof(struct you));
	if (u.ustuck)
		bwrite(fd, &(u.ustuck->m_id), sizeof u.ustuck->m_id);
	bwrite(fd, pl_character, sizeof pl_character);
	bwrite(fd, genocided, sizeof genocided);
	bwrite(fd, fut_geno, sizeof fut_geno);
	savenames(fd);
	for (tmp = 1; tmp <= maxdlevel; tmp++) {

		if (tmp == dlevel || !level_exists[tmp])
			continue;
		glo(tmp);
		if ((ofd = open(lock, O_RDONLY)) < 0) {
			if (!hu)
				pline("Error while saving: cannot read %s.", lock);
			(void) close(fd);
			(void) unlink(SAVEF);
			if (!hu)
				done("tricked");
			return (0);
		}
		getlev(ofd, hackpid, tmp);
		(void) close(ofd);
		bwrite(fd, &tmp, sizeof tmp);	/* level number */
		savelev(fd, tmp);	/* actual level */
		(void) unlink(lock);
	}
	(void) close(fd);
	glo(dlevel);
	(void) unlink(lock);	/* get rid of current level --jgm */
	glo(0);
	(void) unlink(lock);
	return (1);
}
Esempio n. 2
0
// returns 1 if save successful
bool dosave0 (bool failok)
{
    // Create the saved game directory first, if absent
    const char* homedir = getenv ("HOME");
    if (!homedir)
	return false;
    char savefile [PATH_MAX];
    snprintf (ArrayBlock(savefile), _PATH_SAVED_GAMES, homedir);
    if (0 != access (savefile, R_OK))
	mkpath (savefile, S_IRWXU);
    snprintf (ArrayBlock(savefile), HACK_SAVEFILE, homedir);

    int fd = creat (savefile, S_IRUSR| S_IWUSR);
    if (fd < 0) {
	if (failok)
	    pline("Cannot save game: %s (Continue or Quit)", strerror(errno));
	return false;
    }
    bwrite (fd, &_u, sizeof(struct you));
    saveobjchn (fd, invent);
    saveobjchn (fd, fcobj);
    savemonchn (fd, fallen_down);
    bwrite (fd, &_wflags, sizeof(struct worldflag));
    bwrite (fd, pl_character, sizeof pl_character);
    savenames (fd);
    savegenocided (fd);
    for (unsigned i = 0; i < _u.maxdlevel; ++i)
	savelev (fd, &_levels[i]);
    close (fd);
    return true;
}
Esempio n. 3
0
File: save.c Progetto: mbi/NitroHack
void savegame(struct memfile *mf)
{
	int count = 0;
	xchar ltmp;
	
	store_version(mf);
	
	/* Place flags, player info & moves at the beginning of the save.
	 * This makes it possible to read them in nh_get_savegame_status without
	 * parsing all the dungeon and level data */
	save_flags(mf);
	save_you(mf, &u);
	mwrite32(mf, moves);
	save_mon(mf, &youmonst);
	
	/* store dungeon layout */
	save_dungeon(mf);
	savelevchn(mf);
	
	/* store levels */
	for (ltmp = 1; ltmp <= maxledgerno(); ltmp++)
	    if (levels[ltmp])
		count++;
	mwrite32(mf, count);
	for (ltmp = 1; ltmp <= maxledgerno(); ltmp++) {
		if (!levels[ltmp])
		    continue;
		mwrite8(mf, ltmp); /* level number*/
		savelev(mf, ltmp); /* actual level*/
	}
	savegamestate(mf);
}
Esempio n. 4
0
/* save bones and possessions of a deceased adventurer */
void
savebones()
{
	int fd;
	struct obj *otmp;
	struct trap *ttmp;
	struct monst *mtmp;

	if(dlevel <= 0 || dlevel > MAXLEVEL) return;
	if(!rn2(1 + dlevel/2)) return;	/* not so many ghosts on low levels */
	bones[6] = '0' + (dlevel/10);
	bones[7] = '0' + (dlevel%10);
	if((fd = open(bones, O_RDONLY)) >= 0){
		(void) close(fd);
		return;
	}
	/* drop everything; the corpse's possessions are usually cursed */
	otmp = invent;
	while(otmp){
		otmp->ox = u.ux;
		otmp->oy = u.uy;
		otmp->age = 0;		/* very long ago */
		otmp->owornmask = 0;
		if(rn2(5)) otmp->cursed = 1;
		if(!otmp->nobj){
			otmp->nobj = fobj;
			fobj = invent;
			invent = 0;	/* superfluous */
			break;
		}
		otmp = otmp->nobj;
	}
	if(!(mtmp = makemon(PM_GHOST, u.ux, u.uy))) return;
	mtmp->mx = u.ux;
	mtmp->my = u.uy;
	mtmp->msleep = 1;
	(void) strlcpy((char *) mtmp->mextra, plname, mtmp->mxlth);
	mkgold(somegold() + d(dlevel,30), u.ux, u.uy);
	for(mtmp = fmon; mtmp; mtmp = mtmp->nmon){
		mtmp->m_id = 0;
		if(mtmp->mtame) {
			mtmp->mtame = 0;
			mtmp->mpeaceful = 0;
		}
		mtmp->mlstmv = 0;
		if(mtmp->mdispl) unpmon(mtmp);
	}
	for(ttmp = ftrap; ttmp; ttmp = ttmp->ntrap)
		ttmp->tseen = 0;
	for(otmp = fobj; otmp; otmp = otmp->nobj) {
		otmp->o_id = 0;
	     /* otmp->o_cnt_id = 0; - superfluous */
		otmp->onamelth = 0;
		otmp->known = 0;
		otmp->invlet = 0;
		if(otmp->olet == AMULET_SYM && !otmp->spe) {
			otmp->spe = -1;      /* no longer the actual amulet */
			otmp->cursed = 1;    /* flag as gotten from a ghost */
		}
	}
	if((fd = open(bones, O_CREAT | O_TRUNC | O_WRONLY, FMASK)) < 0) return;
	savelev(fd,dlevel);
	(void) close(fd);
}
Esempio n. 5
0
int
dosave()
{
#ifdef KEEP_SAVE
	/*WAC for reloading*/
	register int fd;
#endif

	clear_nhwindow(WIN_MESSAGE);
	if(yn("Really save?") == 'n') {
		clear_nhwindow(WIN_MESSAGE);
		if(multi > 0) nomul(0);
	} else {
		clear_nhwindow(WIN_MESSAGE);
		pline("Saving...");
#if defined(UNIX) || defined(VMS) || defined(__EMX__)
		program_state.done_hup = 0;
#endif
#ifdef KEEP_SAVE
                saverestore = FALSE;
                if (flags.keep_savefile)
                        if(yn("Really quit?") == 'n') saverestore = TRUE;
                if(dosave0() && !saverestore) {
#else
		if(dosave0()) {
#endif
			program_state.something_worth_saving = 0;
			u.uhp = -1;		/* universal game's over indicator */
			/* make sure they see the Saving message */
			display_nhwindow(WIN_MESSAGE, TRUE);
			exit_nhwindows("Be seeing you...");
			terminate(EXIT_SUCCESS);
	}
/*WAC redraw later
		else (void)doredraw();*/
	}
#ifdef KEEP_SAVE
	if (saverestore) {
/*WAC pulled this from pcmain.c - restore game from the file just saved*/
		fd = create_levelfile(0);
		if (fd < 0) {
			raw_print("Cannot create lock file");
		} else {
			hackpid = 1;
			write(fd, (genericptr_t) &hackpid, sizeof(hackpid));
			close(fd);
		}
#ifdef MFLOPPY
		level_info[0].where = ACTIVE;
#endif

		fd = restore_saved_game();
		if (fd >= 0) dorecover(fd);
		check_special_room(FALSE);
		flags.move = 0;
/*WAC correct these after restore*/
		if(flags.moonphase == FULL_MOON)
			change_luck(1);         
		if(flags.friday13)
			change_luck(-1);
		if(iflags.window_inited)
			clear_nhwindow(WIN_MESSAGE);
	}
	saverestore = FALSE;
#endif
	(void)doredraw();
	return 0;
}


#if defined(UNIX) || defined(VMS) || defined (__EMX__) || defined(WIN32)
/*ARGSUSED*/
void
hangup(sig_unused)  /* called as signal() handler, so sent at least one arg */
int sig_unused;
{
# ifdef NOSAVEONHANGUP
	(void) signal(SIGINT, SIG_IGN);
	clearlocks();
#  ifndef VMS
	terminate(EXIT_FAILURE);
#  endif
# else	/* SAVEONHANGUP */
	if (!program_state.done_hup++) {
	    if (program_state.something_worth_saving)
		(void) dosave0();
#  ifdef VMS
	    /* don't call exit when already within an exit handler;
	       that would cancel any other pending user-mode handlers */
	    if (!program_state.exiting)
#  endif
	    {
		clearlocks();
		terminate(EXIT_FAILURE);
	    }
	}
# endif
	return;
}
#endif

/* returns 1 if save successful */
int
dosave0()
{
	const char *fq_save;
	register int fd, ofd;
	xchar ltmp;
	d_level uz_save;
	char whynot[BUFSZ];

	if (!SAVEF[0])
		return 0;
	fq_save = fqname(SAVEF, SAVEPREFIX, 1);	/* level files take 0 */

#if defined(UNIX) || defined(VMS)
	(void) signal(SIGHUP, SIG_IGN);
#endif
#ifndef NO_SIGNAL
	(void) signal(SIGINT, SIG_IGN);
#endif

#if defined(MICRO) && defined(MFLOPPY)
	if (!saveDiskPrompt(0)) return 0;
#endif

	HUP if (iflags.window_inited) {
	    uncompress_area(fq_save, SAVEF);
	    fd = open_savefile();
	    if (fd > 0) {
		(void) close(fd);
		clear_nhwindow(WIN_MESSAGE);
		There("seems to be an old save file.");
		if (yn("Overwrite the old file?") == 'n') {
		    compress_area(fq_save, SAVEF);
#ifdef KEEP_SAVE
/*WAC don't restore if you didn't save*/
			saverestore = FALSE;
#endif
		    return 0;
		}
	    }
	}

	HUP mark_synch();	/* flush any buffered screen output */

	fd = create_savefile();
	if(fd < 0) {
		HUP pline("Cannot open save file.");
		(void) delete_savefile();	/* ab@unido */
		return(0);
	}

	vision_recalc(2);	/* shut down vision to prevent problems
				   in the event of an impossible() call */
	
	/* undo date-dependent luck adjustments made at startup time */
	if(flags.moonphase == FULL_MOON)	/* ut-sally!fletcher */
		change_luck(-1);		/* and unido!ab */
	if(flags.friday13)
		change_luck(1);
	if(iflags.window_inited)
	    HUP clear_nhwindow(WIN_MESSAGE);

#if defined(MICRO) && defined(TTY_GRAPHICS)
	if (!strncmpi("tty", windowprocs.name, 3)) {
	dotcnt = 0;
	dotrow = 2;
	curs(WIN_MAP, 1, 1);
	  putstr(WIN_MAP, 0, "Saving:");
	}
#endif
#ifdef MFLOPPY
	/* make sure there is enough disk space */
	if (iflags.checkspace) {
	    long fds, needed;

	    savelev(fd, ledger_no(&u.uz), COUNT_SAVE);
	    savegamestate(fd, COUNT_SAVE);
	    needed = bytes_counted;

	    for (ltmp = 1; ltmp <= maxledgerno(); ltmp++)
		if (ltmp != ledger_no(&u.uz) && level_info[ltmp].where)
		    needed += level_info[ltmp].size + (sizeof ltmp);
	    fds = freediskspace(fq_save);
	    if (needed > fds) {
		HUP {
		    There("is insufficient space on SAVE disk.");
		    pline("Require %ld bytes but only have %ld.", needed, fds);
		}
		flushout();
		(void) close(fd);
		(void) delete_savefile();
		return 0;
	    }

	    co_false();
	}
Esempio n. 6
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);
}
Esempio n. 7
0
/* returns 1 if save successful */
int
dosave0(void)
{
    const char *fq_save;
    register int fd, ofd;
    xchar ltmp;
    d_level uz_save;
    char whynot[BUFSZ];

#ifdef WHEREIS_FILE
    delete_whereis();
#endif

    if (!SAVEF[0])
        return 0;
    fq_save = fqname(SAVEF, SAVEPREFIX, 1);	/* level files take 0 */

#if defined(UNIX) || defined(VMS)
    (void) signal(SIGHUP, SIG_IGN);
#endif
#ifndef NO_SIGNAL
    (void) signal(SIGINT, SIG_IGN);
#endif

#if defined(MICRO) && defined(MFLOPPY)
    if (!saveDiskPrompt(0)) return 0;
#endif

    HUP if (iflags.window_inited) {
        uncompress_area(fq_save, SAVEF);
        fd = open_savefile();
        if (fd > 0) {
            (void) close(fd);
            clear_nhwindow(WIN_MESSAGE);
            There("seems to be an old save file.");
            if (yn("Overwrite the old file?") == 'n') {
                compress_area(fq_save, SAVEF);
                return 0;
            }
        }
    }

    HUP mark_synch();	/* flush any buffered screen output */

    fd = create_savefile();
    if(fd < 0) {
        HUP pline("Cannot open save file.");
        (void) delete_savefile();	/* ab@unido */
        return(0);
    }

    vision_recalc(2);	/* shut down vision to prevent problems
				   in the event of an impossible() call */

    /* undo date-dependent luck adjustments made at startup time */
    if(flags.moonphase == FULL_MOON)	/* ut-sally!fletcher */
        change_luck(-1);		/* and unido!ab */
    if(flags.friday13)
        change_luck(1);
    if(iflags.window_inited)
        HUP clear_nhwindow(WIN_MESSAGE);

#ifdef MICRO
    dotcnt = 0;
    dotrow = 2;
    curs(WIN_MAP, 1, 1);
    if (strncmpi("X11", windowprocs.name, 3))
        putstr(WIN_MAP, 0, "Saving:");
#endif
#ifdef MFLOPPY
    /* make sure there is enough disk space */
    if (iflags.checkspace) {
        long fds, needed;

        savelev(fd, ledger_no(&u.uz), COUNT_SAVE);
        savegamestate(fd, COUNT_SAVE);
        needed = bytes_counted;

        for (ltmp = 1; ltmp <= maxledgerno(); ltmp++)
            if (ltmp != ledger_no(&u.uz) && level_info[ltmp].where)
                needed += level_info[ltmp].size + (sizeof ltmp);
        fds = freediskspace(fq_save);
        if (needed > fds) {
            HUP {
                There("is insufficient space on SAVE disk.");
                pline("Require %ld bytes but only have %ld.", needed, fds);
            }
            flushout();
            (void) close(fd);
            (void) delete_savefile();
            return 0;
        }
Esempio n. 8
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);
}