comparison arogue7/trader.c @ 125:adfa37e67084

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