/* -1 if object could not be found (but was paid) */ static int dopayobj(struct bill_x *bp) { 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) { 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(obj); } return (1); }
/* -1 if object could not be found (but was paid) */ static Short dopayobj(bill_t *bp) { obj_t *obj; Long ltmp; /* find the object on one of the lists */ obj = bp_to_obj(bp); if (!obj) { message("BUG: Shopkeeper administration out of order."); setpaid(); /* be nice to the player */ return 0; } if (!(obj->bitflags & O_IS_UNPAID) && !bp->useup) { message("BUG: Paid object on bill??"); return 1; } obj->bitflags &= ~O_IS_UNPAID; ltmp = bp->price * bp->bquantity; if (ANGRY(shopkeeper)) ltmp += ltmp/3; if (you.ugold < ltmp) { StrPrintF(ScratchBuffer, "You don't have gold enough to pay %s.", doname(obj)); message(ScratchBuffer); obj->bitflags |= O_IS_UNPAID; return 0; } pay(ltmp, shopkeeper); StrPrintF(ScratchBuffer, "You bought %s for %ld gold piece%s", doname(obj), ltmp, (ltmp == 1 ? "." : "s.")); message(ScratchBuffer); if (bp->useup) { obj_t *otmp = billobjs; if (obj == billobjs) billobjs = obj->nobj; else { while (otmp && otmp->nobj != obj) otmp = otmp->nobj; if (otmp) otmp->nobj = obj->nobj; else message("BUG: Error in shopkeeper administration."); } free_me((VoidPtr) obj); } return 1; }
static void findshk(Short roomno) { monst_t *mtmp; for (mtmp = fmon ; mtmp ; mtmp = mtmp->nmon) if ((mtmp->bitflags & M_IS_SHOPKEEPER) && ESHK(mtmp)->shoproom == roomno && ESHK(mtmp)->shoplevel == dlevel) { shopkeeper = mtmp; bill = ESHK(shopkeeper)->bill; shlevel = dlevel; if (ANGRY(shopkeeper) && StrNCompare(ESHK(shopkeeper)->customer, plname, PL_NSIZ)) shopkeeper->bitflags |= M_IS_PEACEFUL; // NOTANGRY(shopkeeper) = 1; /* billobjs = 0; -- this is wrong if we save in a shop */ /* (and it is harmless to have too many things in billobjs) */ return; } shopkeeper = NULL; shlevel = 0; // bill = (struct bill_x *) -1000; /* dump core when referenced */ bill = NULL; }
static void findshk(int roomno) { struct monst *mtmp; for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) if (mtmp->isshk && ESHK(mtmp)->shoproom == roomno && ESHK(mtmp)->shoplevel == dlevel) { shopkeeper = mtmp; bill = &(ESHK(shopkeeper)->bill[0]); shlevel = dlevel; if (ANGRY(shopkeeper) && strncmp(ESHK(shopkeeper)->customer, plname, PL_NSIZ)) NOTANGRY(shopkeeper) = 1; /* billobjs = 0; -- this is wrong if we save in a shop */ /* (and it is harmless to have too many things in billobjs) */ return; } shopkeeper = NULL; shlevel = 0; bill = (struct bill_x *) - 1000; /* dump core when referenced */ }
/* * shk_move: return 1: he moved 0: he didnt -1: let m_move do it */ int shk_move(struct monst *shkp) { struct monst *mtmp; struct permonst *mdat = shkp->data; xchar gx, gy, omx, omy, nx, ny, nix, niy; schar appr, i; int udist; int z; schar shkroom, chi, chcnt, cnt; boolean uondoor = 0, satdoor, avoid = 0, badinv; coord poss[9]; int info[9]; struct obj *ib = NULL; omx = shkp->mx; omy = shkp->my; if ((udist = dist(omx, omy)) < 3) { if (ANGRY(shkp)) { hitu(shkp, d(mdat->damn, mdat->damd) + 1); return (0); } if (ESHK(shkp)->following) { if (strncmp(ESHK(shkp)->customer, plname, PL_NSIZ)) { pline("Hello %s! I was looking for %s.", plname, ESHK(shkp)->customer); ESHK(shkp)->following = 0; return (0); } if (!ESHK(shkp)->robbed) { /* impossible? */ ESHK(shkp)->following = 0; return (0); } if (moves > followmsg + 4) { pline("Hello %s! Didn't you forget to pay?", plname); followmsg = moves; } if (udist < 2) return (0); } } shkroom = inroom(omx, omy); appr = 1; gx = ESHK(shkp)->shk.x; gy = ESHK(shkp)->shk.y; satdoor = (gx == omx && gy == omy); if (ESHK(shkp)->following || ((z = holetime()) >= 0 && z * z <= udist)) { gx = u.ux; gy = u.uy; if (shkroom < 0 || shkroom != inroom(u.ux, u.uy)) if (udist > 4) return (-1); /* leave it to m_move */ } else if (ANGRY(shkp)) { long saveBlind = Blind; Blind = 0; if (shkp->mcansee && !Invis && cansee(omx, omy)) { gx = u.ux; gy = u.uy; } Blind = saveBlind; avoid = FALSE; } else { #define GDIST(x, y) ((x - gx) * (x - gx) + (y - gy) * (y - gy)) if (Invis) avoid = FALSE; else { uondoor = (u.ux == ESHK(shkp)->shd.x && u.uy == ESHK(shkp)->shd.y); if (uondoor) { if (ESHK(shkp)->billct) pline("Hello %s! Will you please pay before leaving?", plname); badinv = (carrying(PICK_AXE) || carrying(ICE_BOX)); if (satdoor && badinv) return (0); avoid = !badinv; } else { avoid = (u.uinshop && dist(gx, gy) > 8); badinv = FALSE; } if (((!ESHK(shkp)->robbed && !ESHK(shkp)->billct) || avoid) && GDIST(omx, omy) < 3) { if (!badinv && !online(omx, omy)) return (0); if (satdoor) appr = gx = gy = 0; } } } if (omx == gx && omy == gy) return (0); if (shkp->mconf) { avoid = FALSE; appr = 0; } nix = omx; niy = omy; cnt = mfndpos(shkp, poss, info, ALLOW_SSM); if (avoid && uondoor) { /* perhaps we cannot avoid him */ for (i = 0; i < cnt; i++) if (!(info[i] & NOTONL)) goto notonl_ok; avoid = FALSE; notonl_ok: ; } chi = -1; chcnt = 0; for (i = 0; i < cnt; i++) { nx = poss[i].x; ny = poss[i].y; if (levl[nx][ny].typ == ROOM || shkroom != ESHK(shkp)->shoproom || ESHK(shkp)->following) { #ifdef STUPID /* cater for stupid compilers */ int zz; #endif /* STUPID */ if (uondoor && (ib = sobj_at(ICE_BOX, nx, ny))) { nix = nx; niy = ny; chi = i; break; } if (avoid && (info[i] & NOTONL)) continue; if ((!appr && !rn2(++chcnt)) || #ifdef STUPID (appr && (zz = GDIST(nix, niy)) && zz > GDIST(nx, ny)) #else (appr && GDIST(nx, ny) < GDIST(nix, niy)) #endif /* STUPID */ ) { nix = nx; niy = ny; chi = i; } } } if (nix != omx || niy != omy) { if (info[chi] & ALLOW_M) { mtmp = m_at(nix, niy); if (hitmm(shkp, mtmp) == 1 && rn2(3) && hitmm(mtmp, shkp) == 2) return (2); return (0); } else if (info[chi] & ALLOW_U) { hitu(shkp, d(mdat->damn, mdat->damd) + 1); return (0); } shkp->mx = nix; shkp->my = niy; pmon(shkp); if (ib) { freeobj(ib); mpickobj(shkp, ib); } return (1); } return (0); }
void subfrombill(struct obj *obj) { long ltmp; int tmp; struct obj *otmp; 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)) return; if ((bp = onbill(obj)) != NULL) { obj->unpaid = 0; if (bp->bquan > obj->quan) { otmp = newobj(0); *otmp = *obj; bp->bo_id = otmp->o_id = flags.ident++; otmp->quan = (bp->bquan -= obj->quan); otmp->owt = 0; /* superfluous */ otmp->onamelth = 0; bp->useup = 1; otmp->nobj = billobjs; billobjs = otmp; return; } ESHK(shopkeeper)->billct--; *bp = bill[ESHK(shopkeeper)->billct]; return; } if (obj->unpaid) { pline("%s didn't notice.", Monnam(shopkeeper)); obj->unpaid = 0; return; /* %% */ } /* he dropped something of his own - probably wants to sell it */ if (shopkeeper->msleep || shopkeeper->mfroz || inroom(shopkeeper->mx, shopkeeper->my) != ESHK(shopkeeper)->shoproom) return; if (ESHK(shopkeeper)->billct == BILLSZ || ((tmp = shtypes[rooms[ESHK(shopkeeper)->shoproom].rtype - 8]) && tmp != obj->olet) || strchr("_0", obj->olet)) { pline("%s seems not interested.", Monnam(shopkeeper)); return; } ltmp = getprice(obj) * obj->quan; if (ANGRY(shopkeeper)) { ltmp /= 3; NOTANGRY(shopkeeper) = 1; } else ltmp /= 2; if (ESHK(shopkeeper)->robbed) { if ((ESHK(shopkeeper)->robbed -= ltmp) < 0) ESHK(shopkeeper)->robbed = 0; pline("Thank you for your contribution to restock this recently plundered shop."); return; } if (ltmp > shopkeeper->mgold) ltmp = shopkeeper->mgold; pay(-ltmp, shopkeeper); if (!ltmp) pline("%s gladly accepts %s but cannot pay you at present.", Monnam(shopkeeper), doname(obj)); else pline("You sold %s and got %ld gold piece%s.", doname(obj), ltmp, plur(ltmp)); }
int dopay(void) { long ltmp; struct bill_x *bp; struct monst *shkp; int pass, tmp; multi = 0; 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 / 2) 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)) { pline("But in order to appease %s,", amonnam(shkp, "angry")); if (u.ugold >= 1000) { ltmp = 1000; pline(" you give him 1000 gold pieces."); } else { ltmp = u.ugold; pline(" you give him all your money."); } pay(ltmp, shkp); if (strncmp(ESHK(shkp)->customer, plname, PL_NSIZ) || rn2(3)) { pline("%s calms down.", Monnam(shkp)); NOTANGRY(shkp) = 1; } else pline("%s is as angry as ever.", Monnam(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); bill[tmp] = bill[--ESHK(shopkeeper)->billct]; } } pline("Thank you for shopping in %s's %s store!", shkname(shopkeeper), shopnam[rooms[ESHK(shopkeeper)->shoproom].rtype - 8]); NOTANGRY(shopkeeper) = 1; return (1); }
/* * shk_move: return 1: he moved 0: he didnt -1: let m_move do it * (what about "return 2" ??? */ Short shk_move(monst_t *shkp) { monst_t *mtmp; permonst_t *mdat = shkp->data; UChar gx,gy,omx,omy,nx,ny,nix,niy; Int8 appr,i; Short udist; Short z; Int8 shkroom,chi,chcnt,cnt; Boolean uondoor=false, satdoor, avoid=false, badinv; coord poss[9]; Short info[9]; obj_t *ib = NULL; omx = shkp->mx; omy = shkp->my; if ((udist = dist(omx,omy)) < 3) { if (ANGRY(shkp)) { hit_you(shkp, dice(mdat->damn, mdat->damd)+1); return 0; } if (ESHK(shkp)->following) { if (StrNCompare(ESHK(shkp)->customer, plname, PL_NSIZ)) { StrPrintF(ScratchBuffer, "Hello %s! I was looking for %s.", plname, ESHK(shkp)->customer); message(ScratchBuffer); ESHK(shkp)->following = false; return 0; } if (!ESHK(shkp)->robbed) { /* impossible? */ ESHK(shkp)->following = false; return 0; } if (moves > followmsg+4) { StrPrintF(ScratchBuffer, "Hello %s! Didn't you forget to pay?", plname); message(ScratchBuffer); followmsg = moves; } if (udist < 2) return 0; } } shkroom = inroom(omx,omy); appr = 1; gx = ESHK(shkp)->shk.x; gy = ESHK(shkp)->shk.y; satdoor = (gx == omx && gy == omy); if (ESHK(shkp)->following || ((z = holetime()) >= 0 && z*z <= udist)){ gx = you.ux; gy = you.uy; if (shkroom < 0 || shkroom != inroom(you.ux,you.uy)) if (udist > 4) return -1; /* leave it to m_move */ } else if (ANGRY(shkp)) { Long saveBlind = Blind; Blind = 0; if ((shkp->mcansee_and_blinded & M_CAN_SEE) && !Invis && cansee(omx,omy)) { gx = you.ux; gy = you.uy; } Blind = saveBlind; avoid = false; } else { #define GDIST(x,y) ((x-gx)*(x-gx)+(y-gy)*(y-gy)) if (Invis) avoid = false; else { uondoor = (you.ux == ESHK(shkp)->shd.x && you.uy == ESHK(shkp)->shd.y); if (uondoor) { if (ESHK(shkp)->billct) { StrPrintF(ScratchBuffer, "Hello %s! Will you please pay before leaving?", plname); message(ScratchBuffer); } badinv = (carrying(PICK_AXE) || carrying(ICE_BOX)); if (satdoor && badinv) return 0; avoid = !badinv; } else { avoid = (you.uinshop && dist(gx,gy) > 8); badinv = false; } if (((!ESHK(shkp)->robbed && !ESHK(shkp)->billct) || avoid) && GDIST(omx,omy) < 3) { if (!badinv && !online(omx,omy)) return 0; if (satdoor) appr = gx = gy = 0; } } } if (omx == gx && omy == gy) return 0; if (shkp->bitflags & M_IS_CONFUSED) { avoid = false; appr = 0; } nix = omx; niy = omy; cnt = mfindpos(shkp,poss,info,ALLOW_SSM); if (avoid && uondoor) { /* perhaps we cannot avoid him */ for (i=0; i<cnt; i++) if (!(info[i] & NOTONL)) goto notonl_ok; avoid = false; notonl_ok: ; } chi = -1; chcnt = 0; for (i = 0 ; i < cnt ; i++) { nx = poss[i].x; ny = poss[i].y; if (get_cell_type(floor_info[nx][ny]) == ROOM || shkroom != ESHK(shkp)->shoproom || ESHK(shkp)->following) { #ifdef STUPID /* cater for stupid compilers */ Short zz; #endif STUPID if (uondoor && (ib = sobj_at(ICE_BOX, nx, ny))) { nix = nx; niy = ny; chi = i; break; } if (avoid && (info[i] & NOTONL)) continue; if ((!appr && !rund(++chcnt)) || #ifdef STUPID (appr && (zz = GDIST(nix,niy)) && zz > GDIST(nx,ny)) #else (appr && GDIST(nx,ny) < GDIST(nix,niy)) #endif STUPID ) { nix = nx; niy = ny; chi = i; } } } if (nix != omx || niy != omy) { if (info[chi] & ALLOW_M){ mtmp = mon_at(nix,niy); if (hitmm(shkp,mtmp) == 1 && rund(3) && hitmm(mtmp,shkp) == 2) return 2; return 0; } else if (info[chi] & ALLOW_U){ hit_you(shkp, dice(mdat->damn, mdat->damd)+1); return 0; } shkp->mx = nix; shkp->my = niy; pmon(shkp); if (ib) { unlink_obj(ib);//freeobj mpickobj(shkp, ib); } return 1; } return 0; }
void subfrombill(struct obj *obj) { Long ltmp; Short tmp; obj_t *otmp; bill_t *bp; eshk_t *eshk = (shopkeeper ? ESHK(shopkeeper) : NULL); if (!inshop() || (you.ux == eshk->shk.x && you.uy == eshk->shk.y) || (you.ux == eshk->shd.x && you.uy == eshk->shd.y)) return; if ((bp = onbill(obj)) != 0) { obj->bitflags &= ~O_IS_UNPAID; if (bp->bquantity > obj->quantity) { otmp = (obj_t *) md_malloc(sizeof(obj_t));// newobj(0); *otmp = *obj; bp->bo_id = otmp->o_id = flags.ident++; otmp->quantity = (bp->bquantity -= obj->quantity); otmp->owt = 0; /* superfluous */ do_name(otmp, NULL); // otmp->onamelth = 0; // Undo name (if any) bp->useup = true; otmp->nobj = billobjs; billobjs = otmp; return; } eshk->billct--; *bp = bill[eshk->billct]; return; } if (obj->bitflags & O_IS_UNPAID) { StrPrintF(ScratchBuffer, "%s didn't notice.", Monnam(shopkeeper)); message(ScratchBuffer); obj->bitflags &= ~O_IS_UNPAID; return; /* %% */ } /* he dropped something of his own - probably wants to sell it */ if ((shopkeeper->bitflags & (M_IS_ASLEEP | M_IS_FROZEN)) || inroom(shopkeeper->mx,shopkeeper->my) != eshk->shoproom) return; if (eshk->billct == BILLSZ || ((tmp = shtypes[rooms[eshk->shoproom].rtype-8]) && tmp != obj->olet) || StrChr("_0", obj->olet)) { StrPrintF(ScratchBuffer, "%s seems not interested.", Monnam(shopkeeper)); message(ScratchBuffer); return; } ltmp = getprice(obj) * obj->quantity; if (ANGRY(shopkeeper)) { ltmp /= 3; shopkeeper->bitflags |= M_IS_PEACEFUL; // NOTANGRY(shopkeeper) = 1; } else ltmp /= 2; if (eshk->robbed) { if ((eshk->robbed -= ltmp) < 0) eshk->robbed = 0; message("Thank you for your contribution to restock this recently plundered shop."); return; } if (ltmp > shopkeeper->mgold) ltmp = shopkeeper->mgold; pay(-ltmp, shopkeeper); if (!ltmp) StrPrintF(ScratchBuffer, "%s gladly accepts %s but cannot pay you at present.", Monnam(shopkeeper), doname(obj)); else StrPrintF(ScratchBuffer, "You sold %s and got %ld gold piece%s", doname(obj), ltmp, (ltmp == 1 ? "." : "s.")); message(ScratchBuffer); }
// What does the return value indicate?? Boolean dopay() { Long ltmp; bill_t *bp; monst_t *shkp; Short pass, tmp; multi = 0; inshop(); for (shkp = fmon ; shkp ; shkp = shkp->nmon) if ((shkp->bitflags & M_IS_SHOPKEEPER) && dist(shkp->mx,shkp->my) < 3) break; if (!shkp && you.uinshop && inroom(shopkeeper->mx,shopkeeper->my) == ESHK(shopkeeper)->shoproom) shkp = shopkeeper; if (!shkp) { message("There is nobody here to receive your payment."); return false; } ltmp = ESHK(shkp)->robbed; if (shkp != shopkeeper && NOTANGRY(shkp)) { if (!ltmp) { StrPrintF(ScratchBuffer, "You do not owe %s anything.", monnam(shkp)); message(ScratchBuffer); } else if (!you.ugold) { message("You have no money."); } else { Long ugold = you.ugold; if (you.ugold > ltmp) { StrPrintF(ScratchBuffer, "You give %s the %ld gold pieces he asked for.", monnam(shkp), ltmp); message(ScratchBuffer); pay(ltmp, shkp); } else { StrPrintF(ScratchBuffer, "You give %s all your gold.", monnam(shkp)); message(ScratchBuffer); pay(you.ugold, shkp); } if (ugold < ltmp/2) { message("Unfortunately, he doesn't look satisfied."); } else { ESHK(shkp)->robbed = 0; ESHK(shkp)->following = false; if (ESHK(shkp)->shoplevel != dlevel) { /* For convenience's sake, let him disappear */ shkp->minvent = NULL; /* %% */ // xxx leak? shkp->mgold = 0; mondead(shkp); } } } return true; } if (!ESHK(shkp)->billct) { StrPrintF(ScratchBuffer, "You do not owe %s anything.", monnam(shkp)); message(ScratchBuffer); if (!you.ugold) { message("Moreover, you have no money."); return true; } if (ESHK(shkp)->robbed) { message("But since his shop has been robbed recently,"); StrPrintF(ScratchBuffer, "you%srepay %s's expenses.", (you.ugold < ESHK(shkp)->robbed) ? " partially " : " ", monnam(shkp)); message(ScratchBuffer); pay(min(you.ugold, ESHK(shkp)->robbed), shkp); ESHK(shkp)->robbed = 0; return true; } if (ANGRY(shkp)) { StrPrintF(ScratchBuffer, "But in order to appease %s,", amonnam(shkp, "angry")); message(ScratchBuffer); if (you.ugold >= 1000) { ltmp = 1000; message(" you give him 1000 gold pieces."); } else { ltmp = you.ugold; message(" you give him all your money."); } pay(ltmp, shkp); if (StrNCompare(ESHK(shkp)->customer, plname, PL_NSIZ) || rund(3)){ StrPrintF(ScratchBuffer, "%s calms down.", Monnam(shkp)); message(ScratchBuffer); shkp->bitflags |= M_IS_PEACEFUL; // NOTANGRY(shopkeeper) = 1; } else { StrPrintF(ScratchBuffer, "%s is as angry as ever.", Monnam(shkp)); message(ScratchBuffer); } } return true; } if (shkp != shopkeeper) { message("BUG: dopay: not to shopkeeper?"); if (shopkeeper) setpaid(); return false; } 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 true; bill[tmp] = bill[--ESHK(shopkeeper)->billct]; } } StrPrintF(ScratchBuffer, "Thank you for shopping in %s's %s store!", shkname(shopkeeper), shopnam[rooms[ESHK(shopkeeper)->shoproom].rtype - 8]); shopkeeper->bitflags |= M_IS_PEACEFUL; // NOTANGRY(shopkeeper) = 1; return true; }