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