void keepdogs() { struct monst *mtmp; for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) if(dist(mtmp->mx,mtmp->my) < 3 && follower(mtmp) && !mtmp->msleep && !mtmp->mfroz) { relmon(mtmp); mtmp->nmon = mydogs; mydogs = mtmp; unpmon(mtmp); keepdogs(); /* we destroyed the link, so use recursion */ return; /* (admittedly somewhat primitive) */ } }
/* Be careful not to call panic from here! */ void done(const char *st1) { #ifdef WIZARD if(wizard && *st1 == 'd'){ u.uswldtim = 0; if(u.uhpmax < 0) u.uhpmax = 100; /* arbitrary */ u.uhp = u.uhpmax; pline("For some reason you are still alive."); flags.move = 0; if(multi > 0) multi = 0; else multi = -1; flags.botl = 1; return; } #endif /* WIZARD */ signal(SIGINT, done_intr); signal(SIGQUIT, done_intr); signal(SIGHUP, done_hangup); if(*st1 == 'q' && u.uhp < 1){ st1 = "died"; killer = "quit while already on Charon's boat"; } if(*st1 == 's') killer = "starvation"; else if(*st1 == 'd' && st1[1] == 'r') killer = "drowning"; else if(*st1 == 'p') killer = "panic"; else if(*st1 == 't') killer = "trickery"; else if(!index("bcd", *st1)) killer = st1; paybill(); clearlocks(); if(flags.toplin == 1) more(); if(index("bcds", *st1)){ #ifdef WIZARD if(!wizard) #endif /* WIZARD */ savebones(); if(!flags.notombstone) outrip(); } if(*st1 == 'c') killer = st1; /* after outrip() */ settty(NULL); /* does a clear_screen() */ if(!done_stopprint) printf("Goodbye %s %s...\n\n", pl_character, plname); { long int tmp; tmp = u.ugold - u.ugold0; if(tmp < 0) tmp = 0; if(*st1 == 'd' || *st1 == 'b') tmp -= tmp/10; u.urexp += tmp; u.urexp += 50 * maxdlevel; if(maxdlevel > 20) u.urexp += 1000*((maxdlevel > 30) ? 10 : maxdlevel - 20); } if(*st1 == 'e') { struct monst *mtmp; struct obj *otmp; int i; unsigned worthlessct = 0; boolean has_amulet = FALSE; killer = st1; keepdogs(); mtmp = mydogs; if(mtmp) { if(!done_stopprint) printf("You"); while(mtmp) { if(!done_stopprint) printf(" and %s", monnam(mtmp)); if(mtmp->mtame) u.urexp += mtmp->mhp; mtmp = mtmp->nmon; } if(!done_stopprint) printf("\nescaped from the dungeon with %ld points,\n", u.urexp); } else if(!done_stopprint) printf("You escaped from the dungeon with %ld points,\n", u.urexp); for(otmp = invent; otmp; otmp = otmp->nobj) { if(otmp->olet == GEM_SYM){ i = otmp->quan*objects[otmp->otyp].g_val; if(i == 0) { worthlessct += otmp->quan; continue; } u.urexp += i; if(!done_stopprint) printf("\t%s (worth %d Zorkmids),\n", doname(otmp), i); } else if(otmp->olet == AMULET_SYM) { i = (otmp->spe < 0) ? 2 : 5000; u.urexp += i; if(!done_stopprint) printf("\t%s (worth %d Zorkmids),\n", doname(otmp), i); if(otmp->spe >= 0) { has_amulet = TRUE; killer = "escaped (with amulet)"; } } } if(worthlessct) if(!done_stopprint) printf("\t%u worthless piece%s of coloured glass,\n", worthlessct, plur(worthlessct)); if(has_amulet) u.urexp *= 2; } else if(!done_stopprint) printf("You %s on dungeon level %d with %ld points,\n", st1, dlevel, u.urexp); if(!done_stopprint) printf("and %ld piece%s of gold, after %ld move%s.\n", u.ugold, plur(u.ugold), moves, plur(moves)); if(!done_stopprint) printf("You were level %u with a maximum of %d hit points when you %s.\n", u.ulevel, u.uhpmax, st1); if(*st1 == 'e' && !done_stopprint){ getret(); /* all those pieces of coloured glass ... */ cls(); } #ifdef WIZARD if(!wizard) #endif /* WIZARD */ topten(); if(done_stopprint) printf("\n\n"); exit(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); }