From: PatR Date: Thu, 5 May 2016 00:42:58 +0000 (-0700) Subject: disclosing genocided/extinct monsters X-Git-Tag: NetHack-3.6.1_RC01~793 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e0537a76d47b1f4ceef3c239bbceda3b93a8de8f;p=nethack disclosing genocided/extinct monsters Make the handling of unique monsters consistent between vanquished monsters and genocided/extinct monsters. No visible difference to players. This also prevents Nazgul and erinys from being polymorphed into some other form to reduce the chance that their kill count fails to match the expected number when they're reported to be extinct. [My long test game (with 3451 total dead critters as of the last save file) used for exercising the sorting of vanquished monsters included 120 soldiers 111 wolves 9 Nazgul 2 erinyes and the genocided/extinct list had none genocided, those four extinct. No doubt the missing third erinys was alive somewhere rather than counted as something else after getting polymorphed, so this band-aid wouldn't have helped this particular game.] --- diff --git a/src/end.c b/src/end.c index eab613d9d..f41890dc6 100644 --- a/src/end.c +++ b/src/end.c @@ -1578,6 +1578,10 @@ dovanquished() 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_OVL void list_vanquished(defquery, ask) char defquery; @@ -1639,7 +1643,7 @@ boolean ask; upstart(buf)); prev_mlet = mlet; } - if ((mons[i].geno & G_UNIQ) && i != PM_HIGH_PRIEST) { + if (UniqCritterIndx(i)) { Sprintf(buf, "%s%s", !type_is_pname(&mons[i]) ? "the " : "", mons[i].mname); @@ -1704,10 +1708,14 @@ num_genocides() { int i, n = 0; - for (i = LOW_PM; i < NUMMONS; ++i) - if (mvitals[i].mvflags & G_GENOD) + for (i = LOW_PM; i < NUMMONS; ++i) { + if (mvitals[i].mvflags & G_GENOD) { ++n; - + if (UniqCritterIndx(i)) + impossible("unique creature '%d: %s' genocided?", + i, mons[i].mname); + } + } return n; } @@ -1716,11 +1724,12 @@ num_extinct() { int i, n = 0; - for (i = LOW_PM; i < NUMMONS; ++i) - if (!(mvitals[i].mvflags & G_GENOD) && (mvitals[i].mvflags & G_GONE) - && !(mons[i].geno & G_UNIQ)) + for (i = LOW_PM; i < NUMMONS; ++i) { + if (UniqCritterIndx(i)) + continue; + if ((mvitals[i].mvflags & G_GONE) == G_EXTINCT) ++n; - + } return n; } @@ -1755,19 +1764,24 @@ boolean ask; putstr(klwin, 0, buf); putstr(klwin, 0, ""); - for (i = LOW_PM; i < NUMMONS; i++) - if (mvitals[i].mvflags & G_GONE && !(mons[i].geno & G_UNIQ)) { - if ((mons[i].geno & G_UNIQ) && i != PM_HIGH_PRIEST) - Sprintf(buf, "%s%s", - !type_is_pname(&mons[i]) ? "" : "the ", - mons[i].mname); - else - Strcpy(buf, makeplural(mons[i].mname)); - if (!(mvitals[i].mvflags & G_GENOD)) + 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 (mvitals[i].mvflags & G_GONE) { + Strcpy(buf, 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 ((mvitals[i].mvflags & G_GONE) == G_EXTINCT) Strcat(buf, " (extinct)"); putstr(klwin, 0, buf); } - + } putstr(klwin, 0, ""); if (ngenocided > 0) { Sprintf(buf, "%d species genocided.", ngenocided); diff --git a/src/makemon.c b/src/makemon.c index 61de5af0e..73a1138d4 100644 --- a/src/makemon.c +++ b/src/makemon.c @@ -1326,6 +1326,11 @@ int mbirth_limit(mndx) int mndx; { + /* There is an implicit limit of 4 for "high priest of ", + * but aligned priests can grow into high priests, thus they aren't + * really limited to 4, so leave the default amount in place for them. + */ + /* assert(MAXMONNO < 255); */ return (mndx == PM_NAZGUL ? 9 : mndx == PM_ERINYS ? 3 : MAXMONNO); } diff --git a/src/mon.c b/src/mon.c index d3e9c97de..b4a8f97f6 100644 --- a/src/mon.c +++ b/src/mon.c @@ -3217,8 +3217,14 @@ boolean msg; /* "The oldmon turns into a newmon!" */ /* Riders are immune to polymorph and green slime (but apparent Rider might actually be a doppelganger) */ - if (is_rider(mtmp->data) && mtmp->cham == NON_PM) - return 0; + if (mtmp->cham == NON_PM) { /* not a shapechanger */ + if (is_rider(olddata)) + return 0; + /* make Nazgul and erinyes immune too, to reduce chance of + anomalous extinction feedback during final disclsoure */ + if (mbirth_limit(monsndx(olddata)) < MAXMONNO) + return 0; + } if (msg) { /* like Monnam() but never mention saddle */