Annotation of early-roguelike/srogue/trader.c, Revision 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