home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Games / NetHack 3.1.3 / source / src / read.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-08-01  |  30.9 KB  |  931 lines  |  [TEXT/R*ch]

  1. /*    SCCS Id: @(#)read.c    3.1    93/05/26    */
  2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  3. /* NetHack may be freely redistributed.  See license for details. */
  4.  
  5. #include "hack.h"
  6.  
  7. /* elven armor vibrates warningly when enchanted beyond a limit */
  8. #define is_elven_armor(optr)    ((optr)->otyp == ELVEN_LEATHER_HELM\
  9.                 || (optr)->otyp == ELVEN_MITHRIL_COAT\
  10.                 || (optr)->otyp == ELVEN_CLOAK\
  11.                 || (optr)->otyp == ELVEN_SHIELD\
  12.                 || (optr)->otyp == ELVEN_BOOTS)
  13.  
  14. #ifdef OVLB
  15.  
  16. boolean    known;
  17.  
  18. static NEARDATA const char readable[] =
  19.            { ALL_CLASSES, SCROLL_CLASS, SPBOOK_CLASS, 0 };
  20. static const char all_count[] = { ALLOW_COUNT, ALL_CLASSES, 0 };
  21.  
  22. static void FDECL(wand_explode, (struct obj *));
  23. static void NDECL(do_class_genocide);
  24. static void FDECL(stripspe,(struct obj *));
  25. static void FDECL(p_glow1,(struct obj *));
  26. static void FDECL(p_glow2,(struct obj *,const char *));
  27. static void FDECL(forget,(BOOLEAN_P));
  28.  
  29. #endif /* OVLB */
  30.  
  31. #ifndef OVERLAY
  32. STATIC_DCL void FDECL(set_lit, (int,int,genericptr_t));
  33. #endif
  34.  
  35. #ifdef OVLB
  36.  
  37. int
  38. doread()
  39. {
  40.     register struct obj *scroll;
  41.     register boolean confused;
  42.  
  43.     known = FALSE;
  44.     if(check_capacity(NULL)) return (0);
  45.     scroll = getobj(readable, "read");
  46.     if(!scroll) return(0);
  47.  
  48.     /* outrumor has its own blindness check */
  49.     if(scroll->otyp == FORTUNE_COOKIE) {
  50.         if(flags.verbose)
  51.         You("break up the cookie and throw away the pieces.");
  52.         outrumor(bcsign(scroll), TRUE);
  53.         useup(scroll);
  54.         return(1);
  55.     } else if (scroll->oclass != SCROLL_CLASS
  56.         && scroll->oclass != SPBOOK_CLASS) {
  57.         pline(silly_thing_to, "read");
  58.         return(0);
  59.     } else if (Blind) {
  60.         const char *what = 0;
  61.         if (scroll->oclass == SPBOOK_CLASS)
  62.         what = "mystic runes";
  63.         else if (!scroll->dknown)
  64.         what = "formula on the scroll";
  65.         if (what) {
  66.         pline("Being blind, you cannot read the %s.", what);
  67.         return(0);
  68.         }
  69.     }
  70.  
  71.     confused = (Confusion != 0);
  72.     if(scroll->oclass == SPBOOK_CLASS) {
  73.         if(confused) {
  74.         You("cannot grasp the meaning of this tome.");
  75.         return(0);
  76.         } else
  77.         return(study_book(scroll));
  78.     }
  79. #ifndef NO_SIGNAL
  80.     scroll->in_use = TRUE;    /* scroll, not spellbook, now being read */
  81. #endif
  82.     if(scroll->otyp != SCR_BLANK_PAPER) {
  83.       if(Blind)
  84.         pline("As you pronounce the formula on it, the scroll disappears.");
  85.       else
  86.         pline("As you read the scroll, it disappears.");
  87.       if(confused) {
  88.         if (Hallucination)
  89.         pline("Being so trippy, you screw up...");
  90.         else
  91.         pline("Being confused, you mispronounce the magic words...");
  92.       }
  93.     }
  94.     if(!seffects(scroll))  {
  95.         if(!objects[scroll->otyp].oc_name_known) {
  96.             if(known) {
  97.             makeknown(scroll->otyp);
  98.             more_experienced(0,10);
  99.             } else if(!objects[scroll->otyp].oc_uname)
  100.             docall(scroll);
  101.         }
  102.         if(scroll->otyp != SCR_BLANK_PAPER)
  103.             useup(scroll);
  104. #ifndef NO_SIGNAL
  105.         else scroll->in_use = FALSE;
  106. #endif
  107.     }
  108.     return(1);
  109. }
  110.  
  111. static void
  112. stripspe(obj)
  113. register struct obj *obj;
  114. {
  115.     if (obj->blessed) pline(nothing_happens);
  116.     else {
  117.         if (obj->spe > 0) {
  118.             obj->spe = 0;
  119.             if (obj->otyp == OIL_LAMP || obj->otyp == BRASS_LANTERN)
  120.             obj->age = 0;
  121.             Your("%s vibrates briefly.",xname(obj));
  122.         } else pline(nothing_happens);
  123.     }
  124. }
  125.  
  126. static void
  127. p_glow1(otmp)
  128. register struct obj    *otmp;
  129. {
  130.     Your("%s %s briefly.", xname(otmp),
  131.         Blind ? "vibrates" : "glows");
  132. }
  133.  
  134. static void
  135. p_glow2(otmp,color)
  136. register struct obj    *otmp;
  137. register const char *color;
  138. {
  139.     Your("%s %s%s for a moment.",
  140.         xname(otmp),
  141.         Blind ? "vibrates" : "glows ",
  142.         Blind ? (const char *)"" : Hallucination ? hcolor() : color);
  143. }
  144.  
  145. /*
  146.  * recharge an object; curse_bless is -1 if the recharging implement
  147.  * was cursed, +1 if blessed, 0 otherwise.
  148.  */
  149. void
  150. recharge(obj, curse_bless)
  151. struct obj *obj;
  152. int curse_bless;
  153. {
  154.     register int n;
  155.     boolean is_cursed, is_blessed;
  156.  
  157.     is_cursed = curse_bless < 0;
  158.     is_blessed = curse_bless > 0;
  159.  
  160.     if (obj->oclass == WAND_CLASS) {
  161.         if (obj->otyp == WAN_WISHING) {
  162.         if (obj->recharged) {    /* recharged once already? */
  163.             wand_explode(obj);
  164.             return;
  165.         }
  166.         if (is_cursed) stripspe(obj);
  167.         else if (is_blessed) {
  168.             if (obj->spe != 3) {
  169.             obj->spe = 3;
  170.             p_glow2(obj,blue);
  171.             } else {
  172.             wand_explode(obj);
  173.             return;
  174.             }
  175.         } else {
  176.             if (obj->spe < 3) {
  177.             obj->spe++;
  178.             p_glow2(obj,blue);
  179.             } else pline(nothing_happens);
  180.         }
  181.         obj->recharged = 1; /* another recharging disallowed */
  182.         } else {
  183.         if (is_cursed) stripspe(obj);
  184.         else if (is_blessed) {
  185.             if (objects[obj->otyp].oc_dir == NODIR) {
  186.             n = rn1(5,11);
  187.             if (obj->spe < n) obj->spe = n;
  188.             else obj->spe++;
  189.             } else {
  190.             n = rn1(5,4);
  191.             if (obj->spe < n) obj->spe = n;
  192.             else obj->spe++;
  193.             }
  194.             p_glow2(obj,blue);
  195.         } else {
  196.             obj->spe++;
  197.             p_glow1(obj);
  198.         }
  199.         }
  200.     } else if (obj->oclass == RING_CLASS &&
  201.                     objects[obj->otyp].oc_charged) {
  202.         /* charging does not affect ring's curse/bless status */
  203.         int s = is_blessed ? rnd(3) : is_cursed ? -rnd(2) : 1;
  204.         boolean is_on = (obj == uleft || obj == uright);
  205.  
  206.         /* destruction depends on current state, not adjustment */
  207.         if (obj->spe > rn2(7) || obj->spe <= -5) {
  208.         Your("%s pulsates momentarily, then explodes!",
  209.              xname(obj));
  210.         if (is_on) Ring_gone(obj);
  211.         s = rnd(3 * abs(obj->spe));    /* amount of damage */
  212.         useup(obj);
  213.         losehp(s, "exploding ring", KILLED_BY_AN);
  214.         } else {
  215.         long mask = is_on ? (obj == uleft ? LEFT_RING :
  216.                      RIGHT_RING) : 0L;
  217.         Your("%s spins %sclockwise for a moment.",
  218.              xname(obj), s < 0 ? "counter" : "");
  219.         /* cause attributes and/or properties to be updated */
  220.         if (is_on) Ring_off(obj);
  221.         obj->spe += s;    /* update the ring while it's off */
  222.         if (is_on) setworn(obj, mask), Ring_on(obj);
  223.         /* oartifact: if a touch-sensitive artifact ring is
  224.            ever created the above will need to be revised  */
  225.         }
  226.     } else {
  227.         switch(obj->otyp) {
  228.         case MAGIC_MARKER:
  229.         if (is_cursed) stripspe(obj);
  230.         else if (obj->recharged) {
  231.             if (obj->spe < 3)
  232.             Your("marker seems permanently dried out.");
  233.             else
  234.             pline(nothing_happens);
  235.         } else if (is_blessed) {
  236.             n = obj->spe;
  237.             if (n < 50) obj->spe = 50;
  238.             if (n >= 50 && n < 75) obj->spe = 75;
  239.             if (n >= 75) obj->spe += 10;
  240.             p_glow2(obj,blue);
  241.             obj->recharged = 1;
  242.         } else {
  243.             if (obj->spe < 50) obj->spe = 50;
  244.             else obj->spe++;
  245.             p_glow2(obj,White);
  246.             obj->recharged = 1;
  247.         }
  248.         break;
  249.         case OIL_LAMP:
  250.         case BRASS_LANTERN:
  251.         if (is_cursed) {
  252.             stripspe(obj);
  253.             if (obj->lamplit) {
  254.             if (!Blind)
  255.                 pline("%s goes out!", The(xname(obj)));
  256.             obj->lamplit = 0;
  257.             check_lamps();
  258.             }
  259.         } else if (is_blessed) {
  260.             obj->spe = 1;
  261.             obj->age = 1500;
  262.             p_glow2(obj,blue);
  263.         } else {
  264.             obj->spe = 1;
  265.             obj->age += 750;
  266.             if (obj->age > 1500) obj->age = 1500;
  267.             p_glow1(obj);
  268.         }
  269.         break;
  270.         case CRYSTAL_BALL:
  271.         if (is_cursed) stripspe(obj);
  272.         else if (is_blessed) {
  273.             obj->spe = 6;
  274.             p_glow2(obj,blue);
  275.         } else {
  276.             if (obj->spe < 5) {
  277.             obj->spe++;
  278.             p_glow1(obj);
  279.             } else pline(nothing_happens);
  280.         }
  281.         break;
  282.         case HORN_OF_PLENTY:
  283.         case BAG_OF_TRICKS:
  284.         case CAN_OF_GREASE:
  285.         if (is_cursed) stripspe(obj);
  286.         else if (is_blessed) {
  287.             if (obj->spe <= 10)
  288.             obj->spe += rn1(10, 6);
  289.             else obj->spe += rn1(5, 6);
  290.             p_glow2(obj,blue);
  291.         } else {
  292.             obj->spe += rnd(5);
  293.             p_glow1(obj);
  294.         }
  295.         break;
  296.         case MAGIC_FLUTE:
  297.         case MAGIC_HARP:
  298.         case FROST_HORN:
  299.         case FIRE_HORN:
  300.         case DRUM_OF_EARTHQUAKE:
  301.         if (is_cursed) {
  302.             stripspe(obj);
  303.         } else if (is_blessed) {
  304.             obj->spe += d(2,4);
  305.             p_glow2(obj,blue);
  306.         } else {
  307.             obj->spe += rnd(4);
  308.             p_glow1(obj);
  309.         }
  310.         break;
  311.         default:
  312.         You("have a feeling of loss.");
  313.         break;
  314.         } /* switch */
  315.     }
  316. }
  317.  
  318. /*
  319.  * forget some things (e.g. after reading a scroll of amnesia). abs(howmuch)
  320.  * controls the level of forgetfulness; 0 == part of the map, 1 == all of
  321.  * of map,  2 == part of map + spells, 3 == all of map + spells.
  322.  */
  323.  
  324. static void
  325. forget(howmuch)
  326. boolean howmuch;
  327. {
  328.     register int zx, zy;
  329.     register struct trap *trap;
  330.  
  331.     if (Punished) u.bc_felt = 0;    /* forget felt ball&chain */
  332.  
  333.     known = TRUE;
  334.     for(zx = 0; zx < COLNO; zx++) for(zy = 0; zy < ROWNO; zy++)
  335.         if (howmuch & 1 || rn2(7)) {
  336.         /* Zonk all memory of this location. */
  337.         levl[zx][zy].seen = levl[zx][zy].waslit = 0;
  338.         levl[zx][zy].glyph = cmap_to_glyph(S_stone);
  339.         }
  340.  
  341.     /* forget all traps (except the one the hero is in :-) */
  342.     for (trap = ftrap; trap; trap = trap->ntrap)
  343.         if (trap->tx != u.ux || trap->ty != u.uy) trap->tseen = 0;
  344.  
  345.     /*
  346.      * Make sure that what was seen is restored correctly.  To do this,
  347.      * we need to go blind for an instant --- turn off the display,
  348.      * then restart it.  All this work is needed to correctly handle
  349.      * walls which are stone on one side and wall on the other.  Turning
  350.      * off the seen bit above will make the wall revert to stone,  but
  351.      * there are cases where we don't want this to happen.  The easiest
  352.      * thing to do is to run it through the vision system again, which
  353.      * is always correct.
  354.      */
  355.     docrt();        /* this correctly will reset vision */
  356.  
  357.     if(howmuch & 2) losespells();
  358. }
  359.  
  360. int
  361. seffects(sobj)
  362. register struct obj    *sobj;
  363. {
  364.     register int cval;
  365.     register boolean confused = (Confusion != 0);
  366.     register struct obj *otmp;
  367.  
  368.     if (objects[sobj->otyp].oc_magic)
  369.         exercise(A_WIS, TRUE);        /* just for trying */
  370.     switch(sobj->otyp) {
  371. #ifdef MAIL
  372.     case SCR_MAIL:
  373.         known = TRUE;
  374.         if (sobj->spe)
  375.             pline("This seems to be junk mail addressed to the finder of the Eye of Larn.");
  376.         /* note to the puzzled: the game Larn actually sends you junk
  377.          * mail if you win!
  378.          */
  379.         else readmail(sobj);
  380.         break;
  381. #endif
  382.     case SCR_ENCHANT_ARMOR:
  383.         {
  384.         register schar s;
  385.         otmp = some_armor();
  386.         if(!otmp) {
  387.             strange_feeling(sobj,
  388.                     !Blind ? "Your skin glows then fades." :
  389.                     "Your skin feels warm for a moment.");
  390.             exercise(A_CON, !sobj->cursed);
  391.             exercise(A_STR, !sobj->cursed);
  392.             return(1);
  393.         }
  394.         if(confused) {
  395.             otmp->oerodeproof = !(sobj->cursed);
  396.             if(Blind) {
  397.                 otmp->rknown = FALSE;
  398.                 Your("%s feels warm for a moment.",
  399.                 xname(otmp));
  400.             } else {
  401.                 otmp->rknown = TRUE;
  402.                 Your("%s is covered by a %s %s %s!",
  403.                 xname(otmp),
  404.                 sobj->cursed ? "mottled" : "shimmering",
  405.                 Hallucination ? hcolor() :
  406.                   sobj->cursed ? Black : golden,
  407.                 sobj->cursed ? "glow" :
  408.                   (is_shield(otmp) ? "layer" : "shield"));
  409.             }
  410.             if (otmp->oerodeproof && otmp->oeroded) {
  411.                 otmp->oeroded = 0;
  412.                 Your("%s %ss good as new!",
  413.                  xname(otmp), Blind ? "feel" : "look");
  414.             }
  415.             break;
  416.         }
  417.         if((otmp->spe > ((otmp->otyp == ELVEN_MITHRIL_COAT) ? 5 : 3))
  418.                 && rn2(otmp->spe) && !sobj->cursed) {
  419.         Your("%s violently %s%s for a while, then evaporates.",
  420.                 xname(otmp),
  421.                 Blind ? "vibrates" : "glows ",
  422.                 Blind ? nul : Hallucination ? hcolor() : silver);
  423.             if(is_cloak(otmp)) (void) Cloak_off();
  424.             if(is_boots(otmp)) (void) Boots_off();
  425.             if(is_helmet(otmp)) (void) Helmet_off();
  426.             if(is_gloves(otmp)) (void) Gloves_off();
  427.             if(is_shield(otmp)) (void) Shield_off();
  428.             if(otmp == uarm) (void) Armor_gone();
  429.             useup(otmp);
  430.             break;
  431.         }
  432.         s = sobj->cursed ? -1 :
  433.             otmp->spe >= 9 ? (rn2(otmp->spe) == 0) :
  434.             sobj->blessed ? rnd(3-otmp->spe/3) : 1;
  435.         if (s >= 0 && otmp->otyp >= GRAY_DRAGON_SCALES &&
  436.                     otmp->otyp <= YELLOW_DRAGON_SCALES) {
  437.             /* dragon scales get turned into dragon scale mail */
  438.             Your("%s merges and hardens!", xname(otmp));
  439.             setworn((struct obj *)0, W_ARM);
  440.             /* assumes same order */
  441.             otmp->otyp = GRAY_DRAGON_SCALE_MAIL +
  442.                         otmp->otyp - GRAY_DRAGON_SCALES;
  443.             otmp->cursed = 0;
  444.             if (sobj->blessed) {
  445.                 otmp->spe++;
  446.                 otmp->blessed = 1;
  447.             }
  448.             otmp->known = 1;
  449.             setworn(otmp, W_ARM);
  450.             break;
  451.         }
  452.         Your("%s %s%s%s for a %s.",
  453.             xname(otmp),
  454.                 s == 0 ? "violently " : nul,
  455.             Blind ? "vibrates" : "glows ",
  456.             Blind ? nul : Hallucination ? hcolor() :
  457.               sobj->cursed ? Black : silver,
  458.               (s*s>1) ? "while" : "moment");
  459.         otmp->cursed = sobj->cursed;
  460.         if (!otmp->blessed || sobj->cursed)
  461.             otmp->blessed = sobj->blessed;
  462.         if (s) {
  463.             otmp->spe += s;
  464.             adj_abon(otmp, s);
  465.         }
  466.  
  467.         /* an elven magic clue, cookie@keebler */
  468.         if((otmp->spe > ((otmp->otyp == ELVEN_MITHRIL_COAT) ? 5 : 3))
  469.                 && (is_elven_armor(otmp) || !rn2(7)))
  470.             Your("%s suddenly vibrates %s.",
  471.                 xname(otmp),
  472.                 Blind ? "again" : "unexpectedly");
  473.         break;
  474.         }
  475.     case SCR_DESTROY_ARMOR:
  476.         {
  477.         otmp = some_armor();
  478.         if(confused) {
  479.             if(!otmp) {
  480.                 strange_feeling(sobj,"Your bones itch.");
  481.                 exercise(A_STR, FALSE);
  482.                 exercise(A_CON, FALSE);
  483.                 return(1);
  484.             }
  485.             otmp->oerodeproof = sobj->cursed;
  486.             p_glow2(otmp,purple);
  487.             break;
  488.         }
  489.         if(!sobj->cursed || !otmp || !otmp->cursed) {
  490.             if(!destroy_arm(otmp)) {
  491.             strange_feeling(sobj,"Your skin itches.");
  492.             exercise(A_STR, FALSE);
  493.             exercise(A_CON, FALSE);
  494.             return(1);
  495.             }
  496.         } else {    /* armor and scroll both cursed */
  497.             Your("%s vibrates.", xname(otmp));
  498.             if (otmp->spe >= -6) otmp->spe--;
  499.             make_stunned(HStun + rn1(10, 10), TRUE);
  500.         }
  501.         }
  502.         break;
  503.     case SCR_CONFUSE_MONSTER:
  504.     case SPE_CONFUSE_MONSTER:
  505.         if(u.usym != S_HUMAN || sobj->cursed) {
  506.             if(!HConfusion) You("feel confused.");
  507.             make_confused(HConfusion + rnd(100),FALSE);
  508.         } else  if(confused) {
  509.             if(!sobj->blessed) {
  510.             Your("%s begin to %s%s.",
  511.                 makeplural(body_part(HAND)),
  512.                 Blind ? "tingle" : "glow ",
  513.                 Blind ? nul : Hallucination ? hcolor() : purple);
  514.             make_confused(HConfusion + rnd(100),FALSE);
  515.             } else {
  516.             pline("A %s%s surrounds your %s.",
  517.                 Blind ? nul : Hallucination ? hcolor() : red,
  518.                 Blind ? "faint buzz" : " glow",
  519.                 body_part(HEAD));
  520.             make_confused(0L,TRUE);
  521.             }
  522.         } else {
  523.             if (!sobj->blessed) {
  524.             Your("%s%s %s%s.",
  525.             makeplural(body_part(HAND)),
  526.             Blind ? "" : " begin to glow",
  527.             Blind ? (const char *)"tingle" : Hallucination ? hcolor() : red,
  528.             u.umconf ? " even more" : "");
  529.             u.umconf++;
  530.             } else {
  531.             if (Blind)
  532.                 Your("%s tingle %s sharply.",
  533.                 makeplural(body_part(HAND)),
  534.                 u.umconf ? "even more" : "very");
  535.             else
  536.                 Your("%s glow a%s brilliant %s.",
  537.                 makeplural(body_part(HAND)),
  538.                 u.umconf ? "n even more" : "",
  539.                 Hallucination ? hcolor() : red);
  540.             u.umconf += rn1(8, 2);
  541.             }
  542.         }
  543.         break;
  544.     case SCR_SCARE_MONSTER:
  545.     case SPE_CAUSE_FEAR:
  546.         {    register int ct = 0;
  547.         register struct monst *mtmp;
  548.  
  549.         for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
  550.             if(cansee(mtmp->mx,mtmp->my)) {
  551.             if(confused || sobj->cursed) {
  552.                 mtmp->mflee = mtmp->mfrozen = mtmp->msleep = 0;
  553.                 mtmp->mcanmove = 1;
  554.             } else
  555.                 if (! resist(mtmp, sobj->oclass, 0, NOTELL))
  556.                 mtmp->mflee = 1;
  557.             if(!mtmp->mtame) ct++;    /* pets don't laugh at you */
  558.             }
  559.         if(!ct)
  560.               You("hear %s in the distance.",
  561.                    (confused || sobj->cursed) ? "sad wailing" :
  562.                             "maniacal laughter");
  563.         else if(sobj->otyp == SCR_SCARE_MONSTER)
  564.             You("hear %s close by.",
  565.                   (confused || sobj->cursed) ? "sad wailing" :
  566.                          "maniacal laughter");
  567.         break;
  568.         }
  569.     case SCR_BLANK_PAPER:
  570.         if (Blind)
  571.         You("don't remember there being any magic words on this scroll.");
  572.         else
  573.         pline("This scroll seems to be blank.");
  574.         known = TRUE;
  575.         break;
  576.     case SCR_REMOVE_CURSE:
  577.     case SPE_REMOVE_CURSE:
  578.         {    register struct obj *obj;
  579.         if(confused)
  580.             if (Hallucination)
  581.             You("feel the power of the Force against you!");
  582.             else
  583.             You("feel like you need some help.");
  584.         else
  585.             if (Hallucination)
  586.             You("feel in touch with the Universal Oneness.");
  587.             else
  588.             You("feel like someone is helping you.");
  589.  
  590.         if(sobj->cursed) pline("The scroll disintegrates.");
  591.         else {
  592.             for(obj = invent; obj ; obj = obj->nobj)
  593.             if(sobj->blessed || obj->owornmask ||
  594.                (obj->otyp == LOADSTONE)) {
  595.                 if(confused) blessorcurse(obj, 2);
  596.                 else uncurse(obj);
  597.             }
  598.         }
  599.         if(Punished && !confused) unpunish();
  600.         break;
  601.         }
  602.     case SCR_CREATE_MONSTER:
  603. #if defined(WIZARD) || defined(EXPLORE_MODE)
  604.         if (wizard || discover)
  605.         known = TRUE;
  606. #endif /* WIZARD || EXPLORE_MODE */
  607.     case SPE_CREATE_MONSTER:
  608.         {    register int cnt = 1;
  609.  
  610.         if(!rn2(73) && !sobj->blessed) cnt += rnd(4);
  611.         if(confused || sobj->cursed) cnt += 12;
  612.         while(cnt--) {
  613. #ifdef WIZARD
  614.             if(!wizard || !create_particular())
  615. #endif /* WIZARD  */
  616.             (void) makemon (confused ? &mons[PM_ACID_BLOB] :
  617.                     (struct permonst *) 0, u.ux, u.uy);
  618.         }
  619.         /* flush monsters before asking for identification */
  620.         flush_screen(0);
  621.         break;
  622.         }
  623. /*        break;    /*NOTREACHED*/
  624.     case SCR_ENCHANT_WEAPON:
  625.         if(uwep && (uwep->oclass == WEAPON_CLASS ||
  626.                 uwep->otyp == PICK_AXE ||
  627.                 uwep->otyp == UNICORN_HORN) && confused) {
  628.         /* oclass check added 10/25/86 GAN */
  629.             uwep->oerodeproof = !(sobj->cursed);
  630.             if(Blind) {
  631.                 uwep->rknown = FALSE;
  632.                 Your("weapon feels warm for a moment.");
  633.             } else {
  634.                 uwep->rknown = TRUE;
  635.                 Your("%s covered by a %s %s %s!",
  636.                 aobjnam(uwep, "are"),
  637.                 sobj->cursed ? "mottled" : "shimmering",
  638.                 Hallucination ? hcolor() :
  639.                   sobj->cursed ? purple : golden,
  640.                 sobj->cursed ? "glow" : "shield");
  641.             }
  642.             if (uwep->oerodeproof && uwep->oeroded) {
  643.                 uwep->oeroded = 0;
  644.                 Your("%s good as new!",
  645.                  aobjnam(uwep, Blind ? "feel" : "look"));
  646.             }
  647.         } else return !chwepon(sobj,
  648.                        sobj->cursed ? -1 :
  649.                        !uwep ? 1 :
  650.                        uwep->spe >= 9 ? (rn2(uwep->spe) == 0) :
  651.                        sobj->blessed ? rnd(3-uwep->spe/3) : 1);
  652.         break;
  653.     case SCR_TAMING:
  654.     case SPE_CHARM_MONSTER:
  655.         {    register int i,j;
  656.         register int bd = confused ? 5 : 1;
  657.         register struct monst *mtmp;
  658.  
  659.         for(i = -bd; i <= bd; i++) for(j = -bd; j <= bd; j++)
  660.         if(isok(u.ux+i, u.uy+j) && (mtmp = m_at(u.ux+i, u.uy+j))) {
  661.             if(sobj->cursed) {
  662.             if(!mtmp->mtame) mtmp->mpeaceful = 0;
  663.             } else {
  664.             if (mtmp->isshk) {
  665.                 if (!mtmp->mpeaceful) {
  666.                 pline("%s calms down.", Monnam(mtmp));
  667.                 mtmp->mpeaceful = 1;
  668.                 }
  669.             } else if(!resist(mtmp, sobj->oclass, 0, NOTELL))
  670.                 (void) tamedog(mtmp, (struct obj *) 0);
  671.             }
  672.         }
  673.         break;
  674.         }
  675.     case SCR_GENOCIDE:
  676.         You("have found a scroll of genocide!");
  677.         known = TRUE;
  678.         if (sobj->blessed) do_class_genocide();
  679.         else do_genocide(!sobj->cursed | (2 * !!Confusion));
  680.         break;
  681.     case SCR_LIGHT:
  682.         if(!Blind) known = TRUE;
  683.         litroom(!confused && !sobj->cursed, sobj);
  684.         break;
  685.     case SCR_TELEPORTATION:
  686.         if(confused || sobj->cursed) level_tele();
  687.         else {
  688.             if (sobj->blessed && !Teleport_control) {
  689.                 known = TRUE;
  690.                 if (yn("Do you wish to teleport?")=='n')
  691.                     break;
  692.             }
  693.             tele();
  694.             if(Teleport_control || !couldsee(u.ux0, u.uy0) ||
  695.                (distu(u.ux0, u.uy0) >= 16))
  696.                 known = TRUE;
  697.         }
  698.         break;
  699.     case SCR_GOLD_DETECTION:
  700.         if (confused || sobj->cursed) return(trap_detect(sobj));
  701.         else return(gold_detect(sobj));
  702.     case SCR_FOOD_DETECTION:
  703.     case SPE_DETECT_FOOD:
  704.         if (food_detect(sobj))
  705.             return(1);    /* nothing detected */
  706.         break;
  707.     case SPE_IDENTIFY:
  708.         cval = rn2(5);
  709.         goto id;
  710.     case SCR_IDENTIFY:
  711.         /* known = TRUE; */
  712.         if(confused)
  713.             You("identify this as an identify scroll.");
  714.         else
  715.             pline("This is an identify scroll.");
  716.         if (sobj->blessed || (!sobj->cursed && !rn2(5))) {
  717.             cval = rn2(5);
  718.             /* Note: if rn2(5)==0, identify all items */
  719.             if (cval == 1 && sobj->blessed && Luck > 0) ++cval;
  720.         } else    cval = 1;
  721.         useup(sobj);
  722.         makeknown(SCR_IDENTIFY);
  723.     id:
  724.         if(invent && !confused) {
  725.             int ret;
  726.             /* use up `cval' "charges"; 0 is special case */
  727.             do {
  728.             ret = ggetobj("identify", identify, cval);
  729.             if (ret < 0) break;    /* quit or no eligible items */
  730.             } while (ret == 0 || (cval -= ret) > 0);
  731.         }
  732.         return(1);
  733.     case SCR_CHARGING:
  734.         if (confused) {
  735.             You("feel charged up!");
  736.             if (u.uen < u.uenmax)
  737.             u.uen = u.uenmax;
  738.             else
  739.             u.uen = (u.uenmax += d(5,4));
  740.             flags.botl = 1;
  741.             break;
  742.         }
  743.         known = TRUE;
  744.         pline("This is a charging scroll.");
  745.         otmp = getobj(all_count, "charge");
  746.         if (!otmp) break;
  747.         recharge(otmp, sobj->cursed ? -1 : (sobj->blessed ? 1 : 0));
  748.         break;
  749.     case SCR_MAGIC_MAPPING:
  750.         if (level.flags.nommap) {
  751.             Your("mind is filled with crazy lines!");
  752.             if (Hallucination)
  753.             pline("Wow!  Modern art.");
  754.             else
  755.             Your("head spins in bewilderment.");
  756.             make_confused(HConfusion + rnd(30), FALSE);
  757.             break;
  758.         }
  759.         known = TRUE;
  760.     case SPE_MAGIC_MAPPING:
  761.         if (level.flags.nommap) {
  762.             Your("head spins as something blocks the spell!");
  763.             make_confused(HConfusion + rnd(30), FALSE);
  764.             break;
  765.         }
  766.         pline("A map coalesces in your mind!");
  767.         cval = (sobj->cursed && !confused);
  768.         if(cval) HConfusion = 1;    /* to screw up map */
  769.         do_mapping();
  770.         if(cval) {
  771.             HConfusion = 0;        /* restore */
  772.             pline("Unfortunately, you can't grasp the details.");
  773.         }
  774.         break;
  775.     case SCR_AMNESIA:
  776.         known = TRUE;
  777.         forget( ((!sobj->blessed) << 1) | (!confused || sobj->cursed) );
  778.         if (Hallucination) /* Ommmmmm! */
  779.             Your("mind releases itself from mundane concerns.");
  780.         else if (!strncmpi(plname, "Maud", 4))
  781.             pline("As your mind turns inward on itself, you forget everything else.");
  782.         else if (rn2(2))
  783.             pline("Who was that Maud person anyway?");
  784.         else
  785.             pline("Thinking of Maud you forget everything else.");
  786.         exercise(A_WIS, FALSE);
  787.         break;
  788.     case SCR_FIRE:
  789.         /*
  790.          * Note: Modifications have been made as of 3.0 to allow for
  791.          * some damage under all potential cases.
  792.          */
  793.         cval = bcsign(sobj);
  794.         useup(sobj);
  795.         makeknown(SCR_FIRE);
  796.         if(confused) {
  797.             if(Fire_resistance) {
  798.               shieldeff(u.ux, u.uy);
  799.             if(!Blind)
  800.                 pline("Oh, look, what a pretty fire in your %s.",
  801.                 makeplural(body_part(HAND)));
  802.             else You("feel a pleasant warmth in your %s.",
  803.                 makeplural(body_part(HAND)));
  804.             } else {
  805.             pline("The scroll catches fire and you burn your %s.",
  806.                 makeplural(body_part(HAND)));
  807.             losehp(1, "scroll of fire", KILLED_BY_AN);
  808.             }
  809.             return(1);
  810.         }
  811.         if (Underwater)
  812.             pline("The water around you vaporizes violently!");
  813.         else
  814.             pline("The scroll erupts in a tower of flame!");
  815.         explode(u.ux, u.uy, 11, (2*(rn1(3, 3) + 2 * cval) + 1)/3,
  816.                             SCROLL_CLASS);
  817.         return(1);
  818.     case SCR_PUNISHMENT:
  819.         known = TRUE;
  820.         if(confused || sobj->blessed) {
  821.             You("feel guilty.");
  822.             break;
  823.         }
  824.         punish(sobj);
  825.         break;
  826.     default:
  827.         impossible("What weird effect is this? (%u)", sobj->otyp);
  828.     }
  829.     return(0);
  830. }
  831.  
  832. static void
  833. wand_explode(obj)
  834. register struct obj *obj;
  835. {
  836.     Your("%s vibrates violently, and explodes!",xname(obj));
  837.     nhbell();
  838.     losehp(rn2(2*(u.uhpmax+1)/3),"exploding wand", KILLED_BY_AN);
  839.     useup(obj);
  840.     exercise(A_STR, FALSE);
  841. }
  842.  
  843. /*
  844.  * Low-level lit-field update routine.
  845.  */
  846. STATIC_PTR void
  847. set_lit(x,y,val)
  848. int x, y;
  849. genericptr_t val;
  850. {
  851.     levl[x][y].lit = (val == (genericptr_t)-1) ? 0 : 1;
  852.     return;
  853. }
  854.  
  855. void
  856. litroom(on,obj)
  857. register boolean on;
  858. struct obj *obj;
  859. {
  860.     /* first produce the text (provided you're not blind) */
  861.     if(!on) {
  862.         register struct obj *otmp;
  863.  
  864.         if (!Blind) {
  865.             if(u.uswallow) {
  866.             pline("It seems even darker in here than before.");
  867.             return;
  868.             }
  869.             You("are surrounded by darkness!");
  870.         }
  871.  
  872.         /* the magic douses lamps, et al, too */
  873.         for(otmp = invent; otmp; otmp = otmp->nobj)
  874.             if (otmp->lamplit)
  875.             (void) snuff_lit(otmp);
  876.         if (Blind) goto do_it;
  877.     } else {
  878.         if (Blind) goto do_it;
  879.         if(u.uswallow){
  880.             if (is_animal(u.ustuck->data))
  881.                 pline("%s stomach is lit.",
  882.                          s_suffix(Monnam(u.ustuck)));
  883.             else
  884.                 if (is_whirly(u.ustuck->data))
  885.                     pline("%s shines briefly.",
  886.                           Monnam(u.ustuck));
  887.                 else
  888.                     pline("%s glistens.", Monnam(u.ustuck));
  889.             return;
  890.         }
  891.         pline("A lit field surrounds you!");
  892.     }
  893.  
  894. do_it:
  895.     /* No-op in water - can only see the adjacent squares and that's it! */
  896.     if (Underwater || Is_waterlevel(&u.uz)) return;
  897.     /*
  898.      *  If we are darkening the room and the hero is punished but not
  899.      *  blind, then we have to pick up and replace the ball and chain so
  900.      *  that we don't remember them if they are out of sight.
  901.      */
  902.     if (Punished && !on && !Blind)
  903.         move_bc(1, 0, uball->ox, uball->oy, uchain->ox, uchain->oy);
  904.  
  905. #ifdef REINCARNATION
  906.     if (Is_rogue_level(&u.uz)) {
  907.         /* Can't use do_clear_area because MAX_RADIUS is too small */
  908.         /* rogue lighting must light the entire room */
  909.         int rnum = levl[u.ux][u.uy].roomno - ROOMOFFSET;
  910.         int rx, ry;
  911.         if(rnum >= 0) {
  912.         for(rx = rooms[rnum].lx-1; rx <= rooms[rnum].hx+1; rx++)
  913.             for(ry = rooms[rnum].ly-1; ry <= rooms[rnum].hy+1; ry++)
  914.             set_lit(rx, ry, (genericptr_t)((on)? 1 : -1));
  915.         rooms[rnum].rlit = on;
  916.         }
  917.         /* hallways remain dark on the rogue level */
  918.     } else
  919. #endif
  920.         do_clear_area(u.ux,u.uy,
  921.         (obj && obj->oclass==SCROLL_CLASS && obj->blessed) ? 9 : 5,
  922.         set_lit, (genericptr_t)((on)? 1 : -1));
  923.  
  924.     /*
  925.      *  If we are not blind, then force a redraw on all positions in sight
  926.      *  by temporarily blinding the hero.  The vision recalculation will
  927.      *  correctly update all previously seen positions *and* correctly
  928.      *  set the waslit bit [could be messed up from above].
  929.      */
  930.     if (!Blind) {
  931.