[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     ! 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