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

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

1.1     ! rubenllo    1: /*
        !             2:     util.c  -  all sorts of miscellaneous routines
        !             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:     Based on "Rogue: Exploring the Dungeons of Doom"
        !            13:     Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
        !            14:     All rights reserved.
        !            15:
        !            16:     See the file LICENSE.TXT for full copyright and licensing information.
        !            17: */
        !            18:
        !            19: #include <curses.h>
        !            20: #include <ctype.h>
        !            21: #include <string.h>
        !            22: #include "rogue.h"
        !            23:
        !            24: /*
        !            25:  * this routine computes the players current AC without dex bonus's
        !            26:  */
        !            27:
        !            28: int
        !            29: ac_compute(bool ignoremetal)
        !            30: {
        !            31:     register int ac;
        !            32:
        !            33:     ac = pstats.s_arm; /* base armor of "skin" */
        !            34:     if (cur_armor) {
        !            35:         if (!ignoremetal ||
        !            36:              (cur_armor->o_which != LEATHER             &&
        !            37:               cur_armor->o_which != STUDDED_LEATHER     &&
        !            38:               cur_armor->o_which != PADDED_ARMOR))
        !            39:                 ac -= (10 - cur_armor->o_ac);
        !            40:     }
        !            41:     if (player.t_ctype == C_MONK)
        !            42:         ac -= pstats.s_lvl * 3 / 5;
        !            43:     ac -= ring_value(R_PROTECT);
        !            44:     if (cur_misc[WEAR_BRACERS] != NULL)
        !            45:         ac -= cur_misc[WEAR_BRACERS]->o_ac;
        !            46:     if (cur_misc[WEAR_CLOAK] != NULL)
        !            47:         ac -= cur_misc[WEAR_CLOAK]->o_ac;
        !            48:
        !            49:     /* If player has the cloak, must be wearing it */
        !            50:     if (cur_relic[EMORI_CLOAK]) ac -= 15;
        !            51:
        !            52:     if (ac > 25)
        !            53:         ac = 25;
        !            54:     return(ac);
        !            55: }
        !            56:
        !            57: /*
        !            58:  * aggravate:
        !            59:  *      aggravate all the monsters on this level
        !            60:  */
        !            61:
        !            62: void
        !            63: aggravate(bool do_uniques, bool do_good)
        !            64: {
        !            65:     register struct linked_list *mi;
        !            66:     register struct thing *thingptr;
        !            67:
        !            68:     for (mi = mlist; mi != NULL; mi = next(mi)) {
        !            69:         thingptr = THINGPTR(mi);
        !            70:         if (do_good == FALSE && off(*thingptr, ISMEAN)) continue;
        !            71:         if (do_uniques || off(*thingptr, ISUNIQUE)) runto(thingptr, &hero);
        !            72:     }
        !            73: }
        !            74:
        !            75: /*
        !            76:  * cansee:
        !            77:  *      returns true if the hero can see a certain coordinate.
        !            78:  */
        !            79:
        !            80: bool
        !            81: cansee(int y, int x)
        !            82: {
        !            83:     register struct room *rer;
        !            84:     register int radius;
        !            85:     coord tp;
        !            86:
        !            87:     if (on(player, ISBLIND))
        !            88:         return FALSE;
        !            89:
        !            90:     tp.y = y;
        !            91:     tp.x = x;
        !            92:     rer = roomin(&tp);
        !            93:
        !            94:     /* How far can we see? */
        !            95:     if (levtype == OUTSIDE) {
        !            96:         if (daytime) radius = 36;
        !            97:         else if (lit_room(rer)) radius = 9;
        !            98:         else radius = 3;
        !            99:     }
        !           100:     else radius = 3;
        !           101:
        !           102:     /*
        !           103:      * We can only see if the hero in the same room as
        !           104:      * the coordinate and the room is lit or if it is close.
        !           105:      */
        !           106:     return ((rer != NULL &&
        !           107:              levtype != OUTSIDE &&
        !           108:              (levtype != MAZELEV ||     /* Maze level needs direct line */
        !           109:               maze_view(tp.y, tp.x)) &&
        !           110:              rer == roomin(&hero) &&
        !           111:              lit_room(rer)) ||
        !           112:             DISTANCE(y, x, hero.y, hero.x) < radius);
        !           113: }
        !           114:
        !           115: /*
        !           116:  * check_level:
        !           117:  *      Check to see if the guy has gone up a level.
        !           118:  *
        !           119:  *      Return points needed to obtain next level.
        !           120:  *
        !           121:  * These are certain beginning experience levels for all players.
        !           122:  * All further experience levels are computed by muliplying by 2
        !           123:  * up through MAXDOUBLE. Then the cap is added in to compute
        !           124:  * further levels
        !           125:  */
        !           126:
        !           127: long
        !           128: check_level(void)
        !           129: {
        !           130:     register int i, j, add = 0;
        !           131:     register unsigned long exp;
        !           132:     long retval;        /* Return value */
        !           133:     int nsides;
        !           134:
        !           135:     pstats.s_lvl -= pstats.s_lvladj; /* correct for level adjustment */
        !           136:     /* See if we are past the doubling stage */
        !           137:     exp = char_class[player.t_ctype].cap;
        !           138:     if (pstats.s_exp >= exp) {
        !           139:         i = pstats.s_exp/exp;   /* First get amount above doubling area */
        !           140:         retval = exp + i * exp; /* Compute next higher boundary */
        !           141:         i += MAXDOUBLE; /* Add in the previous doubled levels */
        !           142:     }
        !           143:     else {
        !           144:         i = 0;
        !           145:         exp = char_class[player.t_ctype].start_exp;
        !           146:         while (exp <= pstats.s_exp) {
        !           147:             i++;
        !           148:             exp <<= 1;
        !           149:         }
        !           150:         retval = exp;
        !           151:     }
        !           152:     if (++i > pstats.s_lvl) {
        !           153:         nsides = char_class[player.t_ctype].hit_pts;
        !           154:         for (j=0; j<(i-pstats.s_lvl); j++) /* Take care of multi-level jumps */
        !           155:             add += max(1, roll(1,nsides) + const_bonus());
        !           156:         max_stats.s_hpt += add;
        !           157:         if ((pstats.s_hpt += add) > max_stats.s_hpt)
        !           158:             pstats.s_hpt = max_stats.s_hpt;
        !           159:         msg("Welcome, %s, to level %d",
        !           160:             cnames[player.t_ctype][min(i-1, NUM_CNAMES-1)], i);
        !           161:     }
        !           162:     pstats.s_lvl = i;
        !           163:     pstats.s_lvl += pstats.s_lvladj; /* correct for level adjustment */
        !           164:     return(retval);
        !           165: }
        !           166:
        !           167: /*
        !           168:  * Used to modify the players strength
        !           169:  * it keeps track of the highest it has been, just in case
        !           170:  */
        !           171:
        !           172: void
        !           173: chg_str(int amt)
        !           174: {
        !           175:     register int ring_str;              /* ring strengths */
        !           176:     register struct stats *ptr;         /* for speed */
        !           177:
        !           178:     ptr = &pstats;
        !           179:     ring_str = ring_value(R_ADDSTR);
        !           180:     ptr->s_str -= ring_str;
        !           181:     ptr->s_str += amt;
        !           182:     if (ptr->s_str > MAXATT) ptr->s_str = MAXATT;
        !           183:     if (ptr->s_str > max_stats.s_str)
        !           184:         max_stats.s_str = ptr->s_str;
        !           185:     ptr->s_str += ring_str;
        !           186:     if (ptr->s_str <= 0) {
        !           187:     pstats.s_hpt = -1;
        !           188:         death(D_STRENGTH);
        !           189:     }
        !           190:     updpack(TRUE, &player);
        !           191: }
        !           192:
        !           193: /*
        !           194:  * let's confuse the player
        !           195:  */
        !           196:
        !           197: void
        !           198: confus_player(void)
        !           199: {
        !           200:     if (off(player, ISCLEAR))
        !           201:     {
        !           202:         msg("Wait, what's going on here!  Huh? What? Who?");
        !           203:         if (find_slot(unconfuse))
        !           204:             lengthen(unconfuse, HUHDURATION);
        !           205:         else
        !           206:             fuse(unconfuse, NULL, HUHDURATION, AFTER);
        !           207:         turn_on(player, ISHUH);
        !           208:     }
        !           209:     else msg("You feel dizzy for a moment, but it quickly passes.");
        !           210: }
        !           211:
        !           212: /*
        !           213:  * this routine computes the players current dexterity
        !           214:  */
        !           215:
        !           216: int
        !           217: dex_compute(void)
        !           218: {
        !           219:     if (cur_misc[WEAR_GAUNTLET] != NULL         &&
        !           220:         cur_misc[WEAR_GAUNTLET]->o_which == MM_G_DEXTERITY) {
        !           221:         if (cur_misc[WEAR_GAUNTLET]->o_flags & ISCURSED)
        !           222:             return (3);
        !           223:         else
        !           224:             return (21);
        !           225:     }
        !           226:     else
        !           227:             return (pstats.s_dext);
        !           228: }
        !           229:
        !           230: /*
        !           231:  * diag_ok:
        !           232:  *      Check to see if the move is legal if it is diagonal
        !           233:  */
        !           234:
        !           235: bool
        !           236: diag_ok(coord *sp, coord *ep, struct thing *flgptr)
        !           237: {
        !           238:     register int numpaths = 0;
        !           239:
        !           240:     /* Horizontal and vertical moves are always ok */
        !           241:     if (ep->x == sp->x || ep->y == sp->y)
        !           242:         return TRUE;
        !           243:
        !           244:     /* Diagonal moves are not allowed if there is a horizontal or
        !           245:      * vertical path to the destination
        !           246:      */
        !           247:     if (step_ok(ep->y, sp->x, MONSTOK, flgptr)) numpaths++;
        !           248:     if (step_ok(sp->y, ep->x, MONSTOK, flgptr)) numpaths++;
        !           249:     return(numpaths != 1);
        !           250: }
        !           251:
        !           252: /*
        !           253:  * pick a random position around the give (y, x) coordinates
        !           254:  */
        !           255:
        !           256: coord *
        !           257: fallpos(coord *pos, bool be_clear, int range)
        !           258: {
        !           259:         register int tried, i, j;
        !           260:         register char ch;
        !           261:         static coord ret;
        !           262:         static short masks[] = {
        !           263:                 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x100 };
        !           264:
        !           265: /*
        !           266:  * Pick a spot at random centered on the position given by 'pos' and
        !           267:  * up to 'range' squares away from 'pos'
        !           268:  *
        !           269:  * If 'be_clear' is TRUE, the spot must be either FLOOR or PASSAGE
        !           270:  * inorder to be considered valid
        !           271:  *
        !           272:  * Generate a number from 0 to 8, representing the position to pick.
        !           273:  * Note that this DOES include the positon 'pos' itself
        !           274:  *
        !           275:  * If this position is not valid, mark it as 'tried', and pick another.
        !           276:  * Whenever a position is picked that has been tried before,
        !           277:  * sequentially find the next untried position. This eliminates costly
        !           278:  * random number generation
        !           279:  */
        !           280:
        !           281:         tried = 0;
        !           282:         while( tried != 0x1ff ) {
        !           283:                 i = rnd(9);
        !           284:                 while( tried & masks[i] )
        !           285:                         i = (i + 1) % 9;
        !           286:
        !           287:                 tried |= masks[i];
        !           288:
        !           289:                 for( j = 1; j <= range; j++ ) {
        !           290:                         ret.x = pos->x + j*grid[i].x;
        !           291:                         ret.y = pos->y + j*grid[i].y;
        !           292:
        !           293:                         if (ret.x == hero.x && ret.y == hero.y)
        !           294:                                 continue; /* skip the hero */
        !           295:
        !           296:                         if (ret.x < 0 || ret.x > cols - 1 ||
        !           297:                             ret.y < 1 || ret.y > lines - 3)
        !           298:                                 continue; /* off the screen? */
        !           299:
        !           300:                         ch = winat(ret.y, ret.x);
        !           301:
        !           302:                         /*
        !           303:                          * Check to make certain the spot is valid
        !           304:                          */
        !           305:                         switch( ch ) {
        !           306:                         case FLOOR:
        !           307:                         case PASSAGE:
        !           308:                                 return( &ret );
        !           309:                         case GOLD:
        !           310:                         case SCROLL:
        !           311:                         case POTION:
        !           312:                         case STICK:
        !           313:                         case RING:
        !           314:                         case WEAPON:
        !           315:                         case ARMOR:
        !           316:                         case MM:
        !           317:                         case FOOD:
        !           318:                                 if(!be_clear && levtype != POSTLEV)
        !           319:                                         return( &ret );
        !           320:                         default:
        !           321:                                 break;
        !           322:                         }
        !           323:                 }
        !           324:         }
        !           325:         return( NULL );
        !           326: }
        !           327:
        !           328: /*
        !           329:  * findmindex:
        !           330:  *      Find the index into the monster table of a monster given its name.
        !           331:  */
        !           332:
        !           333: int
        !           334: findmindex(char *name)
        !           335: {
        !           336:     int which;
        !           337:
        !           338:     for (which=1; which<NUMMONST; which++) {
        !           339:          if (strcmp(name, monsters[which].m_name) == 0)
        !           340:              break;
        !           341:     }
        !           342:     if (which >= NUMMONST) {
        !           343:          debug("couldn't find monster index");
        !           344:          which = 1;
        !           345:     }
        !           346:     return(which);
        !           347: }
        !           348:
        !           349: /*
        !           350:  * find_mons:
        !           351:  *      Find the monster from his coordinates
        !           352:  */
        !           353:
        !           354: struct linked_list *
        !           355: find_mons(int y, int x)
        !           356: {
        !           357:     register struct linked_list *item;
        !           358:     register struct thing *th;
        !           359:
        !           360:     for (item = mlist; item != NULL; item = next(item))
        !           361:     {
        !           362:         th = THINGPTR(item);
        !           363:         if (th->t_pos.y == y && th->t_pos.x == x)
        !           364:             return item;
        !           365:     }
        !           366:     return NULL;
        !           367: }
        !           368:
        !           369: /*
        !           370:  * find_obj:
        !           371:  *      find the unclaimed object at y, x
        !           372:  */
        !           373:
        !           374: struct linked_list *
        !           375: find_obj(int y, int x)
        !           376: {
        !           377:     register struct linked_list *obj;
        !           378:     register struct object *op;
        !           379:
        !           380:     for (obj = lvl_obj; obj != NULL; obj = next(obj))
        !           381:     {
        !           382:         op = OBJPTR(obj);
        !           383:         if (op->o_pos.y == y && op->o_pos.x == x)
        !           384:                 return obj;
        !           385:     }
        !           386:     return NULL;
        !           387: }
        !           388:
        !           389: /*
        !           390:  * get coordinates from the player using the cursor keys (or mouse)
        !           391:  */
        !           392:
        !           393: coord
        !           394: get_coordinates(void)
        !           395: {
        !           396:     register int which;
        !           397:     coord c;
        !           398:
        !           399:     c = hero;
        !           400:     wmove(cw, hero.y, hero.x);
        !           401:     draw(cw);
        !           402:     for (;;) {
        !           403:         which = (wgetch(cw) & 0177);
        !           404:         switch(which) {
        !           405:             case ESC:
        !           406:                 c = hero;
        !           407:                 wmove(cw, c.y, c.x);
        !           408:                 draw(cw);
        !           409:             case '\n':
        !           410:             case '\r':
        !           411:                 return(c);
        !           412:             when 'h':
        !           413:             case 'H':
        !           414:                 c.x--;
        !           415:             when 'j':
        !           416:             case 'J':
        !           417:                 c.y++;
        !           418:             when 'k':
        !           419:             case 'K':
        !           420:                 c.y--;
        !           421:             when 'l':
        !           422:             case 'L':
        !           423:                 c.x++;
        !           424:             when 'y':
        !           425:             case 'Y':
        !           426:                 c.x--; c.y--;
        !           427:             when 'u':
        !           428:             case 'U':
        !           429:                 c.x++; c.y--;
        !           430:             when 'b':
        !           431:             case 'B':
        !           432:                 c.x--; c.y++;
        !           433:             when 'n':
        !           434:             case 'N':
        !           435:                 c.x++; c.y++;
        !           436:             when '*':
        !           437:                mpos = 0;
        !           438:                msg("Use h,j,k,l,y,u,b,n to position cursor, then press enter.");
        !           439:         }
        !           440:         c.y = max(c.y, 1);
        !           441:         c.y = min(c.y, lines - 3);
        !           442:         c.x = max(c.x, 0);
        !           443:         c.x = min(c.x, cols - 1);
        !           444:         wmove(cw, c.y, c.x);
        !           445:         draw(cw);
        !           446:     }
        !           447: }
        !           448:
        !           449: /*
        !           450:  * set up the direction co_ordinate for use in various "prefix" commands
        !           451:  */
        !           452:
        !           453: bool
        !           454: get_dir(coord *direction)
        !           455: {
        !           456:     register char *prompt;
        !           457:     register bool gotit;
        !           458:     int x,y;
        !           459:
        !           460:     prompt = terse ? "Direction?" :  "Which direction? ";
        !           461:     msg(prompt);
        !           462:     do
        !           463:     {
        !           464:         gotit = TRUE;
        !           465:         switch (wgetch(msgw))
        !           466:         {
        !           467:             case 'h': case'H': direction->y =  0; direction->x = -1;
        !           468:             when 'j': case'J': direction->y =  1; direction->x =  0;
        !           469:             when 'k': case'K': direction->y = -1; direction->x =  0;
        !           470:             when 'l': case'L': direction->y =  0; direction->x =  1;
        !           471:             when 'y': case'Y': direction->y = -1; direction->x = -1;
        !           472:             when 'u': case'U': direction->y = -1; direction->x =  1;
        !           473:             when 'b': case'B': direction->y =  1; direction->x = -1;
        !           474:             when 'n': case'N': direction->y =  1; direction->x =  1;
        !           475:             when ESC: return (FALSE);
        !           476:             otherwise:
        !           477:                 mpos = 0;
        !           478:                 msg(prompt);
        !           479:                 gotit = FALSE;
        !           480:         }
        !           481:     } until (gotit);
        !           482:     if ((on(player, ISHUH) || on(player, ISDANCE)) && rnd(100) > 20) {
        !           483:         do
        !           484:         {
        !           485:             *direction = grid[rnd(9)];
        !           486:         } while (direction->y == 0 && direction->x == 0);
        !           487:     }
        !           488:     else if (on(player, ISFLEE)) {
        !           489:             y = hero.y;
        !           490:             x = hero.x;
        !           491:             while (shoot_ok(winat(y, x))) {
        !           492:                 y += direction->y;
        !           493:                 x += direction->x;
        !           494:             }
        !           495:             if (isalpha(mvwinch(mw, y, x))) {
        !           496:                 if (y == player.t_dest->y && x == player.t_dest->x) {
        !           497:                     mpos = 0;
        !           498:                     msg("You are too frightened to!");
        !           499:                     return(FALSE);
        !           500:             }
        !           501:         }
        !           502:     }
        !           503:     mpos = 0;
        !           504:     return TRUE;
        !           505: }
        !           506:
        !           507:
        !           508: /*
        !           509:  * get_worth:
        !           510:  *      Calculate an objects worth in gold
        !           511:  */
        !           512:
        !           513: long
        !           514: get_worth(struct object *obj)
        !           515: {
        !           516:         reg long worth, wh;
        !           517:
        !           518:         worth = 0;
        !           519:         wh = obj->o_which;
        !           520:         switch (obj->o_type) {
        !           521:             case FOOD:
        !           522:                 worth = 2;
        !           523:             when WEAPON:
        !           524:                 if (wh < MAXWEAPONS) {
        !           525:                     worth = weaps[wh].w_worth;
        !           526:                     worth += s_magic[S_ALLENCH].mi_worth *
        !           527:                                  (obj->o_hplus + obj->o_dplus);
        !           528:                 }
        !           529:             when ARMOR:
        !           530:                 if (wh < MAXARMORS) {
        !           531:                     worth = armors[wh].a_worth;
        !           532:                     worth += s_magic[S_ALLENCH].mi_worth *
        !           533:                                 (armors[wh].a_class - obj->o_ac);
        !           534:                 }
        !           535:             when SCROLL:
        !           536:                 if (wh < MAXSCROLLS)
        !           537:                     worth = s_magic[wh].mi_worth;
        !           538:             when POTION:
        !           539:                 if (wh < MAXPOTIONS)
        !           540:                     worth = p_magic[wh].mi_worth;
        !           541:             when RING:
        !           542:                 if (wh < MAXRINGS) {
        !           543:                     worth = r_magic[wh].mi_worth;
        !           544:                     worth += obj->o_ac * 40;
        !           545:                 }
        !           546:             when STICK:
        !           547:                 if (wh < MAXSTICKS) {
        !           548:                     worth = ws_magic[wh].mi_worth;
        !           549:                     worth += 20 * obj->o_charges;
        !           550:                 }
        !           551:             when MM:
        !           552:                 if (wh < MAXMM) {
        !           553:                     worth = m_magic[wh].mi_worth;
        !           554:                     switch (wh) {
        !           555:                         case MM_BRACERS:        worth += 40  * obj->o_ac;
        !           556:                         when MM_PROTECT:        worth += 60  * obj->o_ac;
        !           557:                         when MM_DISP:           /* ac already figured in price*/
        !           558:                         otherwise:              worth += 20  * obj->o_ac;
        !           559:                     }
        !           560:                 }
        !           561:             when RELIC:
        !           562:                 if (wh < MAXRELIC) {
        !           563:                     worth = rel_magic[wh].mi_worth;
        !           564:                     if (wh == quest_item) worth *= 10;
        !           565:                 }
        !           566:             otherwise:
        !           567:                 worth = 0;
        !           568:         }
        !           569:         if (obj->o_flags & ISPROT)      /* 300% more for protected */
        !           570:             worth *= 3;
        !           571:         if (obj->o_flags &  ISBLESSED)  /* 50% more for blessed */
        !           572:             worth = worth * 3 / 2;
        !           573:         if (obj->o_flags & ISCURSED)    /* half for cursed */
        !           574:             worth /= 2;
        !           575:         if (worth < 0)
        !           576:             worth = 0;
        !           577:         return worth;
        !           578: }
        !           579:
        !           580: /*
        !           581:  *      invisible()
        !           582:  */
        !           583:
        !           584: bool
        !           585: invisible(struct thing *monst)
        !           586: {
        !           587:         register bool   ret_code;
        !           588:
        !           589:         ret_code  = on(*monst, CANSURPRISE);
        !           590:         ret_code &= !ISWEARING(R_ALERT);
        !           591:         ret_code |= (on(*monst, ISINVIS) ||
        !           592:                         (on(*monst, ISSHADOW) && rnd(100) < 90)) &&
        !           593:                         off(player, CANSEE);
        !           594:         return( ret_code );
        !           595: }
        !           596:
        !           597: /*
        !           598:  * see if the object is one of the currently used items
        !           599:  */
        !           600:
        !           601: bool
        !           602: is_current(struct object *obj)
        !           603: {
        !           604:     if (obj == NULL)
        !           605:         return FALSE;
        !           606:     if (obj == cur_armor         || obj == cur_weapon        ||
        !           607:         obj == cur_ring[LEFT_1]  || obj == cur_ring[LEFT_2]  ||
        !           608:         obj == cur_ring[LEFT_3]  || obj == cur_ring[LEFT_4]  ||
        !           609:         obj == cur_ring[RIGHT_1] || obj == cur_ring[RIGHT_2] ||
        !           610:     obj == cur_ring[RIGHT_3] || obj == cur_ring[RIGHT_4] ||
        !           611:         obj == cur_misc[WEAR_BOOTS]    || obj == cur_misc[WEAR_JEWEL] ||
        !           612:         obj == cur_misc[WEAR_BRACERS]  || obj == cur_misc[WEAR_CLOAK] ||
        !           613:         obj == cur_misc[WEAR_GAUNTLET] || obj == cur_misc[WEAR_NECKLACE]) {
        !           614:
        !           615:         return TRUE;
        !           616:     }
        !           617:
        !           618:     /* Is it a "current" relic? */
        !           619:     if (obj->o_type == RELIC) {
        !           620:         switch (obj->o_which) {
        !           621:             case MUSTY_DAGGER:
        !           622:             case EMORI_CLOAK:
        !           623:             case HEIL_ANKH:
        !           624:             case YENDOR_AMULET:
        !           625:             case STONEBONES_AMULET:
        !           626:             case HRUGGEK_MSTAR:
        !           627:             case AXE_AKLAD:
        !           628:             case YEENOGHU_FLAIL:
        !           629:             case SURTUR_RING:
        !           630:                 if (cur_relic[obj->o_which]) return TRUE;
        !           631:         }
        !           632:     }
        !           633:
        !           634:     return FALSE;
        !           635: }
        !           636:
        !           637:
        !           638: /*
        !           639:  * Look:
        !           640:  *      A quick glance all around the player
        !           641:  *     wakeup: Should we wake up monsters
        !           642:  *     runend: At end of a run -- for mazes
        !           643:  */
        !           644:
        !           645: void
        !           646: look(bool wakeup, bool runend)
        !           647: {
        !           648:     register int x, y, radius;
        !           649:     register unsigned char ch, och;
        !           650:     register int oldx, oldy;
        !           651:     register bool inpass, horiz, vert, do_light = FALSE, do_blank = FALSE;
        !           652:     register int passcount = 0, curfloorcount = 0, nextfloorcount = 0;
        !           653:     register struct room *rp;
        !           654:     register int ey, ex;
        !           655:
        !           656:     inpass = ((rp = roomin(&hero)) == NULL); /* Are we in a passage? */
        !           657:
        !           658:     /* Are we moving vertically or horizontally? */
        !           659:     if (runch == 'h' || runch == 'l') horiz = TRUE;
        !           660:     else horiz = FALSE;
        !           661:     if (runch == 'j' || runch == 'k') vert = TRUE;
        !           662:     else vert = FALSE;
        !           663:
        !           664:     /* How far around himself can the player see? */
        !           665:     if (levtype == OUTSIDE) {
        !           666:         if (daytime) radius = 9;
        !           667:         else if (lit_room(rp)) radius = 3;
        !           668:         else radius = 1;
        !           669:     }
        !           670:     else radius = 1;
        !           671:
        !           672:     getyx(cw, oldy, oldx);      /* Save current position */
        !           673:
        !           674:     /* Blank out the floor around our last position and check for
        !           675:      * moving out of a corridor in a maze.
        !           676:      */
        !           677:     if (levtype == OUTSIDE) do_blank = !daytime;
        !           678:     else if (oldrp != NULL && !lit_room(oldrp) && off(player, ISBLIND))
        !           679:             do_blank = TRUE;
        !           680:
        !           681:     /* Now move around the old position and blank things out */
        !           682:     ey = player.t_oldpos.y + radius;
        !           683:     ex = player.t_oldpos.x + radius;
        !           684:     for (x = player.t_oldpos.x - radius; x <= ex; x++)
        !           685:       if (x >= 0 && x < cols)
        !           686:         for (y = player.t_oldpos.y - radius; y <= ey; y++) {
        !           687:             struct linked_list *it;
        !           688:             coord here;         /* Current <x,y> coordinate */
        !           689:             unsigned char savech;        /* Saves character in monster window */
        !           690:             bool in_room;       /* Are we in a room? */
        !           691:
        !           692:             if (y < 1 || y > lines - 3) continue;
        !           693:
        !           694:             /* See what's there -- ignore monsters, just see what they're on */
        !           695:             savech = mvwinch(mw, y, x);
        !           696:             waddch(mw, ' ');
        !           697:             ch = show(y, x);
        !           698:             mvwaddch(mw, y, x, savech); /* Restore monster */
        !           699:
        !           700:             /*
        !           701:              * If we have a monster that we can't see anymore, make sure
        !           702:              * that we can note that fact.
        !           703:              */
        !           704:             if (isalpha(savech) &&
        !           705:                 (y < hero.y - radius || y > hero.y + radius ||
        !           706:                  x < hero.x - radius || x > hero.x + radius)) {
        !           707:                 /* Find the monster */
        !           708:                 it = find_mons(y, x);
        !           709:             }
        !           710:             else it = NULL;
        !           711:
        !           712:             /* Are we in a room? */
        !           713:             here.y = y;
        !           714:             here.x = x;
        !           715:             in_room = (roomin(&here) != NULL);
        !           716:
        !           717:             if ((do_blank || !in_room) && (y != hero.y || x != hero.x))
        !           718:                 switch (ch) {
        !           719:                     case DOOR:
        !           720:                     case SECRETDOOR:
        !           721:                     case PASSAGE:
        !           722:                     case STAIRS:
        !           723:                     case TRAPDOOR:
        !           724:                     case TELTRAP:
        !           725:                     case BEARTRAP:
        !           726:                     case SLEEPTRAP:
        !           727:                     case ARROWTRAP:
        !           728:                     case DARTTRAP:
        !           729:                     case WORMHOLE:
        !           730:                     case MAZETRAP:
        !           731:                     case POOL:
        !           732:                     case POST:
        !           733:                     case VERTWALL:
        !           734:                     case HORZWALL:
        !           735:                     case WALL:
        !           736:                         /* If there was a monster showing, make it disappear */
        !           737:                         if (isalpha(savech)) {
        !           738:                             mvwaddch(cw, y, x, ch);
        !           739:
        !           740:                             /*
        !           741:                              * If we found it (we should!), set it to
        !           742:                              * the right character!
        !           743:                              */
        !           744:                             if (it) (THINGPTR(it))->t_oldch = ch;
        !           745:                         }
        !           746:                         break;
        !           747:                     when FLOOR:
        !           748:                     case FOREST:
        !           749:                     default:
        !           750:                         mvwaddch(cw, y, x, in_room ? ' ' : PASSAGE);
        !           751:
        !           752:                         /* If we found a monster, set it to darkness! */
        !           753:                         if (it) (THINGPTR(it))->t_oldch = mvwinch(cw, y, x);
        !           754:                 }
        !           755:
        !           756:             /* Moving out of a corridor? */
        !           757:             if (levtype == MAZELEV && !ce(hero, player.t_oldpos) &&
        !           758:                 !running && !isrock(ch) &&  /* Not running and not a wall */
        !           759:                 ((vert && x != player.t_oldpos.x && y==player.t_oldpos.y) ||
        !           760:                  (horiz && y != player.t_oldpos.y && x==player.t_oldpos.x)))
        !           761:                     do_light = off(player, ISBLIND);
        !           762:         }
        !           763:
        !           764:     /* Take care of unlighting a corridor */
        !           765:     if (do_light && lit_room(rp)) light(&player.t_oldpos);
        !           766:
        !           767:     /* Are we coming or going between a wall and a corridor in a maze? */
        !           768:     och = show(player.t_oldpos.y, player.t_oldpos.x);
        !           769:     ch = show(hero.y, hero.x);
        !           770:     if (levtype == MAZELEV &&
        !           771:         ((isrock(och) && !isrock(ch)) || (isrock(ch) && !isrock(och)))) {
        !           772:         do_light = off(player, ISBLIND); /* Light it up if not blind */
        !           773:
        !           774:         /* Unlight what we just saw */
        !           775:         if (do_light && lit_room(&rooms[0])) light(&player.t_oldpos);
        !           776:     }
        !           777:
        !           778:     /* Look around the player */
        !           779:     ey = hero.y + radius;
        !           780:     ex = hero.x + radius;
        !           781:     for (x = hero.x - radius; x <= ex; x++)
        !           782:         if (x >= 0 && x < cols) for (y = hero.y - radius; y <= ey; y++) {
        !           783:             if (y < 1 || y >= lines - 2)
        !           784:                 continue;
        !           785:             if (isalpha(mvwinch(mw, y, x)))
        !           786:             {
        !           787:                 register struct linked_list *it;
        !           788:                 register struct thing *tp;
        !           789:
        !           790:                 if (wakeup)
        !           791:                     it = wake_monster(y, x);
        !           792:                 else
        !           793:                     it = find_mons(y, x);
        !           794:
        !           795:                 if (it) {
        !           796:                     tp = THINGPTR(it);
        !           797:                     tp->t_oldch = mvinch(y, x);
        !           798:                     if (isatrap(tp->t_oldch)) {
        !           799:                         register struct trap *trp = trap_at(y, x);
        !           800:
        !           801:                         tp->t_oldch = (trp->tr_flags & ISFOUND) ? tp->t_oldch
        !           802:                                                                 : trp->tr_show;
        !           803:                     }
        !           804:                     if (tp->t_oldch == FLOOR && !lit_room(rp) &&
        !           805:                         off(player, ISBLIND))
        !           806:                             tp->t_oldch = ' ';
        !           807:                 }
        !           808:             }
        !           809:
        !           810:             /*
        !           811:              * Secret doors show as walls
        !           812:              */
        !           813:             if ((ch = show(y, x)) == SECRETDOOR)
        !           814:                 ch = secretdoor(y, x);
        !           815:             /*
        !           816:              * Don't show room walls if he is in a passage and
        !           817:              * check for maze turns
        !           818:              */
        !           819:             if (off(player, ISBLIND))
        !           820:             {
        !           821:                 if (y == hero.y && x == hero.x
        !           822:                     || (inpass && (ch == HORZWALL || ch == VERTWALL)))
        !           823:                         continue;
        !           824:
        !           825:                 /* Did we come to a crossroads in a maze? */
        !           826:                 if (levtype == MAZELEV &&
        !           827:                     (runend || !ce(hero, player.t_oldpos)) &&
        !           828:                     !isrock(ch) &&      /* Not a wall */
        !           829:                     ((vert && x != hero.x && y == hero.y) ||
        !           830:                      (horiz && y != hero.y && x == hero.x)))
        !           831:                         /* Just came to a turn */
        !           832:                         do_light = off(player, ISBLIND);
        !           833:             }
        !           834:             else if (y != hero.y || x != hero.x)
        !           835:                 continue;
        !           836:
        !           837:             wmove(cw, y, x);
        !           838:             waddch(cw, ch);
        !           839:             if (door_stop && !firstmove && running)
        !           840:             {
        !           841:                 switch (runch)
        !           842:                 {
        !           843:                     case 'h':
        !           844:                         if (x == hero.x + 1)
        !           845:                             continue;
        !           846:                     when 'j':
        !           847:                         if (y == hero.y - 1)
        !           848:                             continue;
        !           849:                     when 'k':
        !           850:                         if (y == hero.y + 1)
        !           851:                             continue;
        !           852:                     when 'l':
        !           853:                         if (x == hero.x - 1)
        !           854:                             continue;
        !           855:                     when 'y':
        !           856:                         if ((x + y) - (hero.x + hero.y) >= 1)
        !           857:                             continue;
        !           858:                     when 'u':
        !           859:                         if ((y - x) - (hero.y - hero.x) >= 1)
        !           860:                             continue;
        !           861:                     when 'n':
        !           862:                         if ((x + y) - (hero.x + hero.y) <= -1)
        !           863:                             continue;
        !           864:                     when 'b':
        !           865:                         if ((y - x) - (hero.y - hero.x) <= -1)
        !           866:                             continue;
        !           867:                 }
        !           868:                 switch (ch)
        !           869:                 {
        !           870:                     case DOOR:
        !           871:                         if (x == hero.x || y == hero.y)
        !           872:                             running = FALSE;
        !           873:                         break;
        !           874:                     case PASSAGE:
        !           875:                         if (x == hero.x || y == hero.y)
        !           876:                             passcount++;
        !           877:                         break;
        !           878:                     case FLOOR:
        !           879:                         /* Stop by new passages in a maze (floor next to us) */
        !           880:                         if ((levtype == MAZELEV) &&
        !           881:                             !(hero.y == y && hero.x == x)) {
        !           882:                             if (vert) { /* Moving vertically */
        !           883:                                 /* We have a passage on our row */
        !           884:                                 if (y == hero.y) curfloorcount++;
        !           885:
        !           886:                                 /* Some passage on the next row */
        !           887:                                 else if (y != player.t_oldpos.y)
        !           888:                                     nextfloorcount++;
        !           889:                             }
        !           890:                             else {      /* Moving horizontally */
        !           891:                                 /* We have a passage on our column */
        !           892:                                 if (x == hero.x) curfloorcount++;
        !           893:
        !           894:                                 /* Some passage in the next column */
        !           895:                                 else if (x != player.t_oldpos.x)
        !           896:                                     nextfloorcount++;
        !           897:                             }
        !           898:                         }
        !           899:                     case VERTWALL:
        !           900:                     case HORZWALL:
        !           901:                     case ' ':
        !           902:                         break;
        !           903:                     default:
        !           904:                         running = FALSE;
        !           905:                         break;
        !           906:                 }
        !           907:             }
        !           908:         }
        !           909:
        !           910:     /* Have we passed a side passage, with multiple choices? */
        !           911:     if (curfloorcount > 0 && nextfloorcount > 0) running = FALSE;
        !           912:
        !           913:     else if (door_stop && !firstmove && passcount > 1)
        !           914:         running = FALSE;
        !           915:
        !           916:     /* Do we have to light up the area (just stepped into a new corridor)? */
        !           917:     if (do_light && !running && lit_room(rp)) light(&hero);
        !           918:
        !           919:     mvwaddch(cw, hero.y, hero.x, PLAYER);
        !           920:     wmove(cw, oldy, oldx);
        !           921:     if (!ce(player.t_oldpos, hero)) {
        !           922:         player.t_oldpos = hero; /* Don't change if we didn't move */
        !           923:         oldrp = rp;
        !           924:     }
        !           925: }
        !           926:
        !           927: /*
        !           928:  * Lower a level of experience
        !           929:  */
        !           930:
        !           931: void
        !           932: lower_level(short who)
        !           933: {
        !           934:     int fewer, nsides;
        !           935:        unsigned long exp;
        !           936:
        !           937:     msg("You suddenly feel less skillful.");
        !           938:     if (--pstats.s_lvl == 0) {
        !           939:     pstats.s_hpt = -1;
        !           940:         death(who);             /* All levels gone */
        !           941:     }
        !           942:     if (pstats.s_lvladj > 0) { /* lose artificial levels first */
        !           943:         pstats.s_lvladj--;
        !           944:         return;
        !           945:     }
        !           946:     exp = char_class[player.t_ctype].cap;
        !           947:     if (pstats.s_exp >= exp*2)
        !           948:         pstats.s_exp -= exp;
        !           949:     else
        !           950:         pstats.s_exp /= 2;
        !           951:
        !           952:     nsides = char_class[player.t_ctype].hit_pts;
        !           953:     fewer = max(1, roll(1,nsides) + const_bonus());
        !           954:     pstats.s_hpt -= fewer;
        !           955:     max_stats.s_hpt -= fewer;
        !           956:     if (max_stats.s_hpt <= 0)
        !           957:     max_stats.s_hpt = 0;
        !           958:     if (pstats.s_hpt <= 0) {
        !           959:         pstats.s_hpt = -1;
        !           960:         death(who);
        !           961:     }
        !           962: }
        !           963:
        !           964: /*
        !           965:  * print out the name of a monster
        !           966:  */
        !           967:
        !           968: char *
        !           969: monster_name(struct thing *tp)
        !           970: {
        !           971:     prbuf[0] = '\0';
        !           972:     if (on(*tp, ISFLEE) || on(*tp, WASTURNED))
        !           973:         strcat(prbuf, "terrified ");
        !           974:     if (on(*tp, ISHUH))
        !           975:         strcat(prbuf, "confused ");
        !           976:     if (on(*tp, ISCHARMED))
        !           977:         strcat(prbuf, "charmed ");
        !           978:     else if (on(*tp, ISFLY))
        !           979:         strcat(prbuf, "flying ");
        !           980:
        !           981:     /* If it is sleeping or stoned, write over any of the above attributes */
        !           982:     if (off(*tp, ISRUN))
        !           983:         strcpy(prbuf, "sleeping ");
        !           984:     if (on(*tp, ISSTONE))
        !           985:         strcpy(prbuf, "petrified ");
        !           986:
        !           987:     if (tp->t_name) strcat(prbuf, tp->t_name);
        !           988:     else strcat(prbuf, monsters[tp->t_index].m_name);
        !           989:
        !           990:     return(prbuf);
        !           991: }
        !           992:
        !           993: /*
        !           994:  * move_hero:
        !           995:  *      Try to move the hero somplace besides next to where he is.  We ask him
        !           996:  *      where.  There can be restrictions based on why he is moving.
        !           997:  */
        !           998:
        !           999: bool
        !          1000: move_hero(int why)
        !          1001: {
        !          1002:     char *action = NULL;
        !          1003:     unsigned char which;
        !          1004:     coord c;
        !          1005:
        !          1006:     switch (why) {
        !          1007:         case H_TELEPORT:
        !          1008:             action = "teleport";
        !          1009:     }
        !          1010:
        !          1011:     msg("Where do you wish to %s to? (* for help) ", action);
        !          1012:     c = get_coordinates();
        !          1013:     mpos = 0;
        !          1014:     which = winat(c.y, c.x);
        !          1015:     switch (which) {
        !          1016:         default:
        !          1017:             if (!isrock(which) || off(player, CANINWALL)) break;
        !          1018:
        !          1019:         case FLOOR:
        !          1020:         case PASSAGE:
        !          1021:         case DOOR:
        !          1022:         case STAIRS:
        !          1023:         case POST:
        !          1024:         case GOLD:
        !          1025:         case POTION:
        !          1026:         case SCROLL:
        !          1027:         case FOOD:
        !          1028:         case WEAPON:
        !          1029:         case ARMOR:
        !          1030:         case RING:
        !          1031:         case MM:
        !          1032:         case RELIC:
        !          1033:         case STICK:
        !          1034:             hero = c;
        !          1035:             return(TRUE);
        !          1036:     }
        !          1037:     return(FALSE);
        !          1038: }
        !          1039:
        !          1040: /*
        !          1041:  * raise_level:
        !          1042:  *      The guy just magically went up a level.
        !          1043:  */
        !          1044:
        !          1045: void
        !          1046: raise_level(void)
        !          1047: {
        !          1048:     unsigned long test;  /* Next level -- be sure it is not an overflow */
        !          1049:
        !          1050:     test = check_level();       /* Get next boundary */
        !          1051:
        !          1052:     /* Be sure it is higher than what we have no -- else overflow */
        !          1053:     if (test > pstats.s_exp) pstats.s_exp = test;
        !          1054:     check_level();
        !          1055:
        !          1056:     /* Give him a bonus */
        !          1057:     switch (player.t_ctype) {
        !          1058:         case C_FIGHTER:
        !          1059:             (*add_abil[A_STRENGTH])(1);
        !          1060:         when C_RANGER:
        !          1061:         case C_PALADIN:
        !          1062:             (*add_abil[A_CHARISMA])(1);
        !          1063:         when C_MAGICIAN:
        !          1064:             (*add_abil[A_INTELLIGENCE])(1);
        !          1065:         when C_CLERIC:
        !          1066:         case C_DRUID:
        !          1067:             (*add_abil[A_WISDOM])(1);
        !          1068:         when C_THIEF:
        !          1069:         case C_ASSASSIN:
        !          1070:             (*add_abil[A_DEXTERITY])(1);
        !          1071:         when C_MONK:
        !          1072:             (*add_abil[A_CONSTITUTION])(1);
        !          1073:     }
        !          1074: }
        !          1075:
        !          1076: /*
        !          1077:  * saving throw matrix for character saving throws
        !          1078:  * this table is indexed by char type and saving throw type
        !          1079:  */
        !          1080:
        !          1081: static const char st_matrix[NUM_CHARTYPES][5] = {
        !          1082: /* Poison,      Petrify,        wand,           Breath,         Magic */
        !          1083: { 13,           14,             15,             16,             17 },
        !          1084: { 13,           14,             15,             16,             17 },
        !          1085: { 13,           14,             15,             16,             17 },
        !          1086: { 11,           12,             13,             14,             15 },
        !          1087: { 11,           12,             13,             14,             15 },
        !          1088: { 12,           13,             14,             15,             16 },
        !          1089: { 12,           13,             14,             15,             16 },
        !          1090: { 11,           12,             12,             14,             15 },
        !          1091: { 12,           13,             14,             15,             16 },
        !          1092: { 13,           14,             15,             16,             17 }
        !          1093: };
        !          1094:
        !          1095: /*
        !          1096:  * save:
        !          1097:  *      See if a creature saves against something
        !          1098:  * which: which type of save
        !          1099:  * who: who is saving
        !          1100:  * adj: saving throw adjustment
        !          1101:  */
        !          1102:
        !          1103: bool
        !          1104: save(int which, struct thing *who, int adj)
        !          1105: {
        !          1106:     register int need, level, protect;
        !          1107:
        !          1108:     protect = 0;
        !          1109:     level = who->t_stats.s_lvl;
        !          1110:     need = st_matrix[who->t_ctype][which];
        !          1111:     switch (who->t_ctype) {
        !          1112:     case C_FIGHTER:
        !          1113:     case C_RANGER:
        !          1114:     case C_PALADIN:
        !          1115:         need -= (2 * (level-1) / 5) - 1;        /* for level 61; -= 25 */
        !          1116:     when C_THIEF:
        !          1117:     case C_ASSASSIN:
        !          1118:     case C_MONK:
        !          1119:     case C_MONSTER:
        !          1120:         need -= (2 * (level-1) / 5) - 3;        /* for level 61; -= 27 */
        !          1121:     when C_MAGICIAN:
        !          1122:     case C_CLERIC:
        !          1123:     case C_DRUID:
        !          1124:         need -= (2 * (level-1) / 5) - 5;        /* for level 61; -= 29 */
        !          1125:     }
        !          1126:     /*
        !          1127:      * add in pluses against poison for execeptional constitution
        !          1128:      */
        !          1129:     if (which == VS_POISON && who->t_stats.s_const > 18)
        !          1130:         need -= (who->t_stats.s_const - 17) / 2;
        !          1131:     if (who == &player) {
        !          1132:         /*
        !          1133:          * does the player have a ring of protection on?
        !          1134:          */
        !          1135:         protect +=  ring_value(R_PROTECT);
        !          1136:         /*
        !          1137:          * does the player have a cloak of protection on?
        !          1138:          */
        !          1139:         if (cur_misc[WEAR_CLOAK])
        !          1140:             protect += cur_misc[WEAR_CLOAK]->o_ac;
        !          1141:
        !          1142:         protect = min(protect, 10);/* limit protection to +10 */
        !          1143:         need -= protect;
        !          1144:     }
        !          1145:     need -= adj;
        !          1146:     /*
        !          1147:      * always miss or save on a 1 (except for UNIQUEs
        !          1148:      */
        !          1149:     if (who == &player || off(*who, ISUNIQUE))
        !          1150:         need = max(need, 2);
        !          1151:     need = min(20, need); /* always make our save on a 20 */
        !          1152:     debug("need a %d to save", need);
        !          1153:     return (roll(1, 20) >= need);
        !          1154: }
        !          1155:
        !          1156: /*
        !          1157:  * secret_door:
        !          1158:  *      Figure out what a secret door looks like.
        !          1159:  */
        !          1160:
        !          1161: char
        !          1162: secretdoor(int y, int x)
        !          1163: {
        !          1164:     register int i;
        !          1165:     register struct room *rp;
        !          1166:     register coord *cpp;
        !          1167:     static coord cp;
        !          1168:
        !          1169:     cp.y = y;
        !          1170:     cp.x = x;
        !          1171:     cpp = &cp;
        !          1172:     for (rp = rooms, i = 0; i < MAXROOMS; rp++, i++)
        !          1173:         if (inroom(rp, cpp))
        !          1174:             if (y == rp->r_pos.y || y == rp->r_pos.y + rp->r_max.y - 1)
        !          1175:                 return(HORZWALL);
        !          1176:             else
        !          1177:                 return(VERTWALL);
        !          1178:
        !          1179:     return('p');
        !          1180: }
        !          1181:
        !          1182: /*
        !          1183:  * this routine computes the players current strength
        !          1184:  */
        !          1185:
        !          1186: int
        !          1187: str_compute(void)
        !          1188: {
        !          1189:     if (cur_misc[WEAR_GAUNTLET] != NULL         &&
        !          1190:         cur_misc[WEAR_GAUNTLET]->o_which == MM_G_OGRE) {
        !          1191:         if (cur_misc[WEAR_GAUNTLET]->o_flags & ISCURSED)
        !          1192:             return (3);
        !          1193:         else
        !          1194:             return (21);
        !          1195:     }
        !          1196:     else
        !          1197:             return (pstats.s_str);
        !          1198: }
        !          1199:
        !          1200: /*
        !          1201:  * copy string using unctrl for things
        !          1202:  */
        !          1203:
        !          1204: void
        !          1205: strucpy(char *s1, char *s2, int len)
        !          1206: {
        !          1207:     const char *sp;
        !          1208:     while (len--)
        !          1209:     {
        !          1210:         strcpy(s1, (sp = unctrl(*s2)));
        !          1211:         s1 += strlen(sp);
        !          1212:         s2++;
        !          1213:     }
        !          1214:     *s1 = '\0';
        !          1215: }
        !          1216:
        !          1217: /*
        !          1218:  * tr_name:
        !          1219:  *      print the name of a trap
        !          1220:  */
        !          1221:
        !          1222: char *
        !          1223: tr_name(char ch)
        !          1224: {
        !          1225:     register char *s = NULL;
        !          1226:
        !          1227:     switch (ch)
        !          1228:     {
        !          1229:         case TRAPDOOR:
        !          1230:             s = terse ? "A trapdoor." : "You found a trapdoor.";
        !          1231:         when BEARTRAP:
        !          1232:             s = terse ? "A beartrap." : "You found a beartrap.";
        !          1233:         when SLEEPTRAP:
        !          1234:             s = terse ? "A sleeping gas trap.":"You found a sleeping gas trap.";
        !          1235:         when ARROWTRAP:
        !          1236:             s = terse ? "An arrow trap." : "You found an arrow trap.";
        !          1237:         when TELTRAP:
        !          1238:             s = terse ? "A teleport trap." : "You found a teleport trap.";
        !          1239:         when DARTTRAP:
        !          1240:             s = terse ? "A dart trap." : "You found a poison dart trap.";
        !          1241:         when POOL:
        !          1242:             s = terse ? "A shimmering pool." : "You found a shimmering pool";
        !          1243:         when MAZETRAP:
        !          1244:             s = terse ? "A maze entrance." : "You found a maze entrance";
        !          1245:         when WORMHOLE:
        !          1246:             s = terse ? "A worm hole." : "You found a worm hole entrance";
        !          1247:     }
        !          1248:     return s;
        !          1249: }
        !          1250:
        !          1251: /*
        !          1252:  * for printfs: if string starts with a vowel, return "n" for an "an"
        !          1253:  */
        !          1254:
        !          1255: char *
        !          1256: vowelstr(char *str)
        !          1257: {
        !          1258:     switch (*str)
        !          1259:     {
        !          1260:         case 'a':
        !          1261:         case 'e':
        !          1262:         case 'i':
        !          1263:         case 'o':
        !          1264:         case 'u':
        !          1265:             return "n";
        !          1266:         default:
        !          1267:             return "";
        !          1268:     }
        !          1269: }
        !          1270:
        !          1271: /*
        !          1272:  * wake up a room full (hopefully) of creatures
        !          1273:  */
        !          1274:
        !          1275: void
        !          1276: wake_room(struct room *rp)
        !          1277: {
        !          1278:         register struct linked_list *item;
        !          1279:         register struct thing *tp;
        !          1280:
        !          1281:         for (item=mlist; item!=NULL; item=next(item)) {
        !          1282:             tp = THINGPTR(item);
        !          1283:             if (off(*tp,ISRUN) && on(*tp,ISMEAN) && roomin(&tp->t_pos) == rp)
        !          1284:                 runto(tp, &hero);
        !          1285:         }
        !          1286: }
        !          1287:
        !          1288:
        !          1289: /*
        !          1290:  * waste_time:
        !          1291:  *      Do nothing but let other things happen
        !          1292:  */
        !          1293:
        !          1294: void
        !          1295: waste_time(void)
        !          1296: {
        !          1297:     if (inwhgt)                 /* if from wghtchk then done */
        !          1298:         return;
        !          1299:     do_daemons(BEFORE);
        !          1300:     do_fuses(BEFORE);
        !          1301:     do_daemons(AFTER);
        !          1302:     do_fuses(AFTER);
        !          1303: }
        !          1304:

CVSweb