comparison srogue/trader.c @ 36:2128c7dc8a40

Import Super-Rogue 9.0 from the Roguelike Restoration Project (r1490)
author elwin
date Thu, 25 Nov 2010 12:21:41 +0000
parents
children 94a0d9dd5ce1
comparison
equal deleted inserted replaced
35:05018c63a721 36:2128c7dc8a40
1 /*
2 * Anything to do with trading posts & mazes
3 *
4 * @(#)trader.c 9.0 (rdk) 7/17/84
5 *
6 * Super-Rogue
7 * Copyright (C) 1984 Robert D. Kindelberger
8 * All rights reserved.
9 *
10 * See the file LICENSE.TXT for full copyright and licensing information.
11 */
12
13 #include <stdlib.h>
14 #include "rogue.h"
15 #include "rogue.ext"
16
17 #define NOTPRICED -1
18
19 /*
20 * do_post:
21 * Put a trading post room and stuff on the screen
22 */
23 do_post()
24 {
25 struct coord tp;
26 reg int i;
27 reg struct room *rp;
28 reg struct object *op;
29 reg struct linked_list *ll;
30
31 free_list(lvl_obj); /* throw old items away */
32
33 for (rp = rooms; rp < &rooms[MAXROOMS]; rp++) {
34 rp->r_goldval = 0; /* no gold */
35 rp->r_nexits = 0; /* no exits */
36 rp->r_flags = ISGONE; /* kill all rooms */
37 }
38 rp = &rooms[0]; /* point to only room */
39 rp->r_flags = 0; /* this room NOT gone */
40 rp->r_max.x = 40;
41 rp->r_max.y = 10; /* 10 * 40 room */
42 rp->r_pos.x = (COLS - rp->r_max.x) / 2; /* center horizontal */
43 rp->r_pos.y = 1; /* 2nd line */
44 draw_room(rp); /* draw the only room */
45 i = roll(4,10); /* 10 to 40 items */
46 for (; i > 0 ; i--) { /* place all the items */
47 ll = new_thing(FALSE, ANYTHING); /* get something */
48 attach(lvl_obj, ll);
49 op = OBJPTR(ll);
50 setoflg(op, ISPOST); /* object in trading post */
51 tp = *rnd_pos(rp);
52 op->o_pos = tp;
53 mvaddch(tp.y,tp.x,op->o_type);
54 }
55 trader = 0;
56 wmove(cw,12,0);
57 waddstr(cw,"Welcome to Friendly Fiend's Flea Market\n\r");
58 waddstr(cw,"=======================================\n\r");
59 waddstr(cw,"$: Prices object that you stand upon.\n\r");
60 waddstr(cw,"#: Buys the object that you stand upon.\n\r");
61 waddstr(cw,"%: Trades in something in your pack for gold.\n\r");
62 trans_line();
63 }
64
65 /*
66 * price_it:
67 * Price the object that the hero stands on
68 */
69 price_it()
70 {
71 static char *bargain[] = {
72 "great bargain",
73 "quality product",
74 "exceptional find",
75 };
76 reg struct linked_list *item;
77 reg struct object *obj;
78 reg int worth;
79
80 if (!open_market()) /* after buying hours */
81 return FALSE;
82 if ((item = find_obj(hero.y,hero.x)) == NULL)
83 return FALSE;
84 obj = OBJPTR(item);
85 if (curprice == NOTPRICED) {
86 worth = get_worth(obj);
87 worth += 50 - rnd(100);
88 if (worth < 25)
89 worth = 25;
90 worth *= 3; /* slightly expensive */
91 curprice = worth; /* save price */
92 strcpy(curpurch, obj->o_typname); /* save item */
93 }
94 msg("That %s is a %s for only %d pieces of gold", curpurch,
95 bargain[rnd(3)], curprice);
96 return TRUE;
97 }
98
99 /*
100 * buy_it:
101 * Buy the item on which the hero stands
102 */
103 buy_it()
104 {
105 reg int wh;
106
107 if (purse <= 0) {
108 msg("You have no money.");
109 return;
110 }
111 if (curprice < 0) { /* if not yet priced */
112 wh = price_it();
113 if (!wh) /* nothing to price */
114 return;
115 msg("Do you want to buy it? ");
116 do {
117 wh = readchar();
118 if (isupper(wh))
119 wh = tolower(wh);
120 if (wh == ESCAPE || wh == 'n') {
121 msg("");
122 return;
123 }
124 } until(wh == 'y');
125 }
126 mpos = 0;
127 if (curprice > purse) {
128 msg("You can't afford to buy that %s !",curpurch);
129 return;
130 }
131 /*
132 * See if the hero has done all his transacting
133 */
134 if (!open_market())
135 return;
136 /*
137 * The hero bought the item here
138 */
139 mpos = 0;
140 wh = add_pack(NULL,FALSE); /* try to put it in his pack */
141 if (wh) { /* he could get it */
142 purse -= curprice; /* take his money */
143 ++trader; /* another transaction */
144 trans_line(); /* show remaining deals */
145 curprice = NOTPRICED;
146 curpurch[0] = '\0';
147 }
148 }
149
150 /*
151 * sell_it:
152 * Sell an item to the trading post
153 */
154 sell_it()
155 {
156 reg struct linked_list *item;
157 reg struct object *obj;
158 reg int wo, ch;
159
160 if (!open_market()) /* after selling hours */
161 return;
162
163 if ((item = get_item("sell",0)) == NULL)
164 return;
165 obj = OBJPTR(item);
166 wo = get_worth(obj);
167 if (wo <= 0) {
168 mpos = 0;
169 msg("We don't buy those.");
170 return;
171 }
172 if (wo < 25)
173 wo = 25;
174 msg("Your %s is worth %d pieces of gold.", obj->o_typname, wo);
175 msg("Do you want to sell it? ");
176 do {
177 ch = readchar();
178 if (isupper(ch))
179 ch = tolower(ch);
180 if (ch == ESCAPE || ch == 'n') {
181 msg("");
182 return;
183 }
184 } until (ch == 'y');
185 mpos = 0;
186 if (drop(item) == TRUE) { /* drop this item */
187 nochange = FALSE; /* show gold value */
188 purse += wo; /* give him his money */
189 ++trader; /* another transaction */
190 wo = obj->o_count;
191 obj->o_count = 1;
192 msg("Sold %s",inv_name(obj,TRUE));
193 obj->o_count = wo;
194 trans_line(); /* show remaining deals */
195 }
196 }
197
198 /*
199 * open_market:
200 * Retruns TRUE when ok do to transacting
201 */
202 open_market()
203 {
204 if (trader >= MAXPURCH) {
205 msg("The market is closed. The stairs are that-a-way.");
206 return FALSE;
207 }
208 else
209 return TRUE;
210 }
211
212 /*
213 * get_worth:
214 * Calculate an objects worth in gold
215 */
216 get_worth(obj)
217 struct object *obj;
218 {
219 reg int worth, wh;
220
221 worth = 0;
222 wh = obj->o_which;
223 switch (obj->o_type) {
224 case FOOD:
225 worth = 2;
226 when WEAPON:
227 if (wh < MAXWEAPONS) {
228 worth = w_magic[wh].mi_worth;
229 worth *= (2 + (4 * obj->o_hplus + 4 * obj->o_dplus));
230 }
231 when ARMOR:
232 if (wh < MAXARMORS) {
233 worth = a_magic[wh].mi_worth;
234 worth *= (1 + (10 * (armors[wh].a_class - obj->o_ac)));
235 }
236 when SCROLL:
237 if (wh < MAXSCROLLS)
238 worth = s_magic[wh].mi_worth;
239 when POTION:
240 if (wh < MAXPOTIONS)
241 worth = p_magic[wh].mi_worth;
242 when RING:
243 if (wh < MAXRINGS) {
244 worth = r_magic[wh].mi_worth;
245 if (magring(obj)) {
246 if (obj->o_ac > 0)
247 worth += obj->o_ac * 40;
248 else
249 worth = 50;
250 }
251 }
252 when STICK:
253 if (wh < MAXSTICKS) {
254 worth = ws_magic[wh].mi_worth;
255 worth += 20 * obj->o_charges;
256 }
257 when AMULET:
258 worth = 1000;
259 otherwise:
260 worth = 0;
261 }
262 if (worth < 0)
263 worth = 0;
264 if (o_on(obj, ISPROT)) /* 300% more for protected */
265 worth *= 3;
266 if (o_on(obj, ISBLESS)) /* 50% more for blessed */
267 worth = worth * 3 / 2;
268 return worth;
269 }
270
271 /*
272 * trans_line:
273 * Show how many transactions the hero has left
274 */
275 trans_line()
276 {
277 sprintf(prbuf,"You have %d transactions remaining.",MAXPURCH-trader);
278 mvwaddstr(cw, LINES - 4, 0, prbuf);
279 }
280
281 /*
282 * domaze:
283 * Draw the maze on this level.
284 */
285 do_maze()
286 {
287 struct coord tp;
288 reg int i, least;
289 reg struct room *rp;
290 bool treas;
291
292 for (rp = rooms; rp < &rooms[MAXROOMS]; rp++) {
293 rp->r_goldval = 0;
294 rp->r_nexits = 0; /* no exits */
295 rp->r_flags = ISGONE; /* kill all rooms */
296 }
297 rp = &rooms[0]; /* point to only room */
298 rp->r_flags = ISDARK; /* mazes always dark */
299 rp->r_pos.x = 0; /* room fills whole screen */
300 rp->r_pos.y = 1;
301 rp->r_max.x = COLS - 1;
302 rp->r_max.y = LINES - 2;
303 rp->r_goldval = 500 + (rnd(10) + 1) * GOLDCALC;
304 draw_maze(); /* put maze into window */
305 rp->r_gold = *rnd_pos(rp);
306 mvaddch(rp->r_gold.y, rp->r_gold.x, GOLD);
307 if (rnd(100) < 3) { /* 3% for treasure maze level */
308 treas = TRUE;
309 least = 6;
310 rp->r_flags |= ISTREAS;
311 }
312 else { /* normal maze level */
313 least = 1;
314 treas = FALSE;
315 }
316 for (i = 0; i < level + least; i++)
317 if (treas || rnd(100) < 50) /* put in some little buggers */
318 add_mon(rp, treas);
319 }
320
321 struct cell {
322 char y_pos;
323 char x_pos;
324 };
325 struct bordercells {
326 char num_pos; /* number of frontier cells next to you */
327 struct cell conn[4]; /* the y,x position of above cell */
328 } mborder;
329
330 char *frontier, *bits;
331 char *moffset(), *foffset();
332 int tlines, tcols;
333
334 /*
335 * draw_maze:
336 * Generate and draw the maze on the screen
337 */
338 draw_maze()
339 {
340 reg int i, j, more;
341 reg char *ptr;
342
343 tlines = (LINES - 3) / 2;
344 tcols = (COLS - 1) / 2;
345 bits = ALLOC((LINES - 3) * (COLS - 1));
346 frontier = ALLOC(tlines * tcols);
347 ptr = frontier;
348 while (ptr < (frontier + (tlines * tcols)))
349 *ptr++ = TRUE;
350 for (i = 0; i < LINES - 3; i++) {
351 for (j = 0; j < COLS - 1; j++) {
352 if (i % 2 == 1 && j % 2 == 1)
353 *moffset(i, j) = FALSE; /* floor */
354 else
355 *moffset(i, j) = TRUE; /* wall */
356 }
357 }
358 for (i = 0; i < tlines; i++) {
359 for (j = 0; j < tcols; j++) {
360 do
361 more = findcells(i,j);
362 while(more != 0);
363 }
364 }
365 crankout();
366 FREE(frontier);
367 FREE(bits);
368 }
369
370 /*
371 * moffset:
372 * Calculate memory address for bits
373 */
374 char *
375 moffset(y, x)
376 int y, x;
377 {
378 char *ptr;
379
380 ptr = bits + (y * (COLS - 1)) + x;
381 return ptr;
382 }
383
384 /*
385 * foffset:
386 * Calculate memory address for frontier
387 */
388 char *
389 foffset(y, x)
390 int y, x;
391 {
392 char *ptr;
393
394 ptr = frontier + (y * tcols) + x;
395 return ptr;
396 }
397
398 /*
399 * findcells:
400 * Figure out cells to open up
401 */
402 findcells(y,x)
403 int x, y;
404 {
405 reg int rtpos, i;
406
407 *foffset(y, x) = FALSE;
408 mborder.num_pos = 0;
409 if (y < tlines - 1) { /* look below */
410 if (*foffset(y + 1, x)) {
411 mborder.conn[mborder.num_pos].y_pos = y + 1;
412 mborder.conn[mborder.num_pos].x_pos = x;
413 mborder.num_pos += 1;
414 }
415 }
416 if (y > 0) { /* look above */
417 if (*foffset(y - 1, x)) {
418 mborder.conn[mborder.num_pos].y_pos = y - 1;
419 mborder.conn[mborder.num_pos].x_pos = x;
420 mborder.num_pos += 1;
421
422 }
423 }
424 if (x < tcols - 1) { /* look right */
425 if (*foffset(y, x + 1)) {
426 mborder.conn[mborder.num_pos].y_pos = y;
427 mborder.conn[mborder.num_pos].x_pos = x + 1;
428 mborder.num_pos += 1;
429 }
430 }
431 if (x > 0) { /* look left */
432 if (*foffset(y, x - 1)) {
433 mborder.conn[mborder.num_pos].y_pos = y;
434 mborder.conn[mborder.num_pos].x_pos = x - 1;
435 mborder.num_pos += 1;
436
437 }
438 }
439 if (mborder.num_pos == 0) /* no neighbors available */
440 return 0;
441 else {
442 i = rnd(mborder.num_pos);
443 rtpos = mborder.num_pos - 1;
444 rmwall(mborder.conn[i].y_pos, mborder.conn[i].x_pos, y, x);
445 return rtpos;
446 }
447 }
448
449 /*
450 * rmwall:
451 * Removes appropriate walls from the maze
452 */
453 rmwall(newy, newx, oldy, oldx)
454 int newy, newx, oldy, oldx;
455 {
456 reg int xdif,ydif;
457
458 xdif = newx - oldx;
459 ydif = newy - oldy;
460
461 *moffset((oldy * 2) + ydif + 1, (oldx * 2) + xdif + 1) = FALSE;
462 findcells(newy, newx);
463 }
464
465
466 /*
467 * crankout:
468 * Does actual drawing of maze to window
469 */
470 crankout()
471 {
472 reg int x, y, i;
473
474 for (y = 0; y < LINES - 3; y++) {
475 move(y + 1, 0);
476 for (x = 0; x < COLS - 1; x++) {
477 if (*moffset(y, x)) { /* here is a wall */
478 if (y == 0 || y == LINES - 4) /* top or bottom line */
479 addch('-');
480 else if (x == 0 || x == COLS - 2) /* left | right side */
481 addch('|');
482 else if (y % 2 == 0 && x % 2 == 0) {
483 if (*moffset(y, x - 1) || *moffset(y, x + 1))
484 addch('-');
485 else
486 addch('|');
487 }
488 else if (y % 2 == 0)
489 addch('-');
490 else
491 addch('|');
492 }
493 else
494 addch(FLOOR);
495 }
496 }
497 }