diff options
Diffstat (limited to 'hack/hack.lev.c')
-rw-r--r-- | hack/hack.lev.c | 276 |
1 files changed, 276 insertions, 0 deletions
diff --git a/hack/hack.lev.c b/hack/hack.lev.c new file mode 100644 index 0000000..d47b873 --- /dev/null +++ b/hack/hack.lev.c @@ -0,0 +1,276 @@ +/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ +/* hack.lev.c - version 1.0.3 */ +/* $FreeBSD: src/games/hack/hack.lev.c,v 1.4 1999/11/16 10:26:36 marcel Exp $ */ + +#include "hack.h" +extern struct obj *billobjs; +extern char SAVEF[]; +extern char nul[]; + +#ifndef NOWORM +extern struct wseg *wsegs[32], *wheads[32]; +extern long wgrowtime[32]; +#endif /* NOWORM */ + +boolean level_exists[MAXLEVEL+1]; + +static void savegoldchn(int, struct gold *); +static void savetrapchn(int, struct trap *); + +void +savelev(int fd, xchar lev) +{ +#ifndef NOWORM + struct wseg *wtmp, *wtmp2; + int tmp; +#endif /* NOWORM */ + + if (fd < 0) + panic("Save on bad file!"); /* impossible */ + if (lev >= 0 && lev <= MAXLEVEL) + level_exists[lev] = TRUE; + + bwrite(fd, (char *)&hackpid, sizeof(hackpid)); + bwrite(fd, (char *)&lev, sizeof(lev)); + bwrite(fd, (char *)levl, sizeof(levl)); + bwrite(fd, (char *)&moves, sizeof(long)); + bwrite(fd, (char *)&xupstair, sizeof(xupstair)); + bwrite(fd, (char *)&yupstair, sizeof(yupstair)); + bwrite(fd, (char *)&xdnstair, sizeof(xdnstair)); + bwrite(fd, (char *)&ydnstair, sizeof(ydnstair)); + savemonchn(fd, fmon); + savegoldchn(fd, fgold); + savetrapchn(fd, ftrap); + saveobjchn(fd, fobj); + saveobjchn(fd, billobjs); + billobjs = NULL; + save_engravings(fd); +#ifndef QUEST + bwrite(fd, (char *)rooms, sizeof(rooms)); + bwrite(fd, (char *)doors, sizeof(doors)); +#endif /* QUEST */ + fgold = 0; + ftrap = 0; + fmon = 0; + fobj = 0; +#ifndef NOWORM + bwrite(fd, (char *)wsegs, sizeof(wsegs)); + for (tmp = 1; tmp < 32; tmp++) { + for (wtmp = wsegs[tmp]; wtmp; wtmp = wtmp2) { + wtmp2 = wtmp->nseg; + bwrite(fd, (char *)wtmp, sizeof(struct wseg)); + } + wsegs[tmp] = NULL; + } + bwrite(fd, (char *)wgrowtime, sizeof(wgrowtime)); +#endif /* NOWORM */ +} + +void +bwrite(int fd, char *loc, unsigned int num) +{ + /* lint wants the 3rd arg of write to be an int; lint -p an unsigned */ + if (write(fd, loc, (int)num) != (int)num) + panic("cannot write %u bytes to file #%d", num, fd); +} + +void +saveobjchn(int fd, struct obj *otmp) +{ + struct obj *otmp2; + unsigned xl; + int minusone = -1; + + while (otmp) { + otmp2 = otmp->nobj; + xl = otmp->onamelth; + bwrite(fd, (char *)&xl, sizeof(int)); + bwrite(fd, (char *)otmp, xl + sizeof(struct obj)); + free(otmp); + otmp = otmp2; + } + bwrite(fd, (char *)&minusone, sizeof(int)); +} + +void +savemonchn(int fd, struct monst *mtmp) +{ + struct monst *mtmp2; + unsigned xl; + int minusone = -1; + struct permonst *monbegin = &mons[0]; + + bwrite(fd, (char *)&monbegin, sizeof(monbegin)); + + while (mtmp) { + mtmp2 = mtmp->nmon; + xl = mtmp->mxlth + mtmp->mnamelth; + bwrite(fd, (char *)&xl, sizeof(int)); + bwrite(fd, (char *)mtmp, xl + sizeof(struct monst)); + if (mtmp->minvent) + saveobjchn(fd, mtmp->minvent); + free(mtmp); + mtmp = mtmp2; + } + bwrite(fd, (char *)&minusone, sizeof(int)); +} + +static void +savegoldchn(int fd, struct gold *gold) +{ + struct gold *gold2; + + while (gold) { + gold2 = gold->ngold; + bwrite(fd, (char *)gold, sizeof(struct gold)); + free(gold); + gold = gold2; + } + bwrite(fd, nul, sizeof(struct gold)); +} + +static void +savetrapchn(int fd, struct trap *trap) +{ + struct trap *trap2; + + while (trap) { + trap2 = trap->ntrap; + bwrite(fd, (char *)trap, sizeof(struct trap)); + free(trap); + trap = trap2; + } + bwrite(fd, nul, sizeof(struct trap)); +} + +void +getlev(int fd, int pid, xchar lev) +{ + struct gold *gold; + struct trap *trap; +#ifndef NOWORM + struct wseg *wtmp; +#endif /* NOWORM */ + int tmp; + long omoves; + int hpid; + xchar dlvl; + + /* First some sanity checks */ + mread(fd, (char *)&hpid, sizeof(hpid)); + mread(fd, (char *)&dlvl, sizeof(dlvl)); + if ((pid && pid != hpid) || (lev && dlvl != lev)) { + pline("Strange, this map is not as I remember it."); + pline("Somebody is trying some trickery here ..."); + pline("This game is void ..."); + done("tricked"); + } + + fgold = 0; + ftrap = 0; + mread(fd, (char *)levl, sizeof(levl)); + mread(fd, (char *)&omoves, sizeof(omoves)); + mread(fd, (char *)&xupstair, sizeof(xupstair)); + mread(fd, (char *)&yupstair, sizeof(yupstair)); + mread(fd, (char *)&xdnstair, sizeof(xdnstair)); + mread(fd, (char *)&ydnstair, sizeof(ydnstair)); + + fmon = restmonchn(fd); + + /* regenerate animals while on another level */ + { + long tmoves = (moves > omoves) ? moves - omoves : 0; + struct monst *mtmp, *mtmp2; + + for (mtmp = fmon; mtmp; mtmp = mtmp2) { + long newhp; /* tmoves may be very large */ + + mtmp2 = mtmp->nmon; + if (strchr(genocided, mtmp->data->mlet)) { + mondead(mtmp); + continue; + } + + if (mtmp->mtame && tmoves > 250) { + mtmp->mtame = 0; + mtmp->mpeaceful = 0; + } + + newhp = mtmp->mhp + + (strchr(MREGEN, mtmp->data->mlet) ? tmoves : tmoves / 20); + if (newhp > mtmp->mhpmax) + mtmp->mhp = mtmp->mhpmax; + else + mtmp->mhp = newhp; + } + } + + setgd(); + gold = newgold(); + mread(fd, (char *)gold, sizeof(struct gold)); + while (gold->gx) { + gold->ngold = fgold; + fgold = gold; + gold = newgold(); + mread(fd, (char *)gold, sizeof(struct gold)); + } + free(gold); + trap = newtrap(); + mread(fd, (char *)trap, sizeof(struct trap)); + while (trap->tx) { + trap->ntrap = ftrap; + ftrap = trap; + trap = newtrap(); + mread(fd, (char *)trap, sizeof(struct trap)); + } + free(trap); + fobj = restobjchn(fd); + billobjs = restobjchn(fd); + rest_engravings(fd); +#ifndef QUEST + mread(fd, (char *)rooms, sizeof(rooms)); + mread(fd, (char *)doors, sizeof(doors)); +#endif /* QUEST */ +#ifndef NOWORM + mread(fd, (char *)wsegs, sizeof(wsegs)); + for (tmp = 1; tmp < 32; tmp++) + if (wsegs[tmp]) { + wheads[tmp] = wsegs[tmp] = wtmp = newseg(); + for (;;) { + mread(fd, (char *)wtmp, sizeof(struct wseg)); + if (!wtmp->nseg) + break; + wheads[tmp]->nseg = wtmp = newseg(); + wheads[tmp] = wtmp; + } + } + mread(fd, (char *)wgrowtime, sizeof(wgrowtime)); +#endif /* NOWORM */ +} + +void +mread(int fd, char *buf, unsigned int len) +{ + int rlen; + + rlen = read(fd, buf, (int)len); + if (rlen != (int)len) { + pline("Read %d instead of %u bytes.\n", rlen, len); + if (restoring) { + unlink(SAVEF); + error("Error restoring old game."); + } + panic("Error reading level file."); + } +} + +void +mklev(void) +{ + if (getbones()) + return; + + in_mklev = TRUE; + makelevel(); + in_mklev = FALSE; +} |