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