logging experience level changes again

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.
This commit is contained in:
PatR
2022-02-10 05:45:07 -08:00
parent c036c59b00
commit 96ba3c04d1
7 changed files with 79 additions and 21 deletions
+1
View File
@@ -2060,6 +2060,7 @@ extern void nhassert_failed(const char *, const char *, int);
extern void set_uasmon(void); extern void set_uasmon(void);
extern void float_vs_flight(void); extern void float_vs_flight(void);
extern void change_sex(void); extern void change_sex(void);
extern void livelog_newform(boolean, int, int);
extern void polyself(int); extern void polyself(int);
extern int polymon(int); extern int polymon(int);
extern void rehumanize(void); extern void rehumanize(void);
+1 -1
View File
@@ -17,7 +17,7 @@
* Incrementing EDITLEVEL can be used to force invalidation of old bones * Incrementing EDITLEVEL can be used to force invalidation of old bones
* and save files. * and save files.
*/ */
#define EDITLEVEL 48 #define EDITLEVEL 49
/* /*
* Development status possibilities. * Development status possibilities.
+4 -2
View File
@@ -358,8 +358,10 @@ struct you {
boolean umoved; /* changed map location (post-move) */ boolean umoved; /* changed map location (post-move) */
int last_str_turn; /* 0: none, 1: half turn, 2: full turn int last_str_turn; /* 0: none, 1: half turn, 2: full turn
+: turn right, -: turn left */ +: turn right, -: turn left */
int ulevel; /* 1 to MAXULEV */ int ulevel; /* 1 to MAXULEV (30) */
int ulevelmax; 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 utrap; /* trap timeout */
unsigned utraptype; /* defined if utrap nonzero. one of utraptypes */ unsigned utraptype; /* defined if utrap nonzero. one of utraptypes */
char urooms[5]; /* rooms (roomno + 3) occupied now */ char urooms[5]; /* rooms (roomno + 3) occupied now */
+7 -4
View File
@@ -867,23 +867,26 @@ Amulet_on(void)
make_slimed(0L, (char *) 0); make_slimed(0L, (char *) 0);
break; break;
case AMULET_OF_CHANGE: { case AMULET_OF_CHANGE: {
int orig_sex = poly_gender(); int new_sex, orig_sex = poly_gender();
if (Unchanging) if (Unchanging)
break; break;
change_sex(); change_sex();
new_sex = poly_gender();
/* Don't use same message as polymorph */ /* Don't use same message as polymorph */
if (orig_sex != poly_gender()) { if (new_sex != orig_sex) {
makeknown(AMULET_OF_CHANGE); makeknown(AMULET_OF_CHANGE);
You("are suddenly very %s!", You("are suddenly very %s!",
flags.female ? "feminine" : "masculine"); flags.female ? "feminine" : "masculine");
g.context.botl = 1; g.context.botl = 1;
newsym(u.ux, u.uy); /* glyphmon flag and tile may have gone newsym(u.ux, u.uy); /* glyphmon flag and tile may have gone
from male to female or vice versa */ * from male to female or vice versa */
} else } else {
/* already polymorphed into single-gender monster; only /* already polymorphed into single-gender monster; only
changed the character's base sex */ changed the character's base sex */
You("don't feel like yourself."); You("don't feel like yourself.");
}
livelog_newform(FALSE, orig_sex, new_sex);
pline_The("amulet disintegrates!"); pline_The("amulet disintegrates!");
if (orig_sex == poly_gender() && uamul->dknown if (orig_sex == poly_gender() && uamul->dknown
&& !objects[AMULET_OF_CHANGE].oc_name_known && !objects[AMULET_OF_CHANGE].oc_name_known
+17 -7
View File
@@ -225,7 +225,7 @@ losexp(const char *drainer) /* cause of death, if drain should be fatal */
u.ulevel -= 1; u.ulevel -= 1;
/* remove intrinsic abilities */ /* remove intrinsic abilities */
adjabil(u.ulevel + 1, u.ulevel); 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 { } else {
if (drainer) { if (drainer) {
g.killer.format = KILLED_BY; g.killer.format = KILLED_BY;
@@ -285,8 +285,10 @@ newexplevel(void)
} }
void void
pluslvl(boolean incr) /* true iff via incremental experience growth */ pluslvl(
{ /* (false for potion of gain level) */ boolean incr) /* True: incremental experience growth;
* False: potion of gain level or wraith corpse */
{
int hpinc, eninc; int hpinc, eninc;
if (!incr) if (!incr)
@@ -314,7 +316,7 @@ pluslvl(boolean incr) /* true iff via incremental experience growth */
/* increase level (unless already maxxed) */ /* increase level (unless already maxxed) */
if (u.ulevel < MAXULEV) { 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 */ /* increase experience points to reflect new level */
if (incr) { if (incr) {
@@ -332,12 +334,20 @@ pluslvl(boolean incr) /* true iff via incremental experience growth */
if (u.ulevelmax < u.ulevel) if (u.ulevelmax < u.ulevel)
u.ulevelmax = u.ulevel; u.ulevelmax = u.ulevel;
adjabil(u.ulevel - 1, u.ulevel); /* give new intrinsics */ adjabil(u.ulevel - 1, u.ulevel); /* give new intrinsics */
old_ach_cnt = count_achievements();
newrank = xlev_to_rank(u.ulevel); newrank = xlev_to_rank(u.ulevel);
if (newrank > oldrank) if (newrank > oldrank)
record_achievement(achieve_rank(newrank)); record_achievement(achieve_rank(newrank));
else /* a new rank achievement will log its own message; log a simpler
livelog_printf(LL_MINORAC, "gained experience level %d", message here if we didn't just get an achievement (so when rank
u.ulevel); 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; g.context.botl = TRUE;
} }
+2 -1
View File
@@ -2097,7 +2097,8 @@ show_conduct(int final)
*/ */
static void 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; int i, achidx, absidx, acnt;
char title[QBUFSZ], buf[QBUFSZ]; char title[QBUFSZ], buf[QBUFSZ];
+47 -6
View File
@@ -264,17 +264,47 @@ change_sex(void)
#if 0 #if 0
/* change monster type to match new sex; disabled with /* change monster type to match new sex; disabled with
PM_AMOROUS_DEMON */ PM_AMOROUS_DEMON */
u.umonnum = (u.umonnum == PM_SUCCUBUS) ? PM_INCUBUS : PM_SUCCUBUS; u.umonnum = (u.umonnum == PM_SUCCUBUS) ? PM_INCUBUS : PM_SUCCUBUS;
#endif #endif
set_uasmon(); 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 static void
newman(void) newman(void)
{ {
int i, oldlvl, newlvl, hpmax, enmax; const char *newform;
int i, oldlvl, newlvl, oldgend, newgend, hpmax, enmax;
oldlvl = u.ulevel; oldlvl = u.ulevel;
newlvl = oldlvl + rn1(5, -2); /* new = old + {-2,-1,0,+1,+2} */ newlvl = oldlvl + rn1(5, -2); /* new = old + {-2,-1,0,+1,+2} */
@@ -295,6 +325,7 @@ newman(void)
u.ulevelmax = newlvl; u.ulevelmax = newlvl;
u.ulevel = newlvl; u.ulevel = newlvl;
oldgend = poly_gender();
if (g.sex_change_ok && !rn2(10)) if (g.sex_change_ok && !rn2(10))
change_sex(); change_sex();
@@ -371,13 +402,23 @@ newman(void)
} }
} }
newuhs(FALSE); newuhs(FALSE);
polyman("You feel like a new %s!", /* use saved gender we're about to revert to, not current */
/* use saved gender we're about to revert to, not current */ newform = ((Upolyd ? u.mfemale : flags.female) && g.urace.individual.f)
((Upolyd ? u.mfemale : flags.female) && g.urace.individual.f)
? g.urace.individual.f ? g.urace.individual.f
: (g.urace.individual.m) : (g.urace.individual.m)
? 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) { if (Slimed) {
Your("body transforms, but there is still slime on you."); Your("body transforms, but there is still slime on you.");
make_slimed(10L, (const char *) 0); make_slimed(10L, (const char *) 0);