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