Mercurial > hg > early-roguelike
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/xrogue/trader.c Tue Apr 21 08:55:20 2015 -0400 @@ -0,0 +1,498 @@ +/* + trader.c - Anything to do with trading posts + + XRogue: Expeditions into the Dungeons of Doom + Copyright (C) 1991 Robert Pietkivitch + All rights reserved. + + Based on "Advanced Rogue" + Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T + All rights reserved. + + See the file LICENSE.TXT for full copyright and licensing information. +*/ + +#include <curses.h> +#include "rogue.h" + +/* + * buy_it: + * Buy the item on which the hero stands + */ + +buy_it() +{ + reg int wh; + struct linked_list *item = NULL; + struct object *obj = NULL; + int wasfood = FALSE; + + 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 = wgetch(cw); + if (wh == ESC || wh == 'n') { + msg(""); + return; + } + } until(wh == 'y'); + } + mpos = 0; + if (curprice > purse) { + msg("You can't afford it!"); + return; + } + /* + * See if the hero has done all his transacting + */ + if (!open_market()) + return; + /* + * The hero bought the item here + */ + item = find_obj(hero.y, hero.x); + obj = OBJPTR(item); + mpos = 0; + wasfood = ISMULT(obj->o_type); + if (add_pack((struct linked_list *)NULL,TRUE)) {/* try to put it in his pack */ + purse -= curprice; /* take his money */ + ++trader; /* another transaction */ + trans_line(); /* show remaining deals */ + curprice = -1; /* reset stuff */ + curpurch[0] = 0; + if (!wasfood) /* if it was food then the object has been deleted */ + { + whatis (item); /* identify it */ + obj = OBJPTR(item); + obj->o_flags &= ~ISPOST; /* turn off ISPOST */ + obj->o_flags |= ISKNOW; /* he knows the item */ + msg("%s", inv_name(obj, TRUE)); + } + else + msg("a food ration."); + } +} + +/* + * do_post: + * Put a trading post room and stuff on the screen + */ + +do_post(startup) +bool startup; /* True if equipping the player at the beginning of the game */ +{ + coord tp; + reg int i, j = 0, k; + reg struct room *rp; + reg struct object *op; + reg struct linked_list *ll; + + o_free_list(lvl_obj); /* throw old items away */ + + for (rp = rooms; rp < &rooms[MAXROOMS]; rp++) + 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 */ + + /* Are we equipping the player? */ + if (startup) { + int wpt; + + /* + * Give the rogue some weaponry. + * Create every kind of weapon there is. + */ + for (wpt=0; wpt<MAXWEAPONS; wpt++) { + ll = spec_item(WEAPON, wpt, rnd(100)/80+1, rnd(121)/60); + attach(lvl_obj, ll); + op = OBJPTR(ll); + op->o_flags |= (ISPOST | ISKNOW); + do { + rnd_pos(rp,&tp); + } until (mvinch(tp.y, tp.x) == FLOOR); + op->o_pos = tp; + mvaddch(tp.y,tp.x,op->o_type); + } + + /* + * Suit of armor. + * Create every kind of armor there is. + */ + for (i=0; i<MAXARMORS; i++) { + ll = spec_item(ARMOR, i, rnd(100)/75, 0); + attach(lvl_obj, ll); + op = OBJPTR(ll); + op->o_flags |= (ISPOST | ISKNOW); + op->o_weight = armors[i].a_wght; + do { + rnd_pos(rp,&tp); + } until (mvinch(tp.y, tp.x) == FLOOR); + op->o_pos = tp; + mvaddch(tp.y,tp.x,op->o_type); + } + + /* Now create some rods/wands/staffs */ + for (i=rnd(4)+2; i>0; i--) { + if (i == 1 && player.t_ctype != C_FIGHTER) j = WS_HIT; + else if (i == 5 && (player.t_ctype == C_RANGER || + player.t_ctype == C_PALADIN || + player.t_ctype == C_MONK)) j = WS_FEAR; + else switch (rnd(8)) { + case 0: j = WS_SLOW_M; + when 1: j = WS_TELMON; + when 2: j = WS_CONFMON; + when 3: j = WS_PARALYZE; + when 4: j = WS_MDEG; + when 5: j = WS_WONDER; + when 6: j = WS_LIGHT; + when 7: j = WS_CANCEL; + } + ll = spec_item(STICK, j, 0, 0); + attach(lvl_obj, ll); + op = OBJPTR(ll); + + /* Let clerics and MU'S know what kind they are */ + switch (player.t_ctype) { + case C_MAGICIAN: + case C_CLERIC: + case C_DRUID: + op->o_flags |= (ISPOST | ISKNOW); + otherwise: + op->o_flags |= ISPOST; + } + fix_stick(op); + do { + rnd_pos(rp,&tp); + } until (mvinch(tp.y, tp.x) == FLOOR); + op->o_pos = tp; + mvaddch(tp.y,tp.x,op->o_type); + } + + /* Now let's make some rings */ + for (i=rnd(5)+3; i>0; i--) { + k = 0; + if (i == 6 && player.t_ctype != C_MONK) j = R_HEALTH; + else if (i == 7) j = R_HEROISM; + else switch (rnd(21)) { + case 0: j = R_ADDINTEL; k = roll(1,3); + when 1: j = R_ADDSTR; k = roll(1,3); + when 2: j = R_ADDWISDOM; k = roll(1,3); + when 3: j = R_ADDHIT; k = roll(1,3); + when 4: j = R_ADDDAM; k = roll(1,3); + when 5: j = R_PROTECT; k = roll(1,3); + when 6: j = R_DIGEST; k = 1; + when 7: j = R_SUSABILITY; + when 8: j = R_SEEINVIS; + when 9: j = R_ALERT; + when 10: j = R_FIRE; + when 11: j = R_WARMTH; + when 12: j = R_FREEDOM; + when 13: j = R_STEALTH; + when 14: j = R_CARRY; + when 15: j = R_LIGHT; + when 16: j = R_TELCONTROL; + when 17: j = R_DELUSION; + when 18: j = R_FEAR; + when 19: j = R_AGGR; + when 20: j = R_SEARCH; + } + ll = spec_item(RING, j, k, 0); + attach(lvl_obj, ll); + op = OBJPTR(ll); + + /* + * Let fighters, thieves, and monks know what kind + * of rings these are. + */ + switch (player.t_ctype) { + case C_FIGHTER: + case C_THIEF: + case C_MONK: + op->o_flags |= (ISPOST | ISKNOW); + otherwise: + op->o_flags |= ISPOST; + } + do { + rnd_pos(rp,&tp); + } until (mvinch(tp.y, tp.x) == FLOOR); + op->o_pos = tp; + mvaddch(tp.y,tp.x,op->o_type); + } + + /* Let's offer some potions */ + for (i=rnd(4)+3; i>0; i--) { + if (i == 1 && player.t_ctype == C_ASSASSIN) j = P_POISON; + else if (i == 6) j = P_PHASE; + else switch (rnd(11)) { + case 0: j = P_CLEAR; + when 1: j = P_HEALING; + when 2: j = P_MFIND; + when 3: j = P_HASTE; + when 4: j = P_RESTORE; + when 5: j = P_FLY; + when 6: j = P_FFIND; + when 7: j = P_SEEINVIS; + when 8: j = P_TFIND; + when 9: j = P_INVIS; + when 10: j = P_SKILL; + } + + /* Make the potion */ + ll = spec_item(POTION, j, 0, 0); + attach(lvl_obj, ll); + op = OBJPTR(ll); + op->o_flags |= ISPOST; + + /* Place the potion */ + do { + rnd_pos(rp,&tp); + } until (mvinch(tp.y, tp.x) == FLOOR); + op->o_pos = tp; + mvaddch(tp.y,tp.x,op->o_type); + } + + /* Let's offer some scrolls */ + for (i=rnd(4)+3; i>0; i--) { + if (i == 1 && player.t_ctype != C_MONK) j = S_CURING; + else if (i == 6 && player.t_ctype != C_THIEF) j = S_FINDTRAPS; + else switch (rnd(11)) { + case 0: j = S_CONFUSE; + when 1: j = S_MAP; + when 2: j = S_LIGHT; + when 3: j = S_SLEEP; + when 4: j = S_IDENT; + when 5: j = S_GFIND; + when 6: j = S_REMOVE; + when 7: j = S_HOLD; + when 8: j = S_PETRIFY; + when 9: j = S_SCARE; + when 10: j = S_TELEP; + } + + /* Make the scroll */ + ll = spec_item(SCROLL, j, 0, 0); + attach(lvl_obj, ll); + op = OBJPTR(ll); + op->o_flags |= ISPOST; + + /* Place the scroll */ + do { + rnd_pos(rp,&tp); + } until (mvinch(tp.y, tp.x) == FLOOR); + op->o_pos = tp; + mvaddch(tp.y,tp.x,op->o_type); + } + + /* And finally, let's get some food */ + for (i=rnd(3)+2; i>0; i--) { + ll = spec_item(FOOD, 0, 0, 0); + attach(lvl_obj, ll); + op = OBJPTR(ll); + op->o_weight = things[TYP_FOOD].mi_wght; + op->o_flags |= ISPOST; + do { + rnd_pos(rp,&tp); + } until (mvinch(tp.y, tp.x) == FLOOR); + op->o_pos = tp; + mvaddch(tp.y,tp.x,op->o_type); + } + } + else { /* in trading post itself */ + i = roll(10, 4); /* 10 to 40 items */ + for (; i > 0 ; i--) { /* place all the items */ + ll = new_thing(ALL, TRUE); /* get something */ + attach(lvl_obj, ll); + op = OBJPTR(ll); + op->o_flags |= ISPOST; /* object in trading post */ + do { + rnd_pos(rp,&tp); + } until (mvinch(tp.y, tp.x) == FLOOR); + op->o_pos = tp; + mvaddch(tp.y,tp.x,op->o_type); + } + } + wmove(cw,12,0); + nofont(cw); + trader = 0; + if (startup) { + waddstr(cw,"Welcome to Friendly Fiend's Equipage\n\r"); + waddstr(cw,"====================================\n\r"); + } + else { + 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"); + newfont(cw); + trans_line(); +} + +/* + * open_market: + * Retruns TRUE when ok do to transacting + */ + +open_market() +{ + if (trader >= MAXPURCH && !wizard && level != 0) { + msg("The market is closed. The stairs are that-a-way! "); + return FALSE; + } + else { + return TRUE; + } +} + +/* + * price_it: + * Price the object that the hero stands on + */ + +price_it() +{ + reg struct linked_list *item; + reg struct object *obj; + reg int worth; + reg char *str; + + if (!open_market()) /* after buying hours */ + return FALSE; + if ((item = find_obj(hero.y,hero.x)) == NULL) { + debug("Can't find the item"); + return FALSE; + } + obj = OBJPTR(item); + worth = get_worth(obj); + if (worth < 0) { + msg("That's not for sale."); + return FALSE; + } + if (worth < 25) + worth = 25; + + /* Our shopkeeper is affected by the person's charisma */ + if (pstats.s_charisma > 24) /* but don't give it away! */ + worth = (int) ((float) worth * (18. / (float)24)); + else + worth = (int) ((float) worth * (18. / (float)pstats.s_charisma)); + + str = inv_name(obj, TRUE); + msg("%s for only %d pieces of gold", str, worth); + curprice = worth; /* save price */ + strcpy(curpurch,str); /* save item */ + return TRUE; +} + +/* + * sell_it: + * Sell an item to the trading post + */ + +sell_it() +{ + reg struct linked_list *item; + reg struct object *obj; + reg int wo, ch; + + if (!open_market()) /* after selling hours */ + return; + + if ((item = get_item(pack, "sell", ALL, FALSE, FALSE)) == 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.",typ_name(obj),wo); + msg("Do you want to sell it? "); + do { + ch = wgetch(cw); + if (ch == ESC || ch == 'n') { + msg(""); + return; + } + } until (ch == 'y'); + mpos = 0; + if (drop(item) == TRUE) { /* drop this item */ + purse += wo; /* give him his money */ + ++trader; /* another transaction */ + wo = obj->o_count; + if (obj->o_group == 0) /* dropped one at a time */ + obj->o_count = 1; + msg("Sold %s",inv_name(obj,TRUE)); + obj->o_count = wo; + trans_line(); /* show remaining deals */ + } +} + +/* + * trans_line: + * Show how many transactions the hero has left + */ + +trans_line() +{ + if (level == 0) + sprintf(prbuf, "You are welcome to spend whatever gold you have."); + else if (!wizard) + sprintf(prbuf,"You have %d transactions remaining.", + MAXPURCH - trader); + else + sprintf(prbuf, + "You have infinite transactions remaining oh great wizard."); + nofont(cw); + mvwaddstr(cw,lines - 4,0,prbuf); + newfont(cw); +} + +/* + * typ_name: + * Return the name for this type of object + */ + +char * +typ_name(obj) +reg struct object *obj; +{ + static char buff[20]; + reg int wh; + + switch (obj->o_type) { + case POTION: wh = TYP_POTION; + when SCROLL: wh = TYP_SCROLL; + when STICK: wh = TYP_STICK; + when RING: wh = TYP_RING; + when ARMOR: wh = TYP_ARMOR; + when WEAPON: wh = TYP_WEAPON; + when MM: wh = TYP_MM; + when FOOD: wh = TYP_FOOD; + when RELIC: wh = TYP_RELIC; + otherwise: wh = -1; + } + if (wh < 0) + strcpy(buff,"unknown"); + else + strcpy(buff,things[wh].mi_name); + return (buff); +} +