]> granicus.if.org Git - nethack/commitdiff
fix #H4274 - monster growing up changes gender
authorPatR <rankin@nethack.org>
Wed, 16 Mar 2016 22:03:37 +0000 (15:03 -0700)
committerPatR <rankin@nethack.org>
Wed, 16 Mar 2016 22:03:37 +0000 (15:03 -0700)
Most of the humanoid species have Lords and several have Kings,
but none of them have Ladies or Queens.  When a female grows up
to reach that level of monster, she changes into male.  This fix
gives an alternate message acknowledging that change rather than
prevent taking on the stronger form.  A better fix would be to
add ogre ladies and dwarf queens as separate monsters, but doing
so will break 3.6.0 save file compatibility.

(I started out with an alternate fix, adding mons[].fname for the
dozen or so creatures which warrant an alternate name for females.
But that requires statues, figurines, corpses, tins, and maybe
even eggs to track gender [some statues already do, and corpses
and statues with attached mtraits also implicitly do] and to not
stack with equivalent ones of the opposite gender.  Plus glyphs
to track them, and new tiles.  It was becoming too complicated
for such a relatively unimportant feature.  Separate monsters is
the way to go, deferred until save file format changes again.)

doc/fixes36.1
src/makemon.c

index d990e736c97af800454aa0d574c2abe500c54d31..31655d3abb75bceac6652383874dfc8f4a762a94 100644 (file)
@@ -188,6 +188,8 @@ grammar bit: polyself w/ gender change yielded "you turn into a Elvenking"
 some blindness cures ignored u.ucreamed
 some instances of stun or confusion timers were being overridden rather than
        incremented when new stun or confusion damage was suffered
+female gnome who gains level can grow up into male-only gnome lord; give an
+       an alternate message instead of prohibiting the promotion
 
 
 Platform- and/or Interface-Specific Fixes
index 422a446c2c51028aae1ef5877bcf68ed3fb56d35..9e2d5b9a603e171b9e5aa568151a9811da9d54a3 100644 (file)
@@ -1668,6 +1668,7 @@ grow_up(mtmp, victim)
 struct monst *mtmp, *victim;
 {
     int oldtype, newtype, max_increase, cur_increase, lev_limit, hp_threshold;
+    unsigned fem;
     struct permonst *ptr = mtmp->data;
 
     /* monster died after killing enemy but before calling this function */
@@ -1728,6 +1729,9 @@ struct monst *mtmp, *victim;
     else if (lev_limit > 49)
         lev_limit = (ptr->mlevel > 49 ? 50 : 49);
 
+    /* new form might force gender change */
+    fem = is_male(ptr) ? 0 : is_female(ptr) ? 1 : mtmp->female;
+
     if ((int) ++mtmp->m_lev >= mons[newtype].mlevel && newtype != oldtype) {
         ptr = &mons[newtype];
         if (mvitals[newtype].mvflags & G_GENOD) { /* allow G_EXTINCT */
@@ -1739,14 +1743,31 @@ struct monst *mtmp, *victim;
             mondied(mtmp);
             return (struct permonst *) 0;
         } else if (canspotmon(mtmp)) {
+            char buf[BUFSZ];
+
+            /* 3.6.1:
+             * Temporary (?) hack to fix growing into opposite gender.
+             */
+            Sprintf(buf, "%s%s",
+                    /* deal with female gnome becoming a gnome lord */
+                    (mtmp->female && !fem) ? "male "
+                        /* or a male gnome becoming a gnome lady
+                           (can't happen with 3.6.0 mons[], but perhaps
+                           slightly less sexist if prepared for it...) */
+                      : (fem && !mtmp->female) ? "female " : "",
+                    ptr->mname);
             pline("%s %s %s.", Monnam(mtmp),
-                  humanoid(ptr) ? "becomes" : "grows up into",
-                  an(ptr->mname));
+                  (fem != mtmp->female) ? "changes into"
+                                        : humanoid(ptr) ? "becomes"
+                                                        : "grows up into",
+                  an(buf));
         }
         set_mon_data(mtmp, ptr, 1);    /* preserve intrinsics */
         newsym(mtmp->mx, mtmp->my);    /* color may change */
         lev_limit = (int) mtmp->m_lev; /* never undo increment */
     }
+    mtmp->female = fem; /* gender might be changing */
+
     /* sanity checks */
     if ((int) mtmp->m_lev > lev_limit) {
         mtmp->m_lev--; /* undo increment */