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

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

1.1       rubenllo    1: /*
                      2:  * Contains functions for dealing with things like
                      3:  * potions and scrolls
                      4:  *
                      5:  * @(#)things.c        9.0     (rdk)    7/17/84
                      6:  *
                      7:  * Super-Rogue
                      8:  * Copyright (C) 1984 Robert D. Kindelberger
                      9:  * All rights reserved.
                     10:  *
                     11:  * Based on "Rogue: Exploring the Dungeons of Doom"
                     12:  * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
                     13:  * All rights reserved.
                     14:  *
                     15:  * See the file LICENSE.TXT for full copyright and licensing information.
                     16:  */
                     17:
                     18: #include <ctype.h>
                     19: #include <string.h>
                     20: #include "rogue.h"
                     21: #include "rogue.ext"
                     22:
                     23: void basic_init(struct object *cur);
                     24:
                     25: /*
                     26:  * inv_name:
                     27:  *     Return the name of something as it would appear in an inventory.
                     28:  */
                     29: char *
                     30: inv_name(struct object *obj, bool drop)
                     31: {
                     32:        reg char *pb, *tn, *pl;
                     33:        reg int wh, knowit;
                     34:        char nm[3], *inm, *q;
                     35:
                     36:        wh = obj->o_which;
                     37:        knowit = FALSE;
                     38:        if (obj->o_count > 1)
                     39:                pl = "s";
                     40:        else
                     41:                pl = "";
                     42:        if (obj->o_count > 1)
                     43:                sprintf(nm, "%d", obj->o_count);
                     44:        else
                     45:                strcpy(nm, "A");
                     46:        tn = obj->o_typname;
                     47:        q = "";
                     48:        switch(obj->o_type) {
                     49:        case SCROLL:
                     50:                sprintf(prbuf, "%s %s%s ", nm, tn, pl);
                     51:                pb = &prbuf[strlen(prbuf)];
                     52:                if (s_know[wh] || o_on(obj,ISPOST)) {
                     53:                        knowit = TRUE;
                     54:                        sprintf(pb, "of %s", s_magic[wh].mi_name);
                     55:                }
                     56:                else if (s_guess[wh])
                     57:                        sprintf(pb, "called %s", s_guess[wh]);
                     58:                else
                     59:                        sprintf(pb, "titled '%s'", s_names[wh]);
                     60:     when POTION:
                     61:                sprintf(prbuf, "%s %s%s ", nm, tn, pl);
                     62:                pb = &prbuf[strlen(prbuf)];
                     63:                if (p_know[wh] || o_on(obj, ISPOST)) {
                     64:                        sprintf(pb, "of %s", p_magic[wh].mi_name);
                     65:                        knowit = TRUE;
                     66:                        if (p_know[wh]) {
                     67:                                pb = &prbuf[strlen(prbuf)];
                     68:                                sprintf(pb,"(%s)",p_colors[wh]);
                     69:                        }
                     70:                }
                     71:                else if (p_guess[wh])
                     72:                        sprintf(pb,"called %s(%s)", p_guess[wh],p_colors[wh]);
                     73:                else if (obj->o_count == 1)
                     74:                        sprintf(prbuf,"%s%s %s %s%s", nm, vowelstr(p_colors[wh]),
                     75:                                p_colors[wh], tn, pl);
                     76:                else
                     77:                        sprintf(prbuf,"%s %s %s%s", nm, p_colors[wh], tn, pl);
                     78:        when FOOD:
                     79:                if (wh == 1) {
                     80:                        if (obj->o_count == 1)
                     81:                                q = vowelstr(fruit);
                     82:                        sprintf(prbuf, "%s%s %.72s%s", nm, q, fruit, pl);
                     83:                }
                     84:                else {
                     85:                        if (obj->o_count == 1)
                     86:                                sprintf(prbuf, "Some %s", tn);
                     87:                        else
                     88:                                sprintf(prbuf, "%s rations of %s", nm, tn);
                     89:                }
                     90:                knowit = TRUE;
                     91:        when WEAPON:
                     92:                inm = w_magic[wh].mi_name;
                     93:                strcpy(prbuf, nm);
                     94:                if (obj->o_count == 1)
                     95:                        q = vowelstr(inm);
                     96:                pb = &prbuf[strlen(prbuf)];
                     97:                if (o_on(obj,ISKNOW | ISPOST)) {
                     98:                        knowit = TRUE;
                     99:                        sprintf(pb, " %s %s", num(obj->o_hplus, obj->o_dplus), inm);
                    100:                }
                    101:                else
                    102:                        sprintf(pb, "%s %s", q, inm);
                    103:                strcat(prbuf, pl);
                    104:        when ARMOR:
                    105:                inm = a_magic[wh].mi_name;
                    106:                if (o_on(obj,ISKNOW | ISPOST)) {
                    107:                        knowit = TRUE;
                    108:                        sprintf(prbuf, "%s %s",num(armors[wh].a_class - obj->o_ac, 0),
                    109:                                inm);
                    110:                }
                    111:                else
                    112:                        sprintf(prbuf, "%s", inm);
                    113:        when AMULET:
                    114:                strcpy(prbuf, "The Amulet of Yendor");
                    115:        when STICK: {
                    116:                struct rod *rd;
                    117:
                    118:                rd = &ws_stuff[wh];
                    119:                sprintf(prbuf, "A %s ", rd->ws_type);
                    120:                pb = &prbuf[strlen(prbuf)];
                    121:                if (ws_know[wh] || o_on(obj, ISPOST)) {
                    122:                        knowit = TRUE;
                    123:                        sprintf(pb,"of %s%s",ws_magic[wh].mi_name,charge_str(obj));
                    124:                        if (ws_know[wh]) {
                    125:                                pb = &prbuf[strlen(prbuf)];
                    126:                                sprintf(pb,"(%s)",rd->ws_made);
                    127:                        }
                    128:                }
                    129:                else if (ws_guess[wh])
                    130:                        sprintf(pb, "called %s(%s)", ws_guess[wh], rd->ws_made);
                    131:                else
                    132:                        sprintf(prbuf, "A%s %s %s", vowelstr(rd->ws_made),
                    133:                                rd->ws_made, rd->ws_type);
                    134:        }
                    135:     when RING:
                    136:                if (r_know[wh] || o_on(obj, ISPOST)) {
                    137:                        knowit = TRUE;
                    138:                        sprintf(prbuf, "A%s %s of %s", ring_num(obj), tn,
                    139:                          r_magic[wh].mi_name);
                    140:                        if (r_know[wh]) {
                    141:                                pb = &prbuf[strlen(prbuf)];
                    142:                                sprintf(pb,"(%s)", r_stones[wh]);
                    143:                        }
                    144:                }
                    145:                else if (r_guess[wh])
                    146:                        sprintf(prbuf,"A %s called %s(%s)",tn, r_guess[wh],
                    147:                                r_stones[wh]);
                    148:                else
                    149:                        sprintf(prbuf,"A%s %s %s",vowelstr(r_stones[wh]),
                    150:                                r_stones[wh], tn);
                    151:        otherwise:
                    152:                sprintf(prbuf,"Something bizarre %s", unctrl(obj->o_type));
                    153:        }
                    154:        if (obj == cur_armor)
                    155:                strcat(prbuf, " (being worn)");
                    156:        if (obj == cur_weapon)
                    157:                strcat(prbuf, " (weapon in hand)");
                    158:        if (obj == cur_ring[LEFT])
                    159:                strcat(prbuf, " (on left hand)");
                    160:        else if (obj == cur_ring[RIGHT])
                    161:                strcat(prbuf, " (on right hand)");
                    162:        if (drop && isupper(prbuf[0]))
                    163:                prbuf[0] = tolower(prbuf[0]);
                    164:        else if (!drop && islower(*prbuf))
                    165:                *prbuf = toupper(*prbuf);
                    166:        if (o_on(obj, ISPROT))
                    167:                strcat(prbuf, " [!]");
                    168:        if (o_on(obj, ISPOST))
                    169:                strcat(prbuf, " [$]");
                    170:        if (knowit) {
                    171:                if (o_on(obj, ISCURSED))
                    172:                        strcat(prbuf, " [-]");
                    173:                else if (o_on(obj, ISBLESS))
                    174:                        strcat(prbuf, " [+]");
                    175:        }
                    176:        if (!drop)
                    177:                strcat(prbuf, ".");
                    178:        return prbuf;
                    179: }
                    180:
                    181: /*
                    182:  * money:
                    183:  *     Add to characters purse
                    184:  */
                    185: void
                    186: money(void)
                    187: {
                    188:        reg struct room *rp;
                    189:        reg struct linked_list *item;
                    190:        reg struct thing *tp;
                    191:
                    192:        rp = player.t_room;
                    193:        if (rp != NULL && ce(hero, rp->r_gold)) {
                    194:                msg("%d gold pieces.", rp->r_goldval);
                    195:                purse += rp->r_goldval;
                    196:                rp->r_goldval = 0;
                    197:                cmov(rp->r_gold);
                    198:                addch(FLOOR);
                    199:                /*
                    200:                 * once gold is taken, all monsters will chase him
                    201:                 */
                    202:                for (item = mlist; item != NULL; item = next(item)) {
                    203:                        tp = THINGPTR(item);
                    204:                        if (rnd(100) < 70 && tp->t_room == rp && !iswearing(R_STEALTH)
                    205:                          && ((tp->t_flags & (ISMEAN | ISGREED)) || rnd(1000) < 20))
                    206:                                runto(&tp->t_pos, &hero);
                    207:                }
                    208:        }
                    209:        else
                    210:                msg("That gold must have been counterfeit.");
                    211: }
                    212:
                    213:
                    214: /*
                    215:  * drop:
                    216:  *     put something down
                    217:  */
                    218: int
                    219: drop(struct linked_list *item)
                    220: {
                    221:        reg char ch;
                    222:        reg struct linked_list *ll, *nll;
                    223:        reg struct object *op;
                    224:
                    225:        if (item == NULL) {
                    226:                ch = mvinch(hero.y, hero.x);
                    227:                if (ch != FLOOR && ch != PASSAGE && ch != POOL) {
                    228:                        msg("There is something there already.");
                    229:                        after = FALSE;
                    230:                        return SOMTHERE;
                    231:                }
                    232:                if ((ll = get_item("drop", 0)) == NULL)
                    233:                        return FALSE;
                    234:        }
                    235:        else {
                    236:                ll = item;
                    237:        }
                    238:        op = OBJPTR(ll);
                    239:        if (!dropcheck(op))
                    240:                return CANTDROP;
                    241:        /*
                    242:         * Take it out of the pack
                    243:         */
                    244:        if (op->o_count >= 2 && op->o_type != WEAPON) {
                    245:                nll = new_item(sizeof *op);
                    246:                op->o_count--;
                    247:                op->o_vol = itemvol(op);
                    248:                op = OBJPTR(nll);
                    249:                *op = *(OBJPTR(ll));
                    250:                op->o_count = 1;
                    251:                op->o_vol = itemvol(op);
                    252:                ll = nll;
                    253:        }
                    254:        else {
                    255:                detach(pack, ll);
                    256:        }
                    257:        if (ch == POOL) {
                    258:                msg("%s sinks out of sight.",inv_name(op, TRUE));
                    259:                discard(ll);
                    260:        }
                    261:        else {                  /* put on dungeon floor */
                    262:                if (levtype == POSTLEV) {
                    263:                        op->o_pos = hero;       /* same place as hero */
                    264:                        fall(ll,FALSE);
                    265:                        if (item == NULL)       /* if item wasn't sold */
                    266:                                msg("Thanks for your donation to the Fiend's flea market.");
                    267:                }
                    268:                else {
                    269:                        attach(lvl_obj, ll);
                    270:                        mvaddch(hero.y, hero.x, op->o_type);
                    271:                        op->o_pos = hero;
                    272:                        msg("Dropped %s", inv_name(op, TRUE));
                    273:                }
                    274:        }
                    275:        updpack();                      /* new pack weight */
                    276:        return TRUE;
                    277: }
                    278:
                    279:
                    280: /*
                    281:  * dropcheck:
                    282:  *     Do special checks for dropping or unweilding|unwearing|unringing
                    283:  */
                    284: bool
                    285: dropcheck(struct object *op)
                    286: {
                    287:        if (op == NULL)
                    288:                return TRUE;
                    289:        if (levtype == POSTLEV) {
                    290:                if (o_on(op,ISCURSED) && o_on(op,ISKNOW)) {
                    291:                        msg("The trader does not accept shoddy merchandise.");
                    292:                        return FALSE;
                    293:                }
                    294:                else {
                    295:                        cur_null(op);   /* update cur_weapon, etc */
                    296:                        return TRUE;
                    297:                }
                    298:        }
                    299:        if (op != cur_armor && op != cur_weapon
                    300:          && op != cur_ring[LEFT] && op != cur_ring[RIGHT])
                    301:                return TRUE;
                    302:        if (o_on(op,ISCURSED)) {
                    303:                msg("You can't.  It appears to be cursed.");
                    304:                return FALSE;
                    305:        }
                    306:        if (op == cur_weapon)
                    307:                cur_weapon = NULL;
                    308:        else if (op == cur_armor) {
                    309:                waste_time();
                    310:                cur_armor = NULL;
                    311:        }
                    312:        else if (op == cur_ring[LEFT] || op == cur_ring[RIGHT])
                    313:                toss_ring(op);
                    314:        return TRUE;
                    315: }
                    316:
                    317:
                    318: /*
                    319:  * new_thing:
                    320:  *     Return a new thing
                    321:  */
                    322: struct linked_list *
                    323: new_thing(bool treas, int type, int which)
                    324: {
                    325:        struct linked_list *item;
                    326:        struct magic_item *mi;
                    327:        struct object *cur;
                    328:        int chance, whi;
                    329:
                    330:        item = new_item(sizeof *cur);
                    331:        cur = OBJPTR(item);
                    332:        basic_init(cur);
                    333:        if (type == DONTCARE) {
                    334:                if (++no_food > 4 && !treas)
                    335:                        whi = TYP_FOOD;
                    336:                else
                    337:                        whi = pick_one(things);
                    338:        }
                    339:        else {
                    340:                whi = getindex(type);
                    341:        }
                    342:        mi = thnginfo[whi].mf_magic;
                    343:        if (which == DONTCARE) {
                    344:                which = 0;
                    345:                if (mi != NULL)
                    346:                        which = pick_one(mi);
                    347:        }
                    348:        cur->o_typname = things[whi].mi_name;
                    349:        cur->o_weight = things[whi].mi_wght;
                    350:        switch (whi) {
                    351:                case TYP_AMULET:
                    352:                        cur->o_type = AMULET;
                    353:                        cur->o_hplus = 500;
                    354:                        strcpy(cur->o_hurldmg,"80d8");  /* if thrown, WOW!!! */
                    355:                        cur->o_vol = itemvol(cur);
                    356:                when TYP_POTION:
                    357:                        cur->o_type = POTION;
                    358:                        cur->o_which = which;
                    359:                        cur->o_count += extras();
                    360:                        cur->o_vol = itemvol(cur);
                    361:                when TYP_SCROLL:
                    362:                        cur->o_type = SCROLL;
                    363:                        cur->o_which = which;
                    364:                        cur->o_count += extras();
                    365:                        cur->o_vol = itemvol(cur);
                    366:                when TYP_FOOD:
                    367:                        no_food = 0;
                    368:                        initfood(cur);
                    369:                when TYP_WEAPON:
                    370:                        cur->o_which = which;
                    371:                        init_weapon(cur, which);
                    372:                        if ((chance = rnd(100)) < 10) {
                    373:                                setoflg(cur,ISCURSED);
                    374:                                cur->o_hplus -= rnd(3)+1;
                    375:                                cur->o_dplus -= rnd(3)+1;
                    376:                        }
                    377:                        else if (chance < 15) {
                    378:                                cur->o_hplus += rnd(3)+1;
                    379:                                cur->o_dplus += rnd(3)+1;
                    380:                        }
                    381:                when TYP_ARMOR:
                    382:                        cur->o_which = which;
                    383:                        initarmor(cur, which);
                    384:                        if ((chance = rnd(100)) < 20) {
                    385:                                setoflg(cur,ISCURSED);
                    386:                                cur->o_ac += rnd(3)+1;
                    387:                        }
                    388:                        else if (chance < 30)
                    389:                                cur->o_ac -= rnd(3)+1;
                    390:                when TYP_RING:
                    391:                        cur->o_which = which;
                    392:                        init_ring(cur, FALSE);
                    393:                when TYP_STICK:
                    394:                default:
                    395:                        cur->o_which = which;
                    396:                        fix_stick(cur);
                    397:        }
                    398:        return item;
                    399: }
                    400:
                    401: /*
                    402:  * basic_init:
                    403:  *     Set all params of an object to the basic values.
                    404:  */
                    405: void
                    406: basic_init(struct object *cur)
                    407: {
                    408:        cur->o_ac = 11;
                    409:        cur->o_count = 1;
                    410:        cur->o_launch = 0;
                    411:        cur->o_typname = NULL;
                    412:        cur->o_group = newgrp();
                    413:        cur->o_weight = cur->o_vol = 0;
                    414:        cur->o_hplus = cur->o_dplus = 0;
                    415:        strcpy(cur->o_damage,"0d0");
                    416:        strcpy(cur->o_hurldmg,"0d0");
                    417:        cur->o_flags = cur->o_type = cur->o_which = 0;
                    418: }
                    419:
                    420: /*
                    421:  * extras:
                    422:  *     Return the number of extra items to be created
                    423:  */
                    424: int
                    425: extras(void)
                    426: {
                    427:        reg int i;
                    428:
                    429:        i = rnd(100);
                    430:        if (i < 4)                      /* 4% for 2 more */
                    431:                return 2;
                    432:        else if (i < 11)        /* 7% for 1 more */
                    433:                return 1;
                    434:        else                            /* otherwise no more */
                    435:                return 0;
                    436: }
                    437:
                    438:
                    439: /*
                    440:  * pick_one:
                    441:  *     Pick an item out of a list of nitems possible magic items
                    442:  */
                    443: int
                    444: pick_one(struct magic_item *mag)
                    445: {
                    446:        reg struct magic_item *start;
                    447:        reg int i;
                    448:
                    449:        start = mag;
                    450:        for (i = rnd(1000); mag->mi_name != NULL; mag++) {
                    451:                if (i < mag->mi_prob)
                    452:                        break;
                    453:                if (mag->mi_name == NULL) {
                    454:                        if (author() || wizard) {
                    455:                                for (mag = start; mag->mi_name != NULL; mag++)
                    456:                                        msg("%s: %d%%", mag->mi_name, mag->mi_prob);
                    457:                        }
                    458:                        mag = start;
                    459:                }
                    460:        }
                    461:        return mag - start;
                    462: }

CVSweb