]> granicus.if.org Git - nethack/commitdiff
Merge branch 'master' into nhmall-booktribute
authornhmall <mjnh@persona.ca>
Sun, 12 Apr 2015 14:02:17 +0000 (10:02 -0400)
committernhmall <mjnh@persona.ca>
Sun, 12 Apr 2015 14:02:17 +0000 (10:02 -0400)
Conflicts:
doc/fixes35.0
include/extern.h
src/mkobj.c
src/mon.c
src/objnam.c
win/share/objects.txt

1  2 
doc/fixes35.0
include/extern.h
include/obj.h
src/files.c
src/mkobj.c
src/mon.c
src/objects.c
src/objnam.c
src/trap.c
src/zap.c
win/share/objects.txt

diff --cc doc/fixes35.0
index 0993ac70738b3cea90a8738ed8b7bef51401353f,4c4754c6bfcf88090fea595875745e2ec00fc835..5f5abf2500c81778d9964abec8ddd87dd61a2cf0
@@@ -1112,7 -1115,7 +1115,8 @@@ show more explicit reason why player wa
  added new hallucinatory-only gods
  options to create the character blind or nudist
  moving clouds on the plane of air
+ disclose extinct species alongside genocided ones
 +tribute to Terry Pratchett
  
  
  Platform- and/or Interface-Specific New Features
Simple merge
diff --cc include/obj.h
Simple merge
diff --cc src/files.c
Simple merge
diff --cc src/mkobj.c
index 0f67aed133cd7cadaabc68b024769b2d849aca3d,0fd6ab589bd3e3e61ad0474d89546938780b8dc9..a9d0ebfe81e30e13220393c00702b7ea3f30d601
@@@ -585,296 -585,298 +585,305 @@@ int otyp
  boolean init;
  boolean artif;
  {
-       int mndx, tryct;
-       struct obj *otmp;
-       char let = objects[otyp].oc_class;
-       otmp = newobj();
-       *otmp = zeroobj;
-       otmp->age = monstermoves;
-       otmp->o_id = context.ident++;
-       if (!otmp->o_id) otmp->o_id = context.ident++;  /* ident overflowed */
-       otmp->quan = 1L;
-       otmp->oclass = let;
-       otmp->otyp = otyp;
-       otmp->where = OBJ_FREE;
-       otmp->dknown = index(dknowns, let) ? 0 : 1;
-       if ((otmp->otyp >= ELVEN_SHIELD && otmp->otyp <= ORCISH_SHIELD) ||
-                       otmp->otyp == SHIELD_OF_REFLECTION)
-               otmp->dknown = 0;
-       if (!objects[otmp->otyp].oc_uses_known)
-               otmp->known = 1;
-       otmp->lknown = 0;
-       otmp->cknown = 0;
-       otmp->corpsenm = NON_PM;
-       if (init) switch (let) {
-       case WEAPON_CLASS:
-               otmp->quan = is_multigen(otmp) ? (long) rn1(6,6) : 1L;
-               if(!rn2(11)) {
-                       otmp->spe = rne(3);
-                       otmp->blessed = rn2(2);
-               } else if(!rn2(10)) {
-                       curse(otmp);
-                       otmp->spe = -rne(3);
-               } else  blessorcurse(otmp, 10);
-               if (is_poisonable(otmp) && !rn2(100))
-                       otmp->opoisoned = 1;
-               if (artif && !rn2(20))
-                   otmp = mk_artifact(otmp, (aligntyp)A_NONE);
-               break;
-       case FOOD_CLASS:
-           otmp->oeaten = 0;
-           switch(otmp->otyp) {
-           case CORPSE:
-               /* possibly overridden by mkcorpstat() */
-               tryct = 50;
-               do otmp->corpsenm = undead_to_corpse(rndmonnum());
-               while ((mvitals[otmp->corpsenm].mvflags & G_NOCORPSE) && (--tryct > 0));
-               if (tryct == 0) {
-               /* perhaps rndmonnum() only wants to make G_NOCORPSE monsters on
-                  this level; let's create an adventurer's corpse instead, then */
-                       otmp->corpsenm = PM_HUMAN;
-               }
-               /* timer set below */
-               break;
-           case EGG:
-               otmp->corpsenm = NON_PM;        /* generic egg */
-               if (!rn2(3)) for (tryct = 200; tryct > 0; --tryct) {
-                   mndx = can_be_hatched(rndmonnum());
-                   if (mndx != NON_PM && !dead_species(mndx, TRUE)) {
-                       otmp->corpsenm = mndx;          /* typed egg */
-                       break;
-                   }
-               }
-               /* timer set below */
-               break;
-           case TIN:
-               otmp->corpsenm = NON_PM;        /* empty (so far) */
-               if (!rn2(6))
-                   set_tin_variety(otmp, SPINACH_TIN);
-               else for (tryct = 200; tryct > 0; --tryct) {
-                   mndx = undead_to_corpse(rndmonnum());
-                   if (mons[mndx].cnutrit &&
-                           !(mvitals[mndx].mvflags & G_NOCORPSE)) {
-                       otmp->corpsenm = mndx;
-                       set_tin_variety(otmp, RANDOM_TIN);
-                       break;
-                   }
-               }
-               blessorcurse(otmp, 10);
-               break;
-           case SLIME_MOLD:
-               otmp->spe = context.current_fruit;
-               flags.made_fruit = TRUE;
-               break;
-           case KELP_FROND:
-               otmp->quan = (long) rnd(2);
-               break;
-           }
-           if (otmp->otyp != CORPSE && otmp->otyp != MEAT_RING &&
-                   otmp->otyp != KELP_FROND && !rn2(6))
-               otmp->quan = 2L;
-           break;
-       case GEM_CLASS:
-               otmp->corpsenm = 0;     /* LOADSTONE hack */
-               if (otmp->otyp == LOADSTONE) curse(otmp);
-               else if (otmp->otyp == ROCK) otmp->quan = (long) rn1(6,6);
-               else if (otmp->otyp != LUCKSTONE && !rn2(6)) otmp->quan = 2L;
-               else otmp->quan = 1L;
-               break;
-       case TOOL_CLASS:
-           switch(otmp->otyp) {
-               case TALLOW_CANDLE:
-               case WAX_CANDLE:        otmp->spe = 1;
-                                       otmp->age = 20L * /* 400 or 200 */
-                                             (long)objects[otmp->otyp].oc_cost;
-                                       otmp->lamplit = 0;
-                                       otmp->quan = 1L +
-                                             (long)(rn2(2) ? rn2(7) : 0);
-                                       blessorcurse(otmp, 5);
-                                       break;
-               case BRASS_LANTERN:
-               case OIL_LAMP:          otmp->spe = 1;
-                                       otmp->age = (long) rn1(500,1000);
-                                       otmp->lamplit = 0;
-                                       blessorcurse(otmp, 5);
-                                       break;
-               case MAGIC_LAMP:        otmp->spe = 1;
-                                       otmp->lamplit = 0;
-                                       blessorcurse(otmp, 2);
-                                       break;
-               case CHEST:
-               case LARGE_BOX:         otmp->olocked = !!(rn2(5));
-                                       otmp->otrapped = !(rn2(10));
-               case ICE_BOX:
-               case SACK:
-               case OILSKIN_SACK:
-               case BAG_OF_HOLDING:    mkbox_cnts(otmp);
-                                       break;
-               case LEASH:             otmp->leashmon = 0;
-                                       break;
-               case EXPENSIVE_CAMERA:
-               case TINNING_KIT:
-               case MAGIC_MARKER:      otmp->spe = rn1(70,30);
-                                       break;
-               case CAN_OF_GREASE:     otmp->spe = rnd(25);
-                                       blessorcurse(otmp, 10);
-                                       break;
-               case CRYSTAL_BALL:      otmp->spe = rnd(5);
-                                       blessorcurse(otmp, 2);
-                                       break;
-               case HORN_OF_PLENTY:
-               case BAG_OF_TRICKS:     otmp->spe = rnd(20);
-                                       break;
-               case FIGURINE:  {       int tryct2 = 0;
-                                       do
-                                           otmp->corpsenm = rndmonnum();
-                                       while(is_human(&mons[otmp->corpsenm])
-                                               && tryct2++ < 30);
-                                       blessorcurse(otmp, 4);
-                                       break;
-                               }
-               case BELL_OF_OPENING:   otmp->spe = 3;
-                                       break;
-               case MAGIC_FLUTE:
-               case MAGIC_HARP:
-               case FROST_HORN:
-               case FIRE_HORN:
-               case DRUM_OF_EARTHQUAKE:
-                                       otmp->spe = rn1(5,4);
-                                       break;
-           }
-           break;
-       case AMULET_CLASS:
-               if (otmp->otyp == AMULET_OF_YENDOR) context.made_amulet = TRUE;
-               if(rn2(10) && (otmp->otyp == AMULET_OF_STRANGULATION ||
-                  otmp->otyp == AMULET_OF_CHANGE ||
-                  otmp->otyp == AMULET_OF_RESTFUL_SLEEP)) {
-                       curse(otmp);
-               } else  blessorcurse(otmp, 10);
-       case VENOM_CLASS:
-       case CHAIN_CLASS:
-       case BALL_CLASS:
-               break;
-       case POTION_CLASS:
-               otmp->fromsink = 0;
-               if (otmp->otyp == POT_OIL)
-                   otmp->age = MAX_OIL_IN_FLASK;       /* amount of oil */
-               /* fall through */
-       case SCROLL_CLASS:
+     int mndx, tryct;
+     struct obj *otmp;
+     char let = objects[otyp].oc_class;
+     otmp = newobj();
+     *otmp = zeroobj;
+     otmp->age = monstermoves;
+     otmp->o_id = context.ident++;
+     if (!otmp->o_id) otmp->o_id = context.ident++;    /* ident overflowed */
+     otmp->quan = 1L;
+     otmp->oclass = let;
+     otmp->otyp = otyp;
+     otmp->where = OBJ_FREE;
+     otmp->dknown = index(dknowns, let) ? 0 : 1;
+     if ((otmp->otyp >= ELVEN_SHIELD && otmp->otyp <= ORCISH_SHIELD) ||
+             otmp->otyp == SHIELD_OF_REFLECTION)
+         otmp->dknown = 0;
+     if (!objects[otmp->otyp].oc_uses_known)
+         otmp->known = 1;
+     otmp->lknown = 0;
+     otmp->cknown = 0;
+     otmp->corpsenm = NON_PM;
+     if (init) switch (let) {
+     case WEAPON_CLASS:
+         otmp->quan = is_multigen(otmp) ? (long) rn1(6,6) : 1L;
+         if(!rn2(11)) {
+             otmp->spe = rne(3);
+             otmp->blessed = rn2(2);
+         } else if(!rn2(10)) {
+             curse(otmp);
+             otmp->spe = -rne(3);
+         } else        blessorcurse(otmp, 10);
+         if (is_poisonable(otmp) && !rn2(100))
+             otmp->opoisoned = 1;
+         if (artif && !rn2(20))
+             otmp = mk_artifact(otmp, (aligntyp)A_NONE);
+         break;
+     case FOOD_CLASS:
+         otmp->oeaten = 0;
+         switch(otmp->otyp) {
+             case CORPSE:
+                 /* possibly overridden by mkcorpstat() */
+                 tryct = 50;
+                 do otmp->corpsenm = undead_to_corpse(rndmonnum());
+                 while ((mvitals[otmp->corpsenm].mvflags & G_NOCORPSE) && (--tryct > 0));
+                 if (tryct == 0) {
+                     /* perhaps rndmonnum() only wants to make G_NOCORPSE monsters on
+                        this level; let's create an adventurer's corpse instead, then */
+                     otmp->corpsenm = PM_HUMAN;
+                 }
+                 /* timer set below */
+                 break;
+             case EGG:
+                 otmp->corpsenm = NON_PM;      /* generic egg */
+                 if (!rn2(3)) for (tryct = 200; tryct > 0; --tryct) {
+                     mndx = can_be_hatched(rndmonnum());
+                     if (mndx != NON_PM && !dead_species(mndx, TRUE)) {
+                         otmp->corpsenm = mndx;                /* typed egg */
+                         break;
+                     }
+                 }
+                 /* timer set below */
+                 break;
+             case TIN:
+                 otmp->corpsenm = NON_PM;      /* empty (so far) */
+                 if (!rn2(6))
+                     set_tin_variety(otmp, SPINACH_TIN);
+                 else for (tryct = 200; tryct > 0; --tryct) {
+                     mndx = undead_to_corpse(rndmonnum());
+                     if (mons[mndx].cnutrit &&
+                             !(mvitals[mndx].mvflags & G_NOCORPSE)) {
+                         otmp->corpsenm = mndx;
+                         set_tin_variety(otmp, RANDOM_TIN);
+                         break;
+                     }
+                 }
+                 blessorcurse(otmp, 10);
+                 break;
+             case SLIME_MOLD:
+                 otmp->spe = context.current_fruit;
+                 flags.made_fruit = TRUE;
+                 break;
+             case KELP_FROND:
+                 otmp->quan = (long) rnd(2);
+                 break;
+         }
+         if (Is_pudding(otmp)) {
+             otmp->globby = 1;
+             otmp->known = otmp->bknown = otmp->rknown = otmp->dknown = 1;
+             otmp->corpsenm = PM_GRAY_OOZE + (otmp->otyp - GLOB_OF_GRAY_OOZE);
+             /* this ensures that they don't fail merging because of
+              * BUC status or other irrelevancies */
+         } else {
+             if (otmp->otyp != CORPSE && otmp->otyp != MEAT_RING
+                     && otmp->otyp != KELP_FROND && !rn2(6)) {
+                 otmp->quan = 2L;
+             }
+         }
+         break;
+     case GEM_CLASS:
+         otmp->corpsenm = 0;   /* LOADSTONE hack */
+         if (otmp->otyp == LOADSTONE) curse(otmp);
+         else if (otmp->otyp == ROCK) otmp->quan = (long) rn1(6,6);
+         else if (otmp->otyp != LUCKSTONE && !rn2(6)) otmp->quan = 2L;
+         else otmp->quan = 1L;
+         break;
+     case TOOL_CLASS:
+         switch(otmp->otyp) {
+         case TALLOW_CANDLE:
+         case WAX_CANDLE:      otmp->spe = 1;
+                     otmp->age = 20L * /* 400 or 200 */
+                           (long)objects[otmp->otyp].oc_cost;
+                     otmp->lamplit = 0;
+                     otmp->quan = 1L +
+                           (long)(rn2(2) ? rn2(7) : 0);
+                     blessorcurse(otmp, 5);
+                     break;
+         case BRASS_LANTERN:
+         case OIL_LAMP:                otmp->spe = 1;
+                     otmp->age = (long) rn1(500,1000);
+                     otmp->lamplit = 0;
+                     blessorcurse(otmp, 5);
+                     break;
+         case MAGIC_LAMP:      otmp->spe = 1;
+                     otmp->lamplit = 0;
+                     blessorcurse(otmp, 2);
+                     break;
+         case CHEST:
+         case LARGE_BOX:               otmp->olocked = !!(rn2(5));
+                     otmp->otrapped = !(rn2(10));
+         case ICE_BOX:
+         case SACK:
+         case OILSKIN_SACK:
+         case BAG_OF_HOLDING:  mkbox_cnts(otmp);
+                     break;
+         case LEASH:           otmp->leashmon = 0;
+                     break;
+         case EXPENSIVE_CAMERA:
+         case TINNING_KIT:
+         case MAGIC_MARKER:    otmp->spe = rn1(70,30);
+                     break;
+         case CAN_OF_GREASE:   otmp->spe = rnd(25);
+                     blessorcurse(otmp, 10);
+                     break;
+         case CRYSTAL_BALL:    otmp->spe = rnd(5);
+                     blessorcurse(otmp, 2);
+                     break;
+         case HORN_OF_PLENTY:
+         case BAG_OF_TRICKS:   otmp->spe = rnd(20);
+                     break;
+         case FIGURINE:        {       int tryct2 = 0;
+                     do
+                         otmp->corpsenm = rndmonnum();
+                     while(is_human(&mons[otmp->corpsenm])
+                         && tryct2++ < 30);
+                     blessorcurse(otmp, 4);
+                     break;
+                 }
+         case BELL_OF_OPENING:   otmp->spe = 3;
+                     break;
+         case MAGIC_FLUTE:
+         case MAGIC_HARP:
+         case FROST_HORN:
+         case FIRE_HORN:
+         case DRUM_OF_EARTHQUAKE:
+                     otmp->spe = rn1(5,4);
+                     break;
+         }
+         break;
+     case AMULET_CLASS:
+         if (otmp->otyp == AMULET_OF_YENDOR) context.made_amulet = TRUE;
+         if(rn2(10) && (otmp->otyp == AMULET_OF_STRANGULATION ||
+            otmp->otyp == AMULET_OF_CHANGE ||
+            otmp->otyp == AMULET_OF_RESTFUL_SLEEP)) {
+             curse(otmp);
+         } else        blessorcurse(otmp, 10);
+     case VENOM_CLASS:
+     case CHAIN_CLASS:
+     case BALL_CLASS:
+         break;
+     case POTION_CLASS:
+         otmp->fromsink = 0;
+         if (otmp->otyp == POT_OIL)
+             otmp->age = MAX_OIL_IN_FLASK;     /* amount of oil */
+         /* fall through */
+     case SCROLL_CLASS:
  #ifdef MAIL
-               if (otmp->otyp != SCR_MAIL)
+         if (otmp->otyp != SCR_MAIL)
  #endif
-                       blessorcurse(otmp, 4);
-               break;
-       case SPBOOK_CLASS:
-               otmp->spestudied = 0;
-               blessorcurse(otmp, 17);
-               break;
-       case ARMOR_CLASS:
-               if(rn2(10) && (otmp->otyp == FUMBLE_BOOTS ||
-                  otmp->otyp == LEVITATION_BOOTS ||
-                  otmp->otyp == HELM_OF_OPPOSITE_ALIGNMENT ||
-                  otmp->otyp == GAUNTLETS_OF_FUMBLING ||
-                  !rn2(11))) {
-                       curse(otmp);
-                       otmp->spe = -rne(3);
-               } else if(!rn2(10)) {
-                       otmp->blessed = rn2(2);
-                       otmp->spe = rne(3);
-               } else  blessorcurse(otmp, 10);
-               if (artif && !rn2(40))                
-                   otmp = mk_artifact(otmp, (aligntyp)A_NONE);
-               /* simulate lacquered armor for samurai */
-               if (Role_if(PM_SAMURAI) && otmp->otyp == SPLINT_MAIL &&
-                   (moves <= 1 || In_quest(&u.uz))) {
+             blessorcurse(otmp, 4);
+         break;
+     case SPBOOK_CLASS:
+         otmp->spestudied = 0;
+         blessorcurse(otmp, 17);
+         break;
+     case ARMOR_CLASS:
+         if(rn2(10) && (otmp->otyp == FUMBLE_BOOTS ||
+            otmp->otyp == LEVITATION_BOOTS ||
+            otmp->otyp == HELM_OF_OPPOSITE_ALIGNMENT ||
+            otmp->otyp == GAUNTLETS_OF_FUMBLING ||
+            !rn2(11))) {
+             curse(otmp);
+             otmp->spe = -rne(3);
+         } else if(!rn2(10)) {
+             otmp->blessed = rn2(2);
+             otmp->spe = rne(3);
+         } else        blessorcurse(otmp, 10);
+         if (artif && !rn2(40))                
+             otmp = mk_artifact(otmp, (aligntyp)A_NONE);
+         /* simulate lacquered armor for samurai */
+         if (Role_if(PM_SAMURAI) && otmp->otyp == SPLINT_MAIL &&
+             (moves <= 1 || In_quest(&u.uz))) {
  #ifdef UNIXPC
-                       /* optimizer bitfield bug */
-                       otmp->oerodeproof = 1;
-                       otmp->rknown = 1;
+             /* optimizer bitfield bug */
+             otmp->oerodeproof = 1;
+             otmp->rknown = 1;
  #else
-                       otmp->oerodeproof = otmp->rknown = 1;
+             otmp->oerodeproof = otmp->rknown = 1;
  #endif
-               }
-               break;
-       case WAND_CLASS:
-               if(otmp->otyp == WAN_WISHING) otmp->spe = rnd(3); else
-               otmp->spe = rn1(5,
-                       (objects[otmp->otyp].oc_dir == NODIR) ? 11 : 4);
-               blessorcurse(otmp, 17);
-               otmp->recharged = 0; /* used to control recharging */
-               break;
-       case RING_CLASS:
-               if(objects[otmp->otyp].oc_charged) {
-                   blessorcurse(otmp, 3);
-                   if(rn2(10)) {
-                       if(rn2(10) && bcsign(otmp))
-                           otmp->spe = bcsign(otmp) * rne(3);
-                       else otmp->spe = rn2(2) ? rne(3) : -rne(3);
-                   }
-                   /* make useless +0 rings much less common */
-                   if (otmp->spe == 0) otmp->spe = rn2(4) - rn2(3);
-                   /* negative rings are usually cursed */
-                   if (otmp->spe < 0 && rn2(5)) curse(otmp);
-               } else if(rn2(10) && (otmp->otyp == RIN_TELEPORTATION ||
-                         otmp->otyp == RIN_POLYMORPH ||
-                         otmp->otyp == RIN_AGGRAVATE_MONSTER ||
-                         otmp->otyp == RIN_HUNGER || !rn2(9))) {
-                       curse(otmp);
-               }
-               break;
-       case ROCK_CLASS:
-               switch (otmp->otyp) {
-                   case STATUE:
-                       /* possibly overridden by mkcorpstat() */
-                       otmp->corpsenm = rndmonnum();
-                       if (!verysmall(&mons[otmp->corpsenm]) &&
-                               rn2(level_difficulty()/2 + 10) > 10)
-                           (void) add_to_container(otmp,
-                                                   mkobj(SPBOOK_CLASS,FALSE));
-               }
-               break;
-       case COIN_CLASS:
-               break;  /* do nothing */
-       default:
-               impossible("impossible mkobj %d, sym '%c'.", otmp->otyp,
-                                               objects[otmp->otyp].oc_class);
-               return (struct obj *)0;
-       }
-       /* some things must get done (corpsenm, timers) even if init = 0 */
-       switch (otmp->otyp) {
-           case CORPSE:
-               if (otmp->corpsenm == NON_PM) {
-                   otmp->corpsenm = undead_to_corpse(rndmonnum());
-                   if (mvitals[otmp->corpsenm].mvflags & (G_NOCORPSE|G_GONE))
-                       otmp->corpsenm = urole.malenum;
-               }
-               /*FALLTHRU*/
-           case STATUE:
-           case FIGURINE:
-               if (otmp->corpsenm == NON_PM) otmp->corpsenm = rndmonnum();
-               /*FALLTHRU*/
-           case EGG:
-        /* case TIN: */
-               set_corpsenm(otmp, otmp->corpsenm);
-               break;
+         }
+         break;
+     case WAND_CLASS:
+         if(otmp->otyp == WAN_WISHING) otmp->spe = rnd(3); else
+         otmp->spe = rn1(5,
+             (objects[otmp->otyp].oc_dir == NODIR) ? 11 : 4);
+         blessorcurse(otmp, 17);
+         otmp->recharged = 0; /* used to control recharging */
+         break;
+     case RING_CLASS:
+         if(objects[otmp->otyp].oc_charged) {
+             blessorcurse(otmp, 3);
+             if(rn2(10)) {
+             if(rn2(10) && bcsign(otmp))
+                 otmp->spe = bcsign(otmp) * rne(3);
+             else otmp->spe = rn2(2) ? rne(3) : -rne(3);
+             }
+             /* make useless +0 rings much less common */
+             if (otmp->spe == 0) otmp->spe = rn2(4) - rn2(3);
+             /* negative rings are usually cursed */
+             if (otmp->spe < 0 && rn2(5)) curse(otmp);
+         } else if(rn2(10) && (otmp->otyp == RIN_TELEPORTATION ||
+               otmp->otyp == RIN_POLYMORPH ||
+               otmp->otyp == RIN_AGGRAVATE_MONSTER ||
+               otmp->otyp == RIN_HUNGER || !rn2(9))) {
+             curse(otmp);
+         }
+         break;
+     case ROCK_CLASS:
+         switch (otmp->otyp) {
+             case STATUE:
+             /* possibly overridden by mkcorpstat() */
+             otmp->corpsenm = rndmonnum();
+             if (!verysmall(&mons[otmp->corpsenm]) &&
+                 rn2(level_difficulty()/2 + 10) > 10)
+                 (void) add_to_container(otmp,
+                             mkobj(SPBOOK_CLASS,FALSE));
+         }
+         break;
+     case COIN_CLASS:
+         break;        /* do nothing */
+     default:
+         impossible("impossible mkobj %d, sym '%c'.", otmp->otyp,
+                         objects[otmp->otyp].oc_class);
+         return (struct obj *)0;
+     }
+     /* some things must get done (corpsenm, timers) even if init = 0 */
+     switch (otmp->otyp) {
+         case CORPSE:
+         if (otmp->corpsenm == NON_PM) {
+             otmp->corpsenm = undead_to_corpse(rndmonnum());
+             if (mvitals[otmp->corpsenm].mvflags & (G_NOCORPSE|G_GONE))
+             otmp->corpsenm = urole.malenum;
+         }
+         /*FALLTHRU*/
+         case STATUE:
+         case FIGURINE:
+         if (otmp->corpsenm == NON_PM) otmp->corpsenm = rndmonnum();
+         /*FALLTHRU*/
+         case EGG:
+      /* case TIN: */
+         set_corpsenm(otmp, otmp->corpsenm);
+         break;
 +          case SPE_NOVEL:
 +              {
 +                  int novidx = -1;
 +                  otmp = oname(otmp, noveltitle(&novidx));
 +                  otmp->novelidx = novidx;
 +              }
 +              break;
-       }
+     }
  
-       /* unique objects may have an associated artifact entry */
-       if (objects[otyp].oc_unique && !otmp->oartifact)
-           otmp = mk_artifact(otmp, (aligntyp)A_NONE);
-       otmp->owt = weight(otmp);
-       return(otmp);
+     /* unique objects may have an associated artifact entry */
+     if (objects[otyp].oc_unique && !otmp->oartifact)
+         otmp = mk_artifact(otmp, (aligntyp)A_NONE);
+     otmp->owt = weight(otmp);
+     return(otmp);
  }
  
  /*
diff --cc src/mon.c
index 5427f8da48f7bf44b70c50d3f6b62586e50fe674,93fef1b0c030a70afb86fc2fe4306f5a7bc3215d..856b97b991a029b81039b9f9bd33a45a47464254
+++ b/src/mon.c
  mondead(mtmp)
  register struct monst *mtmp;
  {
-       struct permonst *mptr;
-       int tmp;
-       lifesaved_monster(mtmp);
-       if (mtmp->mhp > 0) return;
-       if (is_vampshifter(mtmp)) {
-               int mndx = mtmp->cham;
-               int x = mtmp->mx, y = mtmp->my;
-               /* this only happens if shapeshifted */
-               if (mndx >= LOW_PM && mndx != monsndx(mtmp->data)) {
-                       char buf[BUFSZ];
-                       boolean in_door = amorphous(mtmp->data) &&
-                                        closed_door(mtmp->mx,mtmp->my);
-                       Sprintf(buf,
-                               "The %s%s suddenly %s and rises as %%s!",
-                               (nonliving(mtmp->data) ||
-                                noncorporeal(mtmp->data) ||
-                                amorphous(mtmp->data)) ? "" : "seemingly dead ",
-                               x_monnam(mtmp, ARTICLE_NONE, (char *)0, 
-                                   SUPPRESS_SADDLE | SUPPRESS_HALLUCINATION |
-                                   SUPPRESS_INVISIBLE | SUPPRESS_IT, FALSE),
-                               (nonliving(mtmp->data) ||
-                                noncorporeal(mtmp->data) ||
-                                amorphous(mtmp->data)) ?
-                               "reconstitutes" : "transforms");
-                       mtmp->mcanmove = 1;
-                       mtmp->mfrozen = 0;
-                       if (mtmp->mhpmax <= 0) mtmp->mhpmax = 10;
-                       mtmp->mhp = mtmp->mhpmax;
-                       /* this can happen if previously a fog cloud */
-                       if (u.uswallow && (mtmp == u.ustuck))
-                               expels(mtmp, mtmp->data, FALSE);
-                       if (in_door) {
-                               coord new_xy;
-                               if (enexto(&new_xy,
-                                           mtmp->mx, mtmp->my, &mons[mndx])) {
-                                       rloc_to(mtmp, new_xy.x, new_xy.y);
-                               }
-                       }
-                       newcham(mtmp, &mons[mndx], FALSE, FALSE);
-                       if (mtmp->data == &mons[mndx])
-                               mtmp->cham = NON_PM;
-                       else
-                               mtmp->cham = mndx;
-                       if ((!Blind && canseemon(mtmp)) || sensemon(mtmp))
-                               pline(buf, a_monnam(mtmp));
-                       newsym(x,y);
-                       return;
-               }
-       }
-       /* dead vault guard is actually kept at coordinate <0,0> until
-          his temporary corridor to/from the vault has been removed;
-          need to do this after life-saving and before m_detach() */
-       if (mtmp->isgd && !grddead(mtmp)) return;
-       /* Player is thrown from his steed when it dies */
-       if (mtmp == u.usteed)
-               dismount_steed(DISMOUNT_GENERIC);
-       mptr = mtmp->data;              /* save this for m_detach() */
-       /* restore chameleon, lycanthropes to true form at death */
-       if (mtmp->cham >= LOW_PM) {
-           set_mon_data(mtmp, &mons[mtmp->cham], -1);
-           mtmp->cham = NON_PM;
-       }
-       else if (mtmp->data == &mons[PM_WEREJACKAL])
-           set_mon_data(mtmp, &mons[PM_HUMAN_WEREJACKAL], -1);
-       else if (mtmp->data == &mons[PM_WEREWOLF])
-           set_mon_data(mtmp, &mons[PM_HUMAN_WEREWOLF], -1);
-       else if (mtmp->data == &mons[PM_WERERAT])
-           set_mon_data(mtmp, &mons[PM_HUMAN_WERERAT], -1);
-       /* if MAXMONNO monsters of a given type have died, and it
-        * can be done, extinguish that monster.
-        *
-        * mvitals[].died does double duty as total number of dead monsters
-        * and as experience factor for the player killing more monsters.
-        * this means that a dragon dying by other means reduces the
-        * experience the player gets for killing a dragon directly; this
-        * is probably not too bad, since the player likely finagled the
-        * first dead dragon via ring of conflict or pets, and extinguishing
-        * based on only player kills probably opens more avenues of abuse
-        * for rings of conflict and such.
-        */
-       tmp = monsndx(mtmp->data);
-       if (mvitals[tmp].died < 255) mvitals[tmp].died++;
-       /* if it's a (possibly polymorphed) quest leader, mark him as dead */
-       if (mtmp->m_id == quest_status.leader_m_id)
-           quest_status.leader_is_dead = TRUE;
+     struct permonst *mptr;
+     int tmp;
+     lifesaved_monster(mtmp);
+     if (mtmp->mhp > 0) return;
+     if (is_vampshifter(mtmp)) {
+         int mndx = mtmp->cham;
+         int x = mtmp->mx, y = mtmp->my;
+         /* this only happens if shapeshifted */
+         if (mndx >= LOW_PM && mndx != monsndx(mtmp->data)) {
+             char buf[BUFSZ];
+             boolean in_door = amorphous(mtmp->data) &&
+                      closed_door(mtmp->mx,mtmp->my);
+             Sprintf(buf,
+                 "The %s%s suddenly %s and rises as %%s!",
+                 (nonliving(mtmp->data) ||
+                  noncorporeal(mtmp->data) ||
+                  amorphous(mtmp->data)) ? "" : "seemingly dead ",
+                     x_monnam(mtmp, ARTICLE_NONE, (char *)0, 
+                         SUPPRESS_SADDLE | SUPPRESS_HALLUCINATION |
+                     SUPPRESS_INVISIBLE | SUPPRESS_IT, FALSE),
+                 (nonliving(mtmp->data) ||
+                  noncorporeal(mtmp->data) ||
+                  amorphous(mtmp->data)) ?
+                 "reconstitutes" : "transforms");
+             mtmp->mcanmove = 1;
+             mtmp->mfrozen = 0;
+             if (mtmp->mhpmax <= 0) mtmp->mhpmax = 10;
+             mtmp->mhp = mtmp->mhpmax;
+             /* this can happen if previously a fog cloud */
+             if (u.uswallow && (mtmp == u.ustuck))
+                 expels(mtmp, mtmp->data, FALSE);
+             if (in_door) {
+                 coord new_xy;
+                 if (enexto(&new_xy,
+                         mtmp->mx, mtmp->my, &mons[mndx])) {
+                     rloc_to(mtmp, new_xy.x, new_xy.y);
+                 }
+             }
+             newcham(mtmp, &mons[mndx], FALSE, FALSE);
+             if (mtmp->data == &mons[mndx])
+                 mtmp->cham = NON_PM;
+             else
+                 mtmp->cham = mndx;
+             if ((!Blind && canseemon(mtmp)) || sensemon(mtmp))
+                 pline(buf, a_monnam(mtmp));
+             newsym(x,y);
+             return;
+         }
+     }
+     /* dead vault guard is actually kept at coordinate <0,0> until
+        his temporary corridor to/from the vault has been removed;
+        need to do this after life-saving and before m_detach() */
+     if (mtmp->isgd && !grddead(mtmp)) return;
+     /* Player is thrown from his steed when it dies */
+     if (mtmp == u.usteed)
+         dismount_steed(DISMOUNT_GENERIC);
+     mptr = mtmp->data;                /* save this for m_detach() */
+     /* restore chameleon, lycanthropes to true form at death */
+     if (mtmp->cham >= LOW_PM) {
+         set_mon_data(mtmp, &mons[mtmp->cham], -1);
+         mtmp->cham = NON_PM;
+     }
+     else if (mtmp->data == &mons[PM_WEREJACKAL])
+         set_mon_data(mtmp, &mons[PM_HUMAN_WEREJACKAL], -1);
+     else if (mtmp->data == &mons[PM_WEREWOLF])
+         set_mon_data(mtmp, &mons[PM_HUMAN_WEREWOLF], -1);
+     else if (mtmp->data == &mons[PM_WERERAT])
+         set_mon_data(mtmp, &mons[PM_HUMAN_WERERAT], -1);
+     /* if MAXMONNO monsters of a given type have died, and it
+      * can be done, extinguish that monster.
+      *
+      * mvitals[].died does double duty as total number of dead monsters
+      * and as experience factor for the player killing more monsters.
+      * this means that a dragon dying by other means reduces the
+      * experience the player gets for killing a dragon directly; this
+      * is probably not too bad, since the player likely finagled the
+      * first dead dragon via ring of conflict or pets, and extinguishing
+      * based on only player kills probably opens more avenues of abuse
+      * for rings of conflict and such.
+      */
+     tmp = monsndx(mtmp->data);
+     if (mvitals[tmp].died < 255) mvitals[tmp].died++;
+     /* if it's a (possibly polymorphed) quest leader, mark him as dead */
+     if (mtmp->m_id == quest_status.leader_m_id)
+         quest_status.leader_is_dead = TRUE;
  #ifdef MAIL
-       /* if the mail daemon dies, no more mail delivery.  -3. */
-       if (tmp == PM_MAIL_DAEMON) mvitals[tmp].mvflags |= G_GENOD;
+     /* if the mail daemon dies, no more mail delivery.  -3. */
+     if (tmp == PM_MAIL_DAEMON) mvitals[tmp].mvflags |= G_GENOD;
  #endif
  
-       if (mtmp->data->mlet == S_KOP) {
-           /* Dead Kops may come back. */
-           switch(rnd(5)) {
-               case 1:      /* returns near the stairs */
-                       (void) makemon(mtmp->data,xdnstair,ydnstair,NO_MM_FLAGS);
-                       break;
-               case 2:      /* randomly */
-                       (void) makemon(mtmp->data,0,0,NO_MM_FLAGS);
-                       break;
-               default:
-                       break;
-           }
-       }
-       if(mtmp->iswiz) wizdead();
-       if(mtmp->data->msound == MS_NEMESIS) nemdead();
-       if(glyph_is_invisible(levl[mtmp->mx][mtmp->my].glyph))
-           unmap_object(mtmp->mx, mtmp->my);
-       m_detach(mtmp, mptr);
+     if (mtmp->data->mlet == S_KOP) {
+         /* Dead Kops may come back. */
+         switch(rnd(5)) {
+         case 1:            /* returns near the stairs */
+             (void) makemon(mtmp->data,xdnstair,ydnstair,NO_MM_FLAGS);
+             break;
+         case 2:            /* randomly */
+             (void) makemon(mtmp->data,0,0,NO_MM_FLAGS);
+             break;
+         default:
+             break;
+         }
+     }
+     if(mtmp->iswiz) wizdead();
+     if(mtmp->data->msound == MS_NEMESIS) nemdead();
 -        if(mtmp->data == &mons[PM_MEDUSA])
 -            u.uachieve.killed_medusa = 1;
+     if(glyph_is_invisible(levl[mtmp->mx][mtmp->my].glyph))
+         unmap_object(mtmp->mx, mtmp->my);
+     m_detach(mtmp, mptr);
  }
  
  /* TRUE if corpse might be dropped, magr may die if mon was swallowed */
diff --cc src/objects.c
Simple merge
diff --cc src/objnam.c
index 1f99308031faf10af5fc9a5c389d78126cbb768e,a0db8c6817c502fdd25c9b13d796e90ade2ae2cb..3c5580c0d3dae16f71e366f08a4e937f3d46aba9
@@@ -249,267 -248,263 +248,274 @@@ xname_flags(obj, cxn_flags
  register struct obj *obj;
  unsigned cxn_flags;   /* bitmask of CXN_xxx values */
  {
-       register char *buf;
-       register int typ = obj->otyp;
-       register struct objclass *ocl = &objects[typ];
-       int nn = ocl->oc_name_known, omndx = obj->corpsenm;
-       const char *actualn = OBJ_NAME(*ocl);
-       const char *dn = OBJ_DESCR(*ocl);
-       const char *un = ocl->oc_uname;
+     register char *buf;
+     register int typ = obj->otyp;
+     register struct objclass *ocl = &objects[typ];
+     int nn = ocl->oc_name_known, omndx = obj->corpsenm;
+     const char *actualn = OBJ_NAME(*ocl);
+     const char *dn = OBJ_DESCR(*ocl);
+     const char *un = ocl->oc_uname;
        boolean pluralize = (obj->quan != 1L) && !(cxn_flags & CXN_SINGULAR);
-       boolean known, dknown, bknown;
-       buf = nextobuf() + PREFIX;      /* leave room for "17 -3 " */
-       if (Role_if(PM_SAMURAI) && Japanese_item_name(typ))
-               actualn = Japanese_item_name(typ);
-       buf[0] = '\0';
-       /*
-        * clean up known when it's tied to oc_name_known, eg after AD_DRIN
-        * This is only required for unique objects since the article
-        * printed for the object is tied to the combination of the two
-        * and printing the wrong article gives away information.
-        */
-       if (!nn && ocl->oc_uses_known && ocl->oc_unique) obj->known = 0;
-       if (!Blind) obj->dknown = TRUE;
-       if (Role_if(PM_PRIEST)) obj->bknown = TRUE;
+     boolean known, dknown, bknown;
  
-       if (iflags.override_ID) {
-               known = dknown = bknown = TRUE;
-               nn = 1;
-       } else {
-               known = obj->known;
-               dknown = obj->dknown;
-               bknown = obj->bknown;
-       }
+     buf = nextobuf() + PREFIX;        /* leave room for "17 -3 " */
+     if (Role_if(PM_SAMURAI) && Japanese_item_name(typ))
+         actualn = Japanese_item_name(typ);
  
-       if (obj_is_pname(obj))
-           goto nameit;
-       switch (obj->oclass) {
-           case AMULET_CLASS:
-               if (!dknown)
-                       Strcpy(buf, "amulet");
-               else if (typ == AMULET_OF_YENDOR ||
-                        typ == FAKE_AMULET_OF_YENDOR)
-                       /* each must be identified individually */
-                       Strcpy(buf, known ? actualn : dn);
-               else if (nn)
-                       Strcpy(buf, actualn);
-               else if (un)
-                       Sprintf(buf,"amulet called %s", un);
-               else
-                       Sprintf(buf,"%s amulet", dn);
-               break;
-           case WEAPON_CLASS:
-               if (is_poisonable(obj) && obj->opoisoned)
-                       Strcpy(buf, "poisoned ");
-           case VENOM_CLASS:
-           case TOOL_CLASS:
-               if (typ == LENSES)
-                       Strcpy(buf, "pair of ");
-               if (!dknown)
-                       Strcat(buf, dn ? dn : actualn);
-               else if (nn)
-                       Strcat(buf, actualn);
-               else if (un) {
-                       Strcat(buf, dn ? dn : actualn);
-                       Strcat(buf, " called ");
-                       Strcat(buf, un);
-               } else
-                       Strcat(buf, dn ? dn : actualn);
-               /* If we use an() here we'd have to remember never to use */
-               /* it whenever calling doname() or xname(). */
-               if (typ == FIGURINE && omndx != NON_PM)
-                   Sprintf(eos(buf), " of a%s %s",
-                           index(vowels, *mons[omndx].mname) ? "n" : "",
-                           mons[omndx].mname);
-               break;
-           case ARMOR_CLASS:
-               /* depends on order of the dragon scales objects */
-               if (typ >= GRAY_DRAGON_SCALES && typ <= YELLOW_DRAGON_SCALES) {
-                       Sprintf(buf, "set of %s", actualn);
-                       break;
-               }
-               if(is_boots(obj) || is_gloves(obj)) Strcpy(buf,"pair of ");
-               if(obj->otyp >= ELVEN_SHIELD && obj->otyp <= ORCISH_SHIELD
-                               && !dknown) {
-                       Strcpy(buf, "shield");
-                       break;
-               }
-               if(obj->otyp == SHIELD_OF_REFLECTION && !dknown) {
-                       Strcpy(buf, "smooth shield");
-                       break;
-               }
+     buf[0] = '\0';
+     /*
+      * clean up known when it's tied to oc_name_known, eg after AD_DRIN
+      * This is only required for unique objects since the article
+      * printed for the object is tied to the combination of the two
+      * and printing the wrong article gives away information.
+      */
+     if (!nn && ocl->oc_uses_known && ocl->oc_unique) obj->known = 0;
+     if (!Blind) obj->dknown = TRUE;
+     if (Role_if(PM_PRIEST)) obj->bknown = TRUE;
  
-               if(nn)  Strcat(buf, actualn);
-               else if(un) {
-                       if(is_boots(obj))
-                               Strcat(buf,"boots");
-                       else if(is_gloves(obj))
-                               Strcat(buf,"gloves");
-                       else if(is_cloak(obj))
-                               Strcpy(buf,"cloak");
-                       else if(is_helmet(obj))
-                               Strcpy(buf,"helmet");
-                       else if(is_shield(obj))
-                               Strcpy(buf,"shield");
-                       else
-                               Strcpy(buf,"armor");
-                       Strcat(buf, " called ");
-                       Strcat(buf, un);
-               } else  Strcat(buf, dn);
-               break;
-           case FOOD_CLASS:
-               if (typ == SLIME_MOLD) {
-                       register struct fruit *f;
-                       for(f=ffruit; f; f = f->nextf) {
-                               if(f->fid == obj->spe) {
-                                       Strcpy(buf, f->fname);
-                                       break;
-                               }
-                       }
-                       if (!f) {
-                           impossible("Bad fruit #%d?", obj->spe);
-                           Strcpy(buf, "fruit");
-                       } else if (pluralize) {
-                           /* ick; already pluralized fruit names
-                              are allowed--we want to try to avoid
-                              adding a redundant plural suffix */
-                           Strcpy(buf, makeplural(makesingular(buf)));
-                           pluralize = FALSE;
-                       }
-                       break;
-               }
+     if (iflags.override_ID) {
+         known = dknown = bknown = TRUE;
+         nn = 1;
+     } else {
+         known = obj->known;
+         dknown = obj->dknown;
+         bknown = obj->bknown;
+     }
  
-               Strcpy(buf, actualn);
-               if (typ == TIN && known)
-                       tin_details(obj, omndx, buf);
-               break;
-           case COIN_CLASS:
-           case CHAIN_CLASS:
-               Strcpy(buf, actualn);
-               break;
-           case ROCK_CLASS:
-               if (typ == STATUE && omndx != NON_PM)
-                   Sprintf(buf, "%s%s of %s%s",
-                       (Role_if(PM_ARCHEOLOGIST) &&
-                           (obj->spe & STATUE_HISTORIC)) ? "historic " : "",
-                       actualn,
-                       type_is_pname(&mons[omndx]) ? "" :
-                         the_unique_pm(&mons[omndx]) ? "the " :
-                           index(vowels, *mons[omndx].mname) ? "an " : "a ",
-                       mons[omndx].mname);
-               else Strcpy(buf, actualn);
-               break;
-           case BALL_CLASS:
-               Sprintf(buf, "%sheavy iron ball",
-                       (obj->owt > ocl->oc_weight) ? "very " : "");
-               break;
-           case POTION_CLASS:
-               if (dknown && obj->odiluted)
-                       Strcpy(buf, "diluted ");
-               if(nn || un || !dknown) {
-                       Strcat(buf, "potion");
-                       if(!dknown) break;
-                       if(nn) {
-                           Strcat(buf, " of ");
-                           if (typ == POT_WATER &&
-                               bknown && (obj->blessed || obj->cursed)) {
-                               Strcat(buf, obj->blessed ? "holy " : "unholy ");
-                           }
-                           Strcat(buf, actualn);
-                       } else {
-                               Strcat(buf, " called ");
-                               Strcat(buf, un);
-                       }
-               } else {
-                       Strcat(buf, dn);
-                       Strcat(buf, " potion");
-               }
-               break;
-       case SCROLL_CLASS:
-               Strcpy(buf, "scroll");
-               if(!dknown) break;
-               if(nn) {
-                       Strcat(buf, " of ");
-                       Strcat(buf, actualn);
-               } else if(un) {
-                       Strcat(buf, " called ");
-                       Strcat(buf, un);
-               } else if (ocl->oc_magic) {
-                       Strcat(buf, " labeled ");
-                       Strcat(buf, dn);
-               } else {
-                       Strcpy(buf, dn);
-                       Strcat(buf, " scroll");
-               }
-               break;
-       case WAND_CLASS:
-               if(!dknown)
-                       Strcpy(buf, "wand");
-               else if(nn)
-                       Sprintf(buf, "wand of %s", actualn);
-               else if(un)
-                       Sprintf(buf, "wand called %s", un);
-               else
-                       Sprintf(buf, "%s wand", dn);
-               break;
-       case SPBOOK_CLASS:
-               if (typ == SPE_NOVEL) {         /* 3.6 tribute */
-                   if (!dknown) {
-                       Strcpy(buf, "book");
-                   } else if (nn) {
-                       Strcpy(buf, actualn);
-                   } else if (un) {
-                       Sprintf(buf, "novel called %s", un);
-                   } else
-                       Sprintf(buf, "%s book", dn);
-                   break;
-               } else
-                                               /* end of tribute */
-               if (!dknown) {
-                       Strcpy(buf, "spellbook");
-               } else if (nn) {
-                       if (typ != SPE_BOOK_OF_THE_DEAD)
-                           Strcpy(buf, "spellbook of ");
-                       Strcat(buf, actualn);
-               } else if (un) {
-                       Sprintf(buf, "spellbook called %s", un);
-               } else
-                       Sprintf(buf, "%s spellbook", dn);
-               break;
-       case RING_CLASS:
-               if(!dknown)
-                       Strcpy(buf, "ring");
-               else if(nn)
-                       Sprintf(buf, "ring of %s", actualn);
-               else if(un)
-                       Sprintf(buf, "ring called %s", un);
-               else
-                       Sprintf(buf, "%s ring", dn);
-               break;
-       case GEM_CLASS:
-           {
-               const char *rock =
-                           (ocl->oc_material == MINERAL) ? "stone" : "gem";
-               if (!dknown) {
-                   Strcpy(buf, rock);
-               } else if (!nn) {
-                   if (un) Sprintf(buf,"%s called %s", rock, un);
-                   else Sprintf(buf, "%s %s", dn, rock);
-               } else {
-                   Strcpy(buf, actualn);
-                   if (GemStone(typ)) Strcat(buf, " stone");
-               }
-               break;
-           }
-       default:
-               Sprintf(buf,"glorkum %d %d %d", obj->oclass, typ, obj->spe);
-       }
-       if (pluralize) Strcpy(buf, makeplural(buf));
+     if (obj_is_pname(obj))
+         goto nameit;
+     switch (obj->oclass) {
+         case AMULET_CLASS:
+         if (!dknown)
+             Strcpy(buf, "amulet");
+         else if (typ == AMULET_OF_YENDOR ||
+              typ == FAKE_AMULET_OF_YENDOR)
+             /* each must be identified individually */
+             Strcpy(buf, known ? actualn : dn);
+         else if (nn)
+             Strcpy(buf, actualn);
+         else if (un)
+             Sprintf(buf,"amulet called %s", un);
+         else
+             Sprintf(buf,"%s amulet", dn);
+         break;
+         case WEAPON_CLASS:
+         if (is_poisonable(obj) && obj->opoisoned)
+             Strcpy(buf, "poisoned ");
+         case VENOM_CLASS:
+         case TOOL_CLASS:
+         if (typ == LENSES)
+             Strcpy(buf, "pair of ");
+         if (!dknown)
+             Strcat(buf, dn ? dn : actualn);
+         else if (nn)
+             Strcat(buf, actualn);
+         else if (un) {
+             Strcat(buf, dn ? dn : actualn);
+             Strcat(buf, " called ");
+             Strcat(buf, un);
+         } else
+             Strcat(buf, dn ? dn : actualn);
+         /* If we use an() here we'd have to remember never to use */
+         /* it whenever calling doname() or xname(). */
+         if (typ == FIGURINE && omndx != NON_PM)
+             Sprintf(eos(buf), " of a%s %s",
+                 index(vowels, *mons[omndx].mname) ? "n" : "",
+                 mons[omndx].mname);
+         break;
+         case ARMOR_CLASS:
+         /* depends on order of the dragon scales objects */
+         if (typ >= GRAY_DRAGON_SCALES && typ <= YELLOW_DRAGON_SCALES) {
+             Sprintf(buf, "set of %s", actualn);
+             break;
+         }
+         if(is_boots(obj) || is_gloves(obj)) Strcpy(buf,"pair of ");
+         if(obj->otyp >= ELVEN_SHIELD && obj->otyp <= ORCISH_SHIELD
+                 && !dknown) {
+             Strcpy(buf, "shield");
+             break;
+         }
+         if(obj->otyp == SHIELD_OF_REFLECTION && !dknown) {
+             Strcpy(buf, "smooth shield");
+             break;
+         }
+         if(nn)        Strcat(buf, actualn);
+         else if(un) {
+             if(is_boots(obj))
+                 Strcat(buf,"boots");
+             else if(is_gloves(obj))
+                 Strcat(buf,"gloves");
+             else if(is_cloak(obj))
+                 Strcpy(buf,"cloak");
+             else if(is_helmet(obj))
+                 Strcpy(buf,"helmet");
+             else if(is_shield(obj))
+                 Strcpy(buf,"shield");
+             else
+                 Strcpy(buf,"armor");
+             Strcat(buf, " called ");
+             Strcat(buf, un);
+         } else        Strcat(buf, dn);
+         break;
+         case FOOD_CLASS:
+         if (typ == SLIME_MOLD) {
+             register struct fruit *f;
+             for(f=ffruit; f; f = f->nextf) {
+                 if(f->fid == obj->spe) {
+                     Strcpy(buf, f->fname);
+                     break;
+                 }
+             }
+             if (!f) {
+                 impossible("Bad fruit #%d?", obj->spe);
+                 Strcpy(buf, "fruit");
+             } else if (pluralize) {
+                 /* ick; already pluralized fruit names
+                    are allowed--we want to try to avoid
+                    adding a redundant plural suffix */
+                 Strcpy(buf, makeplural(makesingular(buf)));
+                 pluralize = FALSE;
+             }
+             break;
+         }
+         if (Is_pudding(obj)) {
+             Sprintf(buf, "%s%s",
+                         obj->owt < 100 ? "small " 
+                           : obj->owt > 500 ? "very large "
+                             : obj->owt > 300 ? "large "
+                               : "", actualn);
+             break;
+         }
+         Strcpy(buf, actualn);
+         if (typ == TIN && known)
+             tin_details(obj, omndx, buf);
+         break;
+         case COIN_CLASS:
+         case CHAIN_CLASS:
+         Strcpy(buf, actualn);
+         break;
+         case ROCK_CLASS:
+         if (typ == STATUE && omndx != NON_PM)
+             Sprintf(buf, "%s%s of %s%s",
+             (Role_if(PM_ARCHEOLOGIST) &&
+                 (obj->spe & STATUE_HISTORIC)) ? "historic " : "",
+             actualn,
+             type_is_pname(&mons[omndx]) ? "" :
+               the_unique_pm(&mons[omndx]) ? "the " :
+                 index(vowels, *mons[omndx].mname) ? "an " : "a ",
+             mons[omndx].mname);
+         else Strcpy(buf, actualn);
+         break;
+         case BALL_CLASS:
+         Sprintf(buf, "%sheavy iron ball",
+             (obj->owt > ocl->oc_weight) ? "very " : "");
+         break;
+         case POTION_CLASS:
+         if (dknown && obj->odiluted)
+             Strcpy(buf, "diluted ");
+         if(nn || un || !dknown) {
+             Strcat(buf, "potion");
+             if(!dknown) break;
+             if(nn) {
+                 Strcat(buf, " of ");
+                 if (typ == POT_WATER &&
+                 bknown && (obj->blessed || obj->cursed)) {
+                 Strcat(buf, obj->blessed ? "holy " : "unholy ");
+                 }
+                 Strcat(buf, actualn);
+             } else {
+                 Strcat(buf, " called ");
+                 Strcat(buf, un);
+             }
+         } else {
+             Strcat(buf, dn);
+             Strcat(buf, " potion");
+         }
+         break;
+     case SCROLL_CLASS:
+         Strcpy(buf, "scroll");
+         if(!dknown) break;
+         if(nn) {
+             Strcat(buf, " of ");
+             Strcat(buf, actualn);
+         } else if(un) {
+             Strcat(buf, " called ");
+             Strcat(buf, un);
+         } else if (ocl->oc_magic) {
+             Strcat(buf, " labeled ");
+             Strcat(buf, dn);
+         } else {
+             Strcpy(buf, dn);
+             Strcat(buf, " scroll");
+         }
+         break;
+     case WAND_CLASS:
+         if(!dknown)
+             Strcpy(buf, "wand");
+         else if(nn)
+             Sprintf(buf, "wand of %s", actualn);
+         else if(un)
+             Sprintf(buf, "wand called %s", un);
+         else
+             Sprintf(buf, "%s wand", dn);
+         break;
+     case SPBOOK_CLASS:
 -        if (!dknown) {
++        if (typ == SPE_NOVEL) {               /* 3.6 tribute */
++            if (!dknown)
++                Strcpy(buf, "book");
++          else if (nn)
++                Strcpy(buf, actualn);
++          else if (un)
++                Sprintf(buf, "novel called %s", un);
++          else
++                Sprintf(buf, "%s book", dn);
++            break;
++           /* end of tribute */
++      } else if (!dknown) {
+             Strcpy(buf, "spellbook");
+         } else if (nn) {
+             if (typ != SPE_BOOK_OF_THE_DEAD)
+                 Strcpy(buf, "spellbook of ");
+             Strcat(buf, actualn);
+         } else if (un) {
+             Sprintf(buf, "spellbook called %s", un);
+         } else
+             Sprintf(buf, "%s spellbook", dn);
+         break;
+     case RING_CLASS:
+         if(!dknown)
+             Strcpy(buf, "ring");
+         else if(nn)
+             Sprintf(buf, "ring of %s", actualn);
+         else if(un)
+             Sprintf(buf, "ring called %s", un);
+         else
+             Sprintf(buf, "%s ring", dn);
+         break;
+     case GEM_CLASS:
+         {
+         const char *rock =
+                 (ocl->oc_material == MINERAL) ? "stone" : "gem";
+         if (!dknown) {
+             Strcpy(buf, rock);
+         } else if (!nn) {
+             if (un) Sprintf(buf,"%s called %s", rock, un);
+             else Sprintf(buf, "%s %s", dn, rock);
+         } else {
+             Strcpy(buf, actualn);
+             if (GemStone(typ)) Strcat(buf, " stone");
+         }
+         break;
+         }
+     default:
+         Sprintf(buf,"glorkum %d %d %d", obj->oclass, typ, obj->spe);
+     }
+     if (pluralize) Strcpy(buf, makeplural(buf));
  
        if (obj->otyp == T_SHIRT && program_state.gameover) {
            char tmpbuf[BUFSZ];
@@@ -2447,831 -2448,825 +2459,846 @@@ struct obj *no_wish
     also, spe should always be positive  -- some cheaters may try to confuse
     atoi()
  */
-       if (spe < 0) {
-               spesgn = -1;    /* cheaters get what they deserve */
-               spe = abs(spe);
-       }
-       if (spe > SCHAR_LIM)
-               spe = SCHAR_LIM;
-       if (rechrg < 0 || rechrg > 7) rechrg = 7;       /* recharge_limit */
-       /* now we have the actual name, as delivered by xname, say
-               green potions called whisky
-               scrolls labeled "QWERTY"
-               egg
-               fortune cookies
-               very heavy iron ball named hoei
-               wand of wishing
-               elven cloak
-       */
-       if ((p = strstri(bp, " named ")) != 0) {
-               *p = 0;
-               name = p+7;
-       }
-       if ((p = strstri(bp, " called ")) != 0) {
-               *p = 0;
-               un = p+8;
-               /* "helmet called telepathy" is not "helmet" (a specific type)
-                * "shield called reflection" is not "shield" (a general type)
-                */
-               for(i = 0; i < SIZE(o_ranges); i++)
-                   if(!strcmpi(bp, o_ranges[i].name)) {
-                       oclass = o_ranges[i].oclass;
-                       goto srch;
-                   }
-       }
-       if ((p = strstri(bp, " labeled ")) != 0) {
-               *p = 0;
-               dn = p+9;
-       } else if ((p = strstri(bp, " labelled ")) != 0) {
-               *p = 0;
-               dn = p+10;
-       }
-       if ((p = strstri(bp, " of spinach")) != 0) {
-               *p = 0;
-               contents = SPINACH;
-       }
+     if (spe < 0) {
+         spesgn = -1;  /* cheaters get what they deserve */
+         spe = abs(spe);
+     }
+     if (spe > SCHAR_LIM)
+         spe = SCHAR_LIM;
+     if (rechrg < 0 || rechrg > 7) rechrg = 7; /* recharge_limit */
+     /* now we have the actual name, as delivered by xname, say
+         green potions called whisky
+         scrolls labeled "QWERTY"
+         egg
+         fortune cookies
+         very heavy iron ball named hoei
+         wand of wishing
+         elven cloak
+     */
+     if ((p = strstri(bp, " named ")) != 0) {
+         *p = 0;
+         name = p+7;
+     }
+     if ((p = strstri(bp, " called ")) != 0) {
+         *p = 0;
+         un = p+8;
+         /* "helmet called telepathy" is not "helmet" (a specific type)
+          * "shield called reflection" is not "shield" (a general type)
+          */
+         for(i = 0; i < SIZE(o_ranges); i++)
+             if(!strcmpi(bp, o_ranges[i].name)) {
+             oclass = o_ranges[i].oclass;
+             goto srch;
+             }
+     }
+     if ((p = strstri(bp, " labeled ")) != 0) {
+         *p = 0;
+         dn = p+9;
+     } else if ((p = strstri(bp, " labelled ")) != 0) {
+         *p = 0;
+         dn = p+10;
+     }
+     if ((p = strstri(bp, " of spinach")) != 0) {
+         *p = 0;
+         contents = SPINACH;
+     }
  
-       /*
-       Skip over "pair of ", "pairs of", "set of" and "sets of".
-       Accept "3 pair of boots" as well as "3 pairs of boots". It is valid
-       English either way.  See makeplural() for more on pair/pairs.
-       We should only double count if the object in question is not
-       refered to as a "pair of".  E.g. We should double if the player
-       types "pair of spears", but not if the player types "pair of
-       lenses".  Luckily (?) all objects that are refered to as pairs
-       -- boots, gloves, and lenses -- are also not mergable, so cnt is
-       ignored anyway.
-       */
-       if(!strncmpi(bp, "pair of ",8)) {
-               bp += 8;
-               cnt *= 2;
-       } else if(cnt > 1 && !strncmpi(bp, "pairs of ",9)) {
-               bp += 9;
-               cnt *= 2;
-       } else if (!strncmpi(bp, "set of ",7)) {
-               bp += 7;
-       } else if (!strncmpi(bp, "sets of ",8)) {
-               bp += 8;
-       }
+     /*
+     Skip over "pair of ", "pairs of", "set of" and "sets of".
+     Accept "3 pair of boots" as well as "3 pairs of boots". It is valid
+     English either way.  See makeplural() for more on pair/pairs.
+     We should only double count if the object in question is not
+     refered to as a "pair of".  E.g. We should double if the player
+     types "pair of spears", but not if the player types "pair of
+     lenses".  Luckily (?) all objects that are refered to as pairs
+     -- boots, gloves, and lenses -- are also not mergable, so cnt is
+     ignored anyway.
+     */
+     if(!strncmpi(bp, "pair of ",8)) {
+         bp += 8;
+         cnt *= 2;
+     } else if(cnt > 1 && !strncmpi(bp, "pairs of ",9)) {
+         bp += 9;
+         cnt *= 2;
+     } else if (!strncmpi(bp, "set of ",7)) {
+         bp += 7;
+     } else if (!strncmpi(bp, "sets of ",8)) {
+         bp += 8;
+     }
  
-       /*
-        * Find corpse type using "of" (figurine of an orc, tin of orc meat)
-        * Don't check if it's a wand or spellbook.
-        * (avoid "wand/finger of death" confusion).
-        */
-       if (!strstri(bp, "wand ")
-        && !strstri(bp, "spellbook ")
-        && !strstri(bp, "finger ")) {
-           if (((p = strstri(bp, "tin of ")) != 0) &&
-               (tmp = tin_variety_txt(p+7, &tinv)) &&
-               (mntmp = name_to_mon(p+7+tmp)) >= LOW_PM) {
-               *(p+3) = 0;
-               tvariety = tinv;
-           } else if ((p = strstri(bp, " of ")) != 0
-               && (mntmp = name_to_mon(p+4)) >= LOW_PM)
-               *p = 0;
-       }
-       /* Find corpse type w/o "of" (red dragon scale mail, yeti corpse) */
-       if (strncmpi(bp, "samurai sword", 13)) /* not the "samurai" monster! */
-       if (strncmpi(bp, "wizard lock", 11)) /* not the "wizard" monster! */
-       if (strncmpi(bp, "ninja-to", 8)) /* not the "ninja" rank */
-       if (strncmpi(bp, "master key", 10)) /* not the "master" rank */
-       if (strncmpi(bp, "magenta", 7)) /* not the "mage" rank */
-       if (mntmp < LOW_PM && strlen(bp) > 2 &&
-           (mntmp = name_to_mon(bp)) >= LOW_PM) {
-               int mntmptoo, mntmplen; /* double check for rank title */
-               char *obp = bp;
-               mntmptoo = title_to_mon(bp, (int *)0, &mntmplen);
-               bp += mntmp != mntmptoo ? (int)strlen(mons[mntmp].mname) : mntmplen;
-               if (*bp == ' ') bp++;
-               else if (!strncmpi(bp, "s ", 2)) bp += 2;
-               else if (!strncmpi(bp, "es ", 3)) bp += 3;
-               else if (!*bp && !actualn && !dn && !un && !oclass) {
-                   /* no referent; they don't really mean a monster type */
-                   bp = obp;
-                   mntmp = NON_PM;
-               }
-       }
+     /* intercept pudding globs here; they're a valid wish target,
+      * but we need them to not get treated like a corpse.
+      * 
+      * also don't let player wish for multiple globs. 
+      */
+     if ((p = strstri(bp, "glob of ")) != 0 
+           || (p = strstri(bp, "globs of ")) != 0) {
+         int globoffset = (*(p+4) == 's') ? 9 : 8;
+         if ((mntmp = name_to_mon(p + globoffset)) >= PM_GRAY_OOZE
+                 && mntmp <= PM_BLACK_PUDDING) {
+             mntmp = NON_PM;     /* lie to ourselves */
+             cnt = 0;            /* force only one */
+         }
+     } else {
+         /*
+          * Find corpse type using "of" (figurine of an orc, tin of orc meat)
+          * Don't check if it's a wand or spellbook.
+          * (avoid "wand/finger of death" confusion).
+          */
+         if (!strstri(bp, "wand ")
+             && !strstri(bp, "spellbook ")
+             && !strstri(bp, "finger ")) {
+             if (((p = strstri(bp, "tin of ")) != 0) &&
+                 (tmp = tin_variety_txt(p + 7, &tinv)) &&
+                 (mntmp = name_to_mon(p + 7 + tmp)) >= LOW_PM) {
+                 *(p + 3) = 0;
+                 tvariety = tinv;
+             } else if ((p = strstri(bp, " of ")) != 0
+                        && (mntmp = name_to_mon(p + 4)) >= LOW_PM)
+                        *p = 0;
+         }
+     }
+     /* Find corpse type w/o "of" (red dragon scale mail, yeti corpse) */
+     if (strncmpi(bp, "samurai sword", 13)) /* not the "samurai" monster! */
+     if (strncmpi(bp, "wizard lock", 11)) /* not the "wizard" monster! */
+     if (strncmpi(bp, "ninja-to", 8)) /* not the "ninja" rank */
+     if (strncmpi(bp, "master key", 10)) /* not the "master" rank */
+     if (strncmpi(bp, "magenta", 7)) /* not the "mage" rank */
+     if (mntmp < LOW_PM && strlen(bp) > 2 &&
+         (mntmp = name_to_mon(bp)) >= LOW_PM) {
+         int mntmptoo, mntmplen;       /* double check for rank title */
+         char *obp = bp;
+         mntmptoo = title_to_mon(bp, (int *)0, &mntmplen);
+         bp += mntmp != mntmptoo ? (int)strlen(mons[mntmp].mname) : mntmplen;
+         if (*bp == ' ') bp++;
+         else if (!strncmpi(bp, "s ", 2)) bp += 2;
+         else if (!strncmpi(bp, "es ", 3)) bp += 3;
+         else if (!*bp && !actualn && !dn && !un && !oclass) {
+             /* no referent; they don't really mean a monster type */
+             bp = obp;
+             mntmp = NON_PM;
+         }
+     }
  
-       /* first change to singular if necessary */
-       if (*bp) {
-               char *sng = makesingular(bp);
-               if (strcmp(bp, sng)) {
-                       if (cnt == 1) cnt = 2;
-                       Strcpy(bp, sng);
-               }
-       }
+     /* first change to singular if necessary */
+     if (*bp) {
+         char *sng = makesingular(bp);
+         if (strcmp(bp, sng)) {
+             if (cnt == 1) cnt = 2;
+             Strcpy(bp, sng);
+         }
+     }
  
-       /* Alternate spellings (pick-ax, silver sabre, &c) */
+     /* Alternate spellings (pick-ax, silver sabre, &c) */
      {
-       struct alt_spellings *as = spellings;
-       while (as->sp) {
-               if (fuzzymatch(bp, as->sp, " -", TRUE)) {
-                       typ = as->ob;
-                       goto typfnd;
-               }
-               as++;
-       }
-       /* can't use spellings list for this one due to shuffling */
-       if (!strncmpi(bp, "grey spell", 10))
-               *(bp + 2) = 'a';
-       if ((p = strstri(bp, "armour")) != 0) {
-               /* skip past "armo", then copy remainer beyond "u" */
-               p += 4;
-               while ((*p = *(p + 1)) != '\0') ++p;    /* self terminating */
-       }
+     struct alt_spellings *as = spellings;
+     while (as->sp) {
+         if (fuzzymatch(bp, as->sp, " -", TRUE)) {
+             typ = as->ob;
+             goto typfnd;
+         }
+         as++;
+     }
+     /* can't use spellings list for this one due to shuffling */
+     if (!strncmpi(bp, "grey spell", 10))
+         *(bp + 2) = 'a';
+     if ((p = strstri(bp, "armour")) != 0) {
+         /* skip past "armo", then copy remainer beyond "u" */
+         p += 4;
+         while ((*p = *(p + 1)) != '\0') ++p;  /* self terminating */
+     }
      }
  
-       /* dragon scales - assumes order of dragons */
-       if(!strcmpi(bp, "scales") &&
-                       mntmp >= PM_GRAY_DRAGON && mntmp <= PM_YELLOW_DRAGON) {
-               typ = GRAY_DRAGON_SCALES + mntmp - PM_GRAY_DRAGON;
-               mntmp = NON_PM; /* no monster */
-               goto typfnd;
-       }
+     /* dragon scales - assumes order of dragons */
+     if(!strcmpi(bp, "scales") &&
+             mntmp >= PM_GRAY_DRAGON && mntmp <= PM_YELLOW_DRAGON) {
+         typ = GRAY_DRAGON_SCALES + mntmp - PM_GRAY_DRAGON;
+         mntmp = NON_PM;       /* no monster */
+         goto typfnd;
+     }
  
-       p = eos(bp);
-       if(!BSTRCMPI(bp, p-10, "holy water")) {
-               typ = POT_WATER;
-               if ((p-bp) >= 12 && *(p-12) == 'u')
-                       iscursed = 1; /* unholy water */
-               else blessed = 1;
-               goto typfnd;
-       }
-       if(unlabeled && !BSTRCMPI(bp, p-6, "scroll")) {
-               typ = SCR_BLANK_PAPER;
-               goto typfnd;
-       }
-       if(unlabeled && !BSTRCMPI(bp, p-9, "spellbook")) {
-               typ = SPE_BLANK_PAPER;
-               goto typfnd;
-       }
-       /*
-        * NOTE: Gold pieces are handled as objects nowadays, and therefore
-        * this section should probably be reconsidered as well as the entire
-        * gold/money concept.  Maybe we want to add other monetary units as
-        * well in the future. (TH)
-        */
-       if(!BSTRCMPI(bp, p-10, "gold piece") || !BSTRCMPI(bp, p-7, "zorkmid") ||
-          !strcmpi(bp, "gold") || !strcmpi(bp, "money") ||
-          !strcmpi(bp, "coin") || *bp == GOLD_SYM) {
-               if (cnt > 5000 && !wizard) cnt = 5000;
-               else if (cnt < 1) cnt = 1;
-               otmp = mksobj(GOLD_PIECE, FALSE, FALSE);
-               otmp->quan = (long) cnt;
-               otmp->owt = weight(otmp);
-               context.botl = 1;
-               return otmp;
-       }
+     p = eos(bp);
+     if(!BSTRCMPI(bp, p-10, "holy water")) {
+         typ = POT_WATER;
+         if ((p-bp) >= 12 && *(p-12) == 'u')
+             iscursed = 1; /* unholy water */
+         else blessed = 1;
+         goto typfnd;
+     }
+     if(unlabeled && !BSTRCMPI(bp, p-6, "scroll")) {
+         typ = SCR_BLANK_PAPER;
+         goto typfnd;
+     }
+     if(unlabeled && !BSTRCMPI(bp, p-9, "spellbook")) {
+         typ = SPE_BLANK_PAPER;
+         goto typfnd;
+     }
+     /*
+      * NOTE: Gold pieces are handled as objects nowadays, and therefore
+      * this section should probably be reconsidered as well as the entire
+      * gold/money concept.  Maybe we want to add other monetary units as
+      * well in the future. (TH)
+      */
+     if(!BSTRCMPI(bp, p-10, "gold piece") || !BSTRCMPI(bp, p-7, "zorkmid") ||
+        !strcmpi(bp, "gold") || !strcmpi(bp, "money") ||
+        !strcmpi(bp, "coin") || *bp == GOLD_SYM) {
+         if (cnt > 5000 && !wizard) cnt = 5000;
+         else if (cnt < 1) cnt = 1;
+         otmp = mksobj(GOLD_PIECE, FALSE, FALSE);
+         otmp->quan = (long) cnt;
+         otmp->owt = weight(otmp);
+         context.botl = 1;
+         return otmp;
+     }
  
-       /* check for single character object class code ("/" for wand, &c) */
-       if (strlen(bp) == 1 &&
-                  (i = def_char_to_objclass(*bp)) < MAXOCLASSES &&
-                   i > ILLOBJ_CLASS && (i != VENOM_CLASS || wizard)) {
-               oclass = i;
-               goto any;
-       }
+     /* check for single character object class code ("/" for wand, &c) */
+     if (strlen(bp) == 1 &&
+            (i = def_char_to_objclass(*bp)) < MAXOCLASSES &&
+             i > ILLOBJ_CLASS && (i != VENOM_CLASS || wizard)) {
+         oclass = i;
+         goto any;
+     }
  
-       /* Search for class names: XXXXX potion, scroll of XXXXX.  Avoid */
-       /* false hits on, e.g., rings for "ring mail". */
-       if(strncmpi(bp, "enchant ", 8) &&
-          strncmpi(bp, "destroy ", 8) &&
-          strncmpi(bp, "detect food", 11) &&
-          strncmpi(bp, "food detection", 14) &&
-          strncmpi(bp, "ring mail", 9) &&
-          strncmpi(bp, "studded leather armor", 21) &&
-          strncmpi(bp, "leather armor", 13) &&
-          strncmpi(bp, "tooled horn", 11) &&
-          strncmpi(bp, "food ration", 11) &&
-          strncmpi(bp, "meat ring", 9)
-       )
-       for (i = 0; i < (int)(sizeof wrpsym); i++) {
-               register int j = strlen(wrp[i]);
-               if(!strncmpi(bp, wrp[i], j)){
-                       oclass = wrpsym[i];
-                       if(oclass != AMULET_CLASS) {
-                           bp += j;
-                           if(!strncmpi(bp, " of ", 4)) actualn = bp+4;
-                           /* else if(*bp) ?? */
-                       } else
-                           actualn = bp;
-                       goto srch;
-               }
-               if(!BSTRCMPI(bp, p-j, wrp[i])){
-                       oclass = wrpsym[i];
-                       p -= j;
-                       *p = 0;
-                       if(p > bp && p[-1] == ' ') p[-1] = 0;
-                       actualn = dn = bp;
-                       goto srch;
-               }
-       }
+     /* Search for class names: XXXXX potion, scroll of XXXXX.  Avoid */
+     /* false hits on, e.g., rings for "ring mail". */
+     if(strncmpi(bp, "enchant ", 8) &&
+        strncmpi(bp, "destroy ", 8) &&
+        strncmpi(bp, "detect food", 11) &&
+        strncmpi(bp, "food detection", 14) &&
+        strncmpi(bp, "ring mail", 9) &&
+        strncmpi(bp, "studded leather armor", 21) &&
+        strncmpi(bp, "leather armor", 13) &&
+        strncmpi(bp, "tooled horn", 11) &&
+        strncmpi(bp, "food ration", 11) &&
+        strncmpi(bp, "meat ring", 9)
+     )
+     for (i = 0; i < (int)(sizeof wrpsym); i++) {
+         register int j = strlen(wrp[i]);
+         if(!strncmpi(bp, wrp[i], j)){
+             oclass = wrpsym[i];
+             if(oclass != AMULET_CLASS) {
+                 bp += j;
+                 if(!strncmpi(bp, " of ", 4)) actualn = bp+4;
+                 /* else if(*bp) ?? */
+             } else
+                 actualn = bp;
+             goto srch;
+         }
+         if(!BSTRCMPI(bp, p-j, wrp[i])){
+             oclass = wrpsym[i];
+             p -= j;
+             *p = 0;
+             if(p > bp && p[-1] == ' ') p[-1] = 0;
+             actualn = dn = bp;
+             goto srch;
+         }
+     }
  
-       /* Wishing in wizard mode can create traps and furniture.
-        * Part I:  distinguish between trap and object for the two
-        * types of traps which have corresponding objects:  bear trap
-        * and land mine.  "beartrap" (object) and "bear trap" (trap)
-        * have a difference in spelling which we used to exploit by
-        * adding a special case in wishymatch(), but "land mine" is
-        * spelled the same either way so needs different handing.
-        * Since we need something else for land mine, we've dropped
-        * the bear trap hack so that both are handled exactly the
-        * same.  To get an armed trap instead of a disarmed object,
-        * the player can prefix either the object name or the trap
-        * name with "trapped " (which ordinarily applies to chests
-        * and tins), or append something--anything at all except for
-        * " object", but " trap" is suggested--to either the trap
-        * name or the object name.
-        */
-       if (wizard && (!strncmpi(bp, "bear", 4) || !strncmpi(bp, "land", 4))) {
-           boolean beartrap = (lowc(*bp) == 'b');
-           char *zp = bp + 4; /* skip "bear"/"land" */
-           if (*zp == ' ') ++zp;       /* embedded space is optional */
-           if (!strncmpi(zp, beartrap ? "trap" : "mine", 4)) {
-               zp += 4;
-               if (trapped == 2 || !strcmpi(zp, " object")) {
-                   /* "untrapped <foo>" or "<foo> object" */
-                   typ = beartrap ? BEARTRAP : LAND_MINE;
-                   goto typfnd;
-               } else if (trapped == 1 || *zp != '\0') {
-                   /* "trapped <foo>" or "<foo> trap" (actually "<foo>*") */
-                   int idx = trap_to_defsym(beartrap ? BEAR_TRAP : LANDMINE);
-                   /* use canonical trap spelling, skip object matching */
-                   Strcpy(bp, defsyms[idx].explanation);
-                   goto wiztrap;
-               }
-               /* [no prefix or suffix; we're going to end up matching
-                  the object name and getting a disarmed trap object] */
-           }
-       }
+     /* Wishing in wizard mode can create traps and furniture.
+      * Part I:  distinguish between trap and object for the two
+      * types of traps which have corresponding objects:  bear trap
+      * and land mine.  "beartrap" (object) and "bear trap" (trap)
+      * have a difference in spelling which we used to exploit by
+      * adding a special case in wishymatch(), but "land mine" is
+      * spelled the same either way so needs different handing.
+      * Since we need something else for land mine, we've dropped
+      * the bear trap hack so that both are handled exactly the
+      * same.  To get an armed trap instead of a disarmed object,
+      * the player can prefix either the object name or the trap
+      * name with "trapped " (which ordinarily applies to chests
+      * and tins), or append something--anything at all except for
+      * " object", but " trap" is suggested--to either the trap
+      * name or the object name.
+      */
+     if (wizard && (!strncmpi(bp, "bear", 4) || !strncmpi(bp, "land", 4))) {
+         boolean beartrap = (lowc(*bp) == 'b');
+         char *zp = bp + 4; /* skip "bear"/"land" */
+         if (*zp == ' ') ++zp; /* embedded space is optional */
+         if (!strncmpi(zp, beartrap ? "trap" : "mine", 4)) {
+         zp += 4;
+         if (trapped == 2 || !strcmpi(zp, " object")) {
+             /* "untrapped <foo>" or "<foo> object" */
+             typ = beartrap ? BEARTRAP : LAND_MINE;
+             goto typfnd;
+         } else if (trapped == 1 || *zp != '\0') {
+             /* "trapped <foo>" or "<foo> trap" (actually "<foo>*") */
+             int idx = trap_to_defsym(beartrap ? BEAR_TRAP : LANDMINE);
+             /* use canonical trap spelling, skip object matching */
+             Strcpy(bp, defsyms[idx].explanation);
+             goto wiztrap;
+         }
+         /* [no prefix or suffix; we're going to end up matching
+            the object name and getting a disarmed trap object] */
+         }
+     }
  
  retry:
-       /* "grey stone" check must be before general "stone" */
-       for (i = 0; i < SIZE(o_ranges); i++)
-           if(!strcmpi(bp, o_ranges[i].name)) {
-               typ = rnd_class(o_ranges[i].f_o_range, o_ranges[i].l_o_range);
-               goto typfnd;
-           }
-       if (!BSTRCMPI(bp, p-6, " stone")) {
-               p[-6] = 0;
-               oclass = GEM_CLASS;
-               dn = actualn = bp;
-               goto srch;
-       } else if (!strcmpi(bp, "looking glass")) {
-               ;       /* avoid false hit on "* glass" */
-       } else if (!BSTRCMPI(bp, p-6, " glass") || !strcmpi(bp, "glass")) {
-               register char *g = bp;
-               if (strstri(g, "broken")) return (struct obj *)0;
-               if (!strncmpi(g, "worthless ", 10)) g += 10;
-               if (!strncmpi(g, "piece of ", 9)) g += 9;
-               if (!strncmpi(g, "colored ", 8)) g += 8;
-               else if (!strncmpi(g, "coloured ", 9)) g += 9;
-               if (!strcmpi(g, "glass")) {     /* choose random color */
-                       /* 9 different kinds */
-                       typ = LAST_GEM + rnd(9);
-                       if (objects[typ].oc_class == GEM_CLASS) goto typfnd;
-                       else typ = 0;   /* somebody changed objects[]? punt */
-               } else {                /* try to construct canonical form */
-                       char tbuf[BUFSZ];
-                       Strcpy(tbuf, "worthless piece of ");
-                       Strcat(tbuf, g);  /* assume it starts with the color */
-                       Strcpy(bp, tbuf);
-               }
-       }
+     /* "grey stone" check must be before general "stone" */
+     for (i = 0; i < SIZE(o_ranges); i++)
+         if(!strcmpi(bp, o_ranges[i].name)) {
+         typ = rnd_class(o_ranges[i].f_o_range, o_ranges[i].l_o_range);
+         goto typfnd;
+         }
+     if (!BSTRCMPI(bp, p-6, " stone")) {
+         p[-6] = 0;
+         oclass = GEM_CLASS;
+         dn = actualn = bp;
+         goto srch;
+     } else if (!strcmpi(bp, "looking glass")) {
+         ;     /* avoid false hit on "* glass" */
+     } else if (!BSTRCMPI(bp, p-6, " glass") || !strcmpi(bp, "glass")) {
+         register char *g = bp;
+         if (strstri(g, "broken")) return (struct obj *)0;
+         if (!strncmpi(g, "worthless ", 10)) g += 10;
+         if (!strncmpi(g, "piece of ", 9)) g += 9;
+         if (!strncmpi(g, "colored ", 8)) g += 8;
+         else if (!strncmpi(g, "coloured ", 9)) g += 9;
+         if (!strcmpi(g, "glass")) {   /* choose random color */
+             /* 9 different kinds */
+             typ = LAST_GEM + rnd(9);
+             if (objects[typ].oc_class == GEM_CLASS) goto typfnd;
+             else typ = 0;     /* somebody changed objects[]? punt */
+         } else {              /* try to construct canonical form */
+             char tbuf[BUFSZ];
+             Strcpy(tbuf, "worthless piece of ");
+             Strcat(tbuf, g);  /* assume it starts with the color */
+             Strcpy(bp, tbuf);
+         }
+     }
  
-       actualn = bp;
-       if (!dn) dn = actualn; /* ex. "skull cap" */
+     actualn = bp;
+     if (!dn) dn = actualn; /* ex. "skull cap" */
  srch:
-       /* check real names of gems first */
-       if(!oclass && actualn) {
-           for(i = bases[GEM_CLASS]; i <= LAST_GEM; i++) {
-               register const char *zn;
-               if((zn = OBJ_NAME(objects[i])) && !strcmpi(actualn, zn)) {
-                   typ = i;
-                   goto typfnd;
-               }
-           }
-       }
-       i = oclass ? bases[(int)oclass] : 1;
-       while(i < NUM_OBJECTS && (!oclass || objects[i].oc_class == oclass)){
-               register const char *zn;
-               if (actualn && (zn = OBJ_NAME(objects[i])) != 0 &&
-                           wishymatch(actualn, zn, TRUE)) {
-                       typ = i;
-                       goto typfnd;
-               }
-               if (dn && (zn = OBJ_DESCR(objects[i])) != 0 &&
-                           wishymatch(dn, zn, FALSE)) {
-                       /* don't match extra descriptions (w/o real name) */
-                       if (!OBJ_NAME(objects[i])) return (struct obj *)0;
-                       typ = i;
-                       goto typfnd;
-               }
-               if (un && (zn = objects[i].oc_uname) != 0 &&
-                           wishymatch(un, zn, FALSE)) {
-                       typ = i;
-                       goto typfnd;
-               }
-               i++;
-       }
-       if (actualn) {
-               struct Jitem *j = Japanese_items;
-               while(j->item) {
-                       if (actualn && !strcmpi(actualn, j->name)) {
-                               typ = j->item;
-                               goto typfnd;
-                       }
-                       j++;
-               }
-       }
-       /* if we've stripped off "armor" and failed to match anything
-          in objects[], append "mail" and try again to catch misnamed
-          requests like "plate armor" and "yellow dragon scale armor" */
-       if (oclass == ARMOR_CLASS && !strstri(bp, "mail")) {
-               /* modifying bp's string is ok; we're about to resort
-                  to random armor if this also fails to match anything */
-               Strcat(bp, " mail");
-               goto retry;
-       }
-       if (!strcmpi(bp, "spinach")) {
-               contents = SPINACH;
-               typ = TIN;
-               goto typfnd;
-       }
-       /* Note: not strcmpi.  2 fruits, one capital, one not, are possible.
-          Also not strncmp.  We used to ignore trailing text with it, but
-          that resulted in "grapefruit" matching "grape" if the latter came
-          earlier than the former in the fruit list. */
-       {
-           char *fp;
-           int l, cntf;
-           int blessedf, iscursedf, uncursedf, halfeatenf;
-           blessedf = iscursedf = uncursedf = halfeatenf = 0;
-           cntf = 0;
-           fp = fruitbuf;
-           for(;;) {
-               if (!fp || !*fp) break;
-               if (!strncmpi(fp, "an ", l=3) ||
-                   !strncmpi(fp, "a ", l=2)) {
-                       cntf = 1;
-               } else if (!cntf && digit(*fp)) {
-                       cntf = atoi(fp);
-                       while(digit(*fp)) fp++;
-                       while(*fp == ' ') fp++;
-                       l = 0;
-               } else if (!strncmpi(fp, "blessed ", l=8)) {
-                       blessedf = 1;
-               } else if (!strncmpi(fp, "cursed ", l=7)) {
-                       iscursedf = 1;
-               } else if (!strncmpi(fp, "uncursed ", l=9)) {
-                       uncursedf = 1;
-               } else if (!strncmpi(fp, "partly eaten ", l=13) ||
-                          !strncmpi(fp, "partially eaten ", l=16)) {
-                       halfeatenf = 1;
-               } else break;
-               fp += l;
-           }
-           for(f=ffruit; f; f = f->nextf) {
-               /* match type: 0=none, 1=exact, 2=singular, 3=plural */
-               int ftyp = 0;
-               if (!strcmp(fp, f->fname)) ftyp = 1;
-               else if (!strcmp(fp, makesingular(f->fname))) ftyp = 2;
-               else if (!strcmp(fp, makeplural(f->fname))) ftyp = 3;
-               if (ftyp) {
-                       typ = SLIME_MOLD;
-                       blessed = blessedf;
-                       iscursed = iscursedf;
-                       uncursed = uncursedf;
-                       halfeaten = halfeatenf;
-                       /* adjust count if user explicitly asked for
-                          singular amount (can't happen unless fruit
-                          has been given an already pluralized name)
-                          or for plural amount */
-                       if (ftyp == 2 && !cntf) cntf = 1;
-                       else if (ftyp == 3 && !cntf) cntf = 2;
-                       cnt = cntf;
-                       ftype = f->fid;
-                       goto typfnd;
-               }
-           }
-       }
+     /* check real names of gems first */
+     if(!oclass && actualn) {
+         for(i = bases[GEM_CLASS]; i <= LAST_GEM; i++) {
+         register const char *zn;
+         if((zn = OBJ_NAME(objects[i])) && !strcmpi(actualn, zn)) {
+             typ = i;
+             goto typfnd;
+         }
+         }
+     }
+     i = oclass ? bases[(int)oclass] : 1;
+     while(i < NUM_OBJECTS && (!oclass || objects[i].oc_class == oclass)){
+         register const char *zn;
+         if (actualn && (zn = OBJ_NAME(objects[i])) != 0 &&
+                 wishymatch(actualn, zn, TRUE)) {
+             typ = i;
+             goto typfnd;
+         }
+         if (dn && (zn = OBJ_DESCR(objects[i])) != 0 &&
+                 wishymatch(dn, zn, FALSE)) {
+             /* don't match extra descriptions (w/o real name) */
+             if (!OBJ_NAME(objects[i])) return (struct obj *)0;
+             typ = i;
+             goto typfnd;
+         }
+         if (un && (zn = objects[i].oc_uname) != 0 &&
+                 wishymatch(un, zn, FALSE)) {
+             typ = i;
+             goto typfnd;
+         }
+         i++;
+     }
+     if (actualn) {
+         struct Jitem *j = Japanese_items;
+         while(j->item) {
+             if (actualn && !strcmpi(actualn, j->name)) {
+                 typ = j->item;
+                 goto typfnd;
+             }
+             j++;
+         }
+     }
+     /* if we've stripped off "armor" and failed to match anything
+        in objects[], append "mail" and try again to catch misnamed
+        requests like "plate armor" and "yellow dragon scale armor" */
+     if (oclass == ARMOR_CLASS && !strstri(bp, "mail")) {
+         /* modifying bp's string is ok; we're about to resort
+            to random armor if this also fails to match anything */
+         Strcat(bp, " mail");
+         goto retry;
+     }
+     if (!strcmpi(bp, "spinach")) {
+         contents = SPINACH;
+         typ = TIN;
+         goto typfnd;
+     }
+     /* Note: not strcmpi.  2 fruits, one capital, one not, are possible.
+        Also not strncmp.  We used to ignore trailing text with it, but
+        that resulted in "grapefruit" matching "grape" if the latter came
+        earlier than the former in the fruit list. */
+     {
+         char *fp;
+         int l, cntf;
+         int blessedf, iscursedf, uncursedf, halfeatenf;
+         blessedf = iscursedf = uncursedf = halfeatenf = 0;
+         cntf = 0;
+         fp = fruitbuf;
+         for(;;) {
+         if (!fp || !*fp) break;
+         if (!strncmpi(fp, "an ", l=3) ||
+             !strncmpi(fp, "a ", l=2)) {
+             cntf = 1;
+         } else if (!cntf && digit(*fp)) {
+             cntf = atoi(fp);
+             while(digit(*fp)) fp++;
+             while(*fp == ' ') fp++;
+             l = 0;
+         } else if (!strncmpi(fp, "blessed ", l=8)) {
+             blessedf = 1;
+         } else if (!strncmpi(fp, "cursed ", l=7)) {
+             iscursedf = 1;
+         } else if (!strncmpi(fp, "uncursed ", l=9)) {
+             uncursedf = 1;
+         } else if (!strncmpi(fp, "partly eaten ", l=13) ||
+                !strncmpi(fp, "partially eaten ", l=16)) {
+             halfeatenf = 1;
+         } else break;
+         fp += l;
+         }
+         for(f=ffruit; f; f = f->nextf) {
+         /* match type: 0=none, 1=exact, 2=singular, 3=plural */
+         int ftyp = 0;
+         if (!strcmp(fp, f->fname)) ftyp = 1;
+         else if (!strcmp(fp, makesingular(f->fname))) ftyp = 2;
+         else if (!strcmp(fp, makeplural(f->fname))) ftyp = 3;
+         if (ftyp) {
+             typ = SLIME_MOLD;
+             blessed = blessedf;
+             iscursed = iscursedf;
+             uncursed = uncursedf;
+             halfeaten = halfeatenf;
+             /* adjust count if user explicitly asked for
+                singular amount (can't happen unless fruit
+                has been given an already pluralized name)
+                or for plural amount */
+             if (ftyp == 2 && !cntf) cntf = 1;
+             else if (ftyp == 3 && !cntf) cntf = 2;
+             cnt = cntf;
+             ftype = f->fid;
+             goto typfnd;
+         }
+         }
+     }
  
-       if(!oclass && actualn) {
-           short objtyp;
+     if(!oclass && actualn) {
+         short objtyp;
  
-           /* Perhaps it's an artifact specified by name, not type */
-           name = artifact_name(actualn, &objtyp);
-           if(name) {
-               typ = objtyp;
-               goto typfnd;
-           }
-       }
-       /* Let wizards wish for traps and furniture.
-        * Must come after objects check so wizards can still wish for
-        * trap objects like beartraps.
-        * Disallow such topology tweaks for WIZKIT startup wishes.
-        */
+         /* Perhaps it's an artifact specified by name, not type */
+         name = artifact_name(actualn, &objtyp);
+         if(name) {
+         typ = objtyp;
+         goto typfnd;
+         }
+     }
+     /* Let wizards wish for traps and furniture.
+      * Must come after objects check so wizards can still wish for
+      * trap objects like beartraps.
+      * Disallow such topology tweaks for WIZKIT startup wishes.
+      */
  wiztrap:
-       if (wizard && !program_state.wizkit_wishing) {
-               struct rm *lev;
-               int trap, x = u.ux, y = u.uy;
-               for (trap = NO_TRAP+1; trap < TRAPNUM; trap++) {
-                       struct trap *t;
-                       const char *tname;
-                       tname = defsyms[trap_to_defsym(trap)].explanation;
-                       if (strncmpi(tname, bp, strlen(tname))) continue;
-                       /* found it; avoid stupid mistakes */
-                       if ((trap == TRAPDOOR || trap == HOLE) &&
-                               !Can_fall_thru(&u.uz)) trap = ROCKTRAP;
-                       if ((t = maketrap(x, y, trap)) != 0) {
-                           trap = t->ttyp;
-                           tname = defsyms[trap_to_defsym(trap)].explanation;
-                           pline("%s%s.", An(tname),
-                                 (trap != MAGIC_PORTAL) ? "" : " to nowhere");
-                       } else
-                           pline("Creation of %s failed.", an(tname));
-                       return(&zeroobj);
-               }
-               /* furniture and terrain */
-               lev = &levl[x][y];
-               p = eos(bp);
-               if (!BSTRCMPI(bp, p-8, "fountain")) {
-                       lev->typ = FOUNTAIN;
-                       level.flags.nfountains++;
-                       if(!strncmpi(bp, "magic ", 6)) lev->blessedftn = 1;
-                       pline("A %sfountain.", lev->blessedftn ? "magic " : "");
-                       newsym(x, y);
-                       return(&zeroobj);
-               }
-               if (!BSTRCMPI(bp, p-6, "throne")) {
-                       lev->typ = THRONE;
-                       pline("A throne.");
-                       newsym(x, y);
-                       return(&zeroobj);
-               }
-               if (!BSTRCMPI(bp, p-4, "sink")) {
-                       lev->typ = SINK;
-                       level.flags.nsinks++;
-                       pline("A sink.");
-                       newsym(x, y);
-                       return &zeroobj;
-               }
-               /* ("water" matches "potion of water" rather than terrain) */
-               if (!BSTRCMPI(bp, p-4, "pool") || !BSTRCMPI(bp, p-4, "moat")) {
-                       lev->typ = !BSTRCMPI(bp, p-4, "pool") ? POOL : MOAT;
-                       del_engr_at(x, y);
-                       pline("A %s.", (lev->typ == POOL) ? "pool" : "moat");
-                       /* Must manually make kelp! */
-                       water_damage_chain(level.objects[x][y], TRUE);
-                       newsym(x, y);
-                       return &zeroobj;
-               }
-               if (!BSTRCMPI(bp, p-4, "lava")) { /* also matches "molten lava" */
-                       lev->typ = LAVAPOOL;
-                       del_engr_at(x, y);
-                       pline("A pool of molten lava.");
-                       if (!(Levitation || Flying)) (void) lava_effects();
-                       newsym(x, y);
-                       return &zeroobj;
-               }
-               if (!BSTRCMPI(bp, p-5, "altar")) {
-                   aligntyp al;
-                   lev->typ = ALTAR;
-                   if(!strncmpi(bp, "chaotic ", 8))
-                       al = A_CHAOTIC;
-                   else if(!strncmpi(bp, "neutral ", 8))
-                       al = A_NEUTRAL;
-                   else if(!strncmpi(bp, "lawful ", 7))
-                       al = A_LAWFUL;
-                   else if(!strncmpi(bp, "unaligned ", 10))
-                       al = A_NONE;
-                   else /* -1 - A_CHAOTIC, 0 - A_NEUTRAL, 1 - A_LAWFUL */
-                       al = (!rn2(6)) ? A_NONE : rn2((int)A_LAWFUL+2) - 1;
-                   lev->altarmask = Align2amask(al);
-                   pline("%s altar.", An(align_str(al)));
-                   newsym(x, y);
-                   return(&zeroobj);
-               }
-               if (!BSTRCMPI(bp, p-5, "grave") ||
-                       !BSTRCMPI(bp, p-9, "headstone")) {
-                   make_grave(x, y, (char *)0);
-                   pline("%s.", IS_GRAVE(lev->typ) ? "A grave" :
-                                "Can't place a grave here");
-                   newsym(x, y);
-                   return(&zeroobj);
-               }
-               if (!BSTRCMPI(bp, p-4, "tree")) {
-                   lev->typ = TREE;
-                   pline("A tree.");
-                   newsym(x, y);
-                   block_point(x, y);
-                   return &zeroobj;
-               }
-               if (!BSTRCMPI(bp, p-4, "bars")) {
-                   lev->typ = IRONBARS;
-                   pline("Iron bars.");
-                   newsym(x, y);
-                   return &zeroobj;
-               }
-       }
+     if (wizard && !program_state.wizkit_wishing) {
+         struct rm *lev;
+         int trap, x = u.ux, y = u.uy;
+         for (trap = NO_TRAP+1; trap < TRAPNUM; trap++) {
+             struct trap *t;
+             const char *tname;
+             tname = defsyms[trap_to_defsym(trap)].explanation;
+             if (strncmpi(tname, bp, strlen(tname))) continue;
+             /* found it; avoid stupid mistakes */
+             if ((trap == TRAPDOOR || trap == HOLE) &&
+                 !Can_fall_thru(&u.uz)) trap = ROCKTRAP;
+             if ((t = maketrap(x, y, trap)) != 0) {
+                 trap = t->ttyp;
+                 tname = defsyms[trap_to_defsym(trap)].explanation;
+                 pline("%s%s.", An(tname),
+                   (trap != MAGIC_PORTAL) ? "" : " to nowhere");
+             } else
+                 pline("Creation of %s failed.", an(tname));
+             return(&zeroobj);
+         }
+         /* furniture and terrain */
+         lev = &levl[x][y];
+         p = eos(bp);
+         if (!BSTRCMPI(bp, p-8, "fountain")) {
+             lev->typ = FOUNTAIN;
+             level.flags.nfountains++;
+             if(!strncmpi(bp, "magic ", 6)) lev->blessedftn = 1;
+             pline("A %sfountain.", lev->blessedftn ? "magic " : "");
+             newsym(x, y);
+             return(&zeroobj);
+         }
+         if (!BSTRCMPI(bp, p-6, "throne")) {
+             lev->typ = THRONE;
+             pline("A throne.");
+             newsym(x, y);
+             return(&zeroobj);
+         }
+         if (!BSTRCMPI(bp, p-4, "sink")) {
+             lev->typ = SINK;
+             level.flags.nsinks++;
+             pline("A sink.");
+             newsym(x, y);
+             return &zeroobj;
+         }
+         /* ("water" matches "potion of water" rather than terrain) */
+         if (!BSTRCMPI(bp, p-4, "pool") || !BSTRCMPI(bp, p-4, "moat")) {
+             lev->typ = !BSTRCMPI(bp, p-4, "pool") ? POOL : MOAT;
+             del_engr_at(x, y);
+             pline("A %s.", (lev->typ == POOL) ? "pool" : "moat");
+             /* Must manually make kelp! */
+             water_damage_chain(level.objects[x][y], TRUE);
+             newsym(x, y);
+             return &zeroobj;
+         }
+         if (!BSTRCMPI(bp, p-4, "lava")) { /* also matches "molten lava" */
+             lev->typ = LAVAPOOL;
+             del_engr_at(x, y);
+             pline("A pool of molten lava.");
+             if (!(Levitation || Flying)) (void) lava_effects();
+             newsym(x, y);
+             return &zeroobj;
+         }
+         if (!BSTRCMPI(bp, p-5, "altar")) {
+             aligntyp al;
+             lev->typ = ALTAR;
+             if(!strncmpi(bp, "chaotic ", 8))
+             al = A_CHAOTIC;
+             else if(!strncmpi(bp, "neutral ", 8))
+             al = A_NEUTRAL;
+             else if(!strncmpi(bp, "lawful ", 7))
+             al = A_LAWFUL;
+             else if(!strncmpi(bp, "unaligned ", 10))
+             al = A_NONE;
+             else /* -1 - A_CHAOTIC, 0 - A_NEUTRAL, 1 - A_LAWFUL */
+             al = (!rn2(6)) ? A_NONE : rn2((int)A_LAWFUL+2) - 1;
+             lev->altarmask = Align2amask(al);
+             pline("%s altar.", An(align_str(al)));
+             newsym(x, y);
+             return(&zeroobj);
+         }
+         if (!BSTRCMPI(bp, p-5, "grave") ||
+             !BSTRCMPI(bp, p-9, "headstone")) {
+             make_grave(x, y, (char *)0);
+             pline("%s.", IS_GRAVE(lev->typ) ? "A grave" :
+                  "Can't place a grave here");
+             newsym(x, y);
+             return(&zeroobj);
+         }
+         if (!BSTRCMPI(bp, p-4, "tree")) {
+             lev->typ = TREE;
+             pline("A tree.");
+             newsym(x, y);
+             block_point(x, y);
+             return &zeroobj;
+         }
+         if (!BSTRCMPI(bp, p-4, "bars")) {
+             lev->typ = IRONBARS;
+             pline("Iron bars.");
+             newsym(x, y);
+             return &zeroobj;
+         }
+     }
  
-       if(!oclass) return((struct obj *)0);
+     if(!oclass) return((struct obj *)0);
  any:
-       if(!oclass) oclass = wrpsym[rn2((int)sizeof(wrpsym))];
+     if(!oclass) oclass = wrpsym[rn2((int)sizeof(wrpsym))];
  typfnd:
-       if (typ) oclass = objects[typ].oc_class;
-       /* handle some objects that are only allowed in wizard mode */
-       if (typ && !wizard) {
-           switch (typ) {
-               case AMULET_OF_YENDOR:
-                   typ = FAKE_AMULET_OF_YENDOR;
-                   break;
-               case CANDELABRUM_OF_INVOCATION:
-                   typ = rnd_class(TALLOW_CANDLE, WAX_CANDLE);
-                   break;
-               case BELL_OF_OPENING:
-                   typ = BELL;
-                   break;
-               case SPE_BOOK_OF_THE_DEAD:
-                   typ = SPE_BLANK_PAPER;
-                   break;
-               case MAGIC_LAMP:
-                   typ = OIL_LAMP;
-                   break;
-               default:
-                   /* catch any other non-wishable objects (venom) */
-                   if (objects[typ].oc_nowish) return ((struct obj *)0);
-                   break;
-           }
-       }
+     if (typ) oclass = objects[typ].oc_class;
+     /* handle some objects that are only allowed in wizard mode */
+     if (typ && !wizard) {
+         switch (typ) {
+         case AMULET_OF_YENDOR:
+             typ = FAKE_AMULET_OF_YENDOR;
+             break;
+         case CANDELABRUM_OF_INVOCATION:
+             typ = rnd_class(TALLOW_CANDLE, WAX_CANDLE);
+             break;
+         case BELL_OF_OPENING:
+             typ = BELL;
+             break;
+         case SPE_BOOK_OF_THE_DEAD:
+             typ = SPE_BLANK_PAPER;
+             break;
+         case MAGIC_LAMP:
+             typ = OIL_LAMP;
+             break;
+         default:
+             /* catch any other non-wishable objects (venom) */
+             if (objects[typ].oc_nowish) return ((struct obj *)0);
+             break;
+         }
+     }
  
-       /*
-        * Create the object, then fine-tune it.
-        */
-       otmp = typ ? mksobj(typ, TRUE, FALSE) : mkobj(oclass, FALSE);
-       typ = otmp->otyp, oclass = otmp->oclass; /* what we actually got */
-       if (islit &&
-               (typ == OIL_LAMP || typ == MAGIC_LAMP || typ == BRASS_LANTERN ||
-                Is_candle(otmp) || typ == POT_OIL)) {
-           place_object(otmp, u.ux, u.uy);  /* make it viable light source */
-           begin_burn(otmp, FALSE);
-           obj_extract_self(otmp);      /* now release it for caller's use */
-       }
 +      if (typ && wizard) {
 +          if (typ == SPE_NOVEL) {
 +              if (name && !lookup_novel(name, (int *)0)) {
 +                  pline("There's no novel by that name.");
 +                  return ((struct obj *)0);
 +              }
 +          }
 +      }
 +
+     /*
+      * Create the object, then fine-tune it.
+      */
+     otmp = typ ? mksobj(typ, TRUE, FALSE) : mkobj(oclass, FALSE);
+     typ = otmp->otyp, oclass = otmp->oclass; /* what we actually got */
+     if (islit &&
+         (typ == OIL_LAMP || typ == MAGIC_LAMP || typ == BRASS_LANTERN ||
+          Is_candle(otmp) || typ == POT_OIL)) {
+         place_object(otmp, u.ux, u.uy);  /* make it viable light source */
+         begin_burn(otmp, FALSE);
+         obj_extract_self(otmp);        /* now release it for caller's use */
+     }
  
-       /* if player specified a reasonable count, maybe honor it */
-       if (cnt > 0 && objects[typ].oc_merge &&
-               (wizard || cnt < rnd(6) ||
-                (cnt <= 7 && Is_candle(otmp)) ||
-                (cnt <= 20 &&
-                 ((oclass == WEAPON_CLASS && is_ammo(otmp))
-                               || typ == ROCK || is_missile(otmp)))))
-           otmp->quan = (long) cnt;
-       if (oclass == VENOM_CLASS) otmp->spe = 1;
-       if (spesgn == 0) {
-               spe = otmp->spe;
-       } else if (wizard) {
-               ;       /* no alteration to spe */
-       } else if (oclass == ARMOR_CLASS || oclass == WEAPON_CLASS ||
-                is_weptool(otmp) ||
-                       (oclass==RING_CLASS && objects[typ].oc_charged)) {
-               if(spe > rnd(5) && spe > otmp->spe) spe = 0;
-               if(spe > 2 && Luck < 0) spesgn = -1;
-       } else {
-               if (oclass == WAND_CLASS) {
-                       if (spe > 1 && spesgn == -1) spe = 1;
-               } else {
-                       if (spe > 0 && spesgn == -1) spe = 0;
-               }
-               if (spe > otmp->spe) spe = otmp->spe;
-       }
+     /* if player specified a reasonable count, maybe honor it */
+     if (cnt > 0 && objects[typ].oc_merge &&
+         (wizard || cnt < rnd(6) ||
+          (cnt <= 7 && Is_candle(otmp)) ||
+          (cnt <= 20 &&
+           ((oclass == WEAPON_CLASS && is_ammo(otmp))
+                 || typ == ROCK || is_missile(otmp)))))
+         otmp->quan = (long) cnt;
+     if (oclass == VENOM_CLASS) otmp->spe = 1;
+     if (spesgn == 0) {
+         spe = otmp->spe;
+     } else if (wizard) {
+         ;     /* no alteration to spe */
+     } else if (oclass == ARMOR_CLASS || oclass == WEAPON_CLASS ||
+          is_weptool(otmp) ||
+             (oclass==RING_CLASS && objects[typ].oc_charged)) {
+         if(spe > rnd(5) && spe > otmp->spe) spe = 0;
+         if(spe > 2 && Luck < 0) spesgn = -1;
+     } else {
+         if (oclass == WAND_CLASS) {
+             if (spe > 1 && spesgn == -1) spe = 1;
+         } else {
+             if (spe > 0 && spesgn == -1) spe = 0;
+         }
+         if (spe > otmp->spe) spe = otmp->spe;
+     }
  
-       if (spesgn == -1) spe = -spe;
-       /* set otmp->spe.  This may, or may not, use spe... */
-       switch (typ) {
-               case TIN: if (contents==EMPTY) {
-                               otmp->corpsenm = NON_PM;
-                               otmp->spe = 0;
-                       } else if (contents==SPINACH) {
-                               otmp->corpsenm = NON_PM;
-                               otmp->spe = 1;
-                       }
-                       break;
-               case SLIME_MOLD: otmp->spe = ftype;
-                       /* Fall through */
-               case SKELETON_KEY: case CHEST: case LARGE_BOX:
-               case HEAVY_IRON_BALL: case IRON_CHAIN: case STATUE:
-                       /* otmp->cobj already done in mksobj() */
-                               break;
+     if (spesgn == -1) spe = -spe;
+     /* set otmp->spe.  This may, or may not, use spe... */
+     switch (typ) {
+         case TIN: if (contents==EMPTY) {
+                 otmp->corpsenm = NON_PM;
+                 otmp->spe = 0;
+             } else if (contents==SPINACH) {
+                 otmp->corpsenm = NON_PM;
+                 otmp->spe = 1;
+             }
+             break;
+         case SLIME_MOLD: otmp->spe = ftype;
+             /* Fall through */
+         case SKELETON_KEY: case CHEST: case LARGE_BOX:
+         case HEAVY_IRON_BALL: case IRON_CHAIN: case STATUE:
+             /* otmp->cobj already done in mksobj() */
+                 break;
  #ifdef MAIL
-               case SCR_MAIL: otmp->spe = 1; break;
+         case SCR_MAIL: otmp->spe = 1; break;
  #endif
-               case WAN_WISHING:
-                       if (!wizard) {
-                               otmp->spe = (rn2(10) ? -1 : 0);
-                               break;
-                       }
-                       /* fall through, if wizard */
-               default: otmp->spe = spe;
-       }
+         case WAN_WISHING:
+             if (!wizard) {
+                 otmp->spe = (rn2(10) ? -1 : 0);
+                 break;
+             }
+             /* fall through, if wizard */
+         default: otmp->spe = spe;
+     }
  
-       /* set otmp->corpsenm or dragon scale [mail] */
-       if (mntmp >= LOW_PM) {
-               if (mntmp == PM_LONG_WORM_TAIL) mntmp = PM_LONG_WORM;
-               switch (typ) {
-               case TIN:
-                       otmp->spe = 0; /* No spinach */
-                       if (dead_species(mntmp, FALSE)) {
-                           otmp->corpsenm = NON_PM;    /* it's empty */
-                       } else if (!(mons[mntmp].geno & G_UNIQ) &&
-                                  !(mvitals[mntmp].mvflags & G_NOCORPSE) &&
-                                  mons[mntmp].cnutrit != 0) {
-                           otmp->corpsenm = mntmp;
-                       }
-                       break;
-               case CORPSE:
-                       if (!(mons[mntmp].geno & G_UNIQ) &&
-                                  !(mvitals[mntmp].mvflags & G_NOCORPSE)) {
-                           if (mons[mntmp].msound == MS_GUARDIAN)
-                               mntmp = genus(mntmp,1);
-                           set_corpsenm(otmp, mntmp);
-                       }
-                       break;
-               case FIGURINE:
-                       if (!(mons[mntmp].geno & G_UNIQ)
-                           && !is_human(&mons[mntmp])
+     /* set otmp->corpsenm or dragon scale [mail] */
+     if (mntmp >= LOW_PM) {
+         if (mntmp == PM_LONG_WORM_TAIL) mntmp = PM_LONG_WORM;
+         switch (typ) {
+         case TIN:
+             otmp->spe = 0; /* No spinach */
+             if (dead_species(mntmp, FALSE)) {
+                 otmp->corpsenm = NON_PM;      /* it's empty */
+             } else if (!(mons[mntmp].geno & G_UNIQ) &&
+                    !(mvitals[mntmp].mvflags & G_NOCORPSE) &&
+                    mons[mntmp].cnutrit != 0) {
+                 otmp->corpsenm = mntmp;
+             }
+             break;
+         case CORPSE:
+             if (!(mons[mntmp].geno & G_UNIQ) &&
+                    !(mvitals[mntmp].mvflags & G_NOCORPSE)) {
+                 if (mons[mntmp].msound == MS_GUARDIAN)
+                     mntmp = genus(mntmp,1);
+                 set_corpsenm(otmp, mntmp);
+             }
+             break;
+         case FIGURINE:
+             if (!(mons[mntmp].geno & G_UNIQ)
+                 && !is_human(&mons[mntmp])
  #ifdef MAIL
-                           && mntmp != PM_MAIL_DAEMON
+                 && mntmp != PM_MAIL_DAEMON
  #endif
-                                                       )
-                               otmp->corpsenm = mntmp;
-                       break;
-               case EGG:
-                       mntmp = can_be_hatched(mntmp);
-                       /* this also sets hatch timer if appropriate */
-                       set_corpsenm(otmp, mntmp);
-                       break;
-               case STATUE: otmp->corpsenm = mntmp;
-                       if (Has_contents(otmp) && verysmall(&mons[mntmp]))
-                           delete_contents(otmp);      /* no spellbook */
-                       otmp->spe = ishistoric ? STATUE_HISTORIC : 0;
-                       break;
-               case SCALE_MAIL:
-                       /* Dragon mail - depends on the order of objects */
-                       /*               & dragons.                      */
-                       if (mntmp >= PM_GRAY_DRAGON &&
-                                               mntmp <= PM_YELLOW_DRAGON)
-                           otmp->otyp = GRAY_DRAGON_SCALE_MAIL +
-                                                   mntmp - PM_GRAY_DRAGON;
-                       break;
-               }
-       }
-       /* set blessed/cursed -- setting the fields directly is safe
-        * since weight() is called below and addinv() will take care
-        * of luck */
-       if (iscursed) {
-               curse(otmp);
-       } else if (uncursed) {
-               otmp->blessed = 0;
-               otmp->cursed = (Luck < 0 && !wizard);
-       } else if (blessed) {
-               otmp->blessed = (Luck >= 0 || wizard);
-               otmp->cursed = (Luck < 0 && !wizard);
-       } else if (spesgn < 0) {
-               curse(otmp);
-       }
+                             )
+                 otmp->corpsenm = mntmp;
+             break;
+         case EGG:
+             mntmp = can_be_hatched(mntmp);
+             /* this also sets hatch timer if appropriate */
+             set_corpsenm(otmp, mntmp);
+             break;
+         case STATUE: otmp->corpsenm = mntmp;
+             if (Has_contents(otmp) && verysmall(&mons[mntmp]))
+                 delete_contents(otmp);        /* no spellbook */
+             otmp->spe = ishistoric ? STATUE_HISTORIC : 0;
+             break;
+         case SCALE_MAIL:
+             /* Dragon mail - depends on the order of objects */
+             /*                 & dragons.                      */
+             if (mntmp >= PM_GRAY_DRAGON &&
+                         mntmp <= PM_YELLOW_DRAGON)
+                 otmp->otyp = GRAY_DRAGON_SCALE_MAIL +
+                             mntmp - PM_GRAY_DRAGON;
+             break;
+         }
+     }
  
-       /* set eroded */
-       if (is_damageable(otmp) || otmp->otyp == CRYSKNIFE) {
-           if (eroded && (is_flammable(otmp) || is_rustprone(otmp)))
-                   otmp->oeroded = eroded;
-           if (eroded2 && (is_corrodeable(otmp) || is_rottable(otmp)))
-                   otmp->oeroded2 = eroded2;
+     /* set blessed/cursed -- setting the fields directly is safe
+      * since weight() is called below and addinv() will take care
+      * of luck */
+     if (iscursed) {
+         curse(otmp);
+     } else if (uncursed) {
+         otmp->blessed = 0;
+         otmp->cursed = (Luck < 0 && !wizard);
+     } else if (blessed) {
+         otmp->blessed = (Luck >= 0 || wizard);
+         otmp->cursed = (Luck < 0 && !wizard);
+     } else if (spesgn < 0) {
+         curse(otmp);
+     }
  
-           /* set erodeproof */
-           if (erodeproof && !eroded && !eroded2)
-                   otmp->oerodeproof = (Luck >= 0 || wizard);
-       }
+     /* set eroded */
+     if (is_damageable(otmp) || otmp->otyp == CRYSKNIFE) {
+         if (eroded && (is_flammable(otmp) || is_rustprone(otmp)))
+             otmp->oeroded = eroded;
+         if (eroded2 && (is_corrodeable(otmp) || is_rottable(otmp)))
+             otmp->oeroded2 = eroded2;
  
-       /* set otmp->recharged */
-       if (oclass == WAND_CLASS) {
-           /* prevent wishing abuse */
-           if (otmp->otyp == WAN_WISHING && !wizard) rechrg = 1;
-           otmp->recharged = (unsigned)rechrg;
-       }
+         /* set erodeproof */
+         if (erodeproof && !eroded && !eroded2)
+             otmp->oerodeproof = (Luck >= 0 || wizard);
+     }
  
-       /* set poisoned */
-       if (ispoisoned) {
-           if (is_poisonable(otmp))
-               otmp->opoisoned = (Luck >= 0);
-           else if (oclass == FOOD_CLASS)
-               /* try to taint by making it as old as possible */
-               otmp->age = 1L;
-       }
-       /* and [un]trapped */
-       if (trapped) {
-           if (Is_box(otmp) || typ == TIN)
-               otmp->otrapped = (trapped == 1);
-       }
+     /* set otmp->recharged */
+     if (oclass == WAND_CLASS) {
+         /* prevent wishing abuse */
+         if (otmp->otyp == WAN_WISHING && !wizard) rechrg = 1;
+         otmp->recharged = (unsigned)rechrg;
+     }
  
-       if (isgreased) otmp->greased = 1;
+     /* set poisoned */
+     if (ispoisoned) {
+         if (is_poisonable(otmp))
+         otmp->opoisoned = (Luck >= 0);
+         else if (oclass == FOOD_CLASS)
+         /* try to taint by making it as old as possible */
+         otmp->age = 1L;
+     }
+     /* and [un]trapped */
+     if (trapped) {
+         if (Is_box(otmp) || typ == TIN)
+         otmp->otrapped = (trapped == 1);
+     }
  
-       if (isdiluted && otmp->oclass == POTION_CLASS &&
-                       otmp->otyp != POT_WATER)
-               otmp->odiluted = 1;
+     if (isgreased) otmp->greased = 1;
  
-       /* set tin variety */
-       if (otmp->otyp == TIN && tvariety >= 0 && (rn2(4) || wizard))
-               set_tin_variety(otmp, tvariety);
+     if (isdiluted && otmp->oclass == POTION_CLASS &&
+             otmp->otyp != POT_WATER)
+         otmp->odiluted = 1;
  
-       if (name) {
-               const char *aname;
-               short objtyp;
+     /* set tin variety */
+     if (otmp->otyp == TIN && tvariety >= 0 && (rn2(4) || wizard))
+         set_tin_variety(otmp, tvariety);
  
-               /* an artifact name might need capitalization fixing */
-               aname = artifact_name(name, &objtyp);
-               if (aname && objtyp == otmp->otyp) name = aname;
+     if (name) {
+         const char *aname;
+         short objtyp;
  
-               /* 3.6.0 tribute - fix up novel */
-               if (otmp->otyp == SPE_NOVEL) {
-                   int novidx = 0;
-                   const char *novelname;
+         /* an artifact name might need capitalization fixing */
+         aname = artifact_name(name, &objtyp);
+         if (aname && objtyp == otmp->otyp) name = aname;
  
-                   novelname = lookup_novel(name, &novidx);
-                   if (novelname) {
-                       otmp->novelidx = novidx;
-                       name = novelname;
-                   }
-               }                       
++        /* 3.6.0 tribute - fix up novel */
++        if (otmp->otyp == SPE_NOVEL) {
++            int novidx = 0;
++            const char *novelname;
 +
-               otmp = oname(otmp, name);
-               if (otmp->oartifact) {
-                       otmp->quan = 1L;
-                       u.uconduct.wisharti++;
-               }
++            novelname = lookup_novel(name, &novidx);
++            if (novelname) {
++                 otmp->novelidx = novidx;
++                 name = novelname;
++            }
 +      }
 +
-       /* more wishing abuse: don't allow wishing for certain artifacts */
-       /* and make them pay; charge them for the wish anyway! */
-       if ((is_quest_artifact(otmp) ||
-                   (otmp->oartifact && rn2(nartifact_exist()) > 1)) &&
-               !wizard) {
-           artifact_exists(otmp, safe_oname(otmp), FALSE);
-           obfree(otmp, (struct obj *) 0);
-           otmp = &zeroobj;
-           pline("For a moment, you feel %s in your %s, but it disappears!",
-                 something,
-                 makeplural(body_part(HAND)));
-       }
+         otmp = oname(otmp, name);
+         if (otmp->oartifact) {
+             otmp->quan = 1L;
+             u.uconduct.wisharti++;    /* KMH, conduct */
+         }
+     }
  
-       if (halfeaten && otmp->oclass == FOOD_CLASS) {
-               if (otmp->otyp == CORPSE)
-                       otmp->oeaten = mons[otmp->corpsenm].cnutrit;
-               else otmp->oeaten = objects[otmp->otyp].oc_nutrition;
-               /* (do this adjustment before setting up object's weight) */
-               consume_oeaten(otmp, 1);
-       }
-       otmp->owt = weight(otmp);
-       if (very && otmp->otyp == HEAVY_IRON_BALL) otmp->owt += 160;
+     /* more wishing abuse: don't allow wishing for certain artifacts */
+     /* and make them pay; charge them for the wish anyway! */
+     if ((is_quest_artifact(otmp) ||
+             (otmp->oartifact && rn2(nartifact_exist()) > 1)) &&
+         !wizard) {
+         artifact_exists(otmp, safe_oname(otmp), FALSE);
+         obfree(otmp, (struct obj *) 0);
+         otmp = &zeroobj;
+         pline("For a moment, you feel %s in your %s, but it disappears!",
+           something,
+           makeplural(body_part(HAND)));
+     }
+     if (halfeaten && otmp->oclass == FOOD_CLASS) {
+         if (otmp->otyp == CORPSE)
+             otmp->oeaten = mons[otmp->corpsenm].cnutrit;
+         else otmp->oeaten = objects[otmp->otyp].oc_nutrition;
+         /* (do this adjustment before setting up object's weight) */
+         consume_oeaten(otmp, 1);
+     }
+     otmp->owt = weight(otmp);
+     if (very && otmp->otyp == HEAVY_IRON_BALL) otmp->owt += 160;
  
-       return(otmp);
+     return(otmp);
  }
  
  int
diff --cc src/trap.c
Simple merge
diff --cc src/zap.c
Simple merge
index 09f3747f370263c5d345e8b33f6447ea11e5a533,5c9a69b73805f11f02c2f516c21aec0243ee543b..257a277e6057351f3f54114e4cf63fad5c6f4ff1
@@@ -6930,26 -7006,7 +7006,25 @@@ P = (108, 145, 182
    MMMMMMMJJJAAMMMM
    MMMMMMMMMMMMMMMM
  }
 -# tile 368 (papyrus / Book of the Dead)
 +# tile 363 (paperback / novel)
 +{
 +  MMMMMMMMMMMMMMMM
 +  MMMMMMMMMMMMMMMM
 +  MMMMMMMMMMMMMMMM
 +  MMMMEEEEMMMMMMMM
 +  MMMMEEEEEEMMMMMM
 +  MMMEEEEEEEEEEMMM
 +  MMMEEEEEEEEEBMMM
 +  MMEEEEEEEEEEOAMM
 +  MMEEEEEEEEEBOAAM
 +  MEEEEEEEEEEOEAMM
 +  MEEEEEEEEEBOAAMM
 +  MEOOEEEEEEOEAMMM
 +  MMEEOOOEEBOAAMMM
 +  MMMMEEEOOOEAMMMM
 +  MMMMMMMEEEAAMMMM
 +  MMMMMMMMMMMMMMMM
 +}
- # tile 364 (papyrus / Book of the Dead)
  {
    MMMMMMMMMMMMMMMM
    MMMMMMMMMMMMMMMM