[BACK]Return to misc.c CVS log [TXT][DIR] Up to [contributed] / early-roguelike / xrogue

Annotation of early-roguelike/xrogue/misc.c, Revision 1.1

1.1     ! rubenllo    1: /*
        !             2:     misc.c - routines dealing specifically with miscellaneous magic
        !             3:
        !             4:     XRogue: Expeditions into the Dungeons of Doom
        !             5:     Copyright (C) 1991 Robert Pietkivitch
        !             6:     All rights reserved.
        !             7:
        !             8:     Based on "Advanced Rogue"
        !             9:     Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
        !            10:     All rights reserved.
        !            11:
        !            12:     See the file LICENSE.TXT for full copyright and licensing information.
        !            13: */
        !            14:
        !            15: #include <stdlib.h>
        !            16: #include <curses.h>
        !            17: #include <ctype.h>
        !            18: #include <string.h>
        !            19: #include "rogue.h"
        !            20:
        !            21: /*
        !            22:  * changeclass:
        !            23:  *      Change the player's class to the specified one.
        !            24:  */
        !            25:
        !            26: void
        !            27: changeclass(int newclass)
        !            28: {
        !            29:     if (newclass == player.t_ctype) {
        !            30:         msg("You feel more skillful.");
        !            31:         raise_level();
        !            32:     }
        !            33:     else {
        !            34:         /*
        !            35:          * reset his class and then use check_level to reset hit
        !            36:          * points and the right level for his exp pts
        !            37:          * drop exp pts by 10%
        !            38:          */
        !            39:         long save;
        !            40:
        !            41:         msg("You are transformed into a %s! ", char_class[newclass].name);
        !            42:
        !            43:         /*
        !            44:          * if he becomes a thief or an assassin give him studded leather armor
        !            45:          */
        !            46:         if ((newclass == C_THIEF || newclass == C_ASSASSIN) &&
        !            47:             cur_armor != NULL && cur_armor->o_which != STUDDED_LEATHER)
        !            48:                 cur_armor->o_which = STUDDED_LEATHER;
        !            49:         /*
        !            50:          * if he becomes a monk he can't wear any armor
        !            51:      * so give him a cloak of protection
        !            52:          */
        !            53:         if (newclass == C_MONK && cur_armor != NULL) {
        !            54:                 cur_armor->o_ac = armors[cur_armor->o_which].a_class -
        !            55:                                   cur_armor->o_ac;
        !            56:                 cur_armor->o_type = MM;
        !            57:                 cur_armor->o_which = MM_PROTECT;
        !            58:                 cur_armor->o_flags &= ~(ISPROT | ISKNOW);
        !            59:                 cur_misc[WEAR_CLOAK] = cur_armor;
        !            60:                 cur_armor = NULL;
        !            61:         }
        !            62:     /*
        !            63:      * otherwise give him plate armor
        !            64:      */
        !            65:         if ((newclass != C_THIEF ||
        !            66:          newclass != C_ASSASSIN || newclass != C_MONK) &&
        !            67:          cur_armor != NULL && cur_armor->o_which != PLATE_ARMOR)
        !            68:                 cur_armor->o_which = PLATE_ARMOR;
        !            69:
        !            70:         /*
        !            71:          * if he used to be a spell caster of some sort, kill the fuse
        !            72:          */
        !            73:         if (player.t_ctype == C_MAGICIAN || player.t_ctype == C_RANGER)
        !            74:                 extinguish(spell_recovery);
        !            75:         if (player.t_ctype == C_DRUID || player.t_ctype == C_MONK)
        !            76:                 extinguish(chant_recovery);
        !            77:         if ((player.t_ctype == C_CLERIC || player.t_ctype == C_PALADIN) &&
        !            78:              !cur_relic[HEIL_ANKH])
        !            79:                 extinguish(prayer_recovery);
        !            80:
        !            81:         /*
        !            82:          * if he becomes a spell caster of some kind, give him a fuse
        !            83:          */
        !            84:         if (newclass == C_MAGICIAN || newclass == C_RANGER)
        !            85:                 fuse(spell_recovery, NULL, SPELLTIME, AFTER);
        !            86:         if (newclass == C_DRUID || newclass == C_MONK)
        !            87:                 fuse(chant_recovery, NULL, SPELLTIME, AFTER);
        !            88:         if ((newclass==C_CLERIC || newclass==C_PALADIN) && !cur_misc[HEIL_ANKH])
        !            89:                 fuse(prayer_recovery, NULL, SPELLTIME, AFTER);
        !            90:         /*
        !            91:          * if he's changing from a fighter, ranger, or paladin then we
        !            92:      * may have to change his sword since only these types can wield
        !            93:      * the two-handed sword.
        !            94:          */
        !            95:         if ((player.t_ctype == C_FIGHTER ||
        !            96:         player.t_ctype == C_RANGER   ||
        !            97:             player.t_ctype == C_PALADIN) &&
        !            98:         cur_weapon != NULL && cur_weapon->o_type == WEAPON &&
        !            99:             (cur_weapon->o_which == BASWORD  ||
        !           100:         cur_weapon->o_which == TWOSWORD) &&
        !           101:             !(newclass == C_FIGHTER || newclass == C_RANGER ||
        !           102:             newclass == C_PALADIN)  &&
        !           103:         cur_weapon->o_which == TWOSWORD)
        !           104:                 cur_weapon->o_which = SWORD;
        !           105:
        !           106:         /*
        !           107:          * if he's changing from a thief, assassin, fighter, or monk
        !           108:      * then we may have to change his sword again since only these
        !           109:      * types can wield the bastard sword.
        !           110:          */
        !           111:         if ((player.t_ctype == C_THIEF  || player.t_ctype == C_ASSASSIN ||
        !           112:             player.t_ctype == C_FIGHTER || player.t_ctype == C_MONK)    &&
        !           113:         cur_weapon != NULL && cur_weapon->o_type == WEAPON &&
        !           114:             (cur_weapon->o_which == BASWORD  ||
        !           115:             cur_weapon->o_which == TWOSWORD) &&
        !           116:             !(newclass == C_THIEF || newclass == C_ASSASSIN ||
        !           117:             newclass == C_MONK)   &&
        !           118:         cur_weapon->o_which == BASWORD)
        !           119:                 cur_weapon->o_which = SWORD;
        !           120:
        !           121:         /*
        !           122:          * if he was a thief, assassin, or monk then take out
        !           123:      * the trap_look() daemon
        !           124:          */
        !           125:         if (player.t_ctype == C_THIEF || player.t_ctype == C_MONK ||
        !           126:             player.t_ctype == C_ASSASSIN)
        !           127:                 kill_daemon(trap_look);
        !           128:
        !           129:         /*
        !           130:          * if he becomes a thief, assassin, or monk then add
        !           131:      * the trap_look() daemon
        !           132:          */
        !           133:         if (newclass == C_THIEF || newclass == C_ASSASSIN ||
        !           134:         newclass == C_MONK)
        !           135:                 start_daemon(trap_look, NULL, AFTER);
        !           136:
        !           137:     /* adjust stats */
        !           138:         char_type = player.t_ctype = newclass;
        !           139:         save = pstats.s_hpt;
        !           140:         max_stats.s_hpt = pstats.s_hpt = 0;
        !           141:         max_stats.s_lvl = pstats.s_lvl = 0;
        !           142:         max_stats.s_lvladj = pstats.s_lvladj = 0;
        !           143:         max_stats.s_exp = pstats.s_exp + rnd(4);
        !           144:         check_level();
        !           145:         if (pstats.s_hpt > save) /* don't add to current hits */
        !           146:             pstats.s_hpt = save;
        !           147:     }
        !           148:     dsrpt_player(); /* this should disrupt whatever we were doing */
        !           149: }
        !           150:
        !           151: /*
        !           152:  * Use the relic that our monster is wielding.
        !           153:  */
        !           154:
        !           155: void
        !           156: m_use_relic(struct thing *monster)
        !           157: {
        !           158:     register struct object *obj;
        !           159:
        !           160:     /* Make sure we really have it */
        !           161:     if (monster->t_using) obj = OBJPTR(monster->t_using);
        !           162:     else {
        !           163:         debug("Relic not set!");
        !           164:         monster->t_action = A_NIL;
        !           165:         return;
        !           166:     }
        !           167:
        !           168:     /* Now let's see what we're using */
        !           169:     if (obj->o_type == RELIC) switch (obj->o_which) {
        !           170:         case MING_STAFF: {
        !           171:             static struct object missile = {
        !           172:               MISSILE, {0,0}, 0, "", "0d4 " , NULL, 0, WS_MISSILE, 100, 1
        !           173:             };
        !           174:
        !           175:             debug("Firing Ming's staff");
        !           176:             sprintf(missile.o_hurldmg, "%dd4", monster->t_stats.s_lvl);
        !           177:             do_motion(&missile,
        !           178:                        monster->t_newpos.y, monster->t_newpos.x, monster);
        !           179:             hit_monster(unc(missile.o_pos), &missile, monster);
        !           180:             monster->t_artifact = monster->t_artifact * 4 / 5;
        !           181:         }
        !           182:         when EMORI_CLOAK:
        !           183:             debug("stunning with Emori's cloak");
        !           184:             do_zap(monster, obj, &monster->t_newpos, WS_PARALYZE, 0);
        !           185:             obj->o_charges = 0;
        !           186:
        !           187:         when ASMO_ROD: {
        !           188:             char *name;
        !           189:
        !           190:             switch (rnd(3)) { /* Select a function */
        !           191:                 case 0:    name = "lightning bolt";
        !           192:                 when 1:    name = "flame";
        !           193:                 otherwise: name = "ice";
        !           194:             }
        !           195:             shoot_bolt( monster,
        !           196:                         monster->t_pos,
        !           197:                         monster->t_newpos,
        !           198:                         FALSE,
        !           199:                         monster->t_index,
        !           200:                         name,
        !           201:                         roll(monster->t_stats.s_lvl,6));
        !           202:             monster->t_artifact /= 2;
        !           203:         }
        !           204:         when BRIAN_MANDOLIN:
        !           205:             /* Make sure the defendant is still around */
        !           206:             if (DISTANCE(monster->t_pos.y, monster->t_pos.x,
        !           207:                          hero.y, hero.x) < 25) {
        !           208:                 if (!save(VS_MAGIC, &player, -4) &&
        !           209:                     !ISWEARING(R_ALERT)) {
        !           210:                     msg("Some beautiful music enthralls you.");
        !           211:                     player.t_no_move += movement(&player) * FREEZETIME;
        !           212:                     player.t_action = A_FREEZE;
        !           213:                     monster->t_artifact = monster->t_artifact * 2 / 3;
        !           214:                 }
        !           215:                 else {
        !           216:                     msg("You wince at a sour note.");
        !           217:                     monster->t_artifact /= 3;
        !           218:                 }
        !           219:             }
        !           220:         when GERYON_HORN:
        !           221:             /* Make sure the defendant is still around */
        !           222:             if (DISTANCE(monster->t_pos.y, monster->t_pos.x,
        !           223:                          hero.y, hero.x) < 25) {
        !           224:                 if (!ISWEARING(R_HEROISM) &&
        !           225:                     !save(VS_MAGIC, &player, -4)) {
        !           226:                         turn_on(player, ISFLEE);
        !           227:                         player.t_dest = &monster->t_pos;
        !           228:                         msg("A shrill blast terrifies you.");
        !           229:                         monster->t_artifact = monster->t_artifact * 3 / 4;
        !           230:                 }
        !           231:                 else  {
        !           232:                     msg("A shrill blast sends chills up your spine! ");
        !           233:                     monster->t_artifact /= 3;
        !           234:                 }
        !           235:             }
        !           236:
        !           237:         otherwise:
        !           238:             /* Unknown RELIC! */
        !           239:             debug("Unknown wielded relic %d", obj->o_which);
        !           240:     }
        !           241:     else debug("Declared relic is %d", obj->o_type);
        !           242:
        !           243:     turn_off(*monster, CANSURPRISE);
        !           244:     /* Reset the monsters actions */
        !           245:     monster->t_action = A_NIL;
        !           246:     monster->t_using = NULL;
        !           247: }
        !           248:
        !           249: /*
        !           250:  * add something to the contents of something else
        !           251:  * bag: the holder of the items
        !           252:  * item: the item to put inside
        !           253:  */
        !           254:
        !           255: void
        !           256: put_contents(struct object *bag, struct linked_list *item)
        !           257: {
        !           258:     register struct linked_list *titem;
        !           259:     register struct object *tobj;
        !           260:
        !           261:     bag->o_ac++;
        !           262:     tobj = OBJPTR(item);
        !           263:     for (titem = bag->contents; titem != NULL; titem = next(titem)) {
        !           264:         if ((OBJPTR(titem))->o_which == tobj->o_which)
        !           265:             break;
        !           266:     }
        !           267:     if (titem == NULL) {        /* if not a duplicate put at beginning */
        !           268:         attach(bag->contents, item);
        !           269:     }
        !           270:     else {
        !           271:         item->l_prev = titem;
        !           272:         item->l_next = titem->l_next;
        !           273:         if (next(titem) != NULL)
        !           274:             (titem->l_next)->l_prev = item;
        !           275:         titem->l_next = item;
        !           276:     }
        !           277: }
        !           278:
        !           279: /*
        !           280:  * remove something from something else
        !           281:  * bag: the holder of the items
        !           282:  */
        !           283:
        !           284: void
        !           285: take_contents(struct object *bag, struct linked_list *item)
        !           286: {
        !           287:
        !           288:     if (bag->o_ac <= 0) {
        !           289:         msg("Nothing to take out");
        !           290:         return;
        !           291:     }
        !           292:     bag->o_ac--;
        !           293:     detach(bag->contents, item);
        !           294:     if (!add_pack(item, FALSE))
        !           295:         put_contents(bag, item);
        !           296: }
        !           297:
        !           298:
        !           299: void
        !           300: do_bag(struct linked_list *item)
        !           301: {
        !           302:
        !           303:     register struct linked_list *titem = NULL;
        !           304:     register struct object *obj, *tobj;
        !           305:     bool doit = TRUE;
        !           306:
        !           307:     obj = OBJPTR(item);
        !           308:     while (doit) {
        !           309:         msg("What do you want to do? (* for a list): ");
        !           310:         mpos = 0;
        !           311:         switch (wgetch(cw)) {
        !           312:             case EOF:
        !           313:             case ESC:
        !           314:                 msg ("");
        !           315:                 doit = FALSE;
        !           316:             when '1':
        !           317:                 inventory(obj->contents, ALL);
        !           318:
        !           319:             when '2':
        !           320:                 if (obj->o_ac >= MAXCONTENTS) {
        !           321:                     msg("the %s is full", m_magic[obj->o_which].mi_name);
        !           322:                     break;
        !           323:                 }
        !           324:                 switch (obj->o_which) {
        !           325:                 case MM_BEAKER:
        !           326:                     titem = get_item(pack, "put in", POTION, FALSE, FALSE);
        !           327:                 when MM_BOOK:
        !           328:                     titem = get_item(pack, "put in", SCROLL, FALSE, FALSE);
        !           329:                 }
        !           330:                 if (titem == NULL)
        !           331:                     break;
        !           332:                 detach(pack, titem);
        !           333:                 inpack--;
        !           334:                 put_contents(obj, titem);
        !           335:
        !           336:             when '3':
        !           337:                 titem = get_item(obj->contents,"take out",ALL,FALSE,FALSE);
        !           338:                 if (titem == NULL)
        !           339:                     break;
        !           340:                 take_contents(obj, titem);
        !           341:
        !           342:             when '4':
        !           343:                 switch (obj->o_which) {
        !           344:                 case MM_BEAKER:
        !           345:                     titem = get_item(obj->contents,"quaff",ALL,FALSE,FALSE);
        !           346:                     if (titem == NULL)
        !           347:                         break;
        !           348:                     tobj = OBJPTR(titem);
        !           349:                     obj->o_ac--;
        !           350:                     detach(obj->contents, titem);
        !           351:                     quaff(tobj->o_which,
        !           352:                           tobj->o_kind,
        !           353:                           tobj->o_flags,
        !           354:                           TRUE);
        !           355:                     if (p_know[tobj->o_which] && p_guess[tobj->o_which])
        !           356:                     {
        !           357:                         free(p_guess[tobj->o_which]);
        !           358:                         p_guess[tobj->o_which] = NULL;
        !           359:                     }
        !           360:                     else if (!p_know[tobj->o_which]             &&
        !           361:                              askme                              &&
        !           362:                              (tobj->o_flags & ISKNOW) == 0      &&
        !           363:                              (tobj->o_flags & ISPOST) == 0      &&
        !           364:                              p_guess[tobj->o_which] == NULL) {
        !           365:                         nameitem(titem, FALSE);
        !           366:                     }
        !           367:                     o_discard(titem);
        !           368:                 when MM_BOOK:
        !           369:                     if (on(player, ISBLIND)) {
        !           370:                         msg("You can't see to read anything! ");
        !           371:                         break;
        !           372:                     }
        !           373:                     titem = get_item(obj->contents,"read",ALL,FALSE,FALSE);
        !           374:                     if (titem == NULL)
        !           375:                         break;
        !           376:                     tobj = OBJPTR(titem);
        !           377:                     obj->o_ac--;
        !           378:                     detach(obj->contents, titem);
        !           379:                     read_scroll(tobj->o_which,
        !           380:                                 tobj->o_flags & (ISCURSED|ISBLESSED),
        !           381:                                 TRUE);
        !           382:                     if (s_know[tobj->o_which] && s_guess[tobj->o_which])
        !           383:                     {
        !           384:                         free(s_guess[tobj->o_which]);
        !           385:                         s_guess[tobj->o_which] = NULL;
        !           386:                     }
        !           387:                     else if (!s_know[tobj->o_which]             &&
        !           388:                              askme                              &&
        !           389:                              (tobj->o_flags & ISKNOW) == 0      &&
        !           390:                              (tobj->o_flags & ISPOST) == 0      &&
        !           391:                              s_guess[tobj->o_which] == NULL) {
        !           392:                         nameitem(titem, FALSE);
        !           393:                     }
        !           394:                     o_discard(titem);
        !           395:                 }
        !           396:                 doit = FALSE;
        !           397:
        !           398:             otherwise:
        !           399:                 wclear(hw);
        !           400:                 touchwin(hw);
        !           401:                 mvwaddstr(hw,0,0,"The following operations are available:");
        !           402:                 mvwaddstr(hw,2,0,"[1]\tInventory\n");
        !           403:                 wprintw(hw,"[2]\tPut something in the %s\n",
        !           404:                         m_magic[obj->o_which].mi_name);
        !           405:                 wprintw(hw,"[3]\tTake something out of the %s\n",
        !           406:                         m_magic[obj->o_which].mi_name);
        !           407:                 switch(obj->o_which) {
        !           408:                     case MM_BEAKER: waddstr(hw,"[4]\tQuaff a potion\n");
        !           409:                     when MM_BOOK:   waddstr(hw,"[4]\tRead a scroll\n");
        !           410:                 }
        !           411:         /* this is confusing! <press space to continue> */
        !           412:                 /* waddstr(hw,"[ESC]\tLeave this menu\n"); */
        !           413:                 mvwaddstr(hw, lines-1, 0, spacemsg);
        !           414:                 draw(hw);
        !           415:                 wait_for (' ');
        !           416:                 restscr(cw);
        !           417:         }
        !           418:     }
        !           419: }
        !           420:
        !           421: void
        !           422: do_panic(int who)
        !           423: {
        !           424:     /* who: kind of monster to panic (all if who is 0) */
        !           425:     register int x,y;
        !           426:     register struct linked_list *mon, *item;
        !           427:     register struct thing *th;
        !           428:
        !           429:     for (x = hero.x-2; x <= hero.x+2; x++) {
        !           430:         for (y = hero.y-2; y <= hero.y+2; y++) {
        !           431:             if (y < 1 || x < 0 || y > lines - 3  || x > cols - 1)
        !           432:                 continue;
        !           433:             if (isalpha(mvwinch(mw, y, x))) {
        !           434:
        !           435:                 if ((mon = find_mons(y, x)) != NULL) {
        !           436:                     th = THINGPTR(mon);
        !           437:
        !           438:                     /* Is this the right kind of monster to panic? */
        !           439:                     if (who && th->t_index != who) continue;
        !           440:
        !           441:                     if ((who && th->t_stats.s_intel < 14) ||
        !           442:                         (!on(*th, ISUNDEAD) && !save(VS_MAGIC, th, 0) &&
        !           443:               off(*th, WASTURNED))) {
        !           444:                           msg("%s %s.", prname(monster_name(th), TRUE),
        !           445:                             terse ? "panics" : "turns to run in panic");
        !           446:
        !           447:                         turn_on(*th, ISFLEE);
        !           448:                         turn_on(*th, WASTURNED);
        !           449:                         turn_off(*th, CANSURPRISE);
        !           450:
        !           451:                         /* Disrupt what it was doing */
        !           452:                         dsrpt_monster(th, TRUE, TRUE);
        !           453:
        !           454:                         /* If monster was suffocating, stop it */
        !           455:                         if (on(*th, DIDSUFFOCATE)) {
        !           456:                             turn_off(*th, DIDSUFFOCATE);
        !           457:                             extinguish(suffocate);
        !           458:                         }
        !           459:
        !           460:                         /* If monster held us, stop it */
        !           461:                         if (on(*th, DIDHOLD) && (--hold_count == 0))
        !           462:                                 turn_off(player, ISHELD);
        !           463:                         turn_off(*th, DIDHOLD);
        !           464:
        !           465:                         /*
        !           466:                          * if he has something he might drop it
        !           467:                          */
        !           468:                         if ((item = th->t_pack) != NULL         &&
        !           469:                             (OBJPTR(item))->o_type != RELIC     &&
        !           470:                             rnd(100) < 67) {
        !           471:                                 detach(th->t_pack, item);
        !           472:                                 fall(item, FALSE);
        !           473:                         }
        !           474:
        !           475:                         /* It is okay to turn tail */
        !           476:                         th->t_oldpos = th->t_pos;
        !           477:                     }
        !           478:                     runto(th, &hero);
        !           479:                 }
        !           480:             }
        !           481:         }
        !           482:     }
        !           483: }
        !           484:
        !           485: /*
        !           486:  * print miscellaneous magic bonuses
        !           487:  */
        !           488:
        !           489: int
        !           490: misc_name(char *str, struct object *obj)
        !           491: {
        !           492:     char buf1[LINELEN];
        !           493:
        !           494:     *str = 0;
        !           495:     buf1[0] = 0;
        !           496:
        !           497:     if (!(obj->o_flags & ISKNOW))
        !           498:     {
        !           499:         strcat(str,m_magic[obj->o_which].mi_name);
        !           500:         return(0);
        !           501:     }
        !           502:
        !           503:     switch (obj->o_which)
        !           504:     {
        !           505:         case MM_BRACERS:
        !           506:         case MM_PROTECT:
        !           507:             strcat(str, num(obj->o_ac, 0));
        !           508:             strcat(str, " ");
        !           509:     }
        !           510:     switch (obj->o_which) {
        !           511:     case MM_CRYSTAL:
        !           512:             if (obj->o_flags & ISBLESSED)
        !           513:                 strcat(str, "glowing ");
        !           514:     }
        !           515:     switch (obj->o_which) {
        !           516:         case MM_G_OGRE:
        !           517:         case MM_G_DEXTERITY:
        !           518:         case MM_JEWEL:
        !           519:         case MM_STRANGLE:
        !           520:         case MM_R_POWERLESS:
        !           521:         case MM_DANCE:
        !           522:             if (obj->o_flags & ISCURSED)
        !           523:                 strcat(str, "cursed ");
        !           524:         when MM_CRYSTAL:
        !           525:             if (obj->o_flags & ISCURSED)
        !           526:                 strcat(str, "opaque ");
        !           527:     }
        !           528:     strcat(str, m_magic[obj->o_which].mi_name);
        !           529:
        !           530:     switch (obj->o_which)
        !           531:     {
        !           532:         case MM_JUG:
        !           533:             if (obj->o_ac == JUG_EMPTY)
        !           534:                 strcat(buf1, " [empty]");
        !           535:             else if (p_know[obj->o_ac])
        !           536:                 sprintf(buf1, " [containing a potion of %s (%s)]",
        !           537:                         p_magic[obj->o_ac].mi_name,
        !           538:                         p_colors[obj->o_ac]);
        !           539:             else sprintf(buf1, " [containing a%s %s liquid]",
        !           540:                         vowelstr(p_colors[obj->o_ac]),
        !           541:                         p_colors[obj->o_ac]);
        !           542:         when MM_BEAKER:
        !           543:         case MM_BOOK: {
        !           544:             sprintf(buf1, " [containing %d]", obj->o_ac);
        !           545:         }
        !           546:         when MM_OPEN:
        !           547:         case MM_HUNGER:
        !           548:             sprintf(buf1, " [%d ring%s]", obj->o_charges,
        !           549:                           obj->o_charges == 1 ? "" : "s");
        !           550:         when MM_DRUMS:
        !           551:             sprintf(buf1, " [%d beat%s]", obj->o_charges,
        !           552:                           obj->o_charges == 1 ? "" : "s");
        !           553:         when MM_DISAPPEAR:
        !           554:         case MM_CHOKE:
        !           555:             sprintf(buf1, " [%d pinch%s]", obj->o_charges,
        !           556:                           obj->o_charges == 1 ? "" : "es");
        !           557:         when MM_KEOGHTOM:
        !           558:             sprintf(buf1, " [%d application%s]", obj->o_charges,
        !           559:                           obj->o_charges == 1 ? "" : "s");
        !           560:         when MM_SKILLS:
        !           561:             sprintf(buf1, " [%s]", char_class[obj->o_ac].name);
        !           562:     }
        !           563:     strcat(str, buf1);
        !           564:
        !           565:     return(0);
        !           566: }
        !           567:
        !           568: void
        !           569: use_emori(void)
        !           570: {
        !           571:     char selection;     /* Cloak function */
        !           572:     int state = 0;      /* Menu state */
        !           573:
        !           574:     msg("What do you want to do? (* for a list): ");
        !           575:     do {
        !           576:         selection = wgetch(cw);
        !           577:         switch (selection) {
        !           578:             case '*':
        !           579:               if (state != 1) {
        !           580:                 wclear(hw);
        !           581:                 touchwin(hw);
        !           582:                 mvwaddstr(hw, 2, 0,  "[1] Fly\n[2] Stop flying\n");
        !           583:                 waddstr(hw,          "[3] Turn invisible\n[4] Turn Visible\n");
        !           584:                 mvwaddstr(hw, 0, 0, "What do you want to do? ");
        !           585:                 draw(hw);
        !           586:                 state = 1;      /* Now in prompt window */
        !           587:               }
        !           588:               break;
        !           589:
        !           590:             case ESC:
        !           591:                 if (state == 1) {
        !           592:                     restscr(cw);
        !           593:                 }
        !           594:                 msg("");
        !           595:
        !           596:                 after = FALSE;
        !           597:                 return;
        !           598:
        !           599:             when '1':
        !           600:             case '2':
        !           601:             case '3':
        !           602:             case '4':
        !           603:                 if (state == 1) {       /* In prompt window */
        !           604:                     restscr(cw);
        !           605:                 }
        !           606:
        !           607:                 msg("");
        !           608:
        !           609:                 state = 2;      /* Finished */
        !           610:                 break;
        !           611:
        !           612:             default:
        !           613:                 if (state == 1) {       /* In the prompt window */
        !           614:                     mvwaddstr(hw, 0, 0,
        !           615:                                 "Please enter a selection between 1 and 4:  ");
        !           616:                     draw(hw);
        !           617:                 }
        !           618:                 else {  /* Normal window */
        !           619:                     mpos = 0;
        !           620:                     msg("Please enter a selection between 1 and 4:  ");
        !           621:                 }
        !           622:         }
        !           623:     } while (state != 2);
        !           624:
        !           625:     /* We now must have a selection between 1 and 4 */
        !           626:     switch (selection) {
        !           627:         case '1':       /* Fly */
        !           628:             if (on(player, ISFLY)) {
        !           629:                 extinguish(land);       /* Extinguish in case of potion */
        !           630:                 msg("%slready flying.", terse ? "A" : "You are a");
        !           631:             }
        !           632:             else {
        !           633:                 msg("You feel lighter than air!");
        !           634:                 turn_on(player, ISFLY);
        !           635:             }
        !           636:         when '2':       /* Stop flying */
        !           637:             if (off(player, ISFLY))
        !           638:                 msg("%sot flying.", terse ? "N" : "You are n");
        !           639:             else {
        !           640:                 if (find_slot(land))
        !           641:                     msg("%sot flying by the cloak.",
        !           642:                         terse ? "N" : "You are n");
        !           643:                 else land();
        !           644:             }
        !           645:         when '3':       /* Turn invisible */
        !           646:             if (off(player, ISINVIS)) {
        !           647:                 turn_on(player, ISINVIS);
        !           648:                 msg("You have a tingling feeling all over your body. ");
        !           649:                 PLAYER = IPLAYER;
        !           650:                 light(&hero);
        !           651:             }
        !           652:             else {
        !           653:                 extinguish(appear);     /* Extinguish in case of potion */
        !           654:                 extinguish(dust_appear);/* dust of disappearance        */
        !           655:                 msg("%slready invisible.", terse ? "A" : "You are a");
        !           656:             }
        !           657:         when '4':       /* Turn visible */
        !           658:             if (off(player, ISINVIS))
        !           659:                 msg("%sot invisible.", terse ? "N" : "You are n");
        !           660:             else {
        !           661:                 if (find_slot(appear) || find_slot(dust_appear))
        !           662:                     msg("%sot invisible by the cloak.",
        !           663:                         terse ? "N" : "You are n");
        !           664:                 else appear();
        !           665:             }
        !           666:     }
        !           667: }
        !           668:
        !           669: /*
        !           670:  * try to write a scroll with the quill of Nagrom
        !           671:  */
        !           672:
        !           673: void
        !           674: use_quill(struct object *obj)
        !           675: {
        !           676:     struct linked_list  *item;
        !           677:     register int        i,
        !           678:                         scroll_ability;
        !           679:     int                 which_scroll,
        !           680:                         curlen,
        !           681:                         maxlen = 0,
        !           682:                         dummy = 0;
        !           683:     bool                nohw = FALSE;
        !           684:
        !           685:     i = which_scroll = 0;
        !           686:     scroll_ability = obj->o_charges;
        !           687:
        !           688:     /* Prompt for scrolls */
        !           689:     msg("Which scroll are you writing? (* for list): ");
        !           690:
        !           691:     which_scroll = (int) (wgetch(cw) - 'a');
        !           692:     msg("");    /* Get rid of the prompt */
        !           693:     if (which_scroll == (int) ESC - (int) 'a') {
        !           694:         after = FALSE;
        !           695:         return;
        !           696:     }
        !           697:     if (which_scroll >= 0 && which_scroll < MAXQUILL) nohw = TRUE;
        !           698:
        !           699:     else if (slow_invent) {
        !           700:         register char c;
        !           701:
        !           702:         nohw = TRUE;
        !           703:         do {
        !           704:             for (i=0; i<MAXQUILL; i++) {
        !           705:                 msg("");
        !           706:                 mvwaddch(msgw, 0, 0, '[');
        !           707:                 waddch(msgw, (char) ((int) 'a' + i));
        !           708:                 waddstr(msgw, "] A scroll of ");
        !           709:                 waddstr(msgw, s_magic[quill_scrolls[i].s_which].mi_name);
        !           710:                 waddstr(msgw, morestr);
        !           711:                 clearok(msgw, FALSE);
        !           712:                 draw(msgw);
        !           713:                 do {
        !           714:                     c = wgetch(cw);
        !           715:                 } while (c != ' ' && c != ESC);
        !           716:                 if (c == ESC)
        !           717:                     break;
        !           718:             }
        !           719:             msg("");
        !           720:             mvwaddstr(msgw, 0, 0, "Which scroll are you writing? ");
        !           721:             clearok(msgw, FALSE);
        !           722:             draw(msgw);
        !           723:
        !           724:             which_scroll = (int) (wgetch(cw) - 'a');
        !           725:         } while (which_scroll != (int) (ESC - 'a') &&
        !           726:                  (which_scroll < 0 || which_scroll >= MAXQUILL));
        !           727:
        !           728:         if (which_scroll == (int) (ESC - 'a')) {
        !           729:             mpos = 0;
        !           730:             msg("");
        !           731:             after = FALSE;
        !           732:             return;
        !           733:         }
        !           734:     }
        !           735:     else {
        !           736:         /* Now display the possible scrolls */
        !           737:         wclear(hw);
        !           738:         touchwin(hw);
        !           739:         mvwaddstr(hw, 2, 0, "   Cost            Scroll");
        !           740:         mvwaddstr(hw, 3, 0,
        !           741:                 "-----------------------------------------------");
        !           742:         maxlen = 47;    /* Maximum width of header */
        !           743:
        !           744:         for (i=0; i<MAXQUILL; i++) {
        !           745:             wmove(hw, i+4, 0);
        !           746:             sprintf(prbuf, "[%c]        %3d     A scroll of %s",
        !           747:                     (char) ((int) 'a' + i),
        !           748:                     quill_scrolls[i].s_cost,
        !           749:                     s_magic[quill_scrolls[i].s_which].mi_name);
        !           750:             waddstr(hw, prbuf);
        !           751:
        !           752:             /* Get the length of the line */
        !           753:             getyx(hw, dummy, curlen);
        !           754:             if (maxlen < curlen) maxlen = curlen;
        !           755:         }
        !           756:
        !           757:         sprintf(prbuf, "[Current scroll power = %d]", scroll_ability);
        !           758:         mvwaddstr(hw, 0, 0, prbuf);
        !           759:         waddstr(hw, " Which scroll are you writing? ");
        !           760:         getyx(hw, dummy, curlen);
        !           761:         if (maxlen < curlen) maxlen = curlen;
        !           762:
        !           763:         /* Should we overlay? */
        !           764:         if (menu_overlay && MAXQUILL + 3 < lines - 3) {
        !           765:             over_win(cw, hw, MAXQUILL + 5, maxlen + 3, 0, curlen, '\0');
        !           766:         }
        !           767:         else draw(hw);
        !           768:     }
        !           769:
        !           770:     if (!nohw) {
        !           771:         which_scroll = (int) (wgetch(cw) - 'a');
        !           772:         while (which_scroll < 0 || which_scroll >= MAXQUILL) {
        !           773:             if (which_scroll == (int) ESC - (int) 'a') {
        !           774:                 after = FALSE;
        !           775:
        !           776:                 /* Restore the screen */
        !           777:                 if (MAXQUILL + 3 < lines / 2) {
        !           778:                     clearok(cw, FALSE);
        !           779:                     touchwin(cw);
        !           780:                 }
        !           781:                 else restscr(cw);
        !           782:                 return;
        !           783:             }
        !           784:             wmove(hw, 0, 0);
        !           785:             wclrtoeol(hw);
        !           786:             waddstr(hw, "Please enter one of the listed scrolls. ");
        !           787:             getyx(hw, dummy, curlen);
        !           788:             if (maxlen < curlen) maxlen = curlen;
        !           789:
        !           790:             /* Should we overlay? */
        !           791:             if (menu_overlay && MAXQUILL + 3 < lines - 3) {
        !           792:                 over_win(cw, hw, MAXQUILL + 5, maxlen + 3,
        !           793:                             0, curlen, '\0');
        !           794:             }
        !           795:             else draw(hw);
        !           796:
        !           797:             which_scroll = (int) (wgetch(cw) - 'a');
        !           798:         }
        !           799:     }
        !           800:
        !           801:     /* Now restore the screen if we have to */
        !           802:     if (!nohw) {
        !           803:         if (MAXQUILL + 3 < lines / 2) {
        !           804:             touchwin(cw);
        !           805:             clearok(cw, FALSE);
        !           806:         }
        !           807:         else restscr(cw);
        !           808:     }
        !           809:
        !           810:     /* We've waited our required time. */
        !           811:     player.t_using = NULL;
        !           812:     player.t_action = A_NIL;
        !           813:
        !           814:     if (quill_scrolls[which_scroll].s_cost > scroll_ability) {
        !           815:         msg("Your attempt fails.");
        !           816:         return;
        !           817:     }
        !           818:
        !           819:     obj->o_charges -= quill_scrolls[which_scroll].s_cost;
        !           820:     item = spec_item(SCROLL, quill_scrolls[which_scroll].s_which, 0, 0);
        !           821:     if (add_pack(item, FALSE) == FALSE) {
        !           822:         (OBJPTR(item))->o_pos = hero;
        !           823:         fall(item, TRUE);
        !           824:     }
        !           825:
        !           826:     which_scroll = dummy; /* Hack to stop IRIX complaint about dummy not */
        !           827:                           /* being used */
        !           828: }
        !           829:
        !           830: /*
        !           831:  * Use something
        !           832:  */
        !           833:
        !           834: void
        !           835: use_mm(int which)
        !           836: {
        !           837:     register struct object *obj = NULL;
        !           838:     register struct linked_list *item = NULL;
        !           839:     bool is_mm;
        !           840:
        !           841:     is_mm = FALSE;
        !           842:
        !           843:     if (which < 0) {    /* A real miscellaneous magic item  */
        !           844:         /* This is miscellaneous magic.  It takes 3 movement periods to use */
        !           845:         if (player.t_action != C_USE) {
        !           846:             int units;  /* Number of movement units for the item */
        !           847:
        !           848:             item = get_item(pack, "use", USEABLE, FALSE, FALSE);
        !           849:
        !           850:             /*
        !           851:              * Make certain that it is a micellaneous magic item
        !           852:              */
        !           853:             if (item == NULL)
        !           854:                 return;
        !           855:
        !           856:             units = usage_time(item);
        !           857:             if (units < 0) return;
        !           858:
        !           859:             player.t_using = item;      /* Remember what it is */
        !           860:             player.t_action = C_USE;    /* We are quaffing */
        !           861:             player.t_no_move = units * movement(&player);
        !           862:             return;
        !           863:         }
        !           864:
        !           865:         /* We have waited our time, let's use the item */
        !           866:         item = player.t_using;
        !           867:         player.t_using = NULL;
        !           868:         player.t_action = A_NIL;
        !           869:
        !           870:         is_mm = TRUE;
        !           871:
        !           872:         obj = OBJPTR(item);
        !           873:         which = obj->o_which;
        !           874:     }
        !           875:
        !           876:     if (obj->o_type == POTION) {                /* A potion */
        !           877:         is_mm = FALSE;
        !           878:         inpack--;
        !           879:         detach (pack, item);
        !           880:         switch (obj->o_which) {
        !           881:             case P_POISON:
        !           882:                 if (cur_weapon) {
        !           883:                     if (cur_weapon->o_type == RELIC) {
        !           884:                         msg("The poison burns off %s",
        !           885:                             inv_name(cur_weapon,FALSE));
        !           886:                     }
        !           887:                     else {
        !           888:                         cur_weapon->o_flags |= ISPOISON;
        !           889:                         msg("Your weapon has %s gooey stuff on it",
        !           890:                             p_colors[cur_weapon->o_which]);
        !           891:                     }
        !           892:                 }
        !           893:                 else
        !           894:                     msg("The poison pours on the floor and disappears!");
        !           895:         }
        !           896:         o_discard(item);
        !           897:     }
        !           898:     else if (obj->o_type == RELIC) {            /* An artifact */
        !           899:         is_mm = FALSE;
        !           900:         switch (obj->o_which) {
        !           901:             case EMORI_CLOAK:
        !           902:                 use_emori();
        !           903:             when QUILL_NAGROM:
        !           904:                 use_quill(obj);
        !           905:             when BRIAN_MANDOLIN:
        !           906:                 /* Put monsters around us to sleep */
        !           907:                 read_scroll(S_HOLD, 0, FALSE);
        !           908:             when GERYON_HORN:
        !           909:                 /* Chase close monsters away */
        !           910:                 msg("The horn blasts a shrill tone.");
        !           911:                 do_panic(0);
        !           912:             when EYE_VECNA:
        !           913:                 msg("The pain slowly subsides.. ");
        !           914:             when HEIL_ANKH:
        !           915:                 msg("Your hand grows very warm. ");
        !           916:             when YENDOR_AMULET:
        !           917:                 msg("Your chest glows! ");
        !           918:                 do_panic(findmindex("frost giant"));
        !           919:             when STONEBONES_AMULET:
        !           920:                 msg("Your chest glows! ");
        !           921:                 do_panic(findmindex("storm giant"));
        !           922:             when SURTUR_RING:
        !           923:                 do_panic(findmindex("fire giant"));
        !           924:             when ALTERAN_CARD:  /* the card allows you to teleport anywhere */
        !           925:         do_teleport();
        !           926:         }
        !           927:     }
        !           928:     else switch (which) {               /* Miscellaneous Magic */
        !           929:         /*
        !           930:          * the jug of alchemy manufactures potions when you drink
        !           931:          * the potion it will make another after a while
        !           932:          */
        !           933:         case MM_JUG:
        !           934:             if (obj->o_ac == JUG_EMPTY) {
        !           935:                 msg("The jug is empty");
        !           936:                 break;
        !           937:             }
        !           938:             quaff (obj->o_ac, 0, 0, FALSE);
        !           939:             obj->o_ac = JUG_EMPTY;
        !           940:             fuse (alchemy, obj, ALCHEMYTIME, AFTER);
        !           941:             if (!(obj->o_flags & ISKNOW))
        !           942:                 whatis(item);
        !           943:
        !           944:         /*
        !           945:          * the beaker of plentiful potions is used to hold potions
        !           946:          * the book of infinite spells is used to hold scrolls
        !           947:          */
        !           948:         when MM_BEAKER:
        !           949:         case MM_BOOK:
        !           950:             do_bag(item);
        !           951:
        !           952:         /*
        !           953:          * the chime of opening opens up secret doors
        !           954:          */
        !           955:         when MM_OPEN:
        !           956:         {
        !           957:             register struct linked_list *exit;
        !           958:             register struct room *rp;
        !           959:             register coord *cp;
        !           960:
        !           961:             if (obj->o_charges <= 0) {
        !           962:                 msg("The chime is cracked!");
        !           963:                 break;
        !           964:             }
        !           965:             obj->o_charges--;
        !           966:             msg("chime... chime... hime... ime... me... e...");
        !           967:             if ((rp = roomin(&hero)) == NULL) {
        !           968:                 search(FALSE, TRUE); /* Non-failing search for door */
        !           969:                 break;
        !           970:             }
        !           971:             for (exit = rp->r_exit; exit != NULL; exit = next(exit)) {
        !           972:                 cp = DOORPTR(exit);
        !           973:                 if (winat(cp->y, cp->x) == SECRETDOOR) {
        !           974:                     mvaddch (cp->y, cp->x, DOOR);
        !           975:                     if (cansee (cp->y, cp->x))
        !           976:                         mvwaddch(cw, cp->y, cp->x, DOOR);
        !           977:                 }
        !           978:             }
        !           979:         }
        !           980:
        !           981:         /*
        !           982:          * the chime of hunger just makes the hero hungry
        !           983:          */
        !           984:         when MM_HUNGER:
        !           985:             if (obj->o_charges <= 0) {
        !           986:                 msg("The chime is spent. ");
        !           987:                 break;
        !           988:             }
        !           989:             obj->o_charges--;
        !           990:             if (food_left >= MORETIME + 5) {
        !           991:                 food_left = MORETIME + 5;
        !           992:                 msg("A strange sensation comes over you.. ");
        !           993:                 msg(terse? "Getting hungry" : "You are starting to get hungry");
        !           994:                 hungry_state = F_HUNGRY;
        !           995:             }
        !           996:             if (player.t_ctype == C_PALADIN ||
        !           997:                 player.t_ctype == C_RANGER  || player.t_ctype == C_MONK) {
        !           998:                     msg("You feel a chilling sensation!");
        !           999:                     aggravate(TRUE, FALSE);
        !          1000:             }
        !          1001:             else {
        !          1002:                 aggravate(TRUE, TRUE);
        !          1003:             }
        !          1004:
        !          1005:         /*
        !          1006:          * the drums of panic make all creatures within two squares run
        !          1007:          * from the hero in panic unless they save or they are mindless
        !          1008:          * undead
        !          1009:          */
        !          1010:         when MM_DRUMS:
        !          1011:             if (obj->o_charges <= 0) {
        !          1012:                 msg("The drum is broken.");
        !          1013:                 break;
        !          1014:             }
        !          1015:             obj->o_charges--;
        !          1016:             do_panic(0);
        !          1017:         return;
        !          1018:         /*
        !          1019:          * dust of disappearance makes the player invisible for a while
        !          1020:          */
        !          1021:         when MM_DISAPPEAR:
        !          1022:             m_know[MM_DISAPPEAR] = TRUE;
        !          1023:             if (obj->o_charges <= 0) {
        !          1024:                 msg("No more dust!");
        !          1025:                 break;
        !          1026:             }
        !          1027:             obj->o_charges--;
        !          1028:             if (terse) msg("You sneeze! ");
        !          1029:             else msg("Ahh.. Ahh... Choo!! ");
        !          1030:             if (!find_slot(dust_appear)) {
        !          1031:                 turn_on(player, ISINVIS);
        !          1032:                 fuse(dust_appear, NULL, DUSTTIME, AFTER);
        !          1033:                 PLAYER = IPLAYER;
        !          1034:                 light(&hero);
        !          1035:             }
        !          1036:             else lengthen(dust_appear, DUSTTIME);
        !          1037:
        !          1038:         /*
        !          1039:          * dust of choking and sneezing can kill the hero if he misses
        !          1040:          * the save
        !          1041:          */
        !          1042:         when MM_CHOKE:
        !          1043:             m_know[MM_CHOKE] = TRUE;
        !          1044:             if (obj->o_charges <= 0) {
        !          1045:                 msg("No more dust!");
        !          1046:                 break;
        !          1047:             }
        !          1048:             obj->o_charges--;
        !          1049:             if (terse) msg("You snort! ");
        !          1050:             else msg("aaAAACHOOOooo. Cough. Cough. Sneeze. Sneeze.");
        !          1051:             if (!cur_relic[SURTUR_RING] && !save(VS_POISON, &player, 0)) {
        !          1052:                 msg ("You choke to death!!!  --More--");
        !          1053:                 wait_for(' ');
        !          1054:                 pstats.s_hpt = -1;  /* in case he hangs up the phone! */
        !          1055:                 death(D_CHOKE);
        !          1056:             }
        !          1057:             else {
        !          1058:                 msg("You begin to cough and choke uncontrollably! ");
        !          1059:                 if (find_slot(unchoke))
        !          1060:                     lengthen(unchoke, DUSTTIME);
        !          1061:                 else
        !          1062:                     fuse(unchoke, NULL, DUSTTIME, AFTER);
        !          1063:                 turn_on(player, ISHUH);
        !          1064:                 turn_on(player, ISBLIND);
        !          1065:                 light(&hero);
        !          1066:             }
        !          1067:
        !          1068:         when MM_KEOGHTOM:
        !          1069:             /*
        !          1070:              * this is a very powerful healing ointment
        !          1071:              * but it takes a while to put on...
        !          1072:              */
        !          1073:             obj->o_charges--;
        !          1074:             if (on(player, HASDISEASE)) {
        !          1075:                 extinguish(cure_disease);
        !          1076:                 cure_disease();
        !          1077:                 msg(terse ? "You feel yourself improving."
        !          1078:                           : "You begin to feel yourself improving again.");
        !          1079:             }
        !          1080:             if (on(player, HASINFEST)) {
        !          1081:                 turn_off(player, HASINFEST);
        !          1082:                 infest_dam = 0;
        !          1083:                 msg(terse ? "You feel yourself improving."
        !          1084:                           : "You begin to feel yourself improving again.");
        !          1085:             }
        !          1086:             if (on(player, DOROT)) {
        !          1087:                 msg("You feel your skin returning to normal.");
        !          1088:                 turn_off(player, DOROT);
        !          1089:             }
        !          1090:             pstats.s_hpt += roll(pstats.s_lvl, 6);
        !          1091:             if (pstats.s_hpt > max_stats.s_hpt)
        !          1092:                 pstats.s_hpt = max_stats.s_hpt;
        !          1093:             sight();
        !          1094:             msg("You begin to feel much better.");
        !          1095:
        !          1096:         /*
        !          1097:          * The book has a character class associated with it.
        !          1098:          * if your class matches that of the book, it will raise your
        !          1099:          * level by one. If your class does not match the one of the book,
        !          1100:          * it change your class to that of book.
        !          1101:          * Note that it takes a while to read.
        !          1102:          */
        !          1103:         when MM_SKILLS:
        !          1104:             detach (pack, item);
        !          1105:             inpack--;
        !          1106:             changeclass(obj->o_ac);
        !          1107:     when MM_CRYSTAL:
        !          1108:     {
        !          1109:         register char *str;
        !          1110:
        !          1111:             detach (pack, item);
        !          1112:             inpack--;
        !          1113:             if (obj->o_flags & ISCURSED) {
        !          1114:             if (is_mm && !m_know[MM_CRYSTAL])
        !          1115:                 str = "rock in a curious sort of way";
        !          1116:         else
        !          1117:             str = "crystal briefly";
        !          1118:         msg("You rub the %s and yell out in agony! ", str);
        !          1119:           /* curse his pack */
        !          1120:         read_scroll(S_REMOVE, obj->o_flags & ISCURSED, FALSE);
        !          1121:           /* aggravate monsters */
        !          1122:         read_scroll(S_HOLD, obj->o_flags & ISCURSED, FALSE);
        !          1123:                 player.t_no_move += (2 * movement(&player) * FREEZETIME);
        !          1124:                 player.t_action = A_FREEZE;
        !          1125:           /* loss of 1/4 total hit points */
        !          1126:         pstats.s_hpt -= ((max_stats.s_hpt / 4));
        !          1127:                 max_stats.s_hpt -= rnd(3)+3;
        !          1128:         if (pstats.s_hpt > max_stats.s_hpt)
        !          1129:                 pstats.s_hpt = max_stats.s_hpt;
        !          1130:                 if ((pstats.s_hpt < 1) || (max_stats.s_hpt < 1)) {
        !          1131:             pstats.s_hpt = -1;
        !          1132:             msg("The crystal has absorbed you...  --More--");
        !          1133:             wait_for(' ');
        !          1134:                     death(D_CRYSTAL);
        !          1135:         }
        !          1136:         }
        !          1137:         else {  /* if normal, give him a bonus */
        !          1138:             if (is_mm && !m_know[MM_CRYSTAL])
        !          1139:                     str = "flashes brightly";
        !          1140:         else
        !          1141:             str = "vibrates softly";
        !          1142:         msg("You rub the crystal and it %s...  ", str);
        !          1143:           /* cure him */
        !          1144:         read_scroll(S_CURING, 0, FALSE);
        !          1145:           /* give him weird hands */
        !          1146:                 turn_on(player, CANHUH);
        !          1147:         msg("Your fingertips turn blue.  ");
        !          1148:           /* add intelligence */
        !          1149:                 if (player.t_ctype == C_MAGICIAN) {
        !          1150:                 max_stats.s_intel += 1;
        !          1151:                 pstats.s_intel += 1;
        !          1152:         }
        !          1153:           /* add strength */
        !          1154:                 if (player.t_ctype == C_FIGHTER) {
        !          1155:             max_stats.s_str += 1;
        !          1156:                 pstats.s_str += 1;
        !          1157:         }
        !          1158:           /* add wisdom */
        !          1159:                 if (player.t_ctype == C_CLERIC || player.t_ctype == C_PALADIN) {
        !          1160:                     max_stats.s_wisdom += 1;
        !          1161:                     pstats.s_wisdom += 1;
        !          1162:         }
        !          1163:           /* add dexterity */
        !          1164:                 if (player.t_ctype == C_THIEF || player.t_ctype == C_ASSASSIN) {
        !          1165:                     max_stats.s_dext += 1;
        !          1166:                     pstats.s_dext += 1;
        !          1167:         }
        !          1168:               /* add constitution */
        !          1169:                 if (player.t_ctype == C_MONK) {
        !          1170:                     max_stats.s_const += 1;
        !          1171:                     pstats.s_const += 1;
        !          1172:         }
        !          1173:           /* add charisma */
        !          1174:                 if (player.t_ctype == C_RANGER || player.t_ctype == C_PALADIN) {
        !          1175:                 max_stats.s_charisma += 1;
        !          1176:                 pstats.s_charisma += 1;
        !          1177:         }
        !          1178:         }
        !          1179:             if (obj->o_flags & ISBLESSED) {  /* if blessed */
        !          1180:             if (is_mm && !m_know[MM_CRYSTAL])
        !          1181:             msg("The crystal disappears from your hands.  ");
        !          1182:         else
        !          1183:             msg("Your hands absorb the medicine crystal.  ");
        !          1184:             /* set hit points to at least 50 */
        !          1185:         if (max_stats.s_hpt < 50) {
        !          1186:             max_stats.s_hpt = 50;
        !          1187:                     pstats.s_hpt = max_stats.s_hpt;
        !          1188:         }
        !          1189:         else {  /* or just add 10% */
        !          1190:             max_stats.s_hpt += (max_stats.s_hpt / 10);
        !          1191:                     pstats.s_hpt = max_stats.s_hpt;
        !          1192:         }
        !          1193:             /* heck, really make it memorable */
        !          1194:         read_scroll(S_REMOVE, obj->o_flags & ISBLESSED, FALSE);
        !          1195:         }
        !          1196:     }
        !          1197:         otherwise:
        !          1198:             msg("What a strange magic item you have!");
        !          1199:     }
        !          1200:     status(FALSE);
        !          1201:     if (is_mm && m_know[which] && m_guess[which]) {
        !          1202:         free(m_guess[which]);
        !          1203:         m_guess[which] = NULL;
        !          1204:     }
        !          1205:     else if (is_mm && !m_know[which] && askme &&
        !          1206:              (obj->o_flags & ISKNOW) == 0 &&
        !          1207:              m_guess[which] == NULL) {
        !          1208:         nameitem(item, FALSE);
        !          1209:     }
        !          1210:     if (item != NULL && (which == MM_SKILLS || which == MM_CRYSTAL))
        !          1211:         o_discard(item);
        !          1212:     updpack(TRUE, &player);
        !          1213: }
        !          1214:
        !          1215: /*
        !          1216:  * usage_time:
        !          1217:  *      Return how long it takes to use an item.  For now we only give time
        !          1218:  *      for MM, RELIC, SCROLL, and POTION items.
        !          1219:  */
        !          1220:
        !          1221: int
        !          1222: usage_time(struct linked_list *item)
        !          1223: {
        !          1224:     register struct object *obj;
        !          1225:     register int units = -1;
        !          1226:
        !          1227:     obj = OBJPTR(item);
        !          1228:     switch (obj->o_type) {
        !          1229:         case SCROLL:    units = 4;
        !          1230:         when POTION:    units = 3;
        !          1231:         when RELIC:                     /* An artifact */
        !          1232:             switch (obj->o_which) {
        !          1233:                 case BRIAN_MANDOLIN:
        !          1234:                 case GERYON_HORN:       units = 4;
        !          1235:                 when QUILL_NAGROM:
        !          1236:                 case EMORI_CLOAK:
        !          1237:                 case HEIL_ANKH:         units = 3;
        !          1238:                 when YENDOR_AMULET:
        !          1239:                 case STONEBONES_AMULET: units = 2;
        !          1240:                 when EYE_VECNA:         units = 6;
        !          1241:                     /* The eye will do nothing other than give a headache */
        !          1242:                     pstats.s_hpt -= rnd(25)+1;
        !          1243:                     msg("You feel a sharp pain shoot through your forehead!");
        !          1244:                     if (pstats.s_hpt < 1) {
        !          1245:                pstats.s_hpt = -1;
        !          1246:                        msg ("The pain is too much for you to bear!  --More--");
        !          1247:                        wait_for(' ');
        !          1248:                        death(D_RELIC);
        !          1249:                     }
        !          1250:                 when SURTUR_RING:
        !          1251:                     units = 3;
        !          1252:                     msg("Your nose tickles a bit.");
        !          1253:         when ALTERAN_CARD:
        !          1254:             units = 2;
        !          1255:             msg("You gaze intently at the card... ");
        !          1256:             }
        !          1257:         when MM:
        !          1258:             switch (obj->o_which) {     /* Miscellaneous Magic */
        !          1259:                 case MM_JUG:
        !          1260:                     if (obj->o_ac == JUG_EMPTY) {
        !          1261:                         msg("The jug is empty");
        !          1262:                         return (-1);
        !          1263:                     }
        !          1264:                     units = 2;
        !          1265:                 when MM_BEAKER:
        !          1266:                 case MM_BOOK:
        !          1267:                     /* This is a strange case because it can go forever */
        !          1268:                     units = 1;
        !          1269:                 case MM_CHOKE: /* Dust */
        !          1270:                 when MM_HUNGER: /* Chimes */
        !          1271:                     units = 3;
        !          1272:                 when MM_OPEN:
        !          1273:                 case MM_DRUMS:
        !          1274:                 case MM_DISAPPEAR:
        !          1275:                     units = 4;
        !          1276:                 when MM_KEOGHTOM:
        !          1277:             /* Ointment */
        !          1278:                     if (obj->o_charges <= 0) {
        !          1279:                         msg("The jar is empty!");
        !          1280:                         return (-1);
        !          1281:                     }
        !          1282:                     units = 5;
        !          1283:                 when MM_SKILLS:
        !          1284:                     /* A whole book! */
        !          1285:                     units = 15;
        !          1286:                 when MM_CRYSTAL:
        !          1287:             /* Enhance player's quest */
        !          1288:             units = 5;
        !          1289:                 otherwise:
        !          1290:                     /* What is it? */
        !          1291:                     units = -1;
        !          1292:             }
        !          1293:         otherwise:      units = -1;
        !          1294:     }
        !          1295:
        !          1296:     return (units);
        !          1297: }
        !          1298:

CVSweb