Annotation of early-roguelike/arogue7/trader.c, Revision 1.1
1.1 ! rubenllo 1: /*
! 2: * trader.c - Anything to do with trading posts
! 3: *
! 4: * Advanced Rogue
! 5: * Copyright (C) 1984, 1985, 1986 Michael Morgan, Ken Dalka and AT&T
! 6: * All rights reserved.
! 7: *
! 8: * Based on "Rogue: Exploring the Dungeons of Doom"
! 9: * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
! 10: * All rights reserved.
! 11: *
! 12: * See the file LICENSE.TXT for full copyright and licensing information.
! 13: */
! 14:
! 15: /*
! 16: * Anything to do with trading posts
! 17: */
! 18:
! 19: #include <ctype.h>
! 20: #include <string.h>
! 21: #include "curses.h"
! 22: #include "rogue.h"
! 23:
! 24: bool open_market(void);
! 25: void trans_line(void);
! 26: char *typ_name(struct object *obj);
! 27:
! 28:
! 29: /*
! 30: * buy_it:
! 31: * Buy the item on which the hero stands
! 32: */
! 33: void
! 34: buy_it(void)
! 35: {
! 36: reg int wh;
! 37: struct linked_list *item;
! 38:
! 39: if (purse <= 0) {
! 40: msg("You have no money.");
! 41: return;
! 42: }
! 43: if (curprice < 0) { /* if not yet priced */
! 44: wh = price_it();
! 45: if (!wh) /* nothing to price */
! 46: return;
! 47: msg("Do you want to buy it? ");
! 48: do {
! 49: wh = tolower(readchar());
! 50: if (wh == ESCAPE || wh == 'n') {
! 51: msg("");
! 52: return;
! 53: }
! 54: } until(wh == 'y');
! 55: }
! 56: mpos = 0;
! 57: if (curprice > purse) {
! 58: msg("You can't afford to buy that %s !",curpurch);
! 59: return;
! 60: }
! 61: /*
! 62: * See if the hero has done all his transacting
! 63: */
! 64: if (!open_market())
! 65: return;
! 66: /*
! 67: * The hero bought the item here
! 68: */
! 69: item = find_obj(hero.y, hero.x);
! 70: mpos = 0;
! 71: if (add_pack(NULL, TRUE, &item)) { /* try to put it in his pack */
! 72: purse -= curprice; /* take his money */
! 73: ++trader; /* another transaction */
! 74: trans_line(); /* show remaining deals */
! 75: curprice = -1; /* reset stuff */
! 76: curpurch[0] = 0;
! 77: whatis (item); /* identify it after purchase */
! 78: (OBJPTR(item))->o_flags &= ~ISPOST; /* turn off ISPOST */
! 79: msg("%s", inv_name(OBJPTR(item), TRUE));
! 80: }
! 81: }
! 82:
! 83: /*
! 84: * do_post:
! 85: * Put a trading post room and stuff on the screen
! 86: * startup: True if equipping the player at the beginning of the game
! 87: */
! 88: void
! 89: do_post(bool startup)
! 90: {
! 91: coord tp;
! 92: reg int i, j, k;
! 93: reg struct room *rp;
! 94: reg struct object *op;
! 95: reg struct linked_list *ll;
! 96:
! 97: o_free_list(lvl_obj); /* throw old items away */
! 98:
! 99: for (rp = rooms; rp < &rooms[MAXROOMS]; rp++)
! 100: rp->r_flags = ISGONE; /* kill all rooms */
! 101:
! 102: rp = &rooms[0]; /* point to only room */
! 103: rp->r_flags = 0; /* this room NOT gone */
! 104: rp->r_max.x = 40;
! 105: rp->r_max.y = 10; /* 10 * 40 room */
! 106: rp->r_pos.x = (cols - rp->r_max.x) / 2; /* center horizontal */
! 107: rp->r_pos.y = 1; /* 2nd line */
! 108: draw_room(rp); /* draw the only room */
! 109:
! 110: /* Are we equipping the player? */
! 111: if (startup) {
! 112: int wpt;
! 113:
! 114: /*
! 115: * Give the rogue some weaponry.
! 116: */
! 117: for (wpt=0; wpt<MAXWEAPONS; wpt++) {
! 118: ll = spec_item(WEAPON, wpt, rnd(2), rnd(2)+1);
! 119: attach(lvl_obj, ll);
! 120: op = OBJPTR(ll);
! 121: op->o_flags |= (ISPOST | ISKNOW);
! 122: do {
! 123: rnd_pos(rp,&tp);
! 124: } until (mvinch(tp.y, tp.x) == FLOOR);
! 125: op->o_pos = tp;
! 126: mvaddch(tp.y,tp.x,op->o_type);
! 127: }
! 128:
! 129: /*
! 130: * And his suit of armor.......
! 131: * Thieves can only wear leather armor,
! 132: * so make sure some is available for them.
! 133: */
! 134: for (i=0; i<MAXARMORS; i++) {
! 135: ll = spec_item(ARMOR, i, 0, 0);
! 136: attach(lvl_obj, ll);
! 137: op = OBJPTR(ll);
! 138: op->o_flags |= (ISPOST | ISKNOW);
! 139: op->o_weight = armors[i].a_wght;
! 140: do {
! 141: rnd_pos(rp,&tp);
! 142: } until (mvinch(tp.y, tp.x) == FLOOR);
! 143: op->o_pos = tp;
! 144: mvaddch(tp.y,tp.x,op->o_type);
! 145: }
! 146:
! 147: /* Now create some wands */
! 148: for (i=rnd(4)+2; i>0; i--) {
! 149: switch (rnd(8)) {
! 150: case 0: j = WS_SLOW_M;
! 151: when 1: j = WS_TELMON;
! 152: when 2: j = WS_CONFMON;
! 153: when 3: j = WS_PARALYZE;
! 154: when 4: j = WS_MDEG;
! 155: when 5: j = WS_WONDER;
! 156: when 6: j = WS_FEAR;
! 157: when 7: j = WS_LIGHT;
! 158: }
! 159: ll = spec_item(STICK, j, 0, 0);
! 160: attach(lvl_obj, ll);
! 161: op = OBJPTR(ll);
! 162:
! 163: /* Let clerics and MU'S know what kind they are */
! 164: switch (player.t_ctype) {
! 165: case C_MAGICIAN:
! 166: case C_CLERIC:
! 167: case C_DRUID:
! 168: op->o_flags |= (ISPOST | ISKNOW);
! 169: otherwise:
! 170: op->o_flags |= ISPOST;
! 171: }
! 172: fix_stick(op);
! 173: do {
! 174: rnd_pos(rp,&tp);
! 175: } until (mvinch(tp.y, tp.x) == FLOOR);
! 176: op->o_pos = tp;
! 177: mvaddch(tp.y,tp.x,op->o_type);
! 178: }
! 179:
! 180: /* Now let's make some rings */
! 181: for (i=rnd(4)+3; i>0; i--) {
! 182: k = 0;
! 183: switch (rnd(15)) {
! 184: case 0: j = R_PROTECT; k = roll(1,2);
! 185: when 1: j = R_ADDSTR; k = roll(1,3);
! 186: when 2: j = R_ADDHIT; k = roll(1,3);
! 187: when 3: j = R_ADDDAM; k = roll(1,3);
! 188: when 4: j = R_DIGEST; k = 1;
! 189: when 5: j = R_ADDINTEL; k = roll(1,3);
! 190: when 6: j = R_ADDWISDOM;k = roll(1,3);
! 191: when 7: j = R_SUSABILITY;
! 192: when 8: j = R_SEEINVIS;
! 193: when 9: j = R_ALERT;
! 194: when 10:j = R_HEALTH;
! 195: when 11:j = R_HEROISM;
! 196: when 12:j = R_FIRE;
! 197: when 13:j = R_WARMTH;
! 198: when 14:j = R_FREEDOM;
! 199: }
! 200: ll = spec_item(RING, j, k, 0);
! 201: attach(lvl_obj, ll);
! 202: op = OBJPTR(ll);
! 203:
! 204: /*
! 205: * Let fighters, assassins, monks, and thieves know what kind
! 206: * of rings these are.
! 207: */
! 208: switch (player.t_ctype) {
! 209: case C_FIGHTER:
! 210: case C_THIEF:
! 211: case C_ASSASIN:
! 212: case C_MONK:
! 213: op->o_flags |= (ISPOST | ISKNOW);
! 214: otherwise:
! 215: op->o_flags |= ISPOST;
! 216: }
! 217: do {
! 218: rnd_pos(rp,&tp);
! 219: } until (mvinch(tp.y, tp.x) == FLOOR);
! 220: op->o_pos = tp;
! 221: mvaddch(tp.y,tp.x,op->o_type);
! 222: }
! 223:
! 224: /* Let's offer some potions */
! 225: for (i=rnd(3)+1; i>0; i--) {
! 226: /* Choose the type of potion */
! 227: if (i == 1 && player.t_ctype == C_ASSASIN) j = P_POISON;
! 228: else switch (rnd(8)) {
! 229: case 0: j = P_CLEAR;
! 230: when 1: j = P_HEALING;
! 231: when 2: j = P_MFIND;
! 232: when 3: j = P_TFIND;
! 233: when 4: j = P_HASTE;
! 234: when 5: j = P_RESTORE;
! 235: when 6: j = P_FLY;
! 236: when 7: j = P_FFIND;
! 237: }
! 238:
! 239: /* Make the potion */
! 240: ll = spec_item(POTION, j, 0, 0);
! 241: attach(lvl_obj, ll);
! 242: op = OBJPTR(ll);
! 243: op->o_flags |= ISPOST;
! 244:
! 245: /* Place the potion */
! 246: do {
! 247: rnd_pos(rp,&tp);
! 248: } until (mvinch(tp.y, tp.x) == FLOOR);
! 249: op->o_pos = tp;
! 250: mvaddch(tp.y,tp.x,op->o_type);
! 251: }
! 252:
! 253: /* Let's offer some scrolls */
! 254: for (i=rnd(3)+1; i>0; i--) {
! 255: /* Choose the type of scrolls */
! 256: switch (rnd(8)) {
! 257: case 0: j = S_CONFUSE;
! 258: when 1: j = S_MAP;
! 259: when 2: j = S_LIGHT;
! 260: when 3: j = S_SLEEP;
! 261: when 4: j = S_IDENT;
! 262: when 5: j = S_GFIND;
! 263: when 6: j = S_REMOVE;
! 264: when 7: j = S_CURING;
! 265: }
! 266:
! 267: /* Make the scroll */
! 268: ll = spec_item(SCROLL, j, 0, 0);
! 269: attach(lvl_obj, ll);
! 270: op = OBJPTR(ll);
! 271: op->o_flags |= ISPOST;
! 272:
! 273: /* Place the scroll */
! 274: do {
! 275: rnd_pos(rp,&tp);
! 276: } until (mvinch(tp.y, tp.x) == FLOOR);
! 277: op->o_pos = tp;
! 278: mvaddch(tp.y,tp.x,op->o_type);
! 279: }
! 280:
! 281: /* And finally, let's get some food */
! 282: for (i=rnd(3)+1; i>0; i--) {
! 283: ll = spec_item(FOOD, 0, 0, 0);
! 284: attach(lvl_obj, ll);
! 285: op = OBJPTR(ll);
! 286: op->o_weight = things[TYP_FOOD].mi_wght;
! 287: op->o_flags |= ISPOST;
! 288: do {
! 289: rnd_pos(rp,&tp);
! 290: } until (mvinch(tp.y, tp.x) == FLOOR);
! 291: op->o_pos = tp;
! 292: mvaddch(tp.y,tp.x,op->o_type);
! 293: }
! 294: }
! 295: else {
! 296: i = roll(10, 4); /* 10 to 40 items */
! 297: for (; i > 0 ; i--) { /* place all the items */
! 298: ll = new_thing(ALL, TRUE); /* get something */
! 299: attach(lvl_obj, ll);
! 300: op = OBJPTR(ll);
! 301: op->o_flags |= ISPOST; /* object in trading post */
! 302: do {
! 303: rnd_pos(rp,&tp);
! 304: } until (mvinch(tp.y, tp.x) == FLOOR);
! 305: op->o_pos = tp;
! 306: mvaddch(tp.y,tp.x,op->o_type);
! 307: }
! 308: }
! 309: wmove(cw,12,0);
! 310: trader = 0;
! 311: if (startup) {
! 312: waddstr(cw,"Welcome to Friendly Fiend's Equipage\n\r");
! 313: waddstr(cw,"====================================\n\r");
! 314: }
! 315: else {
! 316: waddstr(cw,"Welcome to Friendly Fiend's Flea Market\n\r");
! 317: waddstr(cw,"=======================================\n\r");
! 318: }
! 319: waddstr(cw,"$: Prices object that you stand upon.\n\r");
! 320: waddstr(cw,"#: Buys the object that you stand upon.\n\r");
! 321: waddstr(cw,"%: Trades in something in your pack for gold.\n\r");
! 322: trans_line();
! 323: }
! 324:
! 325:
! 326: /*
! 327: * get_worth:
! 328: * Calculate an objects worth in gold
! 329: */
! 330: int
! 331: get_worth(struct object *obj)
! 332: {
! 333: reg int worth, wh;
! 334:
! 335: worth = 0;
! 336: wh = obj->o_which;
! 337: switch (obj->o_type) {
! 338: case FOOD:
! 339: worth = 2;
! 340: when WEAPON:
! 341: if (wh < MAXWEAPONS) {
! 342: worth = weaps[wh].w_worth;
! 343: worth += s_magic[S_ALLENCH].mi_worth *
! 344: (obj->o_hplus + obj->o_dplus);
! 345: }
! 346: when ARMOR:
! 347: if (wh < MAXARMORS) {
! 348: worth = armors[wh].a_worth;
! 349: worth += s_magic[S_ALLENCH].mi_worth *
! 350: (armors[wh].a_class - obj->o_ac);
! 351: }
! 352: when SCROLL:
! 353: if (wh < MAXSCROLLS)
! 354: worth = s_magic[wh].mi_worth;
! 355: when POTION:
! 356: if (wh < MAXPOTIONS)
! 357: worth = p_magic[wh].mi_worth;
! 358: when RING:
! 359: if (wh < MAXRINGS) {
! 360: worth = r_magic[wh].mi_worth;
! 361: worth += obj->o_ac * 40;
! 362: }
! 363: when STICK:
! 364: if (wh < MAXSTICKS) {
! 365: worth = ws_magic[wh].mi_worth;
! 366: worth += 20 * obj->o_charges;
! 367: }
! 368: when MM:
! 369: if (wh < MAXMM) {
! 370: worth = m_magic[wh].mi_worth;
! 371: switch (wh) {
! 372: case MM_BRACERS: worth += 40 * obj->o_ac;
! 373: when MM_PROTECT: worth += 60 * obj->o_ac;
! 374: when MM_DISP: /* ac already figured in price*/
! 375: otherwise: worth += 20 * obj->o_ac;
! 376: }
! 377: }
! 378: when RELIC:
! 379: if (wh < MAXRELIC) {
! 380: worth = rel_magic[wh].mi_worth;
! 381: if (wh == quest_item) worth *= 10;
! 382: }
! 383: otherwise:
! 384: worth = 0;
! 385: }
! 386: if (obj->o_flags & ISPROT) /* 300% more for protected */
! 387: worth *= 3;
! 388: if (obj->o_flags & ISBLESSED) /* 50% more for blessed */
! 389: worth = worth * 3 / 2;
! 390: if (obj->o_flags & ISCURSED) /* half for cursed */
! 391: worth /= 2;
! 392: if (worth < 0)
! 393: worth = 0;
! 394: return worth;
! 395: }
! 396:
! 397: /*
! 398: * open_market:
! 399: * Retruns TRUE when ok do to transacting
! 400: */
! 401: bool
! 402: open_market(void)
! 403: {
! 404: if (trader >= MAXPURCH && !wizard && level != 0) {
! 405: msg("The market is closed. The stairs are that-a-way.");
! 406: return FALSE;
! 407: }
! 408: else {
! 409: return TRUE;
! 410: }
! 411: }
! 412:
! 413: /*
! 414: * price_it:
! 415: * Price the object that the hero stands on
! 416: */
! 417: bool
! 418: price_it(void)
! 419: {
! 420: reg struct linked_list *item;
! 421: reg struct object *obj;
! 422: reg int worth;
! 423: reg char *str;
! 424:
! 425: if (!open_market()) /* after buying hours */
! 426: return FALSE;
! 427: if ((item = find_obj(hero.y,hero.x)) == NULL) {
! 428: debug("Can't find the item");
! 429: return FALSE;
! 430: }
! 431: obj = OBJPTR(item);
! 432: worth = get_worth(obj);
! 433: if (worth < 0) {
! 434: msg("That's not for sale.");
! 435: return FALSE;
! 436: }
! 437: if (worth < 25)
! 438: worth = 25;
! 439:
! 440: /* Our shopkeeper is affected by the person's charisma */
! 441: worth = (int) ((float) worth * (17. / (float)pstats.s_charisma));
! 442: str = inv_name(obj, TRUE);
! 443: msg("%s for only %d pieces of gold", str, worth);
! 444: curprice = worth; /* save price */
! 445: strcpy(curpurch,str); /* save item */
! 446: return TRUE;
! 447: }
! 448:
! 449:
! 450:
! 451: /*
! 452: * sell_it:
! 453: * Sell an item to the trading post
! 454: */
! 455: void
! 456: sell_it(void)
! 457: {
! 458: reg struct linked_list *item;
! 459: reg struct object *obj;
! 460: reg int wo, ch;
! 461:
! 462: if (!open_market()) /* after selling hours */
! 463: return;
! 464:
! 465: if ((item = get_item(pack, "sell", ALL, FALSE, FALSE)) == NULL)
! 466: return;
! 467: obj = OBJPTR(item);
! 468: wo = get_worth(obj);
! 469: if (wo <= 0) {
! 470: mpos = 0;
! 471: msg("We don't buy those.");
! 472: return;
! 473: }
! 474: if (wo < 25)
! 475: wo = 25;
! 476: msg("Your %s is worth %d pieces of gold.",typ_name(obj),wo);
! 477: msg("Do you want to sell it? ");
! 478: do {
! 479: ch = tolower(readchar());
! 480: if (ch == ESCAPE || ch == 'n') {
! 481: msg("");
! 482: return;
! 483: }
! 484: } until (ch == 'y');
! 485: mpos = 0;
! 486: if (drop(item) == TRUE) { /* drop this item */
! 487: purse += wo; /* give him his money */
! 488: ++trader; /* another transaction */
! 489: wo = obj->o_count;
! 490: if (obj->o_group == 0) /* dropped one at a time */
! 491: obj->o_count = 1;
! 492: msg("Sold %s",inv_name(obj,TRUE));
! 493: obj->o_count = wo;
! 494: trans_line(); /* show remaining deals */
! 495: }
! 496: }
! 497:
! 498: /*
! 499: * trans_line:
! 500: * Show how many transactions the hero has left
! 501: */
! 502: void
! 503: trans_line(void)
! 504: {
! 505: if (level == 0)
! 506: sprintf(prbuf, "You are welcome to spend whatever you have.");
! 507: else if (!wizard)
! 508: sprintf(prbuf,"You have %d transactions remaining.",
! 509: MAXPURCH - trader);
! 510: else
! 511: sprintf(prbuf,
! 512: "You have infinite transactions remaining oh great wizard.");
! 513: mvwaddstr(cw,lines - 3,0,prbuf);
! 514: }
! 515:
! 516:
! 517:
! 518: /*
! 519: * typ_name:
! 520: * Return the name for this type of object
! 521: */
! 522: char *
! 523: typ_name(struct object *obj)
! 524: {
! 525: static char buff[20];
! 526: reg int wh;
! 527:
! 528: switch (obj->o_type) {
! 529: case POTION: wh = TYP_POTION;
! 530: when SCROLL: wh = TYP_SCROLL;
! 531: when STICK: wh = TYP_STICK;
! 532: when RING: wh = TYP_RING;
! 533: when ARMOR: wh = TYP_ARMOR;
! 534: when WEAPON: wh = TYP_WEAPON;
! 535: when MM: wh = TYP_MM;
! 536: when FOOD: wh = TYP_FOOD;
! 537: when RELIC: wh = TYP_RELIC;
! 538: otherwise: wh = -1;
! 539: }
! 540: if (wh < 0)
! 541: strcpy(buff,"unknown");
! 542: else
! 543: strcpy(buff,things[wh].mi_name);
! 544: return (buff);
! 545: }
! 546:
! 547:
CVSweb