~ubuntu-branches/ubuntu/vivid/nethack/vivid

« back to all changes in this revision

Viewing changes to .pc/0014-94_enh_sortloot.dpatch-by-Jeroen-Demeyer-and-Jukka-L.patch/src/end.c

  • Committer: Package Import Robot
  • Author(s): Vincent Cheng, Bernhard R. Link, Vincent Cheng
  • Date: 2012-06-11 00:47:38 UTC
  • mfrom: (3.1.9 sid)
  • Revision ID: package-import@ubuntu.com-20120611004738-3fy8b3wi0j45y2oq
Tags: 3.4.3-14
* Team upload.

[ Bernhard R. Link ]
* switch to "3.0 (quilt)"
* bump Standards-Version
* modernize debian/rules:
- use dpkg-buildflags
- support build-arch/-indep
- make parallel safe
- don't avoid make errors
* add patch so it can compile with -Werror=format-security
* drop no longer needed patches (-qt and -gnome are gone)
* don't use /dev/null as install template (Closes: 644647)
* drop nethack-common menu (both -console and -x11 have one)

[ Vincent Cheng ]
* Adopt package. (Closes: #673584)
  - Change Maintainer to Debian Games Team.
  - Add myself to Uploaders.
* Modify 0006-Common-config.h-for-all-binary-packages.patch to enable
  AUTOPICKUP_EXCEPTIONS. (Closes: #329318)
* Modify 0011-Pasi-Kallinen-s-patch-to-add-colors-to-inventory-ite.patch
  and 0017-Debian-and-Linux-specifics-defined-in-unixconf.h.patch; add
  0021-fix-kfreebsd-ftbfs.patch to fix FTBFS on kfreebsd.
* Convert debian/copyright to DEP-5 machine-readable format.
* Use dh_lintian to install overrides instead of manually installing them
  in debian/rules.
* Add watch file.
* Add Homepage field in debian/control.
* Add Vcs-* fields in debian/control.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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. */
 
4
 
 
5
#define NEED_VARARGS    /* comment line for pre-compiled headers */
 
6
 
 
7
#include "hack.h"
 
8
#include "eshk.h"
 
9
#ifndef NO_SIGNAL
 
10
#include <signal.h>
 
11
#endif
 
12
#include "dlb.h"
 
13
 
 
14
        /* these probably ought to be generated by makedefs, like LAST_GEM */
 
15
#define FIRST_GEM    DILITHIUM_CRYSTAL
 
16
#define FIRST_AMULET AMULET_OF_ESP
 
17
#define LAST_AMULET  AMULET_OF_YENDOR
 
18
 
 
19
struct valuable_data { long count; int typ; };
 
20
 
 
21
static struct valuable_data
 
22
        gems[LAST_GEM+1 - FIRST_GEM + 1], /* 1 extra for glass */
 
23
        amulets[LAST_AMULET+1 - FIRST_AMULET];
 
24
 
 
25
static struct val_list { struct valuable_data *list; int size; } valuables[] = {
 
26
        { gems,    sizeof gems / sizeof *gems },
 
27
        { amulets, sizeof amulets / sizeof *amulets },
 
28
        { 0, 0 }
 
29
};
 
30
 
 
31
#ifndef NO_SIGNAL
 
32
STATIC_PTR void FDECL(done_intr, (int));
 
33
# if defined(UNIX) || defined(VMS) || defined (__EMX__)
 
34
static void FDECL(done_hangup, (int));
 
35
# endif
 
36
#endif
 
37
STATIC_DCL void FDECL(disclose,(int,BOOLEAN_P));
 
38
STATIC_DCL void FDECL(get_valuables, (struct obj *));
 
39
STATIC_DCL void FDECL(sort_valuables, (struct valuable_data *,int));
 
40
STATIC_DCL void FDECL(artifact_score, (struct obj *,BOOLEAN_P,winid));
 
41
STATIC_DCL void FDECL(savelife, (int));
 
42
STATIC_DCL void FDECL(list_vanquished, (CHAR_P,BOOLEAN_P));
 
43
#ifdef DUMP_LOG
 
44
extern void NDECL(dump_spells);
 
45
void FDECL(do_vanquished, (int, BOOLEAN_P, BOOLEAN_P));
 
46
STATIC_DCL void FDECL(list_genocided, (int, BOOLEAN_P, BOOLEAN_P));
 
47
#else
 
48
STATIC_DCL void FDECL(list_genocided, (CHAR_P,BOOLEAN_P));
 
49
#endif /* DUMP_LOG */
 
50
STATIC_DCL boolean FDECL(should_query_disclose_option, (int,char *));
 
51
 
 
52
#if defined(__BEOS__) || defined(MICRO) || defined(WIN32) || defined(OS2)
 
53
extern void FDECL(nethack_exit,(int));
 
54
#else
 
55
#define nethack_exit exit
 
56
#endif
 
57
 
 
58
#define done_stopprint program_state.stopprint
 
59
 
 
60
#ifdef AMIGA
 
61
# define NH_abort()     Abort(0)
 
62
#else
 
63
# ifdef SYSV
 
64
# define NH_abort()     (void) abort()
 
65
# else
 
66
#  ifdef WIN32
 
67
# define NH_abort()     win32_abort()
 
68
#  else
 
69
# define NH_abort()     abort()
 
70
#  endif
 
71
# endif
 
72
#endif
 
73
 
 
74
/*
 
75
 * The order of these needs to match the macros in hack.h.
 
76
 */
 
77
static NEARDATA const char *deaths[] = {                /* the array of death */
 
78
        "died", "choked", "poisoned", "starvation", "drowning",
 
79
        "burning", "dissolving under the heat and pressure",
 
80
        "crushed", "turned to stone", "turned into slime",
 
81
        "genocided", "panic", "trickery",
 
82
        "quit", "escaped", "ascended"
 
83
};
 
84
 
 
85
static NEARDATA const char *ends[] = {          /* "when you..." */
 
86
        "died", "choked", "were poisoned", "starved", "drowned",
 
87
        "burned", "dissolved in the lava",
 
88
        "were crushed", "turned to stone", "turned into slime",
 
89
        "were genocided", "panicked", "were tricked",
 
90
        "quit", "escaped", "ascended"
 
91
};
 
92
 
 
93
extern const char * const killed_by_prefix[];   /* from topten.c */
 
94
 
 
95
#ifdef DUMP_LOG
 
96
FILE *dump_fp = (FILE *)0;  /* file pointer for dumps */
 
97
/* functions dump_init, dump_exit and dump are from the dump patch */
 
98
 
 
99
void
 
100
dump_init ()
 
101
{
 
102
  if (dump_fn[0]) {
 
103
    char *p = (char *) strstr(dump_fn, "%n");
 
104
    if (p) {
 
105
      int new_dump_fn_len = strlen(dump_fn)+strlen(plname)-2; /* %n */
 
106
      char *new_dump_fn = (char *) alloc((unsigned)(new_dump_fn_len+1));
 
107
      char *q = new_dump_fn;
 
108
      strncpy(q, dump_fn, p-dump_fn);
 
109
      q += p-dump_fn;
 
110
      strncpy(q, plname, strlen(plname) + 1);
 
111
      regularize(q);
 
112
      q[strlen(plname)] = '\0';
 
113
      q += strlen(q);
 
114
      p += 2;   /* skip "%n" */
 
115
      strncpy(q, p, strlen(p));
 
116
      new_dump_fn[new_dump_fn_len] = '\0';
 
117
 
 
118
      dump_fp = fopen(new_dump_fn, "w");
 
119
      if (!dump_fp) {
 
120
        pline("Can't open %s for output.", new_dump_fn);
 
121
        pline("Dump file not created.");
 
122
      }
 
123
      free(new_dump_fn);
 
124
      
 
125
    } else {
 
126
      dump_fp = fopen (dump_fn, "w");
 
127
 
 
128
      if (!dump_fp) {
 
129
        pline("Can't open %s for output.", dump_fn);
 
130
        pline("Dump file not created.");
 
131
      }
 
132
    }
 
133
  }
 
134
}
 
135
 
 
136
void
 
137
dump_exit ()
 
138
{
 
139
  if (dump_fp)
 
140
    fclose (dump_fp);
 
141
}
 
142
 
 
143
void dump (pre, str)
 
144
     char *pre, *str;
 
145
{
 
146
  if (dump_fp)
 
147
    fprintf (dump_fp, "%s%s\n", pre, str);
 
148
}
 
149
#endif  /* DUMP_LOG */
 
150
 
 
151
/*ARGSUSED*/
 
152
void
 
153
done1(sig_unused)   /* called as signal() handler, so sent at least one arg */
 
154
int sig_unused;
 
155
{
 
156
#ifndef NO_SIGNAL
 
157
        (void) signal(SIGINT,SIG_IGN);
 
158
#endif
 
159
        if(flags.ignintr) {
 
160
#ifndef NO_SIGNAL
 
161
                (void) signal(SIGINT, (SIG_RET_TYPE) done1);
 
162
#endif
 
163
                clear_nhwindow(WIN_MESSAGE);
 
164
                curs_on_u();
 
165
                wait_synch();
 
166
                if(multi > 0) nomul(0);
 
167
        } else {
 
168
                (void)done2();
 
169
        }
 
170
}
 
171
 
 
172
 
 
173
/* "#quit" command or keyboard interrupt */
 
174
int
 
175
done2()
 
176
{
 
177
        if(yn("Really quit?") == 'n') {
 
178
#ifndef NO_SIGNAL
 
179
                (void) signal(SIGINT, (SIG_RET_TYPE) done1);
 
180
#endif
 
181
                clear_nhwindow(WIN_MESSAGE);
 
182
                curs_on_u();
 
183
                wait_synch();
 
184
                if(multi > 0) nomul(0);
 
185
                if(multi == 0) {
 
186
                    u.uinvulnerable = FALSE;    /* avoid ctrl-C bug -dlc */
 
187
                    u.usleep = 0;
 
188
                }
 
189
                return 0;
 
190
        }
 
191
#if defined(WIZARD) && (defined(UNIX) || defined(VMS) || defined(LATTICE))
 
192
        if(wizard) {
 
193
            int c;
 
194
# ifdef VMS
 
195
            const char *tmp = "Enter debugger?";
 
196
# else
 
197
#  ifdef LATTICE
 
198
            const char *tmp = "Create SnapShot?";
 
199
#  else
 
200
            const char *tmp = "Dump core?";
 
201
#  endif
 
202
# endif
 
203
            if ((c = ynq(tmp)) == 'y') {
 
204
                (void) signal(SIGINT, (SIG_RET_TYPE) done1);
 
205
                exit_nhwindows((char *)0);
 
206
                NH_abort();
 
207
            } else if (c == 'q') done_stopprint++;
 
208
        }
 
209
#endif
 
210
#ifndef LINT
 
211
        done(QUIT);
 
212
#endif
 
213
        return 0;
 
214
}
 
215
 
 
216
#ifndef NO_SIGNAL
 
217
/*ARGSUSED*/
 
218
STATIC_PTR void
 
219
done_intr(sig_unused) /* called as signal() handler, so sent at least one arg */
 
220
int sig_unused;
 
221
{
 
222
        done_stopprint++;
 
223
        (void) signal(SIGINT, SIG_IGN);
 
224
# if defined(UNIX) || defined(VMS)
 
225
        (void) signal(SIGQUIT, SIG_IGN);
 
226
# endif
 
227
        return;
 
228
}
 
229
 
 
230
# if defined(UNIX) || defined(VMS) || defined(__EMX__)
 
231
static void
 
232
done_hangup(sig)        /* signal() handler */
 
233
int sig;
 
234
{
 
235
        program_state.done_hup++;
 
236
        (void)signal(SIGHUP, SIG_IGN);
 
237
        done_intr(sig);
 
238
        return;
 
239
}
 
240
# endif
 
241
#endif /* NO_SIGNAL */
 
242
 
 
243
void
 
244
done_in_by(mtmp)
 
245
register struct monst *mtmp;
 
246
{
 
247
        char buf[BUFSZ];
 
248
        boolean distorted = (boolean)(Hallucination && canspotmon(mtmp));
 
249
 
 
250
        You("die...");
 
251
        mark_synch();   /* flush buffered screen output */
 
252
        buf[0] = '\0';
 
253
        killer_format = KILLED_BY_AN;
 
254
        /* "killed by the high priest of Crom" is okay, "killed by the high
 
255
           priest" alone isn't */
 
256
        if ((mtmp->data->geno & G_UNIQ) != 0 && !(mtmp->data == &mons[PM_HIGH_PRIEST] && !mtmp->ispriest)) {
 
257
            if (!type_is_pname(mtmp->data))
 
258
                Strcat(buf, "the ");
 
259
            killer_format = KILLED_BY;
 
260
        }
 
261
        /* _the_ <invisible> <distorted> ghost of Dudley */
 
262
        if (mtmp->data == &mons[PM_GHOST] && mtmp->mnamelth) {
 
263
                Strcat(buf, "the ");
 
264
                killer_format = KILLED_BY;
 
265
        }
 
266
        if (mtmp->minvis)
 
267
                Strcat(buf, "invisible ");
 
268
        if (distorted)
 
269
                Strcat(buf, "hallucinogen-distorted ");
 
270
 
 
271
        if(mtmp->data == &mons[PM_GHOST]) {
 
272
                Strcat(buf, "ghost");
 
273
                if (mtmp->mnamelth) Sprintf(eos(buf), " of %s", NAME(mtmp));
 
274
        } else if(mtmp->isshk) {
 
275
                Sprintf(eos(buf), "%s %s, the shopkeeper",
 
276
                        (mtmp->female ? "Ms." : "Mr."), shkname(mtmp));
 
277
                killer_format = KILLED_BY;
 
278
        } else if (mtmp->ispriest || mtmp->isminion) {
 
279
                /* m_monnam() suppresses "the" prefix plus "invisible", and
 
280
                   it overrides the effect of Hallucination on priestname() */
 
281
                killer = m_monnam(mtmp);
 
282
                Strcat(buf, killer);
 
283
        } else {
 
284
                Strcat(buf, mtmp->data->mname);
 
285
                if (mtmp->mnamelth)
 
286
                    Sprintf(eos(buf), " called %s", NAME(mtmp));
 
287
        }
 
288
 
 
289
        if (multi) Strcat(buf, ", while helpless");
 
290
        killer = buf;
 
291
        if (mtmp->data->mlet == S_WRAITH)
 
292
                u.ugrave_arise = PM_WRAITH;
 
293
        else if (mtmp->data->mlet == S_MUMMY && urace.mummynum != NON_PM)
 
294
                u.ugrave_arise = urace.mummynum;
 
295
        else if (mtmp->data->mlet == S_VAMPIRE && Race_if(PM_HUMAN))
 
296
                u.ugrave_arise = PM_VAMPIRE;
 
297
        else if (mtmp->data == &mons[PM_GHOUL])
 
298
                u.ugrave_arise = PM_GHOUL;
 
299
        if (u.ugrave_arise >= LOW_PM &&
 
300
                                (mvitals[u.ugrave_arise].mvflags & G_GENOD))
 
301
                u.ugrave_arise = NON_PM;
 
302
        if (touch_petrifies(mtmp->data))
 
303
                done(STONING);
 
304
        else
 
305
                done(DIED);
 
306
        return;
 
307
}
 
308
 
 
309
#if defined(WIN32)
 
310
#define NOTIFY_NETHACK_BUGS
 
311
#endif
 
312
 
 
313
/*VARARGS1*/
 
314
void
 
315
panic VA_DECL(const char *, str)
 
316
        VA_START(str);
 
317
        VA_INIT(str, char *);
 
318
 
 
319
        if (program_state.panicking++)
 
320
            NH_abort(); /* avoid loops - this should never happen*/
 
321
 
 
322
        if (iflags.window_inited) {
 
323
            raw_print("\r\nOops...");
 
324
            wait_synch();       /* make sure all pending output gets flushed */
 
325
            exit_nhwindows((char *)0);
 
326
            iflags.window_inited = 0; /* they're gone; force raw_print()ing */
 
327
        }
 
328
 
 
329
        raw_print(program_state.gameover ?
 
330
                  "Postgame wrapup disrupted." :
 
331
                  !program_state.something_worth_saving ?
 
332
                  "Program initialization has failed." :
 
333
                  "Suddenly, the dungeon collapses.");
 
334
#if defined(WIZARD) && !defined(MICRO)
 
335
# if defined(NOTIFY_NETHACK_BUGS)
 
336
        if (!wizard)
 
337
            raw_printf("Report the following error to \"%s\".",
 
338
                        "nethack-bugs@nethack.org");
 
339
        else if (program_state.something_worth_saving)
 
340
            raw_print("\nError save file being written.\n");
 
341
# else
 
342
        if (!wizard)
 
343
            raw_printf("Report error to \"%s\"%s.",
 
344
#  ifdef WIZARD_NAME    /*(KR1ED)*/
 
345
                        WIZARD_NAME,
 
346
#  else
 
347
                        WIZARD,
 
348
#  endif
 
349
                        !program_state.something_worth_saving ? "" :
 
350
                        " and it may be possible to rebuild.");
 
351
# endif
 
352
        if (program_state.something_worth_saving) {
 
353
            set_error_savefile();
 
354
            (void) dosave0();
 
355
        }
 
356
#endif
 
357
        {
 
358
            char buf[BUFSZ];
 
359
            Vsprintf(buf,str,VA_ARGS);
 
360
            raw_print(buf);
 
361
            paniclog("panic", buf);
 
362
        }
 
363
#ifdef WIN32
 
364
        interject(INTERJECT_PANIC);
 
365
#endif
 
366
#if defined(WIZARD) && (defined(UNIX) || defined(VMS) || defined(LATTICE) || defined(WIN32))
 
367
        if (wizard)
 
368
            NH_abort(); /* generate core dump */
 
369
#endif
 
370
        VA_END();
 
371
        done(PANICKED);
 
372
}
 
373
 
 
374
STATIC_OVL boolean
 
375
should_query_disclose_option(category, defquery)
 
376
int category;
 
377
char *defquery;
 
378
{
 
379
    int idx;
 
380
    char *dop = index(disclosure_options, category);
 
381
 
 
382
    if (dop && defquery) {
 
383
        idx = dop - disclosure_options;
 
384
        if (idx < 0 || idx > (NUM_DISCLOSURE_OPTIONS - 1)) {
 
385
            impossible(
 
386
                   "should_query_disclose_option: bad disclosure index %d %c",
 
387
                       idx, category);
 
388
            *defquery = DISCLOSE_PROMPT_DEFAULT_YES;
 
389
            return TRUE;
 
390
        }
 
391
        if (flags.end_disclose[idx] == DISCLOSE_YES_WITHOUT_PROMPT) {
 
392
            *defquery = 'y';
 
393
            return FALSE;
 
394
        } else if (flags.end_disclose[idx] == DISCLOSE_NO_WITHOUT_PROMPT) {
 
395
            *defquery = 'n';
 
396
            return FALSE;
 
397
        } else if (flags.end_disclose[idx] == DISCLOSE_PROMPT_DEFAULT_YES) {
 
398
            *defquery = 'y';
 
399
            return TRUE;
 
400
        } else if (flags.end_disclose[idx] == DISCLOSE_PROMPT_DEFAULT_NO) {
 
401
            *defquery = 'n';
 
402
            return TRUE;
 
403
        }
 
404
    }
 
405
    if (defquery)
 
406
        impossible("should_query_disclose_option: bad category %c", category);
 
407
    else
 
408
        impossible("should_query_disclose_option: null defquery");
 
409
    return TRUE;
 
410
}
 
411
 
 
412
STATIC_OVL void
 
413
disclose(how,taken)
 
414
int how;
 
415
boolean taken;
 
416
{
 
417
        char    c = 0, defquery;
 
418
        char    qbuf[QBUFSZ];
 
419
        boolean ask;
 
420
 
 
421
        if (invent) {
 
422
            if(taken)
 
423
                Sprintf(qbuf,"Do you want to see what you had when you %s?",
 
424
                        (how == QUIT) ? "quit" : "died");
 
425
            else
 
426
                Strcpy(qbuf,"Do you want your possessions identified?");
 
427
 
 
428
            ask = should_query_disclose_option('i', &defquery);
 
429
            if (!done_stopprint) {
 
430
                c = ask ? yn_function(qbuf, ynqchars, defquery) : defquery;
 
431
                if (c == 'y') {
 
432
                        struct obj *obj;
 
433
 
 
434
                        for (obj = invent; obj; obj = obj->nobj) {
 
435
                            makeknown(obj->otyp);
 
436
                            obj->known = obj->bknown = obj->dknown = obj->rknown = 1;
 
437
                        }
 
438
#ifdef DUMP_LOG
 
439
                        (void) dump_inventory((char *)0, TRUE);
 
440
                        do_containerconts(invent, TRUE, TRUE, TRUE);
 
441
#else
 
442
                        (void) display_inventory((char *)0, TRUE);
 
443
                        container_contents(invent, TRUE, TRUE);
 
444
#endif /* DUMP_LOG */
 
445
                }
 
446
                if (c == 'q')  done_stopprint++;
 
447
            }
 
448
        }
 
449
 
 
450
        ask = should_query_disclose_option('a', &defquery);
 
451
        if (!done_stopprint) {
 
452
            c = ask ? yn_function("Do you want to see your attributes?",
 
453
                                  ynqchars, defquery) : defquery;
 
454
            if (c == 'y')
 
455
                enlightenment(how >= PANICKED ? 1 : 2); /* final */
 
456
            if (c == 'q') done_stopprint++;
 
457
        }
 
458
#ifdef DUMP_LOG
 
459
        if (dump_fp) {
 
460
          dump_enlightenment((int) (how >= PANICKED ? 1 : 2));
 
461
          dump_spells();
 
462
        }
 
463
#endif
 
464
 
 
465
        ask = should_query_disclose_option('v', &defquery);
 
466
        if (!done_stopprint)
 
467
#ifdef DUMP_LOG
 
468
            do_vanquished(defquery, ask, TRUE);
 
469
#else
 
470
            list_vanquished(defquery, ask);
 
471
#endif
 
472
 
 
473
        ask = should_query_disclose_option('g', &defquery);
 
474
        if (!done_stopprint)
 
475
#ifdef DUMP_LOG
 
476
            list_genocided(defquery, ask,TRUE);
 
477
#else
 
478
            list_genocided(defquery, ask);
 
479
#endif
 
480
 
 
481
        ask = should_query_disclose_option('c', &defquery);
 
482
        if (!done_stopprint) {
 
483
            c = ask ? yn_function("Do you want to see your conduct?",
 
484
                                  ynqchars, defquery) : defquery;
 
485
            if (c == 'y')
 
486
                show_conduct(how >= PANICKED ? 1 : 2);
 
487
            if (c == 'q') done_stopprint++;
 
488
        }
 
489
#ifdef DUMP_LOG
 
490
        if (dump_fp) {
 
491
            dump_conduct(how >= PANICKED ? 1 : 2);
 
492
            dump_weapon_skill();
 
493
        }
 
494
#endif
 
495
}
 
496
 
 
497
/* try to get the player back in a viable state after being killed */
 
498
STATIC_OVL void
 
499
savelife(how)
 
500
int how;
 
501
{
 
502
        u.uswldtim = 0;
 
503
        u.uhp = u.uhpmax;
 
504
        if (u.uhunger < 500) {
 
505
            u.uhunger = 500;
 
506
            newuhs(FALSE);
 
507
        }
 
508
        /* cure impending doom of sickness hero won't have time to fix */
 
509
        if ((Sick & TIMEOUT) == 1) {
 
510
            u.usick_type = 0;
 
511
            Sick = 0;
 
512
        }
 
513
        if (how == CHOKING) init_uhunger();
 
514
        nomovemsg = "You survived that attempt on your life.";
 
515
        flags.move = 0;
 
516
        if(multi > 0) multi = 0; else multi = -1;
 
517
        if(u.utrap && u.utraptype == TT_LAVA) u.utrap = 0;
 
518
        flags.botl = 1;
 
519
        u.ugrave_arise = NON_PM;
 
520
        HUnchanging = 0L;
 
521
        curs_on_u();
 
522
}
 
523
 
 
524
/*
 
525
 * Get valuables from the given list.  Revised code: the list always remains
 
526
 * intact.
 
527
 */
 
528
STATIC_OVL void
 
529
get_valuables(list)
 
530
struct obj *list;       /* inventory or container contents */
 
531
{
 
532
    register struct obj *obj;
 
533
    register int i;
 
534
 
 
535
    /* find amulets and gems, ignoring all artifacts */
 
536
    for (obj = list; obj; obj = obj->nobj)
 
537
        if (Has_contents(obj)) {
 
538
            get_valuables(obj->cobj);
 
539
        } else if (obj->oartifact) {
 
540
            continue;
 
541
        } else if (obj->oclass == AMULET_CLASS) {
 
542
            i = obj->otyp - FIRST_AMULET;
 
543
            if (!amulets[i].count) {
 
544
                amulets[i].count = obj->quan;
 
545
                amulets[i].typ = obj->otyp;
 
546
            } else amulets[i].count += obj->quan; /* always adds one */
 
547
        } else if (obj->oclass == GEM_CLASS && obj->otyp < LUCKSTONE) {
 
548
            i = min(obj->otyp, LAST_GEM + 1) - FIRST_GEM;
 
549
            if (!gems[i].count) {
 
550
                gems[i].count = obj->quan;
 
551
                gems[i].typ = obj->otyp;
 
552
            } else gems[i].count += obj->quan;
 
553
        }
 
554
    return;
 
555
}
 
556
 
 
557
/*
 
558
 *  Sort collected valuables, most frequent to least.  We could just
 
559
 *  as easily use qsort, but we don't care about efficiency here.
 
560
 */
 
561
STATIC_OVL void
 
562
sort_valuables(list, size)
 
563
struct valuable_data list[];
 
564
int size;               /* max value is less than 20 */
 
565
{
 
566
    register int i, j;
 
567
    struct valuable_data ltmp;
 
568
 
 
569
    /* move greater quantities to the front of the list */
 
570
    for (i = 1; i < size; i++) {
 
571
        if (list[i].count == 0) continue;       /* empty slot */
 
572
        ltmp = list[i]; /* structure copy */
 
573
        for (j = i; j > 0; --j)
 
574
            if (list[j-1].count >= ltmp.count) break;
 
575
            else {
 
576
                list[j] = list[j-1];
 
577
            }
 
578
        list[j] = ltmp;
 
579
    }
 
580
    return;
 
581
}
 
582
 
 
583
/* called twice; first to calculate total, then to list relevant items */
 
584
STATIC_OVL void
 
585
artifact_score(list, counting, endwin)
 
586
struct obj *list;
 
587
boolean counting;       /* true => add up points; false => display them */
 
588
winid endwin;
 
589
{
 
590
    char pbuf[BUFSZ];
 
591
    struct obj *otmp;
 
592
    long value, points;
 
593
    short dummy;        /* object type returned by artifact_name() */
 
594
 
 
595
    for (otmp = list; otmp; otmp = otmp->nobj) {
 
596
        if (otmp->oartifact ||
 
597
                        otmp->otyp == BELL_OF_OPENING ||
 
598
                        otmp->otyp == SPE_BOOK_OF_THE_DEAD ||
 
599
                        otmp->otyp == CANDELABRUM_OF_INVOCATION) {
 
600
            value = arti_cost(otmp);    /* zorkmid value */
 
601
            points = value * 5 / 2;     /* score value */
 
602
            if (counting) {
 
603
                u.urexp += points;
 
604
            } else {
 
605
                makeknown(otmp->otyp);
 
606
                otmp->known = otmp->dknown = otmp->bknown = otmp->rknown = 1;
 
607
                /* assumes artifacts don't have quan > 1 */
 
608
                Sprintf(pbuf, "%s%s (worth %ld %s and %ld points)",
 
609
                        the_unique_obj(otmp) ? "The " : "",
 
610
                        otmp->oartifact ? artifact_name(xname(otmp), &dummy) :
 
611
                                OBJ_NAME(objects[otmp->otyp]),
 
612
                        value, currency(value), points);
 
613
                putstr(endwin, 0, pbuf);
 
614
#ifdef DUMP_LOG
 
615
                if (dump_fp)
 
616
                  dump("", pbuf);
 
617
#endif
 
618
            }
 
619
        }
 
620
        if (Has_contents(otmp))
 
621
            artifact_score(otmp->cobj, counting, endwin);
 
622
    }
 
623
}
 
624
 
 
625
/* Be careful not to call panic from here! */
 
626
void
 
627
done(how)
 
628
int how;
 
629
{
 
630
        boolean taken;
 
631
        char kilbuf[BUFSZ], pbuf[BUFSZ];
 
632
        winid endwin = WIN_ERR;
 
633
        boolean bones_ok, have_windows = iflags.window_inited;
 
634
        struct obj *corpse = (struct obj *)0;
 
635
        long umoney;
 
636
 
 
637
        if (how == TRICKED) {
 
638
            if (killer) {
 
639
                paniclog("trickery", killer);
 
640
                killer = 0;
 
641
            }
 
642
#ifdef WIZARD
 
643
            if (wizard) {
 
644
                You("are a very tricky wizard, it seems.");
 
645
                return;
 
646
            }
 
647
#endif
 
648
        }
 
649
 
 
650
        /* kilbuf: used to copy killer in case it comes from something like
 
651
         *      xname(), which would otherwise get overwritten when we call
 
652
         *      xname() when listing possessions
 
653
         * pbuf: holds Sprintf'd output for raw_print and putstr
 
654
         */
 
655
        if (how == ASCENDED || (!killer && how == GENOCIDED))
 
656
                killer_format = NO_KILLER_PREFIX;
 
657
        /* Avoid killed by "a" burning or "a" starvation */
 
658
        if (!killer && (how == STARVING || how == BURNING))
 
659
                killer_format = KILLED_BY;
 
660
        Strcpy(kilbuf, (!killer || how >= PANICKED ? deaths[how] : killer));
 
661
        killer = kilbuf;
 
662
 
 
663
        if (how < PANICKED) u.umortality++;
 
664
        if (Lifesaved && (how <= GENOCIDED)) {
 
665
                pline("But wait...");
 
666
                makeknown(AMULET_OF_LIFE_SAVING);
 
667
                Your("medallion %s!",
 
668
                      !Blind ? "begins to glow" : "feels warm");
 
669
                if (how == CHOKING) You("vomit ...");
 
670
                You_feel("much better!");
 
671
                pline_The("medallion crumbles to dust!");
 
672
                if (uamul) useup(uamul);
 
673
 
 
674
                (void) adjattrib(A_CON, -1, TRUE);
 
675
                if(u.uhpmax <= 0) u.uhpmax = 10;        /* arbitrary */
 
676
                savelife(how);
 
677
                if (how == GENOCIDED)
 
678
                        pline("Unfortunately you are still genocided...");
 
679
                else {
 
680
                        killer = 0;
 
681
                        killer_format = 0;
 
682
                        return;
 
683
                }
 
684
        }
 
685
        if ((
 
686
#ifdef WIZARD
 
687
                        wizard ||
 
688
#endif
 
689
                        discover) && (how <= GENOCIDED)) {
 
690
                if(yn("Die?") == 'y') goto die;
 
691
                pline("OK, so you don't %s.",
 
692
                        (how == CHOKING) ? "choke" : "die");
 
693
                if(u.uhpmax <= 0) u.uhpmax = u.ulevel * 8;      /* arbitrary */
 
694
                savelife(how);
 
695
                killer = 0;
 
696
                killer_format = 0;
 
697
                return;
 
698
        }
 
699
 
 
700
    /*
 
701
     *  The game is now over...
 
702
     */
 
703
 
 
704
die:
 
705
        program_state.gameover = 1;
 
706
        /* in case of a subsequent panic(), there's no point trying to save */
 
707
        program_state.something_worth_saving = 0;
 
708
#ifdef DUMP_LOG
 
709
        /* D: Grab screen dump right here */
 
710
        if (dump_fn[0]) {
 
711
          dump_init();
 
712
          Sprintf(pbuf, "%s, %s %s %s %s", plname,
 
713
                  aligns[1 - u.ualign.type].adj,
 
714
                  genders[flags.female].adj,
 
715
                  urace.adj,
 
716
                  (flags.female && urole.name.f)?
 
717
                   urole.name.f : urole.name.m);
 
718
          dump("", pbuf);
 
719
          /* D: Add a line for clearance from the screen dump */
 
720
          dump("", "");
 
721
          dump_screen();
 
722
        }
 
723
#endif /* DUMP_LOG */
 
724
        /* render vision subsystem inoperative */
 
725
        iflags.vision_inited = 0;
 
726
        /* might have been killed while using a disposable item, so make sure
 
727
           it's gone prior to inventory disclosure and creation of bones data */
 
728
        inven_inuse(TRUE);
 
729
 
 
730
        /* Sometimes you die on the first move.  Life's not fair.
 
731
         * On those rare occasions you get hosed immediately, go out
 
732
         * smiling... :-)  -3.
 
733
         */
 
734
        if (moves <= 1 && how < PANICKED)       /* You die... --More-- */
 
735
            pline("Do not pass go.  Do not collect 200 %s.", currency(200L));
 
736
 
 
737
        if (have_windows) wait_synch(); /* flush screen output */
 
738
#ifndef NO_SIGNAL
 
739
        (void) signal(SIGINT, (SIG_RET_TYPE) done_intr);
 
740
# if defined(UNIX) || defined(VMS) || defined (__EMX__)
 
741
        (void) signal(SIGQUIT, (SIG_RET_TYPE) done_intr);
 
742
        (void) signal(SIGHUP, (SIG_RET_TYPE) done_hangup);
 
743
# endif
 
744
#endif /* NO_SIGNAL */
 
745
 
 
746
        bones_ok = (how < GENOCIDED) && can_make_bones();
 
747
 
 
748
        if (how == TURNED_SLIME)
 
749
            u.ugrave_arise = PM_GREEN_SLIME;
 
750
 
 
751
        if (bones_ok && u.ugrave_arise < LOW_PM) {
 
752
            /* corpse gets burnt up too */
 
753
            if (how == BURNING)
 
754
                u.ugrave_arise = (NON_PM - 2);  /* leave no corpse */
 
755
            else if (how == STONING)
 
756
                u.ugrave_arise = (NON_PM - 1);  /* statue instead of corpse */
 
757
            else if (u.ugrave_arise == NON_PM &&
 
758
                     !(mvitals[u.umonnum].mvflags & G_NOCORPSE)) {
 
759
                int mnum = u.umonnum;
 
760
 
 
761
                if (!Upolyd) {
 
762
                    /* Base corpse on race when not poly'd since original
 
763
                     * u.umonnum is based on role, and all role monsters
 
764
                     * are human.
 
765
                     */
 
766
                    mnum = (flags.female && urace.femalenum != NON_PM) ?
 
767
                        urace.femalenum : urace.malenum;
 
768
                }
 
769
                corpse = mk_named_object(CORPSE, &mons[mnum],
 
770
                                       u.ux, u.uy, plname);
 
771
                Sprintf(pbuf, "%s, %s%s", plname,
 
772
                        killer_format == NO_KILLER_PREFIX ? "" :
 
773
                        killed_by_prefix[how],
 
774
                        killer_format == KILLED_BY_AN ? an(killer) : killer);
 
775
                make_grave(u.ux, u.uy, pbuf);
 
776
            }
 
777
        }
 
778
 
 
779
        if (how == QUIT) {
 
780
                killer_format = NO_KILLER_PREFIX;
 
781
                if (u.uhp < 1) {
 
782
                        how = DIED;
 
783
                        u.umortality++; /* skipped above when how==QUIT */
 
784
                        /* note that killer is pointing at kilbuf */
 
785
                        Strcpy(kilbuf, "quit while already on Charon's boat");
 
786
                }
 
787
        }
 
788
        if (how == ESCAPED || how == PANICKED)
 
789
                killer_format = NO_KILLER_PREFIX;
 
790
 
 
791
        if (how != PANICKED) {
 
792
            /* these affect score and/or bones, but avoid them during panic */
 
793
            taken = paybill((how == ESCAPED) ? -1 : (how != QUIT));
 
794
            paygd();
 
795
            clearpriests();
 
796
        } else  taken = FALSE;  /* lint; assert( !bones_ok ); */
 
797
 
 
798
        clearlocks();
 
799
 
 
800
        if (have_windows) display_nhwindow(WIN_MESSAGE, FALSE);
 
801
 
 
802
        if (strcmp(flags.end_disclose, "none") && how != PANICKED)
 
803
                disclose(how, taken);
 
804
        /* finish_paybill should be called after disclosure but before bones */
 
805
        if (bones_ok && taken) finish_paybill();
 
806
 
 
807
        /* calculate score, before creating bones [container gold] */
 
808
        {
 
809
            long tmp;
 
810
            int deepest = deepest_lev_reached(FALSE);
 
811
 
 
812
#ifndef GOLDOBJ
 
813
            umoney = u.ugold;
 
814
            tmp = u.ugold0;
 
815
#else
 
816
            umoney = money_cnt(invent);
 
817
            tmp = u.umoney0;
 
818
#endif
 
819
            umoney += hidden_gold();    /* accumulate gold from containers */
 
820
            tmp = umoney - tmp;         /* net gain */
 
821
 
 
822
            if (tmp < 0L)
 
823
                tmp = 0L;
 
824
            if (how < PANICKED)
 
825
                tmp -= tmp / 10L;
 
826
            u.urexp += tmp;
 
827
            u.urexp += 50L * (long)(deepest - 1);
 
828
            if (deepest > 20)
 
829
                u.urexp += 1000L * (long)((deepest > 30) ? 10 : deepest - 20);
 
830
            if (how == ASCENDED) u.urexp *= 2L;
 
831
        }
 
832
 
 
833
        if (bones_ok) {
 
834
#ifdef WIZARD
 
835
            if (!wizard || yn("Save bones?") == 'y')
 
836
#endif
 
837
                savebones(corpse);
 
838
            /* corpse may be invalid pointer now so
 
839
                ensure that it isn't used again */
 
840
            corpse = (struct obj *)0;
 
841
        }
 
842
 
 
843
        /* update gold for the rip output, which can't use hidden_gold()
 
844
           (containers will be gone by then if bones just got saved...) */
 
845
#ifndef GOLDOBJ
 
846
        u.ugold = umoney;
 
847
#else
 
848
        done_money = umoney;
 
849
#endif
 
850
 
 
851
        /* clean up unneeded windows */
 
852
        if (have_windows) {
 
853
            wait_synch();
 
854
            display_nhwindow(WIN_MESSAGE, TRUE);
 
855
            destroy_nhwindow(WIN_MAP);
 
856
            destroy_nhwindow(WIN_STATUS);
 
857
            destroy_nhwindow(WIN_MESSAGE);
 
858
            WIN_MESSAGE = WIN_STATUS = WIN_MAP = WIN_ERR;
 
859
 
 
860
            if(!done_stopprint || flags.tombstone)
 
861
                endwin = create_nhwindow(NHW_TEXT);
 
862
 
 
863
            if (how < GENOCIDED && flags.tombstone && endwin != WIN_ERR)
 
864
                outrip(endwin, how);
 
865
        } else
 
866
            done_stopprint = 1; /* just avoid any more output */
 
867
 
 
868
/* changing kilbuf really changes killer. we do it this way because
 
869
   killer is declared a (const char *)
 
870
*/
 
871
        if (u.uhave.amulet) Strcat(kilbuf, " (with the Amulet)");
 
872
        else if (how == ESCAPED) {
 
873
            if (Is_astralevel(&u.uz))   /* offered Amulet to wrong deity */
 
874
                Strcat(kilbuf, " (in celestial disgrace)");
 
875
            else if (carrying(FAKE_AMULET_OF_YENDOR))
 
876
                Strcat(kilbuf, " (with a fake Amulet)");
 
877
                /* don't bother counting to see whether it should be plural */
 
878
        }
 
879
 
 
880
        Sprintf(pbuf, "%s %s the %s...", Goodbye(), plname,
 
881
                how != ASCENDED ?
 
882
                   (const char *) ((flags.female && urole.name.f) ?
 
883
                      urole.name.f : urole.name.m) :
 
884
                   (const char *) (flags.female ? "Demigoddess" : "Demigod"));
 
885
        if (!done_stopprint) {
 
886
            putstr(endwin, 0, pbuf);
 
887
            putstr(endwin, 0, "");
 
888
        }
 
889
#ifdef DUMP_LOG
 
890
        if (dump_fp) dump("", pbuf);
 
891
#endif
 
892
 
 
893
        if (how == ESCAPED || how == ASCENDED) {
 
894
            register struct monst *mtmp;
 
895
            register struct obj *otmp;
 
896
            register struct val_list *val;
 
897
            register int i;
 
898
 
 
899
            for (val = valuables; val->list; val++)
 
900
                for (i = 0; i < val->size; i++) {
 
901
                    val->list[i].count = 0L;
 
902
                }
 
903
            get_valuables(invent);
 
904
 
 
905
            /* add points for collected valuables */
 
906
            for (val = valuables; val->list; val++)
 
907
                for (i = 0; i < val->size; i++)
 
908
                    if (val->list[i].count != 0L)
 
909
                        u.urexp += val->list[i].count
 
910
                                  * (long)objects[val->list[i].typ].oc_cost;
 
911
 
 
912
            /* count the points for artifacts */
 
913
            artifact_score(invent, TRUE, endwin);
 
914
 
 
915
            keepdogs(TRUE);
 
916
            viz_array[0][0] |= IN_SIGHT; /* need visibility for naming */
 
917
            mtmp = mydogs;
 
918
            Strcpy(pbuf, "You");
 
919
            if (mtmp) {
 
920
                while (mtmp) {
 
921
                    Sprintf(eos(pbuf), " and %s", mon_nam(mtmp));
 
922
                    if (mtmp->mtame)
 
923
                        u.urexp += mtmp->mhp;
 
924
                    mtmp = mtmp->nmon;
 
925
                }
 
926
                if (!done_stopprint) putstr(endwin, 0, pbuf);
 
927
#ifdef DUMP_LOG
 
928
                if (dump_fp) dump("", pbuf);
 
929
#endif
 
930
                pbuf[0] = '\0';
 
931
            } else {
 
932
                if (!done_stopprint) Strcat(pbuf, " ");
 
933
            }
 
934
            Sprintf(eos(pbuf), "%s with %ld point%s,",
 
935
                        how==ASCENDED ? "went to your reward" :
 
936
                                        "escaped from the dungeon",
 
937
                        u.urexp, plur(u.urexp));
 
938
#ifdef DUMP_LOG
 
939
            if (dump_fp) dump("", pbuf);
 
940
#endif
 
941
            if (!done_stopprint) {
 
942
                putstr(endwin, 0, pbuf);
 
943
            }
 
944
 
 
945
            if (!done_stopprint)
 
946
                artifact_score(invent, FALSE, endwin);  /* list artifacts */
 
947
 
 
948
            /* list valuables here */
 
949
            for (val = valuables; val->list; val++) {
 
950
                sort_valuables(val->list, val->size);
 
951
                for (i = 0; i < val->size && !done_stopprint; i++) {
 
952
                    int typ = val->list[i].typ;
 
953
                    long count = val->list[i].count;
 
954
 
 
955
                    if (count == 0L) continue;
 
956
                    if (objects[typ].oc_class != GEM_CLASS || typ <= LAST_GEM) {
 
957
                        otmp = mksobj(typ, FALSE, FALSE);
 
958
                        makeknown(otmp->otyp);
 
959
                        otmp->known = 1;        /* for fake amulets */
 
960
                        otmp->dknown = 1;       /* seen it (blindness fix) */
 
961
                        otmp->onamelth = 0;
 
962
                        otmp->quan = count;
 
963
                        Sprintf(pbuf, "%8ld %s (worth %ld %s),",
 
964
                                count, xname(otmp),
 
965
                                count * (long)objects[typ].oc_cost, currency(2L));
 
966
                        obfree(otmp, (struct obj *)0);
 
967
                    } else {
 
968
                        Sprintf(pbuf,
 
969
                                "%8ld worthless piece%s of colored glass,",
 
970
                                count, plur(count));
 
971
                    }
 
972
                    putstr(endwin, 0, pbuf);
 
973
#ifdef DUMP_LOG
 
974
                    if (dump_fp) dump("", pbuf);
 
975
#endif
 
976
                }
 
977
            }
 
978
 
 
979
        } else if (!done_stopprint) {
 
980
            /* did not escape or ascend */
 
981
            if (u.uz.dnum == 0 && u.uz.dlevel <= 0) {
 
982
                /* level teleported out of the dungeon; `how' is DIED,
 
983
                   due to falling or to "arriving at heaven prematurely" */
 
984
                Sprintf(pbuf, "You %s beyond the confines of the dungeon",
 
985
                        (u.uz.dlevel < 0) ? "passed away" : ends[how]);
 
986
            } else {
 
987
                /* more conventional demise */
 
988
                const char *where = dungeons[u.uz.dnum].dname;
 
989
 
 
990
                if (Is_astralevel(&u.uz)) where = "The Astral Plane";
 
991
                Sprintf(pbuf, "You %s in %s", ends[how], where);
 
992
                if (!In_endgame(&u.uz) && !Is_knox(&u.uz))
 
993
                    Sprintf(eos(pbuf), " on dungeon level %d",
 
994
                            In_quest(&u.uz) ? dunlev(&u.uz) : depth(&u.uz));
 
995
            }
 
996
 
 
997
            Sprintf(eos(pbuf), " with %ld point%s,",
 
998
                    u.urexp, plur(u.urexp));
 
999
            putstr(endwin, 0, pbuf);
 
1000
#ifdef DUMP_LOG
 
1001
            if (dump_fp) dump("", pbuf);
 
1002
#endif
 
1003
        }
 
1004
 
 
1005
        if (!done_stopprint) {
 
1006
            Sprintf(pbuf, "and %ld piece%s of gold, after %ld move%s.",
 
1007
                    umoney, plur(umoney), moves, plur(moves));
 
1008
            putstr(endwin, 0, pbuf);
 
1009
#ifdef DUMP_LOG
 
1010
            if (dump_fp) {
 
1011
              dump("", pbuf);
 
1012
              Sprintf(pbuf, "Killer: %s", killer);
 
1013
              dump("", pbuf);
 
1014
            }
 
1015
#endif
 
1016
        }
 
1017
        if (!done_stopprint) {
 
1018
            Sprintf(pbuf,
 
1019
             "You were level %d with a maximum of %d hit point%s when you %s.",
 
1020
                    u.ulevel, u.uhpmax, plur(u.uhpmax), ends[how]);
 
1021
            putstr(endwin, 0, pbuf);
 
1022
            putstr(endwin, 0, "");
 
1023
#ifdef DUMP_LOG
 
1024
            if (dump_fp) dump("", pbuf);
 
1025
#endif
 
1026
        }
 
1027
        if (!done_stopprint)
 
1028
            display_nhwindow(endwin, TRUE);
 
1029
        if (endwin != WIN_ERR)
 
1030
            destroy_nhwindow(endwin);
 
1031
 
 
1032
        /* "So when I die, the first thing I will see in Heaven is a
 
1033
         * score list?" */
 
1034
        if (flags.toptenwin) {
 
1035
            topten(how);
 
1036
            if (have_windows)
 
1037
                exit_nhwindows((char *)0);
 
1038
        } else {
 
1039
            if (have_windows)
 
1040
                exit_nhwindows((char *)0);
 
1041
            topten(how);
 
1042
        }
 
1043
#ifdef DUMP_LOG
 
1044
        if (dump_fp) dump_exit();
 
1045
#endif
 
1046
 
 
1047
        if(done_stopprint) { raw_print(""); raw_print(""); }
 
1048
        terminate(EXIT_SUCCESS);
 
1049
}
 
1050
 
 
1051
 
 
1052
void
 
1053
container_contents(list, identified, all_containers)
 
1054
struct obj *list;
 
1055
boolean identified, all_containers;
 
1056
#ifdef DUMP_LOG
 
1057
{
 
1058
        do_containerconts(list, identified, all_containers, FALSE);
 
1059
}
 
1060
 
 
1061
void do_containerconts(list, identified, all_containers, want_dump)
 
1062
struct obj *list;
 
1063
boolean identified, all_containers, want_dump;
 
1064
#endif
 
1065
/* The original container_contents function */
 
1066
{
 
1067
        register struct obj *box, *obj;
 
1068
        char buf[BUFSZ];
 
1069
 
 
1070
        for (box = list; box; box = box->nobj) {
 
1071
            if (Is_container(box) || box->otyp == STATUE) {
 
1072
                if (box->otyp == BAG_OF_TRICKS) {
 
1073
                    continue;   /* wrong type of container */
 
1074
                } else if (box->cobj) {
 
1075
                    winid tmpwin = create_nhwindow(NHW_MENU);
 
1076
                    Sprintf(buf, "Contents of %s:", the(xname(box)));
 
1077
                    putstr(tmpwin, 0, buf);
 
1078
                    putstr(tmpwin, 0, "");
 
1079
#ifdef DUMP_LOG
 
1080
                    if (dump_fp) dump("", buf);
 
1081
#endif
 
1082
                    for (obj = box->cobj; obj; obj = obj->nobj) {
 
1083
                        if (identified) {
 
1084
                            makeknown(obj->otyp);
 
1085
                            obj->known = obj->bknown =
 
1086
                            obj->dknown = obj->rknown = 1;
 
1087
                        }
 
1088
                        putstr(tmpwin, 0, doname(obj));
 
1089
#ifdef DUMP_LOG
 
1090
                        if (want_dump)  dump("  ", doname(obj));
 
1091
#endif
 
1092
                    }
 
1093
#ifdef DUMP_LOG
 
1094
                    if (want_dump)  dump("","");
 
1095
#endif
 
1096
                    display_nhwindow(tmpwin, TRUE);
 
1097
                    destroy_nhwindow(tmpwin);
 
1098
                    if (all_containers) {
 
1099
#ifdef DUMP_LOG
 
1100
                        do_containerconts(box->cobj, identified, TRUE,
 
1101
                                          want_dump);
 
1102
#else
 
1103
                        container_contents(box->cobj, identified, TRUE);
 
1104
#endif /* DUMP_LOG */
 
1105
                    }
 
1106
                } else {
 
1107
                    pline("%s empty.", Tobjnam(box, "are"));
 
1108
                    display_nhwindow(WIN_MESSAGE, FALSE);
 
1109
#ifdef DUMP_LOG
 
1110
                    if (want_dump) {
 
1111
                      dump(The(xname(box)), " is empty.");
 
1112
                      dump("", "");
 
1113
                    }
 
1114
#endif
 
1115
                }
 
1116
            }
 
1117
            if (!all_containers)
 
1118
                break;
 
1119
        }
 
1120
}
 
1121
 
 
1122
 
 
1123
/* should be called with either EXIT_SUCCESS or EXIT_FAILURE */
 
1124
void
 
1125
terminate(status)
 
1126
int status;
 
1127
{
 
1128
#ifdef MAC
 
1129
        getreturn("to exit");
 
1130
#endif
 
1131
        /* don't bother to try to release memory if we're in panic mode, to
 
1132
           avoid trouble in case that happens to be due to memory problems */
 
1133
        if (!program_state.panicking) {
 
1134
            freedynamicdata();
 
1135
            dlb_cleanup();
 
1136
        }
 
1137
 
 
1138
        nethack_exit(status);
 
1139
}
 
1140
 
 
1141
STATIC_OVL void
 
1142
list_vanquished(defquery, ask)
 
1143
char defquery;
 
1144
boolean ask;
 
1145
#ifdef DUMP_LOG
 
1146
{
 
1147
  do_vanquished(defquery, ask, FALSE);
 
1148
}
 
1149
 
 
1150
void
 
1151
do_vanquished(defquery, ask, want_dump)
 
1152
int defquery;
 
1153
boolean ask;
 
1154
boolean want_dump;
 
1155
#endif
 
1156
{
 
1157
    register int i, lev;
 
1158
    int ntypes = 0, max_lev = 0, nkilled;
 
1159
    long total_killed = 0L;
 
1160
    char c;
 
1161
    winid klwin;
 
1162
    char buf[BUFSZ];
 
1163
 
 
1164
    /* get totals first */
 
1165
    for (i = LOW_PM; i < NUMMONS; i++) {
 
1166
        if (mvitals[i].died) ntypes++;
 
1167
        total_killed += (long)mvitals[i].died;
 
1168
        if (mons[i].mlevel > max_lev) max_lev = mons[i].mlevel;
 
1169
    }
 
1170
 
 
1171
    /* vanquished creatures list;
 
1172
     * includes all dead monsters, not just those killed by the player
 
1173
     */
 
1174
    if (ntypes != 0) {
 
1175
        c = ask ? yn_function("Do you want an account of creatures vanquished?",
 
1176
                              ynqchars, defquery) : defquery;
 
1177
        if (c == 'q') done_stopprint++;
 
1178
        if (c == 'y') {
 
1179
            klwin = create_nhwindow(NHW_MENU);
 
1180
            putstr(klwin, 0, "Vanquished creatures:");
 
1181
            putstr(klwin, 0, "");
 
1182
#ifdef DUMP_LOG
 
1183
            if (want_dump)  dump("", "Vanquished creatures");
 
1184
#endif
 
1185
 
 
1186
            /* countdown by monster "toughness" */
 
1187
            for (lev = max_lev; lev >= 0; lev--)
 
1188
              for (i = LOW_PM; i < NUMMONS; i++)
 
1189
                if (mons[i].mlevel == lev && (nkilled = mvitals[i].died) > 0) {
 
1190
                    if ((mons[i].geno & G_UNIQ) && i != PM_HIGH_PRIEST) {
 
1191
                        Sprintf(buf, "%s%s",
 
1192
                                !type_is_pname(&mons[i]) ? "The " : "",
 
1193
                                mons[i].mname);
 
1194
                        if (nkilled > 1) {
 
1195
                            switch (nkilled) {
 
1196
                                case 2:  Sprintf(eos(buf)," (twice)");  break;
 
1197
                                case 3:  Sprintf(eos(buf)," (thrice)");  break;
 
1198
                                default: Sprintf(eos(buf)," (%d time%s)",
 
1199
                                                 nkilled, plur(nkilled));
 
1200
                                         break;
 
1201
                            }
 
1202
                        }
 
1203
                    } else {
 
1204
                        /* trolls or undead might have come back,
 
1205
                           but we don't keep track of that */
 
1206
                        if (nkilled == 1)
 
1207
                            Strcpy(buf, an(mons[i].mname));
 
1208
                        else
 
1209
                            Sprintf(buf, "%d %s",
 
1210
                                    nkilled, makeplural(mons[i].mname));
 
1211
                    }
 
1212
                    putstr(klwin, 0, buf);
 
1213
#ifdef DUMP_LOG
 
1214
                    if (want_dump)  dump("  ", buf);
 
1215
#endif
 
1216
                }
 
1217
            /*
 
1218
             * if (Hallucination)
 
1219
             *     putstr(klwin, 0, "and a partridge in a pear tree");
 
1220
             */
 
1221
            if (ntypes > 1) {
 
1222
                putstr(klwin, 0, "");
 
1223
                Sprintf(buf, "%ld creatures vanquished.", total_killed);
 
1224
                putstr(klwin, 0, buf);
 
1225
#ifdef DUMP_LOG
 
1226
                if (want_dump)  dump("  ", buf);
 
1227
#endif
 
1228
            }
 
1229
            display_nhwindow(klwin, TRUE);
 
1230
            destroy_nhwindow(klwin);
 
1231
#ifdef DUMP_LOG
 
1232
            if (want_dump)  dump("", "");
 
1233
#endif
 
1234
        }
 
1235
    }
 
1236
}
 
1237
 
 
1238
/* number of monster species which have been genocided */
 
1239
int
 
1240
num_genocides()
 
1241
{
 
1242
    int i, n = 0;
 
1243
 
 
1244
    for (i = LOW_PM; i < NUMMONS; ++i)
 
1245
        if (mvitals[i].mvflags & G_GENOD) ++n;
 
1246
 
 
1247
    return n;
 
1248
}
 
1249
 
 
1250
#ifdef DUMP_LOG
 
1251
STATIC_OVL void
 
1252
list_genocided(defquery, ask, want_dump)
 
1253
int defquery;
 
1254
boolean ask;
 
1255
boolean want_dump;
 
1256
#else
 
1257
STATIC_OVL void
 
1258
list_genocided(defquery, ask)
 
1259
char defquery;
 
1260
boolean ask;
 
1261
#endif
 
1262
{
 
1263
    register int i;
 
1264
    int ngenocided;
 
1265
    char c;
 
1266
    winid klwin;
 
1267
    char buf[BUFSZ];
 
1268
 
 
1269
    ngenocided = num_genocides();
 
1270
 
 
1271
    /* genocided species list */
 
1272
    if (ngenocided != 0) {
 
1273
        c = ask ? yn_function("Do you want a list of species genocided?",
 
1274
                              ynqchars, defquery) : defquery;
 
1275
        if (c == 'q') done_stopprint++;
 
1276
        if (c == 'y') {
 
1277
            klwin = create_nhwindow(NHW_MENU);
 
1278
            Sprintf(buf, "Genocided species:");
 
1279
            putstr(klwin, 0, buf);
 
1280
            putstr(klwin, 0, "");
 
1281
#ifdef DUMP_LOG
 
1282
            if (want_dump)  dump("", buf);
 
1283
#endif
 
1284
 
 
1285
            for (i = LOW_PM; i < NUMMONS; i++)
 
1286
                if (mvitals[i].mvflags & G_GENOD) {
 
1287
                    if ((mons[i].geno & G_UNIQ) && i != PM_HIGH_PRIEST)
 
1288
                        Sprintf(buf, "%s%s",
 
1289
                                !type_is_pname(&mons[i]) ? "" : "the ",
 
1290
                                mons[i].mname);
 
1291
                    else
 
1292
                        Strcpy(buf, makeplural(mons[i].mname));
 
1293
                    putstr(klwin, 0, buf);
 
1294
#ifdef DUMP_LOG
 
1295
                    if (want_dump)  dump("  ", buf);
 
1296
#endif
 
1297
                }
 
1298
 
 
1299
            putstr(klwin, 0, "");
 
1300
            Sprintf(buf, "%d species genocided.", ngenocided);
 
1301
            putstr(klwin, 0, buf);
 
1302
#ifdef DUMP_LOG
 
1303
            if (want_dump)  dump("  ", buf);
 
1304
#endif
 
1305
 
 
1306
            display_nhwindow(klwin, TRUE);
 
1307
            destroy_nhwindow(klwin);
 
1308
        }
 
1309
    }
 
1310
}
 
1311
 
 
1312
/*end.c*/