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 */
15 extern int enter_explore_mode(void);
18 extern char msgs
[][BUFSZ
];
19 extern int msgs_count
[];
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
},
41 STATIC_PTR
void done_intr(int);
42 # if defined(UNIX) || defined(VMS) || defined (__EMX__)
43 static void done_hangup(int);
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
);
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
);
60 STATIC_DCL
void list_genocided(CHAR_P
,BOOLEAN_P
);
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);
67 #define nethack_exit exit
70 #define done_stopprint program_state.stopprint
73 # define NH_abort() Abort(0)
76 # define NH_abort() (void) abort()
79 # define NH_abort() win32_abort()
81 # define NH_abort() abort()
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"
106 dump_format_str(char *str
)
108 static char buf
[BUFSZ
];
114 if (!str
) return NULL
;
118 end
= buf
+ sizeof(buf
) - 10;
124 snprintf (p
, end
+ 1 - p
, "%ld", u
.ubirthday
);
134 snprintf (p
, end
+ 1 - p
, "%s", plname
);
161 FILE *dump_fp
= (FILE *)0; /* file pointer for dumps */
162 /* functions dump_init, dump_exit and dump are from the dump patch */
168 static char buf
[BUFSIZ
+1+5];
174 if (!dump_fn
[0]) return NULL
;
178 end
= buf
+ sizeof(buf
) - 10;
183 case 't': case 'd': /* starttime */
184 snprintf (p
, end
+ 1 - p
, "%ld", u
.ubirthday
);
189 case 'N': /* first character of player name */
194 case 'n': /* player name */
195 case 's': /* for backwards compatibility */
196 snprintf(p
, end
+ 1 - p
, "%s", plname
);
230 mode_t dumpmode
= S_IRUSR
| S_IWUSR
| S_IRGRP
| S_IROTH
;
233 char *actual_fn
= get_dump_filename();
235 dump_fp
= fopen (actual_fn
, "w");
237 chmod(actual_fn
, dumpmode
);
241 pline("Can't open %s for output.", actual_fn
);
242 pline("Dump file not created.");
256 const char * const pre
;
257 const char * const str
;
260 fprintf (dump_fp
, "%s%s\n", pre
, str
);
262 #endif /* DUMP_LOG */
266 done1(sig_unused
) /* called as signal() handler, so sent at least one arg */
270 # pragma unused ( sig_unused )
273 (void) signal(SIGINT
,SIG_IGN
);
277 (void) signal(SIGINT
, (SIG_RET_TYPE
) done1
);
279 clear_nhwindow(WIN_MESSAGE
);
282 if(multi
> 0) nomul(0, 0, FALSE
);
288 extern const char * const killed_by_prefix
[]; /* from topten.c */
290 /* "#quit" command or keyboard interrupt */
294 if (iflags
.debug_fuzzer
) return 0;
297 int really_quit
= FALSE
;
299 if (flags
.paranoidquit
) {
301 getlin ("Really quit? WARNING: this will erase your game permanently! [yes/no]?",buf
);
303 if (!(strcmp (buf
, "yes"))) really_quit
= TRUE
;
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
;
313 (void) signal(SIGINT
, (SIG_RET_TYPE
) done1
);
315 clear_nhwindow(WIN_MESSAGE
);
318 if(multi
> 0) nomul(0, 0, FALSE
);
320 u
.uinvulnerable
= FALSE
; /* avoid ctrl-C bug -dlc */
325 #if defined(WIZARD) && (defined(UNIX) || defined(VMS) || defined(LATTICE))
329 const char *tmp
= "Enter debugger?";
332 const char *tmp
= "Create SnapShot?";
334 const char *tmp
= "Dump core?";
337 if ((c
= ynq(tmp
)) == 'y') {
338 (void) signal(SIGINT
, (SIG_RET_TYPE
) done1
);
339 exit_nhwindows((char *)0);
341 } else if (c
== 'q') done_stopprint
++;
353 done_intr(sig_unused
) /* called as signal() handler, so sent at least one arg */
357 # pragma unused ( sig_unused )
360 (void) signal(SIGINT
, SIG_IGN
);
361 # if defined(UNIX) || defined(VMS)
362 (void) signal(SIGQUIT
, SIG_IGN
);
367 # if defined(UNIX) || defined(VMS) || defined(__EMX__)
369 done_hangup(sig
) /* signal() handler */
372 program_state
.done_hup
++;
373 sethanguphandler((void (*)(int)) SIG_IGN
);
378 #endif /* NO_SIGNAL */
382 register struct monst
*mtmp
;
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!");
395 mark_synch(); /* flush buffered screen output */
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
))
406 killer_format
= KILLED_BY
;
408 /* _the_ <invisible> <distorted> ghost of Dudley */
409 if (mtmp
->data
== &mons
[PM_GHOST
] && mtmp
->mnamelth
) {
411 killer_format
= KILLED_BY
;
414 strcat(buf
, "invisible ");
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
);
431 strcat(buf
, mtmp
->data
->mname
);
433 sprintf(eos(buf
), " called %s", NAME(mtmp
));
438 if (strlen(multi_txt
) > 0)
439 sprintf(eos(buf
), ", while %s", multi_txt
);
441 strcat(buf
, ", while helpless");
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!");
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
))
467 else if (mtmp
->mtraitor
)
477 #define NOTIFY_NETHACK_BUGS
482 panic
VA_DECL(const char *, 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)
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");
515 raw_printf("Report error to \"%s\"%s.",
516 # ifdef WIZARD_NAME /*(KR1ED)*/
521 !program_state
.something_worth_saving
? "" :
522 " and it may be possible to rebuild.");
524 if (program_state
.something_worth_saving
) {
525 set_error_savefile();
531 vsprintf(buf
,str
,VA_ARGS
);
533 paniclog("panic", buf
);
536 interject(INTERJECT_PANIC
);
538 #if defined(WIZARD) && (defined(UNIX) || defined(VMS) || defined(LATTICE) || defined(WIN32))
540 NH_abort(); /* generate core dump */
547 should_query_disclose_option(category
, defquery
)
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)) {
558 "should_query_disclose_option: bad disclosure index %d %c",
560 *defquery
= DISCLOSE_PROMPT_DEFAULT_YES
;
563 if (flags
.end_disclose
[idx
] == DISCLOSE_YES_WITHOUT_PROMPT
) {
566 } else if (flags
.end_disclose
[idx
] == DISCLOSE_NO_WITHOUT_PROMPT
) {
569 } else if (flags
.end_disclose
[idx
] == DISCLOSE_PROMPT_DEFAULT_YES
) {
572 } else if (flags
.end_disclose
[idx
] == DISCLOSE_PROMPT_DEFAULT_NO
) {
578 impossible("should_query_disclose_option: bad category %c", category
);
580 impossible("should_query_disclose_option: null defquery");
589 char c
= 0, defquery
;
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!");
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");
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
;
610 make_hallucinated(0L, FALSE
, 0L);
613 for (obj
= invent
; obj
; obj
= obj
->nobj
) {
614 makeknown(obj
->otyp
);
615 obj
->known
= obj
->bknown
= obj
->dknown
= obj
->rknown
= 1;
618 (void) dump_inventory((char *)0, TRUE
);
619 do_containerconts(invent
, TRUE
, TRUE
, TRUE
);
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
;
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
;
646 if (c
== 'q') done_stopprint
++;
651 dump_enlightenment((int) (how
>= PANICKED
? 1 : 2));
659 ask
= should_query_disclose_option('v', &defquery
);
662 do_vanquished(defquery
, ask
, TRUE
);
664 list_vanquished(defquery
, ask
);
667 ask
= should_query_disclose_option('g', &defquery
);
670 list_genocided(defquery
, ask
,TRUE
);
672 list_genocided(defquery
, ask
);
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
;
680 show_conduct(how
>= PANICKED
? 1 : 2);
681 if (c
== 'q') done_stopprint
++;
685 dump_conduct(how
>= PANICKED
? 1 : 2);
691 /* try to get the player back in a viable state after being killed */
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
) {
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
)) {
729 if (u
.uhunger
< 1000) {
733 /* cure impending doom of sickness hero won't have time to fix */
734 if ((Sick
& TIMEOUT
) == 1) {
738 if (how
== CHOKING
) init_uhunger();
739 nomovemsg
= "You survived that attempt on your life.";
741 if(multi
> 0) multi
= 0; else multi
= -1;
742 if(u
.utrap
&& u
.utraptype
== TT_LAVA
) u
.utrap
= 0;
744 u
.ugrave_arise
= NON_PM
;
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
764 struct obj
*list
; /* inventory or container contents */
766 register struct obj
*obj
;
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
) {
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
;
792 * Sort collected valuables, most frequent to least. We could just
793 * as easily use qsort, but we don't care about efficiency here.
796 sort_valuables(list
, size
)
797 struct valuable_data list
[];
798 int size
; /* max value is less than 20 */
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;
817 /* called twice; first to calculate total, then to list relevant items */
819 artifact_score(list
, counting
, endwin
)
821 boolean counting
; /* true => add up points; false => display them */
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 */
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
);
854 if (Has_contents(otmp
))
855 artifact_score(otmp
->cobj
, counting
, endwin
);
859 /* Be careful not to call panic from here! */
865 boolean goexplore
= FALSE
;
866 boolean gofreeplay
= FALSE
;
867 char kilbuf
[BUFSZ
], pbuf
[BUFSZ
];
871 winid endwin
= WIN_ERR
;
872 boolean bones_ok
, have_windows
= iflags
.window_inited
;
873 struct obj
*corpse
= (struct obj
*)0;
875 struct obj
*otmp
, *otmp2
;
879 boolean wanttodie
= 0;
881 if (how
== TRICKED
) {
883 paniclog("trickery", killer
);
888 You("are a very tricky wizard, it seems.");
894 if (iflags
.debug_fuzzer
) {
895 if (!(program_state
.panicking
|| how
== PANICKED
)) {
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
));
916 if (how
< PANICKED
) u
.umortality
++;
918 if (DywypiProblem
|| u
.uprops
[DYWYPI_PROBLEM
].extrinsic
|| have_dywypistone() || (uarmf
&& uarmf
->oartifact
== ART_PRADA_S_DEVIL_WEAR
)) {
922 sprintf(qbuf
, "Do you want your possessions identified? DYWYPI?");
923 possid
= yn_function(qbuf
, ynqchars
, 'y');
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...");
935 pline("Nyehehe-hehe-he, you would have lifesaved but you said you want your possessions identified! GAME OVER!");
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
);
946 u
.usymbiote
.mhp
= u
.usymbiote
.mhpmax
;
947 Your("symbiote glows, and your amulet crumbles to dust!");
949 u
.usymbiote
.active
= 0;
950 u
.usymbiote
.mnum
= PM_PLAYERMON
;
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;
967 livelog_avert_death();
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 */
985 else if (uamul
->blessed
)
991 pline("Nyehehe-hehe-he, you would have lifesaved but you said you want your possessions identified! GAME OVER!");
996 (void) adjattrib(A_CON
, -1, TRUE
, TRUE
);
997 if(u
.uhpmax
<= 0) u
.uhpmax
= 1;
1004 livelog_avert_death();
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!");
1018 pline("Nyehehe-hehe-he, you would have lifesaved but you said you want your possessions identified! GAME OVER!");
1022 if(u
.uhpmax
<= 0) u
.uhpmax
= 1; /* arbitrary */
1024 u
.lifesavepenalty
++;
1029 livelog_avert_death();
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;
1055 if (rnd(100) > contingencychance
) goto contingencydone
;
1057 pline("But wait...");
1058 pline("You lost the effect of contingency.");
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 */
1067 u
.lifesavepenalty
++;
1072 livelog_avert_death();
1081 if (uarmh
&& uarmh
->oartifact
== ART_LUXIDREAM_S_ASCENSION
&& how
< GENOCIDED
&& !rn2(10)) {
1082 pline("But wait...");
1083 pline("You come back to life!");
1086 pline("Nyehehe-hehe-he, you would have lifesaved but you said you want your possessions identified! GAME OVER!");
1090 if(u
.uhpmax
<= 0) u
.uhpmax
= 1; /* arbitrary */
1092 u
.lifesavepenalty
++;
1097 livelog_avert_death();
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!");
1111 pline("Nyehehe-hehe-he, you would have lifesaved but you said you want your possessions identified! GAME OVER!");
1115 if(u
.uhpmax
<= 0) u
.uhpmax
= 1; /* arbitrary */
1117 u
.lifesavepenalty
++;
1122 livelog_avert_death();
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!");
1137 pline("Nyehehe-hehe-he, you would have lifesaved but you said you want your possessions identified! GAME OVER!");
1141 if(u
.uhpmax
<= 0) u
.uhpmax
= 1; /* arbitrary */
1143 u
.lifesavepenalty
++;
1148 livelog_avert_death();
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!");
1162 pline("Nyehehe-hehe-he, you would have lifesaved but you said you want your possessions identified! GAME OVER!");
1166 if(u
.uhpmax
<= 0) u
.uhpmax
= 1; /* arbitrary */
1168 u
.lifesavepenalty
++;
1173 livelog_avert_death();
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!");
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 */
1194 u
.lifesavepenalty
++;
1199 livelog_avert_death();
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!");
1213 pline("Nyehehe-hehe-he, you would have lifesaved but you said you want your possessions identified! GAME OVER!");
1217 if(u
.uhpmax
<= 0) u
.uhpmax
= 1; /* arbitrary */
1219 u
.lifesavepenalty
++;
1224 livelog_avert_death();
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) {
1239 for (statxx
= 0; statxx
< A_MAX
; statxx
++) {
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
;
1255 evilskilldecrease();
1257 losexp("failed troll revival", TRUE
, FALSE
);
1259 pline("You come back to life!");
1262 pline("Nyehehe-hehe-he, you would have lifesaved but you said you want your possessions identified! GAME OVER!");
1266 if(u
.uhpmax
<= 0) u
.uhpmax
= 1; /* arbitrary */
1268 u
.lifesavepenalty
++;
1273 livelog_avert_death();
1282 /* Felids have 9 lives --Amy */
1283 if (Race_if(PM_FELID
) && u
.uhpmax
> 10 && how
< GENOCIDED
&& u
.ulevel
> 2 && (u
.felidlives
> 1) ) {
1285 pline("But wait...");
1286 losexp("failed felid revival", TRUE
, FALSE
);
1287 if (u
.uhpmax
< 11) {
1289 for (statxx
= 0; statxx
< A_MAX
; statxx
++) {
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
;
1305 evilskilldecrease();
1307 losexp("failed felid revival", TRUE
, FALSE
);
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
);
1313 pline("Nyehehe-hehe-he, you would have lifesaved but you said you want your possessions identified! GAME OVER!");
1317 if(u
.uhpmax
<= 0) u
.uhpmax
= 1; /* arbitrary */
1319 u
.lifesavepenalty
++;
1324 livelog_avert_death();
1333 if (u
.extralives
&& how
<= GENOCIDED
) {
1334 pline("But wait...");
1335 pline("You have an extra life!");
1338 pline("Nyehehe-hehe-he, you would have lifesaved but you said you want your possessions identified! GAME OVER!");
1343 if(u
.uhpmax
<= 0) u
.uhpmax
= 1; /* arbitrary */
1345 u
.lifesavepenalty
++;
1351 livelog_avert_death();
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!");
1375 pline("Nyehehe-hehe-he, you would have lifesaved but you said you want your possessions identified! GAME OVER!");
1379 (void) adjattrib(A_CON
, -1, TRUE
, TRUE
);
1380 if(u
.uhpmax
<= 0) u
.uhpmax
= 10; /* arbitrary */
1382 u
.lifesavepenalty
++;
1384 if (genomold
&& (how
== GENOCIDED
)) {
1385 if (Race_if(PM_UNGENOMOLD
)) {
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...");
1402 livelog_avert_death();
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!");
1420 pline("Nyehehe-hehe-he, you would have lifesaved but you said you want your possessions identified! GAME OVER!");
1424 (void) adjattrib(A_CON
, -1, TRUE
, TRUE
);
1425 if(u
.uhpmax
<= 0) u
.uhpmax
= 10; /* arbitrary */
1427 u
.lifesavepenalty
++;
1428 if (how
== GENOCIDED
)
1429 pline("Unfortunately you are still genocided...");
1435 livelog_avert_death();
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!");
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 */
1460 u
.lifesavepenalty
++;
1461 if (how
== GENOCIDED
)
1462 pline("Unfortunately you are still genocided...");
1468 livelog_avert_death();
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!");
1486 pline("Nyehehe-hehe-he, you would have lifesaved but you said you want your possessions identified! GAME OVER!");
1490 (void) adjattrib(A_CON
, -1, TRUE
, TRUE
);
1491 if(u
.uhpmax
<= 0) u
.uhpmax
= 10; /* arbitrary */
1493 u
.lifesavepenalty
++;
1494 if (how
== GENOCIDED
)
1495 pline("Unfortunately you are still genocided...");
1501 livelog_avert_death();
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!");
1519 pline("Nyehehe-hehe-he, you would have lifesaved but you said you want your possessions identified! GAME OVER!");
1523 (void) adjattrib(A_CON
, -1, TRUE
, TRUE
);
1524 if(u
.uhpmax
<= 0) u
.uhpmax
= 10; /* arbitrary */
1526 u
.lifesavepenalty
++;
1527 if (how
== GENOCIDED
)
1528 pline("Unfortunately you are still genocided...");
1534 livelog_avert_death();
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!");
1552 pline("Nyehehe-hehe-he, you would have lifesaved but you said you want your possessions identified! GAME OVER!");
1556 (void) adjattrib(A_CON
, -1, TRUE
, TRUE
);
1557 if(u
.uhpmax
<= 0) u
.uhpmax
= 10; /* arbitrary */
1559 u
.lifesavepenalty
++;
1560 if (how
== GENOCIDED
)
1561 pline("Unfortunately you are still genocided...");
1567 livelog_avert_death();
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!");
1585 pline("Nyehehe-hehe-he, you would have lifesaved but you said you want your possessions identified! GAME OVER!");
1589 (void) adjattrib(A_CON
, -1, TRUE
, TRUE
);
1590 if(u
.uhpmax
<= 0) u
.uhpmax
= 10; /* arbitrary */
1592 u
.lifesavepenalty
++;
1593 if (how
== GENOCIDED
)
1594 pline("Unfortunately you are still genocided...");
1600 livelog_avert_death();
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!");
1618 pline("Nyehehe-hehe-he, you would have lifesaved but you said you want your possessions identified! GAME OVER!");
1622 (void) adjattrib(A_CON
, -1, TRUE
, TRUE
);
1623 if(u
.uhpmax
<= 0) u
.uhpmax
= 10; /* arbitrary */
1625 u
.lifesavepenalty
++;
1626 if (how
== GENOCIDED
)
1627 pline("Unfortunately you are still genocided...");
1633 livelog_avert_death();
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!");
1651 pline("Nyehehe-hehe-he, you would have lifesaved but you said you want your possessions identified! GAME OVER!");
1655 (void) adjattrib(A_CON
, -1, TRUE
, TRUE
);
1656 if(u
.uhpmax
<= 0) u
.uhpmax
= 10; /* arbitrary */
1658 u
.lifesavepenalty
++;
1659 if (how
== GENOCIDED
)
1660 pline("Unfortunately you are still genocided...");
1666 livelog_avert_death();
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!");
1684 pline("Nyehehe-hehe-he, you would have lifesaved but you said you want your possessions identified! GAME OVER!");
1688 (void) adjattrib(A_CON
, -1, TRUE
, TRUE
);
1689 if(u
.uhpmax
<= 0) u
.uhpmax
= 10; /* arbitrary */
1691 u
.lifesavepenalty
++;
1692 if (how
== GENOCIDED
)
1693 pline("Unfortunately you are still genocided...");
1699 livelog_avert_death();
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
);
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!");
1730 pline("Nyehehe-hehe-he, you would have lifesaved but you said you want your possessions identified! GAME OVER!");
1734 (void) adjattrib(A_CON
, -1, TRUE
, TRUE
);
1735 if(u
.uhpmax
<= 0) u
.uhpmax
= 10; /* arbitrary */
1737 u
.lifesavepenalty
++;
1738 if (how
== GENOCIDED
)
1739 pline("Unfortunately you are still genocided...");
1745 livelog_avert_death();
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
) {
1764 if (uamul
->obrittle
>= 3) {
1765 pline_The("medallion crumbles to dust!");
1769 pline_The("medallion dulls quite a bit, but remains intact for now.");
1772 if (uamul
->obrittle2
>= 3) {
1773 pline_The("medallion crumbles to dust!");
1777 pline_The("medallion dulls quite a bit, but remains intact for now.");
1781 pline_The("medallion crumbles to dust!");
1786 pline("Nyehehe-hehe-he, you would have lifesaved but you said you want your possessions identified! GAME OVER!");
1790 (void) adjattrib(A_CON
, -1, TRUE
, TRUE
);
1791 if(u
.uhpmax
<= 0) u
.uhpmax
= 10; /* arbitrary */
1793 u
.lifesavepenalty
++;
1794 if (how
== GENOCIDED
)
1795 pline("Unfortunately you are still genocided...");
1801 livelog_avert_death();
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!");
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 */
1826 u
.lifesavepenalty
++;
1827 if (how
== GENOCIDED
)
1828 pline("Unfortunately you are still genocided...");
1834 livelog_avert_death();
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!");
1852 pline("Nyehehe-hehe-he, you would have lifesaved but you said you want your possessions identified! GAME OVER!");
1856 (void) adjattrib(A_CON
, -1, TRUE
, TRUE
);
1857 if(u
.uhpmax
<= 0) u
.uhpmax
= 10; /* arbitrary */
1859 u
.lifesavepenalty
++;
1860 if (how
== GENOCIDED
)
1861 pline("Unfortunately you are still genocided...");
1867 livelog_avert_death();
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!");
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 */
1892 u
.lifesavepenalty
++;
1893 if (how
== GENOCIDED
)
1894 pline("Unfortunately you are still genocided...");
1900 livelog_avert_death();
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
;
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!");
1923 pline("Nyehehe-hehe-he, you would have lifesaved but you said you want your possessions identified! GAME OVER!");
1927 (void) adjattrib(A_CON
, -1, TRUE
, TRUE
);
1928 if(u
.uhpmax
<= 0) u
.uhpmax
= 10; /* arbitrary */
1930 u
.lifesavepenalty
++;
1931 if (how
== GENOCIDED
)
1932 pline("Unfortunately you are still genocided...");
1938 livelog_avert_death();
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!");
1956 pline("Nyehehe-hehe-he, you would have lifesaved but you said you want your possessions identified! GAME OVER!");
1960 (void) adjattrib(A_CON
, -1, TRUE
, TRUE
);
1961 if(u
.uhpmax
<= 0) u
.uhpmax
= 10; /* arbitrary */
1963 u
.lifesavepenalty
++;
1964 if (how
== GENOCIDED
)
1965 pline("Unfortunately you are still genocided...");
1971 livelog_avert_death();
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!");
1990 pline("Nyehehe-hehe-he, you would have lifesaved but you said you want your possessions identified! GAME OVER!");
1994 (void) adjattrib(A_CON
, -1, TRUE
, TRUE
);
1995 if(u
.uhpmax
<= 0) u
.uhpmax
= 10; /* arbitrary */
1997 u
.lifesavepenalty
++;
1998 if (how
== GENOCIDED
)
1999 pline("Unfortunately you are still genocided...");
2005 livelog_avert_death();
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
);
2036 Your("pair of boots %s!", !Blind
? "begins to glow" : "feels warm");
2037 if (how
== CHOKING
) You("vomit ...");
2038 You_feel("much better!");
2041 pline("Nyehehe-hehe-he, you would have lifesaved but you said you want your possessions identified! GAME OVER!");
2045 (void) adjattrib(A_CON
, -1, TRUE
, TRUE
);
2046 if(u
.uhpmax
<= 0) u
.uhpmax
= 10; /* arbitrary */
2048 u
.lifesavepenalty
++;
2049 if (how
== GENOCIDED
)
2050 pline("Unfortunately you are still genocided...");
2056 livelog_avert_death();
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' ) {
2071 pline("Nyehehe-hehe-he, you would have lifesaved but you said you want your possessions identified! GAME OVER!");
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 */
2084 /* lose all items */
2087 for (otmp
= invent
; otmp
; otmp
= otmp2
) {
2090 if (evades_destruction(otmp
) ) dropx(otmp
);
2092 delete_contents(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
) {
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
);
2118 (void) safe_teleds_normalterrain(FALSE
);
2121 livelog_avert_death();
2128 else pline("You frantically hit the 'exit' button to escape from the grave... but it doesn't work...");
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' ) {
2141 pline("Nyehehe-hehe-he, you would have lifesaved but you said you want your possessions identified! GAME OVER!");
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 */
2154 /* lose all items */
2157 for (otmp
= invent
; otmp
; otmp
= otmp2
) {
2160 if (evades_destruction(otmp
) ) dropx(otmp
);
2162 delete_contents(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
) {
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
);
2188 (void) safe_teleds_normalterrain(FALSE
);
2191 livelog_avert_death();
2198 else pline("You should have listened to the voices you heard yesterday, they said: 'Tomorrow, Wendy, you're going to die.'");
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' ) {
2210 pline("Nyehehe-hehe-he, you would have lifesaved but you said you want your possessions identified! GAME OVER!");
2211 goto mrhighheeldone
;
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 */
2223 /* lose all items */
2226 for (otmp
= invent
; otmp
; otmp
= otmp2
) {
2229 if (evades_destruction(otmp
) ) dropx(otmp
);
2231 delete_contents(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
) {
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
);
2257 (void) safe_teleds_normalterrain(FALSE
);
2260 livelog_avert_death();
2267 else pline("Sadly, you lack the strength to get back up, so you stay dead.");
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' ) {
2279 pline("Nyehehe-hehe-he, you would have lifesaved but you said you want your possessions identified! GAME OVER!");
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 */
2292 /* lose all items */
2295 for (otmp
= invent
; otmp
; otmp
= otmp2
) {
2298 if (evades_destruction(otmp
) ) dropx(otmp
);
2300 delete_contents(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
) {
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
);
2326 (void) safe_teleds_normalterrain(FALSE
);
2329 livelog_avert_death();
2336 else pline("You frantically hit the 'exit' button to escape from the grave... but it doesn't work...");
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' ) {
2349 pline("Nyehehe-hehe-he, you would have lifesaved but you said you want your possessions identified! GAME OVER!");
2354 losexp("Rodneyan resurrection", TRUE
, FALSE
);
2355 if (u
.uhpmax
< 11) {
2357 for (statxx
= 0; statxx
< A_MAX
; statxx
++) {
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
;
2373 evilskilldecrease();
2375 losexp("Rodneyan resurrection", TRUE
, FALSE
);
2376 pline("You reappear in good health!");
2377 if(u
.uhpmax
<= 0) u
.uhpmax
= 1; /* arbitrary */
2382 /* lose all items */
2385 for (otmp
= invent
; otmp
; otmp
= otmp2
) {
2388 if (evades_destruction(otmp
) ) dropx(otmp
);
2390 delete_contents(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
) {
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
);
2416 (void) safe_teleds_normalterrain(FALSE
);
2419 livelog_avert_death();
2426 else pline("Too bad! Your experience level is too low for revival to work...");
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 */
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 */
2452 else if (iflags
.death_expl
&& how
<= GENOCIDED
&& !bones_ok
&&
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
;
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! */
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
);
2475 if (!(strcmp (buf
, "yes")) || !(strcmp (buf
, "y")) || !(strcmp (buf
, "ye")) || !(strcmp (buf
, "ys"))) { /* yes, do go on playing after ascending */
2479 } else goto freeplaycheck
;
2482 getlin ("You decided to end the game here. Please confirm your choice with yes [y/yes/no]",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...
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 */
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
)
2523 /* D: Grab screen dump right here */
2524 if (dump_fn
[0] && how
!= PANICKED
&& how
!= TRICKED
) {
2526 sprintf(pbuf
, "%s, %s %s %s %s", playeraliasname
,
2527 aligns
[1 - u
.ualign
.type
].adj
,
2528 genders
[flags
.female
].adj
,
2530 (flags
.female
&& urole
.name
.f
)?
2531 urole
.name
.f
: urole
.name
.m
);
2533 /* D: Add a line for clearance from the screen dump */
2538 if (lastmsg
>= 0 && how
!= PANICKED
&& how
!= TRICKED
) {
2541 dump("Latest messages", "");
2542 for (j
= lastmsg
+ 1; j
< DUMPMSGS
+ lastmsg
+ 1; j
++) {
2544 if (msgs
[i
] && strcmp(msgs
[i
], "") ) {
2545 if (msgs_count
[i
] == 1) {
2548 sprintf(tmpbuf
, "%s (%dx)", msgs
[i
], msgs_count
[i
]);
2556 if (how
!= PANICKED
&& how
!= TRICKED
) (void)doredraw();
2558 #endif /* DUMP_LOG */
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 */
2571 #ifdef RECORD_REALTIME
2572 /* Update the realtime counter to reflect the playtime of the current
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
) {
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
);
2602 #endif /* NO_SIGNAL */
2605 if(iflags
.usealleg
&& (how
< PANICKED
))
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 */
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
;
2625 /* Base corpse on race when not poly'd since original
2626 * u.umonnum is based on role, and all role monsters
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
);
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
);
2645 make_grave(u
.ux
, u
.uy
, pbuf
);
2648 } /* if (!goexplore) */
2649 if (how
== TURNED_SLIME
) killer_format
= NO_KILLER_PREFIX
;
2651 killer_format
= NO_KILLER_PREFIX
;
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
));
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 */
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] */
2684 int deepest
= deepest_lev_reached(FALSE
);
2690 umoney
= money_cnt(invent
);
2693 umoney
+= hidden_gold(); /* accumulate gold from containers */
2694 tmp
= umoney
- tmp
; /* net gain */
2701 u
.urexp
+= 50L * (long)(deepest
- 1);
2702 if (how
== ASCENDED
) {
2707 discover
= FALSE
; /* a kludge to fool the topten function.. */
2709 umoney
-= hidden_gold();
2710 if (u
.urexp
> 1) u
.urexp
/= 2;
2712 u
.urexp
-= 50L * (long)(deepest
- 1);
2714 if (flags
.moreforced
&& !MessagesSuppressed
) display_nhwindow(WIN_MESSAGE
, TRUE
); /* --More-- */
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
;
2729 for (otmpi
= invent
; otmpi
; otmpi
= otmpii
) {
2730 otmpii
= otmpi
->nobj
;
2731 if (otmpi
->otyp
== AMULET_OF_YENDOR
) {
2732 if (otmpi
->owornmask
) {
2740 goto_level(&medusa_level
, TRUE
, FALSE
, FALSE
);
2742 register int newlevX
= 1;
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!");
2760 discover
= FALSE
; /* a kludge to fool the topten function.. */
2762 /* undo some things that were done for score calculation */
2763 /* this branch is not entered when you ascend, escape or quit */
2765 umoney
-= hidden_gold();
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;
2774 if (flags
.moreforced
&& !MessagesSuppressed
) display_nhwindow(WIN_MESSAGE
, TRUE
); /* --More-- */
2780 /* if the screen is redrawn at this point, the MC display can somehow crash --Amy */
2781 program_state
.bonesdo
= TRUE
;
2785 /* KMH -- We need the "Save bones?" prompt for testing! */
2786 if (!wizard
|| yn("Save bones?") == 'y')
2788 {if (Frozen
) corpse
= (struct obj
*)0; /* no corpse if player exploded into ice cubes --Amy */
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...) */
2801 done_money
= umoney
;
2804 /* clean up unneeded windows */
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
);
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, "");*/
2845 if (dump_fp
) dump("", pbuf
);
2848 if (how
== ESCAPED
|| how
== ASCENDED
|| u
.freeplaymode
) {
2849 register struct monst
*mtmp
;
2850 register struct obj
*otmp
;
2851 register struct val_list
*val
;
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
);
2871 viz_array
[0][0] |= IN_SIGHT
; /* need visibility for naming */
2873 strcpy(pbuf
, "You");
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
));
2883 u
.urexp
+= mtmp
->mhp
;
2886 if (!done_stopprint
) putstr(endwin
, 0, pbuf
);
2888 if (dump_fp
) dump("", pbuf
);
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
));
2900 if (dump_fp
) dump("", pbuf
);
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
);
2920 makeknown(otmp
->otyp
);
2921 otmp
->known
= 1; /* for fake amulets */
2922 otmp
->dknown
= 1; /* seen it (blindness fix) */
2925 sprintf(pbuf
, "%8ld %s (worth %ld %s),",
2927 count
* (long)objects
[typ
].oc_cost
, currency(2L));
2928 obfree(otmp
, (struct obj
*)0);
2932 "%8ld worthless piece%s of colored glass,",
2933 count
, plur(count
));
2935 putstr(endwin
, 0, pbuf
);
2937 if (dump_fp
) dump("", pbuf
);
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
]);
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
);
2964 if (dump_fp
) dump("", pbuf
);
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
);
2975 sprintf(pbuf
, "Killer: %s", killer
);
2980 if (!done_stopprint
) {
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, "");*/
2987 if (dump_fp
) dump("", pbuf
);
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
2997 if (flags
.toptenwin
) {
3000 exit_nhwindows((char *)0);
3003 exit_nhwindows((char *)0);
3007 if (dump_fp
) dump_exit();
3010 if(done_stopprint
) { raw_print(""); raw_print(""); }
3011 terminate(EXIT_SUCCESS
);
3016 container_contents(list
, identified
, all_containers
)
3018 boolean identified
, all_containers
;
3021 do_containerconts(list
, identified
, all_containers
, FALSE
);
3024 void do_containerconts(list
, identified
, all_containers
, want_dump
)
3026 boolean identified
, all_containers
, want_dump
;
3028 /* The original container_contents function */
3030 register struct obj
*box
, *obj
;
3031 struct obj
**oarray
;
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 */
3050 invlet
= flags
.inv_order
;
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
))
3062 oarray
[j
] = oarray
[j
-1];
3067 /* Just add it to the array */
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, "");
3080 if (dump_fp
) dump("", buf
);
3082 for (i
= 0; i
< n
; i
++) {
3085 /*for (obj = box->cobj; obj; obj = obj->nobj) {*/ /* pre-sortloot */
3087 makeknown(obj
->otyp
);
3088 obj
->known
= obj
->bknown
=
3089 obj
->dknown
= obj
->rknown
= 1;
3091 putstr(tmpwin
, 0, doname(obj
));
3093 if (want_dump
) dump(" ", doname(obj
));
3097 if (want_dump
) dump("","");
3099 display_nhwindow(tmpwin
, TRUE
);
3100 destroy_nhwindow(tmpwin
);
3101 if (all_containers
) {
3103 do_containerconts(box
->cobj
, identified
, TRUE
,
3106 container_contents(box
->cobj
, identified
, TRUE
);
3107 #endif /* DUMP_LOG */
3110 pline("%s empty.", Tobjnam(box
, "are"));
3111 display_nhwindow(WIN_MESSAGE
, FALSE
);
3114 dump(The(xname(box
)), " is empty.");
3120 if (!all_containers
)
3125 /* should be called with either EXIT_SUCCESS or EXIT_FAILURE */
3130 program_state
.in_moveloop
= 0; /* won't be returning to normal play */
3132 getreturn("to exit");
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
) {
3141 program_state
.exiting
= 1;
3142 nethack_exit(status
);
3146 list_vanquished(defquery
, ask
)
3151 do_vanquished(defquery
, ask
, FALSE
);
3154 /* this function should return something... but the return isn't used anywhere --Amy */
3158 do_vanquished(defquery
, ask
, want_dump
)
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;
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
3188 c
= ask
? yn_function("Do you want an account of creatures vanquished?",
3189 ynqchars
, defquery
) : defquery
;
3190 if (c
== 'q') done_stopprint
++;
3192 klwin
= create_nhwindow(NHW_MENU
);
3193 putstr(klwin
, 0, "Vanquished creatures:");
3194 putstr(klwin
, 0, "");
3196 if (want_dump
) dump("", "Vanquished creatures");
3199 /* countdown by monster "toughness" */
3200 /*for (lev = max_lev; lev >= 0; lev--)*/
3201 for (i
= LOW_PM
; i
< NUMMONS
; i
++)
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
);
3210 if (want_dump
) dump(" ", buf
);
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 " : "",
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
));
3230 /* trolls or undead might have come back,
3231 but we don't keep track of that */
3233 strcpy(buf
, an(mons
[i
].mname
));
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
);
3243 if (want_dump
) dump(" ", buf
);
3247 * if (Hallucination)
3248 * putstr(klwin, 0, "and a partridge in a pear tree");
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
);
3257 if (want_dump
) dump(" ", buf
);
3261 sprintf(buf
, "%ld creature%s vanquished.", total_killed
, total_killed
== 1 ? "" : "s");
3262 putstr(klwin
, 0, buf
);
3264 if (want_dump
) dump(" ", buf
);
3268 if (program_state
.gameover
|| wizard
) {
3269 sprintf(buf
, "%ld boss%s born.", bosses_born
, bosses_born
== 1 ? "" : "es");
3270 putstr(klwin
, 0, buf
);
3272 if (want_dump
) dump(" ", buf
);
3276 sprintf(buf
, "%ld boss%s vanquished.", bosses_killed
, bosses_killed
== 1 ? "" : "es");
3277 putstr(klwin
, 0, buf
);
3279 if (want_dump
) dump(" ", buf
);
3283 display_nhwindow(klwin
, TRUE
);
3284 destroy_nhwindow(klwin
);
3286 if (want_dump
) dump("", "");
3293 return (boolean
) (total_killed
);
3300 if (!list_vanquished('y', FALSE
))
3301 pline("Vanquished monsters listing complete."); /* because dumplog changed that function to a void! --Amy */
3305 /* number of monster species which have been genocided */
3311 for (i
= LOW_PM
; i
< NUMMONS
; ++i
)
3312 if (mvitals
[i
].mvflags
& G_GENOD
) ++n
;
3319 list_genocided(defquery
, ask
, want_dump
)
3325 list_genocided(defquery
, ask
)
3337 /* get totals first */
3338 for (i
= LOW_PM
; i
< NUMMONS
; i
++) {
3339 if (mvitals
[i
].mvflags
& G_GENOD
)
3341 else if ( (mvitals
[i
].mvflags
& G_GONE
) && !(mons
[i
].geno
& G_UNIQ
) )
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
++;
3353 klwin
= create_nhwindow(NHW_MENU
);
3354 sprintf(buf
, "Genocided species:");
3355 putstr(klwin
, 0, buf
);
3356 putstr(klwin
, 0, "");
3358 if (want_dump
) dump("", buf
);
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 ",
3369 strcpy(buf
, makeplural(mons
[i
].mname
));
3370 if( !(mvitals
[i
].mvflags
& G_GENOD
) )
3371 strcat(buf
, " (extinct)");
3372 putstr(klwin
, 0, buf
);
3374 if (want_dump
) dump(" ", buf
);
3378 putstr(klwin
, 0, "");
3379 sprintf(buf
, "%d species genocided.", ngenocided
);
3380 putstr(klwin
, 0, buf
);
3382 if (want_dump
) dump(" ", buf
);
3385 sprintf(buf
, "%d species extinct.", nextincted
);
3386 putstr(klwin
, 0, buf
);
3387 display_nhwindow(klwin
, TRUE
);
3388 destroy_nhwindow(klwin
);
3397 FILE *extrai
= (FILE *)0;
3399 mode_t eimode
= S_IRUSR
| S_IWUSR
| S_IRGRP
| S_IROTH
;
3403 /* certain nasty traps obscure the information - so we want to hide it from whereis too! --Amy */
3404 if (DisplayDoesNotGo
|| TheInfoIsFucked
) {
3408 sprintf(new_fn
, "%s", dump_format_str(EXTRAINFO_FN
));
3410 extrai
= fopen_datafile_area(FILE_AREA_VAR
, new_fn
, "w", LEVELPREFIX
);
3415 if (Is_knox(&u
.uz
)) {
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");
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
);
3548 sprintf(tmpdng
, "%i|%c%cD%i", sortval
, ' ', ' ', depth(&u
.uz
));
3552 chmod(new_fn
, eimode
);
3554 fwrite(tmpdng
,strlen(tmpdng
),1,extrai
);
3557 #endif /* EXTRAINFO_FN */