/* * Anything to do with trading posts & mazes * * @(#)trader.c 9.0 (rdk) 7/17/84 * * Super-Rogue * Copyright (C) 1984 Robert D. Kindelberger * All rights reserved. * * See the file LICENSE.TXT for full copyright and licensing information. */ #include #include #include "rogue.h" #include "rogue.ext" #define NOTPRICED -1 bool open_market(void); void trans_line(void); void draw_maze(void); int findcells(int y, int x); void rmwall(int newy, int newx, int oldy, int oldx); void crankout(void); /* * do_post: * Put a trading post room and stuff on the screen */ void do_post(void) { struct coord tp; reg int i; reg struct room *rp; reg struct object *op; reg struct linked_list *ll; free_list(lvl_obj); /* throw old items away */ for (rp = rooms; rp < &rooms[MAXROOMS]; rp++) { rp->r_goldval = 0; /* no gold */ rp->r_nexits = 0; /* no exits */ rp->r_flags = ISGONE; /* kill all rooms */ } rp = &rooms[0]; /* point to only room */ rp->r_flags = 0; /* this room NOT gone */ rp->r_max.x = 40; rp->r_max.y = 10; /* 10 * 40 room */ rp->r_pos.x = (COLS - rp->r_max.x) / 2; /* center horizontal */ rp->r_pos.y = 1; /* 2nd line */ draw_room(rp); /* draw the only room */ i = roll(4,10); /* 10 to 40 items */ for (; i > 0 ; i--) { /* place all the items */ ll = new_thing(FALSE, ANYTHING); /* get something */ attach(lvl_obj, ll); op = OBJPTR(ll); setoflg(op, ISPOST); /* object in trading post */ tp = *rnd_pos(rp); op->o_pos = tp; mvaddch(tp.y,tp.x,op->o_type); } trader = 0; wmove(cw,12,0); waddstr(cw,"Welcome to Friendly Fiend's Flea Market\n\r"); waddstr(cw,"=======================================\n\r"); waddstr(cw,"$: Prices object that you stand upon.\n\r"); waddstr(cw,"#: Buys the object that you stand upon.\n\r"); waddstr(cw,"%: Trades in something in your pack for gold.\n\r"); trans_line(); } /* * price_it: * Price the object that the hero stands on */ bool price_it(void) { static char *bargain[] = { "great bargain", "quality product", "exceptional find", }; reg struct linked_list *item; reg struct object *obj; reg int worth; if (!open_market()) /* after buying hours */ return FALSE; if ((item = find_obj(hero.y,hero.x)) == NULL) return FALSE; obj = OBJPTR(item); if (curprice == NOTPRICED) { worth = get_worth(obj); worth += 50 - rnd(100); if (worth < 25) worth = 25; worth *= 3; /* slightly expensive */ curprice = worth; /* save price */ strcpy(curpurch, obj->o_typname); /* save item */ } msg("That %s is a %s for only %d pieces of gold", curpurch, bargain[rnd(3)], curprice); return TRUE; } /* * buy_it: * Buy the item on which the hero stands */ void buy_it(void) { reg int wh; if (purse <= 0) { msg("You have no money."); return; } if (curprice < 0) { /* if not yet priced */ wh = price_it(); if (!wh) /* nothing to price */ return; msg("Do you want to buy it? "); do { wh = readchar(); if (isupper(wh)) wh = tolower(wh); if (wh == ESCAPE || wh == 'n') { msg(""); return; } } until(wh == 'y'); } mpos = 0; if (curprice > purse) { msg("You can't afford to buy that %s !",curpurch); return; } /* * See if the hero has done all his transacting */ if (!open_market()) return; /* * The hero bought the item here */ mpos = 0; wh = add_pack(NULL,FALSE); /* try to put it in his pack */ if (wh) { /* he could get it */ purse -= curprice; /* take his money */ ++trader; /* another transaction */ trans_line(); /* show remaining deals */ curprice = NOTPRICED; curpurch[0] = '\0'; } } /* * sell_it: * Sell an item to the trading post */ void sell_it(void) { reg struct linked_list *item; reg struct object *obj; reg int wo, ch; if (!open_market()) /* after selling hours */ return; if ((item = get_item("sell",0)) == NULL) return; obj = OBJPTR(item); wo = get_worth(obj); if (wo <= 0) { mpos = 0; msg("We don't buy those."); return; } if (wo < 25) wo = 25; msg("Your %s is worth %d pieces of gold.", obj->o_typname, wo); msg("Do you want to sell it? "); do { ch = readchar(); if (isupper(ch)) ch = tolower(ch); if (ch == ESCAPE || ch == 'n') { msg(""); return; } } until (ch == 'y'); mpos = 0; if (drop(item) == TRUE) { /* drop this item */ nochange = FALSE; /* show gold value */ purse += wo; /* give him his money */ ++trader; /* another transaction */ wo = obj->o_count; obj->o_count = 1; msg("Sold %s",inv_name(obj,TRUE)); obj->o_count = wo; trans_line(); /* show remaining deals */ } } /* * open_market: * Retruns TRUE when ok do to transacting */ bool open_market(void) { if (trader >= MAXPURCH) { msg("The market is closed. The stairs are that-a-way."); return FALSE; } else return TRUE; } /* * get_worth: * Calculate an objects worth in gold */ int get_worth(struct object *obj) { reg int worth, wh; worth = 0; wh = obj->o_which; switch (obj->o_type) { case FOOD: worth = 2; when WEAPON: if (wh < MAXWEAPONS) { worth = w_magic[wh].mi_worth; worth *= (2 + (4 * obj->o_hplus + 4 * obj->o_dplus)); } when ARMOR: if (wh < MAXARMORS) { worth = a_magic[wh].mi_worth; worth *= (1 + (10 * (armors[wh].a_class - obj->o_ac))); } when SCROLL: if (wh < MAXSCROLLS) worth = s_magic[wh].mi_worth; when POTION: if (wh < MAXPOTIONS) worth = p_magic[wh].mi_worth; when RING: if (wh < MAXRINGS) { worth = r_magic[wh].mi_worth; if (magring(obj)) { if (obj->o_ac > 0) worth += obj->o_ac * 40; else worth = 50; } } when STICK: if (wh < MAXSTICKS) { worth = ws_magic[wh].mi_worth; worth += 20 * obj->o_charges; } when AMULET: worth = 1000; otherwise: worth = 0; } if (worth < 0) worth = 0; if (o_on(obj, ISPROT)) /* 300% more for protected */ worth *= 3; if (o_on(obj, ISBLESS)) /* 50% more for blessed */ worth = worth * 3 / 2; return worth; } /* * trans_line: * Show how many transactions the hero has left */ void trans_line(void) { sprintf(prbuf,"You have %d transactions remaining.",MAXPURCH-trader); mvwaddstr(cw, LINES - 4, 0, prbuf); } /* * domaze: * Draw the maze on this level. */ void do_maze(void) { struct coord tp; reg int i, least; reg struct room *rp; bool treas; for (rp = rooms; rp < &rooms[MAXROOMS]; rp++) { rp->r_goldval = 0; rp->r_nexits = 0; /* no exits */ rp->r_flags = ISGONE; /* kill all rooms */ } rp = &rooms[0]; /* point to only room */ rp->r_flags = ISDARK; /* mazes always dark */ rp->r_pos.x = 0; /* room fills whole screen */ rp->r_pos.y = 1; rp->r_max.x = COLS - 1; rp->r_max.y = LINES - 2; rp->r_goldval = 500 + (rnd(10) + 1) * GOLDCALC; draw_maze(); /* put maze into window */ rp->r_gold = *rnd_pos(rp); mvaddch(rp->r_gold.y, rp->r_gold.x, GOLD); if (rnd(100) < 3) { /* 3% for treasure maze level */ treas = TRUE; least = 6; rp->r_flags |= ISTREAS; } else { /* normal maze level */ least = 1; treas = FALSE; } for (i = 0; i < level + least; i++) if (treas || rnd(100) < 50) /* put in some little buggers */ add_mon(rp, treas); } struct cell { char y_pos; char x_pos; }; struct bordercells { unsigned char num_pos; /* number of frontier cells next to you */ struct cell conn[4]; /* the y,x position of above cell */ } mborder; char *frontier, *bits; char *moffset(int y, int x); char *foffset(int y, int x); int tlines, tcols; /* * draw_maze: * Generate and draw the maze on the screen */ void draw_maze(void) { reg int i, j, more; reg char *ptr; tlines = (LINES - 3) / 2; tcols = (COLS - 1) / 2; bits = ALLOC((LINES - 3) * (COLS - 1)); frontier = ALLOC(tlines * tcols); ptr = frontier; while (ptr < (frontier + (tlines * tcols))) *ptr++ = TRUE; for (i = 0; i < LINES - 3; i++) { for (j = 0; j < COLS - 1; j++) { if (i % 2 == 1 && j % 2 == 1) *moffset(i, j) = FALSE; /* floor */ else *moffset(i, j) = TRUE; /* wall */ } } for (i = 0; i < tlines; i++) { for (j = 0; j < tcols; j++) { do more = findcells(i,j); while(more != 0); } } crankout(); FREE(frontier); FREE(bits); } /* * moffset: * Calculate memory address for bits */ char * moffset(int y, int x) { char *ptr; ptr = bits + (y * (COLS - 1)) + x; return ptr; } /* * foffset: * Calculate memory address for frontier */ char * foffset(int y, int x) { char *ptr; ptr = frontier + (y * tcols) + x; return ptr; } /* * findcells: * Figure out cells to open up */ int findcells(int y, int x) { reg int rtpos, i; *foffset(y, x) = FALSE; mborder.num_pos = 0; if (y < tlines - 1) { /* look below */ if (*foffset(y + 1, x)) { mborder.conn[mborder.num_pos].y_pos = y + 1; mborder.conn[mborder.num_pos].x_pos = x; mborder.num_pos += 1; } } if (y > 0) { /* look above */ if (*foffset(y - 1, x)) { mborder.conn[mborder.num_pos].y_pos = y - 1; mborder.conn[mborder.num_pos].x_pos = x; mborder.num_pos += 1; } } if (x < tcols - 1) { /* look right */ if (*foffset(y, x + 1)) { mborder.conn[mborder.num_pos].y_pos = y; mborder.conn[mborder.num_pos].x_pos = x + 1; mborder.num_pos += 1; } } if (x > 0) { /* look left */ if (*foffset(y, x - 1)) { mborder.conn[mborder.num_pos].y_pos = y; mborder.conn[mborder.num_pos].x_pos = x - 1; mborder.num_pos += 1; } } if (mborder.num_pos == 0) /* no neighbors available */ return 0; else { i = rnd(mborder.num_pos); rtpos = mborder.num_pos - 1; rmwall(mborder.conn[i].y_pos, mborder.conn[i].x_pos, y, x); return rtpos; } } /* * rmwall: * Removes appropriate walls from the maze */ void rmwall(int newy, int newx, int oldy, int oldx) { reg int xdif,ydif; xdif = newx - oldx; ydif = newy - oldy; *moffset((oldy * 2) + ydif + 1, (oldx * 2) + xdif + 1) = FALSE; findcells(newy, newx); } /* * crankout: * Does actual drawing of maze to window */ void crankout(void) { reg int x, y, i; for (y = 0; y < LINES - 3; y++) { move(y + 1, 0); for (x = 0; x < COLS - 1; x++) { if (*moffset(y, x)) { /* here is a wall */ if (y == 0 || y == LINES - 4) /* top or bottom line */ addch('-'); else if (x == 0 || x == COLS - 2) /* left | right side */ addch('|'); else if (y % 2 == 0 && x % 2 == 0) { if (*moffset(y, x - 1) || *moffset(y, x + 1)) addch('-'); else addch('|'); } else if (y % 2 == 0) addch('-'); else addch('|'); } else addch(FLOOR); } } }