home *** CD-ROM | disk | FTP | other *** search
- /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
- /* shk.c - version 1.0.3 */
-
- #include "hack.h"
- #ifdef QUEST
- int shlevel = 0;
- struct monst *shopkeeper = 0;
- struct obj *billobjs = 0;
- obfree(obj,merge) register struct obj *obj, *merge; {
- free((char *) obj);
- }
- inshop(){ return(0); }
- addtobill(){}
- subfrombill(){}
- splitbill(){}
- dopay(){ return(0); }
- paybill(){}
- doinvbill(){ return(0); }
- shkdead(){}
- shkcatch(){ return(0); }
- shk_move(){ return(0); }
- replshk(mtmp,mtmp2) struct monst *mtmp, *mtmp2; {}
- char *shkname(){ return(""); }
-
- #else QUEST
- #include "mfndpos.h"
- #include "mkroom.h"
- #include "eshk.h"
-
- #define ESHK(mon) ((struct eshk *)(&(mon->mextra[0])))
- #define NOTANGRY(mon) mon->mpeaceful
- #define ANGRY(mon) !NOTANGRY(mon)
-
- extern char plname[], *xname();
- extern struct obj *o_on(), *bp_to_obj();
-
- /* Descriptor of current shopkeeper. Note that the bill need not be
- per-shopkeeper, since it is valid only when in a shop. */
- extern struct monst *shopkeeper;
- extern struct bill_x *bill;
- extern int shlevel; /* level of this shopkeeper */
- extern struct obj *billobjs; /* objects on bill with bp->useup */
- /* only accessed here and by save & restore */
- extern long int total; /* filled by addupbill() */
- extern long int followmsg; /* last time of follow message */
-
- /*
- invariants: obj->unpaid iff onbill(obj) [unless bp->useup]
- obj->quan <= bp->bquan
- */
-
-
- extern char shtypes[];
-
- extern char *shopnam[];
-
- extern char *shkname();
-
- extern struct bill_x *onbill();
-
-
- /* return 1 if paid successfully */
- /* 0 if not enough money */
- /* -1 if object could not be found (but was paid) */
- dopayobj(bp) register struct bill_x *bp; {
- register struct obj *obj;
- long ltmp;
-
- /* find the object on one of the lists */
- obj = bp_to_obj(bp);
-
- if(!obj) {
- impossible("Shopkeeper administration out of order.");
- setpaid(); /* be nice to the player */
- return(0);
- }
-
- if(!obj->unpaid && !bp->useup){
- impossible("Paid object on bill??");
- return(1);
- }
- obj->unpaid = 0;
- ltmp = bp->price * bp->bquan;
- if(ANGRY(shopkeeper)) ltmp += ltmp/3;
- if(u.ugold < ltmp){
- pline("You don't have gold enough to pay %s.",
- doname(obj));
- obj->unpaid = 1;
- return(0);
- }
- pay(ltmp, shopkeeper);
- pline("You bought %s for %ld gold piece%s.",
- doname(obj), ltmp, plur(ltmp));
- if(bp->useup) {
- register struct obj *otmp = billobjs;
- if(obj == billobjs)
- billobjs = obj->nobj;
- else {
- while(otmp && otmp->nobj != obj) otmp = otmp->nobj;
- if(otmp) otmp->nobj = obj->nobj;
- else pline("Error in shopkeeper administration.");
- }
- free((char *) obj);
- }
- return(1);
- }
-
- /* routine called after dying (or quitting) with nonempty bill */
- paybill(){
- if(shlevel == dlevel && shopkeeper && ESHK(shopkeeper)->billct){
- addupbill();
- if(total > u.ugold){
- shopkeeper->mgold += u.ugold;
- u.ugold = 0;
- pline("%s comes and takes all your possessions.",
- Monnam(shopkeeper));
- } else {
- u.ugold -= total;
- shopkeeper->mgold += total;
- pline("%s comes and takes the %ld zorkmids you owed him.",
- Monnam(shopkeeper), total);
- }
- setpaid(); /* in case we create bones */
- }
- }
-
- /* find obj on one of the lists */
- struct obj *
- bp_to_obj(bp)
- register struct bill_x *bp;
- {
- register struct obj *obj;
- register struct monst *mtmp;
- register unsigned id = bp->bo_id;
-
- if(bp->useup)
- obj = o_on(id, billobjs);
- else if(!(obj = o_on(id, invent)) &&
- !(obj = o_on(id, fobj)) &&
- !(obj = o_on(id, fcobj))) {
- for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
- if(obj = o_on(id, mtmp->minvent))
- break;
- for(mtmp = fallen_down; mtmp; mtmp = mtmp->nmon)
- if(obj = o_on(id, mtmp->minvent))
- break;
- }
- return(obj);
- }
-
- /* called in hack.c when we pickup an object */
- addtobill(obj) register struct obj *obj; {
- register struct bill_x *bp;
- if(!inshop() ||
- (u.ux == ESHK(shopkeeper)->shk.x && u.uy == ESHK(shopkeeper)->shk.y) ||
- (u.ux == ESHK(shopkeeper)->shd.x && u.uy == ESHK(shopkeeper)->shd.y) ||
- onbill(obj) /* perhaps we threw it away earlier */
- ) return;
- if(ESHK(shopkeeper)->billct == BILLSZ){
- pline("You got that for free!");
- return;
- }
- bp = &bill[ESHK(shopkeeper)->billct];
- bp->bo_id = obj->o_id;
- bp->bquan = obj->quan;
- bp->useup = 0;
- bp->price = getprice(obj);
- ESHK(shopkeeper)->billct++;
- obj->unpaid = 1;
- }
-