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