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

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

1.1       rubenllo    1: /*
                      2:  * Anything to do with trading posts & mazes
                      3:  *
                      4:  * @(#)trader.c        9.0     (rdk)    7/17/84
                      5:  *
                      6:  * Super-Rogue
                      7:  * Copyright (C) 1984 Robert D. Kindelberger
                      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 <string.h>
                     15: #include "rogue.h"
                     16: #include "rogue.ext"
                     17:
                     18: #define NOTPRICED -1
                     19:
                     20: bool open_market(void);
                     21: void trans_line(void);
                     22: void draw_maze(void);
                     23: int findcells(int y, int x);
                     24: void rmwall(int newy, int newx, int oldy, int oldx);
                     25: void crankout(void);
                     26:
                     27: /*
                     28:  * do_post:
                     29:  *     Put a trading post room and stuff on the screen
                     30:  */
                     31: void
                     32: do_post(void)
                     33: {
                     34:        struct coord tp;
                     35:        reg int i;
                     36:        reg struct room *rp;
                     37:        reg struct object *op;
                     38:        reg struct linked_list *ll;
                     39:
                     40:        free_list(lvl_obj);             /* throw old items away */
                     41:
                     42:        for (rp = rooms; rp < &rooms[MAXROOMS]; rp++) {
                     43:                rp->r_goldval = 0;                      /* no gold */
                     44:                rp->r_nexits = 0;                       /* no exits */
                     45:                rp->r_flags = ISGONE;           /* kill all rooms */
                     46:        }
                     47:        rp = &rooms[0];                                 /* point to only room */
                     48:        rp->r_flags = 0;                                /* this room NOT gone */
                     49:        rp->r_max.x = 40;
                     50:        rp->r_max.y = 10;                               /* 10 * 40 room */
                     51:        rp->r_pos.x = (COLS - rp->r_max.x) / 2; /* center horizontal */
                     52:        rp->r_pos.y = 1;                                /* 2nd line */
                     53:        draw_room(rp);                                  /* draw the only room */
                     54:        i = roll(4,10);                                 /* 10 to 40 items */
                     55:        for (; i > 0 ; i--) {                   /* place all the items */
                     56:                ll = new_thing(FALSE, ANYTHING);                /* get something */
                     57:                attach(lvl_obj, ll);
                     58:                op = OBJPTR(ll);
                     59:                setoflg(op, ISPOST);            /* object in trading post */
                     60:                tp = *rnd_pos(rp);
                     61:                op->o_pos = tp;
                     62:                mvaddch(tp.y,tp.x,op->o_type);
                     63:        }
                     64:        trader = 0;
                     65:        wmove(cw,12,0);
                     66:        waddstr(cw,"Welcome to Friendly Fiend's Flea Market\n\r");
                     67:        waddstr(cw,"=======================================\n\r");
                     68:        waddstr(cw,"$: Prices object that you stand upon.\n\r");
                     69:        waddstr(cw,"#: Buys the object that you stand upon.\n\r");
                     70:        waddstr(cw,"%: Trades in something in your pack for gold.\n\r");
                     71:        trans_line();
                     72: }
                     73:
                     74: /*
                     75:  * price_it:
                     76:  *     Price the object that the hero stands on
                     77:  */
                     78: bool
                     79: price_it(void)
                     80: {
                     81:        static char *bargain[] = {
                     82:                "great bargain",
                     83:                "quality product",
                     84:                "exceptional find",
                     85:        };
                     86:        reg struct linked_list *item;
                     87:        reg struct object *obj;
                     88:        reg int worth;
                     89:
                     90:        if (!open_market())             /* after buying hours */
                     91:                return FALSE;
                     92:        if ((item = find_obj(hero.y,hero.x)) == NULL)
                     93:                return FALSE;
                     94:        obj = OBJPTR(item);
                     95:        if (curprice == NOTPRICED) {
                     96:                worth = get_worth(obj);
                     97:                worth += 50 - rnd(100);
                     98:                if (worth < 25)
                     99:                        worth = 25;
                    100:                worth *= 3;                                                     /* slightly expensive */
                    101:                curprice = worth;                                       /* save price */
                    102:                strcpy(curpurch, obj->o_typname);       /* save item */
                    103:        }
                    104:        msg("That %s is a %s for only %d pieces of gold", curpurch,
                    105:          bargain[rnd(3)], curprice);
                    106:        return TRUE;
                    107: }
                    108:
                    109: /*
                    110:  * buy_it:
                    111:  *     Buy the item on which the hero stands
                    112:  */
                    113: void
                    114: buy_it(void)
                    115: {
                    116:        reg int wh;
                    117:
                    118:        if (purse <= 0) {
                    119:                msg("You have no money.");
                    120:                return;
                    121:        }
                    122:        if (curprice < 0) {             /* if not yet priced */
                    123:                wh = price_it();
                    124:                if (!wh)                        /* nothing to price */
                    125:                        return;
                    126:                msg("Do you want to buy it? ");
                    127:                do {
                    128:                        wh = readchar();
                    129:                        if (isupper(wh))
                    130:                                wh = tolower(wh);
                    131:                        if (wh == ESCAPE || wh == 'n') {
                    132:                                msg("");
                    133:                                return;
                    134:                        }
                    135:                } until(wh == 'y');
                    136:        }
                    137:        mpos = 0;
                    138:        if (curprice > purse) {
                    139:                msg("You can't afford to buy that %s !",curpurch);
                    140:                return;
                    141:        }
                    142:        /*
                    143:         * See if the hero has done all his transacting
                    144:         */
                    145:        if (!open_market())
                    146:                return;
                    147:        /*
                    148:         * The hero bought the item here
                    149:         */
                    150:        mpos = 0;
                    151:        wh = add_pack(NULL,FALSE);      /* try to put it in his pack */
                    152:        if (wh) {                                       /* he could get it */
                    153:                purse -= curprice;              /* take his money */
                    154:                ++trader;                               /* another transaction */
                    155:                trans_line();                   /* show remaining deals */
                    156:                curprice = NOTPRICED;
                    157:                curpurch[0] = '\0';
                    158:        }
                    159: }
                    160:
                    161: /*
                    162:  * sell_it:
                    163:  *     Sell an item to the trading post
                    164:  */
                    165: void
                    166: sell_it(void)
                    167: {
                    168:        reg struct linked_list *item;
                    169:        reg struct object *obj;
                    170:        reg int wo, ch;
                    171:
                    172:        if (!open_market())             /* after selling hours */
                    173:                return;
                    174:
                    175:        if ((item = get_item("sell",0)) == NULL)
                    176:                return;
                    177:        obj = OBJPTR(item);
                    178:        wo = get_worth(obj);
                    179:        if (wo <= 0) {
                    180:                mpos = 0;
                    181:                msg("We don't buy those.");
                    182:                return;
                    183:        }
                    184:        if (wo < 25)
                    185:                wo = 25;
                    186:        msg("Your %s is worth %d pieces of gold.", obj->o_typname, wo);
                    187:        msg("Do you want to sell it? ");
                    188:        do {
                    189:                ch = readchar();
                    190:                if (isupper(ch))
                    191:                        ch = tolower(ch);
                    192:                if (ch == ESCAPE || ch == 'n') {
                    193:                        msg("");
                    194:                        return;
                    195:                }
                    196:        } until (ch == 'y');
                    197:        mpos = 0;
                    198:        if (drop(item) == TRUE) {               /* drop this item */
                    199:                nochange = FALSE;               /* show gold value */
                    200:                purse += wo;                    /* give him his money */
                    201:                ++trader;                       /* another transaction */
                    202:                wo = obj->o_count;
                    203:                obj->o_count = 1;
                    204:                msg("Sold %s",inv_name(obj,TRUE));
                    205:                obj->o_count = wo;
                    206:                trans_line();                   /* show remaining deals */
                    207:        }
                    208: }
                    209:
                    210: /*
                    211:  * open_market:
                    212:  *     Retruns TRUE when ok do to transacting
                    213:  */
                    214: bool
                    215: open_market(void)
                    216: {
                    217:        if (trader >= MAXPURCH) {
                    218:                msg("The market is closed. The stairs are that-a-way.");
                    219:                return FALSE;
                    220:        }
                    221:        else
                    222:                return TRUE;
                    223: }
                    224:
                    225: /*
                    226:  * get_worth:
                    227:  *     Calculate an objects worth in gold
                    228:  */
                    229: int
                    230: get_worth(struct object *obj)
                    231: {
                    232:        reg int worth, wh;
                    233:
                    234:        worth = 0;
                    235:        wh = obj->o_which;
                    236:        switch (obj->o_type) {
                    237:        case FOOD:
                    238:                worth = 2;
                    239:        when WEAPON:
                    240:                if (wh < MAXWEAPONS) {
                    241:                        worth = w_magic[wh].mi_worth;
                    242:                        worth *= (2 + (4 * obj->o_hplus + 4 * obj->o_dplus));
                    243:                }
                    244:        when ARMOR:
                    245:                if (wh < MAXARMORS) {
                    246:                        worth = a_magic[wh].mi_worth;
                    247:                        worth *= (1 + (10 * (armors[wh].a_class - obj->o_ac)));
                    248:                }
                    249:        when SCROLL:
                    250:                if (wh < MAXSCROLLS)
                    251:                        worth = s_magic[wh].mi_worth;
                    252:        when POTION:
                    253:                if (wh < MAXPOTIONS)
                    254:                        worth = p_magic[wh].mi_worth;
                    255:        when RING:
                    256:                if (wh < MAXRINGS) {
                    257:                        worth = r_magic[wh].mi_worth;
                    258:                        if (magring(obj)) {
                    259:                                if (obj->o_ac > 0)
                    260:                                        worth += obj->o_ac * 40;
                    261:                                else
                    262:                                        worth = 50;
                    263:                        }
                    264:                }
                    265:        when STICK:
                    266:                if (wh < MAXSTICKS) {
                    267:                        worth = ws_magic[wh].mi_worth;
                    268:                        worth += 20 * obj->o_charges;
                    269:                }
                    270:        when AMULET:
                    271:                worth = 1000;
                    272:        otherwise:
                    273:                worth = 0;
                    274:        }
                    275:        if (worth < 0)
                    276:                worth = 0;
                    277:        if (o_on(obj, ISPROT))          /* 300% more for protected */
                    278:                worth *= 3;
                    279:        if (o_on(obj, ISBLESS))         /* 50% more for blessed */
                    280:                worth = worth * 3 / 2;
                    281:        return worth;
                    282: }
                    283:
                    284: /*
                    285:  * trans_line:
                    286:  *     Show how many transactions the hero has left
                    287:  */
                    288: void
                    289: trans_line(void)
                    290: {
                    291:        sprintf(prbuf,"You have %d transactions remaining.",MAXPURCH-trader);
                    292:        mvwaddstr(cw, LINES - 4, 0, prbuf);
                    293: }
                    294:
                    295: /*
                    296:  * domaze:
                    297:  *     Draw the maze on this level.
                    298:  */
                    299: void
                    300: do_maze(void)
                    301: {
                    302:        struct coord tp;
                    303:        reg int i, least;
                    304:        reg struct room *rp;
                    305:        bool treas;
                    306:
                    307:        for (rp = rooms; rp < &rooms[MAXROOMS]; rp++) {
                    308:                rp->r_goldval = 0;
                    309:                rp->r_nexits = 0;                       /* no exits */
                    310:                rp->r_flags = ISGONE;           /* kill all rooms */
                    311:        }
                    312:        rp = &rooms[0];                                 /* point to only room */
                    313:        rp->r_flags = ISDARK;                   /* mazes always dark */
                    314:        rp->r_pos.x = 0;                                /* room fills whole screen */
                    315:        rp->r_pos.y = 1;
                    316:        rp->r_max.x = COLS - 1;
                    317:        rp->r_max.y = LINES - 2;
                    318:        rp->r_goldval = 500 + (rnd(10) + 1) * GOLDCALC;
                    319:        draw_maze();                            /* put maze into window */
                    320:        rp->r_gold = *rnd_pos(rp);
                    321:        mvaddch(rp->r_gold.y, rp->r_gold.x, GOLD);
                    322:        if (rnd(100) < 3) {                     /* 3% for treasure maze level */
                    323:                treas = TRUE;
                    324:                least = 6;
                    325:                rp->r_flags |= ISTREAS;
                    326:        }
                    327:        else {                                          /* normal maze level */
                    328:                least = 1;
                    329:                treas = FALSE;
                    330:        }
                    331:        for (i = 0; i < level + least; i++)
                    332:                if (treas || rnd(100) < 50)             /* put in some little buggers */
                    333:                        add_mon(rp, treas);
                    334: }
                    335:
                    336: struct cell {
                    337:        char y_pos;
                    338:        char x_pos;
                    339: };
                    340: struct bordercells {
                    341:        unsigned char num_pos;  /* number of frontier cells next to you */
                    342:        struct cell conn[4];    /* the y,x position of above cell */
                    343: } mborder;
                    344:
                    345: char *frontier, *bits;
                    346: char *moffset(int y, int x);
                    347: char *foffset(int y, int x);
                    348: int tlines, tcols;
                    349:
                    350: /*
                    351:  * draw_maze:
                    352:  *     Generate and draw the maze on the screen
                    353:  */
                    354: void
                    355: draw_maze(void)
                    356: {
                    357:        reg int i, j, more;
                    358:        reg char *ptr;
                    359:
                    360:        tlines = (LINES - 3) / 2;
                    361:        tcols = (COLS - 1) / 2;
                    362:        bits = ALLOC((LINES - 3) * (COLS - 1));
                    363:        frontier = ALLOC(tlines * tcols);
                    364:        ptr = frontier;
                    365:        while (ptr < (frontier + (tlines * tcols)))
                    366:                *ptr++ = TRUE;
                    367:        for (i = 0; i < LINES - 3; i++) {
                    368:                for (j = 0; j < COLS - 1; j++) {
                    369:                        if (i % 2 == 1 && j % 2 == 1)
                    370:                                *moffset(i, j) = FALSE;         /* floor */
                    371:                        else
                    372:                                *moffset(i, j) = TRUE;          /* wall */
                    373:                }
                    374:        }
                    375:        for (i = 0; i < tlines; i++) {
                    376:                for (j = 0; j < tcols; j++) {
                    377:                        do
                    378:                                more = findcells(i,j);
                    379:                        while(more != 0);
                    380:                }
                    381:        }
                    382:        crankout();
                    383:        FREE(frontier);
                    384:        FREE(bits);
                    385: }
                    386:
                    387: /*
                    388:  * moffset:
                    389:  *     Calculate memory address for bits
                    390:  */
                    391: char *
                    392: moffset(int y, int x)
                    393: {
                    394:        char *ptr;
                    395:
                    396:        ptr = bits + (y * (COLS - 1)) + x;
                    397:        return ptr;
                    398: }
                    399:
                    400: /*
                    401:  * foffset:
                    402:  *     Calculate memory address for frontier
                    403:  */
                    404: char *
                    405: foffset(int y, int x)
                    406: {
                    407:        char *ptr;
                    408:
                    409:        ptr = frontier + (y * tcols) + x;
                    410:        return ptr;
                    411: }
                    412:
                    413: /*
                    414:  * findcells:
                    415:  *     Figure out cells to open up
                    416:  */
                    417: int
                    418: findcells(int y, int x)
                    419: {
                    420:        reg int rtpos, i;
                    421:
                    422:        *foffset(y, x) = FALSE;
                    423:        mborder.num_pos = 0;
                    424:        if (y < tlines - 1) {                           /* look below */
                    425:                if (*foffset(y + 1, x)) {
                    426:                        mborder.conn[mborder.num_pos].y_pos = y + 1;
                    427:                        mborder.conn[mborder.num_pos].x_pos = x;
                    428:                        mborder.num_pos += 1;
                    429:                }
                    430:        }
                    431:        if (y > 0) {                                            /* look above */
                    432:                if (*foffset(y - 1, x)) {
                    433:                        mborder.conn[mborder.num_pos].y_pos = y - 1;
                    434:                        mborder.conn[mborder.num_pos].x_pos = x;
                    435:                        mborder.num_pos += 1;
                    436:
                    437:                }
                    438:        }
                    439:        if (x < tcols - 1) {                                    /* look right */
                    440:                if (*foffset(y, x + 1)) {
                    441:                        mborder.conn[mborder.num_pos].y_pos = y;
                    442:                        mborder.conn[mborder.num_pos].x_pos = x + 1;
                    443:                        mborder.num_pos += 1;
                    444:                }
                    445:        }
                    446:        if (x > 0) {                                            /* look left */
                    447:                if (*foffset(y, x - 1)) {
                    448:                        mborder.conn[mborder.num_pos].y_pos = y;
                    449:                        mborder.conn[mborder.num_pos].x_pos = x - 1;
                    450:                        mborder.num_pos += 1;
                    451:
                    452:                }
                    453:        }
                    454:        if (mborder.num_pos == 0)                       /* no neighbors available */
                    455:                return 0;
                    456:        else {
                    457:                i = rnd(mborder.num_pos);
                    458:                rtpos = mborder.num_pos - 1;
                    459:                rmwall(mborder.conn[i].y_pos, mborder.conn[i].x_pos, y, x);
                    460:                return rtpos;
                    461:        }
                    462: }
                    463:
                    464: /*
                    465:  * rmwall:
                    466:  *     Removes appropriate walls from the maze
                    467:  */
                    468: void
                    469: rmwall(int newy, int newx, int oldy, int oldx)
                    470: {
                    471:        reg int xdif,ydif;
                    472:
                    473:        xdif = newx - oldx;
                    474:        ydif = newy - oldy;
                    475:
                    476:        *moffset((oldy * 2) + ydif + 1, (oldx * 2) + xdif + 1) = FALSE;
                    477:        findcells(newy, newx);
                    478: }
                    479:
                    480:
                    481: /*
                    482:  * crankout:
                    483:  *     Does actual drawing of maze to window
                    484:  */
                    485: void
                    486: crankout(void)
                    487: {
                    488:        reg int x, y, i;
                    489:
                    490:        for (y = 0; y < LINES - 3; y++) {
                    491:                move(y + 1, 0);
                    492:                for (x = 0; x < COLS - 1; x++) {
                    493:                        if (*moffset(y, x)) {                           /* here is a wall */
                    494:                                if (y == 0 || y == LINES - 4)   /* top or bottom line */
                    495:                                        addch('-');
                    496:                                else if (x == 0 || x == COLS - 2)       /* left | right side */
                    497:                                        addch('|');
                    498:                                else if (y % 2 == 0 && x % 2 == 0) {
                    499:                                        if (*moffset(y, x - 1) || *moffset(y, x + 1))
                    500:                                                addch('-');
                    501:                                        else
                    502:                                                addch('|');
                    503:                                }
                    504:                                else if (y % 2 == 0)
                    505:                                        addch('-');
                    506:                                else
                    507:                                        addch('|');
                    508:                        }
                    509:                        else
                    510:                                addch(FLOOR);
                    511:                }
                    512:        }
                    513: }

CVSweb