This is end.c in view mode; [Download] [Up]
/* SCCS Id: @(#)end.c 3.0 88/05/03 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ /* Changed for graphical version of NetHack on NextStep */ /* by Christoph Marquardt 9/4/93 */ #define MONATTK_H /* comment line for pre-compiled headers */ #define NEED_VARARGS /* comment line for pre-compiled headers */ /* block some unused #defines to avoid overloading some cpp's */ #include "hack.h" #ifndef NO_SIGNAL #include <signal.h> #endif #include "eshk.h" void NDECL(end_box_display); static int NDECL(done_intr); static const char *deaths[] = { /* the array of death */ "died", "choked", "poisoned", "starvation", "drowning", "burning", "crushed", "turned to stone", "genocided", "panic", "trickery", "quit", "escaped", "ascended" }; static const char *ends[] = { /* "when you..." */ "died", "choked", "were poisoned", "starved", "drowned", "burned", "were crushed", "turned to stone", "were genocided", "panicked", "were tricked", "quit", "escaped", "ascended" }; int done1() { #ifndef NO_SIGNAL (void) signal(SIGINT,SIG_IGN); #endif if(flags.ignintr) { #ifndef NO_SIGNAL (void) signal(SIGINT, (SIG_RET_TYPE) done1); #endif clrlin(); curs_on_u(); (void) fflush(stdout); if(multi > 0) nomul(0); return 0; } return done2(); } int done2() { #ifdef MACOS if(!flags.silent) SysBeep(1); if(UseMacAlert(128) != 1) { #else pline("Really quit? "); if(yn() == 'n') { #endif #ifndef NO_SIGNAL (void) signal(SIGINT, (SIG_RET_TYPE) done1); #endif clrlin(); curs_on_u(); (void) fflush(stdout); if(multi > 0) nomul(0); multi = 0; return 0; } #if defined(WIZARD) && (defined(UNIX) || defined(VMS) || defined(LATTICE)) if(wizard) { # ifdef VMS pline("Enter debugger? "); # else # ifdef LATTICE pline("Create SnapShot? "); # else pline("Dump core? "); # endif # endif /* KL - do I need to change the next 3 lines? */ if(yn() == 'y') { (void) signal(SIGINT, (SIG_RET_TYPE) done1); settty(NULL); #ifdef AMIGA Abort(0); #else # ifdef SYSV (void) # endif abort(); #endif } } #endif #ifndef LINT done(QUIT); #endif return 0; } static int done_intr(){ done_stopprint++; #ifndef NO_SIGNAL (void) signal(SIGINT, SIG_IGN); # if defined(UNIX) || defined(VMS) (void) signal(SIGQUIT, SIG_IGN); # endif #endif /* NO_SIGNAL /* */ return 0; } #if defined(UNIX) || defined(VMS) static int done_hangup(){ done_hup++; (void)signal(SIGHUP, SIG_IGN); (void)done_intr(); return 0; } #endif void done_in_by(mtmp) register struct monst *mtmp; { char buf[BUFSZ]; You("die..."); buf[0] = '\0'; if (mtmp->iswiz) { Strcat(buf, "the "); killer_format = KILLED_BY; } if (mtmp->minvis) Strcat(buf, "invisible "); if (Hallucination) Strcat(buf, "hallucinogen-distorted "); if(mtmp->data->mlet == S_GHOST) { register char *gn = (char *) mtmp->mextra; if (!Hallucination && !mtmp->minvis && *gn) { Strcat(buf, "the "); killer_format = KILLED_BY; } Sprintf(eos(buf), (*gn ? "ghost of %s" : "ghost%s"), gn); } else if(mtmp->isshk) { Sprintf(eos(buf), "%s %s, the shopkeeper", (ESHK(mtmp)->ismale ? "Mr." : "Ms."), shkname(mtmp)); killer_format = KILLED_BY; } else Strcat(buf, mtmp->data->mname); if (mtmp->mnamelth) Sprintf(eos(buf), " called %s", NAME(mtmp)); killer = buf; if (mtmp->data->mlet == S_WRAITH) u.ugrave_arise = PM_WRAITH; else if (mtmp->data->mlet == S_MUMMY) u.ugrave_arise = (pl_character[0]=='E') ? PM_ELF_MUMMY : PM_HUMAN_MUMMY; else if (mtmp->data->mlet == S_VAMPIRE) u.ugrave_arise = PM_VAMPIRE; if (u.ugrave_arise > -1 && (mons[u.ugrave_arise].geno & G_GENOD)) u.ugrave_arise = -1; if (mtmp->data->mlet == S_COCKATRICE) done(STONING); else done(DIED); return; } /*VARARGS1*/ boolean panicking; extern boolean hu; /* from save.c */ void panic VA_DECL(const char *, str) VA_START(str); VA_INIT(str, char *); if(panicking++) #ifdef AMIGA Abort(0); #else # ifdef SYSV (void) # endif abort(); /* avoid loops - this should never happen*/ /* was exit(1) */ #endif home(); cls(); (void) puts(" Suddenly, the dungeon collapses."); #if defined(WIZARD) && !defined(MSDOS) if(!wizard) { pline("Report error to %s and it may be possible to rebuild.",WIZARD); more(); } #ifdef VMS { char *sem = rindex(SAVEF, ';'); if (sem) *sem = '\0'; } Strcat(SAVEF, ".e;1"); #else Strcat(SAVEF, ".e"); #endif hu = FALSE; (void) dosave0(); #endif #ifdef MACOS puts(" ERROR: "); #else (void) fputs(" ERROR: ", stdout); #endif #ifdef LATTICE { char pbuf[100]; vsprintf(pbuf,str,VA_ARGS); (void)puts(pbuf); } #else Vprintf(str,VA_ARGS); #endif more(); /* contains a fflush() */ #if defined(WIZARD) && (defined(UNIX) || defined(VMS) || defined(LATTICE)) if (wizard) # ifdef AMIGA Abort(0); # else # ifdef SYSV (void) # endif abort(); /* generate core dump */ # endif #endif VA_END(); done(PANICKED); } /* Be careful not to call panic from here! */ void done(how) int how; { #ifdef MACOS int see_c; char mac_buf[80]; #endif struct permonst *upmon; char kilbuf[BUFSZ], buf2[BUFSZ]; /* kilbuf: used to copy killer in case it comes from something like * xname(), which would otherwise get overwritten when we call * xname() when listing possessions * buf2: same as player name, except it is capitalized */ char c; boolean taken; #ifdef ENDGAME if (how == ASCENDED) killer_format = NO_KILLER_PREFIX; #endif /* Avoid killed by "a" burning or "a" starvation */ if (!killer && (how == STARVING || how == BURNING)) killer_format = KILLED_BY; Strcpy(kilbuf, (!killer || how >= PANICKED ? deaths[how] : killer)); killer = kilbuf; #ifdef WIZARD if (wizard && how == TRICKED) { You("are a very tricky wizard, it seems."); return; } #endif if(Lifesaved && how <= GENOCIDED) { u.uswldtim = 0; if(u.uhpmax < 0) u.uhpmax = 10; /* arbitrary */ u.uhp = u.uhpmax; adjattrib(A_CON, -1, TRUE); pline("But wait..."); makeknown(AMULET_OF_LIFE_SAVING); Your("medallion %s!", !Blind ? "begins to glow" : "feels warm"); You("feel much better!"); pline("The medallion crumbles to dust!"); useup(uamul); if (u.uhunger < 500) u.uhunger = 500; nomovemsg = "You survived that attempt on your life."; curs_on_u(); flags.move = 0; if(multi > 0) multi = 0; else multi = -1; flags.botl = 1; u.ugrave_arise = -1; if (how == GENOCIDED) pline("Unfortunately you are still genocided..."); else { killer = 0; return; } } #if defined(WIZARD) || defined(EXPLORE_MODE) if((wizard || discover) && how <= GENOCIDED) { pline("Die? "); if(yn() == 'y') goto die; u.uswldtim = 0; if(u.uhpmax < 0) u.uhpmax = 100; /* arbitrary */ u.uhp = u.uhpmax; if (u.uhunger < 500) u.uhunger = 500; pline("Ok, so you don't die."); nomovemsg = "You survived that attempt on your life."; curs_on_u(); flags.move = 0; if(multi > 0) multi = 0; else multi = -1; flags.botl = 1; u.ugrave_arise = -1; killer = 0; return; } #endif /* WIZARD || EXPLORE_MODE */ die: #ifndef NO_SIGNAL (void) signal(SIGINT, (SIG_RET_TYPE) done_intr); # if defined(UNIX) || defined(VMS) (void) signal(SIGQUIT, (SIG_RET_TYPE) done_intr); (void) signal(SIGHUP, (SIG_RET_TYPE) done_hangup); # endif #endif /* NO_SIGNAL /* */ upmon = player_mon(); if(u.ugrave_arise > -1) /* create no corpse */ ; else if(how == STONED) (mk_named_object(STATUE, upmon, u.ux, u.uy, plname, strlen(plname)))->spe = 0; /* * If you're burned to a crisp, why leave a corpse? */ else if (how != BURNING) (void) mk_named_object(CORPSE, upmon, u.ux, u.uy, plname, strlen(plname)); if (how == QUIT) { killer_format = NO_KILLER_PREFIX; if (u.uhp < 1) { how = DIED; /* note that killer is pointing at kilbuf */ Strcpy(kilbuf, "quit while already on Charon's boat"); } } if (how == ESCAPED) killer_format = NO_KILLER_PREFIX; taken = paybill(); paygd(); clearlocks(); if(flags.toplin == 1) more(); if(invent) { #ifndef MACOS if(taken) pline("Do you want to see what you had when you %s? ", (how == QUIT) ? "quit" : "died"); else pline("Do you want your possessions identified? "); if ((c = yn_function(ynqchars,'y')) == 'y') { #else { extern short macflags; /* stop user from using menus, etc. */ macflags &= ~(fDoNonKeyEvt | fDoUpdate); } if(taken) sprintf(mac_buf, "Do you want to see what you had when you %s? ", (how == QUIT) ? "quit" : "died"); else sprintf(mac_buf, "Do you want your possessions identified? "); if(!flags.silent) SysBeep(1); if ((c = "qqynq"[UseMacAlertText(129,mac_buf)+1]) == 'y') { #endif /* New dump format by maartenj@cs.vu.nl */ struct obj *obj; for(obj = invent; obj && !done_stopprint; obj = obj->nobj) { makeknown(obj->otyp); obj->known = obj->bknown = obj->dknown = 1; } doinv(NULL); end_box_display(); } if (c == 'q') done_stopprint++; if (taken) { /* paybill has already given the inventory locations in the shop * and put it on the main object list */ struct obj *obj; for(obj = invent; obj; obj = obj->nobj) { obj->owornmask = 0; if(rn2(5)) curse(obj); } invent = (struct obj *) 0; } } if (!done_stopprint) { #ifdef MACOS c = "qqynq"[UseMacAlertText(129, "Do you want to see your instrinsics ?")+1]; #else pline("Do you want to see your intrinsics? "); c = yn_function(ynqchars, 'y'); #endif if (c == 'y') enlightenment(); if (c == 'q') done_stopprint++; } if(how < GENOCIDED) { #ifdef WIZARD if(wizard) { #ifdef MACOS if(!flags.silent) SysBeep(20); if(UseMacAlertText(128, "Save bones ?") == 1) savebones(); #else pline("Save bones? "); if(yn() == 'y') savebones(); #endif } else #endif if (how != PANICKED && how !=TRICKED) savebones(); if(!flags.notombstone) outrip(); } /* changing kilbuf really changes killer. we do it this way because killer is declared a (const char *) */ if(u.uhave_amulet) Strcat(kilbuf, " (with the Amulet)"); settty(NULL); /* does a clear_screen() */ Strcpy(buf2, plname); if('a' <= buf2[0] && buf2[0] <= 'z') buf2[0] += 'A'-'a'; if(!done_stopprint) Printf("Goodbye %s the %s...\n\n", buf2, #ifdef ENDGAME how != ASCENDED ? (const char *)pl_character : flags.female ? (const char *)"Demigoddess" : (const char *)"Demigod"); #else pl_character); #endif { long int tmp; tmp = u.ugold - u.ugold0; if(tmp < 0) tmp = 0; if(how < PANICKED) tmp -= tmp/10; u.urexp += tmp; u.urexp += 50 * maxdlevel; if(maxdlevel > 20) u.urexp += 1000*((maxdlevel > 30) ? 10 : maxdlevel - 20); #ifdef ENDGAME if(how == ASCENDED) u.urexp *= 2; #endif } if(how == ESCAPED #ifdef ENDGAME || how == ASCENDED #endif ) { register struct monst *mtmp; register struct obj *otmp; long i; register unsigned int worthlessct = 0; keepdogs(); mtmp = mydogs; if(mtmp) { if(!done_stopprint) Printf("You"); while(mtmp) { if(!done_stopprint) Printf(" and %s", mon_nam(mtmp)); if(mtmp->mtame) u.urexp += mtmp->mhp; mtmp = mtmp->nmon; } if(!done_stopprint) #ifdef ENDGAME Printf("\n%s with %ld points,\n", how==ASCENDED ? "went to your reward" : "escaped from the dungeon", #else Printf("\nescaped from the dungeon with %ld points,\n", #endif u.urexp); } else if(!done_stopprint) #ifdef ENDGAME Printf("You %s with %ld points,\n", how==ASCENDED ? "went to your reward" : "escaped from the dungeon", #else Printf("You escaped from the dungeon with %ld points,\n", #endif u.urexp); get_all_from_box(); /* don't forget things in boxes and bags */ for(otmp = invent; otmp; otmp = otmp->nobj) { if(otmp->olet == GEM_SYM && otmp->otyp < LUCKSTONE) { makeknown(otmp->otyp); i = (long) otmp->quan * objects[otmp->otyp].g_val; if(i == 0) { worthlessct += otmp->quan; continue; } u.urexp += i; Printf(" %s (worth %ld zorkmids),\n", doname(otmp), i); } else if(otmp->olet == AMULET_SYM) { otmp->known = 1; i = (otmp->spe < 0) ? 2 : otmp->otyp == AMULET_OF_YENDOR ? 5000 : 500; u.urexp += i; Printf(" %s (worth %ld zorkmids),\n", doname(otmp), i); } } if(worthlessct) Printf(" %u worthless piece%s of colored glass,\n", worthlessct, plur((long)worthlessct)); } else if(!done_stopprint) { Printf("You %s ", ends[how]); #ifdef ENDGAME if (how != ASCENDED) { if(dlevel == ENDLEVEL) Printf("in the endgame "); else Printf("on dungeon level %d ", dlevel); } #else Printf("on dungeon level %d ", dlevel); #endif Printf("with %ld points,\n", 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, ends[how]); #if (defined(WIZARD) || defined(EXPLORE_MODE)) # ifndef LOGFILE if(wizard || discover) Printf("\nSince you were in %s mode, the score list \ will not be checked.\n", wizard ? "wizard" : "discover"); else # endif #endif { if (!done_stopprint) { getret(); cls(); } /* "So when I die, the first thing I will see in Heaven is a score list?" */ topten(how); } if(done_stopprint) Printf("\n\n"); #if defined(APOLLO) || defined(MACOS) || defined (NEXT) getret(); #endif #ifdef NEXT exit_main(0); #else exit(0); #endif } void clearlocks(){ #if defined(DGK) eraseall(levels, alllevels); if (ramdisk) eraseall(permbones, alllevels); #else # if defined(UNIX) || defined(MSDOS) || defined(VMS) || defined(MACOS) register int x; # if defined(UNIX) || defined(VMS) (void) signal(SIGHUP,SIG_IGN); # endif for(x = maxdlevel; x >= 0; x--) { glo(x); (void) unlink(lock); /* not all levels need be present */ } # endif #endif } #ifdef NOSAVEONHANGUP int hangup() { (void) signal(SIGINT, SIG_IGN); clearlocks(); # ifndef VMS exit(1); # endif } #endif void end_box_display() { register struct obj *box, *obj; char buf[BUFSZ]; for(box=invent; box; box=box->nobj) { if (Is_container(box) && box->otyp != BAG_OF_TRICKS) { int cnt=0; for(obj=fcobj; obj; obj=obj->nobj) { if (obj->cobj == box) { if (!cnt) { Sprintf(buf, "Contents of the %s:",xname(box)); cornline(0, buf); } makeknown(obj->otyp); obj->known = obj->bknown = obj->dknown = 1; cornline(1,doname(obj)); cnt++; } } if (!cnt) { pline("The %s is empty.", xname(box)); more(); } else cornline(2,""); } } }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.