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

Annotation of early-roguelike/rogue4/things.c, Revision 1.1.1.1

1.1       rubenllo    1: /*
                      2:  * Contains functions for dealing with things like potions, scrolls,
                      3:  * and other items.
                      4:  *
                      5:  * @(#)things.c        4.26 (Berkeley) 5/18/82
                      6:  *
                      7:  * Rogue: Exploring the Dungeons of Doom
                      8:  * Copyright (C) 1980, 1981, 1982 Michael Toy, Ken Arnold and Glenn Wichman
                      9:  * All rights reserved.
                     10:  *
                     11:  * See the file LICENSE.TXT for full copyright and licensing information.
                     12:  */
                     13:
                     14: #include <curses.h>
                     15: #include <ctype.h>
                     16: #include <string.h>
                     17: #include "rogue.h"
                     18:
                     19: int pick_one(struct magic_item *magic, int nitems);
                     20: void print_disc(char type);
                     21: void set_order(short *order, int numthings);
                     22: char *nothing(char type);
                     23:
                     24: bool got_genocide = FALSE;
                     25:
                     26: /*
                     27:  * inv_name:
                     28:  *     Return the name of something as it would appear in an
                     29:  *     inventory.
                     30:  */
                     31: char *
                     32: inv_name(THING *obj, bool drop)
                     33: {
                     34:     register char *pb;
                     35:
                     36:     pb = prbuf;
                     37:     switch (obj->o_type)
                     38:     {
                     39:        case SCROLL:
                     40:            if (obj->o_count == 1)
                     41:            {
                     42:                strcpy(pb, "A scroll ");
                     43:                pb = &prbuf[9];
                     44:            }
                     45:            else
                     46:            {
                     47:                sprintf(pb, "%d scrolls ", obj->o_count);
                     48:                pb = &prbuf[strlen(prbuf)];
                     49:            }
                     50:            if (s_know[obj->o_which])
                     51:                sprintf(pb, "of %s", s_magic[obj->o_which].mi_name);
                     52:            else if (s_guess[obj->o_which])
                     53:                sprintf(pb, "called %s", s_guess[obj->o_which]);
                     54:            else
                     55:                sprintf(pb, "titled '%s'", s_names[obj->o_which]);
                     56:         when POTION:
                     57:            if (obj->o_count == 1)
                     58:            {
                     59:                strcpy(pb, "A potion ");
                     60:                pb = &prbuf[9];
                     61:            }
                     62:            else
                     63:            {
                     64:                sprintf(pb, "%d potions ", obj->o_count);
                     65:                pb = &pb[strlen(prbuf)];
                     66:            }
                     67:            if (p_know[obj->o_which])
                     68:                sprintf(pb, "of %s(%s)", p_magic[obj->o_which].mi_name,
                     69:                    p_colors[obj->o_which]);
                     70:            else if (p_guess[obj->o_which])
                     71:                sprintf(pb, "called %s(%s)", p_guess[obj->o_which],
                     72:                    p_colors[obj->o_which]);
                     73:            else if (obj->o_count == 1)
                     74:                sprintf(prbuf, "A%s %s potion", vowelstr(p_colors[obj->o_which]),
                     75:                    p_colors[obj->o_which]);
                     76:            else
                     77:                sprintf(prbuf, "%d %s potions", obj->o_count,
                     78:                    p_colors[obj->o_which]);
                     79:        when FOOD:
                     80:            if (obj->o_which == 1)
                     81:                if (obj->o_count == 1)
                     82:                    sprintf(pb, "A%s %.76s", vowelstr(fruit), fruit);
                     83:                else
                     84:                    sprintf(pb, "%d %.66ss", obj->o_count, fruit);
                     85:            else
                     86:                if (obj->o_count == 1)
                     87:                    strcpy(pb, "Some food");
                     88:                else
                     89:                    sprintf(pb, "%d rations of food", obj->o_count);
                     90:        when WEAPON:
                     91:            if (obj->o_count > 1)
                     92:                sprintf(pb, "%d ", obj->o_count);
                     93:            else
                     94:                sprintf(pb, "A%s ", vowelstr(w_names[obj->o_which]));
                     95:            pb = &prbuf[strlen(prbuf)];
                     96:            if (obj->o_flags & ISKNOW)
                     97:                sprintf(pb, "%s %s", num(obj->o_hplus, obj->o_dplus, WEAPON),
                     98:                    w_names[obj->o_which]);
                     99:            else
                    100:                sprintf(pb, "%s", w_names[obj->o_which]);
                    101:            if (obj->o_count > 1)
                    102:                strcat(pb, "s");
                    103:        when ARMOR:
                    104:            if (obj->o_flags & ISKNOW)
                    105:            {
                    106:                sprintf(pb, "%s %s [",
                    107:                    num(a_class[obj->o_which] - obj->o_ac, 0, ARMOR),
                    108:                    a_names[obj->o_which]);
                    109:                if (!terse)
                    110:                    strcat(pb, "armor class ");
                    111:                pb = &prbuf[strlen(prbuf)];
                    112:                sprintf(pb, "%d]", obj->o_ac);
                    113:            }
                    114:            else
                    115:                sprintf(pb, "%s", a_names[obj->o_which]);
                    116:        when AMULET:
                    117:            strcpy(pb, "The Amulet of Yendor");
                    118:        when STICK:
                    119:            sprintf(pb, "A%s %s ", vowelstr(ws_type[obj->o_which]),
                    120:                ws_type[obj->o_which]);
                    121:            pb = &prbuf[strlen(prbuf)];
                    122:            if (ws_know[obj->o_which])
                    123:                sprintf(pb, "of %s%s(%s)", ws_magic[obj->o_which].mi_name,
                    124:                    charge_str(obj), ws_made[obj->o_which]);
                    125:            else if (ws_guess[obj->o_which])
                    126:                sprintf(pb, "called %s(%s)", ws_guess[obj->o_which],
                    127:                    ws_made[obj->o_which]);
                    128:            else
                    129:                sprintf(pb = &prbuf[1], "%s %s %s",
                    130:                    vowelstr(ws_made[obj->o_which]), ws_made[obj->o_which],
                    131:                    ws_type[obj->o_which]);
                    132:         when RING:
                    133:            if (r_know[obj->o_which])
                    134:                sprintf(pb, "A%s ring of %s(%s)", ring_num(obj),
                    135:                    r_magic[obj->o_which].mi_name, r_stones[obj->o_which]);
                    136:            else if (r_guess[obj->o_which])
                    137:                sprintf(pb, "A ring called %s(%s)",
                    138:                    r_guess[obj->o_which], r_stones[obj->o_which]);
                    139:            else
                    140:                sprintf(pb, "A%s %s ring", vowelstr(r_stones[obj->o_which]),
                    141:                    r_stones[obj->o_which]);
                    142:        when GOLD:
                    143:                sprintf(pb, "%d pieces of gold", obj->o_goldval);
                    144: #ifdef WIZARD
                    145:        otherwise:
                    146:            debug("Picked up something funny %s", unctrol(obj->o_type));
                    147:            sprintf(pb, "Something bizarre %s", unctrol(obj->o_type));
                    148: #endif
                    149:     }
                    150:     if (obj == cur_armor)
                    151:        strcat(pb, " (being worn)");
                    152:     if (obj == cur_weapon)
                    153:        strcat(pb, " (weapon in hand)");
                    154:     if (obj == cur_ring[LEFT])
                    155:        strcat(pb, " (on left hand)");
                    156:     else if (obj == cur_ring[RIGHT])
                    157:        strcat(pb, " (on right hand)");
                    158:     if (drop && isupper(prbuf[0]))
                    159:        prbuf[0] = tolower(prbuf[0]);
                    160:     else if (!drop && islower(*prbuf))
                    161:        *prbuf = toupper(*prbuf);
                    162:     return prbuf;
                    163: }
                    164:
                    165: /*
                    166:  * drop:
                    167:  *     Put something down
                    168:  */
                    169: void
                    170: drop(void)
                    171: {
                    172:     register char ch;
                    173:     register THING *nobj, *op;
                    174:
                    175:     ch = chat(hero.y, hero.x);
                    176:     if (ch != FLOOR && ch != PASSAGE)
                    177:     {
                    178:        after = FALSE;
                    179:        msg("there is something there already");
                    180:        return;
                    181:     }
                    182:     if ((op = get_item("drop", 0)) == NULL)
                    183:        return;
                    184:     if (!dropcheck(op))
                    185:        return;
                    186:     /*
                    187:      * Take it out of the pack
                    188:      */
                    189:     if (op->o_count >= 2 && op->o_type != WEAPON)
                    190:     {
                    191:        op->o_count--;
                    192:        nobj = new_item();
                    193:        *nobj = *op;
                    194:        nobj->o_count = 1;
                    195:        op = nobj;
                    196:        if (op->o_group != 0)
                    197:                inpack++;
                    198:     }
                    199:     else
                    200:        detach(pack, op);
                    201:     inpack--;
                    202:     /*
                    203:      * Link it into the level object list
                    204:      */
                    205:     attach(lvl_obj, op);
                    206:     chat(hero.y, hero.x) = op->o_type;
                    207:     flat(hero.y, hero.x) |= F_DROPPED;
                    208:     op->o_pos = hero;
                    209:     if (op->o_type == AMULET)
                    210:        amulet = FALSE;
                    211:     msg("dropped %s", inv_name(op, TRUE));
                    212: }
                    213:
                    214: /*
                    215:  * dropcheck:
                    216:  *     Do special checks for dropping or unweilding|unwearing|unringing
                    217:  */
                    218: bool
                    219: dropcheck(THING *op)
                    220: {
                    221:     if (op == NULL)
                    222:        return TRUE;
                    223:     if (op != cur_armor && op != cur_weapon
                    224:        && op != cur_ring[LEFT] && op != cur_ring[RIGHT])
                    225:            return TRUE;
                    226:     if (op->o_flags & ISCURSED)
                    227:     {
                    228:        msg("you can't.  It appears to be cursed");
                    229:        return FALSE;
                    230:     }
                    231:     if (op == cur_weapon)
                    232:        cur_weapon = NULL;
                    233:     else if (op == cur_armor)
                    234:     {
                    235:        waste_time();
                    236:        cur_armor = NULL;
                    237:     }
                    238:     else
                    239:     {
                    240:        cur_ring[op == cur_ring[LEFT] ? LEFT : RIGHT] = NULL;
                    241:        switch (op->o_which)
                    242:        {
                    243:            case R_ADDSTR:
                    244:                chg_str(-op->o_ac);
                    245:                break;
                    246:            case R_SEEINVIS:
                    247:                unsee();
                    248:                extinguish(unsee);
                    249:                break;
                    250:        }
                    251:     }
                    252:     return TRUE;
                    253: }
                    254:
                    255: /*
                    256:  * new_thing:
                    257:  *     Return a new thing
                    258:  */
                    259: THING *
                    260: new_thing(void)
                    261: {
                    262:     register THING *cur;
                    263:     register int j, k;
                    264:
                    265:     cur = new_item();
                    266:     cur->o_hplus = cur->o_dplus = 0;
                    267:     strcpy(cur->o_damage,"0d0");
                    268:     strcpy(cur->o_hurldmg,"0d0");
                    269:     cur->o_ac = 11;
                    270:     cur->o_count = 1;
                    271:     cur->o_group = 0;
                    272:     cur->o_flags = 0;
                    273:     /*
                    274:      * Decide what kind of object it will be
                    275:      * If we haven't had food for a while, let it be food.
                    276:      */
                    277:     switch (no_food > 3 ? 2 : pick_one(things, NUMTHINGS))
                    278:     {
                    279:        case 0:
                    280:            cur->o_type = POTION;
                    281:            cur->o_which = pick_one(p_magic, MAXPOTIONS);
                    282:        when 1:
                    283:            cur->o_type = SCROLL;
                    284:            cur->o_which = pick_one(s_magic, MAXSCROLLS);
                    285:            /*
                    286:             * Only one genocide scroll allowed per game, so if it's
                    287:             * the second one, then turn it into a identify scroll
                    288:             */
                    289:            if (cur->o_which == S_GENOCIDE)
                    290:                if (got_genocide)
                    291:                    cur->o_which = S_IDENT;
                    292:                else
                    293:                    got_genocide = TRUE;
                    294:        when 2:
                    295:            no_food = 0;
                    296:            cur->o_type = FOOD;
                    297:            if (rnd(10) != 0)
                    298:                cur->o_which = 0;
                    299:            else
                    300:                cur->o_which = 1;
                    301:        when 3:
                    302:            cur->o_type = WEAPON;
                    303:            cur->o_which = rnd(MAXWEAPONS);
                    304:            init_weapon(cur, cur->o_which);
                    305:            if ((k = rnd(100)) < 10)
                    306:            {
                    307:                cur->o_flags |= ISCURSED;
                    308:                cur->o_hplus -= rnd(3) + 1;
                    309:            }
                    310:            else if (k < 15)
                    311:                cur->o_hplus += rnd(3) + 1;
                    312:        when 4:
                    313:            cur->o_type = ARMOR;
                    314:            for (j = 0, k = rnd(100); j < MAXARMORS; j++)
                    315:                if (k < a_chances[j])
                    316:                    break;
                    317: #ifdef WIZARD
                    318:            if (j == MAXARMORS)
                    319:            {
                    320:                debug("Picked a bad armor %d", k);
                    321:                j = 0;
                    322:            }
                    323: #endif
                    324:            cur->o_which = j;
                    325:            cur->o_ac = a_class[j];
                    326:            if ((k = rnd(100)) < 20)
                    327:            {
                    328:                cur->o_flags |= ISCURSED;
                    329:                cur->o_ac += rnd(3) + 1;
                    330:            }
                    331:            else if (k < 28)
                    332:                cur->o_ac -= rnd(3) + 1;
                    333:        when 5:
                    334:            cur->o_type = RING;
                    335:            cur->o_which = pick_one(r_magic, MAXRINGS);
                    336:            switch (cur->o_which)
                    337:            {
                    338:                case R_ADDSTR:
                    339:                case R_PROTECT:
                    340:                case R_ADDHIT:
                    341:                case R_ADDDAM:
                    342:                    if ((cur->o_ac = rnd(3)) == 0)
                    343:                    {
                    344:                        cur->o_ac = -1;
                    345:                        cur->o_flags |= ISCURSED;
                    346:                    }
                    347:                when R_AGGR:
                    348:                case R_TELEPORT:
                    349:                    cur->o_flags |= ISCURSED;
                    350:            }
                    351:        when 6:
                    352:            cur->o_type = STICK;
                    353:            cur->o_which = pick_one(ws_magic, MAXSTICKS);
                    354:            fix_stick(cur);
                    355: #ifdef WIZARD
                    356:        otherwise:
                    357:            debug("Picked a bad kind of object");
                    358:            wait_for(' ');
                    359: #endif
                    360:     }
                    361:     return cur;
                    362: }
                    363:
                    364: /*
                    365:  * pick_one:
                    366:  *     Pick an item out of a list of nitems possible magic items
                    367:  */
                    368: int
                    369: pick_one(struct magic_item *magic, int nitems)
                    370: {
                    371:     register struct magic_item *end;
                    372:     register int i;
                    373:     register struct magic_item *start;
                    374:
                    375:     start = magic;
                    376:     for (end = &magic[nitems], i = rnd(100); magic < end; magic++)
                    377:        if (i < magic->mi_prob)
                    378:            break;
                    379:     if (magic == end)
                    380:     {
                    381: #ifdef WIZARD
                    382:        if (wizard)
                    383:        {
                    384:            msg("bad pick_one: %d from %d items", i, nitems);
                    385:            for (magic = start; magic < end; magic++)
                    386:                msg("%s: %d%%", magic->mi_name, magic->mi_prob);
                    387:        }
                    388: #endif
                    389:        magic = start;
                    390:     }
                    391:     return magic - start;
                    392: }
                    393:
                    394: /*
                    395:  * discovered:
                    396:  *     list what the player has discovered in this game of a certain type
                    397:  */
                    398: static int line_cnt = 0;
                    399:
                    400: static bool newpage = FALSE;
                    401:
                    402: static char *lastfmt, *lastarg;
                    403:
                    404: void
                    405: discovered(void)
                    406: {
                    407:     register char ch;
                    408:     register bool disc_list;
                    409:
                    410:     do {
                    411:        disc_list = FALSE;
                    412:        if (!terse)
                    413:            addmsg("for ");
                    414:        addmsg("what type");
                    415:        if (!terse)
                    416:            addmsg(" of object do you want a list");
                    417:        msg("? (* for all)");
                    418:        ch = readchar();
                    419:        switch (ch)
                    420:        {
                    421:            case ESCAPE:
                    422:                msg("");
                    423:                return;
                    424:            case POTION:
                    425:            case SCROLL:
                    426:            case RING:
                    427:            case STICK:
                    428:            case '*':
                    429:                disc_list = TRUE;
                    430:                break;
                    431:            default:
                    432:                if (terse)
                    433:                    msg("Not a type");
                    434:                else
                    435:                    msg("Please type one of %c%c%c%c (ESCAPE to quit)", POTION, SCROLL, RING, STICK);
                    436:        }
                    437:     } while (!disc_list);
                    438:     if (ch == '*')
                    439:     {
                    440:        print_disc(POTION);
                    441:        add_line("", NULL);
                    442:        print_disc(SCROLL);
                    443:        add_line("", NULL);
                    444:        print_disc(RING);
                    445:        add_line("", NULL);
                    446:        print_disc(STICK);
                    447:        end_line();
                    448:     }
                    449:     else
                    450:     {
                    451:        print_disc(ch);
                    452:        end_line();
                    453:     }
                    454: }
                    455:
                    456: /*
                    457:  * print_disc:
                    458:  *     Print what we've discovered of type 'type'
                    459:  */
                    460:
                    461: #define MAX(a,b,c,d)   (a > b ? (a > c ? (a > d ? a : d) : (c > d ? c : d)) : (b > c ? (b > d ? b : d) : (c > d ? c : d)))
                    462:
                    463: void
                    464: print_disc(char type)
                    465: {
                    466:     register bool *know = NULL;
                    467:     register char **guess = NULL;
                    468:     register int i, maxnum = 0, num_found;
                    469:     static THING obj;
                    470:     static short order[MAX(MAXSCROLLS, MAXPOTIONS, MAXRINGS, MAXSTICKS)];
                    471:
                    472:     switch (type)
                    473:     {
                    474:        case SCROLL:
                    475:            maxnum = MAXSCROLLS;
                    476:            know = s_know;
                    477:            guess = s_guess;
                    478:            break;
                    479:        case POTION:
                    480:            maxnum = MAXPOTIONS;
                    481:            know = p_know;
                    482:            guess = p_guess;
                    483:            break;
                    484:        case RING:
                    485:            maxnum = MAXRINGS;
                    486:            know = r_know;
                    487:            guess = r_guess;
                    488:            break;
                    489:        case STICK:
                    490:            maxnum = MAXSTICKS;
                    491:            know = ws_know;
                    492:            guess = ws_guess;
                    493:            break;
                    494:     }
                    495:     set_order(order, maxnum);
                    496:     obj.o_count = 1;
                    497:     obj.o_flags = 0;
                    498:     num_found = 0;
                    499:     for (i = 0; i < maxnum; i++)
                    500:        if (know[order[i]] || guess[order[i]])
                    501:        {
                    502:            obj.o_type = type;
                    503:            obj.o_which = order[i];
                    504:            add_line("%s", inv_name(&obj, FALSE));
                    505:            num_found++;
                    506:        }
                    507:     if (num_found == 0)
                    508:        add_line(nothing(type), NULL);
                    509: }
                    510:
                    511: /*
                    512:  * set_order:
                    513:  *     Set up order for list
                    514:  */
                    515: void
                    516: set_order(short *order, int numthings)
                    517: {
                    518:     register int i, r, t;
                    519:
                    520:     for (i = 0; i< numthings; i++)
                    521:        order[i] = i;
                    522:
                    523:     for (i = numthings; i > 0; i--)
                    524:     {
                    525:        r = rnd(i);
                    526:        t = order[i - 1];
                    527:        order[i - 1] = order[r];
                    528:        order[r] = t;
                    529:     }
                    530: }
                    531:
                    532: /*
                    533:  * add_line:
                    534:  *     Add a line to the list of discoveries
                    535:  */
                    536: void
                    537: add_line(char *fmt, char *arg)
                    538: {
                    539:     if (line_cnt == 0)
                    540:     {
                    541:            wclear(hw);
                    542:            if (slow_invent)
                    543:                mpos = 0;
                    544:     }
                    545:     if (slow_invent)
                    546:     {
                    547:        if (fmt != NULL && *fmt != '\0')
                    548:            msg(fmt, arg);
                    549:        line_cnt++;
                    550:     }
                    551:     else
                    552:     {
                    553:        if (line_cnt >= LINES - 1 || fmt == NULL)
                    554:        {
                    555:            mvwaddstr(hw, LINES - 1, 0, "--Press space to continue--");
                    556:            wrefresh(hw);
                    557:            w_wait_for(hw,' ');
                    558:            clearok(curscr, TRUE);
                    559:            wclear(hw);
                    560:             touchwin(stdscr);
                    561:            newpage = TRUE;
                    562:            line_cnt = 0;
                    563:        }
                    564:        if (fmt != NULL && !(line_cnt == 0 && *fmt == '\0'))
                    565:        {
                    566:            mvwprintw(hw, line_cnt++, 0, fmt, arg);
                    567:            lastfmt = fmt;
                    568:            lastarg = arg;
                    569:        }
                    570:     }
                    571: }
                    572:
                    573: /*
                    574:  * end_line:
                    575:  *     End the list of lines
                    576:  */
                    577: void
                    578: end_line(void)
                    579: {
                    580:     if (!slow_invent)
                    581:     {
                    582:        if (line_cnt == 1 && !newpage)
                    583:        {
                    584:            mpos = 0;
                    585:            msg(lastfmt, lastarg);
                    586:        }
                    587:        else
                    588:        {
                    589:            add_line(NULL, NULL);
                    590:            msg("");
                    591:        }
                    592:     }
                    593:     line_cnt = 0;
                    594:     newpage = FALSE;
                    595: }
                    596:
                    597: /*
                    598:  * nothing:
                    599:  *     Set up prbuf so that message for "nothing found" is there
                    600:  */
                    601: char *
                    602: nothing(char type)
                    603: {
                    604:     register char *sp, *tystr = NULL;
                    605:
                    606:     if (terse)
                    607:        sprintf(prbuf, "Nothing");
                    608:     else
                    609:        sprintf(prbuf, "Haven't discovered anything");
                    610:     if (type != '*')
                    611:     {
                    612:        sp = &prbuf[strlen(prbuf)];
                    613:        switch (type)
                    614:        {
                    615:            case POTION: tystr = "potion";
                    616:            when SCROLL: tystr = "scroll";
                    617:            when RING: tystr = "ring";
                    618:            when STICK: tystr = "stick";
                    619:        }
                    620:        sprintf(sp, " about any %ss", tystr);
                    621:     }
                    622:     return prbuf;
                    623: }

CVSweb