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

Annotation of early-roguelike/rogue5/misc.c, Revision 1.1.1.1

1.1       rubenllo    1: /*
                      2:  * All sorts of miscellaneous routines
                      3:  *
                      4:  * @(#)misc.c  4.66 (Berkeley) 08/06/83
                      5:  *
                      6:  * Rogue: Exploring the Dungeons of Doom
                      7:  * Copyright (C) 1980-1983, 1985, 1999 Michael Toy, Ken Arnold and Glenn Wichman
                      8:  * All rights reserved.
                      9:  *
                     10:  * See the file LICENSE.TXT for full copyright and licensing information.
                     11:  */
                     12:
                     13: #include <stdlib.h>
                     14: #include <curses.h>
                     15: #include <string.h>
                     16: #include <ctype.h>
                     17: #include "rogue.h"
                     18:
                     19: /*
                     20:  * look:
                     21:  *     A quick glance all around the player
                     22:  */
                     23: #undef DEBUG
                     24:
                     25:
                     26: void
                     27: look(int wakeup)
                     28: {
                     29:     int x, y;
                     30:     chtype ch;
                     31:     THING *tp;
                     32:     PLACE *pp;
                     33:     struct room *rp;
                     34:     int ey, ex;
                     35:     int passcount;
                     36:     int pfl, *fp, pch;
                     37:     int sy, sx, sumhero = 0, diffhero = 0;
                     38: # ifdef DEBUG
                     39:     static int done = FALSE;
                     40:
                     41:     if (done)
                     42:        return;
                     43:     done = TRUE;
                     44: # endif /* DEBUG */
                     45:     passcount = 0;
                     46:     rp = proom;
                     47:     if (!ce(oldpos, hero))
                     48:     {
                     49:        erase_lamp(&oldpos, oldrp);
                     50:        oldpos = hero;
                     51:        oldrp = rp;
                     52:     }
                     53:     ey = hero.y + 1;
                     54:     ex = hero.x + 1;
                     55:     sx = hero.x - 1;
                     56:     sy = hero.y - 1;
                     57:     if (door_stop && !firstmove && running)
                     58:     {
                     59:        sumhero = hero.y + hero.x;
                     60:        diffhero = hero.y - hero.x;
                     61:     }
                     62:     pp = INDEX(hero.y, hero.x);
                     63:     pch = pp->p_ch;
                     64:     pfl = pp->p_flags;
                     65:
                     66:     for (y = sy; y <= ey; y++)
                     67:        if (y > 0 && y < NUMLINES - 1) for (x = sx; x <= ex; x++)
                     68:        {
                     69:            if (x < 0 || x >= NUMCOLS)
                     70:                continue;
                     71:            if (!on(player, ISBLIND))
                     72:            {
                     73:                if (y == hero.y && x == hero.x)
                     74:                    continue;
                     75:            }
                     76:
                     77:            pp = INDEX(y, x);
                     78:            ch = pp->p_ch;
                     79:            if (ch == ' ')              /* nothing need be done with a ' ' */
                     80:                    continue;
                     81:            fp = &pp->p_flags;
                     82:            if (pch != DOOR && ch != DOOR)
                     83:                if ((pfl & F_PASS) != (*fp & F_PASS))
                     84:                    continue;
                     85:            if (((*fp & F_PASS) || ch == DOOR) &&
                     86:                 ((pfl & F_PASS) || pch == DOOR))
                     87:            {
                     88:                if (hero.x != x && hero.y != y &&
                     89:                    !step_ok(chat(y, hero.x)) && !step_ok(chat(hero.y, x)))
                     90:                        continue;
                     91:            }
                     92:
                     93:            if ((tp = pp->p_monst) == NULL)
                     94:                ch = trip_ch(y, x, ch);
                     95:            else
                     96:                if (on(player, SEEMONST) && on(*tp, ISINVIS))
                     97:                {
                     98:                    if (door_stop && !firstmove)
                     99:                        running = FALSE;
                    100:                    continue;
                    101:                }
                    102:                else
                    103:                {
                    104:                    if (wakeup)
                    105:                        wake_monster(y, x);
                    106:                    if (see_monst(tp))
                    107:                    {
                    108:                        if (on(player, ISHALU))
                    109:                            ch = rnd(26) + 'A';
                    110:                        else
                    111:                            ch = tp->t_disguise;
                    112:                    }
                    113:                }
                    114:            if (on(player, ISBLIND) && (y != hero.y || x != hero.x))
                    115:                continue;
                    116:
                    117:            move(y, x);
                    118:
                    119:            if ((proom->r_flags & ISDARK) && !see_floor && ch == FLOOR)
                    120:                ch = ' ';
                    121:
                    122:            if (tp != NULL || ch != CCHAR( inch() ))
                    123:                addch(ch);
                    124:
                    125:            if (door_stop && !firstmove && running)
                    126:            {
                    127:                switch (runch)
                    128:                {
                    129:                    case 'h':
                    130:                        if (x == ex)
                    131:                            continue;
                    132:                    when 'j':
                    133:                        if (y == sy)
                    134:                            continue;
                    135:                    when 'k':
                    136:                        if (y == ey)
                    137:                            continue;
                    138:                    when 'l':
                    139:                        if (x == sx)
                    140:                            continue;
                    141:                    when 'y':
                    142:                        if ((y + x) - sumhero >= 1)
                    143:                            continue;
                    144:                    when 'u':
                    145:                        if ((y - x) - diffhero >= 1)
                    146:                            continue;
                    147:                    when 'n':
                    148:                        if ((y + x) - sumhero <= -1)
                    149:                            continue;
                    150:                    when 'b':
                    151:                        if ((y - x) - diffhero <= -1)
                    152:                            continue;
                    153:                }
                    154:                switch (ch)
                    155:                {
                    156:                    case DOOR:
                    157:                        if (x == hero.x || y == hero.y)
                    158:                            running = FALSE;
                    159:                        break;
                    160:                    case PASSAGE:
                    161:                        if (x == hero.x || y == hero.y)
                    162:                            passcount++;
                    163:                        break;
                    164:                    case FLOOR:
                    165:                    case '|':
                    166:                    case '-':
                    167:                    case ' ':
                    168:                        break;
                    169:                    default:
                    170:                        running = FALSE;
                    171:                        break;
                    172:                }
                    173:            }
                    174:        }
                    175:     if (door_stop && !firstmove && passcount > 1)
                    176:        running = FALSE;
                    177:     if (!running || !jump)
                    178:        mvaddch(hero.y, hero.x, PLAYER);
                    179: # ifdef DEBUG
                    180:     done = FALSE;
                    181: # endif /* DEBUG */
                    182: }
                    183:
                    184: /*
                    185:  * trip_ch:
                    186:  *     Return the character appropriate for this space, taking into
                    187:  *     account whether or not the player is tripping.
                    188:  */
                    189: int
                    190: trip_ch(int y, int x, int ch)
                    191: {
                    192:     if (on(player, ISHALU) && after)
                    193:        switch (ch)
                    194:        {
                    195:            case FLOOR:
                    196:            case ' ':
                    197:            case PASSAGE:
                    198:            case '-':
                    199:            case '|':
                    200:            case DOOR:
                    201:            case TRAP:
                    202:                break;
                    203:            default:
                    204:                if (y != stairs.y || x != stairs.x || !seenstairs)
                    205:                    ch = rnd_thing();
                    206:                break;
                    207:        }
                    208:     return ch;
                    209: }
                    210:
                    211: /*
                    212:  * erase_lamp:
                    213:  *     Erase the area shown by a lamp in a dark room.
                    214:  */
                    215:
                    216: void
                    217: erase_lamp(const coord *pos, const struct room *rp)
                    218: {
                    219:     int y, x, ey, sy, ex;
                    220:
                    221:     if (!(see_floor && (rp->r_flags & (ISGONE|ISDARK)) == ISDARK
                    222:        && !on(player,ISBLIND)))
                    223:            return;
                    224:
                    225:     ey = pos->y + 1;
                    226:     ex = pos->x + 1;
                    227:     sy = pos->y - 1;
                    228:     for (x = pos->x - 1; x <= ex; x++)
                    229:        for (y = sy; y <= ey; y++)
                    230:        {
                    231:            if (y == hero.y && x == hero.x)
                    232:                continue;
                    233:            move(y, x);
                    234:            if (CCHAR( inch() ) == FLOOR)
                    235:                addch(' ');
                    236:        }
                    237: }
                    238:
                    239: /*
                    240:  * show_floor:
                    241:  *     Should we show the floor in her room at this time?
                    242:  */
                    243: int
                    244: show_floor(void)
                    245: {
                    246:     if ((proom->r_flags & (ISGONE|ISDARK)) == ISDARK && !on(player, ISBLIND))
                    247:        return see_floor;
                    248:     else
                    249:        return TRUE;
                    250: }
                    251:
                    252: /*
                    253:  * find_obj:
                    254:  *     Find the unclaimed object at y, x
                    255:  */
                    256: THING *
                    257: find_obj(int y, int x)
                    258: {
                    259:     THING *obj;
                    260:
                    261:     for (obj = lvl_obj; obj != NULL; obj = next(obj))
                    262:     {
                    263:        if (obj->o_pos.y == y && obj->o_pos.x == x)
                    264:                return obj;
                    265:     }
                    266: #ifdef MASTER
                    267:     sprintf(prbuf, "Non-object %d,%d", y, x);
                    268:     msg(prbuf);
                    269:     return NULL;
                    270: #else
                    271:     /* NOTREACHED */
                    272:     return NULL;
                    273: #endif
                    274: }
                    275:
                    276: /*
                    277:  * eat:
                    278:  *     She wants to eat something, so let her try
                    279:  */
                    280:
                    281: void
                    282: eat(void)
                    283: {
                    284:     THING *obj;
                    285:
                    286:     if ((obj = get_item("eat", FOOD)) == NULL)
                    287:        return;
                    288:     if (obj->o_type != FOOD)
                    289:     {
                    290:        if (!terse)
                    291:            msg("ugh, you would get ill if you ate that");
                    292:        else
                    293:            msg("that's Inedible!");
                    294:        return;
                    295:     }
                    296:     if (food_left < 0)
                    297:        food_left = 0;
                    298:     if ((food_left += HUNGERTIME - 200 + rnd(400)) > STOMACHSIZE)
                    299:        food_left = STOMACHSIZE;
                    300:     hungry_state = 0;
                    301:     if (obj == cur_weapon)
                    302:        cur_weapon = NULL;
                    303:     if (obj->o_which == 1)
                    304:        msg("my, that was a yummy %s", fruit);
                    305:     else
                    306:        if (rnd(100) > 70)
                    307:        {
                    308:            pstats.s_exp++;
                    309:            msg("%s, this food tastes awful", choose_str("bummer", "yuk"));
                    310:            check_level();
                    311:        }
                    312:        else
                    313:            msg("%s, that tasted good", choose_str("oh, wow", "yum"));
                    314:     leave_pack(obj, FALSE, FALSE);
                    315: }
                    316:
                    317: /*
                    318:  * check_level:
                    319:  *     Check to see if the guy has gone up a level.
                    320:  */
                    321:
                    322: void
                    323: check_level(void)
                    324: {
                    325:     int i, add, olevel;
                    326:
                    327:     for (i = 0; e_levels[i] != 0; i++)
                    328:        if (e_levels[i] > pstats.s_exp)
                    329:            break;
                    330:     i++;
                    331:     olevel = pstats.s_lvl;
                    332:     pstats.s_lvl = i;
                    333:     if (i > olevel)
                    334:     {
                    335:        add = roll(i - olevel, 10);
                    336:        max_hp += add;
                    337:        pstats.s_hpt += add;
                    338:        msg("welcome to level %d", i);
                    339:     }
                    340: }
                    341:
                    342: /*
                    343:  * chg_str:
                    344:  *     used to modify the playes strength.  It keeps track of the
                    345:  *     highest it has been, just in case
                    346:  */
                    347:
                    348: void
                    349: chg_str(int amt)
                    350: {
                    351:     int comp;
                    352:
                    353:     if (amt == 0)
                    354:        return;
                    355:     add_str(&pstats.s_str, amt);
                    356:     comp = pstats.s_str;
                    357:     if (ISRING(LEFT, R_ADDSTR))
                    358:        add_str(&comp, -cur_ring[LEFT]->o_arm);
                    359:     if (ISRING(RIGHT, R_ADDSTR))
                    360:        add_str(&comp, -cur_ring[RIGHT]->o_arm);
                    361:     if (comp > max_stats.s_str)
                    362:        max_stats.s_str = comp;
                    363: }
                    364:
                    365: /*
                    366:  * add_str:
                    367:  *     Perform the actual add, checking upper and lower bound limits
                    368:  */
                    369: void
                    370: add_str(int *sp, int amt)
                    371: {
                    372:     if ((*sp += amt) < 3)
                    373:        *sp = 3;
                    374:     else if (*sp > 31)
                    375:        *sp = 31;
                    376: }
                    377:
                    378: /*
                    379:  * add_haste:
                    380:  *     Add a haste to the player
                    381:  */
                    382: int
                    383: add_haste(int potion)
                    384: {
                    385:     if (on(player, ISHASTE))
                    386:     {
                    387:        no_command += rnd(8);
                    388:        player.t_flags &= ~(ISRUN|ISHASTE);
                    389:        extinguish(nohaste);
                    390:        msg("you faint from exhaustion");
                    391:        return FALSE;
                    392:     }
                    393:     else
                    394:     {
                    395:        player.t_flags |= ISHASTE;
                    396:        if (potion)
                    397:            fuse(nohaste, 0, rnd(4)+4, AFTER);
                    398:        return TRUE;
                    399:     }
                    400: }
                    401:
                    402: /*
                    403:  * aggravate:
                    404:  *     Aggravate all the monsters on this level
                    405:  */
                    406:
                    407: void
                    408: aggravate(void)
                    409: {
                    410:     THING *mp;
                    411:
                    412:     for (mp = mlist; mp != NULL; mp = next(mp))
                    413:        runto(&mp->t_pos);
                    414: }
                    415:
                    416: /*
                    417:  * vowelstr:
                    418:  *      For printfs: if string starts with a vowel, return "n" for an
                    419:  *     "an".
                    420:  */
                    421: char *
                    422: vowelstr(const char *str)
                    423: {
                    424:     switch (*str)
                    425:     {
                    426:        case 'a': case 'A':
                    427:        case 'e': case 'E':
                    428:        case 'i': case 'I':
                    429:        case 'o': case 'O':
                    430:        case 'u': case 'U':
                    431:            return "n";
                    432:        default:
                    433:            return "";
                    434:     }
                    435: }
                    436:
                    437: /*
                    438:  * is_current:
                    439:  *     See if the object is one of the currently used items
                    440:  */
                    441: int
                    442: is_current(const THING *obj)
                    443: {
                    444:     if (obj == NULL)
                    445:        return FALSE;
                    446:     if (obj == cur_armor || obj == cur_weapon || obj == cur_ring[LEFT]
                    447:        || obj == cur_ring[RIGHT])
                    448:     {
                    449:        if (!terse)
                    450:            addmsg("That's already ");
                    451:        msg("in use");
                    452:        return TRUE;
                    453:     }
                    454:     return FALSE;
                    455: }
                    456:
                    457: /*
                    458:  * get_dir:
                    459:  *      Set up the direction co_ordinate for use in varios "prefix"
                    460:  *     commands
                    461:  */
                    462: int
                    463: get_dir(void)
                    464: {
                    465:     char *prompt;
                    466:     int gotit;
                    467:     static coord last_delt= {0,0};
                    468:
                    469:     if (again && last_dir != '\0')
                    470:     {
                    471:        delta.y = last_delt.y;
                    472:        delta.x = last_delt.x;
                    473:        dir_ch = last_dir;
                    474:     }
                    475:     else
                    476:     {
                    477:        if (!terse)
                    478:            msg(prompt = "which direction? ");
                    479:        else
                    480:            prompt = "direction: ";
                    481:        do
                    482:        {
                    483:            gotit = TRUE;
                    484:            switch (dir_ch = readchar())
                    485:            {
                    486:                case 'h': case'H': delta.y =  0; delta.x = -1;
                    487:                when 'j': case'J': delta.y =  1; delta.x =  0;
                    488:                when 'k': case'K': delta.y = -1; delta.x =  0;
                    489:                when 'l': case'L': delta.y =  0; delta.x =  1;
                    490:                when 'y': case'Y': delta.y = -1; delta.x = -1;
                    491:                when 'u': case'U': delta.y = -1; delta.x =  1;
                    492:                when 'b': case'B': delta.y =  1; delta.x = -1;
                    493:                when 'n': case'N': delta.y =  1; delta.x =  1;
                    494:                when ESCAPE: last_dir = '\0'; reset_last(); msg(""); return FALSE;
                    495:                otherwise:
                    496:                    mpos = 0;
                    497:                    msg(prompt);
                    498:                    gotit = FALSE;
                    499:            }
                    500:        } until (gotit);
                    501:        if (isupper(dir_ch))
                    502:            dir_ch = tolower(dir_ch);
                    503:        last_dir = dir_ch;
                    504:        last_delt.y = delta.y;
                    505:        last_delt.x = delta.x;
                    506:     }
                    507:     if (on(player, ISHUH) && rnd(5) == 0)
                    508:        do
                    509:        {
                    510:            delta.y = rnd(3) - 1;
                    511:            delta.x = rnd(3) - 1;
                    512:        } while (delta.y == 0 && delta.x == 0);
                    513:     mpos = 0;
                    514:     msg("");
                    515:     return TRUE;
                    516: }
                    517:
                    518: /*
                    519:  * sign:
                    520:  *     Return the sign of the number
                    521:  */
                    522: int
                    523: sign(int nm)
                    524: {
                    525:     if (nm < 0)
                    526:        return -1;
                    527:     else
                    528:        return (nm > 0);
                    529: }
                    530:
                    531: /*
                    532:  * spread:
                    533:  *     Give a spread around a given number (+/- 20%)
                    534:  */
                    535: int
                    536: spread(int nm)
                    537: {
                    538:     return nm - nm / 20 + rnd(nm / 10);
                    539: }
                    540:
                    541: /*
                    542:  * call_it:
                    543:  *     Call an object something after use.
                    544:  */
                    545:
                    546: void
                    547: call_it(struct obj_info *info)
                    548: {
                    549:     if (info->oi_know)
                    550:     {
                    551:        if (info->oi_guess)
                    552:        {
                    553:            free(info->oi_guess);
                    554:            info->oi_guess = NULL;
                    555:        }
                    556:     }
                    557:     else if (!info->oi_guess)
                    558:     {
                    559:        msg(terse ? "call it: " : "what do you want to call it? ");
                    560:        if (get_str(prbuf, stdscr) == NORM)
                    561:        {
                    562:            if (info->oi_guess != NULL)
                    563:                free(info->oi_guess);
                    564:            info->oi_guess = malloc(strlen(prbuf) + 1);
                    565:                if (info->oi_guess != NULL)
                    566:                        strcpy(info->oi_guess, prbuf);
                    567:        }
                    568:        msg("");
                    569:     }
                    570: }
                    571:
                    572: /*
                    573:  * rnd_thing:
                    574:  *     Pick a random thing appropriate for this level
                    575:  */
                    576: int
                    577: rnd_thing(void)
                    578: {
                    579:     int i;
                    580:     int thing_list[] = {
                    581:        POTION, SCROLL, RING, STICK, FOOD, WEAPON, ARMOR, STAIRS, GOLD, AMULET
                    582:     };
                    583:
                    584:     if (level >= AMULETLEVEL)
                    585:         i = rnd(sizeof thing_list / sizeof (int));
                    586:     else
                    587:         i = rnd(sizeof thing_list / sizeof (int) - 1);
                    588:     return thing_list[i];
                    589: }
                    590:
                    591: /*
                    592:  str str:
                    593:  *     Choose the first or second string depending on whether it the
                    594:  *     player is tripping
                    595:  */
                    596: const char *
                    597: choose_str(const char *ts, const char *ns)
                    598: {
                    599:        return (on(player, ISHALU) ? ts : ns);
                    600: }

CVSweb