1: /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
   2: /* hack.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:                     lev->scrsym = CORR_SYM;
 343:                 } else
 344:                 if(num == SDOOR) {
 345:                     lev->typ = DOOR;
 346:                     lev->scrsym = '+';
 347:                     /* do sth in doors ? */
 348:                 } else if(lev->seen) continue;
 349: #ifndef QUEST
 350:                 if(num != ROOM)
 351: #endif QUEST
 352:                 {
 353:                   lev->seen = lev->new = 1;
 354:                   if(lev->scrsym == ' ' || !lev->scrsym)
 355:                     newsym(zx,zy);
 356:                   else
 357:                     on_scr(zx,zy);
 358:                 }
 359:             }
 360:         break;
 361:         }
 362:     case SCR_AMNESIA:
 363:         {   register int zx, zy;
 364: 
 365:         known = TRUE;
 366:         for(zx = 0; zx < COLNO; zx++) for(zy = 0; zy < ROWNO; zy++)
 367:             if(!confused || rn2(7))
 368:             if(!cansee(zx,zy))
 369:                 levl[zx][zy].seen = 0;
 370:         docrt();
 371:         pline("Thinking of Maud you forget everything else.");
 372:         break;
 373:         }
 374:     case SCR_FIRE:
 375:         {   register int num;
 376:         register struct monst *mtmp;
 377: 
 378:         known = TRUE;
 379:         if(confused) {
 380:             pline("The scroll catches fire and you burn your hands.");
 381:             losehp(1, "scroll of fire");
 382:         } else {
 383:             pline("The scroll erupts in a tower of flame!");
 384:             if(Fire_resistance)
 385:             pline("You are uninjured.");
 386:             else {
 387:             num = rnd(6);
 388:             u.uhpmax -= num;
 389:             losehp(num, "scroll of fire");
 390:             }
 391:         }
 392:         num = (2*num + 1)/3;
 393:         for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
 394:             if(dist(mtmp->mx,mtmp->my) < 3) {
 395:             mtmp->mhp -= num;
 396:             if(index("FY", mtmp->data->mlet))
 397:                 mtmp->mhp -= 3*num; /* this might well kill 'F's */
 398:             if(mtmp->mhp < 1) {
 399:                 killed(mtmp);
 400:                 break;      /* primitive */
 401:             }
 402:             }
 403:         }
 404:         break;
 405:         }
 406:     case SCR_PUNISHMENT:
 407:         known = TRUE;
 408:         if(confused) {
 409:             pline("You feel guilty.");
 410:             break;
 411:         }
 412:         pline("You are being punished for your misbehaviour!");
 413:         if(Punished){
 414:             pline("Your iron ball gets heavier.");
 415:             uball->owt += 15;
 416:             break;
 417:         }
 418:         Punished = INTRINSIC;
 419:         setworn(mkobj_at(CHAIN_SYM, u.ux, u.uy), W_CHAIN);
 420:         setworn(mkobj_at(BALL_SYM, u.ux, u.uy), W_BALL);
 421:         uball->spe = 1;     /* special ball (see save) */
 422:         break;
 423:     default:
 424:         impossible("What weird language is this written in? (%u)",
 425:             scroll->otyp);
 426:     }
 427:     if(!objects[scroll->otyp].oc_name_known) {
 428:         if(known && !confused) {
 429:             objects[scroll->otyp].oc_name_known = 1;
 430:             more_experienced(0,10);
 431:         } else if(!objects[scroll->otyp].oc_uname)
 432:             docall(scroll);
 433:     }
 434:     useup(scroll);
 435:     return(1);
 436: }
 437: 
 438: identify(otmp)      /* also called by newmail() */
 439: register struct obj *otmp;
 440: {
 441:     objects[otmp->otyp].oc_name_known = 1;
 442:     otmp->known = otmp->dknown = 1;
 443:     prinv(otmp);
 444:     return(1);
 445: }
 446: 
 447: litroom(on)
 448: register boolean on;
 449: {
 450:     register num,zx,zy;
 451: 
 452:     /* first produce the text (provided he is not blind) */
 453:     if(Blind) goto do_it;
 454:     if(!on) {
 455:         if(u.uswallow || !xdnstair || levl[u.ux][u.uy].typ == CORR ||
 456:             !levl[u.ux][u.uy].lit) {
 457:             pline("It seems even darker in here than before.");
 458:             return;
 459:         } else
 460:             pline("It suddenly becomes dark in here.");
 461:     } else {
 462:         if(u.uswallow){
 463:             pline("%s's stomach is lit.", Monnam(u.ustuck));
 464:             return;
 465:         }
 466:         if(!xdnstair){
 467:             pline("Nothing Happens.");
 468:             return;
 469:         }
 470: #ifdef QUEST
 471:         pline("The cave lights up around you, then fades.");
 472:         return;
 473: #else QUEST
 474:         if(levl[u.ux][u.uy].typ == CORR) {
 475:             pline("The corridor lights up around you, then fades.");
 476:             return;
 477:         } else if(levl[u.ux][u.uy].lit) {
 478:             pline("The light here seems better now.");
 479:             return;
 480:         } else
 481:             pline("The room is lit.");
 482: #endif QUEST
 483:     }
 484: 
 485: do_it:
 486: #ifdef QUEST
 487:     return;
 488: #else QUEST
 489:     if(levl[u.ux][u.uy].lit == on)
 490:         return;
 491:     if(levl[u.ux][u.uy].typ == DOOR) {
 492:         if(IS_ROOM(levl[u.ux][u.uy+1].typ)) zy = u.uy+1;
 493:         else if(IS_ROOM(levl[u.ux][u.uy-1].typ)) zy = u.uy-1;
 494:         else zy = u.uy;
 495:         if(IS_ROOM(levl[u.ux+1][u.uy].typ)) zx = u.ux+1;
 496:         else if(IS_ROOM(levl[u.ux-1][u.uy].typ)) zx = u.ux-1;
 497:         else zx = u.ux;
 498:     } else {
 499:         zx = u.ux;
 500:         zy = u.uy;
 501:     }
 502:     for(seelx = u.ux; (num = levl[seelx-1][zy].typ) != CORR && num != 0;
 503:         seelx--);
 504:     for(seehx = u.ux; (num = levl[seehx+1][zy].typ) != CORR && num != 0;
 505:         seehx++);
 506:     for(seely = u.uy; (num = levl[zx][seely-1].typ) != CORR && num != 0;
 507:         seely--);
 508:     for(seehy = u.uy; (num = levl[zx][seehy+1].typ) != CORR && num != 0;
 509:         seehy++);
 510:     for(zy = seely; zy <= seehy; zy++)
 511:         for(zx = seelx; zx <= seehx; zx++) {
 512:             levl[zx][zy].lit = on;
 513:             if(!Blind && dist(zx,zy) > 2)
 514:                 if(on) prl(zx,zy); else nosee(zx,zy);
 515:         }
 516:     if(!on) seehx = 0;
 517: #endif	QUEST
 518: }
 519: 
 520: /* Test whether we may genocide all monsters with symbol  ch  */
 521: monstersym(ch)              /* arnold@ucsfcgl */
 522: register char ch;
 523: {
 524:     register struct permonst *mp;
 525:     extern struct permonst pm_eel;
 526: 
 527:     /*
 528: 	 * can't genocide certain monsters
 529: 	 */
 530:     if (index("12 &:", ch))
 531:         return FALSE;
 532: 
 533:     if (ch == pm_eel.mlet)
 534:         return TRUE;
 535:     for (mp = mons; mp < &mons[CMNUM+2]; mp++)
 536:         if (mp->mlet == ch)
 537:             return TRUE;
 538:     return FALSE;
 539: }

Defined functions

doread defined in line 10; used 2 times
identify defined in line 438; used 3 times
litroom defined in line 447; used 2 times
monstersym defined in line 521; never used
Last modified: 1985-10-18
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 4038
Valid CSS Valid XHTML 1.0 Strict