home *** CD-ROM | disk | FTP | other *** search
- /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
- /* shk.c - version 1.0.3 */
-
- #include "hack.h"
- #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();
-
- dopay(){
- long ltmp;
- register struct bill_x *bp;
- register struct monst *shkp;
- int pass, tmp;
-
- multi = 0;
- (void) inshop();
- for(shkp = fmon; shkp; shkp = shkp->nmon)
- if(shkp->isshk && dist(shkp->mx,shkp->my) < 3)
- break;
- if(!shkp && u.uinshop &&
- inroom(shopkeeper->mx,shopkeeper->my) == ESHK(shopkeeper)->shoproom)
- shkp = shopkeeper;
-
- if(!shkp) {
- pline("There is nobody here to receive your payment.");
- return(0);
- }
- ltmp = ESHK(shkp)->robbed;
- if(shkp != shopkeeper && NOTANGRY(shkp)) {
- if(!ltmp) {
- pline("You do not owe %s anything.", monnam(shkp));
- } else
- if(!u.ugold) {
- pline("You have no money.");
- } else {
- long ugold = u.ugold;
-
- if(u.ugold > ltmp) {
- pline("You give %s the %ld gold pieces he asked for.",
- monnam(shkp), ltmp);
- pay(ltmp, shkp);
- } else {
- pline("You give %s all your gold.", monnam(shkp));
- pay(u.ugold, shkp);
- }
- if(ugold < (ltmp>>1)) {
- pline("Unfortunately, he doesn't look satisfied.");
- } else {
- ESHK(shkp)->robbed = 0;
- ESHK(shkp)->following = 0;
- if(ESHK(shkp)->shoplevel != dlevel) {
- /* For convenience's sake, let him disappear */
- shkp->minvent = 0; /* %% */
- shkp->mgold = 0;
- mondead(shkp);
- }
- }
- }
- return(1);
- }
-
- if(!ESHK(shkp)->billct){
- pline("You do not owe %s anything.", monnam(shkp));
- if(!u.ugold){
- pline("Moreover, you have no money.");
- return(1);
- }
- if(ESHK(shkp)->robbed){
- #define min(a,b) ((a<b)?a:b)
- pline("But since his shop has been robbed recently,");
- pline("you %srepay %s's expenses.",
- (u.ugold < ESHK(shkp)->robbed) ? "partially " : "",
- monnam(shkp));
- pay(min(u.ugold, ESHK(shkp)->robbed), shkp);
- ESHK(shkp)->robbed = 0;
- return(1);
- }
- if(ANGRY(shkp)) dopay2(shkp);
- return(1);
- }
- if(shkp != shopkeeper) {
- impossible("dopay: not to shopkeeper?");
- if(shopkeeper) setpaid();
- return(0);
- }
- for(pass = 0; pass <= 1; pass++) {
- tmp = 0;
- while(tmp < ESHK(shopkeeper)->billct) {
- bp = &bill[tmp];
- if(!pass && !bp->useup) {
- tmp++;
- continue;
- }
- if(!dopayobj(bp)) return(1);
- #ifdef MSDOS
- *bp = bill[--ESHK(shopkeeper)->billct];
- #else
- bill[tmp] = bill[--ESHK(shopkeeper)->billct];
- #endif MSDOS
- }
- }
- pline("Thank you for shopping in %s's %s store!",
- shkname(shopkeeper),
- shopnam[rooms[ESHK(shopkeeper)->shoproom].rtype - 8]);
- NOTANGRY(shopkeeper) = 1;
- return(1);
- }
-