home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / HACKSRC.ZIP / READ.C < prev    next >
C/C++ Source or Header  |  1985-10-16  |  14KB  |  548 lines

  1. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  2. /* read.c - version 1.0.3 */
  3.  
  4. #include "hack.h"
  5.  
  6. extern struct monst *makemon();
  7. extern struct obj *mkobj_at();
  8. int identify();
  9.  
  10. doread() {
  11.     register struct obj *scroll;
  12.     register boolean confused = (Confusion != 0);
  13.     register boolean known = FALSE;
  14.  
  15.     scroll = getobj("?", "read");
  16.     if(!scroll) return(0);
  17.     if(!scroll->dknown && Blind) {
  18.         pline("Being blind, you cannot read the formula on the scroll.");
  19.         return(0);
  20.     }
  21.     if(Blind)
  22.       pline("As you pronounce the formula on it, the scroll disappears.");
  23.     else
  24.       pline("As you read the scroll, it disappears.");
  25.     if(confused)
  26.       pline("Being confused, you mispronounce the magic words ... ");
  27.  
  28.     switch(scroll->otyp) {
  29. #ifdef MAIL
  30.     case SCR_MAIL:
  31.         readmail(/* scroll */);
  32.         break;
  33. #endif MAIL
  34.     case SCR_ENCHANT_ARMOR:
  35.         {    extern struct obj *some_armor();
  36.         register struct obj *otmp = some_armor();
  37.         if(!otmp) {
  38.             strange_feeling(scroll,"Your skin glows then fades.");
  39.             return(1);
  40.         }
  41.         if(confused) {
  42.             pline("Your %s glows silver for a moment.",
  43.                 objects[otmp->otyp].oc_name);
  44.             otmp->rustfree = 1;
  45.             break;
  46.         }
  47.         if(otmp->spe > 3 && rn2(otmp->spe)) {
  48.     pline("Your %s glows violently green for a while, then evaporates.",
  49.             objects[otmp->otyp].oc_name);
  50.             useup(otmp);
  51.             break;
  52.         }
  53.         pline("Your %s glows green for a moment.",
  54.             objects[otmp->otyp].oc_name);
  55.         otmp->cursed = 0;
  56.         otmp->spe++;
  57.         break;
  58.         }
  59.     case SCR_DESTROY_ARMOR:
  60.         if(confused) {
  61.             register struct obj *otmp = some_armor();
  62.             if(!otmp) {
  63.                 strange_feeling(scroll,"Your bones itch.");
  64.                 return(1);
  65.             }
  66.             pline("Your %s glows purple for a moment.",
  67.                 objects[otmp->otyp].oc_name);
  68.             otmp->rustfree = 0;
  69.             break;
  70.         }
  71.         if(uarm) {
  72.             pline("Your armor turns to dust and falls to the floor!");
  73.             useup(uarm);
  74.         } else if(uarmh) {
  75.             pline("Your helmet turns to dust and is blown away!");
  76.             useup(uarmh);
  77.         } else if(uarmg) {
  78.             pline("Your gloves vanish!");
  79.             useup(uarmg);
  80.             selftouch("You");
  81.         } else {
  82.             strange_feeling(scroll,"Your skin itches.");
  83.             return(1);
  84.         }
  85.         break;
  86.     case SCR_CONFUSE_MONSTER:
  87.         if(confused) {
  88.             pline("Your hands begin to glow purple.");
  89.             Confusion += rnd(100);
  90.         } else {
  91.             pline("Your hands begin to glow blue.");
  92.             u.umconf = 1;
  93.         }
  94.         break;
  95.     case SCR_SCARE_MONSTER:
  96.         {    register int ct = 0;
  97.         register struct monst *mtmp;
  98.  
  99.         for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
  100.             if(cansee(mtmp->mx,mtmp->my)) {
  101.                 if(confused)
  102.                     mtmp->mflee = mtmp->mfroz =
  103.                     mtmp->msleep = 0;
  104.                 else
  105.                     mtmp->mflee = 1;
  106.                 ct++;
  107.             }
  108.         if(!ct) {
  109.             if(confused)
  110.             pline("You hear sad wailing in the distance.");
  111.             else
  112.             pline("You hear maniacal laughter in the distance.");
  113.         }
  114.         break;
  115.         }
  116.     case SCR_BLANK_PAPER:
  117.         if(confused)
  118.             pline("You see strange patterns on this scroll.");
  119.         else
  120.             pline("This scroll seems to be blank.");
  121.         break;
  122.     case SCR_REMOVE_CURSE:
  123.         {    register struct obj *obj;
  124.         if(confused)
  125.           pline("You feel like you need some help.");
  126.         else
  127.           pline("You feel like someone is helping you.");
  128.         for(obj = invent; obj ; obj = obj->nobj)
  129.             if(obj->owornmask)
  130.                 obj->cursed = confused;
  131.         if(Punished && !confused) {
  132.             Punished = 0;
  133.             freeobj(uchain);
  134.             unpobj(uchain);
  135.             free((char *) uchain);
  136.             uball->spe = 0;
  137.             uball->owornmask &= ~W_BALL;
  138.             uchain = uball = (struct obj *) 0;
  139.         }
  140.         break;
  141.         }
  142.     case SCR_CREATE_MONSTER:
  143.         {    register int cnt = 1;
  144.  
  145.         if(!rn2(73)) cnt += rnd(4);
  146.         if(confused) cnt += 12;
  147.         while(cnt--)
  148.             (void) makemon(confused ? PM_ACID_BLOB :
  149.             (struct permonst *) 0, u.ux, u.uy);
  150.         break;
  151.         }
  152.     case SCR_ENCHANT_WEAPON:
  153.         if(uwep && confused) {
  154.             pline("Your %s glows silver for a moment.",
  155.                 objects[uwep->otyp].oc_name);
  156.             uwep->rustfree = 1;
  157.         } else
  158.             if(!chwepon(scroll, 1))        /* tests for !uwep */
  159.                 return(1);
  160.         break;
  161.     case SCR_DAMAGE_WEAPON:
  162.         if(uwep && confused) {
  163.             pline("Your %s glows purple for a moment.",
  164.                 objects[uwep->otyp].oc_name);
  165.             uwep->rustfree = 0;
  166.         } else
  167.             if(!chwepon(scroll, -1))    /* tests for !uwep */
  168.                 return(1);
  169.         break;
  170.     case SCR_TAMING:
  171.         {    register int i,j;
  172.         register int bd = confused ? 5 : 1;
  173.         register struct monst *mtmp;
  174.  
  175.         for(i = -bd; i <= bd; i++) for(j = -bd; j <= bd; j++)
  176.         if(mtmp = m_at(u.ux+i, u.uy+j))
  177.             (void) tamedog(mtmp, (struct obj *) 0);
  178.         break;
  179.         }
  180.     case SCR_GENOCIDE:
  181.         {    extern char genocided[], fut_geno[];
  182.         char buf[BUFSZ];
  183.         register struct monst *mtmp, *mtmp2;
  184.  
  185.         pline("You have found a scroll of genocide!");
  186.         known = TRUE;
  187.         if(confused)
  188.             *buf = u.usym;
  189.         else do {
  190.         pline("What monster do you want to genocide (Type the letter)? ");
  191.             getlin(buf);
  192.         } while(strlen(buf) != 1 || !monstersym(*buf));
  193.         if(!index(fut_geno, *buf))
  194.             charcat(fut_geno, *buf);
  195.         if(!index(genocided, *buf))
  196.             charcat(genocided, *buf);
  197.         else {
  198.             pline("Such monsters do not exist in this world.");
  199.             break;
  200.         }
  201.         for(mtmp = fmon; mtmp; mtmp = mtmp2){
  202.             mtmp2 = mtmp->nmon;
  203.             if(mtmp->data->mlet == *buf)
  204.                 mondead(mtmp);
  205.         }
  206.         pline("Wiped out all %c's.", *buf);
  207.         if(*buf == u.usym) {
  208.             killer = "scroll of genocide";
  209.             u.uhp = -1;
  210.         }
  211.         break;
  212.         }
  213.     case SCR_LIGHT:
  214.         if(!Blind) known = TRUE;
  215.         litroom(!confused);
  216.         break;
  217.     case SCR_TELEPORTATION:
  218.         if(confused)
  219.             level_tele();
  220.         else {
  221. #ifdef QUEST
  222.             register int oux = u.ux, ouy = u.uy;
  223.             tele();
  224.             if(dist(oux, ouy) > 100) known = TRUE;
  225. #else QUEST
  226.             register int uroom = inroom(u.ux, u.uy);
  227.             tele();
  228.             if(uroom != inroom(u.ux, u.uy)) known = TRUE;
  229. #endif QUEST
  230.         }
  231.         break;
  232.     case SCR_GOLD_DETECTION:
  233.         /* Unfortunately this code has become slightly less elegant,
  234.            now that gold and traps no longer are of the same type. */
  235.         if(confused) {
  236.         register struct trap *ttmp;
  237.  
  238.         if(!ftrap) {
  239.             strange_feeling(scroll, "Your toes stop itching.");
  240.             return(1);
  241.         } else {
  242.             for(ttmp = ftrap; ttmp; ttmp = ttmp->ntrap)
  243.                 if(ttmp->tx != u.ux || ttmp->ty != u.uy)
  244.                     goto outtrapmap;
  245.             /* only under me - no separate display required */
  246.             pline("Your toes itch!");
  247.             break;
  248.         outtrapmap:
  249.             cls();
  250.             for(ttmp = ftrap; ttmp; ttmp = ttmp->ntrap)
  251.                 at(ttmp->tx, ttmp->ty, '$');
  252.             prme();
  253.             pline("You feel very greedy!");
  254.         }
  255.         } else {
  256.         register struct gold *gtmp;
  257.  
  258.         if(!fgold) {
  259.             strange_feeling(scroll, "You feel materially poor.");
  260.             return(1);
  261.         } else {
  262.             known = TRUE;
  263.             for(gtmp = fgold; gtmp; gtmp = gtmp->ngold)
  264.                 if(gtmp->gx != u.ux || gtmp->gy != u.uy)
  265.                     goto outgoldmap;
  266.             /* only under me - no separate display required */
  267.             pline("You notice some gold between your feet.");
  268.             break;
  269.         outgoldmap:
  270.             cls();
  271.             for(gtmp = fgold; gtmp; gtmp = gtmp->ngold)
  272.                 at(gtmp->gx, gtmp->gy, '$');
  273.             prme();
  274.             pline("You feel very greedy, and sense gold!");
  275.         }
  276.         }
  277.         /* common sequel */
  278.         more();
  279.         docrt();
  280.         break;
  281.     case SCR_FOOD_DETECTION:
  282.         {    register ct = 0, ctu = 0;
  283.         register struct obj *obj;
  284.         register char foodsym = confused ? POTION_SYM : FOOD_SYM;
  285.  
  286.         for(obj = fobj; obj; obj = obj->nobj)
  287.             if(obj->olet == FOOD_SYM) {
  288.                 if(obj->ox == u.ux && obj->oy == u.uy) ctu++;
  289.                 else ct++;
  290.             }
  291.         if(!ct && !ctu) {
  292.             strange_feeling(scroll,"Your nose twitches.");
  293.             return(1);
  294.         } else if(!ct) {
  295.             known = TRUE;
  296.             pline("You smell %s close nearby.",
  297.                 confused ? "something" : "food");
  298.             
  299.         } else {
  300.             known = TRUE;
  301.             cls();
  302.             for(obj = fobj; obj; obj = obj->nobj)
  303.                 if(obj->olet == foodsym)
  304.                 at(obj->ox, obj->oy, FOOD_SYM);
  305.             prme();
  306.             pline("Your nose tingles and you smell %s!",
  307.                 confused ? "something" : "food");
  308.             more();
  309.             docrt();
  310.         }
  311.         break;
  312.         }
  313.     case SCR_IDENTIFY:
  314.         /* known = TRUE; */
  315.         if(confused)
  316.             pline("You identify this as an identify scroll.");
  317.         else
  318.             pline("This is an identify scroll.");
  319.         useup(scroll);
  320.         objects[SCR_IDENTIFY].oc_name_known = 1;
  321.         if(!confused)
  322.             while(
  323.             !ggetobj("identify", identify, rn2(5) ? 1 : rn2(5))
  324.             && invent
  325.             );
  326.         return(1);
  327.     case SCR_MAGIC_MAPPING:
  328.         {    register struct rm *lev;
  329.         register int num, zx, zy;
  330.  
  331.         known = TRUE;
  332.         pline("On this scroll %s a map!",
  333.             confused ? "was" : "is");
  334.         for(zy = 0; zy < ROWNO; zy++)
  335.             for(zx = 0; zx < COLNO; zx++) {
  336.                 if(confused && rn2(7)) continue;
  337.                 lev = &(levl[zx][zy]);
  338.                 if((num = lev->typ) == 0)
  339.                     continue;
  340.                 if(num == SCORR) {
  341.                     lev->typ = CORR;
  342. #ifdef DGK
  343.                     lev->scrsym = symbol.corr;
  344. #else
  345.                     lev->scrsym = CORR_SYM;
  346. #endif DGK
  347.                 } else
  348.                 if(num == SDOOR) {
  349.                     lev->typ = DOOR;
  350. #ifdef DGK
  351.                     lev->scrsym = symbol.door;
  352. #else
  353.                     lev->scrsym = '+';
  354. #endif DGK
  355.                     /* do sth in doors ? */
  356.                 } else if(lev->seen) continue;
  357. #ifndef QUEST
  358.                 if(num != ROOM)
  359. #endif QUEST
  360.                 {
  361.                   lev->seen = lev->new = 1;
  362.                   if(lev->scrsym == ' ' || !lev->scrsym)
  363.                     newsym(zx,zy);
  364.                   else
  365.                     on_scr(zx,zy);
  366.                 }
  367.             }
  368.         break;
  369.         }
  370.     case SCR_AMNESIA:
  371.         {    register int zx, zy;
  372.  
  373.         known = TRUE;
  374.         for(zx = 0; zx < COLNO; zx++) for(zy = 0; zy < ROWNO; zy++)
  375.             if(!confused || rn2(7))
  376.             if(!cansee(zx,zy))
  377.                 levl[zx][zy].seen = 0;
  378.         docrt();
  379.         pline("Thinking of Maud you forget everything else.");
  380.         break;
  381.         }
  382.     case SCR_FIRE:
  383.         {    register int num;
  384.         register struct monst *mtmp;
  385.  
  386.         known = TRUE;
  387.         if(confused) {
  388.             pline("The scroll catches fire and you burn your hands.");
  389.             losehp(1, "scroll of fire");
  390.         } else {
  391.             pline("The scroll erupts in a tower of flame!");
  392.             if(Fire_resistance)
  393.             pline("You are uninjured.");
  394.             else {
  395.             num = rnd(6);
  396.             u.uhpmax -= num;
  397.             losehp(num, "scroll of fire");
  398.             }
  399.         }
  400.         num = (2*num + 1)/3;
  401.         for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
  402.             if(dist(mtmp->mx,mtmp->my) < 3) {
  403.             mtmp->mhp -= num;
  404.             if(index("FY", mtmp->data->mlet))
  405.                 mtmp->mhp -= 3*num;    /* this might well kill 'F's */
  406.             if(mtmp->mhp < 1) {
  407.                 killed(mtmp);
  408.                 break;        /* primitive */
  409.             }
  410.             }
  411.         }
  412.         break;
  413.         }
  414.     case SCR_PUNISHMENT:
  415.         known = TRUE;
  416.         if(confused) {
  417.             pline("You feel guilty.");
  418.             break;
  419.         }
  420.         pline("You are being punished for your misbehaviour!");
  421.         if(Punished){
  422.             pline("Your iron ball gets heavier.");
  423.             uball->owt += 15;
  424.             break;
  425.         }
  426.         Punished = INTRINSIC;
  427.         setworn(mkobj_at(CHAIN_SYM, u.ux, u.uy), W_CHAIN);
  428.         setworn(mkobj_at(BALL_SYM, u.ux, u.uy), W_BALL);
  429.         uball->spe = 1;        /* special ball (see save) */
  430.         break;
  431.     default:
  432.         impossible("What weird language is this written in? (%u)",
  433.             scroll->otyp);
  434.     }
  435.     if(!objects[scroll->otyp].oc_name_known) {
  436.         if(known && !confused) {
  437.             objects[scroll->otyp].oc_name_known = 1;
  438.             more_experienced(0,10);
  439.         } else if(!objects[scroll->otyp].oc_uname)
  440.             docall(scroll);
  441.     }
  442.     useup(scroll);
  443.     return(1);
  444. }
  445.  
  446. identify(otmp)        /* also called by newmail() */
  447. register struct obj *otmp;
  448. {
  449.     objects[otmp->otyp].oc_name_known = 1;
  450.     otmp->known = otmp->dknown = 1;
  451.     prinv(otmp);
  452.     return(1);
  453. }
  454.  
  455. litroom(on)
  456. register boolean on;
  457. {
  458.     register num,zx,zy;
  459.  
  460.     /* first produce the text (provided he is not blind) */
  461.     if(Blind) goto do_it;
  462.     if(!on) {
  463.         if(u.uswallow || !xdnstair || levl[u.ux][u.uy].typ == CORR ||
  464.             !levl[u.ux][u.uy].lit) {
  465.             pline("It seems even darker in here than before.");
  466.             return;
  467.         } else
  468.             pline("It suddenly becomes dark in here.");
  469.     } else {
  470.         if(u.uswallow){
  471.             pline("%s's stomach is lit.", Monnam(u.ustuck));
  472.             return;
  473.         }
  474.         if(!xdnstair){
  475.             pline("Nothing Happens.");
  476.             return;
  477.         }
  478. #ifdef QUEST
  479.         pline("The cave lights up around you, then fades.");
  480.         return;
  481. #else QUEST
  482.         if(levl[u.ux][u.uy].typ == CORR) {
  483.             pline("The corridor lights up around you, then fades.");
  484.             return;
  485.         } else if(levl[u.ux][u.uy].lit) {
  486.             pline("The light here seems better now.");
  487.             return;
  488.         } else
  489.             pline("The room is lit.");
  490. #endif QUEST
  491.     }
  492.  
  493. do_it:
  494. #ifdef QUEST
  495.     return;
  496. #else QUEST
  497.     if(levl[u.ux][u.uy].lit == on)
  498.         return;
  499.     if(levl[u.ux][u.uy].typ == DOOR) {
  500.         if(IS_ROOM(levl[u.ux][u.uy+1].typ)) zy = u.uy+1;
  501.         else if(IS_ROOM(levl[u.ux][u.uy-1].typ)) zy = u.uy-1;
  502.         else zy = u.uy;
  503.         if(IS_ROOM(levl[u.ux+1][u.uy].typ)) zx = u.ux+1;
  504.         else if(IS_ROOM(levl[u.ux-1][u.uy].typ)) zx = u.ux-1;
  505.         else zx = u.ux;
  506.     } else {
  507.         zx = u.ux;
  508.         zy = u.uy;
  509.     }
  510.     for(seelx = u.ux; (num = levl[seelx-1][zy].typ) != CORR && num != 0;
  511.         seelx--);
  512.     for(seehx = u.ux; (num = levl[seehx+1][zy].typ) != CORR && num != 0;
  513.         seehx++);
  514.     for(seely = u.uy; (num = levl[zx][seely-1].typ) != CORR && num != 0;
  515.         seely--);
  516.     for(seehy = u.uy; (num = levl[zx][seehy+1].typ) != CORR && num != 0;
  517.         seehy++);
  518.     for(zy = seely; zy <= seehy; zy++)
  519.         for(zx = seelx; zx <= seehx; zx++) {
  520.             levl[zx][zy].lit = on;
  521.             if(!Blind && dist(zx,zy) > 2)
  522.                 if(on) prl(zx,zy); else nosee(zx,zy);
  523.         }
  524.     if(!on) seehx = 0;
  525. #endif    QUEST
  526. }
  527.  
  528. /* Test whether we may genocide all monsters with symbol  ch  */
  529. monstersym(ch)                /* arnold@ucsfcgl */
  530. register char ch;
  531. {
  532.     register struct permonst *mp;
  533.     extern struct permonst pm_eel;
  534.  
  535.     /*
  536.      * can't genocide certain monsters
  537.      */
  538.     if (index("12 &:", ch))
  539.         return FALSE;
  540.  
  541.     if (ch == pm_eel.mlet)
  542.         return TRUE;
  543.     for (mp = mons; mp < &mons[CMNUM+2]; mp++)
  544.         if (mp->mlet == ch)
  545.             return TRUE;
  546.     return FALSE;
  547. }
  548.