]> granicus.if.org Git - nethack/commitdiff
logging experience level changes again
authorPatR <rankin@nethack.org>
Thu, 10 Feb 2022 13:45:07 +0000 (05:45 -0800)
committerPatR <rankin@nethack.org>
Thu, 10 Feb 2022 13:45:07 +0000 (05:45 -0800)
The livelog message for losing a level had an off-by-1 error, showing
the level the hero ended up at rather than the level that was lost.

There was a message for regaining a previously lost level when rank
title stayed the same but no such message if the title changed (the
achievement of gaining a particular title only occurs once).

Say "regained" rather than "gained" when gaining a previously lost
level.  (Blessed potions of full healing regain levels but can also
reduce u.ulevelmax so a different way to remember peak experience
level has been added.)

Report level change due to polymorphing into new man/woman/elf/&c.
I hadn't realized that that hasn't been recording achievement for new
rank when applicable and decided to leave things that way.

Report gender change when putting on an amulet of change or becoming
a new man/&c unless hero is polymorphed at the time or experience
level is also changing.

include/extern.h
include/patchlevel.h
include/you.h
src/do_wear.c
src/exper.c
src/insight.c
src/polyself.c

index 4f565a1e64924705822f4a3b847dacdfe5b8bc8a..089db22507123f4c0b7649156a4c0c28f9670a0d 100644 (file)
@@ -2060,6 +2060,7 @@ extern void nhassert_failed(const char *, const char *, int);
 extern void set_uasmon(void);
 extern void float_vs_flight(void);
 extern void change_sex(void);
+extern void livelog_newform(boolean, int, int);
 extern void polyself(int);
 extern int polymon(int);
 extern void rehumanize(void);
index 11f6d9d288a9ce898082d3dd720c0d90d89a4665..5cb1e8bc42c7474e73e5ea799dda39ee071cf562 100644 (file)
@@ -17,7 +17,7 @@
  * Incrementing EDITLEVEL can be used to force invalidation of old bones
  * and save files.
  */
-#define EDITLEVEL 48
+#define EDITLEVEL 49
 
 /*
  * Development status possibilities.
index 518a2f5d9c265ebc06571bae4feff7b8ca66c305..39312314a5ffee74d5d772da811dfbf3d7f8b7d9 100644 (file)
@@ -358,8 +358,10 @@ struct you {
     boolean umoved;     /* changed map location (post-move) */
     int last_str_turn;  /* 0: none, 1: half turn, 2: full turn
                            +: turn right, -: turn left */
-    int ulevel;         /* 1 to MAXULEV */
-    int ulevelmax;
+    int ulevel;         /* 1 to MAXULEV (30) */
+    int ulevelmax;      /* highest level, but might go down (to throttle
+                         * lost level recovery via blessed full healing) */
+    int ulevelpeak;     /* really highest level reached; never does down */
     unsigned utrap;     /* trap timeout */
     unsigned utraptype; /* defined if utrap nonzero. one of utraptypes */
     char urooms[5];         /* rooms (roomno + 3) occupied now */
index f0e31d0f3b8d4ea445c2f3ff6a612a7002f4ff5d..f99a8fb4caea7790d4446b57c6487aa40311b562 100644 (file)
@@ -867,23 +867,26 @@ Amulet_on(void)
             make_slimed(0L, (char *) 0);
         break;
     case AMULET_OF_CHANGE: {
-        int orig_sex = poly_gender();
+        int new_sex, orig_sex = poly_gender();
 
         if (Unchanging)
             break;
         change_sex();
+        new_sex = poly_gender();
         /* Don't use same message as polymorph */
-        if (orig_sex != poly_gender()) {
+        if (new_sex != orig_sex) {
             makeknown(AMULET_OF_CHANGE);
             You("are suddenly very %s!",
                 flags.female ? "feminine" : "masculine");
             g.context.botl = 1;
             newsym(u.ux, u.uy); /* glyphmon flag and tile may have gone
-                                   from male to female or vice versa */
-        } else
+                                 * from male to female or vice versa */
+        } else {
             /* already polymorphed into single-gender monster; only
                changed the character's base sex */
             You("don't feel like yourself.");
+        }
+        livelog_newform(FALSE, orig_sex, new_sex);
         pline_The("amulet disintegrates!");
         if (orig_sex == poly_gender() && uamul->dknown
             && !objects[AMULET_OF_CHANGE].oc_name_known
index 02c13a1d802711ebdee47baa8cb8599a0edc88af..ce47763e125042fc80c8ad53dce4635cb36cf6f3 100644 (file)
@@ -225,7 +225,7 @@ losexp(const char *drainer) /* cause of death, if drain should be fatal */
         u.ulevel -= 1;
         /* remove intrinsic abilities */
         adjabil(u.ulevel + 1, u.ulevel);
-        livelog_printf(LL_MINORAC, "lost experience level %d", u.ulevel);
+        livelog_printf(LL_MINORAC, "lost experience level %d", u.ulevel + 1);
     } else {
         if (drainer) {
             g.killer.format = KILLED_BY;
@@ -285,8 +285,10 @@ newexplevel(void)
 }
 
 void
-pluslvl(boolean incr) /* true iff via incremental experience growth */
-{                     /*        (false for potion of gain level)    */
+pluslvl(
+    boolean incr) /* True: incremental experience growth;
+                   * False: potion of gain level or wraith corpse */
+{
     int hpinc, eninc;
 
     if (!incr)
@@ -314,7 +316,7 @@ pluslvl(boolean incr) /* true iff via incremental experience growth */
 
     /* increase level (unless already maxxed) */
     if (u.ulevel < MAXULEV) {
-        int newrank, oldrank = xlev_to_rank(u.ulevel);
+        int old_ach_cnt, newrank, oldrank = xlev_to_rank(u.ulevel);
 
         /* increase experience points to reflect new level */
         if (incr) {
@@ -332,12 +334,20 @@ pluslvl(boolean incr) /* true iff via incremental experience growth */
         if (u.ulevelmax < u.ulevel)
             u.ulevelmax = u.ulevel;
         adjabil(u.ulevel - 1, u.ulevel); /* give new intrinsics */
+
+        old_ach_cnt = count_achievements();
         newrank = xlev_to_rank(u.ulevel);
         if (newrank > oldrank)
             record_achievement(achieve_rank(newrank));
-        else
-            livelog_printf(LL_MINORAC, "gained experience level %d",
-                           u.ulevel);
+        /* a new rank achievement will log its own message; log a simpler
+           message here if we didn't just get an achievement (so when rank
+           hasn't changed or hero just regained a lost level and the rank
+           achievement doesn't get repeated) */
+        if (count_achievements() == old_ach_cnt)
+            livelog_printf(LL_MINORAC, "%sgained experience level %d",
+                           (u.ulevel <= u.ulevelpeak) ? "re" : "", u.ulevel);
+        if (u.ulevel > u.ulevelpeak)
+            u.ulevelpeak = u.ulevel;
     }
     g.context.botl = TRUE;
 }
index a2612bc0c06809f99363e247d38003322bf7a0c3..1b7db88334def647dc655f0fa059376187a1b774 100644 (file)
@@ -2097,7 +2097,8 @@ show_conduct(int final)
  */
 
 static void
-show_achievements(int final) /* used "behind the curtain" by enl_foo() macros */
+show_achievements(
+    int final) /* 'final' is used "behind the curtain" by enl_foo() macros */
 {
     int i, achidx, absidx, acnt;
     char title[QBUFSZ], buf[QBUFSZ];
index a8983e21a708f33c3c3b6082d55ead33faa9fe5f..fb7e389961efde8053ec6d06c1032775dfc55aeb 100644 (file)
@@ -264,17 +264,47 @@ change_sex(void)
 #if 0
         /* change monster type to match new sex; disabled with
            PM_AMOROUS_DEMON */
-
         u.umonnum = (u.umonnum == PM_SUCCUBUS) ? PM_INCUBUS : PM_SUCCUBUS;
 #endif
         set_uasmon();
     }
 }
 
+/* log a message if non-poly'd hero's gender has changed */
+void
+livelog_newform(boolean viapoly, int oldgend, int newgend)
+{
+    char buf[BUFSZ];
+    const char *oldrole, *oldrank, *newrole, *newrank;
+
+    /*
+     * TODO?
+     *  Give other logging feedback here instead of in newman().
+     */
+
+    if (!Upolyd) {
+        if (newgend != oldgend) {
+            oldrole = (oldgend && g.urole.name.f) ? g.urole.name.f
+                                                  : g.urole.name.m;
+            newrole = (newgend && g.urole.name.f) ? g.urole.name.f
+                                                  : g.urole.name.m;
+            oldrank = rank_of(u.ulevel, Role_switch, oldgend);
+            newrank = rank_of(u.ulevel, Role_switch, newgend);
+            Sprintf(buf, "%.10s %.30s", genders[flags.female].adj, newrank);
+            livelog_printf(LL_MINORAC, "%s into %s",
+                           viapoly ? "polymorphed" : "transformed",
+                           an(strcmp(newrole, oldrole) ? newrole
+                              : strcmp(newrank, oldrank) ? newrank
+                                : buf));
+        }
+    }
+}
+
 static void
 newman(void)
 {
-    int i, oldlvl, newlvl, hpmax, enmax;
+    const char *newform;
+    int i, oldlvl, newlvl, oldgend, newgend, hpmax, enmax;
 
     oldlvl = u.ulevel;
     newlvl = oldlvl + rn1(5, -2);     /* new = old + {-2,-1,0,+1,+2} */
@@ -295,6 +325,7 @@ newman(void)
         u.ulevelmax = newlvl;
     u.ulevel = newlvl;
 
+    oldgend = poly_gender();
     if (g.sex_change_ok && !rn2(10))
         change_sex();
 
@@ -371,13 +402,23 @@ newman(void)
         }
     }
     newuhs(FALSE);
-    polyman("You feel like a new %s!",
-            /* use saved gender we're about to revert to, not current */
-            ((Upolyd ? u.mfemale : flags.female) && g.urace.individual.f)
+    /* use saved gender we're about to revert to, not current */
+    newform = ((Upolyd ? u.mfemale : flags.female) && g.urace.individual.f)
                 ? g.urace.individual.f
                 : (g.urace.individual.m)
                    ? g.urace.individual.m
-                   : g.urace.noun);
+                   : g.urace.noun;
+    polyman("You feel like a new %s!", newform);
+
+    newgend = poly_gender();
+    /* note: newman() bypasses achievemnts for new ranks attained and
+       doesn't log "new <form>" when that isn't accompanied by level change */
+    if (newlvl != oldlvl)
+        livelog_printf(LL_MINORAC, "became experience level %d as a new %s",
+                       newlvl, newform);
+    else
+        livelog_newform(TRUE, oldgend, newgend);
+
     if (Slimed) {
         Your("body transforms, but there is still slime on you.");
         make_slimed(10L, (const char *) 0);