diff --git a/include/extern.h b/include/extern.h index 4f565a1e6..089db2250 100644 --- a/include/extern.h +++ b/include/extern.h @@ -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); diff --git a/include/patchlevel.h b/include/patchlevel.h index 11f6d9d28..5cb1e8bc4 100644 --- a/include/patchlevel.h +++ b/include/patchlevel.h @@ -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. diff --git a/include/you.h b/include/you.h index 518a2f5d9..39312314a 100644 --- a/include/you.h +++ b/include/you.h @@ -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 */ diff --git a/src/do_wear.c b/src/do_wear.c index f0e31d0f3..f99a8fb4c 100644 --- a/src/do_wear.c +++ b/src/do_wear.c @@ -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 diff --git a/src/exper.c b/src/exper.c index 02c13a1d8..ce47763e1 100644 --- a/src/exper.c +++ b/src/exper.c @@ -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; } diff --git a/src/insight.c b/src/insight.c index a2612bc0c..1b7db8833 100644 --- a/src/insight.c +++ b/src/insight.c @@ -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]; diff --git a/src/polyself.c b/src/polyself.c index a8983e21a..fb7e38996 100644 --- a/src/polyself.c +++ b/src/polyself.c @@ -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
" 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);