populate insight.c
Move enlightenment and conduct from cmd.c to insight.c. Also move
vanquished monsters plus genocided and/or extinct monsters from end.c
to there. And move the one-line stethoscope/probing feedback for
self and for monsters from priest.c to there.
Achievement feedback has been overhauled a bit. When no achievements
have been recorded, the header for them (after conducts) won't be
shown, and when at least one has been recorded, make the prompt for
asking whether to disclose conduct be about disclosing conduct and
achievements. Also, describe achievements in the Guidebook.
I ran out of gas before updating Guidebook.tex; it will catch up to
Guidebook.mn eventually.
Some of the MS-DOS Makefiles haven't been updated yet so linking
without insight.{o,obj} will break there.
This commit is contained in:
@@ -1084,6 +1084,9 @@ Close a door.
|
||||
Default key is \(oqc\(cq.
|
||||
.lp "#conduct "
|
||||
List voluntary challenges you have maintained.
|
||||
.\" [only in wizard mode:]
|
||||
.\" Also lists various achievements representing progress toward ultimate
|
||||
.\" ascension if any have been attained.
|
||||
Autocompletes.
|
||||
Default key is \(oqM-C\(cq.
|
||||
.lp ""
|
||||
@@ -2726,6 +2729,71 @@ wish for any items is a challenge, as is a game without wishing for
|
||||
an artifact (even if the artifact immediately disappears).
|
||||
When the game offers you an opportunity to make a wish for an item,
|
||||
you may choose \(lqnothing\(rq if you want to decline.
|
||||
.hn 2
|
||||
Achievements
|
||||
.pg
|
||||
End of game disclosure will also display various achievements
|
||||
representing progress toward ultimate ascension, if any have been
|
||||
attained.
|
||||
They aren't directly related to \fIconduct\fP but are grouped with
|
||||
it because they fall into the same category of \(lqbragging rights\(rq
|
||||
and to limit the number of questions during disclosure.
|
||||
.pg
|
||||
The first two are also conducts, the rest are listed roughly in order
|
||||
of difficulty and not necessarily in the order in which you might
|
||||
accomplish them.
|
||||
.lp "Blind "
|
||||
Blind from birth.
|
||||
.lp "Nudist "
|
||||
Never wore any armor.
|
||||
.lp "Mines' End"
|
||||
Explored to the bottom of the Gnomish Mines and found a special item there.
|
||||
.lp "Sokoban "
|
||||
Explored to the top of Sokoban and found a special item there.
|
||||
.lp "Medusa "
|
||||
Defeated Medusa.
|
||||
.lp "Bell "
|
||||
Acquired the Bell of Opening.
|
||||
.lp "Gehennom"
|
||||
Entered Gehennom proper (beyond the Valley).
|
||||
.lp "Candle "
|
||||
Acquired the Candelabrum of Invocation.
|
||||
.lp "Book "
|
||||
Acquired the Book of the Dead.
|
||||
.lp Invocation
|
||||
Gained access to the bottommost level of Gehennom.
|
||||
.lp "Amulet "
|
||||
Acquired the fabled Amulet of Yendor.
|
||||
.lp "Endgame "
|
||||
Reached the Elemental Planes.
|
||||
.lp "Astral "
|
||||
Reached the Astral Plane level.
|
||||
.lp "Ascended"
|
||||
Delivered the Amulet to its final destination.
|
||||
.lp ""
|
||||
.lp "Notes: "
|
||||
.pg
|
||||
\fIBlind\fP and \fINudist\fP are also conducts, and they can only be
|
||||
enabled by setting the correspondingly named option in NETHACKOPTIONS
|
||||
or run-time configuration file prior to game start.
|
||||
In the case of \fIBlind\fP, the option also enforces the conduct.
|
||||
They aren't really significant accomplishments unless/until you make
|
||||
substantial progress into the dungeon but they are treated as
|
||||
Achievements as long as the conduct is enabled and hasn't been broken.
|
||||
.pg
|
||||
The \(lqspecial items\(rq hidden in \fIMines\~End\fP and \fISokoban\fP
|
||||
are not unique but are considered to be prizes or rewards
|
||||
for exploring those levels since doing so is not necessary to complete
|
||||
the game.
|
||||
Finding other instances of the same objects doesn't record the
|
||||
corresponding achievement.
|
||||
.pg
|
||||
The \fIMedusa\fP achievement is recorded if she dies for any reason,
|
||||
even if you are not directly responsible.
|
||||
.pg
|
||||
The \fIValley of the Dead\fP is part of \fIGehennom\fP but the
|
||||
\fIGehennom\fP achievement doesn't get recorded until you make it past
|
||||
that level.
|
||||
.
|
||||
.hn 1
|
||||
Options
|
||||
@@ -3106,7 +3174,7 @@ The possibilities are:
|
||||
.CC a "disclose your attributes;"
|
||||
.CC v "summarize monsters that have been vanquished;"
|
||||
.CC g "list monster species that have been genocided;"
|
||||
.CC c "display your conduct;"
|
||||
.CC c "display your conduct; also achievements, if any;"
|
||||
.CC o "display dungeon overview."
|
||||
.ei
|
||||
.ed
|
||||
|
||||
@@ -198,7 +198,6 @@ E boolean NDECL(status_hilite_menu);
|
||||
E char NDECL(randomkey);
|
||||
E void FDECL(random_response, (char *, int));
|
||||
E int NDECL(rnd_extcmd_idx);
|
||||
E int NDECL(doconduct);
|
||||
E int NDECL(domonability);
|
||||
E char FDECL(cmd_from_func, (int NDECL((*))));
|
||||
E boolean FDECL(redraw_cmd, (CHAR_P));
|
||||
@@ -231,10 +230,6 @@ E void FDECL(rhack, (char *));
|
||||
E int NDECL(doextlist);
|
||||
E int NDECL(extcmd_via_menu);
|
||||
E int NDECL(enter_explore_mode);
|
||||
E char *FDECL(trap_predicament, (char *, int, BOOLEAN_P));
|
||||
E void FDECL(enlightenment, (int, int));
|
||||
E void FDECL(youhiding, (BOOLEAN_P, int));
|
||||
E void FDECL(show_conduct, (int));
|
||||
E boolean FDECL(bind_key, (UCHAR_P, const char *));
|
||||
E void NDECL(dokeylist);
|
||||
E int FDECL(xytod, (SCHAR_P, SCHAR_P));
|
||||
@@ -724,8 +719,6 @@ E void FDECL(done, (int));
|
||||
E void FDECL(container_contents, (struct obj *, BOOLEAN_P,
|
||||
BOOLEAN_P, BOOLEAN_P));
|
||||
E void FDECL(nh_terminate, (int)) NORETURN;
|
||||
E int NDECL(dovanquished);
|
||||
E int NDECL(num_genocides);
|
||||
E void FDECL(delayed_killer, (int, int, const char *));
|
||||
E struct kinfo *FDECL(find_delayed_killer, (int));
|
||||
E void FDECL(dealloc_killer, (struct kinfo *));
|
||||
@@ -986,6 +979,24 @@ E void FDECL(strbuf_empty, (strbuf_t *));
|
||||
E void FDECL(strbuf_nl_to_crlf, (strbuf_t *));
|
||||
E char *FDECL(nonconst, (const char *, char *));
|
||||
|
||||
/* ### insight.c ### */
|
||||
|
||||
E int NDECL(doattributes);
|
||||
E void FDECL(enlightenment, (int, int));
|
||||
E void FDECL(youhiding, (BOOLEAN_P, int));
|
||||
E char *FDECL(trap_predicament, (char *, int, BOOLEAN_P));
|
||||
E int NDECL(doconduct);
|
||||
E void FDECL(show_conduct, (int));
|
||||
E int NDECL(count_uachieve);
|
||||
E int NDECL(dovanquished);
|
||||
E void FDECL(list_vanquished, (CHAR_P, BOOLEAN_P));
|
||||
E int NDECL(num_genocides);
|
||||
E void FDECL(list_genocided, (CHAR_P, BOOLEAN_P));
|
||||
E const char *FDECL(align_str, (ALIGNTYP_P));
|
||||
E char *FDECL(piousness, (BOOLEAN_P, const char *));
|
||||
E void FDECL(mstatusline, (struct monst *));
|
||||
E void NDECL(ustatusline);
|
||||
|
||||
/* ### invent.c ### */
|
||||
|
||||
E Loot *FDECL(sortloot, (struct obj **, unsigned, BOOLEAN_P,
|
||||
@@ -2095,10 +2106,6 @@ E void NDECL(clearpriests);
|
||||
E void FDECL(restpriest, (struct monst *, BOOLEAN_P));
|
||||
E void FDECL(newepri, (struct monst *));
|
||||
E void FDECL(free_epri, (struct monst *));
|
||||
E const char *FDECL(align_str, (ALIGNTYP_P));
|
||||
E char *FDECL(piousness, (BOOLEAN_P, const char *));
|
||||
E void FDECL(mstatusline, (struct monst *));
|
||||
E void NDECL(ustatusline);
|
||||
|
||||
/* ### quest.c ### */
|
||||
|
||||
|
||||
396
src/end.c
396
src/end.c
@@ -32,17 +32,11 @@ static void NDECL(done_object_cleanup);
|
||||
static void FDECL(artifact_score, (struct obj *, BOOLEAN_P, winid));
|
||||
static void FDECL(really_done, (int)) NORETURN;
|
||||
static void FDECL(savelife, (int));
|
||||
static int FDECL(CFDECLSPEC vanqsort_cmp, (const genericptr,
|
||||
const genericptr));
|
||||
static int NDECL(set_vanq_order);
|
||||
static void FDECL(list_vanquished, (CHAR_P, BOOLEAN_P));
|
||||
static void FDECL(list_genocided, (CHAR_P, BOOLEAN_P));
|
||||
static boolean FDECL(should_query_disclose_option, (int, char *));
|
||||
#ifdef DUMPLOG
|
||||
static void NDECL(dump_plines);
|
||||
#endif
|
||||
static void FDECL(dump_everything, (int, time_t));
|
||||
static int NDECL(num_extinct);
|
||||
|
||||
#if defined(__BEOS__) || defined(MICRO) || defined(OS2) || defined(WIN32)
|
||||
extern void FDECL(nethack_exit, (int));
|
||||
@@ -817,10 +811,16 @@ boolean taken;
|
||||
}
|
||||
|
||||
if (!done_stopprint) {
|
||||
ask = should_query_disclose_option('c', &defquery);
|
||||
c = ask ? yn_function("Do you want to see your conduct?", ynqchars,
|
||||
defquery)
|
||||
: defquery;
|
||||
if (should_query_disclose_option('c', &defquery)) {
|
||||
int acnt = count_uachieve();
|
||||
|
||||
Sprintf(qbuf, "Do you want to see your conduct%s%s?",
|
||||
(acnt > 0) ? " and achievement" : "",
|
||||
(acnt > 1) ? "s" : "");
|
||||
c = yn_function(qbuf, ynqchars, defquery);
|
||||
} else {
|
||||
c = defquery;
|
||||
}
|
||||
if (c == 'y')
|
||||
show_conduct((how >= PANICKED) ? 1 : 2);
|
||||
if (c == 'q')
|
||||
@@ -1711,382 +1711,6 @@ int status;
|
||||
nethack_exit(status);
|
||||
}
|
||||
|
||||
static const char *vanqorders[NUM_VANQ_ORDER_MODES] = {
|
||||
"traditional: by monster level, by internal monster index",
|
||||
"by monster toughness, by internal monster index",
|
||||
"alphabetically, first unique monsters, then others",
|
||||
"alphabetically, unique monsters and others intermixed",
|
||||
"by monster class, high to low level within class",
|
||||
"by monster class, low to high level within class",
|
||||
"by count, high to low, by internal index within tied count",
|
||||
"by count, low to high, by internal index within tied count",
|
||||
};
|
||||
|
||||
static int CFDECLSPEC
|
||||
vanqsort_cmp(vptr1, vptr2)
|
||||
const genericptr vptr1;
|
||||
const genericptr vptr2;
|
||||
{
|
||||
int indx1 = *(short *) vptr1, indx2 = *(short *) vptr2,
|
||||
mlev1, mlev2, mstr1, mstr2, uniq1, uniq2, died1, died2, res;
|
||||
const char *name1, *name2, *punct;
|
||||
schar mcls1, mcls2;
|
||||
|
||||
switch (g.vanq_sortmode) {
|
||||
default:
|
||||
case VANQ_MLVL_MNDX:
|
||||
/* sort by monster level */
|
||||
mlev1 = mons[indx1].mlevel, mlev2 = mons[indx2].mlevel;
|
||||
res = mlev2 - mlev1; /* mlevel high to low */
|
||||
break;
|
||||
case VANQ_MSTR_MNDX:
|
||||
/* sort by monster toughness */
|
||||
mstr1 = mons[indx1].difficulty, mstr2 = mons[indx2].difficulty;
|
||||
res = mstr2 - mstr1; /* monstr high to low */
|
||||
break;
|
||||
case VANQ_ALPHA_SEP:
|
||||
uniq1 = ((mons[indx1].geno & G_UNIQ) && indx1 != PM_HIGH_PRIEST);
|
||||
uniq2 = ((mons[indx2].geno & G_UNIQ) && indx2 != PM_HIGH_PRIEST);
|
||||
if (uniq1 ^ uniq2) { /* one or other uniq, but not both */
|
||||
res = uniq2 - uniq1;
|
||||
break;
|
||||
} /* else both unique or neither unique */
|
||||
/*FALLTHRU*/
|
||||
case VANQ_ALPHA_MIX:
|
||||
name1 = mons[indx1].mname, name2 = mons[indx2].mname;
|
||||
res = strcmpi(name1, name2); /* caseblind alhpa, low to high */
|
||||
break;
|
||||
case VANQ_MCLS_HTOL:
|
||||
case VANQ_MCLS_LTOH:
|
||||
/* mons[].mlet is a small integer, 1..N, of type plain char;
|
||||
if 'char' happens to be unsigned, (mlet1 - mlet2) would yield
|
||||
an inappropriate result when mlet2 is greater than mlet1,
|
||||
so force our copies (mcls1, mcls2) to be signed */
|
||||
mcls1 = (schar) mons[indx1].mlet, mcls2 = (schar) mons[indx2].mlet;
|
||||
/* S_ANT through S_ZRUTY correspond to lowercase monster classes,
|
||||
S_ANGEL through S_ZOMBIE correspond to uppercase, and various
|
||||
punctuation characters are used for classes beyond those */
|
||||
if (mcls1 > S_ZOMBIE && mcls2 > S_ZOMBIE) {
|
||||
/* force a specific order to the punctuation classes that's
|
||||
different from the internal order;
|
||||
internal order is ok if neither or just one is punctuation
|
||||
since letters have lower values so come out before punct */
|
||||
static const char punctclasses[] = {
|
||||
S_LIZARD, S_EEL, S_GOLEM, S_GHOST, S_DEMON, S_HUMAN, '\0'
|
||||
};
|
||||
|
||||
if ((punct = index(punctclasses, mcls1)) != 0)
|
||||
mcls1 = (schar) (S_ZOMBIE + 1 + (int) (punct - punctclasses));
|
||||
if ((punct = index(punctclasses, mcls2)) != 0)
|
||||
mcls2 = (schar) (S_ZOMBIE + 1 + (int) (punct - punctclasses));
|
||||
}
|
||||
res = mcls1 - mcls2; /* class */
|
||||
if (res == 0) {
|
||||
mlev1 = mons[indx1].mlevel, mlev2 = mons[indx2].mlevel;
|
||||
res = mlev1 - mlev2; /* mlevel low to high */
|
||||
if (g.vanq_sortmode == VANQ_MCLS_HTOL)
|
||||
res = -res; /* mlevel high to low */
|
||||
}
|
||||
break;
|
||||
case VANQ_COUNT_H_L:
|
||||
case VANQ_COUNT_L_H:
|
||||
died1 = g.mvitals[indx1].died, died2 = g.mvitals[indx2].died;
|
||||
res = died2 - died1; /* dead count high to low */
|
||||
if (g.vanq_sortmode == VANQ_COUNT_L_H)
|
||||
res = -res; /* dead count low to high */
|
||||
break;
|
||||
}
|
||||
/* tiebreaker: internal mons[] index */
|
||||
if (res == 0)
|
||||
res = indx1 - indx2; /* mndx low to high */
|
||||
return res;
|
||||
}
|
||||
|
||||
/* returns -1 if cancelled via ESC */
|
||||
static int
|
||||
set_vanq_order()
|
||||
{
|
||||
winid tmpwin;
|
||||
menu_item *selected;
|
||||
anything any;
|
||||
int i, n, choice;
|
||||
|
||||
tmpwin = create_nhwindow(NHW_MENU);
|
||||
start_menu(tmpwin);
|
||||
any = cg.zeroany; /* zero out all bits */
|
||||
for (i = 0; i < SIZE(vanqorders); i++) {
|
||||
if (i == VANQ_ALPHA_MIX || i == VANQ_MCLS_HTOL) /* skip these */
|
||||
continue;
|
||||
any.a_int = i + 1;
|
||||
add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, vanqorders[i],
|
||||
(i == g.vanq_sortmode)
|
||||
? MENU_ITEMFLAGS_SELECTED : MENU_ITEMFLAGS_NONE);
|
||||
}
|
||||
end_menu(tmpwin, "Sort order for vanquished monster counts");
|
||||
|
||||
n = select_menu(tmpwin, PICK_ONE, &selected);
|
||||
destroy_nhwindow(tmpwin);
|
||||
if (n > 0) {
|
||||
choice = selected[0].item.a_int - 1;
|
||||
/* skip preselected entry if we have more than one item chosen */
|
||||
if (n > 1 && choice == g.vanq_sortmode)
|
||||
choice = selected[1].item.a_int - 1;
|
||||
free((genericptr_t) selected);
|
||||
g.vanq_sortmode = choice;
|
||||
}
|
||||
return (n < 0) ? -1 : g.vanq_sortmode;
|
||||
}
|
||||
|
||||
/* #vanquished command */
|
||||
int
|
||||
dovanquished()
|
||||
{
|
||||
list_vanquished('a', FALSE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* high priests aren't unique but are flagged as such to simplify something */
|
||||
#define UniqCritterIndx(mndx) ((mons[mndx].geno & G_UNIQ) \
|
||||
&& mndx != PM_HIGH_PRIEST)
|
||||
|
||||
static void
|
||||
list_vanquished(defquery, ask)
|
||||
char defquery;
|
||||
boolean ask;
|
||||
{
|
||||
register int i;
|
||||
int pfx, nkilled;
|
||||
unsigned ntypes, ni;
|
||||
long total_killed = 0L;
|
||||
winid klwin;
|
||||
short mindx[NUMMONS];
|
||||
char c, buf[BUFSZ], buftoo[BUFSZ];
|
||||
boolean dumping; /* for DUMPLOG; doesn't need to be conditional */
|
||||
|
||||
dumping = (defquery == 'd');
|
||||
if (dumping)
|
||||
defquery = 'y';
|
||||
|
||||
/* get totals first */
|
||||
ntypes = 0;
|
||||
for (i = LOW_PM; i < NUMMONS; i++) {
|
||||
if ((nkilled = (int) g.mvitals[i].died) == 0)
|
||||
continue;
|
||||
mindx[ntypes++] = i;
|
||||
total_killed += (long) nkilled;
|
||||
}
|
||||
|
||||
/* vanquished creatures list;
|
||||
* includes all dead monsters, not just those killed by the player
|
||||
*/
|
||||
if (ntypes != 0) {
|
||||
char mlet, prev_mlet = 0; /* used as small integer, not character */
|
||||
boolean class_header, uniq_header, was_uniq = FALSE;
|
||||
|
||||
c = ask ? yn_function(
|
||||
"Do you want an account of creatures vanquished?",
|
||||
ynaqchars, defquery)
|
||||
: defquery;
|
||||
if (c == 'q')
|
||||
done_stopprint++;
|
||||
if (c == 'y' || c == 'a') {
|
||||
if (c == 'a') { /* ask player to choose sort order */
|
||||
/* choose value for vanq_sortmode via menu; ESC cancels list
|
||||
of vanquished monsters but does not set 'done_stopprint' */
|
||||
if (set_vanq_order() < 0)
|
||||
return;
|
||||
}
|
||||
uniq_header = (g.vanq_sortmode == VANQ_ALPHA_SEP);
|
||||
class_header = (g.vanq_sortmode == VANQ_MCLS_LTOH
|
||||
|| g.vanq_sortmode == VANQ_MCLS_HTOL);
|
||||
|
||||
klwin = create_nhwindow(NHW_MENU);
|
||||
putstr(klwin, 0, "Vanquished creatures:");
|
||||
if (!dumping)
|
||||
putstr(klwin, 0, "");
|
||||
|
||||
qsort((genericptr_t) mindx, ntypes, sizeof *mindx, vanqsort_cmp);
|
||||
for (ni = 0; ni < ntypes; ni++) {
|
||||
i = mindx[ni];
|
||||
nkilled = g.mvitals[i].died;
|
||||
mlet = mons[i].mlet;
|
||||
if (class_header && mlet != prev_mlet) {
|
||||
Strcpy(buf, def_monsyms[(int) mlet].explain);
|
||||
putstr(klwin, ask ? 0 : iflags.menu_headings,
|
||||
upstart(buf));
|
||||
prev_mlet = mlet;
|
||||
}
|
||||
if (UniqCritterIndx(i)) {
|
||||
Sprintf(buf, "%s%s",
|
||||
!type_is_pname(&mons[i]) ? "the " : "",
|
||||
mons[i].mname);
|
||||
if (nkilled > 1) {
|
||||
switch (nkilled) {
|
||||
case 2:
|
||||
Sprintf(eos(buf), " (twice)");
|
||||
break;
|
||||
case 3:
|
||||
Sprintf(eos(buf), " (thrice)");
|
||||
break;
|
||||
default:
|
||||
Sprintf(eos(buf), " (%d times)", nkilled);
|
||||
break;
|
||||
}
|
||||
}
|
||||
was_uniq = TRUE;
|
||||
} else {
|
||||
if (uniq_header && was_uniq) {
|
||||
putstr(klwin, 0, "");
|
||||
was_uniq = FALSE;
|
||||
}
|
||||
/* trolls or undead might have come back,
|
||||
but we don't keep track of that */
|
||||
if (nkilled == 1)
|
||||
Strcpy(buf, an(mons[i].mname));
|
||||
else
|
||||
Sprintf(buf, "%3d %s", nkilled,
|
||||
makeplural(mons[i].mname));
|
||||
}
|
||||
/* number of leading spaces to match 3 digit prefix */
|
||||
pfx = !strncmpi(buf, "the ", 3) ? 0
|
||||
: !strncmpi(buf, "an ", 3) ? 1
|
||||
: !strncmpi(buf, "a ", 2) ? 2
|
||||
: !digit(buf[2]) ? 4 : 0;
|
||||
if (class_header)
|
||||
++pfx;
|
||||
Sprintf(buftoo, "%*s%s", pfx, "", buf);
|
||||
putstr(klwin, 0, buftoo);
|
||||
}
|
||||
/*
|
||||
* if (Hallucination)
|
||||
* putstr(klwin, 0, "and a partridge in a pear tree");
|
||||
*/
|
||||
if (ntypes > 1) {
|
||||
if (!dumping)
|
||||
putstr(klwin, 0, "");
|
||||
Sprintf(buf, "%ld creatures vanquished.", total_killed);
|
||||
putstr(klwin, 0, buf);
|
||||
}
|
||||
display_nhwindow(klwin, TRUE);
|
||||
destroy_nhwindow(klwin);
|
||||
}
|
||||
} else if (defquery == 'a') {
|
||||
/* #dovanquished rather than final disclosure, so pline() is ok */
|
||||
pline("No creatures have been vanquished.");
|
||||
#ifdef DUMPLOG
|
||||
} else if (dumping) {
|
||||
putstr(0, 0, "No creatures were vanquished."); /* not pline() */
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/* number of monster species which have been genocided */
|
||||
int
|
||||
num_genocides()
|
||||
{
|
||||
int i, n = 0;
|
||||
|
||||
for (i = LOW_PM; i < NUMMONS; ++i) {
|
||||
if (g.mvitals[i].mvflags & G_GENOD) {
|
||||
++n;
|
||||
if (UniqCritterIndx(i))
|
||||
impossible("unique creature '%d: %s' genocided?",
|
||||
i, mons[i].mname);
|
||||
}
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
static int
|
||||
num_extinct()
|
||||
{
|
||||
int i, n = 0;
|
||||
|
||||
for (i = LOW_PM; i < NUMMONS; ++i) {
|
||||
if (UniqCritterIndx(i))
|
||||
continue;
|
||||
if ((g.mvitals[i].mvflags & G_GONE) == G_EXTINCT)
|
||||
++n;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
static void
|
||||
list_genocided(defquery, ask)
|
||||
char defquery;
|
||||
boolean ask;
|
||||
{
|
||||
register int i;
|
||||
int ngenocided, nextinct;
|
||||
char c;
|
||||
winid klwin;
|
||||
char buf[BUFSZ];
|
||||
boolean dumping; /* for DUMPLOG; doesn't need to be conditional */
|
||||
|
||||
dumping = (defquery == 'd');
|
||||
if (dumping)
|
||||
defquery = 'y';
|
||||
|
||||
ngenocided = num_genocides();
|
||||
nextinct = num_extinct();
|
||||
|
||||
/* genocided or extinct species list */
|
||||
if (ngenocided != 0 || nextinct != 0) {
|
||||
Sprintf(buf, "Do you want a list of %sspecies%s%s?",
|
||||
(nextinct && !ngenocided) ? "extinct " : "",
|
||||
(ngenocided) ? " genocided" : "",
|
||||
(nextinct && ngenocided) ? " and extinct" : "");
|
||||
c = ask ? yn_function(buf, ynqchars, defquery) : defquery;
|
||||
if (c == 'q')
|
||||
done_stopprint++;
|
||||
if (c == 'y') {
|
||||
klwin = create_nhwindow(NHW_MENU);
|
||||
Sprintf(buf, "%s%s species:",
|
||||
(ngenocided) ? "Genocided" : "Extinct",
|
||||
(nextinct && ngenocided) ? " or extinct" : "");
|
||||
putstr(klwin, 0, buf);
|
||||
if (!dumping)
|
||||
putstr(klwin, 0, "");
|
||||
|
||||
for (i = LOW_PM; i < NUMMONS; i++) {
|
||||
/* uniques can't be genocided but can become extinct;
|
||||
however, they're never reported as extinct, so skip them */
|
||||
if (UniqCritterIndx(i))
|
||||
continue;
|
||||
if (g.mvitals[i].mvflags & G_GONE) {
|
||||
Sprintf(buf, " %s", makeplural(mons[i].mname));
|
||||
/*
|
||||
* "Extinct" is unfortunate terminology. A species
|
||||
* is marked extinct when its birth limit is reached,
|
||||
* but there might be members of the species still
|
||||
* alive, contradicting the meaning of the word.
|
||||
*/
|
||||
if ((g.mvitals[i].mvflags & G_GONE) == G_EXTINCT)
|
||||
Strcat(buf, " (extinct)");
|
||||
putstr(klwin, 0, buf);
|
||||
}
|
||||
}
|
||||
if (!dumping)
|
||||
putstr(klwin, 0, "");
|
||||
if (ngenocided > 0) {
|
||||
Sprintf(buf, "%d species genocided.", ngenocided);
|
||||
putstr(klwin, 0, buf);
|
||||
}
|
||||
if (nextinct > 0) {
|
||||
Sprintf(buf, "%d species extinct.", nextinct);
|
||||
putstr(klwin, 0, buf);
|
||||
}
|
||||
|
||||
display_nhwindow(klwin, TRUE);
|
||||
destroy_nhwindow(klwin);
|
||||
}
|
||||
#ifdef DUMPLOG
|
||||
} else if (dumping) {
|
||||
putstr(0, 0, "No species were genocided or became extinct.");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/* set a delayed killer, ensure non-delayed killer is cleared out */
|
||||
void
|
||||
delayed_killer(id, format, killername)
|
||||
|
||||
2439
src/insight.c
2439
src/insight.c
File diff suppressed because it is too large
Load Diff
238
src/priest.c
238
src/priest.c
@@ -861,242 +861,4 @@ boolean ghostly;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* align_str(), piousness(), mstatusline() and ustatusline() used to be
|
||||
* in pline.c, presumeably because the latter two generate one line of
|
||||
* output. The USE_OLDARGS config gets warnings from 2016ish-vintage
|
||||
* gcc (for -Wint-to-pointer-cast, activated by -Wall or -W) when they
|
||||
* follow pline() itself. Fixing up the variadic calls like is done for
|
||||
* lev_comp would be needlessly messy there.
|
||||
*
|
||||
* They don't belong here. If/when enlightenment ever gets split off
|
||||
* from cmd.c (which definitely doesn't belong there), they should go
|
||||
* with it.
|
||||
*/
|
||||
|
||||
const char *
|
||||
align_str(alignment)
|
||||
aligntyp alignment;
|
||||
{
|
||||
switch ((int) alignment) {
|
||||
case A_CHAOTIC:
|
||||
return "chaotic";
|
||||
case A_NEUTRAL:
|
||||
return "neutral";
|
||||
case A_LAWFUL:
|
||||
return "lawful";
|
||||
case A_NONE:
|
||||
return "unaligned";
|
||||
}
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
/* used for self-probing */
|
||||
char *
|
||||
piousness(showneg, suffix)
|
||||
boolean showneg;
|
||||
const char *suffix;
|
||||
{
|
||||
static char buf[32]; /* bigger than "insufficiently neutral" */
|
||||
const char *pio;
|
||||
|
||||
/* note: piousness 20 matches MIN_QUEST_ALIGN (quest.h) */
|
||||
if (u.ualign.record >= 20)
|
||||
pio = "piously";
|
||||
else if (u.ualign.record > 13)
|
||||
pio = "devoutly";
|
||||
else if (u.ualign.record > 8)
|
||||
pio = "fervently";
|
||||
else if (u.ualign.record > 3)
|
||||
pio = "stridently";
|
||||
else if (u.ualign.record == 3)
|
||||
pio = "";
|
||||
else if (u.ualign.record > 0)
|
||||
pio = "haltingly";
|
||||
else if (u.ualign.record == 0)
|
||||
pio = "nominally";
|
||||
else if (!showneg)
|
||||
pio = "insufficiently";
|
||||
else if (u.ualign.record >= -3)
|
||||
pio = "strayed";
|
||||
else if (u.ualign.record >= -8)
|
||||
pio = "sinned";
|
||||
else
|
||||
pio = "transgressed";
|
||||
|
||||
Sprintf(buf, "%s", pio);
|
||||
if (suffix && (!showneg || u.ualign.record >= 0)) {
|
||||
if (u.ualign.record != 3)
|
||||
Strcat(buf, " ");
|
||||
Strcat(buf, suffix);
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
/* stethoscope or probing applied to monster -- one-line feedback */
|
||||
void
|
||||
mstatusline(mtmp)
|
||||
struct monst *mtmp;
|
||||
{
|
||||
aligntyp alignment = mon_aligntyp(mtmp);
|
||||
char info[BUFSZ], monnambuf[BUFSZ];
|
||||
|
||||
info[0] = 0;
|
||||
if (mtmp->mtame) {
|
||||
Strcat(info, ", tame");
|
||||
if (wizard) {
|
||||
Sprintf(eos(info), " (%d", mtmp->mtame);
|
||||
if (!mtmp->isminion)
|
||||
Sprintf(eos(info), "; hungry %ld; apport %d",
|
||||
EDOG(mtmp)->hungrytime, EDOG(mtmp)->apport);
|
||||
Strcat(info, ")");
|
||||
}
|
||||
} else if (mtmp->mpeaceful)
|
||||
Strcat(info, ", peaceful");
|
||||
|
||||
if (mtmp->data == &mons[PM_LONG_WORM]) {
|
||||
int segndx, nsegs = count_wsegs(mtmp);
|
||||
|
||||
/* the worm code internals don't consider the head of be one of
|
||||
the worm's segments, but we count it as such when presenting
|
||||
worm feedback to the player */
|
||||
if (!nsegs) {
|
||||
Strcat(info, ", single segment");
|
||||
} else {
|
||||
++nsegs; /* include head in the segment count */
|
||||
segndx = wseg_at(mtmp, g.bhitpos.x, g.bhitpos.y);
|
||||
Sprintf(eos(info), ", %d%s of %d segments",
|
||||
segndx, ordin(segndx), nsegs);
|
||||
}
|
||||
}
|
||||
if (mtmp->cham >= LOW_PM && mtmp->data != &mons[mtmp->cham])
|
||||
/* don't reveal the innate form (chameleon, vampire, &c),
|
||||
just expose the fact that this current form isn't it */
|
||||
Strcat(info, ", shapechanger");
|
||||
/* pets eating mimic corpses mimic while eating, so this comes first */
|
||||
if (mtmp->meating)
|
||||
Strcat(info, ", eating");
|
||||
/* a stethoscope exposes mimic before getting here so this
|
||||
won't be relevant for it, but wand of probing doesn't */
|
||||
if (mtmp->mundetected || mtmp->m_ap_type)
|
||||
mhidden_description(mtmp, TRUE, eos(info));
|
||||
if (mtmp->mcan)
|
||||
Strcat(info, ", cancelled");
|
||||
if (mtmp->mconf)
|
||||
Strcat(info, ", confused");
|
||||
if (mtmp->mblinded || !mtmp->mcansee)
|
||||
Strcat(info, ", blind");
|
||||
if (mtmp->mstun)
|
||||
Strcat(info, ", stunned");
|
||||
if (mtmp->msleeping)
|
||||
Strcat(info, ", asleep");
|
||||
#if 0 /* unfortunately mfrozen covers temporary sleep and being busy \
|
||||
(donning armor, for instance) as well as paralysis */
|
||||
else if (mtmp->mfrozen)
|
||||
Strcat(info, ", paralyzed");
|
||||
#else
|
||||
else if (mtmp->mfrozen || !mtmp->mcanmove)
|
||||
Strcat(info, ", can't move");
|
||||
#endif
|
||||
/* [arbitrary reason why it isn't moving] */
|
||||
else if (mtmp->mstrategy & STRAT_WAITMASK)
|
||||
Strcat(info, ", meditating");
|
||||
if (mtmp->mflee)
|
||||
Strcat(info, ", scared");
|
||||
if (mtmp->mtrapped)
|
||||
Strcat(info, ", trapped");
|
||||
if (mtmp->mspeed)
|
||||
Strcat(info, (mtmp->mspeed == MFAST) ? ", fast"
|
||||
: (mtmp->mspeed == MSLOW) ? ", slow"
|
||||
: ", [? speed]");
|
||||
if (mtmp->minvis)
|
||||
Strcat(info, ", invisible");
|
||||
if (mtmp == u.ustuck)
|
||||
Strcat(info, sticks(g.youmonst.data) ? ", held by you"
|
||||
: !u.uswallow ? ", holding you"
|
||||
: attacktype_fordmg(u.ustuck->data, AT_ENGL, AD_DGST)
|
||||
? ", digesting you"
|
||||
: is_animal(u.ustuck->data) ? ", swallowing you"
|
||||
: ", engulfing you");
|
||||
if (mtmp == u.usteed)
|
||||
Strcat(info, ", carrying you");
|
||||
|
||||
/* avoid "Status of the invisible newt ..., invisible" */
|
||||
/* and unlike a normal mon_nam, use "saddled" even if it has a name */
|
||||
Strcpy(monnambuf, x_monnam(mtmp, ARTICLE_THE, (char *) 0,
|
||||
(SUPPRESS_IT | SUPPRESS_INVISIBLE), FALSE));
|
||||
|
||||
pline("Status of %s (%s): Level %d HP %d(%d) AC %d%s.", monnambuf,
|
||||
align_str(alignment), mtmp->m_lev, mtmp->mhp, mtmp->mhpmax,
|
||||
find_mac(mtmp), info);
|
||||
}
|
||||
|
||||
/* stethoscope or probing applied to hero -- one-line feedback */
|
||||
void
|
||||
ustatusline()
|
||||
{
|
||||
char info[BUFSZ];
|
||||
|
||||
info[0] = '\0';
|
||||
if (Sick) {
|
||||
Strcat(info, ", dying from");
|
||||
if (u.usick_type & SICK_VOMITABLE)
|
||||
Strcat(info, " food poisoning");
|
||||
if (u.usick_type & SICK_NONVOMITABLE) {
|
||||
if (u.usick_type & SICK_VOMITABLE)
|
||||
Strcat(info, " and");
|
||||
Strcat(info, " illness");
|
||||
}
|
||||
}
|
||||
if (Stoned)
|
||||
Strcat(info, ", solidifying");
|
||||
if (Slimed)
|
||||
Strcat(info, ", becoming slimy");
|
||||
if (Strangled)
|
||||
Strcat(info, ", being strangled");
|
||||
if (Vomiting)
|
||||
Strcat(info, ", nauseated"); /* !"nauseous" */
|
||||
if (Confusion)
|
||||
Strcat(info, ", confused");
|
||||
if (Blind) {
|
||||
Strcat(info, ", blind");
|
||||
if (u.ucreamed) {
|
||||
if ((long) u.ucreamed < Blinded || Blindfolded
|
||||
|| !haseyes(g.youmonst.data))
|
||||
Strcat(info, ", cover");
|
||||
Strcat(info, "ed by sticky goop");
|
||||
} /* note: "goop" == "glop"; variation is intentional */
|
||||
}
|
||||
if (Stunned)
|
||||
Strcat(info, ", stunned");
|
||||
if (!u.usteed && Wounded_legs) {
|
||||
const char *what = body_part(LEG);
|
||||
if ((Wounded_legs & BOTH_SIDES) == BOTH_SIDES)
|
||||
what = makeplural(what);
|
||||
Sprintf(eos(info), ", injured %s", what);
|
||||
}
|
||||
if (Glib)
|
||||
Sprintf(eos(info), ", slippery %s", makeplural(body_part(HAND)));
|
||||
if (u.utrap)
|
||||
Strcat(info, ", trapped");
|
||||
if (Fast)
|
||||
Strcat(info, Very_fast ? ", very fast" : ", fast");
|
||||
if (u.uundetected)
|
||||
Strcat(info, ", concealed");
|
||||
if (Invis)
|
||||
Strcat(info, ", invisible");
|
||||
if (u.ustuck) {
|
||||
if (sticks(g.youmonst.data))
|
||||
Strcat(info, ", holding ");
|
||||
else
|
||||
Strcat(info, ", held by ");
|
||||
Strcat(info, mon_nam(u.ustuck));
|
||||
}
|
||||
|
||||
pline("Status of %s (%s): Level %d HP %d(%d) AC %d%s.", g.plname,
|
||||
piousness(FALSE, align_str(u.ualign.type)),
|
||||
Upolyd ? mons[u.umonnum].mlevel : u.ulevel, Upolyd ? u.mh : u.uhp,
|
||||
Upolyd ? u.mhmax : u.uhpmax, u.uac, info);
|
||||
}
|
||||
|
||||
/*priest.c*/
|
||||
|
||||
Reference in New Issue
Block a user