Blindfold removal fix
[slashemextended.git] / src / end.c
blobe12e08ce05aee2dc706bdd5c2d9f9d92b6816a77
1 /* SCCS Id: @(#)end.c 3.4 2003/03/10 */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /* NetHack may be freely redistributed. See license for details. */
5 #define NEED_VARARGS /* comment line for pre-compiled headers */
7 #include <sys/types.h>
8 #include <sys/stat.h>
9 #include "hack.h"
10 #include "eshk.h"
11 #ifndef NO_SIGNAL
12 #include <signal.h>
13 #endif
14 #include "dlb.h"
15 extern int enter_explore_mode(void);
17 #ifdef DUMP_LOG
18 extern char msgs[][BUFSZ];
19 extern int msgs_count[];
20 extern int lastmsg;
21 #endif
23 /* these probably ought to be generated by makedefs, like LAST_GEM */
24 #define FIRST_GEM DILITHIUM_CRYSTAL
25 #define FIRST_AMULET AMULET_OF_ESP
26 #define LAST_AMULET AMULET_OF_YENDOR
28 struct valuable_data { long count; int typ; };
30 static struct valuable_data
31 gems[LAST_GEM+1 - FIRST_GEM + 1], /* 1 extra for glass */
32 amulets[LAST_AMULET+1 - FIRST_AMULET];
34 static struct val_list { struct valuable_data *list; int size; } valuables[] = {
35 { gems, sizeof gems / sizeof *gems },
36 { amulets, sizeof amulets / sizeof *amulets },
37 { 0, 0 }
40 #ifndef NO_SIGNAL
41 STATIC_PTR void done_intr(int);
42 # if defined(UNIX) || defined(VMS) || defined (__EMX__)
43 static void done_hangup(int);
44 # endif
45 #endif
46 STATIC_DCL void disclose(int,BOOLEAN_P);
47 STATIC_DCL void get_valuables(struct obj *);
48 STATIC_DCL void sort_valuables(struct valuable_data *,int);
49 STATIC_DCL void artifact_score(struct obj *,BOOLEAN_P,winid);
50 STATIC_DCL void savelife(int);
51 STATIC_DCL boolean list_vanquished(CHAR_P, BOOLEAN_P);
52 #ifdef DUMP_LOG
53 extern void dump_spells(void);
54 extern void dump_techniques(void);
55 extern void dump_overview(void);
56 extern void dump_discoveries(void);
57 void do_vanquished(int, BOOLEAN_P, BOOLEAN_P);
58 STATIC_DCL void list_genocided(int, BOOLEAN_P, BOOLEAN_P);
59 #else
60 STATIC_DCL void list_genocided(CHAR_P,BOOLEAN_P);
61 #endif /* DUMP_LOG */
62 STATIC_DCL boolean should_query_disclose_option(int,char *);
64 #if defined(__BEOS__) || defined(MICRO) || defined(WIN32) || defined(OS2)
65 extern void nethack_exit(int);
66 #else
67 #define nethack_exit exit
68 #endif
70 #define done_stopprint program_state.stopprint
72 #ifdef AMIGA
73 # define NH_abort() Abort(0)
74 #else
75 # ifdef SYSV
76 # define NH_abort() (void) abort()
77 # else
78 # ifdef WIN32
79 # define NH_abort() win32_abort()
80 # else
81 # define NH_abort() abort()
82 # endif
83 # endif
84 #endif
87 * The order of these needs to match the macros in hack.h.
89 static NEARDATA const char *deaths[] = { /* the array of death */
90 "died", "betrayed", "choked", "poisoned", "starvation", "drowning",
91 "burning", "dissolving under the heat and pressure",
92 "crushed", "turned to stone", "turned into slime",
93 "genocided", "panic", "trickery",
94 "quit", "escaped", "ascended"
97 static NEARDATA const char *ends[] = { /* "when you..." */
98 "died", "were betrayed", "choked", "were poisoned", "starved",
99 "drowned", "burned", "dissolved in the lava",
100 "were crushed", "turned to stone", "turned into slime",
101 "were genocided", "panicked", "were tricked",
102 "quit", "escaped", "ascended"
105 char *
106 dump_format_str(char *str)
108 static char buf[BUFSZ];
109 char *f, *p, *end;
110 int ispercent = 0;
112 buf[0] = '\0';
114 if (!str) return NULL;
116 f = str;
117 p = buf;
118 end = buf + sizeof(buf) - 10;
120 while (*f) {
121 if (ispercent) {
122 switch (*f) {
123 case 't':
124 snprintf (p, end + 1 - p, "%ld", u.ubirthday);
125 while (*p != '\0')
126 p++;
127 break;
128 case 'N':
129 *p = plname[0];
130 p++;
131 *p = '\0';
132 break;
133 case 'n':
134 snprintf (p, end + 1 - p, "%s", plname);
135 while (*p != '\0')
136 p++;
137 break;
138 default:
139 *p = *f;
140 if (p < end)
141 p++;
143 ispercent = 0;
144 } else {
145 if (*f == '%')
146 ispercent = 1;
147 else {
148 *p = *f;
149 if (p < end)
150 p++;
153 f++;
155 *p = '\0';
157 return buf;
160 #ifdef DUMP_LOG
161 FILE *dump_fp = (FILE *)0; /* file pointer for dumps */
162 /* functions dump_init, dump_exit and dump are from the dump patch */
164 static
165 char*
166 get_dump_filename()
168 static char buf[BUFSIZ+1+5];
169 char *f, *p, *end;
170 int ispercent = 0;
172 buf[0] = '\0';
174 if (!dump_fn[0]) return NULL;
176 f = dump_fn;
177 p = buf;
178 end = buf + sizeof(buf) - 10;
180 while (*f) {
181 if (ispercent) {
182 switch (*f) {
183 case 't': case 'd': /* starttime */
184 snprintf (p, end + 1 - p, "%ld", u.ubirthday);
185 while (*p != '\0') {
186 p++;
188 break;
189 case 'N': /* first character of player name */
190 *p = plname[0];
191 p++;
192 *p = '\0';
193 break;
194 case 'n': /* player name */
195 case 's': /* for backwards compatibility */
196 snprintf(p, end + 1 - p, "%s", plname);
197 while (*p != '\0') {
198 p++;
200 break;
201 default:
202 *p = *f;
203 if (p < end) {
204 p++;
207 ispercent = 0;
208 } else {
209 if (*f == '%') {
210 ispercent = 1;
211 } else {
212 *p = *f;
213 if (p < end) {
214 p++;
218 f++;
220 *p = '\0';
222 return buf;
226 void
227 dump_init ()
229 #ifdef PUBLIC_SERVER
230 mode_t dumpmode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
231 #endif
232 if (dump_fn[0]) {
233 char *actual_fn = get_dump_filename();
235 dump_fp = fopen (actual_fn, "w");
236 #ifdef PUBLIC_SERVER
237 chmod(actual_fn, dumpmode);
238 #endif
240 if (!dump_fp) {
241 pline("Can't open %s for output.", actual_fn);
242 pline("Dump file not created.");
247 void
248 dump_exit ()
250 if (dump_fp) {
251 fclose (dump_fp);
255 void dump (pre, str)
256 const char * const pre;
257 const char * const str;
259 if (dump_fp)
260 fprintf (dump_fp, "%s%s\n", pre, str);
262 #endif /* DUMP_LOG */
264 /*ARGSUSED*/
265 void
266 done1(sig_unused) /* called as signal() handler, so sent at least one arg */
267 int sig_unused;
269 #if defined(MAC_MPW)
270 # pragma unused ( sig_unused )
271 #endif
272 #ifndef NO_SIGNAL
273 (void) signal(SIGINT,SIG_IGN);
274 #endif
275 if(flags.ignintr) {
276 #ifndef NO_SIGNAL
277 (void) signal(SIGINT, (SIG_RET_TYPE) done1);
278 #endif
279 clear_nhwindow(WIN_MESSAGE);
280 curs_on_u();
281 wait_synch();
282 if(multi > 0) nomul(0, 0, FALSE);
283 } else {
284 (void)done2();
288 extern const char * const killed_by_prefix[]; /* from topten.c */
290 /* "#quit" command or keyboard interrupt */
292 done2()
294 if (iflags.debug_fuzzer) return 0;
296 char buf[BUFSZ];
297 int really_quit = FALSE;
299 if (flags.paranoidquit) {
301 getlin ("Really quit? WARNING: this will erase your game permanently! [yes/no]?",buf);
302 (void) lcase (buf);
303 if (!(strcmp (buf, "yes"))) really_quit = TRUE;
305 } else {
307 if(yn("Really quit? WARNING: this will erase your game permanently and you disabled the paranoidquit safety option so if you hit 'y' now, your game will be GONE!") != 'n') really_quit = TRUE;
311 if (!really_quit) {
312 #ifndef NO_SIGNAL
313 (void) signal(SIGINT, (SIG_RET_TYPE) done1);
314 #endif
315 clear_nhwindow(WIN_MESSAGE);
316 curs_on_u();
317 wait_synch();
318 if(multi > 0) nomul(0, 0, FALSE);
319 if(multi == 0) {
320 u.uinvulnerable = FALSE; /* avoid ctrl-C bug -dlc */
321 u.usleep = 0;
323 return 0;
325 #if defined(WIZARD) && (defined(UNIX) || defined(VMS) || defined(LATTICE))
326 if(wizard) {
327 int c;
328 # ifdef VMS
329 const char *tmp = "Enter debugger?";
330 # else
331 # ifdef LATTICE
332 const char *tmp = "Create SnapShot?";
333 # else
334 const char *tmp = "Dump core?";
335 # endif
336 # endif
337 if ((c = ynq(tmp)) == 'y') {
338 (void) signal(SIGINT, (SIG_RET_TYPE) done1);
339 exit_nhwindows((char *)0);
340 NH_abort();
341 } else if (c == 'q') done_stopprint++;
343 #endif
344 #ifndef LINT
345 done(QUIT);
346 #endif
347 return 0;
350 #ifndef NO_SIGNAL
351 /*ARGSUSED*/
352 STATIC_PTR void
353 done_intr(sig_unused) /* called as signal() handler, so sent at least one arg */
354 int sig_unused;
356 #if defined(MAC_MPW)
357 # pragma unused ( sig_unused )
358 #endif
359 done_stopprint++;
360 (void) signal(SIGINT, SIG_IGN);
361 # if defined(UNIX) || defined(VMS)
362 (void) signal(SIGQUIT, SIG_IGN);
363 # endif
364 return;
367 # if defined(UNIX) || defined(VMS) || defined(__EMX__)
368 static void
369 done_hangup(sig) /* signal() handler */
370 int sig;
372 program_state.done_hup++;
373 sethanguphandler((void (*)(int)) SIG_IGN);
374 done_intr(sig);
375 return;
377 # endif
378 #endif /* NO_SIGNAL */
380 void
381 done_in_by(mtmp)
382 register struct monst *mtmp;
384 u.youaredead = 1;
385 char buf[BUFSZ];
386 boolean distorted = (boolean)(Hallucination && canspotmon(mtmp));
388 You(isangbander ? "have died." : "die...");
389 /* for those wand o'death, touch o'death, poisoned spike times... */
391 if(mtmp->data == &mons[PM_SOLDIER_ANT]) pline("Go Team Ant!");
393 if (Instant_Death)
394 You("were hosed!");
395 mark_synch(); /* flush buffered screen output */
396 buf[0] = '\0';
397 strcat(buf, "a monster (");
399 killer_format = KILLED_BY;
400 if (!Blind || Blind_telepat || Blind) {
401 /* "killed by the high priest of Crom" is okay, "killed by the high
402 priest" alone isn't */
403 if ((mtmp->data->geno & G_UNIQ) != 0 && !(mtmp->data == &mons[PM_HIGH_PRIEST] && !mtmp->ispriest)) {
404 if (!type_is_pname(mtmp->data))
405 strcat(buf, "the ");
406 killer_format = KILLED_BY;
408 /* _the_ <invisible> <distorted> ghost of Dudley */
409 if (mtmp->data == &mons[PM_GHOST] && mtmp->mnamelth) {
410 strcat(buf, "the ");
411 killer_format = KILLED_BY;
413 if (mtmp->minvis)
414 strcat(buf, "invisible ");
415 if (distorted)
416 strcat(buf, "hallucinogen-distorted ");
418 if(mtmp->data == &mons[PM_GHOST]) {
419 strcat(buf, "ghost");
420 if (mtmp->mnamelth) sprintf(eos(buf), " of %s", NAME(mtmp));
421 } else if(mtmp->isshk) {
422 sprintf(eos(buf), "%s %s, the shopkeeper",
423 (mtmp->female ? "Ms." : "Mr."), shkname(mtmp));
424 killer_format = KILLED_BY;
425 } else if (mtmp->ispriest || mtmp->isminion) {
426 /* m_monnam() suppresses "the" prefix plus "invisible", and
427 it overrides the effect of Hallucination on priestname() */
428 killer = m_monnam(mtmp);
429 strcat(buf, killer);
430 } else {
431 strcat(buf, mtmp->data->mname);
432 if (mtmp->mnamelth)
433 sprintf(eos(buf), " called %s", NAME(mtmp));
435 strcat(buf, ")");
437 if (multi) {
438 if (strlen(multi_txt) > 0)
439 sprintf(eos(buf), ", while %s", multi_txt);
440 else
441 strcat(buf, ", while helpless");
444 } else {
445 killer_format = KILLED_BY;
446 strcat(buf,", while blind");
447 if (multi) strcat(buf," and helpless");
449 if(mtmp->data == &mons[PM_SOLDIER_ANT]) strcat(buf, " Go Team Ant!");
451 killer = buf;
452 if (mtmp->data->mlet == S_WRAITH)
453 u.ugrave_arise = PM_WRAITH;
454 else if (mtmp->data->mlet == S_MUMMY && urace.mummynum != NON_PM)
455 u.ugrave_arise = urace.mummynum;
456 else if (is_vampire(mtmp->data) && Race_if(PM_HUMAN)
457 && mtmp->data != &mons[PM_FIRE_VAMPIRE]
458 && mtmp->data != &mons[PM_STAR_VAMPIRE])
459 u.ugrave_arise = PM_VAMPIRE;
460 else if (mtmp->data == &mons[PM_GHOUL])
461 u.ugrave_arise = PM_GHOUL;
462 if (u.ugrave_arise >= LOW_PM &&
463 (mvitals[u.ugrave_arise].mvflags & G_GENOD))
464 u.ugrave_arise = NON_PM;
465 if (touch_petrifies(mtmp->data))
466 done(STONING);
467 else if (mtmp->mtraitor)
468 done(BETRAYED);
469 else
470 done(DIED);
472 u.youaredead = 0;
473 return;
476 #if defined(WIN32)
477 #define NOTIFY_NETHACK_BUGS
478 #endif
480 /*VARARGS1*/
481 void
482 panic VA_DECL(const char *, str)
483 VA_START(str);
484 VA_INIT(str, char *);
486 if (program_state.panicking++)
487 NH_abort(); /* avoid loops - this should never happen*/
489 if (iflags.window_inited) {
490 raw_print("\r\nOops...");
491 wait_synch(); /* make sure all pending output gets flushed */
492 exit_nhwindows((char *)0);
493 iflags.window_inited = 0; /* they're gone; force raw_print()ing */
496 raw_print(program_state.gameover ?
497 "Postgame wrapup disrupted." :
498 !program_state.something_worth_saving ?
499 "Program initialization has failed." :
500 "Suddenly, the dungeon collapses.");
502 raw_print("\r\nReport this error to Amy so it can be fixed.");
504 raw_print("\r\nYou can contact the admins on the #em.slashem.me IRC channel (Libera)");
506 #if defined(WIZARD) && !defined(MICRO)
507 # if defined(NOTIFY_NETHACK_BUGS)
508 if (!wizard)
509 raw_printf("Report the following error to \"%s\".",
510 "slashem-discuss@lists.sourceforge.net");
511 else if (program_state.something_worth_saving)
512 raw_print("\nError save file being written.\n");
513 # else
514 if (!wizard)
515 raw_printf("Report error to \"%s\"%s.",
516 # ifdef WIZARD_NAME /*(KR1ED)*/
517 WIZARD_NAME,
518 # else
519 WIZARD,
520 # endif
521 !program_state.something_worth_saving ? "" :
522 " and it may be possible to rebuild.");
523 # endif
524 if (program_state.something_worth_saving) {
525 set_error_savefile();
526 (void) dosave0();
528 #endif
530 char buf[BUFSZ];
531 vsprintf(buf,str,VA_ARGS);
532 raw_print(buf);
533 paniclog("panic", buf);
535 #ifdef WIN32
536 interject(INTERJECT_PANIC);
537 #endif
538 #if defined(WIZARD) && (defined(UNIX) || defined(VMS) || defined(LATTICE) || defined(WIN32))
539 if (wizard)
540 NH_abort(); /* generate core dump */
541 #endif
542 VA_END();
543 done(PANICKED);
546 STATIC_OVL boolean
547 should_query_disclose_option(category, defquery)
548 int category;
549 char *defquery;
551 int idx;
552 char *dop = index(disclosure_options, category);
554 if (dop && defquery) {
555 idx = dop - disclosure_options;
556 if (idx < 0 || idx > (NUM_DISCLOSURE_OPTIONS - 1)) {
557 impossible(
558 "should_query_disclose_option: bad disclosure index %d %c",
559 idx, category);
560 *defquery = DISCLOSE_PROMPT_DEFAULT_YES;
561 return TRUE;
563 if (flags.end_disclose[idx] == DISCLOSE_YES_WITHOUT_PROMPT) {
564 *defquery = 'y';
565 return FALSE;
566 } else if (flags.end_disclose[idx] == DISCLOSE_NO_WITHOUT_PROMPT) {
567 *defquery = 'n';
568 return FALSE;
569 } else if (flags.end_disclose[idx] == DISCLOSE_PROMPT_DEFAULT_YES) {
570 *defquery = 'y';
571 return TRUE;
572 } else if (flags.end_disclose[idx] == DISCLOSE_PROMPT_DEFAULT_NO) {
573 *defquery = 'n';
574 return TRUE;
577 if (defquery)
578 impossible("should_query_disclose_option: bad category %c", category);
579 else
580 impossible("should_query_disclose_option: null defquery");
581 return TRUE;
584 STATIC_OVL void
585 disclose(how,taken)
586 int how;
587 boolean taken;
589 char c = 0, defquery;
590 char qbuf[QBUFSZ];
591 boolean ask;
592 boolean hallu=FALSE;
594 if (PlayerHearsSoundEffects) pline(issoviet ? "Igra zakonchena! Ty polnyy otstoy! Vy igrali tak uzhasno plokho, chto ty umer, i teper' vy dolzhny nachat' s nulya!" : "Duedeldue-duedeldue-duedeldue-duedelduedeldueueueueue-wueck!");
596 if (invent) {
597 if(taken)
598 sprintf(qbuf, Role_if(PM_SPACE_MARINE) ? "Game over, man! Game over! (DYWYPI?)" : Role_if(PM_SPACEWARS_FIGHTER) ? "Another one bites the dust... DYWYPI?" : Role_if(PM_CAMPERSTRIKER) ? "A problem has been detected and NetHack has been shut down to prevent damage to your sanity. The problem seems to be caused by the following file: SLASHEM.EXE YET_ANOTHER_STUPID_DEATH (DYWYPI?) If this is the first time you've seen this Stop error screen, restart your game. If this screen appears again, follow these steps: Check to make sure any equipments or spells is properly installed. If this is a proper installation, ask your cheat or spoiler manufacturer for any spoilers you might need. If problems continue, remove any newly created save files (if explore) or bone files. Disable bad options such as rest_on_space or autopickup. If you need to use Explore Mode to remove or disable components, restart your game, press X to select Explore Mode Options, and then select Yes. Technical information: *** STOP: 0x0000DEAD (0x44, 0x75, 0x64, 0x6C, 0x65, 0x79) *** SLASHEM.EXE - Address DLVL1 base at MAINDUN, DateStamp 20150401" : issoviet ? "Tvoi tovari hotjat tebja identifitsirovat? DYWYPI? [da]" : "Do you want to see what you had when you %s? DYWYPI?",
599 (how == QUIT) ? "quit" : "died");
600 else
601 strcpy(qbuf, Role_if(PM_SPACE_MARINE) ? "Game over, man! Game over! (DYWYPI?)" : Role_if(PM_SPACEWARS_FIGHTER) ? "Another one bites the dust... DYWYPI?" : Role_if(PM_CAMPERSTRIKER) ? "A problem has been detected and NetHack has been shut down to prevent damage to your sanity. The problem seems to be caused by the following file: SLASHEM.EXE YET_ANOTHER_STUPID_DEATH (DYWYPI?) If this is the first time you've seen this Stop error screen, restart your game. If this screen appears again, follow these steps: Check to make sure any equipments or spells is properly installed. If this is a proper installation, ask your cheat or spoiler manufacturer for any spoilers you might need. If problems continue, remove any newly created save files (if explore) or bone files. Disable bad options such as rest_on_space or autopickup. If you need to use Explore Mode to remove or disable components, restart your game, press X to select Explore Mode Options, and then select Yes. Technical information: *** STOP: 0x0000DEAD (0x44, 0x75, 0x64, 0x6C, 0x65, 0x79) *** SLASHEM.EXE - Address DLVL1 base at MAINDUN, DateStamp 20150401" : issoviet ? "Tvoi tovari hotjat tebja identifitsirovat? DYWYPI? [da]" : "Do you want your possessions identified? DYWYPI?");
603 ask = should_query_disclose_option('i', &defquery);
604 if (!done_stopprint) {
605 c = ask ? yn_function(qbuf, ynqchars, defquery) : defquery;
606 if (c != 'q') {
607 struct obj *obj;
609 if (Hallucination) {
610 make_hallucinated(0L, FALSE, 0L);
611 hallu = TRUE;
613 for (obj = invent; obj; obj = obj->nobj) {
614 makeknown(obj->otyp);
615 obj->known = obj->bknown = obj->dknown = obj->rknown = 1;
617 #ifdef DUMP_LOG
618 (void) dump_inventory((char *)0, TRUE);
619 do_containerconts(invent, TRUE, TRUE, TRUE);
620 #else
621 (void) display_inventory((char *)0, TRUE);
622 container_contents(invent, TRUE, TRUE);
623 #endif /* DUMP_LOG */
625 if (c == 'q') done_stopprint++;
628 if (!invent) pline(Role_if(PM_SPACEWARS_FIGHTER) ? "Another one bites the dust... DYWYPI? Oops... it seems your inventory was empty!" : Role_if(PM_CAMPERSTRIKER) ? "A problem has been detected and NetHack has been shut down to prevent damage to your sanity. The problem seems to be caused by the following file: SLASHEM.EXE YET_ANOTHER_STUPID_DEATH (DYWYPI?) If this is the first time you've seen this Stop error screen, restart your game. If this screen appears again, follow these steps: Check to make sure any equipments or spells is properly installed. If this is a proper installation, ask your cheat or spoiler manufacturer for any spoilers you might need. If problems continue, remove any newly created save files (if explore) or bone files. Disable bad options such as rest_on_space or autopickup. If you need to use Explore Mode to remove or disable components, restart your game, press X to select Explore Mode Options, and then select Yes. Technical information: *** STOP: 0x0000DEAD (0x44, 0x75, 0x64, 0x6C, 0x65, 0x79) *** SLASHEM.EXE - Address DLVL1 base at MAINDUN, DateStamp 20150401" : issoviet ? "Tvoi tovari hotjat tebja identifitsirovat? DYWYPI? [da]" : "DYWYPI? Oops... it seems your inventory was empty!");
629 if (hallu) make_hallucinated(20L, FALSE, 0L);
631 ask = should_query_disclose_option('a', &defquery);
632 if (!done_stopprint) {
633 c = ask ? yn_function("Do you want to see your attributes?",
634 ynqchars, defquery) : defquery;
635 if (c != 'q')
636 enlightenment(how >= PANICKED ? 1 : 2, 1); /* final */
637 if (c == 'q') done_stopprint++;
640 ask = 1; /* if I can figure out how to do it, I'll make it configurable via disclosure and defquery options --Amy */
641 if (!done_stopprint) {
642 c = ask ? yn_function("Do you want to see your discoveries?",
643 ynqchars, defquery) : defquery;
644 if (c != 'q')
645 dodiscovered();
646 if (c == 'q') done_stopprint++;
649 #ifdef DUMP_LOG
650 if (dump_fp) {
651 dump_enlightenment((int) (how >= PANICKED ? 1 : 2));
652 dump_spells();
653 dump_techniques();
654 dump_discoveries();
655 dump_overview();
657 #endif
659 ask = should_query_disclose_option('v', &defquery);
660 if (!done_stopprint)
661 #ifdef DUMP_LOG
662 do_vanquished(defquery, ask, TRUE);
663 #else
664 list_vanquished(defquery, ask);
665 #endif
667 ask = should_query_disclose_option('g', &defquery);
668 if (!done_stopprint)
669 #ifdef DUMP_LOG
670 list_genocided(defquery, ask,TRUE);
671 #else
672 list_genocided(defquery, ask);
673 #endif
675 ask = should_query_disclose_option('c', &defquery);
676 if (!done_stopprint) {
677 c = ask ? yn_function("Do you want to see your conduct?",
678 ynqchars, defquery) : defquery;
679 if (c != 'q')
680 show_conduct(how >= PANICKED ? 1 : 2);
681 if (c == 'q') done_stopprint++;
683 #ifdef DUMP_LOG
684 if (dump_fp) {
685 dump_conduct(how >= PANICKED ? 1 : 2);
686 dump_weapon_skill();
688 #endif
691 /* try to get the player back in a viable state after being killed */
692 STATIC_OVL void
693 savelife(how)
694 int how;
696 pline("You %s because of %s, but didn't actually die.", ends[how], killer);
698 /* will's sacrifice helpfully triggers *before* perilous life saving erases your inventory :D */
699 if (uimplant && uimplant->oartifact == ART_WILL_S_SACRIFICE) {
700 int i, j, bd = 5;
701 struct monst *mtmp;
703 verbalize("I Am Legend!"); /* yeah totally not a crappy movie reference :-P --Amy */
705 for (i = -bd; i <= bd; i++) for(j = -bd; j <= bd; j++) {
706 if (!isok(u.ux + i, u.uy + j)) continue;
707 if ((mtmp = m_at(u.ux + i, u.uy + j)) != 0 && !DEADMONSTER(mtmp) && mtmp->mtame == 0
708 && mtmp->mnum != quest_info(MS_NEMESIS) && !(mtmp->data->geno & G_UNIQ))
709 (void) tamedog(mtmp, (struct obj *) 0, FALSE);
712 if (powerfulimplants()) {
713 for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
714 if (!DEADMONSTER(mtmp)) {
715 mtmp->mfrenzied = 0;
722 u.uswldtim = 0;
723 if (Second_chance) {
724 u.uhp = u.uhplast;
725 } else {
726 u.uhp = u.uhpmax;
728 u.uhplast = u.uhp;
729 if (u.uhunger < 1000) {
730 u.uhunger = 1000;
731 newuhs(FALSE);
733 /* cure impending doom of sickness hero won't have time to fix */
734 if ((Sick & TIMEOUT) == 1) {
735 u.usick_type = 0;
736 Sick = 0;
738 if (how == CHOKING) init_uhunger();
739 nomovemsg = "You survived that attempt on your life.";
740 flags.move = 0;
741 if(multi > 0) multi = 0; else multi = -1;
742 if(u.utrap && u.utraptype == TT_LAVA) u.utrap = 0;
743 flags.botl = 1;
744 u.ugrave_arise = NON_PM;
745 HUnchanging = 0L;
746 curs_on_u();
748 /* inspired by Elona: anorexia ends if you die, but there is no message --Amy */
749 if (FemaleTrapIna & TIMEOUT) {
750 u.inasuppression = FemaleTrapIna;
751 if (u.inasuppression >= 67108864) u.inasuppression -= 67108864;
752 if (u.inasuppression >= 33554432) u.inasuppression -= 33554432;
753 if (u.inasuppression >= 16777216) u.inasuppression -= 16777216;
754 FemaleTrapIna &= ~TIMEOUT;
759 * Get valuables from the given list. Revised code: the list always remains
760 * intact.
762 STATIC_OVL void
763 get_valuables(list)
764 struct obj *list; /* inventory or container contents */
766 register struct obj *obj;
767 register int i;
769 /* find amulets and gems, ignoring all artifacts */
770 for (obj = list; obj; obj = obj->nobj)
771 if (Has_contents(obj)) {
772 get_valuables(obj->cobj);
773 } else if (obj->oartifact) {
774 continue;
775 } else if (obj->oclass == AMULET_CLASS) {
776 i = obj->otyp - FIRST_AMULET;
777 if (!amulets[i].count) {
778 amulets[i].count = obj->quan;
779 amulets[i].typ = obj->otyp;
780 } else amulets[i].count += obj->quan; /* always adds one */
781 } else if (obj->oclass == GEM_CLASS && obj->otyp < LUCKSTONE) {
782 i = min(obj->otyp, LAST_GEM + 1) - FIRST_GEM;
783 if (!gems[i].count) {
784 gems[i].count = obj->quan;
785 gems[i].typ = obj->otyp;
786 } else gems[i].count += obj->quan;
788 return;
792 * Sort collected valuables, most frequent to least. We could just
793 * as easily use qsort, but we don't care about efficiency here.
795 STATIC_OVL void
796 sort_valuables(list, size)
797 struct valuable_data list[];
798 int size; /* max value is less than 20 */
800 register int i, j;
801 struct valuable_data ltmp;
803 /* move greater quantities to the front of the list */
804 for (i = 1; i < size; i++) {
805 if (list[i].count == 0) continue; /* empty slot */
806 ltmp = list[i]; /* structure copy */
807 for (j = i; j > 0; --j)
808 if (list[j-1].count >= ltmp.count) break;
809 else {
810 list[j] = list[j-1];
812 list[j] = ltmp;
814 return;
817 /* called twice; first to calculate total, then to list relevant items */
818 STATIC_OVL void
819 artifact_score(list, counting, endwin)
820 struct obj *list;
821 boolean counting; /* true => add up points; false => display them */
822 winid endwin;
824 char pbuf[BUFSZ];
825 struct obj *otmp;
826 long value, points;
827 /*short*/int dummy; /* object type returned by artifact_name() */
829 for (otmp = list; otmp; otmp = otmp->nobj) {
830 if (otmp->oartifact ||
831 otmp->otyp == BELL_OF_OPENING ||
832 otmp->otyp == SPE_BOOK_OF_THE_DEAD ||
833 otmp->otyp == CANDELABRUM_OF_INVOCATION) {
834 value = arti_cost(otmp); /* zorkmid value */
835 points = value * 5 / 2; /* score value */
836 if (counting) {
837 u.urexp += points;
838 } else {
839 makeknown(otmp->otyp);
840 otmp->known = otmp->dknown = otmp->bknown = otmp->rknown = 1;
841 /* assumes artifacts don't have quan > 1 */
842 sprintf(pbuf, "%s%s (worth %ld %s and %ld points)",
843 the_unique_obj(otmp) ? "The " : "",
844 otmp->oartifact ? /*artifact_name(*/xname(otmp)/*, &dummy)*/ :
845 OBJ_NAME(objects[otmp->otyp]),
846 value, currency(value), points);
847 putstr(endwin, 0, pbuf);
848 #ifdef DUMP_LOG
849 if (dump_fp)
850 dump("", pbuf);
851 #endif
854 if (Has_contents(otmp))
855 artifact_score(otmp->cobj, counting, endwin);
859 /* Be careful not to call panic from here! */
860 void
861 done(how)
862 int how;
864 boolean taken;
865 boolean goexplore = FALSE;
866 boolean gofreeplay = FALSE;
867 char kilbuf[BUFSZ], pbuf[BUFSZ];
868 #ifdef EPITAPH
869 char ebuf[BUFSZ];
870 #endif
871 winid endwin = WIN_ERR;
872 boolean bones_ok, have_windows = iflags.window_inited;
873 struct obj *corpse = (struct obj *)0;
874 long umoney;
875 struct obj *otmp, *otmp2;
876 int n;
877 char buf[BUFSZ];
879 boolean wanttodie = 0;
881 if (how == TRICKED) {
882 if (killer) {
883 paniclog("trickery", killer);
884 killer = 0;
886 #ifdef WIZARD
887 if (wizard) {
888 You("are a very tricky wizard, it seems.");
889 return;
891 #endif
894 if (iflags.debug_fuzzer) {
895 if (!(program_state.panicking || how == PANICKED)) {
896 savelife(how);
897 killer = '\0';
898 killer_format = 0;
899 return;
903 /* kilbuf: used to copy killer in case it comes from something like
904 * xname(), which would otherwise get overwritten when we call
905 * xname() when listing possessions
906 * pbuf: holds sprintf'd output for raw_print and putstr
908 if (how == ASCENDED || (!killer && how == GENOCIDED))
909 killer_format = NO_KILLER_PREFIX;
910 /* Avoid killed by "a" burning or "a" starvation */
911 if (!killer && (how == STARVING || how == BURNING))
912 killer_format = KILLED_BY;
913 strcpy(kilbuf, (!killer || how >= PANICKED ? deaths[how] : killer));
914 killer = kilbuf;
916 if (how < PANICKED) u.umortality++;
918 if (DywypiProblem || u.uprops[DYWYPI_PROBLEM].extrinsic || have_dywypistone() || (uarmf && uarmf->oartifact == ART_PRADA_S_DEVIL_WEAR)) {
919 wanttodie = 1;
920 char qbuf[QBUFSZ];
921 char possid = 0;
922 sprintf(qbuf, "Do you want your possessions identified? DYWYPI?");
923 possid = yn_function(qbuf, ynqchars, 'y');
924 if (possid != 'n') {
925 u.youaredead = 1;
926 wanttodie = 1;
927 } else wanttodie = 0;
930 /* symbiote can save you from being killed by something other than HP loss --Amy */
931 if (uactivesymbiosis && (u.uhp > 0) && (u.uhpmax > 0) && (rn2(100) < u.symbioteaggressivity) && how < GENOCIDED) {
932 pline("But wait...");
934 if (wanttodie) {
935 pline("Nyehehe-hehe-he, you would have lifesaved but you said you want your possessions identified! GAME OVER!");
936 goto symbiotedone;
939 if (uarmf && itemhasappearance(uarmf, APP_REMORA_HEELS) && u.usymbiote.mnum == PM_REMORA) {
940 if (uarmf->spe > -1) uarmf->spe = -1;
943 if (uamul && uamul->otyp == AMULET_OF_SYMBIOTE_SAVING) {
944 makeknown(AMULET_OF_SYMBIOTE_SAVING);
945 useup(uamul);
946 u.usymbiote.mhp = u.usymbiote.mhpmax;
947 Your("symbiote glows, and your amulet crumbles to dust!");
948 } else {
949 u.usymbiote.active = 0;
950 u.usymbiote.mnum = PM_PLAYERMON;
951 u.usymbiote.mhp = 0;
952 u.usymbiote.mhpmax = 0;
953 u.usymbiote.cursed = u.usymbiote.hvycurse = u.usymbiote.prmcurse = u.usymbiote.bbcurse = u.usymbiote.morgcurse = u.usymbiote.evilcurse = u.usymbiote.stckcurse = 0;
954 if (flags.showsymbiotehp) flags.botl = TRUE;
955 u.cnd_symbiotesdied++;
956 Your("symbiote sacrifices itself to absorb the deadly hit, and saves your life!");
959 (void) adjattrib(A_CON, -1, TRUE, TRUE);
960 if(u.uhpmax <= 0) u.uhpmax = 1;
961 savelife(how);
962 u.lifesavepenalty++;
963 killer = 0;
964 killer_format = 0;
966 #ifdef LIVELOGFILE
967 livelog_avert_death();
968 #endif
970 u.youaredead = 0;
972 return;
974 symbiotedone:
976 if (how == STONING && uamul && uamul->otyp == AMULET_VERSUS_STONE) {
977 pline("But wait...");
978 makeknown(AMULET_VERSUS_STONE);
979 Your("medallion %s%s!",
980 !Blind ? "begins to glow" : "feels warm",
981 uamul->cursed ? " and disintegrates" : "");
982 /* blessed -> uncursed -> cursed -> gone */
983 if (uamul->cursed)
984 useup(uamul);
985 else if (uamul->blessed)
986 unbless(uamul);
987 else
988 curse(uamul);
990 if (wanttodie) {
991 pline("Nyehehe-hehe-he, you would have lifesaved but you said you want your possessions identified! GAME OVER!");
992 goto stoningdone;
995 uunstone();
996 (void) adjattrib(A_CON, -1, TRUE, TRUE);
997 if(u.uhpmax <= 0) u.uhpmax = 1;
998 savelife(how);
999 u.lifesavepenalty++;
1000 killer = 0;
1001 killer_format = 0;
1003 #ifdef LIVELOGFILE
1004 livelog_avert_death();
1005 #endif
1007 u.youaredead = 0;
1009 return;
1011 stoningdone:
1013 if (uarmg && uarmg->oartifact == ART_COME_BACK_TO_LIFE && how < GENOCIDED && rn2(2)) {
1014 pline("But wait...");
1015 pline("You come back to life!");
1017 if (wanttodie) {
1018 pline("Nyehehe-hehe-he, you would have lifesaved but you said you want your possessions identified! GAME OVER!");
1019 goto cbldone;
1022 if(u.uhpmax <= 0) u.uhpmax = 1; /* arbitrary */
1023 savelife(how);
1024 u.lifesavepenalty++;
1025 killer = 0;
1026 killer_format = 0;
1028 #ifdef LIVELOGFILE
1029 livelog_avert_death();
1030 #endif
1031 u.youaredead = 0;
1033 return;
1036 cbldone:
1038 if (u.contingencyturns && how < GENOCIDED) {
1040 int contingencychance = 25;
1042 if (!(PlayerCannotUseSkills) && P_SKILL(P_OCCULT_SPELL) >= P_BASIC) {
1044 switch (P_SKILL(P_OCCULT_SPELL)) {
1045 case P_BASIC: contingencychance = 35; break;
1046 case P_SKILLED: contingencychance = 50; break;
1047 case P_EXPERT: contingencychance = 65; break;
1048 case P_MASTER: contingencychance = 75; break;
1049 case P_GRAND_MASTER: contingencychance = 85; break;
1050 case P_SUPREME_MASTER: contingencychance = 90; break;
1051 default: break;
1055 if (rnd(100) > contingencychance) goto contingencydone;
1057 pline("But wait...");
1058 pline("You lost the effect of contingency.");
1060 if (wanttodie) {
1061 pline("Nyehehe-hehe-he, you would have lifesaved but you said you want your possessions identified! GAME OVER!");
1062 goto contingencydone;
1065 if(u.uhpmax <= 0) u.uhpmax = 1; /* arbitrary */
1066 savelife(how);
1067 u.lifesavepenalty++;
1068 killer = 0;
1069 killer_format = 0;
1071 #ifdef LIVELOGFILE
1072 livelog_avert_death();
1073 #endif
1074 u.youaredead = 0;
1076 return;
1079 contingencydone:
1081 if (uarmh && uarmh->oartifact == ART_LUXIDREAM_S_ASCENSION && how < GENOCIDED && !rn2(10)) {
1082 pline("But wait...");
1083 pline("You come back to life!");
1085 if (wanttodie) {
1086 pline("Nyehehe-hehe-he, you would have lifesaved but you said you want your possessions identified! GAME OVER!");
1087 goto luxidone;
1090 if(u.uhpmax <= 0) u.uhpmax = 1; /* arbitrary */
1091 savelife(how);
1092 u.lifesavepenalty++;
1093 killer = 0;
1094 killer_format = 0;
1096 #ifdef LIVELOGFILE
1097 livelog_avert_death();
1098 #endif
1099 u.youaredead = 0;
1101 return;
1104 luxidone:
1106 if (uwep && uwep->oartifact == ART_ERU_ILUVATAR_S_BIBLE && how < GENOCIDED && !rn2(5)) {
1107 pline("But wait...");
1108 pline("Eru Iluvatar saves your life!");
1110 if (wanttodie) {
1111 pline("Nyehehe-hehe-he, you would have lifesaved but you said you want your possessions identified! GAME OVER!");
1112 goto erudone;
1115 if(u.uhpmax <= 0) u.uhpmax = 1; /* arbitrary */
1116 savelife(how);
1117 u.lifesavepenalty++;
1118 killer = 0;
1119 killer_format = 0;
1121 #ifdef LIVELOGFILE
1122 livelog_avert_death();
1123 #endif
1124 u.youaredead = 0;
1126 return;
1129 erudone:
1131 /* cursed ruffled shirt or victorian underwear may actually be helpful... */
1132 if (uarmu && how < GENOCIDED && (uarmu->otyp == RUFFLED_SHIRT || uarmu->otyp == VICTORIAN_UNDERWEAR) && uarmu->cursed && !rn2(4) ) {
1133 pline("But wait...");
1134 pline("For some reason, you're not dead!");
1136 if (wanttodie) {
1137 pline("Nyehehe-hehe-he, you would have lifesaved but you said you want your possessions identified! GAME OVER!");
1138 goto ruffledone;
1141 if(u.uhpmax <= 0) u.uhpmax = 1; /* arbitrary */
1142 savelife(how);
1143 u.lifesavepenalty++;
1144 killer = 0;
1145 killer_format = 0;
1147 #ifdef LIVELOGFILE
1148 livelog_avert_death();
1149 #endif
1150 u.youaredead = 0;
1152 return;
1155 ruffledone:
1157 if (uarmf && how < GENOCIDED && uarmf->oartifact == ART_UNFAIR_FIGHTING && !rn2(4) ) {
1158 pline("But wait...");
1159 pline("You simply refuse to die, even though you're supposed to have been defeated!");
1161 if (wanttodie) {
1162 pline("Nyehehe-hehe-he, you would have lifesaved but you said you want your possessions identified! GAME OVER!");
1163 goto kristindone;
1166 if(u.uhpmax <= 0) u.uhpmax = 1; /* arbitrary */
1167 savelife(how);
1168 u.lifesavepenalty++;
1169 killer = 0;
1170 killer_format = 0;
1172 #ifdef LIVELOGFILE
1173 livelog_avert_death();
1174 #endif
1175 u.youaredead = 0;
1177 return;
1180 kristindone:
1182 /* double detect monsters can let you lifesave too */
1183 if (StrongDetect_monsters && how < GENOCIDED && !rn2(10) ) {
1184 pline("But wait...");
1185 pline("For some reason, you're not dead!");
1187 if (wanttodie) {
1188 pline("Nyehehe-hehe-he, you would have lifesaved but you said you want your possessions identified! GAME OVER!");
1189 goto detectmonstersdone;
1192 if(u.uhpmax <= 0) u.uhpmax = 1; /* arbitrary */
1193 savelife(how);
1194 u.lifesavepenalty++;
1195 killer = 0;
1196 killer_format = 0;
1198 #ifdef LIVELOGFILE
1199 livelog_avert_death();
1200 #endif
1201 u.youaredead = 0;
1203 return;
1206 detectmonstersdone:
1208 if (uarmf && how < GENOCIDED && uarmf->oartifact == ART_PRINCE_OF_PERSIA && !rn2(2) ) {
1209 pline("But wait...");
1210 pline("You respawn because you're the Prince of Persia!");
1212 if (wanttodie) {
1213 pline("Nyehehe-hehe-he, you would have lifesaved but you said you want your possessions identified! GAME OVER!");
1214 goto persiadone;
1217 if(u.uhpmax <= 0) u.uhpmax = 1; /* arbitrary */
1218 savelife(how);
1219 u.lifesavepenalty++;
1220 killer = 0;
1221 killer_format = 0;
1223 #ifdef LIVELOGFILE
1224 livelog_avert_death();
1225 #endif
1226 u.youaredead = 0;
1228 return;
1231 persiadone:
1233 /* Troll characters have a chance of reviving. --Amy */
1234 if (Race_if(PM_TROLLOR) && u.uhpmax > 10 && how < GENOCIDED && u.ulevel > 2 && rn2(4) ) {
1235 pline("But wait...");
1236 losexp("failed troll revival", TRUE, FALSE);
1237 if (u.uhpmax < 11) {
1238 int statxx;
1239 for (statxx = 0; statxx < A_MAX; statxx++) {
1240 ABASE(statxx) -= 1;
1241 AMAX(statxx) -= 1;
1242 if (ABASE(statxx) < ATTRABSMIN(statxx)) ABASE(statxx) = ATTRABSMIN(statxx);
1243 if (AMAX(statxx) < ATTRABSMIN(statxx)) AMAX(statxx) = ATTRABSMIN(statxx);
1245 u.uenmax -= rnz(50);
1246 if (u.uenmax < 0) u.uenmax = 0;
1247 if (u.uen > u.uenmax) u.uen = u.uenmax;
1248 skillcaploss();
1249 skillcaploss();
1250 skillcaploss();
1251 skillcaploss();
1252 skillcaploss();
1253 evilspellforget();
1254 eviltechincrease();
1255 evilskilldecrease();
1257 losexp("failed troll revival", TRUE, FALSE);
1258 badeffect();
1259 pline("You come back to life!");
1261 if (wanttodie) {
1262 pline("Nyehehe-hehe-he, you would have lifesaved but you said you want your possessions identified! GAME OVER!");
1263 goto trolldone;
1266 if(u.uhpmax <= 0) u.uhpmax = 1; /* arbitrary */
1267 savelife(how);
1268 u.lifesavepenalty++;
1269 killer = 0;
1270 killer_format = 0;
1272 #ifdef LIVELOGFILE
1273 livelog_avert_death();
1274 #endif
1275 u.youaredead = 0;
1277 return;
1280 trolldone:
1282 /* Felids have 9 lives --Amy */
1283 if (Race_if(PM_FELID) && u.uhpmax > 10 && how < GENOCIDED && u.ulevel > 2 && (u.felidlives > 1) ) {
1284 u.felidlives--;
1285 pline("But wait...");
1286 losexp("failed felid revival", TRUE, FALSE);
1287 if (u.uhpmax < 11) {
1288 int statxx;
1289 for (statxx = 0; statxx < A_MAX; statxx++) {
1290 ABASE(statxx) -= 1;
1291 AMAX(statxx) -= 1;
1292 if (ABASE(statxx) < ATTRABSMIN(statxx)) ABASE(statxx) = ATTRABSMIN(statxx);
1293 if (AMAX(statxx) < ATTRABSMIN(statxx)) AMAX(statxx) = ATTRABSMIN(statxx);
1295 u.uenmax -= rnz(50);
1296 if (u.uenmax < 0) u.uenmax = 0;
1297 if (u.uen > u.uenmax) u.uen = u.uenmax;
1298 skillcaploss();
1299 skillcaploss();
1300 skillcaploss();
1301 skillcaploss();
1302 skillcaploss();
1303 evilspellforget();
1304 eviltechincrease();
1305 evilskilldecrease();
1307 losexp("failed felid revival", TRUE, FALSE);
1308 badeffect();
1309 if (!rn2(5)) reallybadeffect();
1310 pline("Thanks to being a felid, you only used up one of your lives, and have %d left!", u.felidlives);
1312 if (wanttodie) {
1313 pline("Nyehehe-hehe-he, you would have lifesaved but you said you want your possessions identified! GAME OVER!");
1314 goto feliddone;
1317 if(u.uhpmax <= 0) u.uhpmax = 1; /* arbitrary */
1318 savelife(how);
1319 u.lifesavepenalty++;
1320 killer = 0;
1321 killer_format = 0;
1323 #ifdef LIVELOGFILE
1324 livelog_avert_death();
1325 #endif
1326 u.youaredead = 0;
1328 return;
1331 feliddone:
1333 if (u.extralives && how <= GENOCIDED) {
1334 pline("But wait...");
1335 pline("You have an extra life!");
1337 if (wanttodie) {
1338 pline("Nyehehe-hehe-he, you would have lifesaved but you said you want your possessions identified! GAME OVER!");
1339 u.extralives--;
1340 goto oneupdone;
1343 if(u.uhpmax <= 0) u.uhpmax = 1; /* arbitrary */
1344 savelife(how);
1345 u.lifesavepenalty++;
1346 u.extralives--;
1347 killer = 0;
1348 killer_format = 0;
1350 #ifdef LIVELOGFILE
1351 livelog_avert_death();
1352 #endif
1353 u.youaredead = 0;
1355 return;
1358 oneupdone:
1360 if ((Second_chance || Lifesaved) && how <= GENOCIDED) {
1362 boolean genomold = FALSE;
1363 if (uamul && uamul->oartifact == ART_REAL_GENOMOLD) genomold = TRUE;
1365 pline("But wait...");
1366 makeknown(Lifesaved ? AMULET_OF_LIFE_SAVING : AMULET_OF_SECOND_CHANCE);
1367 Your("%s %s!", Lifesaved ? "medallion" : "amulet",
1368 !Blind ? "begins to glow" : "feels warm");
1369 if (how == CHOKING) You("vomit ...");
1370 You_feel("much better!");
1371 pline_The("medallion crumbles to dust!");
1372 useup(uamul);
1374 if (wanttodie) {
1375 pline("Nyehehe-hehe-he, you would have lifesaved but you said you want your possessions identified! GAME OVER!");
1376 goto lsdone;
1379 (void) adjattrib(A_CON, -1, TRUE, TRUE);
1380 if(u.uhpmax <= 0) u.uhpmax = 10; /* arbitrary */
1381 savelife(how);
1382 u.lifesavepenalty++;
1384 if (genomold && (how == GENOCIDED)) {
1385 if (Race_if(PM_UNGENOMOLD)) {
1386 polyself(FALSE);
1387 } else {
1388 mvitals[urole.malenum].mvflags &= ~G_GENOD;
1389 mvitals[urace.malenum].mvflags &= ~G_GENOD;
1390 if (urole.femalenum != NON_PM) mvitals[urole.femalenum].mvflags &= ~G_GENOD;
1391 if (urace.femalenum != NON_PM) mvitals[urace.femalenum].mvflags &= ~G_GENOD;
1395 if (!genomold && (how == GENOCIDED))
1396 pline("Unfortunately you are still genocided...");
1397 else {
1399 killer = 0;
1400 killer_format = 0;
1401 #ifdef LIVELOGFILE
1402 livelog_avert_death();
1403 #endif
1404 u.youaredead = 0;
1406 return;
1409 lsdone:
1411 if ((ublindf && ublindf->oartifact == ART_FLOTATION_DEVICE) && how <= GENOCIDED) {
1412 pline("But wait...");
1413 Your("pair of lenses %s!", !Blind ? "begins to glow" : "feels warm");
1414 if (how == CHOKING) You("vomit ...");
1415 You_feel("much better!");
1416 pline_The("lenses crumble to dust!");
1417 useup(ublindf);
1419 if (wanttodie) {
1420 pline("Nyehehe-hehe-he, you would have lifesaved but you said you want your possessions identified! GAME OVER!");
1421 goto flotationdone;
1424 (void) adjattrib(A_CON, -1, TRUE, TRUE);
1425 if(u.uhpmax <= 0) u.uhpmax = 10; /* arbitrary */
1426 savelife(how);
1427 u.lifesavepenalty++;
1428 if (how == GENOCIDED)
1429 pline("Unfortunately you are still genocided...");
1430 else {
1432 killer = 0;
1433 killer_format = 0;
1434 #ifdef LIVELOGFILE
1435 livelog_avert_death();
1436 #endif
1437 u.youaredead = 0;
1439 return;
1442 flotationdone:
1444 if ((uarm && uarm->oartifact == ART_HOW_AS_CRUDE_LIVER) && how <= GENOCIDED) {
1445 pline("But wait...");
1446 Your("armor %s!", !Blind ? "begins to glow" : "feels warm");
1447 if (how == CHOKING) You("vomit ...");
1448 You_feel("much better!");
1449 pline_The("armor crumbles to dust!");
1450 useup(uarm);
1452 if (wanttodie) {
1453 pline("Nyehehe-hehe-he, you would have lifesaved but you said you want your possessions identified! GAME OVER!");
1454 goto crudeliverdone;
1457 (void) adjattrib(A_CON, -1, TRUE, TRUE);
1458 if(u.uhpmax <= 0) u.uhpmax = 10; /* arbitrary */
1459 savelife(how);
1460 u.lifesavepenalty++;
1461 if (how == GENOCIDED)
1462 pline("Unfortunately you are still genocided...");
1463 else {
1465 killer = 0;
1466 killer_format = 0;
1467 #ifdef LIVELOGFILE
1468 livelog_avert_death();
1469 #endif
1470 u.youaredead = 0;
1472 return;
1475 crudeliverdone:
1477 if ((uarmh && uarmh->oartifact == ART_HELM_OF_UNDEATH) && how <= GENOCIDED) {
1478 pline("But wait...");
1479 Your("helmet %s!", !Blind ? "begins to glow" : "feels warm");
1480 if (how == CHOKING) You("vomit ...");
1481 You_feel("much better!");
1482 pline_The("armor crumbles to dust!");
1483 useup(uarmh);
1485 if (wanttodie) {
1486 pline("Nyehehe-hehe-he, you would have lifesaved but you said you want your possessions identified! GAME OVER!");
1487 goto undeathdone;
1490 (void) adjattrib(A_CON, -1, TRUE, TRUE);
1491 if(u.uhpmax <= 0) u.uhpmax = 10; /* arbitrary */
1492 savelife(how);
1493 u.lifesavepenalty++;
1494 if (how == GENOCIDED)
1495 pline("Unfortunately you are still genocided...");
1496 else {
1498 killer = 0;
1499 killer_format = 0;
1500 #ifdef LIVELOGFILE
1501 livelog_avert_death();
1502 #endif
1503 u.youaredead = 0;
1505 return;
1508 undeathdone:
1510 if ((uwep && uwep->oartifact == ART_STELLARIS_MATERIA) && how <= GENOCIDED) {
1511 pline("But wait...");
1512 Your("weapon %s!", !Blind ? "begins to glow" : "feels warm");
1513 if (how == CHOKING) You("vomit ...");
1514 You_feel("much better!");
1515 pline_The("weapon crumbles to dust!");
1516 useup(uwep);
1518 if (wanttodie) {
1519 pline("Nyehehe-hehe-he, you would have lifesaved but you said you want your possessions identified! GAME OVER!");
1520 goto stellarisdone;
1523 (void) adjattrib(A_CON, -1, TRUE, TRUE);
1524 if(u.uhpmax <= 0) u.uhpmax = 10; /* arbitrary */
1525 savelife(how);
1526 u.lifesavepenalty++;
1527 if (how == GENOCIDED)
1528 pline("Unfortunately you are still genocided...");
1529 else {
1531 killer = 0;
1532 killer_format = 0;
1533 #ifdef LIVELOGFILE
1534 livelog_avert_death();
1535 #endif
1536 u.youaredead = 0;
1538 return;
1541 stellarisdone:
1543 if ((uwep && uwep->oartifact == ART_BLACK_MARK) && how <= GENOCIDED) {
1544 pline("But wait...");
1545 Your("weapon %s!", !Blind ? "begins to glow" : "feels warm");
1546 if (how == CHOKING) You("vomit ...");
1547 You_feel("much better!");
1548 pline_The("weapon crumbles to dust!");
1549 useup(uwep);
1551 if (wanttodie) {
1552 pline("Nyehehe-hehe-he, you would have lifesaved but you said you want your possessions identified! GAME OVER!");
1553 goto blackmarkdone;
1556 (void) adjattrib(A_CON, -1, TRUE, TRUE);
1557 if(u.uhpmax <= 0) u.uhpmax = 10; /* arbitrary */
1558 savelife(how);
1559 u.lifesavepenalty++;
1560 if (how == GENOCIDED)
1561 pline("Unfortunately you are still genocided...");
1562 else {
1564 killer = 0;
1565 killer_format = 0;
1566 #ifdef LIVELOGFILE
1567 livelog_avert_death();
1568 #endif
1569 u.youaredead = 0;
1571 return;
1574 blackmarkdone:
1576 if ((uarmu && uarmu->oartifact == ART_TILLMANN_S_TARGET) && how <= GENOCIDED) {
1577 pline("But wait...");
1578 Your("shirt %s!", !Blind ? "begins to glow" : "feels warm");
1579 if (how == CHOKING) You("vomit ...");
1580 You_feel("much better!");
1581 pline_The("shirt crumbles to dust!");
1582 useup(uarmu);
1584 if (wanttodie) {
1585 pline("Nyehehe-hehe-he, you would have lifesaved but you said you want your possessions identified! GAME OVER!");
1586 goto tillmanndone;
1589 (void) adjattrib(A_CON, -1, TRUE, TRUE);
1590 if(u.uhpmax <= 0) u.uhpmax = 10; /* arbitrary */
1591 savelife(how);
1592 u.lifesavepenalty++;
1593 if (how == GENOCIDED)
1594 pline("Unfortunately you are still genocided...");
1595 else {
1597 killer = 0;
1598 killer_format = 0;
1599 #ifdef LIVELOGFILE
1600 livelog_avert_death();
1601 #endif
1602 u.youaredead = 0;
1604 return;
1607 tillmanndone:
1609 if ((uarmf && uarmf->oartifact == ART_GODLY_POSTMAN) && how <= GENOCIDED) {
1610 pline("But wait...");
1611 Your("pair of boots %s!", !Blind ? "begins to glow" : "feels warm");
1612 if (how == CHOKING) You("vomit ...");
1613 You_feel("much better!");
1614 pline_The("boots crumble to dust!");
1615 useup(uarmf);
1617 if (wanttodie) {
1618 pline("Nyehehe-hehe-he, you would have lifesaved but you said you want your possessions identified! GAME OVER!");
1619 goto postmandone;
1622 (void) adjattrib(A_CON, -1, TRUE, TRUE);
1623 if(u.uhpmax <= 0) u.uhpmax = 10; /* arbitrary */
1624 savelife(how);
1625 u.lifesavepenalty++;
1626 if (how == GENOCIDED)
1627 pline("Unfortunately you are still genocided...");
1628 else {
1630 killer = 0;
1631 killer_format = 0;
1632 #ifdef LIVELOGFILE
1633 livelog_avert_death();
1634 #endif
1635 u.youaredead = 0;
1637 return;
1640 postmandone:
1642 if ((uarmf && uarmf->oartifact == ART_DEATHHEAD) && how <= GENOCIDED) {
1643 pline("But wait...");
1644 Your("pair of boots %s!", !Blind ? "begins to glow" : "feels warm");
1645 if (how == CHOKING) You("vomit ...");
1646 You_feel("much better!");
1647 pline_The("boots crumble to dust!");
1648 useup(uarmf);
1650 if (wanttodie) {
1651 pline("Nyehehe-hehe-he, you would have lifesaved but you said you want your possessions identified! GAME OVER!");
1652 goto deathheaddone;
1655 (void) adjattrib(A_CON, -1, TRUE, TRUE);
1656 if(u.uhpmax <= 0) u.uhpmax = 10; /* arbitrary */
1657 savelife(how);
1658 u.lifesavepenalty++;
1659 if (how == GENOCIDED)
1660 pline("Unfortunately you are still genocided...");
1661 else {
1663 killer = 0;
1664 killer_format = 0;
1665 #ifdef LIVELOGFILE
1666 livelog_avert_death();
1667 #endif
1668 u.youaredead = 0;
1670 return;
1673 deathheaddone:
1675 if ((uarmf && uarmf->oartifact == ART_PLAY_THE_GAME_YOURSELF) && how <= GENOCIDED) {
1676 pline("But wait...");
1677 Your("pair of boots %s!", !Blind ? "begins to glow" : "feels warm");
1678 if (how == CHOKING) You("vomit ...");
1679 You_feel("much better!");
1680 pline_The("boots crumble to dust!");
1681 useup(uarmf);
1683 if (wanttodie) {
1684 pline("Nyehehe-hehe-he, you would have lifesaved but you said you want your possessions identified! GAME OVER!");
1685 goto playgamedone;
1688 (void) adjattrib(A_CON, -1, TRUE, TRUE);
1689 if(u.uhpmax <= 0) u.uhpmax = 10; /* arbitrary */
1690 savelife(how);
1691 u.lifesavepenalty++;
1692 if (how == GENOCIDED)
1693 pline("Unfortunately you are still genocided...");
1694 else {
1696 killer = 0;
1697 killer_format = 0;
1698 #ifdef LIVELOGFILE
1699 livelog_avert_death();
1700 #endif
1701 u.youaredead = 0;
1703 return;
1706 playgamedone:
1708 if (have_autohealpotion() && u.uhp < 1 && how < GENOCIDED) {
1710 register struct obj *prcstone;
1712 pline("But wait...");
1713 pline("gulp-gulp-gulp");
1714 if (how == CHOKING) You("vomit ...");
1715 You_feel("much better!");
1717 prcstone = carryingarti(ART_GULP_GULP_GULP);
1719 if (prcstone) {
1720 if (prcstone->quan > 1) {
1721 prcstone->quan -= 1;
1722 prcstone->owt = weight(prcstone);
1723 } else useupall(prcstone);
1724 } else { /* game over */
1725 pline("Except that for some reason the potion didn't work, so you only thought that you felt better and really you're just as dead as before!");
1726 goto gulpdone;
1729 if (wanttodie) {
1730 pline("Nyehehe-hehe-he, you would have lifesaved but you said you want your possessions identified! GAME OVER!");
1731 goto gulpdone;
1734 (void) adjattrib(A_CON, -1, TRUE, TRUE);
1735 if(u.uhpmax <= 0) u.uhpmax = 10; /* arbitrary */
1736 savelife(how);
1737 u.lifesavepenalty++;
1738 if (how == GENOCIDED)
1739 pline("Unfortunately you are still genocided...");
1740 else {
1742 killer = 0;
1743 killer_format = 0;
1744 #ifdef LIVELOGFILE
1745 livelog_avert_death();
1746 #endif
1747 u.youaredead = 0;
1749 return;
1752 gulpdone:
1754 if (uamul && uamul->otyp == AMULET_OF_THIRD_CHANCE && u.uhp < 1 && how < GENOCIDED) {
1756 pline("But wait...");
1757 makeknown(AMULET_OF_THIRD_CHANCE);
1758 Your("amulet %s!", !Blind ? "begins to glow" : "feels warm");
1759 if (how == CHOKING) You("vomit ...");
1760 You_feel("much better!");
1762 if (uamul->oartifact == ART_FOURTH_CHANCE) {
1763 if (rn2(2)) {
1764 if (uamul->obrittle >= 3) {
1765 pline_The("medallion crumbles to dust!");
1766 useup(uamul);
1767 } else {
1768 uamul->obrittle++;
1769 pline_The("medallion dulls quite a bit, but remains intact for now.");
1771 } else {
1772 if (uamul->obrittle2 >= 3) {
1773 pline_The("medallion crumbles to dust!");
1774 useup(uamul);
1775 } else {
1776 uamul->obrittle2++;
1777 pline_The("medallion dulls quite a bit, but remains intact for now.");
1780 } else {
1781 pline_The("medallion crumbles to dust!");
1782 useup(uamul);
1785 if (wanttodie) {
1786 pline("Nyehehe-hehe-he, you would have lifesaved but you said you want your possessions identified! GAME OVER!");
1787 goto thirddone;
1790 (void) adjattrib(A_CON, -1, TRUE, TRUE);
1791 if(u.uhpmax <= 0) u.uhpmax = 10; /* arbitrary */
1792 savelife(how);
1793 u.lifesavepenalty++;
1794 if (how == GENOCIDED)
1795 pline("Unfortunately you are still genocided...");
1796 else {
1798 killer = 0;
1799 killer_format = 0;
1800 #ifdef LIVELOGFILE
1801 livelog_avert_death();
1802 #endif
1803 u.youaredead = 0;
1805 return;
1808 thirddone:
1810 if ((uarm && uarm->oartifact == ART_VERSUS_INSTADEATH) && (u.uhp > 0) && (u.uhpmax > 0) && how < GENOCIDED) {
1811 pline("But wait...");
1812 Your("armor %s!", !Blind ? "begins to glow" : "feels warm");
1813 if (how == CHOKING) You("vomit ...");
1814 You_feel("much better!");
1815 pline_The("armor crumbles to dust!");
1816 useup(uarm);
1818 if (wanttodie) {
1819 pline("Nyehehe-hehe-he, you would have lifesaved but you said you want your possessions identified! GAME OVER!");
1820 goto versusinstadone;
1823 (void) adjattrib(A_CON, -1, TRUE, TRUE);
1824 if(u.uhpmax <= 0) u.uhpmax = 10; /* arbitrary */
1825 savelife(how);
1826 u.lifesavepenalty++;
1827 if (how == GENOCIDED)
1828 pline("Unfortunately you are still genocided...");
1829 else {
1831 killer = 0;
1832 killer_format = 0;
1833 #ifdef LIVELOGFILE
1834 livelog_avert_death();
1835 #endif
1836 u.youaredead = 0;
1838 return;
1841 versusinstadone:
1843 if ((uarmh && uarmh->oartifact == ART_ONE_FREE) && !uarmh->obrittle && how < GENOCIDED) {
1844 pline("But wait...");
1845 Your("helmet %s!", !Blind ? "begins to glow" : "feels warm");
1846 if (how == CHOKING) You("vomit ...");
1847 You_feel("much better!");
1848 uarmh->obrittle = TRUE;
1849 pline_The("helmet becomes brittle!");
1851 if (wanttodie) {
1852 pline("Nyehehe-hehe-he, you would have lifesaved but you said you want your possessions identified! GAME OVER!");
1853 goto helmartidone;
1856 (void) adjattrib(A_CON, -1, TRUE, TRUE);
1857 if(u.uhpmax <= 0) u.uhpmax = 10; /* arbitrary */
1858 savelife(how);
1859 u.lifesavepenalty++;
1860 if (how == GENOCIDED)
1861 pline("Unfortunately you are still genocided...");
1862 else {
1864 killer = 0;
1865 killer_format = 0;
1866 #ifdef LIVELOGFILE
1867 livelog_avert_death();
1868 #endif
1869 u.youaredead = 0;
1871 return;
1874 helmartidone:
1876 if ((uarmh && uarmh->otyp == HELMET_OF_SAVING) && (u.uhp > 0) && (u.uhpmax > 0) && how < GENOCIDED) {
1877 pline("But wait...");
1878 Your("helmet %s!", !Blind ? "begins to glow" : "feels warm");
1879 if (how == CHOKING) You("vomit ...");
1880 You_feel("much better!");
1881 pline_The("helmet is blown away!");
1882 useup(uarmh);
1884 if (wanttodie) {
1885 pline("Nyehehe-hehe-he, you would have lifesaved but you said you want your possessions identified! GAME OVER!");
1886 goto helmsavingdone;
1889 (void) adjattrib(A_CON, -1, TRUE, TRUE);
1890 if(u.uhpmax <= 0) u.uhpmax = 10; /* arbitrary */
1891 savelife(how);
1892 u.lifesavepenalty++;
1893 if (how == GENOCIDED)
1894 pline("Unfortunately you are still genocided...");
1895 else {
1897 killer = 0;
1898 killer_format = 0;
1899 #ifdef LIVELOGFILE
1900 livelog_avert_death();
1901 #endif
1902 u.youaredead = 0;
1904 return;
1907 helmsavingdone:
1909 if ((uarmf && uarmf->oartifact == ART_DON_T_DIE_WHILE_IN_THERE) && (u.uhp > 0) && (u.uhpmax > 0) && how < GENOCIDED) {
1910 boolean overshoesave = FALSE;
1911 if (In_greencross(&u.uz) || In_mainframe(&u.uz) || In_gammacaves(&u.uz) || In_forging(&u.uz) || In_ordered(&u.uz) || In_deadground(&u.uz) || In_subquest(&u.uz) || In_rivalquest(&u.uz) || In_yendorian(&u.uz) || In_bellcaves(&u.uz)) overshoesave = TRUE;
1913 if (overshoesave) {
1915 pline("But wait...");
1916 Your("pair of boots %s!", !Blind ? "begins to glow" : "feels warm");
1917 if (how == CHOKING) You("vomit ...");
1918 You_feel("much better!");
1919 pline_The("boots crumble to dust!");
1920 useup(uarmf);
1922 if (wanttodie) {
1923 pline("Nyehehe-hehe-he, you would have lifesaved but you said you want your possessions identified! GAME OVER!");
1924 goto overshoedone;
1927 (void) adjattrib(A_CON, -1, TRUE, TRUE);
1928 if(u.uhpmax <= 0) u.uhpmax = 10; /* arbitrary */
1929 savelife(how);
1930 u.lifesavepenalty++;
1931 if (how == GENOCIDED)
1932 pline("Unfortunately you are still genocided...");
1933 else {
1935 killer = 0;
1936 killer_format = 0;
1937 #ifdef LIVELOGFILE
1938 livelog_avert_death();
1939 #endif
1940 u.youaredead = 0;
1942 return;
1946 overshoedone:
1948 if (uimplant && uimplant->oartifact == ART_DECAPITATION_UP && how <= GENOCIDED) {
1949 pline("But wait...");
1950 Your("implant %s!", !Blind ? "begins to glow" : "feels warm");
1951 You_feel("much better!");
1952 pline_The("implant crumbles to dust!");
1953 useup(uimplant);
1955 if (wanttodie) {
1956 pline("Nyehehe-hehe-he, you would have lifesaved but you said you want your possessions identified! GAME OVER!");
1957 goto implantdone;
1960 (void) adjattrib(A_CON, -1, TRUE, TRUE);
1961 if(u.uhpmax <= 0) u.uhpmax = 10; /* arbitrary */
1962 savelife(how);
1963 u.lifesavepenalty++;
1964 if (how == GENOCIDED)
1965 pline("Unfortunately you are still genocided...");
1966 else {
1968 killer = 0;
1969 killer_format = 0;
1970 #ifdef LIVELOGFILE
1971 livelog_avert_death();
1972 #endif
1973 u.youaredead = 0;
1975 return;
1980 implantdone:
1982 if (powerfulimplants() && uimplant && uimplant->oartifact == ART_THROW_MY_LIFE_AWAY && how <= GENOCIDED) {
1983 pline("But wait...");
1984 Your("implant %s!", !Blind ? "begins to glow" : "feels warm");
1985 You_feel("much better!");
1986 pline_The("implant crumbles to dust!");
1987 useup(uimplant);
1989 if (wanttodie) {
1990 pline("Nyehehe-hehe-he, you would have lifesaved but you said you want your possessions identified! GAME OVER!");
1991 goto implantdone2;
1994 (void) adjattrib(A_CON, -1, TRUE, TRUE);
1995 if(u.uhpmax <= 0) u.uhpmax = 10; /* arbitrary */
1996 savelife(how);
1997 u.lifesavepenalty++;
1998 if (how == GENOCIDED)
1999 pline("Unfortunately you are still genocided...");
2000 else {
2002 killer = 0;
2003 killer_format = 0;
2004 #ifdef LIVELOGFILE
2005 livelog_avert_death();
2006 #endif
2007 u.youaredead = 0;
2009 return;
2014 implantdone2:
2016 if ((uarmf && uarmf->otyp == OMEGA_HEELS) && u.ulevel >= 3 && ABASE(A_STR) > 1 && ABASE(A_DEX) > 1 && ABASE(A_CON) > 1 && ABASE(A_INT) > 1 && ABASE(A_WIS) > 1 && ABASE(A_CHA) > 1 && (u.uhp > 0) && (u.uhpmax > 0) && how < GENOCIDED) {
2018 pline("But wait...");
2020 losexp("omega heels", TRUE, FALSE);
2021 losexp("omega heels", TRUE, FALSE);
2022 ABASE(A_STR) -= 1;
2023 AMAX(A_STR) -= 1;
2024 ABASE(A_DEX) -= 1;
2025 AMAX(A_DEX) -= 1;
2026 ABASE(A_INT) -= 1;
2027 AMAX(A_INT) -= 1;
2028 ABASE(A_WIS) -= 1;
2029 AMAX(A_WIS) -= 1;
2030 ABASE(A_CON) -= 1;
2031 AMAX(A_CON) -= 1;
2032 ABASE(A_CHA) -= 1;
2033 AMAX(A_CHA) -= 1;
2034 flags.botl = TRUE;
2036 Your("pair of boots %s!", !Blind ? "begins to glow" : "feels warm");
2037 if (how == CHOKING) You("vomit ...");
2038 You_feel("much better!");
2040 if (wanttodie) {
2041 pline("Nyehehe-hehe-he, you would have lifesaved but you said you want your possessions identified! GAME OVER!");
2042 goto omegadone;
2045 (void) adjattrib(A_CON, -1, TRUE, TRUE);
2046 if(u.uhpmax <= 0) u.uhpmax = 10; /* arbitrary */
2047 savelife(how);
2048 u.lifesavepenalty++;
2049 if (how == GENOCIDED)
2050 pline("Unfortunately you are still genocided...");
2051 else {
2053 killer = 0;
2054 killer_format = 0;
2055 #ifdef LIVELOGFILE
2056 livelog_avert_death();
2057 #endif
2058 u.youaredead = 0;
2060 return;
2063 omegadone:
2065 if (MenuIsBugged && how < GENOCIDED) {
2066 pline("But wait! You still have the menu bug!");
2068 if (yn_function("Come back to life?", ynchars, 'y') == 'y' ) {
2070 if (wanttodie) {
2071 pline("Nyehehe-hehe-he, you would have lifesaved but you said you want your possessions identified! GAME OVER!");
2072 goto menunosedone;
2075 if (u.ulevel > 2) {
2076 losexp("menu bug", TRUE, FALSE);
2077 losexp("menu bug", TRUE, FALSE);
2078 pline("You hit the 'exit' button to escape from the grave! There you are again, back from the dead...");
2079 if(u.uhpmax <= 0) u.uhpmax = 1; /* arbitrary */
2080 savelife(how);
2081 killer = 0;
2082 killer_format = 0;
2084 /* lose all items */
2086 while (invent) {
2087 for (otmp = invent; otmp; otmp = otmp2) {
2088 otmp2 = otmp->nobj;
2090 if (evades_destruction(otmp) ) dropx(otmp);
2091 else {
2092 delete_contents(otmp);
2093 useup(otmp);}
2097 /* lose all spells */
2098 for (n = 0; n < MAXSPELL && spellid(n) != NO_SPELL; n++) {
2099 spellid(n) = NO_SPELL;
2102 if (Aggravate_monster) {
2103 u.aggravation = 1;
2104 reset_rndmonst(NON_PM);
2107 (void) makemon(mkclass(S_HUMAN,0), u.ux, u.uy, NO_MM_FLAGS);
2108 (void) makemon(mkclass(S_HUMANOID,0), u.ux, u.uy, NO_MM_FLAGS);
2109 (void) makemon(mkclass(S_DEMON,0), u.ux, u.uy, NO_MM_FLAGS);
2110 (void) makemon(mkclass(S_GNOME,0), u.ux, u.uy, NO_MM_FLAGS);
2111 (void) makemon(mkclass(S_OGRE,0), u.ux, u.uy, NO_MM_FLAGS);
2112 (void) makemon(mkclass(S_GIANT,0), u.ux, u.uy, NO_MM_FLAGS);
2113 (void) makemon(mkclass(S_KOP,0), u.ux, u.uy, NO_MM_FLAGS);
2114 (void) makemon(mkclass(S_ORC,0), u.ux, u.uy, NO_MM_FLAGS);
2116 u.aggravation = 0;
2118 (void) safe_teleds_normalterrain(FALSE);
2120 #ifdef LIVELOGFILE
2121 livelog_avert_death();
2122 #endif
2123 u.youaredead = 0;
2125 return;
2128 else pline("You frantically hit the 'exit' button to escape from the grave... but it doesn't work...");
2133 menunosedone:
2135 if ((flags.female && uarmc && uarmc->oartifact == ART_TOMORROW_WENDY_S_CHOICENA) && how < GENOCIDED) {
2136 pline("But wait! You have perilous life saving!");
2138 if (yn_function("Come back to life?", ynchars, 'y') == 'y' ) {
2140 if (wanttodie) {
2141 pline("Nyehehe-hehe-he, you would have lifesaved but you said you want your possessions identified! GAME OVER!");
2142 goto wendydone;
2145 if (u.ulevel > 2) {
2146 losexp("wendy's choice", TRUE, FALSE);
2147 losexp("wendy's choice", TRUE, FALSE);
2148 pline("You made the conscious choice to rise from the dead!");
2149 if(u.uhpmax <= 0) u.uhpmax = 1; /* arbitrary */
2150 savelife(how);
2151 killer = 0;
2152 killer_format = 0;
2154 /* lose all items */
2156 while (invent) {
2157 for (otmp = invent; otmp; otmp = otmp2) {
2158 otmp2 = otmp->nobj;
2160 if (evades_destruction(otmp) ) dropx(otmp);
2161 else {
2162 delete_contents(otmp);
2163 useup(otmp);}
2167 /* lose all spells */
2168 for (n = 0; n < MAXSPELL && spellid(n) != NO_SPELL; n++) {
2169 spellid(n) = NO_SPELL;
2172 if (Aggravate_monster) {
2173 u.aggravation = 1;
2174 reset_rndmonst(NON_PM);
2177 (void) makemon(mkclass(S_HUMAN,0), u.ux, u.uy, NO_MM_FLAGS);
2178 (void) makemon(mkclass(S_HUMANOID,0), u.ux, u.uy, NO_MM_FLAGS);
2179 (void) makemon(mkclass(S_DEMON,0), u.ux, u.uy, NO_MM_FLAGS);
2180 (void) makemon(mkclass(S_GNOME,0), u.ux, u.uy, NO_MM_FLAGS);
2181 (void) makemon(mkclass(S_OGRE,0), u.ux, u.uy, NO_MM_FLAGS);
2182 (void) makemon(mkclass(S_GIANT,0), u.ux, u.uy, NO_MM_FLAGS);
2183 (void) makemon(mkclass(S_KOP,0), u.ux, u.uy, NO_MM_FLAGS);
2184 (void) makemon(mkclass(S_ORC,0), u.ux, u.uy, NO_MM_FLAGS);
2186 u.aggravation = 0;
2188 (void) safe_teleds_normalterrain(FALSE);
2190 #ifdef LIVELOGFILE
2191 livelog_avert_death();
2192 #endif
2193 u.youaredead = 0;
2195 return;
2198 else pline("You should have listened to the voices you heard yesterday, they said: 'Tomorrow, Wendy, you're going to die.'");
2202 wendydone:
2204 if ((uwep && uwep->oartifact == ART_MR__OF_HIGH_HEELS && uarm && objects[uarm->otyp].oc_color == CLR_BLACK) && how < GENOCIDED) {
2205 pline("But wait! You have perilous life saving!");
2207 if (yn_function("Come back to life?", ynchars, 'y') == 'y' ) {
2209 if (wanttodie) {
2210 pline("Nyehehe-hehe-he, you would have lifesaved but you said you want your possessions identified! GAME OVER!");
2211 goto mrhighheeldone;
2214 if (u.ulevel > 2) {
2215 losexp("Mr. High Heel", TRUE, FALSE);
2216 losexp("Mr. High Heel", TRUE, FALSE);
2217 pline("You are the Mr. of high heels, and therefore don't die!");
2218 if(u.uhpmax <= 0) u.uhpmax = 1; /* arbitrary */
2219 savelife(how);
2220 killer = 0;
2221 killer_format = 0;
2223 /* lose all items */
2225 while (invent) {
2226 for (otmp = invent; otmp; otmp = otmp2) {
2227 otmp2 = otmp->nobj;
2229 if (evades_destruction(otmp) ) dropx(otmp);
2230 else {
2231 delete_contents(otmp);
2232 useup(otmp);}
2236 /* lose all spells */
2237 for (n = 0; n < MAXSPELL && spellid(n) != NO_SPELL; n++) {
2238 spellid(n) = NO_SPELL;
2241 if (Aggravate_monster) {
2242 u.aggravation = 1;
2243 reset_rndmonst(NON_PM);
2246 (void) makemon(mkclass(S_HUMAN,0), u.ux, u.uy, NO_MM_FLAGS);
2247 (void) makemon(mkclass(S_HUMANOID,0), u.ux, u.uy, NO_MM_FLAGS);
2248 (void) makemon(mkclass(S_DEMON,0), u.ux, u.uy, NO_MM_FLAGS);
2249 (void) makemon(mkclass(S_GNOME,0), u.ux, u.uy, NO_MM_FLAGS);
2250 (void) makemon(mkclass(S_OGRE,0), u.ux, u.uy, NO_MM_FLAGS);
2251 (void) makemon(mkclass(S_GIANT,0), u.ux, u.uy, NO_MM_FLAGS);
2252 (void) makemon(mkclass(S_KOP,0), u.ux, u.uy, NO_MM_FLAGS);
2253 (void) makemon(mkclass(S_ORC,0), u.ux, u.uy, NO_MM_FLAGS);
2255 u.aggravation = 0;
2257 (void) safe_teleds_normalterrain(FALSE);
2259 #ifdef LIVELOGFILE
2260 livelog_avert_death();
2261 #endif
2262 u.youaredead = 0;
2264 return;
2267 else pline("Sadly, you lack the strength to get back up, so you stay dead.");
2271 mrhighheeldone:
2273 if (StrongStoned_chiller && how < GENOCIDED) {
2274 pline("But wait! You have perilous life saving!");
2276 if (yn_function("Come back to life?", ynchars, 'y') == 'y' ) {
2278 if (wanttodie) {
2279 pline("Nyehehe-hehe-he, you would have lifesaved but you said you want your possessions identified! GAME OVER!");
2280 goto perilousdone;
2283 if (u.ulevel > 2) {
2284 losexp("totally stoned chiller", TRUE, FALSE);
2285 losexp("totally stoned chiller", TRUE, FALSE);
2286 pline("You hit the 'exit' button to escape from the grave! There you are again, back from the dead...");
2287 if(u.uhpmax <= 0) u.uhpmax = 1; /* arbitrary */
2288 savelife(how);
2289 killer = 0;
2290 killer_format = 0;
2292 /* lose all items */
2294 while (invent) {
2295 for (otmp = invent; otmp; otmp = otmp2) {
2296 otmp2 = otmp->nobj;
2298 if (evades_destruction(otmp) ) dropx(otmp);
2299 else {
2300 delete_contents(otmp);
2301 useup(otmp);}
2305 /* lose all spells */
2306 for (n = 0; n < MAXSPELL && spellid(n) != NO_SPELL; n++) {
2307 spellid(n) = NO_SPELL;
2310 if (Aggravate_monster) {
2311 u.aggravation = 1;
2312 reset_rndmonst(NON_PM);
2315 (void) makemon(mkclass(S_HUMAN,0), u.ux, u.uy, NO_MM_FLAGS);
2316 (void) makemon(mkclass(S_HUMANOID,0), u.ux, u.uy, NO_MM_FLAGS);
2317 (void) makemon(mkclass(S_DEMON,0), u.ux, u.uy, NO_MM_FLAGS);
2318 (void) makemon(mkclass(S_GNOME,0), u.ux, u.uy, NO_MM_FLAGS);
2319 (void) makemon(mkclass(S_OGRE,0), u.ux, u.uy, NO_MM_FLAGS);
2320 (void) makemon(mkclass(S_GIANT,0), u.ux, u.uy, NO_MM_FLAGS);
2321 (void) makemon(mkclass(S_KOP,0), u.ux, u.uy, NO_MM_FLAGS);
2322 (void) makemon(mkclass(S_ORC,0), u.ux, u.uy, NO_MM_FLAGS);
2324 u.aggravation = 0;
2326 (void) safe_teleds_normalterrain(FALSE);
2328 #ifdef LIVELOGFILE
2329 livelog_avert_death();
2330 #endif
2331 u.youaredead = 0;
2333 return;
2336 else pline("You frantically hit the 'exit' button to escape from the grave... but it doesn't work...");
2341 perilousdone:
2343 if (Race_if(PM_RODNEYAN) && u.uhpmax > 10 && how < GENOCIDED) {
2344 pline("But you're Rodney, so your death isn't permanent!");
2346 if (yn_function("Revive?", ynchars, 'y') == 'y' ) {
2348 if (wanttodie) {
2349 pline("Nyehehe-hehe-he, you would have lifesaved but you said you want your possessions identified! GAME OVER!");
2350 goto rodneydone;
2353 if (u.ulevel > 2) {
2354 losexp("Rodneyan resurrection", TRUE, FALSE);
2355 if (u.uhpmax < 11) {
2356 int statxx;
2357 for (statxx = 0; statxx < A_MAX; statxx++) {
2358 ABASE(statxx) -= 1;
2359 AMAX(statxx) -= 1;
2360 if (ABASE(statxx) < ATTRABSMIN(statxx)) ABASE(statxx) = ATTRABSMIN(statxx);
2361 if (AMAX(statxx) < ATTRABSMIN(statxx)) AMAX(statxx) = ATTRABSMIN(statxx);
2363 u.uenmax -= rnz(50);
2364 if (u.uenmax < 0) u.uenmax = 0;
2365 if (u.uen > u.uenmax) u.uen = u.uenmax;
2366 skillcaploss();
2367 skillcaploss();
2368 skillcaploss();
2369 skillcaploss();
2370 skillcaploss();
2371 evilspellforget();
2372 eviltechincrease();
2373 evilskilldecrease();
2375 losexp("Rodneyan resurrection", TRUE, FALSE);
2376 pline("You reappear in good health!");
2377 if(u.uhpmax <= 0) u.uhpmax = 1; /* arbitrary */
2378 savelife(how);
2379 killer = 0;
2380 killer_format = 0;
2382 /* lose all items */
2384 while (invent) {
2385 for (otmp = invent; otmp; otmp = otmp2) {
2386 otmp2 = otmp->nobj;
2388 if (evades_destruction(otmp) ) dropx(otmp);
2389 else {
2390 delete_contents(otmp);
2391 useup(otmp);}
2395 /* lose all spells */
2396 for (n = 0; n < MAXSPELL && spellid(n) != NO_SPELL; n++) {
2397 spellid(n) = NO_SPELL;
2400 if (Aggravate_monster) {
2401 u.aggravation = 1;
2402 reset_rndmonst(NON_PM);
2405 (void) makemon(mkclass(S_HUMAN,0), u.ux, u.uy, NO_MM_FLAGS);
2406 (void) makemon(mkclass(S_HUMANOID,0), u.ux, u.uy, NO_MM_FLAGS);
2407 (void) makemon(mkclass(S_DEMON,0), u.ux, u.uy, NO_MM_FLAGS);
2408 (void) makemon(mkclass(S_GNOME,0), u.ux, u.uy, NO_MM_FLAGS);
2409 (void) makemon(mkclass(S_OGRE,0), u.ux, u.uy, NO_MM_FLAGS);
2410 (void) makemon(mkclass(S_GIANT,0), u.ux, u.uy, NO_MM_FLAGS);
2411 (void) makemon(mkclass(S_KOP,0), u.ux, u.uy, NO_MM_FLAGS);
2412 (void) makemon(mkclass(S_ORC,0), u.ux, u.uy, NO_MM_FLAGS);
2414 u.aggravation = 0;
2416 (void) safe_teleds_normalterrain(FALSE);
2418 #ifdef LIVELOGFILE
2419 livelog_avert_death();
2420 #endif
2421 u.youaredead = 0;
2423 return;
2426 else pline("Too bad! Your experience level is too low for revival to work...");
2431 rodneydone:
2433 /* if you triggered a bones trap, bad luck - you can now leave bones even if you disabled them :P --Amy */
2434 bones_ok = (iflags.bones || (BonesLevelChange || u.uprops[BONES_CHANGE].extrinsic || have_bonestone() || (uarmu && uarmu->oartifact == ART_ELVIS_S_BONES_FILE) ) ) && (how < GENOCIDED) && can_make_bones(); /* dthexpl patch */
2436 if ((
2437 #ifdef WIZARD
2438 wizard ||
2439 #endif
2440 discover) && (how <= GENOCIDED || how == TURNED_SLIME)) {
2441 if(yn("Die?") == 'y') goto die;
2442 pline("OK, so you don't %s.",
2443 (how == CHOKING) ? "choke" : "die");
2444 if(u.uhpmax <= 0) u.uhpmax = u.ulevel * 8; /* arbitrary */
2445 savelife(how);
2446 killer = 0;
2447 killer_format = 0;
2448 u.youaredead = 0;
2449 return;
2452 else if (iflags.death_expl && how <= GENOCIDED && !bones_ok &&
2453 #ifdef WIZARD
2454 !wizard &&
2455 #endif
2456 !discover) {
2457 u.hangupcheat = 666; /* Not "game over" yet, so let's prevent filthy cheaters from doing their thing --Amy */
2458 if(yn("Continue in explore mode?") == 'y') {
2459 enter_explore_mode();
2460 if (discover) goexplore = TRUE;
2461 u.youaredead = 0;
2465 if (how == ASCENDED) {
2467 u.weapon_slots += 20;
2469 /* Amy edit: allow the player to keep their character and go on playing if they ascend! */
2470 freeplaycheck:
2471 if (yn("CONGRATULATIONS!!! You've beaten the game. You can go on playing now if you want, and will gain 20 additional skill slots as a reward. Do you want to keep playing your character?") == 'y') {
2473 getlin ("You decided to keep playing your character. Please confirm your choice with yes [y/yes/no]",buf);
2474 (void) lcase (buf);
2475 if (!(strcmp (buf, "yes")) || !(strcmp (buf, "y")) || !(strcmp (buf, "ye")) || !(strcmp (buf, "ys"))) { /* yes, do go on playing after ascending */
2477 gofreeplay = TRUE;
2479 } else goto freeplaycheck;
2481 } else {
2482 getlin ("You decided to end the game here. Please confirm your choice with yes [y/yes/no]",buf);
2483 (void) lcase (buf);
2484 if (strcmp (buf, "yes") && strcmp (buf, "y") && strcmp (buf, "ye") && strcmp (buf, "ys")) goto freeplaycheck;
2485 /* else the game ends here */
2486 u.freeplaytransit = TRUE;
2487 /* the game is over anyway so it doesn't matter for gameplay purposes whether this check is true,
2488 * but we need it to ensure that your pets can ascend with you --Amy */
2495 * The game is now over...
2498 die:
2500 /* this would have been for junethack, but oh well... RIP */
2501 if (AssholeModeActive) {
2502 boolean havestartscummed = FALSE;
2503 if (moves < 501) havestartscummed = TRUE;
2504 if (u.ulevel < 6) havestartscummed = TRUE;
2505 if (havestartscummed) {
2506 killer_format = KILLED_BY;
2507 killer = "start scumming";
2508 if (!rn2(20)) pline("Dude, startscumming is so lame. Play the game properly instead!");
2512 if(u.uhpmax <= 0) u.uhpmax = 1; /* fixing a VERY annoying dump_techniques SIGFPE */
2513 u.hangupcheat = 0;
2514 if (!goexplore && !gofreeplay) {
2515 program_state.gameover = 1;
2516 /* in case of a subsequent panic(), there's no point trying to save */
2517 program_state.something_worth_saving = 0;
2518 #ifdef HANGUPHANDLING
2519 if (program_state.done_hup)
2520 done_stopprint++;
2521 #endif
2522 #ifdef DUMP_LOG
2523 /* D: Grab screen dump right here */
2524 if (dump_fn[0] && how != PANICKED && how != TRICKED) {
2525 dump_init();
2526 sprintf(pbuf, "%s, %s %s %s %s", playeraliasname,
2527 aligns[1 - u.ualign.type].adj,
2528 genders[flags.female].adj,
2529 urace.adj,
2530 (flags.female && urole.name.f)?
2531 urole.name.f : urole.name.m);
2532 dump("", pbuf);
2533 /* D: Add a line for clearance from the screen dump */
2534 dump("", "");
2535 dump_screen();
2538 if (lastmsg >= 0 && how != PANICKED && how != TRICKED) {
2539 char tmpbuf[BUFSZ];
2540 int i,j;
2541 dump("Latest messages", "");
2542 for (j = lastmsg + 1; j < DUMPMSGS + lastmsg + 1; j++) {
2543 i = j % DUMPMSGS;
2544 if (msgs[i] && strcmp(msgs[i], "") ) {
2545 if (msgs_count[i] == 1) {
2546 dump(" ", msgs[i]);
2547 } else {
2548 sprintf(tmpbuf, "%s (%dx)", msgs[i], msgs_count[i]);
2549 dump(" ", tmpbuf);
2553 dump("","");
2556 if (how != PANICKED && how != TRICKED) (void)doredraw();
2558 #endif /* DUMP_LOG */
2560 #ifdef WHEREIS_FILE
2561 delete_whereis();
2562 #endif
2564 } /* if (!goexplore) */
2565 /* render vision subsystem inoperative */
2566 iflags.vision_inited = 0;
2567 /* might have been killed while using a disposable item, so make sure
2568 it's gone prior to inventory disclosure and creation of bones data */
2569 inven_inuse(TRUE);
2571 #ifdef RECORD_REALTIME
2572 /* Update the realtime counter to reflect the playtime of the current
2573 * game. */
2574 realtime_data.realtime = get_realtime();
2575 #endif /* RECORD_REALTIME */
2577 /* Sometimes you die on the first move. Life's not fair.
2578 * On those rare occasions you get hosed immediately, go out
2579 * smiling... :-) -3.
2581 if (Frozen) pline("Your body shatters and melts into ice cubes."); /* Diablo 2 */
2583 if (botl_score() == 0 && how < PANICKED)
2584 pline("You didn't even score a single point. You noob!");
2586 if (moves <= 1 && how < PANICKED) /* You die... --More-- */
2587 pline("Do not pass go. Do not collect 200 %s.", currency(200L));
2588 else if (moves == 2 && how < PANICKED) {
2589 if (!issoviet) pline("Do not pass go. Do not collect 200 %s.", currency(200L));
2590 else pline("Nekotoryye pizda nazvali sovetskiy reshil, chto vy ne mozhete poluchit' zabavnoye soobshcheniye pryamo seychas.");
2592 /* I'll allow you to see this message if you die on your second turn, too. --Amy */
2594 if (have_windows) wait_synch(); /* flush screen output */
2595 if (!goexplore && !gofreeplay) {
2596 #ifndef NO_SIGNAL
2597 (void) signal(SIGINT, (SIG_RET_TYPE) done_intr);
2598 # if defined(UNIX) || defined(VMS) || defined (__EMX__)
2599 (void) signal(SIGQUIT, (SIG_RET_TYPE) done_intr);
2600 sethanguphandler(done_hangup);
2601 # endif
2602 #endif /* NO_SIGNAL */
2604 #ifdef ALLEG_FX
2605 if(iflags.usealleg && (how < PANICKED))
2606 fade_to_black();
2607 #endif
2609 /* bones_ok = (how < GENOCIDED) && can_make_bones(); moved up */
2611 if (how == TURNED_SLIME)
2612 u.ugrave_arise = PM_GREEN_SLIME;
2614 if (bones_ok && u.ugrave_arise < LOW_PM) {
2615 /* corpse gets burnt up too */
2616 if (how == BURNING)
2617 u.ugrave_arise = (NON_PM - 2); /* leave no corpse */
2618 else if (how == STONING)
2619 u.ugrave_arise = (NON_PM - 1); /* statue instead of corpse */
2620 else if (u.ugrave_arise == NON_PM &&
2621 !(mvitals[u.umonnum].mvflags & G_NOCORPSE)) {
2622 int mnum = u.umonnum;
2624 if (!Upolyd) {
2625 /* Base corpse on race when not poly'd since original
2626 * u.umonnum is based on role, and all role monsters
2627 * are human.
2629 mnum = undead_to_corpse(
2630 (flags.female && urace.femalenum != NON_PM) ?
2631 urace.femalenum : urace.malenum);
2633 corpse = mk_named_object(CORPSE, &mons[mnum], u.ux, u.uy, playeraliasname);
2634 sprintf(pbuf, "%s, %s%s", playeraliasname,
2635 killer_format == NO_KILLER_PREFIX ? "" :
2636 killed_by_prefix[how],
2637 killer_format == KILLED_BY_AN ? an(killer) : killer);
2638 #ifdef EPITAPH
2639 /* ask player if he wants a custom epitaph */
2640 if ('y' == yn("Do you want to write your own epitaph?")) {
2641 getlin("What do you want your epitaph to be?",ebuf);
2642 sprintf(pbuf, "Here lies %s. %s", playeraliasname, ebuf);
2644 #endif
2645 make_grave(u.ux, u.uy, pbuf);
2648 } /* if (!goexplore) */
2649 if (how == TURNED_SLIME) killer_format = NO_KILLER_PREFIX;
2650 if (how == QUIT) {
2651 killer_format = NO_KILLER_PREFIX;
2652 if (u.uhp < 1) {
2653 how = DIED;
2654 u.umortality++; /* skipped above when how==QUIT */
2655 /* note that killer is pointing at kilbuf */
2656 strcpy(kilbuf, "quit while already on Charon's boat");
2659 if (how == ESCAPED || how == PANICKED)
2660 killer_format = NO_KILLER_PREFIX;
2662 if (how != PANICKED) {
2663 /* these affect score and/or bones, but avoid them during panic */
2664 taken = paybill((how == ESCAPED) ? -1 : (how != QUIT));
2665 paygd();
2666 clearpriests();
2667 } else taken = FALSE; /* lint; assert( !bones_ok ); */
2669 if (!goexplore && !gofreeplay) {
2670 delete_savefile(); /* dying during recovery (allmain.c) happens before the savegame file got erased --Amy */
2671 clearlocks();
2673 if (have_windows) display_nhwindow(WIN_MESSAGE, FALSE);
2675 if (strcmp(flags.end_disclose, "none") && how != PANICKED)
2676 disclose(how, taken);
2677 /* finish_paybill should be called after disclosure but before bones */
2678 if (bones_ok && taken) finish_paybill();
2681 /* calculate score, before creating bones [container gold] */
2683 long tmp;
2684 int deepest = deepest_lev_reached(FALSE);
2686 #ifndef GOLDOBJ
2687 umoney = u.ugold;
2688 tmp = u.ugold0;
2689 #else
2690 umoney = money_cnt(invent);
2691 tmp = u.umoney0;
2692 #endif
2693 umoney += hidden_gold(); /* accumulate gold from containers */
2694 tmp = umoney - tmp; /* net gain */
2696 if (tmp < 0L)
2697 tmp = 0L;
2698 if (how < PANICKED)
2699 tmp -= tmp / 10L;
2700 u.urexp += tmp;
2701 u.urexp += 50L * (long)(deepest - 1);
2702 if (how == ASCENDED) {
2703 u.urexp *= 2L;
2705 if (gofreeplay) {
2707 discover = FALSE; /* a kludge to fool the topten function.. */
2708 topten(how);
2709 umoney -= hidden_gold();
2710 if (u.urexp > 1) u.urexp /= 2;
2711 u.urexp -= tmp;
2712 u.urexp -= 50L * (long)(deepest - 1);
2713 vision_reset();
2714 if (flags.moreforced && !MessagesSuppressed) display_nhwindow(WIN_MESSAGE, TRUE); /* --More-- */
2715 (void)doredraw();
2716 u.freeplaymode = TRUE;
2717 u.freeplaytransit = TRUE;
2718 u.freeplayplanes = FALSE;
2720 /* did you kill the elder priest? then you may find the artifact robe randomly generated now --Amy */
2721 if (achieveX.killed_elderpriest) de_energise_artifact(ART_MOTHERFUCKER_TROPHY);
2723 /* might not have been able to finish deep mines, in case the stone didn't generate */
2724 de_energise_artifact(ART_ARKENSTONE_OF_THRAIN);
2726 if (u.uhave.amulet) { /* no longer need the amulet, now that you've won */
2727 struct obj *otmpi, *otmpii;
2728 if (invent) {
2729 for (otmpi = invent; otmpi; otmpi = otmpii) {
2730 otmpii = otmpi->nobj;
2731 if (otmpi->otyp == AMULET_OF_YENDOR) {
2732 if (otmpi->owornmask) {
2733 setnotworn(otmpi);
2735 dropx(otmpi);
2740 goto_level(&medusa_level, TRUE, FALSE, FALSE);
2742 register int newlevX = 1;
2743 d_level newlevelX;
2744 get_level(&newlevelX, newlevX);
2745 goto_level(&newlevelX, TRUE, FALSE, FALSE);
2746 u.freeplaytransit = FALSE;
2747 pline("You find yourself back in the dungeon. Since you've officially won the game, you can freely explore now. If you want to go back to the Elemental Planes, you have to visit Moloch's Sanctum first. You can also retire (commit suicide) when you are ready.");
2749 if (!Race_if(PM_BABYLONIAN)) {
2750 u.weapon_slots += 3;
2751 pline("As a bonus, you gain three additional skill slots!");
2754 return;
2759 if (goexplore) {
2760 discover = FALSE; /* a kludge to fool the topten function.. */
2761 topten(how);
2762 /* undo some things that were done for score calculation */
2763 /* this branch is not entered when you ascend, escape or quit */
2764 discover = TRUE;
2765 umoney -= hidden_gold();
2766 u.urexp -= tmp;
2767 u.urexp -= 50L * (long)(deepest - 1);
2768 /* now do what is done when you refuse to die in explore mode */
2769 if (u.uhpmax <= 0) u.uhpmax = u.ulevel * 8;
2770 savelife(how);
2771 killer = 0;
2772 killer_format = 0;
2773 vision_reset();
2774 if (flags.moreforced && !MessagesSuppressed) display_nhwindow(WIN_MESSAGE, TRUE); /* --More-- */
2775 (void)doredraw();
2776 return;
2780 /* if the screen is redrawn at this point, the MC display can somehow crash --Amy */
2781 program_state.bonesdo = TRUE;
2783 if (bones_ok) {
2784 #ifdef WIZARD
2785 /* KMH -- We need the "Save bones?" prompt for testing! */
2786 if (!wizard || yn("Save bones?") == 'y')
2787 #endif
2788 {if (Frozen) corpse = (struct obj *)0; /* no corpse if player exploded into ice cubes --Amy */
2789 savebones(corpse);
2791 /* corpse may be invalid pointer now so
2792 ensure that it isn't used again */
2793 corpse = (struct obj *)0;
2796 /* update gold for the rip output, which can't use hidden_gold()
2797 (containers will be gone by then if bones just got saved...) */
2798 #ifndef GOLDOBJ
2799 u.ugold = umoney;
2800 #else
2801 done_money = umoney;
2802 #endif
2804 /* clean up unneeded windows */
2805 if (have_windows) {
2806 wait_synch();
2807 display_nhwindow(WIN_MESSAGE, TRUE);
2808 destroy_nhwindow(WIN_MAP);
2809 destroy_nhwindow(WIN_STATUS);
2810 destroy_nhwindow(WIN_MESSAGE);
2811 WIN_MESSAGE = WIN_STATUS = WIN_MAP = WIN_ERR;
2813 if(!done_stopprint || flags.tombstone)
2814 endwin = create_nhwindow(NHW_TEXT);
2816 if (how < GENOCIDED && flags.tombstone && endwin != WIN_ERR)
2817 outrip(endwin, how);
2818 } else
2819 done_stopprint = 1; /* just avoid any more output */
2821 /* changing kilbuf really changes killer. we do it this way because
2822 killer is declared a (const char *)
2824 if (u.uhave.amulet) strcat(kilbuf, " (with the Amulet)");
2825 /*else*/ if (how == ESCAPED) {
2826 if (Is_astralevel(&u.uz)) /* offered Amulet to wrong deity */
2827 strcat(kilbuf, " (in celestial disgrace)");
2828 /*else*/ if (carrying(FAKE_AMULET_OF_YENDOR))
2829 strcat(kilbuf, " (with a fake Amulet)");
2830 /* don't bother counting to see whether it should be plural */
2832 /* since we're not removing the amulet any longer (this is by design)... had to restore celestial disgrace --Amy */
2834 // if (!done_stopprint)
2835 sprintf(pbuf, "%s %s the %s...", Goodbye(), playeraliasname,
2836 (how != ASCENDED && !u.freeplaymode) ?
2837 (const char *) ((flags.female && urole.name.f) ?
2838 urole.name.f : urole.name.m) :
2839 (const char *) (flags.female ? "Demigoddess" : "Demigod"));
2840 if (!done_stopprint) {
2841 putstr(endwin, 0, pbuf);
2842 /*putstr(endwin, 0, "");*/
2844 #ifdef DUMP_LOG
2845 if (dump_fp) dump("", pbuf);
2846 #endif
2848 if (how == ESCAPED || how == ASCENDED || u.freeplaymode) {
2849 register struct monst *mtmp;
2850 register struct obj *otmp;
2851 register struct val_list *val;
2852 register int i;
2854 for (val = valuables; val->list; val++)
2855 for (i = 0; i < val->size; i++) {
2856 val->list[i].count = 0L;
2858 get_valuables(invent);
2860 /* add points for collected valuables */
2861 for (val = valuables; val->list; val++)
2862 for (i = 0; i < val->size; i++)
2863 if (val->list[i].count != 0L)
2864 u.urexp += val->list[i].count
2865 * (long)objects[val->list[i].typ].oc_cost;
2867 /* count the points for artifacts */
2868 artifact_score(invent, TRUE, endwin);
2870 keepdogs(TRUE);
2871 viz_array[0][0] |= IN_SIGHT; /* need visibility for naming */
2872 mtmp = mydogs;
2873 strcpy(pbuf, "You");
2874 if (mtmp) {
2875 while (mtmp) {
2876 /* CAREFUL! if the player has a lot of pets with long names, this can result in a SIGSEGV! --Amy
2877 * the buffer should be 3000 characters long, so this will normally not be an issue, but just in case
2878 * that it would be exceeded, prevent it from crashing upon ascension... */
2879 if (strlen(pbuf) < (BUFSZ - 300)) {
2880 sprintf(eos(pbuf), " and %s", mon_nam(mtmp));
2882 if (mtmp->mtame)
2883 u.urexp += mtmp->mhp;
2884 mtmp = mtmp->nmon;
2886 if (!done_stopprint) putstr(endwin, 0, pbuf);
2887 #ifdef DUMP_LOG
2888 if (dump_fp) dump("", pbuf);
2889 #endif
2890 pbuf[0] = '\0';
2891 } else {
2892 if (!done_stopprint) strcat(pbuf, " ");
2894 sprintf(eos(pbuf), "%s with %ld point%s,",
2895 how==ASCENDED ? "went to your reward" :
2896 u.freeplaymode ? "retired after beating the game" :
2897 "escaped from the dungeon",
2898 u.urexp, plur(u.urexp));
2899 #ifdef DUMP_LOG
2900 if (dump_fp) dump("", pbuf);
2901 #endif
2902 if (!done_stopprint) {
2903 putstr(endwin, 0, pbuf);
2906 if (!done_stopprint)
2907 artifact_score(invent, FALSE, endwin); /* list artifacts */
2909 /* list valuables here */
2910 for (val = valuables; val->list; val++) {
2911 sort_valuables(val->list, val->size);
2912 for (i = 0; i < val->size && !done_stopprint; i++) {
2913 int typ = val->list[i].typ;
2914 long count = val->list[i].count;
2916 if (count == 0L) continue;
2917 if (objects[typ].oc_class != GEM_CLASS || typ <= LAST_GEM) {
2918 otmp = mksobj(typ, FALSE, FALSE, FALSE);
2919 if (otmp) {
2920 makeknown(otmp->otyp);
2921 otmp->known = 1; /* for fake amulets */
2922 otmp->dknown = 1; /* seen it (blindness fix) */
2923 otmp->onamelth = 0;
2924 otmp->quan = count;
2925 sprintf(pbuf, "%8ld %s (worth %ld %s),",
2926 count, xname(otmp),
2927 count * (long)objects[typ].oc_cost, currency(2L));
2928 obfree(otmp, (struct obj *)0);
2930 } else {
2931 sprintf(pbuf,
2932 "%8ld worthless piece%s of colored glass,",
2933 count, plur(count));
2935 putstr(endwin, 0, pbuf);
2936 #ifdef DUMP_LOG
2937 if (dump_fp) dump("", pbuf);
2938 #endif
2942 } else if (!done_stopprint) {
2943 /* did not escape or ascend */
2944 if (u.uz.dnum == 0 && u.uz.dlevel <= 0) {
2945 /* level teleported out of the dungeon; `how' is DIED,
2946 due to falling or to "arriving at heaven prematurely" */
2947 sprintf(pbuf, "You %s beyond the confines of the dungeon",
2948 (u.uz.dlevel < 0) ? "passed away" : ends[how]);
2949 } else {
2950 /* more conventional demise */
2951 const char *where = dungeons[u.uz.dnum].dname;
2953 if (Is_astralevel(&u.uz)) where = "The Astral Plane";
2954 sprintf(pbuf, "You %s in %s", ends[how], where);
2955 if (!In_endgame(&u.uz) && !Is_knox(&u.uz))
2956 sprintf(eos(pbuf), " on dungeon level %d",
2957 In_quest(&u.uz) ? dunlev(&u.uz) : depth(&u.uz));
2960 sprintf(eos(pbuf), " with %ld point%s,",
2961 u.urexp, plur(u.urexp));
2962 putstr(endwin, 0, pbuf);
2963 #ifdef DUMP_LOG
2964 if (dump_fp) dump("", pbuf);
2965 #endif
2968 if (!done_stopprint) {
2969 sprintf(pbuf, "and %ld piece%s of gold, after %ld move%s.",
2970 umoney, plur(umoney), moves, plur(moves));
2971 putstr(endwin, 0, pbuf);
2972 #ifdef DUMP_LOG
2973 if (dump_fp) {
2974 dump("", pbuf);
2975 sprintf(pbuf, "Killer: %s", killer);
2976 dump("", pbuf);
2978 #endif
2980 if (!done_stopprint) {
2981 sprintf(pbuf,
2982 "You were level %d with a maximum of %d hit point%s when you %s.",
2983 u.ulevel, u.uhpmax, plur(u.uhpmax), ends[how]);
2984 putstr(endwin, 0, pbuf);
2985 /*putstr(endwin, 0, "");*/
2986 #ifdef DUMP_LOG
2987 if (dump_fp) dump("", pbuf);
2988 #endif
2990 if (!done_stopprint)
2991 display_nhwindow(endwin, TRUE);
2992 if (endwin != WIN_ERR)
2993 destroy_nhwindow(endwin);
2995 /* "So when I die, the first thing I will see in Heaven is a
2996 * score list?" */
2997 if (flags.toptenwin) {
2998 topten(how);
2999 if (have_windows)
3000 exit_nhwindows((char *)0);
3001 } else {
3002 if (have_windows)
3003 exit_nhwindows((char *)0);
3004 topten(how);
3006 #ifdef DUMP_LOG
3007 if (dump_fp) dump_exit();
3008 #endif
3010 if(done_stopprint) { raw_print(""); raw_print(""); }
3011 terminate(EXIT_SUCCESS);
3015 void
3016 container_contents(list, identified, all_containers)
3017 struct obj *list;
3018 boolean identified, all_containers;
3019 #ifdef DUMP_LOG
3021 do_containerconts(list, identified, all_containers, FALSE);
3024 void do_containerconts(list, identified, all_containers, want_dump)
3025 struct obj *list;
3026 boolean identified, all_containers, want_dump;
3027 #endif
3028 /* The original container_contents function */
3030 register struct obj *box, *obj;
3031 struct obj **oarray;
3032 int i,j,n;
3033 char *invlet;
3034 char buf[BUFSZ];
3036 for (box = list; box; box = box->nobj) {
3037 if (Is_container(box) || box->otyp == STATUE) {
3038 if (box->otyp == BAG_OF_TRICKS) {
3039 continue; /* wrong type of container */
3040 } else if (box->cobj) {
3041 winid tmpwin = create_nhwindow(NHW_MENU);
3043 /* count the number of items */
3044 for (n = 0, obj = box->cobj; obj; obj = obj->nobj) n++;
3045 /* Make a temporary array to store the objects sorted */
3046 oarray = (struct obj **) alloc(n*sizeof(struct obj*));
3048 /* Add objects to the array */
3049 i = 0;
3050 invlet = flags.inv_order;
3051 nextclass:
3052 for (obj = box->cobj; obj; obj = obj->nobj) {
3053 if (!flags.sortpack || obj->oclass == *invlet) {
3054 if (iflags.sortloot == 'f'
3055 || iflags.sortloot == 'l') {
3056 /* Insert object at correct index */
3057 for (j = i; j; j--) {
3058 if (strcmpi(cxname3(obj), cxname3(oarray[j-1]))>0
3059 || (flags.sortpack &&
3060 oarray[j-1]->oclass != obj->oclass))
3061 break;
3062 oarray[j] = oarray[j-1];
3064 oarray[j] = obj;
3065 i++;
3066 } else {
3067 /* Just add it to the array */
3068 oarray[i++] = obj;
3071 } /* for loop */
3072 if (flags.sortpack) {
3073 if (*++invlet) goto nextclass;
3076 sprintf(buf, "Contents of %s:", the(xname(box)));
3077 putstr(tmpwin, 0, buf);
3078 putstr(tmpwin, 0, "");
3079 #ifdef DUMP_LOG
3080 if (dump_fp) dump("", buf);
3081 #endif
3082 for (i = 0; i < n; i++) {
3083 obj = oarray[i];
3085 /*for (obj = box->cobj; obj; obj = obj->nobj) {*/ /* pre-sortloot */
3086 if (identified) {
3087 makeknown(obj->otyp);
3088 obj->known = obj->bknown =
3089 obj->dknown = obj->rknown = 1;
3091 putstr(tmpwin, 0, doname(obj));
3092 #ifdef DUMP_LOG
3093 if (want_dump) dump(" ", doname(obj));
3094 #endif
3096 #ifdef DUMP_LOG
3097 if (want_dump) dump("","");
3098 #endif
3099 display_nhwindow(tmpwin, TRUE);
3100 destroy_nhwindow(tmpwin);
3101 if (all_containers) {
3102 #ifdef DUMP_LOG
3103 do_containerconts(box->cobj, identified, TRUE,
3104 want_dump);
3105 #else
3106 container_contents(box->cobj, identified, TRUE);
3107 #endif /* DUMP_LOG */
3109 } else {
3110 pline("%s empty.", Tobjnam(box, "are"));
3111 display_nhwindow(WIN_MESSAGE, FALSE);
3112 #ifdef DUMP_LOG
3113 if (want_dump) {
3114 dump(The(xname(box)), " is empty.");
3115 dump("", "");
3117 #endif
3120 if (!all_containers)
3121 break;
3125 /* should be called with either EXIT_SUCCESS or EXIT_FAILURE */
3126 void
3127 terminate(status)
3128 int status;
3130 program_state.in_moveloop = 0; /* won't be returning to normal play */
3131 #ifdef MAC
3132 getreturn("to exit");
3133 #endif
3134 /* don't bother to try to release memory if we're in panic mode, to
3135 avoid trouble in case that happens to be due to memory problems */
3136 if (!program_state.panicking) {
3137 freedynamicdata();
3138 dlb_cleanup();
3141 program_state.exiting = 1;
3142 nethack_exit(status);
3145 STATIC_OVL boolean
3146 list_vanquished(defquery, ask)
3147 char defquery;
3148 boolean ask;
3149 #ifdef DUMP_LOG
3151 do_vanquished(defquery, ask, FALSE);
3152 return TRUE;
3154 /* this function should return something... but the return isn't used anywhere --Amy */
3157 void
3158 do_vanquished(defquery, ask, want_dump)
3159 int defquery;
3160 boolean ask;
3161 boolean want_dump;
3162 #endif
3164 register int i, lev;
3165 int ntypes = 0, max_lev = 0, nkilled;
3166 long total_killed = 0L;
3167 long total_born = 0L;
3168 long bosses_killed = 0L;
3169 long bosses_born = 0L;
3170 char c;
3171 winid klwin;
3172 char buf[BUFSZ];
3174 /* get totals first */
3175 for (i = LOW_PM; i < NUMMONS; i++) {
3176 if (mvitals[i].died || program_state.gameover || wizard ) ntypes++;
3177 total_killed += (long)mvitals[i].died;
3178 total_born += (long)mvitals[i].born;
3179 if (mons[i].geno & G_UNIQ) bosses_killed += (long)mvitals[i].died;
3180 if (mons[i].geno & G_UNIQ) bosses_born += (long)mvitals[i].born;
3181 if (mons[i].mlevel > max_lev) max_lev = mons[i].mlevel;
3184 /* vanquished creatures list;
3185 * includes all dead monsters, not just those killed by the player
3187 if (ntypes != 0) {
3188 c = ask ? yn_function("Do you want an account of creatures vanquished?",
3189 ynqchars, defquery) : defquery;
3190 if (c == 'q') done_stopprint++;
3191 if (c != 'q') {
3192 klwin = create_nhwindow(NHW_MENU);
3193 putstr(klwin, 0, "Vanquished creatures:");
3194 putstr(klwin, 0, "");
3195 #ifdef DUMP_LOG
3196 if (want_dump) dump("", "Vanquished creatures");
3197 #endif
3199 /* countdown by monster "toughness" */
3200 /*for (lev = max_lev; lev >= 0; lev--)*/
3201 for (i = LOW_PM; i < NUMMONS; i++)
3203 #if 0
3204 /* Amy test suite */
3206 if ((mons[i].geno & G_UNIQ) && (mons[i].geno & G_GENO)) {
3207 sprintf(buf, "%s UNIQGENO", mons[i].mname);
3208 putstr(klwin, 0, buf);
3209 #ifdef DUMP_LOG
3210 if (want_dump) dump(" ", buf);
3211 #endif
3213 #endif /* 0 */
3215 if (/*mons[i].mlevel == lev &&*/ (((nkilled = mvitals[i].died) > 0) || (nkilled != mvitals[i].born && (program_state.gameover || wizard)) ) ) {
3216 if ((mons[i].geno & G_UNIQ) && i != PM_HIGH_PRIEST) {
3217 sprintf(buf, "%s%s",
3218 !type_is_pname(&mons[i]) ? "The " : "",
3219 mons[i].mname);
3220 if (nkilled != 1) {
3221 switch (nkilled) {
3222 case 2: sprintf(eos(buf)," (twice)"); break;
3223 case 3: sprintf(eos(buf)," (thrice)"); break;
3224 default: sprintf(eos(buf)," (%d time%s)",
3225 nkilled, plur(nkilled));
3226 break;
3229 } else {
3230 /* trolls or undead might have come back,
3231 but we don't keep track of that */
3232 if (nkilled == 1)
3233 strcpy(buf, an(mons[i].mname));
3234 else
3235 sprintf(buf, "%d %s",
3236 nkilled, makeplural(mons[i].mname));
3237 if (nkilled != mvitals[i].born && (program_state.gameover || wizard)) /* only show this after death --Amy */
3238 sprintf(buf + strlen(buf), " (%d created)",
3239 (int) mvitals[i].born);
3241 putstr(klwin, 0, buf);
3242 #ifdef DUMP_LOG
3243 if (want_dump) dump(" ", buf);
3244 #endif
3247 * if (Hallucination)
3248 * putstr(klwin, 0, "and a partridge in a pear tree");
3250 if (ntypes > 1) {
3251 putstr(klwin, 0, "");
3253 if (program_state.gameover || wizard) {
3254 sprintf(buf, "%ld creature%s born.", total_born, total_born == 1 ? "" : "s");
3255 putstr(klwin, 0, buf);
3256 #ifdef DUMP_LOG
3257 if (want_dump) dump(" ", buf);
3258 #endif
3261 sprintf(buf, "%ld creature%s vanquished.", total_killed, total_killed == 1 ? "" : "s");
3262 putstr(klwin, 0, buf);
3263 #ifdef DUMP_LOG
3264 if (want_dump) dump(" ", buf);
3265 #endif
3268 if (program_state.gameover || wizard) {
3269 sprintf(buf, "%ld boss%s born.", bosses_born, bosses_born == 1 ? "" : "es");
3270 putstr(klwin, 0, buf);
3271 #ifdef DUMP_LOG
3272 if (want_dump) dump(" ", buf);
3273 #endif
3276 sprintf(buf, "%ld boss%s vanquished.", bosses_killed, bosses_killed == 1 ? "" : "es");
3277 putstr(klwin, 0, buf);
3278 #ifdef DUMP_LOG
3279 if (want_dump) dump(" ", buf);
3280 #endif
3283 display_nhwindow(klwin, TRUE);
3284 destroy_nhwindow(klwin);
3285 #ifdef DUMP_LOG
3286 if (want_dump) dump("", "");
3287 #endif
3290 #ifdef DUMP_LOG
3291 return;
3292 #else
3293 return (boolean) (total_killed);
3294 #endif
3298 dolistvanq()
3300 if (!list_vanquished('y', FALSE))
3301 pline("Vanquished monsters listing complete."); /* because dumplog changed that function to a void! --Amy */
3302 return(0);
3305 /* number of monster species which have been genocided */
3307 num_genocides()
3309 int i, n = 0;
3311 for (i = LOW_PM; i < NUMMONS; ++i)
3312 if (mvitals[i].mvflags & G_GENOD) ++n;
3314 return n;
3317 #ifdef DUMP_LOG
3318 STATIC_OVL void
3319 list_genocided(defquery, ask, want_dump)
3320 int defquery;
3321 boolean ask;
3322 boolean want_dump;
3323 #else
3324 STATIC_OVL void
3325 list_genocided(defquery, ask)
3326 char defquery;
3327 boolean ask;
3328 #endif
3330 register int i;
3331 int ngenocided=0;
3332 int nextincted=0;
3333 char c;
3334 winid klwin;
3335 char buf[BUFSZ];
3337 /* get totals first */
3338 for (i = LOW_PM; i < NUMMONS; i++) {
3339 if (mvitals[i].mvflags & G_GENOD)
3340 ngenocided++;
3341 else if ( (mvitals[i].mvflags & G_GONE) && !(mons[i].geno & G_UNIQ) )
3342 nextincted++;
3345 /*ngenocided = num_genocides();*/
3347 /* genocided species list */
3348 if (ngenocided != 0 || nextincted != 0) {
3349 c = ask ? yn_function("Do you want a list of species genocided?",
3350 ynqchars, defquery) : defquery;
3351 if (c == 'q') done_stopprint++;
3352 if (c != 'q') {
3353 klwin = create_nhwindow(NHW_MENU);
3354 sprintf(buf, "Genocided species:");
3355 putstr(klwin, 0, buf);
3356 putstr(klwin, 0, "");
3357 #ifdef DUMP_LOG
3358 if (want_dump) dump("", buf);
3359 #endif
3361 for (i = LOW_PM; i < NUMMONS; i++)
3362 if (mvitals[i].mvflags & G_GONE && !(mons[i].geno & G_UNIQ) ) {
3363 /*if (mvitals[i].mvflags & G_GENOD) {*/
3364 if ((mons[i].geno & G_UNIQ) && i != PM_HIGH_PRIEST)
3365 sprintf(buf, "%s%s",
3366 !type_is_pname(&mons[i]) ? "" : "the ",
3367 mons[i].mname);
3368 else
3369 strcpy(buf, makeplural(mons[i].mname));
3370 if( !(mvitals[i].mvflags & G_GENOD) )
3371 strcat(buf, " (extinct)");
3372 putstr(klwin, 0, buf);
3373 #ifdef DUMP_LOG
3374 if (want_dump) dump(" ", buf);
3375 #endif
3378 putstr(klwin, 0, "");
3379 sprintf(buf, "%d species genocided.", ngenocided);
3380 putstr(klwin, 0, buf);
3381 #ifdef DUMP_LOG
3382 if (want_dump) dump(" ", buf);
3383 #endif
3385 sprintf(buf, "%d species extinct.", nextincted);
3386 putstr(klwin, 0, buf);
3387 display_nhwindow(klwin, TRUE);
3388 destroy_nhwindow(klwin);
3393 void
3394 mk_dgl_extrainfo()
3396 #ifdef EXTRAINFO_FN
3397 FILE *extrai = (FILE *)0;
3398 #ifdef UNIX
3399 mode_t eimode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
3400 #endif
3401 char new_fn[512];
3403 /* certain nasty traps obscure the information - so we want to hide it from whereis too! --Amy */
3404 if (DisplayDoesNotGo || TheInfoIsFucked) {
3405 return;
3408 sprintf(new_fn, "%s", dump_format_str(EXTRAINFO_FN));
3410 extrai = fopen_datafile_area(FILE_AREA_VAR, new_fn, "w", LEVELPREFIX);
3411 if (!extrai) {
3412 } else {
3413 char tmpdng[16];
3414 int sortval = 0;
3415 if (Is_knox(&u.uz)) {
3416 sortval = 1000;
3417 sprintf(tmpdng, "%i|%s", sortval, "Knx");
3418 } else if (In_quest(&u.uz)) { /* this depends on the fact that the quest is never longer than 7 levels --Amy */
3419 sortval = 1500 + depth(&u.uz);
3420 sprintf(tmpdng, "%i|%s%i", sortval, " Q", dunlev(&u.uz));
3421 } else if (In_endgame(&u.uz)) {
3422 sprintf(tmpdng, "%i|%s", sortval, "End");
3423 sortval = 10000;
3424 } else if (In_sokoban_real(&u.uz)) {
3425 sprintf(tmpdng, "%i|Sok%i", sortval, depth(&u.uz));
3426 sortval = 200 + depth(&u.uz);
3427 } else if (In_mines(&u.uz)) {
3428 sprintf(tmpdng, "%i|Min%i", sortval, depth(&u.uz));
3429 sortval = 150 + depth(&u.uz);
3430 } else if (In_sheol(&u.uz)) {
3431 sprintf(tmpdng, "%i|She%i", sortval, depth(&u.uz));
3432 sortval = 4000 + depth(&u.uz);
3433 } else if (In_yendorian(&u.uz)) {
3434 sprintf(tmpdng, "%i|Yen%i", sortval, depth(&u.uz));
3435 sortval = 6000 + depth(&u.uz);
3436 } else if (In_forging(&u.uz)) {
3437 sprintf(tmpdng, "%i|%s", sortval, "For");
3438 sortval = 7500 + depth(&u.uz);
3439 } else if (In_ordered(&u.uz)) {
3440 sprintf(tmpdng, "%i|%s", sortval, "Ord");
3441 sortval = 7500 + depth(&u.uz);
3442 } else if (In_deadground(&u.uz)) {
3443 sprintf(tmpdng, "%i|%s", sortval, "Dea");
3444 sortval = 7500 + depth(&u.uz);
3445 } else if (In_illusorycastle(&u.uz)) {
3446 sprintf(tmpdng, "%i|Ill%i", sortval, depth(&u.uz));
3447 sortval = 3000 + depth(&u.uz);
3448 } else if (In_restingzone(&u.uz)) {
3449 sprintf(tmpdng, "%i|Res%i", sortval, depth(&u.uz));
3450 sortval = 3000 + depth(&u.uz);
3451 } else if (In_voiddungeon(&u.uz)) {
3452 sprintf(tmpdng, "%i|Voi%i", sortval, depth(&u.uz));
3453 sortval = 5000 + depth(&u.uz);
3454 } else if (In_netherrealm(&u.uz)) {
3455 sprintf(tmpdng, "%i|Net%i", sortval, depth(&u.uz));
3456 sortval = 5500 + depth(&u.uz);
3457 } else if (In_deepmines(&u.uz)) {
3458 sprintf(tmpdng, "%i|Dee%i", sortval, depth(&u.uz));
3459 sortval = 1200 + depth(&u.uz);
3460 } else if (In_angmar(&u.uz)) {
3461 sprintf(tmpdng, "%i|Ang%i", sortval, depth(&u.uz));
3462 sortval = 3200 + depth(&u.uz);
3463 } else if (In_greencross(&u.uz)) {
3464 sprintf(tmpdng, "%i|Grc%i", sortval, depth(&u.uz));
3465 sortval = 3200 + depth(&u.uz);
3466 } else if (In_emynluin(&u.uz)) {
3467 sprintf(tmpdng, "%i|Emy%i", sortval, depth(&u.uz));
3468 sortval = 3200 + depth(&u.uz);
3469 } else if (In_minotaurmaze(&u.uz)) {
3470 sprintf(tmpdng, "%i|Mit%i", sortval, depth(&u.uz));
3471 sortval = 3200 + depth(&u.uz);
3472 } else if (In_swimmingpool(&u.uz)) {
3473 sprintf(tmpdng, "%i|Swi%i", sortval, depth(&u.uz));
3474 sortval = 3300 + depth(&u.uz);
3475 } else if (In_hellbathroom(&u.uz)) {
3476 sprintf(tmpdng, "%i|Bat%i", sortval, depth(&u.uz));
3477 sortval = 3100 + depth(&u.uz);
3478 } else if (In_minusworld(&u.uz)) {
3479 sprintf(tmpdng, "%i|Miw%i", sortval, depth(&u.uz));
3480 sortval = 3100 + depth(&u.uz);
3481 } else if (In_spacebase(&u.uz)) {
3482 sprintf(tmpdng, "%i|Spa%i", sortval, depth(&u.uz));
3483 sortval = 500 + depth(&u.uz);
3484 } else if (In_sewerplant(&u.uz)) {
3485 sprintf(tmpdng, "%i|Sew%i", sortval, depth(&u.uz));
3486 sortval = 700 + depth(&u.uz);
3487 } else if (In_gammacaves(&u.uz)) {
3488 sprintf(tmpdng, "%i|Gam%i", sortval, depth(&u.uz));
3489 sortval = 900 + depth(&u.uz);
3490 } else if (In_mainframe(&u.uz)) {
3491 sprintf(tmpdng, "%i|Mai%i", sortval, depth(&u.uz));
3492 sortval = 1100 + depth(&u.uz);
3493 } else if (In_poolchallenge(&u.uz)) {
3494 sprintf(tmpdng, "%i|Poo%i", sortval, depth(&u.uz));
3495 sortval = 1100 + depth(&u.uz);
3496 } else if (In_gruechallenge(&u.uz)) {
3497 sprintf(tmpdng, "%i|Gre%i", sortval, depth(&u.uz));
3498 sortval = 1100 + depth(&u.uz);
3499 } else if (In_digdugchallenge(&u.uz)) {
3500 sprintf(tmpdng, "%i|Dig%i", sortval, depth(&u.uz));
3501 sortval = 1100 + depth(&u.uz);
3502 } else if (In_joustchallenge(&u.uz)) {
3503 sprintf(tmpdng, "%i|Jou%i", sortval, depth(&u.uz));
3504 sortval = 1100 + depth(&u.uz);
3505 } else if (In_pacmanchallenge(&u.uz)) {
3506 sprintf(tmpdng, "%i|Pac%i", sortval, depth(&u.uz));
3507 sortval = 1100 + depth(&u.uz);
3508 } else if (In_subquest(&u.uz)) {
3509 sprintf(tmpdng, "%i|Sub%i", sortval, depth(&u.uz));
3510 sortval = 1800 + depth(&u.uz);
3511 } else if (In_rivalquest(&u.uz)) {
3512 sprintf(tmpdng, "%i|Riv%i", sortval, depth(&u.uz));
3513 sortval = 1800 + depth(&u.uz);
3514 } else if (In_bellcaves(&u.uz)) {
3515 sprintf(tmpdng, "%i|%s", sortval, "Bel");
3516 sortval = 1900 + depth(&u.uz);
3517 } else if (In_towndungeon(&u.uz)) {
3518 sprintf(tmpdng, "%i|Tow%i", sortval, depth(&u.uz));
3519 sortval = 400 + depth(&u.uz);
3520 } else if (In_spiders(&u.uz)) {
3521 sprintf(tmpdng, "%i|%s", sortval, "Spi");
3522 sortval = 1500 + depth(&u.uz);
3523 } else if (In_grund(&u.uz)) {
3524 sprintf(tmpdng, "%i|%s", sortval, "Gru");
3525 sortval = 1200 + depth(&u.uz);
3526 } else if (In_icequeen(&u.uz)) {
3527 sprintf(tmpdng, "%i|%s", sortval, "Ice");
3528 sortval = 1300 + depth(&u.uz);
3529 } else if (In_wyrm(&u.uz)) {
3530 sprintf(tmpdng, "%i|%s", sortval, "Wyr");
3531 sortval = 1600 + depth(&u.uz);
3532 } else if (In_tomb(&u.uz)) {
3533 sprintf(tmpdng, "%i|%s", sortval, "Tom");
3534 sortval = 1000 + depth(&u.uz);
3535 } else if (In_slsea(&u.uz)) {
3536 sprintf(tmpdng, "%i|%s", sortval, "Sun");
3537 sortval = 1600 + depth(&u.uz);
3538 } else if (In_gcavern(&u.uz)) {
3539 sprintf(tmpdng, "%i|%s", sortval, "Gia");
3540 sortval = 1600 + depth(&u.uz);
3541 } else if (In_frnkn(&u.uz)) {
3542 sprintf(tmpdng, "%i|%s", sortval, "Frn");
3543 sortval = 3500 + depth(&u.uz);
3544 } else if (In_mtemple(&u.uz)) {
3545 sprintf(tmpdng, "%i|%s", sortval, "Mol");
3546 sortval = 1000 + depth(&u.uz);
3547 } else {
3548 sprintf(tmpdng, "%i|%c%cD%i", sortval, ' ', ' ', depth(&u.uz));
3551 #ifdef UNIX
3552 chmod(new_fn, eimode);
3553 #endif
3554 fwrite(tmpdng,strlen(tmpdng),1,extrai);
3555 fclose(extrai);
3557 #endif /* EXTRAINFO_FN */
3561 /*end.c*/