]> granicus.if.org Git - nethack/commitdiff
allow big humanoids to wear mummy wrappings
authorPatR <rankin@nethack.org>
Sun, 23 Oct 2022 00:14:22 +0000 (17:14 -0700)
committerPatR <rankin@nethack.org>
Sun, 23 Oct 2022 00:14:22 +0000 (17:14 -0700)
A giant mummy starts out with a mummy wrapping but couldn't wear it.
Allow humanoids who are bigger than human size (including poly'd hero
when applicable) to wear such cloaks.  They won't do so if they are
invisible and the cloak would let hero start seeing them.

doc/fixes3-7-0.txt
include/obj.h
src/do_wear.c
src/polyself.c
src/worn.c

index f9c08a7eebe808ac181183ee35b4358e9c877126..7b0f5de4ef763938fb0449440785cfb57b422927 100644 (file)
@@ -1859,6 +1859,7 @@ experimental #saveoptions command to allow saving configuration settings
 mouse buttons can be bound to extended commands
 hero poly'd into purple worm can gain intrinsics from digesting whole monster
 add some tins of spinach to monk's quest (vegan => no Str from giant corpses)
+very large humanoids can wear mummy wrappings
 
 
 Platform- and/or Interface-Specific New Features
index 2e462842e4004bb24071d1e813d5ad7253d032bb..8454ed1f2b514101385e657e239b2a0e31adbea9 100644 (file)
@@ -411,6 +411,12 @@ struct obj {
 #define is_art(o,art) ((o) && (o)->oartifact == (art))
 #define u_wield_art(art) is_art(uwep, art)
 
+/* mummy wrappings are more versatile sizewise than other cloaks */
+#define WrappingAllowed(mptr) \
+    (humanoid(mptr) && (mptr)->msize >= MZ_SMALL && (mptr)->msize <= MZ_HUGE \
+     && !noncorporeal(mptr) && (mptr)->mlet != S_CENTAUR                     \
+     && (mptr) != &mons[PM_WINGED_GARGOYLE] && (mptr) != &mons[PM_MARILITH])
+
 /* Flags for get_obj_location(). */
 #define CONTAINED_TOO 0x1
 #define BURIED_TOO 0x2
index 215c1bc0015f581ad5cd10894a3906f9c3dd13ef..78d5e439ac1560827f907fef81dd6fc862fac74f 100644 (file)
@@ -1876,16 +1876,16 @@ canwearobj(struct obj *otmp, long *mask, boolean noisy)
         return 0;
     }
 
-    which = is_cloak(otmp)
-                ? c_cloak
-                : is_shirt(otmp)
-                    ? c_shirt
-                    : is_suit(otmp)
-                        ? c_suit
-                        : 0;
+    which = is_cloak(otmp) ? c_cloak
+            : is_shirt(otmp) ? c_shirt
+              : is_suit(otmp) ? c_suit
+                : 0;
     if (which && cantweararm(g.youmonst.data)
         /* same exception for cloaks as used in m_dowear() */
-        && (which != c_cloak || g.youmonst.data->msize != MZ_SMALL)
+        && (which != c_cloak
+            || ((otmp->otyp != MUMMY_WRAPPING)
+                ? g.youmonst.data->msize != MZ_SMALL
+                : !WrappingAllowed(g.youmonst.data)))
         && (racial_exception(&g.youmonst, otmp) < 1)) {
         if (noisy)
             pline_The("%s will not fit on your body.", which);
index e8c2ee35bf482a759f2644b7325e781e2b58a517..d1f302ebe73eadaaa9f46b6140dcb0970bbd9a14 100644 (file)
@@ -1042,8 +1042,9 @@ static void
 break_armor(void)
 {
     register struct obj *otmp;
+    struct permonst *uptr = g.youmonst.data;
 
-    if (breakarm(g.youmonst.data)) {
+    if (breakarm(uptr)) {
         if ((otmp = uarm) != 0) {
             if (donning(otmp))
                 cancel_don();
@@ -1057,7 +1058,9 @@ break_armor(void)
             (void) Armor_gone();
             useup(otmp);
         }
-        if ((otmp = uarmc) != 0) {
+        if ((otmp = uarmc) != 0
+            /* mummy wrapping adapts to small and very big sizes */
+            && (otmp->otyp != MUMMY_WRAPPING || !WrappingAllowed(uptr))) {
             if (otmp->oartifact) {
                 Your("%s falls off!", cloak_simple_name(otmp));
                 (void) Cloak_off();
@@ -1072,8 +1075,8 @@ break_armor(void)
             Your("shirt rips to shreds!");
             useup(uarmu);
         }
-    } else if (sliparm(g.youmonst.data)) {
-        if ((otmp = uarm) != 0 && racial_exception(&g.youmonst, otmp) < 1) {
+    } else if (sliparm(uptr)) {
+        if ((otmp = uarm) != 0 && racial_exception(uptr, otmp) < 1) {
             if (donning(otmp))
                 cancel_don();
             Your("armor falls around you!");
@@ -1084,8 +1087,10 @@ break_armor(void)
             (void) Armor_gone();
             dropp(otmp);
         }
-        if ((otmp = uarmc) != 0) {
-            if (is_whirly(g.youmonst.data))
+        if ((otmp = uarmc) != 0
+            /* mummy wrapping adapts to small and very big sizes */
+            && (otmp->otyp != MUMMY_WRAPPING || !WrappingAllowed(uptr))) {
+            if (is_whirly(uptr))
                 Your("%s falls, unsupported!", cloak_simple_name(otmp));
             else
                 You("shrink out of your %s!", cloak_simple_name(otmp));
@@ -1093,7 +1098,7 @@ break_armor(void)
             dropp(otmp);
         }
         if ((otmp = uarmu) != 0) {
-            if (is_whirly(g.youmonst.data))
+            if (is_whirly(uptr))
                 You("seep right through your shirt!");
             else
                 You("become much too small for your shirt!");
@@ -1101,13 +1106,13 @@ break_armor(void)
             dropp(otmp);
         }
     }
-    if (has_horns(g.youmonst.data)) {
+    if (has_horns(uptr)) {
         if ((otmp = uarmh) != 0) {
             if (is_flimsy(otmp) && !donning(otmp)) {
                 char hornbuf[BUFSZ];
 
                 /* Future possibilities: This could damage/destroy helmet */
-                Sprintf(hornbuf, "horn%s", plur(num_horns(g.youmonst.data)));
+                Sprintf(hornbuf, "horn%s", plur(num_horns(uptr)));
                 Your("%s %s through %s.", hornbuf, vtense(hornbuf, "pierce"),
                      yname(otmp));
             } else {
@@ -1120,7 +1125,7 @@ break_armor(void)
             }
         }
     }
-    if (nohands(g.youmonst.data) || verysmall(g.youmonst.data)) {
+    if (nohands(uptr) || verysmall(uptr)) {
         if ((otmp = uarmg) != 0) {
             if (donning(otmp))
                 cancel_don();
@@ -1145,16 +1150,16 @@ break_armor(void)
             dropp(otmp);
         }
     }
-    if (nohands(g.youmonst.data) || verysmall(g.youmonst.data)
-        || slithy(g.youmonst.data) || g.youmonst.data->mlet == S_CENTAUR) {
+    if (nohands(uptr) || verysmall(uptr)
+        || slithy(uptr) || uptr->mlet == S_CENTAUR) {
         if ((otmp = uarmf) != 0) {
             if (donning(otmp))
                 cancel_don();
-            if (is_whirly(g.youmonst.data))
+            if (is_whirly(uptr))
                 Your("boots fall away!");
             else
                 Your("boots %s off your feet!",
-                     verysmall(g.youmonst.data) ? "slide" : "are pushed");
+                     verysmall(uptr) ? "slide" : "are pushed");
             (void) Boots_off();
             dropp(otmp);
         }
@@ -1163,7 +1168,7 @@ break_armor(void)
        it/them on (should also come off if head is too tiny or too huge,
        but putting accessories on doesn't reject those cases [yet?]);
        amulet stays worn */
-    if ((otmp = ublindf) != 0 && !has_head(g.youmonst.data)) {
+    if ((otmp = ublindf) != 0 && !has_head(uptr)) {
         int l;
         const char *eyewear = simpleonames(otmp); /* blindfold|towel|lenses */
 
index ca056fefab7063e634799e71a7a3fdac5b2f8ee7..462abdca84bb53fe40087bebdc46cc7e2a12f410 100644 (file)
@@ -258,10 +258,10 @@ mon_set_minvis(struct monst *mon)
 }
 
 void
-mon_adjust_speed(struct monst *mon,
-                 int adjust,      /* positive => increase speed, negative =>
-                                     decrease */
-                 struct obj *obj) /* item to make known if effect can be seen */
+mon_adjust_speed(
+    struct monst *mon,
+    int adjust,        /* positive => increase speed, negative => decrease */
+    struct obj *obj)   /* item to make known if effect can be seen */
 {
     struct obj *otmp;
     boolean give_msg = !g.in_mklev, petrify = FALSE;
@@ -533,6 +533,8 @@ find_mac(struct monst *mon)
 void
 m_dowear(struct monst *mon, boolean creation)
 {
+    boolean can_wear_armor;
+
 #define RACE_EXCEPTION TRUE
     /* Note the restrictions here are the same as in dowear in do_wear.c
      * except for the additional restriction on intelligence.  (Players
@@ -548,12 +550,15 @@ m_dowear(struct monst *mon, boolean creation)
         return;
 
     m_dowear_type(mon, W_AMUL, creation, FALSE);
+    can_wear_armor = !cantweararm(mon->data); /* for suit, cloak, shirt */
     /* can't put on shirt if already wearing suit */
-    if (!cantweararm(mon->data) && !(mon->misc_worn_check & W_ARM))
+    if (can_wear_armor && !(mon->misc_worn_check & W_ARM))
         m_dowear_type(mon, W_ARMU, creation, FALSE);
-    /* treating small as a special case allows
-       hobbits, gnomes, and kobolds to wear cloaks */
-    if (!cantweararm(mon->data) || mon->data->msize == MZ_SMALL)
+    /* WrappingAllowed() makes any size between small and huge eligible;
+       treating small as a special case allows hobbits, gnomes, and
+       kobolds to wear all cloaks; large and huge allows giants and such
+       to wear mummy wrappings but not other cloaks */
+    if (can_wear_armor || WrappingAllowed(mon->data))
         m_dowear_type(mon, W_ARMC, creation, FALSE);
     m_dowear_type(mon, W_ARMH, creation, FALSE);
     if (!MON_WEP(mon) || !bimanual(MON_WEP(mon)))
@@ -561,15 +566,19 @@ m_dowear(struct monst *mon, boolean creation)
     m_dowear_type(mon, W_ARMG, creation, FALSE);
     if (!slithy(mon->data) && mon->data->mlet != S_CENTAUR)
         m_dowear_type(mon, W_ARMF, creation, FALSE);
-    if (!cantweararm(mon->data))
+    if (can_wear_armor)
         m_dowear_type(mon, W_ARM, creation, FALSE);
     else
         m_dowear_type(mon, W_ARM, creation, RACE_EXCEPTION);
 }
 
 static void
-m_dowear_type(struct monst *mon, long flag, boolean creation,
-              boolean racialexception)
+m_dowear_type(
+    struct monst *mon,
+    long flag,               /* wornmask value */
+    boolean creation,
+    boolean racialexception) /* small monsters that are allowed for player
+                              * races (gnomes) can wear suits */
 {
     struct obj *old, *best, *obj;
     long oldmask = 0L;
@@ -615,6 +624,14 @@ m_dowear_type(struct monst *mon, long flag, boolean creation,
         case W_ARMC:
             if (!is_cloak(obj))
                 continue;
+            /* mummy wrapping is only cloak allowed when bigger than human */
+            if (mon->data->msize > MZ_HUMAN && obj->otyp != MUMMY_WRAPPING)
+                continue;
+            /* avoid mummy wrapping if it will allow hero to see mon (unless
+               this is a new mummy; an invisible one is feasible via ^G) */
+            if (mon->minvis && w_blocks(obj, W_ARMC) == INVIS
+                && !See_invisible && !creation)
+                continue;
             break;
         case W_ARMH:
             if (!is_helmet(obj))
@@ -738,8 +755,9 @@ m_dowear_type(struct monst *mon, long flag, boolean creation,
         if (mon->minvis && !See_invisible) {
             pline("Suddenly you cannot see %s.", nambuf);
             makeknown(best->otyp);
-        } /* else if (!mon->minvis)
-           *     pline("%s suddenly appears!", Amonnam(mon)); */
+        /* } else if (!mon->minvis) {
+         *     pline("%s suddenly appears!", Amonnam(mon)); */
+        }
     }
 }
 #undef RACE_EXCEPTION
@@ -931,7 +949,9 @@ mon_break_armor(struct monst *mon, boolean polyspot)
                 You_hear("a cracking sound.");
             m_useup(mon, otmp);
         }
-        if ((otmp = which_armor(mon, W_ARMC)) != 0) {
+        if ((otmp = which_armor(mon, W_ARMC)) != 0
+            /* mummy wrapping adapts to small and very big sizes */
+            && (otmp->otyp != MUMMY_WRAPPING || !WrappingAllowed(mdat))) {
             if (otmp->oartifact) {
                 if (vis)
                     pline("%s %s falls off!", s_suffix(Monnam(mon)),
@@ -969,7 +989,9 @@ mon_break_armor(struct monst *mon, boolean polyspot)
                 bypass_obj(otmp);
             m_lose_armor(mon, otmp);
         }
-        if ((otmp = which_armor(mon, W_ARMC)) != 0) {
+        if ((otmp = which_armor(mon, W_ARMC)) != 0
+            /* mummy wrapping adapts to small and very big sizes */
+            && (otmp->otyp != MUMMY_WRAPPING || !WrappingAllowed(mdat))) {
             if (vis) {
                 if (is_whirly(mon->data))
                     pline("%s %s falls, unsupported!", s_suffix(Monnam(mon)),