comparison xrogue/trader.c @ 133:e6179860cb76

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