Mercurial > hg > early-roguelike
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 |