OSDN Git Service

import nethack-3.6.0
[jnethack/source.git] / src / shk.c
1 /* NetHack 3.6  shk.c   $NHDT-Date: 1446854234 2015/11/06 23:57:14 $  $NHDT-Branch: master $:$NHDT-Revision: 1.116 $ */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /* NetHack may be freely redistributed.  See license for details. */
4
5 #include "hack.h"
6
7 #define PAY_SOME 2
8 #define PAY_BUY 1
9 #define PAY_CANT 0 /* too poor */
10 #define PAY_SKIP (-1)
11 #define PAY_BROKE (-2)
12
13 STATIC_DCL void FDECL(makekops, (coord *));
14 STATIC_DCL void FDECL(call_kops, (struct monst *, BOOLEAN_P));
15 STATIC_DCL void FDECL(kops_gone, (BOOLEAN_P));
16
17 #define NOTANGRY(mon) ((mon)->mpeaceful)
18 #define ANGRY(mon) (!NOTANGRY(mon))
19 #define IS_SHOP(x) (rooms[x].rtype >= SHOPBASE)
20
21 #define muteshk(shkp)                       \
22     ((shkp)->msleeping || !(shkp)->mcanmove \
23      || (shkp)->data->msound <= MS_ANIMAL)
24
25 extern const struct shclass shtypes[]; /* defined in shknam.c */
26
27 STATIC_VAR NEARDATA long int followmsg; /* last time of follow message */
28 STATIC_VAR const char and_its_contents[] = " and its contents";
29 STATIC_VAR const char the_contents_of[] = "the contents of ";
30
31 STATIC_DCL void FDECL(append_honorific, (char *));
32 STATIC_DCL void FDECL(setpaid, (struct monst *));
33 STATIC_DCL long FDECL(addupbill, (struct monst *));
34 STATIC_DCL void FDECL(pacify_shk, (struct monst *));
35 STATIC_DCL struct bill_x *FDECL(onbill, (struct obj *, struct monst *,
36                                          BOOLEAN_P));
37 STATIC_DCL struct monst *FDECL(next_shkp, (struct monst *, BOOLEAN_P));
38 STATIC_DCL long FDECL(shop_debt, (struct eshk *));
39 STATIC_DCL char *FDECL(shk_owns, (char *, struct obj *));
40 STATIC_DCL char *FDECL(mon_owns, (char *, struct obj *));
41 STATIC_DCL void FDECL(clear_unpaid, (struct obj *));
42 STATIC_DCL long FDECL(check_credit, (long, struct monst *));
43 STATIC_DCL void FDECL(pay, (long, struct monst *));
44 STATIC_DCL long FDECL(get_cost, (struct obj *, struct monst *));
45 STATIC_DCL long FDECL(set_cost, (struct obj *, struct monst *));
46 STATIC_DCL const char *FDECL(shk_embellish, (struct obj *, long));
47 STATIC_DCL long FDECL(cost_per_charge, (struct monst *, struct obj *,
48                                         BOOLEAN_P));
49 STATIC_DCL long FDECL(cheapest_item, (struct monst *));
50 STATIC_DCL int FDECL(dopayobj, (struct monst *, struct bill_x *,
51                                 struct obj **, int, BOOLEAN_P));
52 STATIC_DCL long FDECL(stolen_container, (struct obj *, struct monst *,
53                                          long, BOOLEAN_P));
54 STATIC_DCL long FDECL(getprice, (struct obj *, BOOLEAN_P));
55 STATIC_DCL void FDECL(shk_names_obj, (struct monst *, struct obj *,
56                                       const char *, long, const char *));
57 STATIC_DCL struct obj *FDECL(bp_to_obj, (struct bill_x *));
58 STATIC_DCL boolean FDECL(inherits, (struct monst *, int, int));
59 STATIC_DCL void FDECL(set_repo_loc, (struct monst *));
60 STATIC_DCL boolean NDECL(angry_shk_exists);
61 STATIC_DCL void FDECL(rile_shk, (struct monst *));
62 STATIC_DCL void FDECL(rouse_shk, (struct monst *, BOOLEAN_P));
63 STATIC_DCL void FDECL(remove_damage, (struct monst *, BOOLEAN_P));
64 STATIC_DCL void FDECL(sub_one_frombill, (struct obj *, struct monst *));
65 STATIC_DCL void FDECL(add_one_tobill, (struct obj *, BOOLEAN_P,
66                                        struct monst *));
67 STATIC_DCL void FDECL(dropped_container, (struct obj *, struct monst *,
68                                           BOOLEAN_P));
69 STATIC_DCL void FDECL(add_to_billobjs, (struct obj *));
70 STATIC_DCL void FDECL(bill_box_content, (struct obj *, BOOLEAN_P, BOOLEAN_P,
71                                          struct monst *));
72 STATIC_DCL boolean FDECL(rob_shop, (struct monst *));
73 STATIC_DCL void FDECL(deserted_shop, (char *));
74 STATIC_DCL boolean FDECL(special_stock, (struct obj *, struct monst *,
75                                          BOOLEAN_P));
76 STATIC_DCL const char *FDECL(cad, (BOOLEAN_P));
77
78 /*
79         invariants: obj->unpaid iff onbill(obj) [unless bp->useup]
80                     obj->quan <= bp->bquan
81  */
82
83 /*
84  *  Transfer money from inventory to monster when paying
85  *  shopkeepers, priests, oracle, succubus, and other demons.
86  *  Simple with only gold coins.
87  *  This routine will handle money changing when multiple
88  *  coin types is implemented, only appropriate
89  *  monsters will pay change.  (Peaceful shopkeepers, priests
90  *  and the oracle try to maintain goodwill while selling
91  *  their wares or services.  Angry monsters and all demons
92  *  will keep anything they get their hands on.
93  *  Returns the amount actually paid, so we can know
94  *  if the monster kept the change.
95  */
96 long
97 money2mon(mon, amount)
98 struct monst *mon;
99 long amount;
100 {
101     struct obj *ygold = findgold(invent);
102
103     if (amount <= 0) {
104         impossible("%s payment in money2mon!", amount ? "negative" : "zero");
105         return 0L;
106     }
107     if (!ygold || ygold->quan < amount) {
108         impossible("Paying without %s money?", ygold ? "enough" : "");
109         return 0L;
110     }
111
112     if (ygold->quan > amount)
113         ygold = splitobj(ygold, amount);
114     else if (ygold->owornmask)
115         remove_worn_item(ygold, FALSE); /* quiver */
116     freeinv(ygold);
117     add_to_minv(mon, ygold);
118     context.botl = 1;
119     return amount;
120 }
121
122 /*
123  *  Transfer money from monster to inventory.
124  *  Used when the shopkeeper pay for items, and when
125  *  the priest gives you money for an ale.
126  */
127 void
128 money2u(mon, amount)
129 struct monst *mon;
130 long amount;
131 {
132     struct obj *mongold = findgold(mon->minvent);
133
134     if (amount <= 0) {
135         impossible("%s payment in money2u!", amount ? "negative" : "zero");
136         return;
137     }
138     if (!mongold || mongold->quan < amount) {
139         impossible("%s paying without %s money?", a_monnam(mon),
140                    mongold ? "enough" : "");
141         return;
142     }
143
144     if (mongold->quan > amount)
145         mongold = splitobj(mongold, amount);
146     obj_extract_self(mongold);
147
148     if (!merge_choice(invent, mongold) && inv_cnt(FALSE) >= 52) {
149         You("have no room for the money!");
150         dropy(mongold);
151     } else {
152         addinv(mongold);
153         context.botl = 1;
154     }
155 }
156
157 STATIC_OVL struct monst *
158 next_shkp(shkp, withbill)
159 register struct monst *shkp;
160 register boolean withbill;
161 {
162     for (; shkp; shkp = shkp->nmon) {
163         if (DEADMONSTER(shkp))
164             continue;
165         if (shkp->isshk && (ESHK(shkp)->billct || !withbill))
166             break;
167     }
168
169     if (shkp) {
170         if (NOTANGRY(shkp)) {
171             if (ESHK(shkp)->surcharge)
172                 pacify_shk(shkp);
173         } else {
174             if (!ESHK(shkp)->surcharge)
175                 rile_shk(shkp);
176         }
177     }
178     return shkp;
179 }
180
181 /* called in mon.c */
182 void
183 shkgone(mtmp)
184 struct monst *mtmp;
185 {
186     struct eshk *eshk = ESHK(mtmp);
187     struct mkroom *sroom = &rooms[eshk->shoproom - ROOMOFFSET];
188     struct obj *otmp;
189     char *p;
190     int sx, sy;
191
192     /* [BUG: some of this should be done on the shop level */
193     /*       even when the shk dies on a different level.] */
194     if (on_level(&eshk->shoplevel, &u.uz)) {
195         remove_damage(mtmp, TRUE);
196         sroom->resident = (struct monst *) 0;
197         if (!search_special(ANY_SHOP))
198             level.flags.has_shop = 0;
199
200         /* items on shop floor revert to ordinary objects */
201         for (sx = sroom->lx; sx <= sroom->hx; sx++)
202             for (sy = sroom->ly; sy <= sroom->hy; sy++)
203                 for (otmp = level.objects[sx][sy]; otmp;
204                      otmp = otmp->nexthere)
205                     otmp->no_charge = 0;
206
207         /* Make sure bill is set only when the
208            dead shk is the resident shk. */
209         if ((p = index(u.ushops, eshk->shoproom)) != 0) {
210             setpaid(mtmp);
211             eshk->bill_p = (struct bill_x *) 0;
212             /* remove eshk->shoproom from u.ushops */
213             do {
214                 *p = *(p + 1);
215             } while (*++p);
216         }
217     }
218 }
219
220 void
221 set_residency(shkp, zero_out)
222 register struct monst *shkp;
223 register boolean zero_out;
224 {
225     if (on_level(&(ESHK(shkp)->shoplevel), &u.uz))
226         rooms[ESHK(shkp)->shoproom - ROOMOFFSET].resident =
227             (zero_out) ? (struct monst *) 0 : shkp;
228 }
229
230 void
231 replshk(mtmp, mtmp2)
232 register struct monst *mtmp, *mtmp2;
233 {
234     rooms[ESHK(mtmp2)->shoproom - ROOMOFFSET].resident = mtmp2;
235     if (inhishop(mtmp) && *u.ushops == ESHK(mtmp)->shoproom) {
236         ESHK(mtmp2)->bill_p = &(ESHK(mtmp2)->bill[0]);
237     }
238 }
239
240 /* do shopkeeper specific structure munging -dlc */
241 void
242 restshk(shkp, ghostly)
243 struct monst *shkp;
244 boolean ghostly;
245 {
246     if (u.uz.dlevel) {
247         struct eshk *eshkp = ESHK(shkp);
248
249         if (eshkp->bill_p != (struct bill_x *) -1000)
250             eshkp->bill_p = &eshkp->bill[0];
251         /* shoplevel can change as dungeons move around */
252         /* savebones guarantees that non-homed shk's will be gone */
253         if (ghostly) {
254             assign_level(&eshkp->shoplevel, &u.uz);
255             if (ANGRY(shkp) && strncmpi(eshkp->customer, plname, PL_NSIZ))
256                 pacify_shk(shkp);
257         }
258     }
259 }
260
261 /* Clear the unpaid bit on all of the objects in the list. */
262 STATIC_OVL void
263 clear_unpaid(list)
264 register struct obj *list;
265 {
266     while (list) {
267         if (Has_contents(list))
268             clear_unpaid(list->cobj);
269         list->unpaid = 0;
270         list = list->nobj;
271     }
272 }
273
274 /* either you paid or left the shop or the shopkeeper died */
275 STATIC_OVL void
276 setpaid(shkp)
277 register struct monst *shkp;
278 {
279     register struct obj *obj;
280     register struct monst *mtmp;
281
282     /* FIXME: object handling should be limited to
283        items which are on this particular shk's bill */
284
285     clear_unpaid(invent);
286     clear_unpaid(fobj);
287     clear_unpaid(level.buriedobjlist);
288     if (thrownobj)
289         thrownobj->unpaid = 0;
290     if (kickedobj)
291         kickedobj->unpaid = 0;
292     for (mtmp = fmon; mtmp; mtmp = mtmp->nmon)
293         clear_unpaid(mtmp->minvent);
294     for (mtmp = migrating_mons; mtmp; mtmp = mtmp->nmon)
295         clear_unpaid(mtmp->minvent);
296
297     while ((obj = billobjs) != 0) {
298         obj_extract_self(obj);
299         dealloc_obj(obj);
300     }
301     if (shkp) {
302         ESHK(shkp)->billct = 0;
303         ESHK(shkp)->credit = 0L;
304         ESHK(shkp)->debit = 0L;
305         ESHK(shkp)->loan = 0L;
306     }
307 }
308
309 STATIC_OVL long
310 addupbill(shkp)
311 register struct monst *shkp;
312 {
313     register int ct = ESHK(shkp)->billct;
314     register struct bill_x *bp = ESHK(shkp)->bill_p;
315     register long total = 0L;
316
317     while (ct--) {
318         total += bp->price * bp->bquan;
319         bp++;
320     }
321     return total;
322 }
323
324 STATIC_OVL void
325 call_kops(shkp, nearshop)
326 register struct monst *shkp;
327 register boolean nearshop;
328 {
329     /* Keystone Kops srt@ucla */
330     register boolean nokops;
331
332     if (!shkp)
333         return;
334
335     if (!Deaf)
336         pline("An alarm sounds!");
337
338     nokops = ((mvitals[PM_KEYSTONE_KOP].mvflags & G_GONE)
339               && (mvitals[PM_KOP_SERGEANT].mvflags & G_GONE)
340               && (mvitals[PM_KOP_LIEUTENANT].mvflags & G_GONE)
341               && (mvitals[PM_KOP_KAPTAIN].mvflags & G_GONE));
342
343     if (!angry_guards(!!Deaf) && nokops) {
344         if (flags.verbose && !Deaf)
345             pline("But no one seems to respond to it.");
346         return;
347     }
348
349     if (nokops)
350         return;
351
352     {
353         coord mm;
354
355         if (nearshop) {
356             /* Create swarm around you, if you merely "stepped out" */
357             if (flags.verbose)
358                 pline_The("Keystone Kops appear!");
359             mm.x = u.ux;
360             mm.y = u.uy;
361             makekops(&mm);
362             return;
363         }
364         if (flags.verbose)
365             pline_The("Keystone Kops are after you!");
366         /* Create swarm near down staircase (hinders return to level) */
367         mm.x = xdnstair;
368         mm.y = ydnstair;
369         makekops(&mm);
370         /* Create swarm near shopkeeper (hinders return to shop) */
371         mm.x = shkp->mx;
372         mm.y = shkp->my;
373         makekops(&mm);
374     }
375 }
376
377 /* x,y is strictly inside shop */
378 char
379 inside_shop(x, y)
380 register xchar x, y;
381 {
382     register char rno;
383
384     rno = levl[x][y].roomno;
385     if ((rno < ROOMOFFSET) || levl[x][y].edge || !IS_SHOP(rno - ROOMOFFSET))
386         return NO_ROOM;
387     else
388         return rno;
389 }
390
391 void
392 u_left_shop(leavestring, newlev)
393 char *leavestring;
394 boolean newlev;
395 {
396     struct monst *shkp;
397     struct eshk *eshkp;
398
399     /*
400      * IF player
401      * ((didn't leave outright) AND
402      *  ((he is now strictly-inside the shop) OR
403      *   (he wasn't strictly-inside last turn anyway)))
404      * THEN (there's nothing to do, so just return)
405      */
406     if (!*leavestring && (!levl[u.ux][u.uy].edge || levl[u.ux0][u.uy0].edge))
407         return;
408
409     shkp = shop_keeper(*u.ushops0);
410     if (!shkp || !inhishop(shkp))
411         return; /* shk died, teleported, changed levels... */
412
413     eshkp = ESHK(shkp);
414     if (!eshkp->billct && !eshkp->debit) /* bill is settled */
415         return;
416
417     if (!*leavestring && !muteshk(shkp)) {
418         /*
419          * Player just stepped onto shop-boundary (known from above logic).
420          * Try to intimidate him into paying his bill
421          */
422         verbalize(NOTANGRY(shkp) ? "%s!  Please pay before leaving."
423                                  : "%s!  Don't you leave without paying!",
424                   plname);
425         return;
426     }
427
428     if (rob_shop(shkp)) {
429         call_kops(shkp, (!newlev && levl[u.ux0][u.uy0].edge));
430     }
431 }
432
433 /* robbery from outside the shop via telekinesis or grappling hook */
434 void
435 remote_burglary(x, y)
436 xchar x, y;
437 {
438     struct monst *shkp;
439     struct eshk *eshkp;
440
441     shkp = shop_keeper(*in_rooms(x, y, SHOPBASE));
442     if (!shkp || !inhishop(shkp))
443         return; /* shk died, teleported, changed levels... */
444
445     eshkp = ESHK(shkp);
446     if (!eshkp->billct && !eshkp->debit) /* bill is settled */
447         return;
448
449     if (rob_shop(shkp)) {
450         /*[might want to set 2nd arg based on distance from shop doorway]*/
451         call_kops(shkp, FALSE);
452     }
453 }
454
455 /* shop merchandise has been taken; pay for it with any credit available;
456    return false if the debt is fully covered by credit, true otherwise */
457 STATIC_OVL boolean
458 rob_shop(shkp)
459 struct monst *shkp;
460 {
461     struct eshk *eshkp;
462     long total;
463
464     eshkp = ESHK(shkp);
465     rouse_shk(shkp, TRUE);
466     total = (addupbill(shkp) + eshkp->debit);
467     if (eshkp->credit >= total) {
468         Your("credit of %ld %s is used to cover your shopping bill.",
469              eshkp->credit, currency(eshkp->credit));
470         total = 0L; /* credit gets cleared by setpaid() */
471     } else {
472         You("escaped the shop without paying!");
473         total -= eshkp->credit;
474     }
475     setpaid(shkp);
476     if (!total)
477         return FALSE;
478
479     /* by this point, we know an actual robbery has taken place */
480     eshkp->robbed += total;
481     You("stole %ld %s worth of merchandise.", total, currency(total));
482     if (!Role_if(PM_ROGUE)) /* stealing is unlawful */
483         adjalign(-sgn(u.ualign.type));
484
485     hot_pursuit(shkp);
486     return TRUE;
487 }
488
489 /* give a message when entering an untended shop (caller has verified that) */
490 STATIC_OVL void
491 deserted_shop(enterstring)
492 /*const*/ char *enterstring;
493 {
494     struct monst *mtmp;
495     struct mkroom *r = &rooms[(int) *enterstring - ROOMOFFSET];
496     int x, y, m = 0, n = 0;
497
498     for (x = r->lx; x <= r->hx; ++x)
499         for (y = r->ly; y <= r->hy; ++y) {
500             if (x == u.ux && y == u.uy)
501                 continue;
502             if ((mtmp = m_at(x, y)) != 0) {
503                 ++n;
504                 if (sensemon(mtmp) || ((mtmp->m_ap_type == M_AP_NOTHING
505                                         || mtmp->m_ap_type == M_AP_MONSTER)
506                                        && canseemon(mtmp)))
507                     ++m;
508             }
509         }
510
511     if (Blind && !(Blind_telepat || Detect_monsters))
512         ++n; /* force feedback to be less specific */
513
514     pline("This shop %s %s.", (m < n) ? "seems to be" : "is",
515           !n ? "deserted" : "untended");
516 }
517
518 void
519 u_entered_shop(enterstring)
520 char *enterstring;
521 {
522     register int rt;
523     register struct monst *shkp;
524     register struct eshk *eshkp;
525     static char empty_shops[5];
526
527     if (!*enterstring)
528         return;
529
530     if (!(shkp = shop_keeper(*enterstring))) {
531         if (!index(empty_shops, *enterstring)
532             && in_rooms(u.ux, u.uy, SHOPBASE)
533                    != in_rooms(u.ux0, u.uy0, SHOPBASE))
534             deserted_shop(enterstring);
535         Strcpy(empty_shops, u.ushops);
536         u.ushops[0] = '\0';
537         return;
538     }
539
540     eshkp = ESHK(shkp);
541
542     if (!inhishop(shkp)) {
543         /* dump core when referenced */
544         eshkp->bill_p = (struct bill_x *) -1000;
545         if (!index(empty_shops, *enterstring))
546             deserted_shop(enterstring);
547         Strcpy(empty_shops, u.ushops);
548         u.ushops[0] = '\0';
549         return;
550     }
551
552     eshkp->bill_p = &(eshkp->bill[0]);
553
554     if ((!eshkp->visitct || *eshkp->customer)
555         && strncmpi(eshkp->customer, plname, PL_NSIZ)) {
556         /* You seem to be new here */
557         eshkp->visitct = 0;
558         eshkp->following = 0;
559         (void) strncpy(eshkp->customer, plname, PL_NSIZ);
560         pacify_shk(shkp);
561     }
562
563     if (muteshk(shkp) || eshkp->following)
564         return; /* no dialog */
565
566     if (Invis) {
567         pline("%s senses your presence.", shkname(shkp));
568         verbalize("Invisible customers are not welcome!");
569         return;
570     }
571
572     rt = rooms[*enterstring - ROOMOFFSET].rtype;
573
574     if (ANGRY(shkp)) {
575         verbalize("So, %s, you dare return to %s %s?!", plname,
576                   s_suffix(shkname(shkp)), shtypes[rt - SHOPBASE].name);
577     } else if (eshkp->robbed) {
578         pline("%s mutters imprecations against shoplifters.", shkname(shkp));
579     } else {
580         verbalize("%s, %s!  Welcome%s to %s %s!", Hello(shkp), plname,
581                   eshkp->visitct++ ? " again" : "", s_suffix(shkname(shkp)),
582                   shtypes[rt - SHOPBASE].name);
583     }
584     /* can't do anything about blocking if teleported in */
585     if (!inside_shop(u.ux, u.uy)) {
586         boolean should_block;
587         int cnt;
588         const char *tool;
589         struct obj *pick = carrying(PICK_AXE),
590                    *mattock = carrying(DWARVISH_MATTOCK);
591
592         if (pick || mattock) {
593             cnt = 1;               /* so far */
594             if (pick && mattock) { /* carrying both types */
595                 tool = "digging tool";
596                 cnt = 2; /* `more than 1' is all that matters */
597             } else if (pick) {
598                 tool = "pick-axe";
599                 /* hack: `pick' already points somewhere into inventory */
600                 while ((pick = pick->nobj) != 0)
601                     if (pick->otyp == PICK_AXE)
602                         ++cnt;
603             } else { /* assert(mattock != 0) */
604                 tool = "mattock";
605                 while ((mattock = mattock->nobj) != 0)
606                     if (mattock->otyp == DWARVISH_MATTOCK)
607                         ++cnt;
608                 /* [ALI] Shopkeeper identifies mattock(s) */
609                 if (!Blind)
610                     makeknown(DWARVISH_MATTOCK);
611             }
612             verbalize(NOTANGRY(shkp)
613                           ? "Will you please leave your %s%s outside?"
614                           : "Leave the %s%s outside.",
615                       tool, plur(cnt));
616             should_block = TRUE;
617         } else if (u.usteed) {
618             verbalize(NOTANGRY(shkp) ? "Will you please leave %s outside?"
619                                      : "Leave %s outside.",
620                       y_monnam(u.usteed));
621             should_block = TRUE;
622         } else {
623             should_block =
624                 (Fast && (sobj_at(PICK_AXE, u.ux, u.uy)
625                           || sobj_at(DWARVISH_MATTOCK, u.ux, u.uy)));
626         }
627         if (should_block)
628             (void) dochug(shkp); /* shk gets extra move */
629     }
630     return;
631 }
632
633 /* called when removing a pick-axe or mattock from a container */
634 void
635 pick_pick(obj)
636 struct obj *obj;
637 {
638     struct monst *shkp;
639
640     if (obj->unpaid || !is_pick(obj))
641         return;
642     shkp = shop_keeper(*u.ushops);
643     if (shkp && inhishop(shkp) && !muteshk(shkp)) {
644         static NEARDATA long pickmovetime = 0L;
645
646         /* if you bring a sack of N picks into a shop to sell,
647            don't repeat this N times when they're taken out */
648         if (moves != pickmovetime)
649             verbalize("You sneaky %s!  Get out of here with that pick!",
650                       cad(FALSE));
651         pickmovetime = moves;
652     }
653 }
654
655 /*
656    Decide whether two unpaid items are mergable; caller is responsible for
657    making sure they're unpaid and the same type of object; we check the price
658    quoted by the shopkeeper and also that they both belong to the same shk.
659  */
660 boolean
661 same_price(obj1, obj2)
662 struct obj *obj1, *obj2;
663 {
664     register struct monst *shkp1, *shkp2;
665     struct bill_x *bp1 = 0, *bp2 = 0;
666     boolean are_mergable = FALSE;
667
668     /* look up the first object by finding shk whose bill it's on */
669     for (shkp1 = next_shkp(fmon, TRUE); shkp1;
670          shkp1 = next_shkp(shkp1->nmon, TRUE))
671         if ((bp1 = onbill(obj1, shkp1, TRUE)) != 0)
672             break;
673     /* second object is probably owned by same shk; if not, look harder */
674     if (shkp1 && (bp2 = onbill(obj2, shkp1, TRUE)) != 0) {
675         shkp2 = shkp1;
676     } else {
677         for (shkp2 = next_shkp(fmon, TRUE); shkp2;
678              shkp2 = next_shkp(shkp2->nmon, TRUE))
679             if ((bp2 = onbill(obj2, shkp2, TRUE)) != 0)
680                 break;
681     }
682
683     if (!bp1 || !bp2)
684         impossible("same_price: object wasn't on any bill!");
685     else
686         are_mergable = (shkp1 == shkp2 && bp1->price == bp2->price);
687     return are_mergable;
688 }
689
690 /*
691  * Figure out how much is owed to a given shopkeeper.
692  * At present, we ignore any amount robbed from the shop, to avoid
693  * turning the `$' command into a way to discover that the current
694  * level is bones data which has a shk on the warpath.
695  */
696 STATIC_OVL long
697 shop_debt(eshkp)
698 struct eshk *eshkp;
699 {
700     struct bill_x *bp;
701     int ct;
702     long debt = eshkp->debit;
703
704     for (bp = eshkp->bill_p, ct = eshkp->billct; ct > 0; bp++, ct--)
705         debt += bp->price * bp->bquan;
706     return debt;
707 }
708
709 /* called in response to the `$' command */
710 void
711 shopper_financial_report()
712 {
713     struct monst *shkp, *this_shkp = shop_keeper(inside_shop(u.ux, u.uy));
714     struct eshk *eshkp;
715     long amt;
716     int pass;
717
718     eshkp = this_shkp ? ESHK(this_shkp) : 0;
719     if (eshkp && !(eshkp->credit || shop_debt(eshkp))) {
720         You("have no credit or debt in here.");
721         this_shkp = 0; /* skip first pass */
722     }
723
724     /* pass 0: report for the shop we're currently in, if any;
725        pass 1: report for all other shops on this level. */
726     for (pass = this_shkp ? 0 : 1; pass <= 1; pass++)
727         for (shkp = next_shkp(fmon, FALSE); shkp;
728              shkp = next_shkp(shkp->nmon, FALSE)) {
729             if ((shkp != this_shkp) ^ pass)
730                 continue;
731             eshkp = ESHK(shkp);
732             if ((amt = eshkp->credit) != 0)
733                 You("have %ld %s credit at %s %s.", amt, currency(amt),
734                     s_suffix(shkname(shkp)),
735                     shtypes[eshkp->shoptype - SHOPBASE].name);
736             else if (shkp == this_shkp)
737                 You("have no credit in here.");
738             if ((amt = shop_debt(eshkp)) != 0)
739                 You("owe %s %ld %s.", shkname(shkp), amt, currency(amt));
740             else if (shkp == this_shkp)
741                 You("don't owe any money here.");
742         }
743 }
744
745 int
746 inhishop(mtmp)
747 register struct monst *mtmp;
748 {
749     struct eshk *eshkp = ESHK(mtmp);
750
751     return (index(in_rooms(mtmp->mx, mtmp->my, SHOPBASE), eshkp->shoproom)
752             && on_level(&eshkp->shoplevel, &u.uz));
753 }
754
755 struct monst *
756 shop_keeper(rmno)
757 register char rmno;
758 {
759     struct monst *shkp =
760         rmno >= ROOMOFFSET ? rooms[rmno - ROOMOFFSET].resident : 0;
761
762     if (shkp) {
763         if (NOTANGRY(shkp)) {
764             if (ESHK(shkp)->surcharge)
765                 pacify_shk(shkp);
766         } else {
767             if (!ESHK(shkp)->surcharge)
768                 rile_shk(shkp);
769         }
770     }
771     return shkp;
772 }
773
774 boolean
775 tended_shop(sroom)
776 register struct mkroom *sroom;
777 {
778     register struct monst *mtmp = sroom->resident;
779
780     if (!mtmp)
781         return FALSE;
782     else
783         return (boolean) inhishop(mtmp);
784 }
785
786 STATIC_OVL struct bill_x *
787 onbill(obj, shkp, silent)
788 register struct obj *obj;
789 register struct monst *shkp;
790 register boolean silent;
791 {
792     if (shkp) {
793         register struct bill_x *bp = ESHK(shkp)->bill_p;
794         register int ct = ESHK(shkp)->billct;
795
796         while (--ct >= 0)
797             if (bp->bo_id == obj->o_id) {
798                 if (!obj->unpaid)
799                     pline("onbill: paid obj on bill?");
800                 return bp;
801             } else
802                 bp++;
803     }
804     if (obj->unpaid & !silent)
805         pline("onbill: unpaid obj not on bill?");
806     return (struct bill_x *) 0;
807 }
808
809 /* check whether an object or any of its contents belongs to a shop */
810 boolean
811 is_unpaid(obj)
812 struct obj *obj;
813 {
814     return (boolean) (obj->unpaid
815                       || (Has_contents(obj) && count_unpaid(obj->cobj)));
816 }
817
818 /* Delete the contents of the given object. */
819 void
820 delete_contents(obj)
821 register struct obj *obj;
822 {
823     register struct obj *curr;
824
825     while ((curr = obj->cobj) != 0) {
826         obj_extract_self(curr);
827         obfree(curr, (struct obj *) 0);
828     }
829 }
830
831 /* called with two args on merge */
832 void
833 obfree(obj, merge)
834 register struct obj *obj, *merge;
835 {
836     register struct bill_x *bp;
837     register struct bill_x *bpm;
838     register struct monst *shkp;
839
840     if (obj->otyp == LEASH && obj->leashmon)
841         o_unleash(obj);
842     if (obj->oclass == FOOD_CLASS)
843         food_disappears(obj);
844     if (obj->oclass == SPBOOK_CLASS)
845         book_disappears(obj);
846     if (Has_contents(obj))
847         delete_contents(obj);
848
849     shkp = 0;
850     if (obj->unpaid) {
851         /* look for a shopkeeper who owns this object */
852         for (shkp = next_shkp(fmon, TRUE); shkp;
853              shkp = next_shkp(shkp->nmon, TRUE))
854             if (onbill(obj, shkp, TRUE))
855                 break;
856     }
857     /* sanity check, more or less */
858     if (!shkp)
859         shkp = shop_keeper(*u.ushops);
860     /*
861      * Note:  `shkp = shop_keeper(*u.ushops)' used to be
862      *    unconditional.  But obfree() is used all over
863      *    the place, so making its behavior be dependent
864      *    upon player location doesn't make much sense.
865      */
866
867     if ((bp = onbill(obj, shkp, FALSE)) != 0) {
868         if (!merge) {
869             bp->useup = 1;
870             obj->unpaid = 0; /* only for doinvbill */
871             add_to_billobjs(obj);
872             return;
873         }
874         bpm = onbill(merge, shkp, FALSE);
875         if (!bpm) {
876             /* this used to be a rename */
877             impossible("obfree: not on bill??");
878             return;
879         } else {
880             /* this was a merger */
881             bpm->bquan += bp->bquan;
882             ESHK(shkp)->billct--;
883 #ifdef DUMB
884             {
885                 /* DRS/NS 2.2.6 messes up -- Peter Kendell */
886                 int indx = ESHK(shkp)->billct;
887
888                 *bp = ESHK(shkp)->bill_p[indx];
889             }
890 #else
891             *bp = ESHK(shkp)->bill_p[ESHK(shkp)->billct];
892 #endif
893         }
894     }
895     if (obj->owornmask) {
896         impossible("obfree: deleting worn obj (%d: %ld)", obj->otyp,
897                    obj->owornmask);
898         /* unfortunately at this point we don't know whether worn mask
899            applied to hero or a monster or perhaps something bogus, so
900            can't call remove_worn_item() to get <X>_off() side-effects */
901         setnotworn(obj);
902     }
903     dealloc_obj(obj);
904 }
905
906 STATIC_OVL long
907 check_credit(tmp, shkp)
908 long tmp;
909 register struct monst *shkp;
910 {
911     long credit = ESHK(shkp)->credit;
912
913     if (credit == 0L) {
914         ; /* nothing to do; just 'return tmp;' */
915     } else if (credit >= tmp) {
916         pline_The("price is deducted from your credit.");
917         ESHK(shkp)->credit -= tmp;
918         tmp = 0L;
919     } else {
920         pline_The("price is partially covered by your credit.");
921         ESHK(shkp)->credit = 0L;
922         tmp -= credit;
923     }
924     return tmp;
925 }
926
927 STATIC_OVL void
928 pay(tmp, shkp)
929 long tmp;
930 register struct monst *shkp;
931 {
932     long robbed = ESHK(shkp)->robbed;
933     long balance = ((tmp <= 0L) ? tmp : check_credit(tmp, shkp));
934
935     if (balance > 0)
936         money2mon(shkp, balance);
937     else if (balance < 0)
938         money2u(shkp, -balance);
939     context.botl = 1;
940     if (robbed) {
941         robbed -= tmp;
942         if (robbed < 0)
943             robbed = 0L;
944         ESHK(shkp)->robbed = robbed;
945     }
946 }
947
948 /* return shkp to home position */
949 void
950 home_shk(shkp, killkops)
951 register struct monst *shkp;
952 register boolean killkops;
953 {
954     register xchar x = ESHK(shkp)->shk.x, y = ESHK(shkp)->shk.y;
955
956     (void) mnearto(shkp, x, y, TRUE);
957     level.flags.has_shop = 1;
958     if (killkops) {
959         kops_gone(TRUE);
960         pacify_guards();
961     }
962     after_shk_move(shkp);
963 }
964
965 STATIC_OVL boolean
966 angry_shk_exists()
967 {
968     register struct monst *shkp;
969
970     for (shkp = next_shkp(fmon, FALSE); shkp;
971          shkp = next_shkp(shkp->nmon, FALSE))
972         if (ANGRY(shkp))
973             return TRUE;
974     return FALSE;
975 }
976
977 /* remove previously applied surcharge from all billed items */
978 STATIC_OVL void
979 pacify_shk(shkp)
980 register struct monst *shkp;
981 {
982     NOTANGRY(shkp) = TRUE; /* make peaceful */
983     if (ESHK(shkp)->surcharge) {
984         register struct bill_x *bp = ESHK(shkp)->bill_p;
985         register int ct = ESHK(shkp)->billct;
986
987         ESHK(shkp)->surcharge = FALSE;
988         while (ct-- > 0) {
989             register long reduction = (bp->price + 3L) / 4L;
990             bp->price -= reduction; /* undo 33% increase */
991             bp++;
992         }
993     }
994 }
995
996 /* add aggravation surcharge to all billed items */
997 STATIC_OVL void
998 rile_shk(shkp)
999 register struct monst *shkp;
1000 {
1001     NOTANGRY(shkp) = FALSE; /* make angry */
1002     if (!ESHK(shkp)->surcharge) {
1003         register struct bill_x *bp = ESHK(shkp)->bill_p;
1004         register int ct = ESHK(shkp)->billct;
1005
1006         ESHK(shkp)->surcharge = TRUE;
1007         while (ct-- > 0) {
1008             register long surcharge = (bp->price + 2L) / 3L;
1009             bp->price += surcharge;
1010             bp++;
1011         }
1012     }
1013 }
1014
1015 /* wakeup and/or unparalyze shopkeeper */
1016 STATIC_OVL void
1017 rouse_shk(shkp, verbosely)
1018 struct monst *shkp;
1019 boolean verbosely;
1020 {
1021     if (!shkp->mcanmove || shkp->msleeping) {
1022         /* greed induced recovery... */
1023         if (verbosely && canspotmon(shkp))
1024             pline("%s %s.", Monnam(shkp),
1025                   shkp->msleeping ? "wakes up" : "can move again");
1026         shkp->msleeping = 0;
1027         shkp->mfrozen = 0;
1028         shkp->mcanmove = 1;
1029     }
1030 }
1031
1032 void
1033 make_happy_shk(shkp, silentkops)
1034 register struct monst *shkp;
1035 register boolean silentkops;
1036 {
1037     boolean wasmad = ANGRY(shkp);
1038     struct eshk *eshkp = ESHK(shkp);
1039
1040     pacify_shk(shkp);
1041     eshkp->following = 0;
1042     eshkp->robbed = 0L;
1043     if (!Role_if(PM_ROGUE))
1044         adjalign(sgn(u.ualign.type));
1045     if (!inhishop(shkp)) {
1046         char shk_nam[BUFSZ];
1047         boolean vanished = canseemon(shkp);
1048
1049         Strcpy(shk_nam, mon_nam(shkp));
1050         if (on_level(&eshkp->shoplevel, &u.uz)) {
1051             home_shk(shkp, FALSE);
1052             /* didn't disappear if shk can still be seen */
1053             if (canseemon(shkp))
1054                 vanished = FALSE;
1055         } else {
1056             /* if sensed, does disappear regardless whether seen */
1057             if (sensemon(shkp))
1058                 vanished = TRUE;
1059             /* can't act as porter for the Amulet, even if shk
1060                happens to be going farther down rather than up */
1061             mdrop_special_objs(shkp);
1062             /* arrive near shop's door */
1063             migrate_to_level(shkp, ledger_no(&eshkp->shoplevel),
1064                              MIGR_APPROX_XY, &eshkp->shd);
1065             /* dismiss kops on that level when shk arrives */
1066             eshkp->dismiss_kops = TRUE;
1067         }
1068         if (vanished)
1069             pline("Satisfied, %s suddenly disappears!", shk_nam);
1070     } else if (wasmad)
1071         pline("%s calms down.", Monnam(shkp));
1072
1073     make_happy_shoppers(silentkops);
1074 }
1075
1076 /* called by make_happy_shk() and also by losedogs() for migrating shk */
1077 void
1078 make_happy_shoppers(silentkops)
1079 boolean silentkops;
1080 {
1081     if (!angry_shk_exists()) {
1082         kops_gone(silentkops);
1083         pacify_guards();
1084     }
1085 }
1086
1087 void
1088 hot_pursuit(shkp)
1089 register struct monst *shkp;
1090 {
1091     if (!shkp->isshk)
1092         return;
1093
1094     rile_shk(shkp);
1095     (void) strncpy(ESHK(shkp)->customer, plname, PL_NSIZ);
1096     ESHK(shkp)->following = 1;
1097 }
1098
1099 /* used when the shkp is teleported or falls (ox == 0) out of his shop,
1100  * or when the player is not on a costly_spot and he
1101  * damages something inside the shop.  these conditions
1102  * must be checked by the calling function.
1103  */
1104 void
1105 make_angry_shk(shkp, ox, oy)
1106 register struct monst *shkp;
1107 register xchar ox, oy;
1108 {
1109     xchar sx, sy;
1110     struct eshk *eshkp = ESHK(shkp);
1111
1112     /* all pending shop transactions are now "past due" */
1113     if (eshkp->billct || eshkp->debit || eshkp->loan || eshkp->credit) {
1114         eshkp->robbed += (addupbill(shkp) + eshkp->debit + eshkp->loan);
1115         eshkp->robbed -= eshkp->credit;
1116         if (eshkp->robbed < 0L)
1117             eshkp->robbed = 0L;
1118         /* billct, debit, loan, and credit will be cleared by setpaid */
1119         setpaid(shkp);
1120     }
1121
1122     /* If you just used a wand of teleportation to send the shk away, you
1123        might not be able to see her any more.  Monnam would yield "it",
1124        which makes this message look pretty silly, so temporarily restore
1125        her original location during the call to Monnam. */
1126     sx = shkp->mx, sy = shkp->my;
1127     if (isok(ox, oy) && cansee(ox, oy) && !cansee(sx, sy))
1128         shkp->mx = ox, shkp->my = oy;
1129     pline("%s %s!", Monnam(shkp), !ANGRY(shkp) ? "gets angry" : "is furious");
1130     shkp->mx = sx, shkp->my = sy;
1131     hot_pursuit(shkp);
1132 }
1133
1134 STATIC_VAR const char no_money[] = "Moreover, you%s have no money.";
1135 STATIC_VAR const char not_enough_money[] =
1136     "Besides, you don't have enough to interest %s.";
1137
1138 STATIC_OVL long
1139 cheapest_item(shkp) /* delivers the cheapest item on the list */
1140 register struct monst *shkp;
1141 {
1142     register int ct = ESHK(shkp)->billct;
1143     register struct bill_x *bp = ESHK(shkp)->bill_p;
1144     register long gmin = (bp->price * bp->bquan);
1145
1146     while (ct--) {
1147         if (bp->price * bp->bquan < gmin)
1148             gmin = bp->price * bp->bquan;
1149         bp++;
1150     }
1151     return gmin;
1152 }
1153
1154 int
1155 dopay()
1156 {
1157     register struct eshk *eshkp;
1158     register struct monst *shkp;
1159     struct monst *nxtm, *resident;
1160     long ltmp;
1161     long umoney;
1162     int pass, tmp, sk = 0, seensk = 0;
1163     boolean paid = FALSE, stashed_gold = (hidden_gold() > 0L);
1164
1165     multi = 0;
1166
1167     /* Find how many shk's there are, how many are in
1168      * sight, and are you in a shop room with one.
1169      */
1170     nxtm = resident = 0;
1171     for (shkp = next_shkp(fmon, FALSE); shkp;
1172          shkp = next_shkp(shkp->nmon, FALSE)) {
1173         sk++;
1174         if (ANGRY(shkp) && distu(shkp->mx, shkp->my) <= 2)
1175             nxtm = shkp;
1176         if (canspotmon(shkp))
1177             seensk++;
1178         if (inhishop(shkp) && (*u.ushops == ESHK(shkp)->shoproom))
1179             resident = shkp;
1180     }
1181
1182     if (nxtm) {      /* Player should always appease an */
1183         shkp = nxtm; /* irate shk standing next to them. */
1184         goto proceed;
1185     }
1186
1187     if ((!sk && (!Blind || Blind_telepat)) || (!Blind && !seensk)) {
1188         There("appears to be no shopkeeper here to receive your payment.");
1189         return 0;
1190     }
1191
1192     if (!seensk) {
1193         You_cant("see...");
1194         return 0;
1195     }
1196
1197     /* The usual case.  Allow paying at a distance when
1198      * inside a tended shop.  Should we change that?
1199      */
1200     if (sk == 1 && resident) {
1201         shkp = resident;
1202         goto proceed;
1203     }
1204
1205     if (seensk == 1) {
1206         for (shkp = next_shkp(fmon, FALSE); shkp;
1207              shkp = next_shkp(shkp->nmon, FALSE))
1208             if (canspotmon(shkp))
1209                 break;
1210         if (shkp != resident && distu(shkp->mx, shkp->my) > 2) {
1211             pline("%s is not near enough to receive your payment.",
1212                   Monnam(shkp));
1213             return 0;
1214         }
1215     } else {
1216         struct monst *mtmp;
1217         coord cc;
1218         int cx, cy;
1219
1220         pline("Pay whom?");
1221         cc.x = u.ux;
1222         cc.y = u.uy;
1223         if (getpos(&cc, TRUE, "the creature you want to pay") < 0)
1224             return 0; /* player pressed ESC */
1225         cx = cc.x;
1226         cy = cc.y;
1227         if (cx < 0) {
1228             pline("Try again...");
1229             return 0;
1230         }
1231         if (u.ux == cx && u.uy == cy) {
1232             You("are generous to yourself.");
1233             return 0;
1234         }
1235         mtmp = m_at(cx, cy);
1236         if (!mtmp) {
1237             There("is no one there to receive your payment.");
1238             return 0;
1239         }
1240         if (!mtmp->isshk) {
1241             pline("%s is not interested in your payment.", Monnam(mtmp));
1242             return 0;
1243         }
1244         if (mtmp != resident && distu(mtmp->mx, mtmp->my) > 2) {
1245             pline("%s is too far to receive your payment.", Monnam(mtmp));
1246             return 0;
1247         }
1248         shkp = mtmp;
1249     }
1250
1251     if (!shkp) {
1252         debugpline0("dopay: null shkp.");
1253         return 0;
1254     }
1255 proceed:
1256     eshkp = ESHK(shkp);
1257     ltmp = eshkp->robbed;
1258
1259     /* wake sleeping shk when someone who owes money offers payment */
1260     if (ltmp || eshkp->billct || eshkp->debit)
1261         rouse_shk(shkp, TRUE);
1262
1263     if (!shkp->mcanmove || shkp->msleeping) { /* still asleep/paralyzed */
1264         pline("%s %s.", Monnam(shkp),
1265               rn2(2) ? "seems to be napping" : "doesn't respond");
1266         return 0;
1267     }
1268
1269     if (shkp != resident && NOTANGRY(shkp)) {
1270         umoney = money_cnt(invent);
1271         if (!ltmp)
1272             You("do not owe %s anything.", mon_nam(shkp));
1273         else if (!umoney) {
1274             You("%shave no money.", stashed_gold ? "seem to " : "");
1275             if (stashed_gold)
1276                 pline("But you have some gold stashed away.");
1277         } else {
1278             if (umoney > ltmp) {
1279                 You("give %s the %ld gold piece%s %s asked for.",
1280                     shkname(shkp), ltmp, plur(ltmp), mhe(shkp));
1281                 pay(ltmp, shkp);
1282             } else {
1283                 You("give %s all your%s gold.", shkname(shkp),
1284                     stashed_gold ? " openly kept" : "");
1285                 pay(umoney, shkp);
1286                 if (stashed_gold)
1287                     pline("But you have hidden gold!");
1288             }
1289             if ((umoney < ltmp / 2L) || (umoney < ltmp && stashed_gold))
1290                 pline("Unfortunately, %s doesn't look satisfied.", mhe(shkp));
1291             else
1292                 make_happy_shk(shkp, FALSE);
1293         }
1294         return 1;
1295     }
1296
1297     /* ltmp is still eshkp->robbed here */
1298     if (!eshkp->billct && !eshkp->debit) {
1299         umoney = money_cnt(invent);
1300         if (!ltmp && NOTANGRY(shkp)) {
1301             You("do not owe %s anything.", shkname(shkp));
1302             if (!umoney)
1303                 pline(no_money, stashed_gold ? " seem to" : "");
1304         } else if (ltmp) {
1305             pline("%s is after blood, not money!", shkname(shkp));
1306             if (umoney < ltmp / 2L || (umoney < ltmp && stashed_gold)) {
1307                 if (!umoney)
1308                     pline(no_money, stashed_gold ? " seem to" : "");
1309                 else
1310                     pline(not_enough_money, mhim(shkp));
1311                 return 1;
1312             }
1313             pline("But since %s shop has been robbed recently,", mhis(shkp));
1314             pline("you %scompensate %s for %s losses.",
1315                   (umoney < ltmp) ? "partially " : "", shkname(shkp),
1316                   mhis(shkp));
1317             pay(umoney < ltmp ? umoney : ltmp, shkp);
1318             make_happy_shk(shkp, FALSE);
1319         } else {
1320             /* shopkeeper is angry, but has not been robbed --
1321              * door broken, attacked, etc. */
1322             pline("%s is after your hide, not your money!", Monnam(shkp));
1323             if (umoney < 1000L) {
1324                 if (!umoney)
1325                     pline(no_money, stashed_gold ? " seem to" : "");
1326                 else
1327                     pline(not_enough_money, mhim(shkp));
1328                 return 1;
1329             }
1330             You("try to appease %s by giving %s 1000 gold pieces.",
1331                 x_monnam(shkp, ARTICLE_THE, "angry", 0, FALSE), mhim(shkp));
1332             pay(1000L, shkp);
1333             if (strncmp(eshkp->customer, plname, PL_NSIZ) || rn2(3))
1334                 make_happy_shk(shkp, FALSE);
1335             else
1336                 pline("But %s is as angry as ever.", shkname(shkp));
1337         }
1338         return 1;
1339     }
1340     if (shkp != resident) {
1341         impossible("dopay: not to shopkeeper?");
1342         if (resident)
1343             setpaid(resident);
1344         return 0;
1345     }
1346     /* pay debt, if any, first */
1347     if (eshkp->debit) {
1348         long dtmp = eshkp->debit;
1349         long loan = eshkp->loan;
1350         char sbuf[BUFSZ];
1351         umoney = money_cnt(invent);
1352         Sprintf(sbuf, "You owe %s %ld %s ", shkname(shkp), dtmp,
1353                 currency(dtmp));
1354         if (loan) {
1355             if (loan == dtmp)
1356                 Strcat(sbuf, "you picked up in the store.");
1357             else
1358                 Strcat(sbuf,
1359                        "for gold picked up and the use of merchandise.");
1360         } else
1361             Strcat(sbuf, "for the use of merchandise.");
1362         pline1(sbuf);
1363         if (umoney + eshkp->credit < dtmp) {
1364             pline("But you don't%s have enough gold%s.",
1365                   stashed_gold ? " seem to" : "",
1366                   eshkp->credit ? " or credit" : "");
1367             return 1;
1368         } else {
1369             if (eshkp->credit >= dtmp) {
1370                 eshkp->credit -= dtmp;
1371                 eshkp->debit = 0L;
1372                 eshkp->loan = 0L;
1373                 Your("debt is covered by your credit.");
1374             } else if (!eshkp->credit) {
1375                 money2mon(shkp, dtmp);
1376                 eshkp->debit = 0L;
1377                 eshkp->loan = 0L;
1378                 You("pay that debt.");
1379                 context.botl = 1;
1380             } else {
1381                 dtmp -= eshkp->credit;
1382                 eshkp->credit = 0L;
1383                 money2mon(shkp, dtmp);
1384                 eshkp->debit = 0L;
1385                 eshkp->loan = 0L;
1386                 pline("That debt is partially offset by your credit.");
1387                 You("pay the remainder.");
1388                 context.botl = 1;
1389             }
1390             paid = TRUE;
1391         }
1392     }
1393     /* now check items on bill */
1394     if (eshkp->billct) {
1395         register boolean itemize;
1396         int iprompt;
1397         umoney = money_cnt(invent);
1398         if (!umoney && !eshkp->credit) {
1399             You("%shave no money or credit%s.",
1400                 stashed_gold ? "seem to " : "", paid ? " left" : "");
1401             return 0;
1402         }
1403         if ((umoney + eshkp->credit) < cheapest_item(shkp)) {
1404             You("don't have enough money to buy%s the item%s you picked.",
1405                 eshkp->billct > 1 ? " any of" : "", plur(eshkp->billct));
1406             if (stashed_gold)
1407                 pline("Maybe you have some gold stashed away?");
1408             return 0;
1409         }
1410
1411         /* this isn't quite right; it itemizes without asking if the
1412          * single item on the bill is partly used up and partly unpaid */
1413         iprompt = (eshkp->billct > 1 ? ynq("Itemized billing?") : 'y');
1414         itemize = (iprompt == 'y');
1415         if (iprompt == 'q')
1416             goto thanks;
1417
1418         for (pass = 0; pass <= 1; pass++) {
1419             tmp = 0;
1420             while (tmp < eshkp->billct) {
1421                 struct obj *otmp;
1422                 register struct bill_x *bp = &(eshkp->bill_p[tmp]);
1423
1424                 /* find the object on one of the lists */
1425                 if ((otmp = bp_to_obj(bp)) != 0) {
1426                     /* if completely used up, object quantity is stale;
1427                        restoring it to its original value here avoids
1428                        making the partly-used-up code more complicated */
1429                     if (bp->useup)
1430                         otmp->quan = bp->bquan;
1431                 } else {
1432                     impossible("Shopkeeper administration out of order.");
1433                     setpaid(shkp); /* be nice to the player */
1434                     return 1;
1435                 }
1436                 if (pass == bp->useup && otmp->quan == bp->bquan) {
1437                     /* pay for used-up items on first pass and others
1438                      * on second, so player will be stuck in the store
1439                      * less often; things which are partly used up
1440                      * are processed on both passes */
1441                     tmp++;
1442                 } else {
1443                     switch (dopayobj(shkp, bp, &otmp, pass, itemize)) {
1444                     case PAY_CANT:
1445                         return 1; /*break*/
1446                     case PAY_BROKE:
1447                         paid = TRUE;
1448                         goto thanks; /*break*/
1449                     case PAY_SKIP:
1450                         tmp++;
1451                         continue; /*break*/
1452                     case PAY_SOME:
1453                         paid = TRUE;
1454                         if (itemize)
1455                             bot();
1456                         continue; /*break*/
1457                     case PAY_BUY:
1458                         paid = TRUE;
1459                         break;
1460                     }
1461                     if (itemize)
1462                         bot();
1463                     *bp = eshkp->bill_p[--eshkp->billct];
1464                 }
1465             }
1466         }
1467     thanks:
1468         if (!itemize)
1469             update_inventory(); /* Done in dopayobj() if itemize. */
1470     }
1471     if (!ANGRY(shkp) && paid && !muteshk(shkp))
1472         verbalize("Thank you for shopping in %s %s!", s_suffix(shkname(shkp)),
1473                   shtypes[eshkp->shoptype - SHOPBASE].name);
1474     return 1;
1475 }
1476
1477 /* return 2 if used-up portion paid
1478  *        1 if paid successfully
1479  *        0 if not enough money
1480  *       -1 if skip this object
1481  *       -2 if no money/credit left
1482  */
1483 STATIC_OVL int
1484 dopayobj(shkp, bp, obj_p, which, itemize)
1485 register struct monst *shkp;
1486 register struct bill_x *bp;
1487 struct obj **obj_p;
1488 int which; /* 0 => used-up item, 1 => other (unpaid or lost) */
1489 boolean itemize;
1490 {
1491     register struct obj *obj = *obj_p;
1492     long ltmp, quan, save_quan;
1493     long umoney = money_cnt(invent);
1494     int buy;
1495     boolean stashed_gold = (hidden_gold() > 0L), consumed = (which == 0);
1496
1497     if (!obj->unpaid && !bp->useup) {
1498         impossible("Paid object on bill??");
1499         return PAY_BUY;
1500     }
1501     if (itemize && umoney + ESHK(shkp)->credit == 0L) {
1502         You("%shave no money or credit left.",
1503             stashed_gold ? "seem to " : "");
1504         return PAY_BROKE;
1505     }
1506     /* we may need to temporarily adjust the object, if part of the
1507        original quantity has been used up but part remains unpaid  */
1508     save_quan = obj->quan;
1509     if (consumed) {
1510         /* either completely used up (simple), or split needed */
1511         quan = bp->bquan;
1512         if (quan > obj->quan) /* difference is amount used up */
1513             quan -= obj->quan;
1514     } else {
1515         /* dealing with ordinary unpaid item */
1516         quan = obj->quan;
1517     }
1518     obj->quan = quan;        /* to be used by doname() */
1519     obj->unpaid = 0;         /* ditto */
1520     iflags.suppress_price++; /* affects containers */
1521     ltmp = bp->price * quan;
1522     buy = PAY_BUY; /* flag; if changed then return early */
1523
1524     if (itemize) {
1525         char qbuf[BUFSZ], qsfx[BUFSZ];
1526
1527         Sprintf(qsfx, " for %ld %s.  Pay?", ltmp, currency(ltmp));
1528         (void) safe_qbuf(qbuf, (char *) 0, qsfx, obj,
1529                          (quan == 1L) ? Doname2 : doname, ansimpleoname,
1530                          (quan == 1L) ? "that" : "those");
1531         if (yn(qbuf) == 'n') {
1532             buy = PAY_SKIP;                         /* don't want to buy */
1533         } else if (quan < bp->bquan && !consumed) { /* partly used goods */
1534             obj->quan = bp->bquan - save_quan;      /* used up amount */
1535             verbalize("%s for the other %s before buying %s.",
1536                       ANGRY(shkp) ? "Pay" : "Please pay",
1537                       simpleonames(obj), /* short name suffices */
1538                       save_quan > 1L ? "these" : "this one");
1539             buy = PAY_SKIP; /* shk won't sell */
1540         }
1541     }
1542     if (buy == PAY_BUY && umoney + ESHK(shkp)->credit < ltmp) {
1543         You("don't%s have gold%s enough to pay for %s.",
1544             stashed_gold ? " seem to" : "",
1545             (ESHK(shkp)->credit > 0L) ? " or credit" : "",
1546             thesimpleoname(obj));
1547         buy = itemize ? PAY_SKIP : PAY_CANT;
1548     }
1549
1550     if (buy != PAY_BUY) {
1551         /* restore unpaid object to original state */
1552         obj->quan = save_quan;
1553         obj->unpaid = 1;
1554         iflags.suppress_price--;
1555         return buy;
1556     }
1557
1558     pay(ltmp, shkp);
1559     shk_names_obj(shkp, obj,
1560                   consumed ? "paid for %s at a cost of %ld gold piece%s.%s"
1561                            : "bought %s for %ld gold piece%s.%s",
1562                   ltmp, "");
1563     obj->quan = save_quan; /* restore original count */
1564     /* quan => amount just bought, save_quan => remaining unpaid count */
1565     if (consumed) {
1566         if (quan != bp->bquan) {
1567             /* eliminate used-up portion; remainder is still unpaid */
1568             bp->bquan = obj->quan;
1569             obj->unpaid = 1;
1570             bp->useup = 0;
1571             buy = PAY_SOME;
1572         } else { /* completely used-up, so get rid of it */
1573             obj_extract_self(obj);
1574             /* assert( obj == *obj_p ); */
1575             dealloc_obj(obj);
1576             *obj_p = 0; /* destroy pointer to freed object */
1577         }
1578     } else if (itemize)
1579         update_inventory(); /* Done just once in dopay() if !itemize. */
1580     iflags.suppress_price--;
1581     return buy;
1582 }
1583
1584 static struct repo { /* repossession context */
1585     struct monst *shopkeeper;
1586     coord location;
1587 } repo;
1588
1589 /* routine called after dying (or quitting) */
1590 boolean
1591 paybill(croaked)
1592 int croaked; /* -1: escaped dungeon; 0: quit; 1: died */
1593 {
1594     struct monst *mtmp, *mtmp2, *firstshk, *resident, *creditor, *hostile,
1595         *localshk;
1596     struct eshk *eshkp;
1597     boolean taken = FALSE, local;
1598     int numsk = 0;
1599
1600     /* if we escaped from the dungeon, shopkeepers can't reach us;
1601        shops don't occur on level 1, but this could happen if hero
1602        level teleports out of the dungeon and manages not to die */
1603     if (croaked < 0)
1604         return FALSE;
1605     /* [should probably also return false when dead hero has been
1606         petrified since shk shouldn't be able to grab inventory
1607         which has been shut inside a statue] */
1608
1609     /* this is where inventory will end up if any shk takes it */
1610     repo.location.x = repo.location.y = 0;
1611     repo.shopkeeper = 0;
1612
1613     /*
1614      * Scan all shopkeepers on the level, to prioritize them:
1615      * 1) keeper of shop hero is inside and who is owed money,
1616      * 2) keeper of shop hero is inside who isn't owed any money,
1617      * 3) other shk who is owed money, 4) other shk who is angry,
1618      * 5) any shk local to this level, and if none is found,
1619      * 6) first shk on monster list (last resort; unlikely, since
1620      * any nonlocal shk will probably be in the owed category
1621      * and almost certainly be in the angry category).
1622      */
1623     resident = creditor = hostile = localshk = (struct monst *) 0;
1624     for (mtmp = next_shkp(fmon, FALSE); mtmp;
1625          mtmp = next_shkp(mtmp2, FALSE)) {
1626         mtmp2 = mtmp->nmon;
1627         eshkp = ESHK(mtmp);
1628         local = on_level(&eshkp->shoplevel, &u.uz);
1629         if (local && index(u.ushops, eshkp->shoproom)) {
1630             /* inside this shk's shop [there might be more than one
1631                resident shk if hero is standing in a breech of a shared
1632                wall, so give priority to one who's also owed money] */
1633             if (!resident || eshkp->billct || eshkp->debit || eshkp->robbed)
1634                 resident = mtmp;
1635         } else if (eshkp->billct || eshkp->debit || eshkp->robbed) {
1636             /* owe this shopkeeper money (might also owe others) */
1637             if (!creditor)
1638                 creditor = mtmp;
1639         } else if (eshkp->following || ANGRY(mtmp)) {
1640             /* this shopkeeper is antagonistic (others might be too) */
1641             if (!hostile)
1642                 hostile = mtmp;
1643         } else if (local) {
1644             /* this shopkeeper's shop is on current level */
1645             if (!localshk)
1646                 localshk = mtmp;
1647         }
1648     }
1649
1650     /* give highest priority shopkeeper first crack */
1651     firstshk = resident ? resident
1652                         : creditor ? creditor
1653                                    : hostile ? hostile
1654                                              : localshk;
1655     if (firstshk) {
1656         numsk++;
1657         taken = inherits(firstshk, numsk, croaked);
1658     }
1659
1660     /* now handle the rest */
1661     for (mtmp = next_shkp(fmon, FALSE); mtmp;
1662          mtmp = next_shkp(mtmp2, FALSE)) {
1663         mtmp2 = mtmp->nmon;
1664         eshkp = ESHK(mtmp);
1665         local = on_level(&eshkp->shoplevel, &u.uz);
1666         if (mtmp != firstshk) {
1667             numsk++;
1668             taken |= inherits(mtmp, numsk, croaked);
1669         }
1670         /* for bones: we don't want a shopless shk around */
1671         if (!local)
1672             mongone(mtmp);
1673     }
1674     return taken;
1675 }
1676
1677 STATIC_OVL boolean
1678 inherits(shkp, numsk, croaked)
1679 struct monst *shkp;
1680 int numsk;
1681 int croaked;
1682 {
1683     long loss = 0L;
1684     long umoney;
1685     struct eshk *eshkp = ESHK(shkp);
1686     boolean take = FALSE, taken = FALSE;
1687     unsigned save_minvis = shkp->minvis;
1688     int roomno = *u.ushops;
1689     char takes[BUFSZ];
1690
1691     shkp->minvis = 0;
1692     /* The simplifying principle is that first-come
1693        already took everything you had. */
1694     if (numsk > 1) {
1695         if (cansee(shkp->mx, shkp->my) && croaked) {
1696             takes[0] = '\0';
1697             if (has_head(shkp->data) && !rn2(2))
1698                 Sprintf(takes, ", shakes %s %s,", mhis(shkp),
1699                         mbodypart(shkp, HEAD));
1700             pline("%s %slooks at your corpse%s and %s.", Monnam(shkp),
1701                   (!shkp->mcanmove || shkp->msleeping) ? "wakes up, " : "",
1702                   takes, !inhishop(shkp) ? "disappears" : "sighs");
1703         }
1704         rouse_shk(shkp, FALSE); /* wake shk for bones */
1705         taken = (roomno == eshkp->shoproom);
1706         goto skip;
1707     }
1708
1709     /* get one case out of the way: you die in the shop, the */
1710     /* shopkeeper is peaceful, nothing stolen, nothing owed. */
1711     if (roomno == eshkp->shoproom && inhishop(shkp) && !eshkp->billct
1712         && !eshkp->robbed && !eshkp->debit && NOTANGRY(shkp)
1713         && !eshkp->following) {
1714         taken = (invent != 0);
1715         if (taken)
1716             pline("%s gratefully inherits all your possessions.",
1717                   shkname(shkp));
1718         set_repo_loc(shkp);
1719         goto clear;
1720     }
1721
1722     if (eshkp->billct || eshkp->debit || eshkp->robbed) {
1723         if (roomno == eshkp->shoproom && inhishop(shkp))
1724             loss = addupbill(shkp) + eshkp->debit;
1725         if (loss < eshkp->robbed)
1726             loss = eshkp->robbed;
1727         take = TRUE;
1728     }
1729
1730     if (eshkp->following || ANGRY(shkp) || take) {
1731         if (!invent)
1732             goto skip;
1733         umoney = money_cnt(invent);
1734         takes[0] = '\0';
1735         if (!shkp->mcanmove || shkp->msleeping)
1736             Strcat(takes, "wakes up and ");
1737         if (distu(shkp->mx, shkp->my) > 2)
1738             Strcat(takes, "comes and ");
1739         Strcat(takes, "takes");
1740
1741         if (loss > umoney || !loss || roomno == eshkp->shoproom) {
1742             eshkp->robbed -= umoney;
1743             if (eshkp->robbed < 0L)
1744                 eshkp->robbed = 0L;
1745             if (umoney > 0)
1746                 money2mon(shkp, umoney);
1747             context.botl = 1;
1748             pline("%s %s all your possessions.", shkname(shkp), takes);
1749             taken = TRUE;
1750             /* where to put player's invent (after disclosure) */
1751             set_repo_loc(shkp);
1752         } else {
1753             money2mon(shkp, loss);
1754             context.botl = 1;
1755             pline("%s %s the %ld %s %sowed %s.", Monnam(shkp), takes, loss,
1756                   currency(loss),
1757                   strncmp(eshkp->customer, plname, PL_NSIZ) ? "" : "you ",
1758                   shkp->female ? "her" : "him");
1759             /* shopkeeper has now been paid in full */
1760             pacify_shk(shkp);
1761             eshkp->following = 0;
1762             eshkp->robbed = 0L;
1763         }
1764     skip:
1765         /* in case we create bones */
1766         rouse_shk(shkp, FALSE); /* wake up */
1767         if (!inhishop(shkp))
1768             home_shk(shkp, FALSE);
1769     }
1770 clear:
1771     shkp->minvis = save_minvis;
1772     setpaid(shkp);
1773     return taken;
1774 }
1775
1776 STATIC_OVL void
1777 set_repo_loc(shkp)
1778 struct monst *shkp;
1779 {
1780     register xchar ox, oy;
1781     struct eshk *eshkp = ESHK(shkp);
1782
1783     /* if you're not in this shk's shop room, or if you're in its doorway
1784         or entry spot, then your gear gets dumped all the way inside */
1785     if (*u.ushops != eshkp->shoproom || IS_DOOR(levl[u.ux][u.uy].typ)
1786         || (u.ux == eshkp->shk.x && u.uy == eshkp->shk.y)) {
1787         /* shk.x,shk.y is the position immediately in
1788          * front of the door -- move in one more space
1789          */
1790         ox = eshkp->shk.x;
1791         oy = eshkp->shk.y;
1792         ox += sgn(ox - eshkp->shd.x);
1793         oy += sgn(oy - eshkp->shd.y);
1794     } else { /* already inside this shk's shop */
1795         ox = u.ux;
1796         oy = u.uy;
1797     }
1798     /* finish_paybill will deposit invent here */
1799     repo.location.x = ox;
1800     repo.location.y = oy;
1801     repo.shopkeeper = shkp;
1802 }
1803
1804 /* called at game exit, after inventory disclosure but before making bones */
1805 void
1806 finish_paybill()
1807 {
1808     struct monst *shkp = repo.shopkeeper;
1809     int ox = repo.location.x, oy = repo.location.y;
1810
1811 #if 0 /* don't bother */
1812     if (ox == 0 && oy == 0)
1813         impossible("finish_paybill: no location");
1814 #endif
1815     /* normally done by savebones(), but that's too late in this case */
1816     unleash_all();
1817     /* if hero has any gold left, take it into shopkeeper's possession */
1818     if (shkp) {
1819         long umoney = money_cnt(invent);
1820
1821         if (umoney)
1822             money2mon(shkp, umoney);
1823     }
1824     /* transfer rest of the character's inventory to the shop floor */
1825     drop_upon_death((struct monst *) 0, (struct obj *) 0, ox, oy);
1826 }
1827
1828 /* find obj on one of the lists */
1829 STATIC_OVL struct obj *
1830 bp_to_obj(bp)
1831 register struct bill_x *bp;
1832 {
1833     register struct obj *obj;
1834     register unsigned int id = bp->bo_id;
1835
1836     if (bp->useup)
1837         obj = o_on(id, billobjs);
1838     else
1839         obj = find_oid(id);
1840     return obj;
1841 }
1842
1843 /*
1844  * Look for o_id on all lists but billobj.  Return obj or NULL if not found.
1845  * Its OK for restore_timers() to call this function, there should not
1846  * be any timeouts on the billobjs chain.
1847  */
1848 struct obj *
1849 find_oid(id)
1850 unsigned id;
1851 {
1852     struct obj *obj;
1853     struct monst *mon, *mmtmp[3];
1854     int i;
1855
1856     /* first check various obj lists directly */
1857     if ((obj = o_on(id, invent)) != 0)
1858         return obj;
1859     if ((obj = o_on(id, fobj)) != 0)
1860         return obj;
1861     if ((obj = o_on(id, level.buriedobjlist)) != 0)
1862         return obj;
1863     if ((obj = o_on(id, migrating_objs)) != 0)
1864         return obj;
1865
1866     /* not found yet; check inventory for members of various monst lists */
1867     mmtmp[0] = fmon;
1868     mmtmp[1] = migrating_mons;
1869     mmtmp[2] = mydogs; /* for use during level changes */
1870     for (i = 0; i < 3; i++)
1871         for (mon = mmtmp[i]; mon; mon = mon->nmon)
1872             if ((obj = o_on(id, mon->minvent)) != 0)
1873                 return obj;
1874
1875     /* not found at all */
1876     return (struct obj *) 0;
1877 }
1878
1879 /* Returns the price of an arbitrary item in the shop.
1880    Returns 0 if the item doesn't belong to a shopkeeper. */
1881 long
1882 get_cost_of_shop_item(obj)
1883 register struct obj *obj;
1884 {
1885     struct monst *shkp;
1886     xchar x, y;
1887     long cost = 0L;
1888
1889     if (*u.ushops
1890         && obj->oclass != COIN_CLASS
1891         && obj != uball && obj != uchain
1892         && get_obj_location(obj, &x, &y, 0)
1893         && (obj->unpaid
1894             || (obj->where == OBJ_FLOOR
1895                 && !obj->no_charge && costly_spot(x, y)))
1896         && (shkp = shop_keeper(*in_rooms(x, y, SHOPBASE))) != 0
1897         && inhishop(shkp)) {
1898         cost = obj->quan * get_cost(obj, shkp);
1899         if (Has_contents(obj))
1900             cost += contained_cost(obj, shkp, 0L, FALSE, FALSE);
1901     }
1902     return cost;
1903 }
1904
1905 /* calculate the value that the shk will charge for [one of] an object */
1906 STATIC_OVL long
1907 get_cost(obj, shkp)
1908 register struct obj *obj;
1909 register struct monst *shkp; /* if angry, impose a surcharge */
1910 {
1911     long tmp = getprice(obj, FALSE),
1912          /* used to perform a single calculation even when multiple
1913             adjustments (unID'd, dunce/tourist, charisma) are made */
1914         multiplier = 1L, divisor = 1L;
1915
1916     if (!tmp)
1917         tmp = 5L;
1918     /* shopkeeper may notice if the player isn't very knowledgeable -
1919        especially when gem prices are concerned */
1920     if (!obj->dknown || !objects[obj->otyp].oc_name_known) {
1921         if (obj->oclass == GEM_CLASS
1922             && objects[obj->otyp].oc_material == GLASS) {
1923             int i;
1924             /* get a value that's 'random' from game to game, but the
1925                same within the same game */
1926             boolean pseudorand =
1927                 (((int) ubirthday % obj->otyp) >= obj->otyp / 2);
1928
1929             /* all gems are priced high - real or not */
1930             switch (obj->otyp - LAST_GEM) {
1931             case 1: /* white */
1932                 i = pseudorand ? DIAMOND : OPAL;
1933                 break;
1934             case 2: /* blue */
1935                 i = pseudorand ? SAPPHIRE : AQUAMARINE;
1936                 break;
1937             case 3: /* red */
1938                 i = pseudorand ? RUBY : JASPER;
1939                 break;
1940             case 4: /* yellowish brown */
1941                 i = pseudorand ? AMBER : TOPAZ;
1942                 break;
1943             case 5: /* orange */
1944                 i = pseudorand ? JACINTH : AGATE;
1945                 break;
1946             case 6: /* yellow */
1947                 i = pseudorand ? CITRINE : CHRYSOBERYL;
1948                 break;
1949             case 7: /* black */
1950                 i = pseudorand ? BLACK_OPAL : JET;
1951                 break;
1952             case 8: /* green */
1953                 i = pseudorand ? EMERALD : JADE;
1954                 break;
1955             case 9: /* violet */
1956                 i = pseudorand ? AMETHYST : FLUORITE;
1957                 break;
1958             default:
1959                 impossible("bad glass gem %d?", obj->otyp);
1960                 i = STRANGE_OBJECT;
1961                 break;
1962             }
1963             tmp = (long) objects[i].oc_cost;
1964         } else if (!(obj->o_id % 4)) {
1965             /* unid'd, arbitrarily impose surcharge: tmp *= 4/3 */
1966             multiplier *= 4L;
1967             divisor *= 3L;
1968         }
1969     }
1970     if (uarmh && uarmh->otyp == DUNCE_CAP)
1971         multiplier *= 4L, divisor *= 3L;
1972     else if ((Role_if(PM_TOURIST) && u.ulevel < (MAXULEV / 2))
1973              || (uarmu && !uarm && !uarmc)) /* touristy shirt visible */
1974         multiplier *= 4L, divisor *= 3L;
1975
1976     if (ACURR(A_CHA) > 18)
1977         divisor *= 2L;
1978     else if (ACURR(A_CHA) == 18)
1979         multiplier *= 2L, divisor *= 3L;
1980     else if (ACURR(A_CHA) >= 16)
1981         multiplier *= 3L, divisor *= 4L;
1982     else if (ACURR(A_CHA) <= 5)
1983         multiplier *= 2L;
1984     else if (ACURR(A_CHA) <= 7)
1985         multiplier *= 3L, divisor *= 2L;
1986     else if (ACURR(A_CHA) <= 10)
1987         multiplier *= 4L, divisor *= 3L;
1988
1989     /* tmp = (tmp * multiplier) / divisor [with roundoff tweak] */
1990     tmp *= multiplier;
1991     if (divisor > 1L) {
1992         /* tmp = (((tmp * 10) / divisor) + 5) / 10 */
1993         tmp *= 10L;
1994         tmp /= divisor;
1995         tmp += 5L;
1996         tmp /= 10L;
1997     }
1998
1999     if (tmp <= 0L)
2000         tmp = 1L;
2001     /* the artifact prices in artilist[] are also used as a score bonus;
2002        inflate their shop price here without affecting score calculation */
2003     if (obj->oartifact)
2004         tmp *= 4L;
2005
2006     /* anger surcharge should match rile_shk's, so we do it separately
2007        from the multiplier/divisor calculation */
2008     if (shkp && ESHK(shkp)->surcharge)
2009         tmp += (tmp + 2L) / 3L;
2010     return tmp;
2011 }
2012
2013 /* returns the price of a container's content.  the price
2014  * of the "top" container is added in the calling functions.
2015  * a different price quoted for selling as vs. buying.
2016  */
2017 long
2018 contained_cost(obj, shkp, price, usell, unpaid_only)
2019 struct obj *obj;
2020 struct monst *shkp;
2021 long price;
2022 boolean usell;
2023 boolean unpaid_only;
2024 {
2025     register struct obj *otmp;
2026
2027     /* price of contained objects; "top" container handled by caller */
2028     for (otmp = obj->cobj; otmp; otmp = otmp->nobj) {
2029         if (otmp->oclass == COIN_CLASS)
2030             continue;
2031
2032         if (usell) {
2033             if (saleable(shkp, otmp) && !otmp->unpaid
2034                 && otmp->oclass != BALL_CLASS
2035                 && !(otmp->oclass == FOOD_CLASS && otmp->oeaten)
2036                 && !(Is_candle(otmp)
2037                      && otmp->age < 20L * (long) objects[otmp->otyp].oc_cost))
2038                 price += set_cost(otmp, shkp);
2039         } else if (!otmp->no_charge && (otmp->unpaid || !unpaid_only)) {
2040             price += get_cost(otmp, shkp) * otmp->quan;
2041         }
2042
2043         if (Has_contents(otmp))
2044             price = contained_cost(otmp, shkp, price, usell, unpaid_only);
2045     }
2046
2047     return price;
2048 }
2049
2050 long
2051 contained_gold(obj)
2052 register struct obj *obj;
2053 {
2054     register struct obj *otmp;
2055     register long value = 0L;
2056
2057     /* accumulate contained gold */
2058     for (otmp = obj->cobj; otmp; otmp = otmp->nobj)
2059         if (otmp->oclass == COIN_CLASS)
2060             value += otmp->quan;
2061         else if (Has_contents(otmp))
2062             value += contained_gold(otmp);
2063
2064     return value;
2065 }
2066
2067 STATIC_OVL void
2068 dropped_container(obj, shkp, sale)
2069 register struct obj *obj;
2070 register struct monst *shkp;
2071 register boolean sale;
2072 {
2073     register struct obj *otmp;
2074
2075     /* the "top" container is treated in the calling fn */
2076     for (otmp = obj->cobj; otmp; otmp = otmp->nobj) {
2077         if (otmp->oclass == COIN_CLASS)
2078             continue;
2079
2080         if (!otmp->unpaid && !(sale && saleable(shkp, otmp)))
2081             otmp->no_charge = 1;
2082
2083         if (Has_contents(otmp))
2084             dropped_container(otmp, shkp, sale);
2085     }
2086 }
2087
2088 void
2089 picked_container(obj)
2090 register struct obj *obj;
2091 {
2092     register struct obj *otmp;
2093
2094     /* the "top" container is treated in the calling fn */
2095     for (otmp = obj->cobj; otmp; otmp = otmp->nobj) {
2096         if (otmp->oclass == COIN_CLASS)
2097             continue;
2098
2099         if (otmp->no_charge)
2100             otmp->no_charge = 0;
2101
2102         if (Has_contents(otmp))
2103             picked_container(otmp);
2104     }
2105 }
2106
2107 STATIC_OVL boolean
2108 special_stock(obj, shkp, quietly)
2109 struct obj *obj;
2110 struct monst *shkp;
2111 boolean quietly;
2112 {
2113     /* for unique situations */
2114     if (ESHK(shkp)->shoptype == CANDLESHOP
2115         && obj->otyp == CANDELABRUM_OF_INVOCATION) {
2116         if (!quietly) {
2117             if (is_izchak(shkp, TRUE) && !u.uevent.invoked) {
2118                 verbalize("No thanks, I'd hang onto that if I were you.");
2119                 if (obj->spe < 7)
2120                     verbalize(
2121                              "You'll need %d%s candle%s to go along with it.",
2122                               (7 - obj->spe), (obj->spe > 0) ? " more" : "",
2123                               plur(7 - obj->spe));
2124                 /* [what if hero is already carrying enough candles?
2125                    should Izchak explain how to attach them instead] */
2126             } else {
2127                 verbalize("I won't stock that.  Take it out of here!");
2128             }
2129         }
2130         return TRUE;
2131     }
2132     return FALSE;
2133 }
2134
2135 /* calculate how much the shk will pay when buying [all of] an object */
2136 STATIC_OVL long
2137 set_cost(obj, shkp)
2138 register struct obj *obj;
2139 register struct monst *shkp;
2140 {
2141     long tmp = getprice(obj, TRUE) * obj->quan, multiplier = 1L, divisor = 1L;
2142
2143     if (uarmh && uarmh->otyp == DUNCE_CAP)
2144         divisor *= 3L;
2145     else if ((Role_if(PM_TOURIST) && u.ulevel < (MAXULEV / 2))
2146              || (uarmu && !uarm && !uarmc)) /* touristy shirt visible */
2147         divisor *= 3L;
2148     else
2149         divisor *= 2L;
2150
2151     /* shopkeeper may notice if the player isn't very knowledgeable -
2152        especially when gem prices are concerned */
2153     if (!obj->dknown || !objects[obj->otyp].oc_name_known) {
2154         if (obj->oclass == GEM_CLASS) {
2155             /* different shop keepers give different prices */
2156             if (objects[obj->otyp].oc_material == GEMSTONE
2157                 || objects[obj->otyp].oc_material == GLASS) {
2158                 tmp = (obj->otyp % (6 - shkp->m_id % 3));
2159                 tmp = (tmp + 3) * obj->quan;
2160             }
2161         } else if (tmp > 1L && !rn2(4))
2162             multiplier *= 3L, divisor *= 4L;
2163     }
2164
2165     if (tmp >= 1L) {
2166         /* [see get_cost()] */
2167         tmp *= multiplier;
2168         if (divisor > 1L) {
2169             tmp *= 10L;
2170             tmp /= divisor;
2171             tmp += 5L;
2172             tmp /= 10L;
2173         }
2174         /* avoid adjusting nonzero to zero */
2175         if (tmp < 1L)
2176             tmp = 1L;
2177     }
2178
2179     /* (no adjustment for angry shk here) */
2180     return tmp;
2181 }
2182
2183 /* called when an item's value has been enhanced; if it happens to be
2184    on any shop bill, update that bill to reflect the new higher price
2185    [if the new price drops for some reason, keep the old one in place] */
2186 void
2187 alter_cost(obj, amt)
2188 struct obj *obj;
2189 long amt; /* if 0, use regular shop pricing, otherwise force amount;
2190              if negative, use abs(amt) even if it's less than old cost */
2191 {
2192     struct bill_x *bp = 0;
2193     struct monst *shkp;
2194     long new_price;
2195
2196     for (shkp = next_shkp(fmon, TRUE); shkp; shkp = next_shkp(shkp, TRUE))
2197         if ((bp = onbill(obj, shkp, TRUE)) != 0) {
2198             new_price = !amt ? get_cost(obj, shkp) : (amt < 0L) ? -amt : amt;
2199             if (new_price > bp->price || amt < 0L) {
2200                 bp->price = new_price;
2201                 update_inventory();
2202             }
2203             break; /* done */
2204         }
2205     return;
2206 }
2207
2208 /* called from doinv(invent.c) for inventory of unpaid objects */
2209 long
2210 unpaid_cost(unp_obj, include_contents)
2211 struct obj *unp_obj; /* known to be unpaid or contain unpaid */
2212 boolean include_contents;
2213 {
2214     struct bill_x *bp = (struct bill_x *) 0;
2215     struct monst *shkp;
2216     long amt = 0L;
2217     xchar ox, oy;
2218
2219     if (!get_obj_location(unp_obj, &ox, &oy, BURIED_TOO | CONTAINED_TOO))
2220         ox = u.ux, oy = u.uy; /* (shouldn't happen) */
2221     if ((shkp = shop_keeper(*in_rooms(ox, oy, SHOPBASE))) != 0) {
2222         bp = onbill(unp_obj, shkp, TRUE);
2223     } else {
2224         /* didn't find shk?  try searching bills */
2225         for (shkp = next_shkp(fmon, TRUE); shkp;
2226              shkp = next_shkp(shkp->nmon, TRUE))
2227             if ((bp = onbill(unp_obj, shkp, TRUE)) != 0)
2228                 break;
2229     }
2230
2231     /* onbill() gave no message if unexpected problem occurred */
2232     if (!shkp || (unp_obj->unpaid && !bp)) {
2233         impossible("unpaid_cost: object wasn't on any bill.");
2234     } else {
2235         if (bp)
2236             amt = unp_obj->quan * bp->price;
2237         if (include_contents && Has_contents(unp_obj))
2238             amt = contained_cost(unp_obj, shkp, amt, FALSE, TRUE);
2239     }
2240     return amt;
2241 }
2242
2243 STATIC_OVL void
2244 add_one_tobill(obj, dummy, shkp)
2245 struct obj *obj;
2246 boolean dummy;
2247 struct monst *shkp;
2248 {
2249     struct eshk *eshkp;
2250     struct bill_x *bp;
2251     int bct;
2252
2253     if (!billable(&shkp, obj, *u.ushops, TRUE))
2254         return;
2255     eshkp = ESHK(shkp);
2256
2257     if (eshkp->billct == BILLSZ) {
2258         You("got that for free!");
2259         return;
2260     }
2261
2262     bct = eshkp->billct;
2263     bp = &(eshkp->bill_p[bct]);
2264     bp->bo_id = obj->o_id;
2265     bp->bquan = obj->quan;
2266     if (dummy) {              /* a dummy object must be inserted into  */
2267         bp->useup = 1;        /* the billobjs chain here.  crucial for */
2268         add_to_billobjs(obj); /* eating floorfood in shop.  see eat.c  */
2269     } else
2270         bp->useup = 0;
2271     bp->price = get_cost(obj, shkp);
2272     eshkp->billct++;
2273     obj->unpaid = 1;
2274 }
2275
2276 STATIC_OVL void
2277 add_to_billobjs(obj)
2278 struct obj *obj;
2279 {
2280     if (obj->where != OBJ_FREE)
2281         panic("add_to_billobjs: obj not free");
2282     if (obj->timed)
2283         obj_stop_timers(obj);
2284
2285     obj->nobj = billobjs;
2286     billobjs = obj;
2287     obj->where = OBJ_ONBILL;
2288 }
2289
2290 /* recursive billing of objects within containers. */
2291 STATIC_OVL void
2292 bill_box_content(obj, ininv, dummy, shkp)
2293 register struct obj *obj;
2294 register boolean ininv, dummy;
2295 register struct monst *shkp;
2296 {
2297     register struct obj *otmp;
2298
2299     for (otmp = obj->cobj; otmp; otmp = otmp->nobj) {
2300         if (otmp->oclass == COIN_CLASS)
2301             continue;
2302
2303         /* the "top" box is added in addtobill() */
2304         if (!otmp->no_charge)
2305             add_one_tobill(otmp, dummy, shkp);
2306         if (Has_contents(otmp))
2307             bill_box_content(otmp, ininv, dummy, shkp);
2308     }
2309 }
2310
2311 /* shopkeeper tells you what you bought or sold, sometimes partly IDing it */
2312 STATIC_OVL void
2313 shk_names_obj(shkp, obj, fmt, amt, arg)
2314 struct monst *shkp;
2315 struct obj *obj;
2316 const char *fmt; /* "%s %ld %s %s", doname(obj), amt, plur(amt), arg */
2317 long amt;
2318 const char *arg;
2319 {
2320     char *obj_name, fmtbuf[BUFSZ];
2321     boolean was_unknown = !obj->dknown;
2322
2323     obj->dknown = TRUE;
2324     /* Use real name for ordinary weapons/armor, and spell-less
2325      * scrolls/books (that is, blank and mail), but only if the
2326      * object is within the shk's area of interest/expertise.
2327      */
2328     if (!objects[obj->otyp].oc_magic && saleable(shkp, obj)
2329         && (obj->oclass == WEAPON_CLASS || obj->oclass == ARMOR_CLASS
2330             || obj->oclass == SCROLL_CLASS || obj->oclass == SPBOOK_CLASS
2331             || obj->otyp == MIRROR)) {
2332         was_unknown |= !objects[obj->otyp].oc_name_known;
2333         makeknown(obj->otyp);
2334     }
2335     obj_name = doname(obj);
2336     /* Use an alternate message when extra information is being provided */
2337     if (was_unknown) {
2338         Sprintf(fmtbuf, "%%s; you %s", fmt);
2339         obj_name[0] = highc(obj_name[0]);
2340         pline(fmtbuf, obj_name, (obj->quan > 1L) ? "them" : "it", amt,
2341               plur(amt), arg);
2342     } else {
2343         You(fmt, obj_name, amt, plur(amt), arg);
2344     }
2345 }
2346
2347 /* decide whether a shopkeeper thinks an item belongs to her */
2348 boolean
2349 billable(shkpp, obj, roomno, reset_nocharge)
2350 struct monst **shkpp; /* in: non-null if shk has been validated; out: shk */
2351 struct obj *obj;
2352 char roomno;
2353 boolean reset_nocharge;
2354 {
2355     struct monst *shkp = *shkpp;
2356
2357     /* if caller hasn't supplied a shopkeeper, look one up now */
2358     if (!shkp) {
2359         if (!roomno)
2360             return FALSE;
2361         shkp = shop_keeper(roomno);
2362         if (!shkp || !inhishop(shkp))
2363             return FALSE;
2364         *shkpp = shkp;
2365     }
2366     /* perhaps we threw it away earlier */
2367     if (onbill(obj, shkp, FALSE)
2368         || (obj->oclass == FOOD_CLASS && obj->oeaten))
2369         return FALSE;
2370     /* outer container might be marked no_charge but still have contents
2371        which should be charged for; clear no_charge when picking things up */
2372     if (obj->no_charge) {
2373         if (!Has_contents(obj) || (contained_gold(obj) == 0L
2374                                    && contained_cost(obj, shkp, 0L, FALSE,
2375                                                      !reset_nocharge) == 0L))
2376             shkp = 0; /* not billable */
2377         if (reset_nocharge && !shkp && obj->oclass != COIN_CLASS) {
2378             obj->no_charge = 0;
2379             if (Has_contents(obj))
2380                 picked_container(obj); /* clear no_charge */
2381         }
2382     }
2383     return shkp ? TRUE : FALSE;
2384 }
2385
2386 void
2387 addtobill(obj, ininv, dummy, silent)
2388 struct obj *obj;
2389 boolean ininv, dummy, silent;
2390 {
2391     struct monst *shkp = 0;
2392     long ltmp, cltmp, gltmp;
2393     int contentscount;
2394     boolean container;
2395
2396     if (!billable(&shkp, obj, *u.ushops, TRUE))
2397         return;
2398
2399     if (obj->oclass == COIN_CLASS) {
2400         costly_gold(obj->ox, obj->oy, obj->quan);
2401         return;
2402     } else if (ESHK(shkp)->billct == BILLSZ) {
2403         if (!silent)
2404             You("got that for free!");
2405         return;
2406     }
2407
2408     ltmp = cltmp = gltmp = 0L;
2409     container = Has_contents(obj);
2410
2411     if (!obj->no_charge)
2412         ltmp = get_cost(obj, shkp);
2413
2414     if (obj->no_charge && !container) {
2415         obj->no_charge = 0;
2416         return;
2417     }
2418
2419     if (container) {
2420         cltmp = contained_cost(obj, shkp, cltmp, FALSE, FALSE);
2421         gltmp = contained_gold(obj);
2422
2423         if (ltmp)
2424             add_one_tobill(obj, dummy, shkp);
2425         if (cltmp)
2426             bill_box_content(obj, ininv, dummy, shkp);
2427         picked_container(obj); /* reset contained obj->no_charge */
2428
2429         ltmp += cltmp;
2430
2431         if (gltmp) {
2432             costly_gold(obj->ox, obj->oy, gltmp);
2433             if (!ltmp)
2434                 return;
2435         }
2436
2437         if (obj->no_charge)
2438             obj->no_charge = 0;
2439         contentscount = count_unpaid(obj->cobj);
2440     } else { /* !container */
2441         add_one_tobill(obj, dummy, shkp);
2442         contentscount = 0;
2443     }
2444
2445     if (!muteshk(shkp) && !silent) {
2446         char buf[BUFSZ];
2447
2448         if (!ltmp) {
2449             pline("%s has no interest in %s.", Monnam(shkp), the(xname(obj)));
2450             return;
2451         }
2452         if (!ininv) {
2453             pline("%s will cost you %ld %s%s.", The(xname(obj)), ltmp,
2454                   currency(ltmp), (obj->quan > 1L) ? " each" : "");
2455         } else {
2456             long save_quan = obj->quan;
2457
2458             Strcpy(buf, "\"For you, ");
2459             if (ANGRY(shkp)) {
2460                 Strcat(buf, "scum;");
2461             } else {
2462                 append_honorific(buf);
2463                 Strcat(buf, "; only");
2464             }
2465             obj->quan = 1L; /* fool xname() into giving singular */
2466             pline("%s %ld %s %s %s%s.\"", buf, ltmp, currency(ltmp),
2467                   (save_quan > 1L) ? "per" : (contentscount && !obj->unpaid)
2468                                                  ? "for the contents of this"
2469                                                  : "for this",
2470                   xname(obj),
2471                   (contentscount && obj->unpaid) ? and_its_contents : "");
2472             obj->quan = save_quan;
2473         }
2474     } else if (!silent) {
2475         if (ltmp)
2476             pline_The("list price of %s%s%s is %ld %s%s.",
2477                       (contentscount && !obj->unpaid) ? the_contents_of : "",
2478                       the(xname(obj)),
2479                       (contentscount && obj->unpaid) ? and_its_contents : "",
2480                       ltmp, currency(ltmp), (obj->quan > 1L) ? " each" : "");
2481         else
2482             pline("%s does not notice.", Monnam(shkp));
2483     }
2484 }
2485
2486 void
2487 append_honorific(buf)
2488 char *buf;
2489 {
2490     /* (chooses among [0]..[3] normally; [1]..[4] after the
2491        Wizard has been killed or invocation ritual performed) */
2492     static const char *const honored[] = { "good", "honored", "most gracious",
2493                                            "esteemed",
2494                                            "most renowned and sacred" };
2495     Strcat(buf, honored[rn2(SIZE(honored) - 1) + u.uevent.udemigod]);
2496     if (is_vampire(youmonst.data))
2497         Strcat(buf, (flags.female) ? " dark lady" : " dark lord");
2498     else if (is_elf(youmonst.data))
2499         Strcat(buf, (flags.female) ? " hiril" : " hir");
2500     else
2501         Strcat(buf, !is_human(youmonst.data) ? " creature" : (flags.female)
2502                                                                  ? " lady"
2503                                                                  : " sir");
2504 }
2505
2506 void
2507 splitbill(obj, otmp)
2508 register struct obj *obj, *otmp;
2509 {
2510     /* otmp has been split off from obj */
2511     register struct bill_x *bp;
2512     register long tmp;
2513     register struct monst *shkp = shop_keeper(*u.ushops);
2514
2515     if (!shkp || !inhishop(shkp)) {
2516         impossible("splitbill: no resident shopkeeper??");
2517         return;
2518     }
2519     bp = onbill(obj, shkp, FALSE);
2520     if (!bp) {
2521         impossible("splitbill: not on bill?");
2522         return;
2523     }
2524     if (bp->bquan < otmp->quan) {
2525         impossible("Negative quantity on bill??");
2526     }
2527     if (bp->bquan == otmp->quan) {
2528         impossible("Zero quantity on bill??");
2529     }
2530     bp->bquan -= otmp->quan;
2531
2532     if (ESHK(shkp)->billct == BILLSZ)
2533         otmp->unpaid = 0;
2534     else {
2535         tmp = bp->price;
2536         bp = &(ESHK(shkp)->bill_p[ESHK(shkp)->billct]);
2537         bp->bo_id = otmp->o_id;
2538         bp->bquan = otmp->quan;
2539         bp->useup = 0;
2540         bp->price = tmp;
2541         ESHK(shkp)->billct++;
2542     }
2543 }
2544
2545 STATIC_OVL void
2546 sub_one_frombill(obj, shkp)
2547 register struct obj *obj;
2548 register struct monst *shkp;
2549 {
2550     register struct bill_x *bp;
2551
2552     if ((bp = onbill(obj, shkp, FALSE)) != 0) {
2553         register struct obj *otmp;
2554
2555         obj->unpaid = 0;
2556         if (bp->bquan > obj->quan) {
2557             otmp = newobj();
2558             *otmp = *obj;
2559             otmp->oextra = (struct oextra *) 0;
2560             bp->bo_id = otmp->o_id = context.ident++;
2561             otmp->where = OBJ_FREE;
2562             otmp->quan = (bp->bquan -= obj->quan);
2563             otmp->owt = 0; /* superfluous */
2564             bp->useup = 1;
2565             add_to_billobjs(otmp);
2566             return;
2567         }
2568         ESHK(shkp)->billct--;
2569 #ifdef DUMB
2570         {
2571             /* DRS/NS 2.2.6 messes up -- Peter Kendell */
2572             int indx = ESHK(shkp)->billct;
2573
2574             *bp = ESHK(shkp)->bill_p[indx];
2575         }
2576 #else
2577         *bp = ESHK(shkp)->bill_p[ESHK(shkp)->billct];
2578 #endif
2579         return;
2580     } else if (obj->unpaid) {
2581         impossible("sub_one_frombill: unpaid object not on bill");
2582         obj->unpaid = 0;
2583     }
2584 }
2585
2586 /* recursive check of unpaid objects within nested containers. */
2587 void
2588 subfrombill(obj, shkp)
2589 register struct obj *obj;
2590 register struct monst *shkp;
2591 {
2592     register struct obj *otmp;
2593
2594     sub_one_frombill(obj, shkp);
2595
2596     if (Has_contents(obj))
2597         for (otmp = obj->cobj; otmp; otmp = otmp->nobj) {
2598             if (otmp->oclass == COIN_CLASS)
2599                 continue;
2600
2601             if (Has_contents(otmp))
2602                 subfrombill(otmp, shkp);
2603             else
2604                 sub_one_frombill(otmp, shkp);
2605         }
2606 }
2607
2608 STATIC_OVL long
2609 stolen_container(obj, shkp, price, ininv)
2610 struct obj *obj;
2611 struct monst *shkp;
2612 long price;
2613 boolean ininv;
2614 {
2615     struct obj *otmp;
2616     struct bill_x *bp;
2617     long billamt;
2618
2619     /* the price of contained objects; caller handles top container */
2620     for (otmp = obj->cobj; otmp; otmp = otmp->nobj) {
2621         if (otmp->oclass == COIN_CLASS)
2622             continue;
2623         billamt = 0L;
2624         if (!billable(&shkp, otmp, ESHK(shkp)->shoproom, TRUE)) {
2625             /* billable() returns false for objects already on bill */
2626             if ((bp = onbill(otmp, shkp, FALSE)) == 0)
2627                 continue;
2628             /* this assumes that we're being called by stolen_value()
2629                (or by a recursive call to self on behalf of it) where
2630                the cost of this object is about to be added to shop
2631                debt in place of having it remain on the current bill */
2632             billamt = bp->bquan * bp->price;
2633             sub_one_frombill(otmp, shkp); /* avoid double billing */
2634         }
2635
2636         if (billamt)
2637             price += billamt;
2638         else if (ininv ? otmp->unpaid : !otmp->no_charge)
2639             price += otmp->quan * get_cost(otmp, shkp);
2640
2641         if (Has_contents(otmp))
2642             price = stolen_container(otmp, shkp, price, ininv);
2643     }
2644
2645     return price;
2646 }
2647
2648 long
2649 stolen_value(obj, x, y, peaceful, silent)
2650 struct obj *obj;
2651 xchar x, y;
2652 boolean peaceful, silent;
2653 {
2654     long value = 0L, gvalue = 0L, billamt = 0L;
2655     char roomno = *in_rooms(x, y, SHOPBASE);
2656     struct bill_x *bp;
2657     struct monst *shkp = 0;
2658
2659     if (!billable(&shkp, obj, roomno, FALSE)) {
2660         /* things already on the bill yield a not-billable result, so
2661            we need to check bill before deciding that shk doesn't care */
2662         if ((bp = onbill(obj, shkp, FALSE)) == 0)
2663             return 0L;
2664         /* shk does care; take obj off bill to avoid double billing */
2665         billamt = bp->bquan * bp->price;
2666         sub_one_frombill(obj, shkp);
2667     }
2668
2669     if (obj->oclass == COIN_CLASS) {
2670         gvalue += obj->quan;
2671     } else {
2672         if (billamt)
2673             value += billamt;
2674         else if (!obj->no_charge)
2675             value += obj->quan * get_cost(obj, shkp);
2676
2677         if (Has_contents(obj)) {
2678             boolean ininv =
2679                 (obj->where == OBJ_INVENT || obj->where == OBJ_FREE);
2680
2681             value += stolen_container(obj, shkp, 0L, ininv);
2682             if (!ininv)
2683                 gvalue += contained_gold(obj);
2684         }
2685     }
2686
2687     if (gvalue + value == 0L)
2688         return 0L;
2689
2690     value += gvalue;
2691
2692     if (peaceful) {
2693         boolean credit_use = !!ESHK(shkp)->credit;
2694         value = check_credit(value, shkp);
2695         /* 'peaceful' affects general treatment, but doesn't affect
2696          * the fact that other code expects that all charges after the
2697          * shopkeeper is angry are included in robbed, not debit */
2698         if (ANGRY(shkp))
2699             ESHK(shkp)->robbed += value;
2700         else
2701             ESHK(shkp)->debit += value;
2702
2703         if (!silent) {
2704             const char *still = "";
2705
2706             if (credit_use) {
2707                 if (ESHK(shkp)->credit) {
2708                     You("have %ld %s credit remaining.", ESHK(shkp)->credit,
2709                         currency(ESHK(shkp)->credit));
2710                     return value;
2711                 } else if (!value) {
2712                     You("have no credit remaining.");
2713                     return 0;
2714                 }
2715                 still = "still ";
2716             }
2717             if (obj->oclass == COIN_CLASS)
2718                 You("%sowe %s %ld %s!", still, mon_nam(shkp), value,
2719                     currency(value));
2720             else
2721                 You("%sowe %s %ld %s for %s!", still, mon_nam(shkp), value,
2722                     currency(value), obj->quan > 1L ? "them" : "it");
2723         }
2724     } else {
2725         ESHK(shkp)->robbed += value;
2726
2727         if (!silent) {
2728             if (cansee(shkp->mx, shkp->my)) {
2729                 Norep("%s booms: \"%s, you are a thief!\"", Monnam(shkp),
2730                       plname);
2731             } else
2732                 Norep("You hear a scream, \"Thief!\"");
2733         }
2734         hot_pursuit(shkp);
2735         (void) angry_guards(FALSE);
2736     }
2737     return value;
2738 }
2739
2740 /* auto-response flag for/from "sell foo?" 'a' => 'y', 'q' => 'n' */
2741 static char sell_response = 'a';
2742 static int sell_how = SELL_NORMAL;
2743 /* can't just use sell_response='y' for auto_credit because the 'a' response
2744    shouldn't carry over from ordinary selling to credit selling */
2745 static boolean auto_credit = FALSE;
2746
2747 void
2748 sellobj_state(deliberate)
2749 int deliberate;
2750 {
2751     /* If we're deliberately dropping something, there's no automatic
2752        response to the shopkeeper's "want to sell" query; however, if we
2753        accidentally drop anything, the shk will buy it/them without asking.
2754        This retains the old pre-query risk that slippery fingers while in
2755        shops entailed:  you drop it, you've lost it.
2756      */
2757     sell_response = (deliberate != SELL_NORMAL) ? '\0' : 'a';
2758     sell_how = deliberate;
2759     auto_credit = FALSE;
2760 }
2761
2762 void
2763 sellobj(obj, x, y)
2764 register struct obj *obj;
2765 xchar x, y;
2766 {
2767     register struct monst *shkp;
2768     register struct eshk *eshkp;
2769     long ltmp = 0L, cltmp = 0L, gltmp = 0L, offer, shkmoney;
2770     boolean saleitem, cgold = FALSE, container = Has_contents(obj);
2771     boolean isgold = (obj->oclass == COIN_CLASS);
2772     boolean only_partially_your_contents = FALSE;
2773
2774     if (!(shkp = shop_keeper(*in_rooms(x, y, SHOPBASE))) || !inhishop(shkp))
2775         return;
2776     if (!costly_spot(x, y))
2777         return;
2778     if (!*u.ushops)
2779         return;
2780
2781     if (obj->unpaid && !container && !isgold) {
2782         sub_one_frombill(obj, shkp);
2783         return;
2784     }
2785     if (container) {
2786         /* find the price of content before subfrombill */
2787         cltmp = contained_cost(obj, shkp, cltmp, TRUE, FALSE);
2788         /* find the value of contained gold */
2789         gltmp += contained_gold(obj);
2790         cgold = (gltmp > 0L);
2791     }
2792
2793     saleitem = saleable(shkp, obj);
2794     if (!isgold && !obj->unpaid && saleitem)
2795         ltmp = set_cost(obj, shkp);
2796
2797     offer = ltmp + cltmp;
2798
2799     /* get one case out of the way: nothing to sell, and no gold */
2800     if (!isgold && ((offer + gltmp) == 0L || sell_how == SELL_DONTSELL)) {
2801         boolean unpaid = is_unpaid(obj);
2802
2803         if (container) {
2804             dropped_container(obj, shkp, FALSE);
2805             if (!obj->unpaid && !saleitem)
2806                 obj->no_charge = 1;
2807             if (unpaid)
2808                 subfrombill(obj, shkp);
2809         } else
2810             obj->no_charge = 1;
2811
2812         if (!unpaid && (sell_how != SELL_DONTSELL)
2813             && !special_stock(obj, shkp, FALSE))
2814             pline("%s seems uninterested.", Monnam(shkp));
2815         return;
2816     }
2817
2818     /* you dropped something of your own - probably want to sell it */
2819     rouse_shk(shkp, TRUE); /* wake up sleeping or paralyzed shk */
2820     eshkp = ESHK(shkp);
2821
2822     if (ANGRY(shkp)) { /* they become shop-objects, no pay */
2823         if (!muteshk(shkp))
2824             verbalize("Thank you, scum!");
2825         subfrombill(obj, shkp);
2826         return;
2827     }
2828
2829     if (eshkp->robbed) { /* shkp is not angry? */
2830         if (isgold)
2831             offer = obj->quan;
2832         else if (cgold)
2833             offer += cgold;
2834         if ((eshkp->robbed -= offer < 0L))
2835             eshkp->robbed = 0L;
2836         if (offer && !muteshk(shkp))
2837             verbalize(
2838   "Thank you for your contribution to restock this recently plundered shop.");
2839         subfrombill(obj, shkp);
2840         return;
2841     }
2842
2843     if (isgold || cgold) {
2844         if (!cgold)
2845             gltmp = obj->quan;
2846
2847         if (eshkp->debit >= gltmp) {
2848             if (eshkp->loan) { /* you carry shop's gold */
2849                 if (eshkp->loan >= gltmp)
2850                     eshkp->loan -= gltmp;
2851                 else
2852                     eshkp->loan = 0L;
2853             }
2854             eshkp->debit -= gltmp;
2855             Your("debt is %spaid off.", eshkp->debit ? "partially " : "");
2856         } else {
2857             long delta = gltmp - eshkp->debit;
2858
2859             eshkp->credit += delta;
2860             if (eshkp->debit) {
2861                 eshkp->debit = 0L;
2862                 eshkp->loan = 0L;
2863                 Your("debt is paid off.");
2864             }
2865             if (eshkp->credit == delta)
2866                 You("have established %ld %s credit.", delta,
2867                     currency(delta));
2868             else
2869                 pline("%ld %s added to your credit; total is now %ld %s.",
2870                       delta, currency(delta), eshkp->credit,
2871                       currency(eshkp->credit));
2872         }
2873
2874         if (!offer) {
2875             if (!isgold) {
2876                 if (container)
2877                     dropped_container(obj, shkp, FALSE);
2878                 if (!obj->unpaid && !saleitem)
2879                     obj->no_charge = 1;
2880                 subfrombill(obj, shkp);
2881             }
2882             return;
2883         }
2884     }
2885
2886     if ((!saleitem && !(container && cltmp > 0L)) || eshkp->billct == BILLSZ
2887         || obj->oclass == BALL_CLASS || obj->oclass == CHAIN_CLASS
2888         || offer == 0L || (obj->oclass == FOOD_CLASS && obj->oeaten)
2889         || (Is_candle(obj)
2890             && obj->age < 20L * (long) objects[obj->otyp].oc_cost)) {
2891         pline("%s seems uninterested%s.", Monnam(shkp),
2892               cgold ? " in the rest" : "");
2893         if (container)
2894             dropped_container(obj, shkp, FALSE);
2895         obj->no_charge = 1;
2896         return;
2897     }
2898
2899     shkmoney = money_cnt(shkp->minvent);
2900     if (!shkmoney) {
2901         char c, qbuf[BUFSZ];
2902         long tmpcr = ((offer * 9L) / 10L) + (offer <= 1L);
2903
2904         if (sell_how == SELL_NORMAL || auto_credit) {
2905             c = sell_response = 'y';
2906         } else if (sell_response != 'n') {
2907             pline("%s cannot pay you at present.", shkname(shkp));
2908             Sprintf(qbuf, "Will you accept %ld %s in credit for ", tmpcr,
2909                     currency(tmpcr));
2910             c = ynaq(safe_qbuf(qbuf, qbuf, "?", obj, doname, thesimpleoname,
2911                                (obj->quan == 1L) ? "that" : "those"));
2912             if (c == 'a') {
2913                 c = 'y';
2914                 auto_credit = TRUE;
2915             }
2916         } else /* previously specified "quit" */
2917             c = 'n';
2918
2919         if (c == 'y') {
2920             shk_names_obj(
2921                 shkp, obj,
2922                 (sell_how != SELL_NORMAL)
2923                     ? "traded %s for %ld zorkmid%s in %scredit."
2924                     : "relinquish %s and acquire %ld zorkmid%s in %scredit.",
2925                 tmpcr, (eshkp->credit > 0L) ? "additional " : "");
2926             eshkp->credit += tmpcr;
2927             subfrombill(obj, shkp);
2928         } else {
2929             if (c == 'q')
2930                 sell_response = 'n';
2931             if (container)
2932                 dropped_container(obj, shkp, FALSE);
2933             if (!obj->unpaid)
2934                 obj->no_charge = 1;
2935             subfrombill(obj, shkp);
2936         }
2937     } else {
2938         char qbuf[BUFSZ], qsfx[BUFSZ];
2939         boolean short_funds = (offer > shkmoney), one;
2940
2941         if (short_funds)
2942             offer = shkmoney;
2943         if (!sell_response) {
2944             long yourc = 0L, shksc;
2945
2946             if (container) {
2947                 /* number of items owned by shk */
2948                 shksc = count_contents(obj, TRUE, TRUE, FALSE);
2949                 /* number of items owned by you (total - shksc) */
2950                 yourc = count_contents(obj, TRUE, TRUE, TRUE) - shksc;
2951                 only_partially_your_contents = shksc && yourc;
2952             }
2953             /*
2954                "<shk> offers * for ..." query formatting.
2955                Normal item(s):
2956                 "... your <object>.  Sell it?"
2957                 "... your <objects>.  Sell them?"
2958                A container is either owned by the hero, or already
2959                owned by the shk (!ltmp), or the shk isn't interested
2960                in buying it (also !ltmp).  It's either empty (!cltmp)
2961                or it has contents owned by the hero or it has some
2962                contents owned by the hero and others by the shk.
2963                (The case where it has contents already entirely owned
2964                by the shk is treated the same was if it were empty
2965                since the hero isn't selling any of those contents.)
2966                Your container:
2967                 "... your <empty bag>.  Sell it?"
2968                 "... your <bag> and its contents.  Sell them?"
2969                 "... your <bag> and item inside.  Sell them?"
2970                 "... your <bag> and items inside.  Sell them?"
2971                Shk's container:
2972                 "... your item in the <bag>.  Sell it?"
2973                 "... your items in the <bag>.  Sell them?"
2974              */
2975             Sprintf(qbuf, "%s offers%s %ld gold piece%s for %s%s ",
2976                     shkname(shkp), short_funds ? " only" : "", offer,
2977                     plur(offer),
2978                     (cltmp && !ltmp)
2979                         ? ((yourc == 1L) ? "your item in " : "your items in ")
2980                         : "",
2981                     obj->unpaid ? "the" : "your");
2982             one = obj->unpaid ? (yourc == 1L) : (obj->quan == 1L && !cltmp);
2983             Sprintf(qsfx, "%s.  Sell %s?",
2984                     (cltmp && ltmp)
2985                         ? (only_partially_your_contents
2986                                ? ((yourc == 1L) ? " and item inside"
2987                                                 : " and items inside")
2988                                : and_its_contents)
2989                         : "",
2990                     one ? "it" : "them");
2991             (void) safe_qbuf(qbuf, qbuf, qsfx, obj, xname, simpleonames,
2992                              one ? "that" : "those");
2993         } else
2994             qbuf[0] = '\0'; /* just to pacify lint */
2995
2996         switch (sell_response ? sell_response : ynaq(qbuf)) {
2997         case 'q':
2998             sell_response = 'n';
2999         case 'n':
3000             if (container)
3001                 dropped_container(obj, shkp, FALSE);
3002             if (!obj->unpaid)
3003                 obj->no_charge = 1;
3004             subfrombill(obj, shkp);
3005             break;
3006         case 'a':
3007             sell_response = 'y';
3008         case 'y':
3009             if (container)
3010                 dropped_container(obj, shkp, TRUE);
3011             if (!obj->unpaid && !saleitem)
3012                 obj->no_charge = 1;
3013             subfrombill(obj, shkp);
3014             pay(-offer, shkp);
3015             shk_names_obj(shkp, obj,
3016                           (sell_how != SELL_NORMAL)
3017                            ? ((!ltmp && cltmp && only_partially_your_contents)
3018                          ? "sold some items inside %s for %ld gold piece%s.%s"
3019                          : "sold %s for %ld gold piece%s.%s")
3020             : "relinquish %s and receive %ld gold piece%s in compensation.%s",
3021                           offer, "");
3022             break;
3023         default:
3024             impossible("invalid sell response");
3025         }
3026     }
3027 }
3028
3029 int
3030 doinvbill(mode)
3031 int mode; /* 0: deliver count 1: paged */
3032 {
3033 #ifdef __SASC
3034     void sasc_bug(struct obj *, unsigned);
3035 #endif
3036     struct monst *shkp;
3037     struct eshk *eshkp;
3038     struct bill_x *bp, *end_bp;
3039     struct obj *obj;
3040     long totused;
3041     char *buf_p;
3042     winid datawin;
3043
3044     shkp = shop_keeper(*u.ushops);
3045     if (!shkp || !inhishop(shkp)) {
3046         if (mode != 0)
3047             impossible("doinvbill: no shopkeeper?");
3048         return 0;
3049     }
3050     eshkp = ESHK(shkp);
3051
3052     if (mode == 0) {
3053         /* count expended items, so that the `I' command can decide
3054            whether to include 'x' in its prompt string */
3055         int cnt = !eshkp->debit ? 0 : 1;
3056
3057         for (bp = eshkp->bill_p, end_bp = &eshkp->bill_p[eshkp->billct];
3058              bp < end_bp; bp++)
3059             if (bp->useup
3060                 || ((obj = bp_to_obj(bp)) != 0 && obj->quan < bp->bquan))
3061                 cnt++;
3062         return cnt;
3063     }
3064
3065     datawin = create_nhwindow(NHW_MENU);
3066     putstr(datawin, 0, "Unpaid articles already used up:");
3067     putstr(datawin, 0, "");
3068
3069     totused = 0L;
3070     for (bp = eshkp->bill_p, end_bp = &eshkp->bill_p[eshkp->billct];
3071          bp < end_bp; bp++) {
3072         obj = bp_to_obj(bp);
3073         if (!obj) {
3074             impossible("Bad shopkeeper administration.");
3075             goto quit;
3076         }
3077         if (bp->useup || bp->bquan > obj->quan) {
3078             long oquan, uquan, thisused;
3079
3080             oquan = obj->quan;
3081             uquan = (bp->useup ? bp->bquan : bp->bquan - oquan);
3082             thisused = bp->price * uquan;
3083             totused += thisused;
3084             iflags.suppress_price++; /* suppress "(unpaid)" suffix */
3085             /* Why 'x'?  To match `I x', more or less. */
3086             buf_p = xprname(obj, (char *) 0, 'x', FALSE, thisused, uquan);
3087             iflags.suppress_price--;
3088             putstr(datawin, 0, buf_p);
3089         }
3090     }
3091     if (eshkp->debit) {
3092         /* additional shop debt which has no itemization available */
3093         if (totused)
3094             putstr(datawin, 0, "");
3095         totused += eshkp->debit;
3096         buf_p = xprname((struct obj *) 0, "usage charges and/or other fees",
3097                         GOLD_SYM, FALSE, eshkp->debit, 0L);
3098         putstr(datawin, 0, buf_p);
3099     }
3100     buf_p = xprname((struct obj *) 0, "Total:", '*', FALSE, totused, 0L);
3101     putstr(datawin, 0, "");
3102     putstr(datawin, 0, buf_p);
3103     display_nhwindow(datawin, FALSE);
3104 quit:
3105     destroy_nhwindow(datawin);
3106     return 0;
3107 }
3108
3109 #define HUNGRY 2
3110
3111 STATIC_OVL long
3112 getprice(obj, shk_buying)
3113 register struct obj *obj;
3114 boolean shk_buying;
3115 {
3116     register long tmp = (long) objects[obj->otyp].oc_cost;
3117
3118     if (obj->oartifact) {
3119         tmp = arti_cost(obj);
3120         if (shk_buying)
3121             tmp /= 4;
3122     }
3123     switch (obj->oclass) {
3124     case FOOD_CLASS:
3125         /* simpler hunger check, (2-4)*cost */
3126         if (u.uhs >= HUNGRY && !shk_buying)
3127             tmp *= (long) u.uhs;
3128         if (obj->oeaten)
3129             tmp = 0L;
3130         break;
3131     case WAND_CLASS:
3132         if (obj->spe == -1)
3133             tmp = 0L;
3134         break;
3135     case POTION_CLASS:
3136         if (obj->otyp == POT_WATER && !obj->blessed && !obj->cursed)
3137             tmp = 0L;
3138         break;
3139     case ARMOR_CLASS:
3140     case WEAPON_CLASS:
3141         if (obj->spe > 0)
3142             tmp += 10L * (long) obj->spe;
3143         break;
3144     case TOOL_CLASS:
3145         if (Is_candle(obj)
3146             && obj->age < 20L * (long) objects[obj->otyp].oc_cost)
3147             tmp /= 2L;
3148         break;
3149     }
3150     return tmp;
3151 }
3152
3153 /* shk catches thrown pick-axe */
3154 struct monst *
3155 shkcatch(obj, x, y)
3156 register struct obj *obj;
3157 register xchar x, y;
3158 {
3159     register struct monst *shkp;
3160
3161     if (!(shkp = shop_keeper(inside_shop(x, y))) || !inhishop(shkp))
3162         return 0;
3163
3164     if (shkp->mcanmove && !shkp->msleeping
3165         && (*u.ushops != ESHK(shkp)->shoproom || !inside_shop(u.ux, u.uy))
3166         && dist2(shkp->mx, shkp->my, x, y) < 3
3167         /* if it is the shk's pos, you hit and anger him */
3168         && (shkp->mx != x || shkp->my != y)) {
3169         if (mnearto(shkp, x, y, TRUE) && !muteshk(shkp))
3170             verbalize("Out of my way, scum!");
3171         if (cansee(x, y)) {
3172             pline("%s nimbly%s catches %s.", Monnam(shkp),
3173                   (x == shkp->mx && y == shkp->my) ? "" : " reaches over and",
3174                   the(xname(obj)));
3175             if (!canspotmon(shkp))
3176                 map_invisible(x, y);
3177             delay_output();
3178             mark_synch();
3179         }
3180         subfrombill(obj, shkp);
3181         (void) mpickobj(shkp, obj);
3182         return shkp;
3183     }
3184     return (struct monst *) 0;
3185 }
3186
3187 void
3188 add_damage(x, y, cost)
3189 register xchar x, y;
3190 long cost;
3191 {
3192     struct damage *tmp_dam;
3193     char *shops;
3194
3195     if (IS_DOOR(levl[x][y].typ)) {
3196         struct monst *mtmp;
3197
3198         /* Don't schedule for repair unless it's a real shop entrance */
3199         for (shops = in_rooms(x, y, SHOPBASE); *shops; shops++)
3200             if ((mtmp = shop_keeper(*shops)) != 0 && x == ESHK(mtmp)->shd.x
3201                 && y == ESHK(mtmp)->shd.y)
3202                 break;
3203         if (!*shops)
3204             return;
3205     }
3206     for (tmp_dam = level.damagelist; tmp_dam; tmp_dam = tmp_dam->next)
3207         if (tmp_dam->place.x == x && tmp_dam->place.y == y) {
3208             tmp_dam->cost += cost;
3209             return;
3210         }
3211     tmp_dam = (struct damage *) alloc((unsigned) sizeof(struct damage));
3212     tmp_dam->when = monstermoves;
3213     tmp_dam->place.x = x;
3214     tmp_dam->place.y = y;
3215     tmp_dam->cost = cost;
3216     tmp_dam->typ = levl[x][y].typ;
3217     tmp_dam->next = level.damagelist;
3218     level.damagelist = tmp_dam;
3219     /* If player saw damage, display as a wall forever */
3220     if (cansee(x, y))
3221         levl[x][y].seenv = SVALL;
3222 }
3223
3224 /*
3225  * Do something about damage. Either (!croaked) try to repair it, or
3226  * (croaked) just discard damage structs for non-shared locations, since
3227  * they'll never get repaired. Assume that shared locations will get
3228  * repaired eventually by the other shopkeeper(s). This might be an erroneous
3229  * assumption (they might all be dead too), but we have no reasonable way of
3230  * telling that.
3231  */
3232 STATIC_OVL
3233 void
3234 remove_damage(shkp, croaked)
3235 struct monst *shkp;
3236 boolean croaked;
3237 {
3238     struct damage *tmp_dam, *tmp2_dam;
3239     boolean did_repair = FALSE, saw_door = FALSE, saw_floor = FALSE,
3240             stop_picking = FALSE, doorway_trap = FALSE;
3241     int saw_walls = 0, saw_untrap = 0;
3242     char trapmsg[BUFSZ];
3243
3244     tmp_dam = level.damagelist;
3245     tmp2_dam = 0;
3246     while (tmp_dam) {
3247         register xchar x = tmp_dam->place.x, y = tmp_dam->place.y;
3248         char shops[5];
3249         int disposition;
3250         unsigned old_doormask = 0;
3251
3252         disposition = 0;
3253         Strcpy(shops, in_rooms(x, y, SHOPBASE));
3254         if (index(shops, ESHK(shkp)->shoproom)) {
3255             if (IS_DOOR(levl[x][y].typ))
3256                 old_doormask = levl[x][y].doormask;
3257
3258             if (croaked)
3259                 disposition = (shops[1]) ? 0 : 1;
3260             else if (stop_picking)
3261                 disposition = repair_damage(shkp, tmp_dam, FALSE);
3262             else {
3263                 /* Defer the stop_occupation() until after repair msgs */
3264                 if (closed_door(x, y))
3265                     stop_picking = picking_at(x, y);
3266                 disposition = repair_damage(shkp, tmp_dam, FALSE);
3267                 if (!disposition)
3268                     stop_picking = FALSE;
3269             }
3270         }
3271
3272         if (!disposition) {
3273             tmp2_dam = tmp_dam;
3274             tmp_dam = tmp_dam->next;
3275             continue;
3276         }
3277
3278         if (disposition > 1) {
3279             did_repair = TRUE;
3280             if (cansee(x, y)) {
3281                 if (IS_WALL(levl[x][y].typ)) {
3282                     saw_walls++;
3283                 } else if (IS_DOOR(levl[x][y].typ)
3284                            /* an existing door here implies trap removal */
3285                            && !(old_doormask & (D_ISOPEN | D_CLOSED))) {
3286                     saw_door = TRUE;
3287                 } else if (disposition == 3) { /* untrapped */
3288                     saw_untrap++;
3289                     if (IS_DOOR(levl[x][y].typ))
3290                         doorway_trap = TRUE;
3291                 } else {
3292                     saw_floor = TRUE;
3293                 }
3294             }
3295         }
3296
3297         tmp_dam = tmp_dam->next;
3298         if (!tmp2_dam) {
3299             free((genericptr_t) level.damagelist);
3300             level.damagelist = tmp_dam;
3301         } else {
3302             free((genericptr_t) tmp2_dam->next);
3303             tmp2_dam->next = tmp_dam;
3304         }
3305     }
3306     if (!did_repair)
3307         return;
3308
3309     if (saw_untrap) {
3310         Sprintf(trapmsg, "%s trap%s",
3311                 (saw_untrap > 3) ? "several" : (saw_untrap > 1) ? "some"
3312                                                                 : "a",
3313                 plur(saw_untrap));
3314         Sprintf(eos(trapmsg), " %s", vtense(trapmsg, "are"));
3315         Sprintf(eos(trapmsg), " removed from the %s",
3316                 (doorway_trap && saw_untrap == 1) ? "doorway" : "floor");
3317     } else
3318         trapmsg[0] = '\0'; /* not just lint suppression... */
3319
3320     if (saw_walls) {
3321         char wallbuf[BUFSZ];
3322
3323         Sprintf(wallbuf, "section%s", plur(saw_walls));
3324         pline("Suddenly, %s %s of wall %s up!",
3325               (saw_walls == 1) ? "a" : (saw_walls <= 3) ? "some" : "several",
3326               wallbuf, vtense(wallbuf, "close"));
3327
3328         if (saw_door)
3329             pline_The("shop door reappears!");
3330         if (saw_floor)
3331             pline_The("floor is repaired!");
3332         if (saw_untrap)
3333             pline("%s!", upstart(trapmsg));
3334     } else {
3335         if (saw_door || saw_floor || saw_untrap)
3336             pline("Suddenly, %s%s%s%s%s!",
3337                   saw_door ? "the shop door reappears" : "",
3338                   (saw_door && saw_floor) ? " and " : "",
3339                   saw_floor ? "the floor damage is gone" : "",
3340                   ((saw_door || saw_floor) && *trapmsg) ? " and " : "",
3341                   trapmsg);
3342         else if (inside_shop(u.ux, u.uy) == ESHK(shkp)->shoproom)
3343             You_feel("more claustrophobic than before.");
3344         else if (!Deaf && !rn2(10))
3345             Norep("The dungeon acoustics noticeably change.");
3346     }
3347     if (stop_picking)
3348         stop_occupation();
3349 }
3350
3351 /*
3352  * 0: repair postponed, 1: silent repair (no messages), 2: normal repair
3353  * 3: untrap
3354  */
3355 int
3356 repair_damage(shkp, tmp_dam, catchup)
3357 register struct monst *shkp;
3358 register struct damage *tmp_dam;
3359 boolean catchup; /* restoring a level */
3360 {
3361     register xchar x, y, i;
3362     xchar litter[9];
3363     register struct monst *mtmp;
3364     register struct obj *otmp;
3365     register struct trap *ttmp;
3366
3367     if ((monstermoves - tmp_dam->when) < REPAIR_DELAY)
3368         return 0;
3369     if (shkp->msleeping || !shkp->mcanmove || ESHK(shkp)->following)
3370         return 0;
3371     x = tmp_dam->place.x;
3372     y = tmp_dam->place.y;
3373     if (!IS_ROOM(tmp_dam->typ)) {
3374         if (x == u.ux && y == u.uy)
3375             if (!Passes_walls)
3376                 return 0;
3377         if (x == shkp->mx && y == shkp->my)
3378             return 0;
3379         if ((mtmp = m_at(x, y)) && (!passes_walls(mtmp->data)))
3380             return 0;
3381     }
3382     if ((ttmp = t_at(x, y)) != 0) {
3383         if (x == u.ux && y == u.uy)
3384             if (!Passes_walls)
3385                 return 0;
3386         if (ttmp->ttyp == LANDMINE || ttmp->ttyp == BEAR_TRAP) {
3387             /* convert to an object */
3388             otmp = mksobj((ttmp->ttyp == LANDMINE) ? LAND_MINE : BEARTRAP,
3389                           TRUE, FALSE);
3390             otmp->quan = 1L;
3391             otmp->owt = weight(otmp);
3392             (void) mpickobj(shkp, otmp);
3393         }
3394         deltrap(ttmp);
3395         if (IS_DOOR(tmp_dam->typ) && !(levl[x][y].doormask & D_ISOPEN)) {
3396             levl[x][y].doormask = D_CLOSED;
3397             block_point(x, y);
3398         } else if (IS_WALL(tmp_dam->typ)) {
3399             levl[x][y].typ = tmp_dam->typ;
3400             block_point(x, y);
3401         }
3402         newsym(x, y);
3403         return 3;
3404     }
3405     if (IS_ROOM(tmp_dam->typ)) {
3406         /* No messages, because player already filled trap door */
3407         return 1;
3408     }
3409     if ((tmp_dam->typ == levl[x][y].typ)
3410         && (!IS_DOOR(tmp_dam->typ) || (levl[x][y].doormask > D_BROKEN)))
3411         /* No messages if player already replaced shop door */
3412         return 1;
3413     levl[x][y].typ = tmp_dam->typ;
3414     (void) memset((genericptr_t) litter, 0, sizeof(litter));
3415     if ((otmp = level.objects[x][y]) != 0) {
3416 /* Scatter objects haphazardly into the shop */
3417 #define NEED_UPDATE 1
3418 #define OPEN 2
3419 #define INSHOP 4
3420 #define horiz(i) ((i % 3) - 1)
3421 #define vert(i) ((i / 3) - 1)
3422         for (i = 0; i < 9; i++) {
3423             if ((i == 4) || (!ZAP_POS(levl[x + horiz(i)][y + vert(i)].typ)))
3424                 continue;
3425             litter[i] = OPEN;
3426             if (inside_shop(x + horiz(i), y + vert(i))
3427                 == ESHK(shkp)->shoproom)
3428                 litter[i] |= INSHOP;
3429         }
3430         if (Punished && !u.uswallow
3431             && ((uchain->ox == x && uchain->oy == y)
3432                 || (uball->ox == x && uball->oy == y))) {
3433             /*
3434              * Either the ball or chain is in the repair location.
3435              *
3436              * Take the easy way out and put ball&chain under hero.
3437              */
3438             if (!muteshk(shkp))
3439                 verbalize("Get your junk out of my wall!");
3440             unplacebc(); /* pick 'em up */
3441             placebc();   /* put 'em down */
3442         }
3443         while ((otmp = level.objects[x][y]) != 0)
3444             /* Don't mess w/ boulders -- just merge into wall */
3445             if ((otmp->otyp == BOULDER) || (otmp->otyp == ROCK)) {
3446                 obj_extract_self(otmp);
3447                 obfree(otmp, (struct obj *) 0);
3448             } else {
3449                 while (!(litter[i = rn2(9)] & INSHOP))
3450                     ;
3451                 remove_object(otmp);
3452                 place_object(otmp, x + horiz(i), y + vert(i));
3453                 litter[i] |= NEED_UPDATE;
3454             }
3455     }
3456     if (catchup)
3457         return 1; /* repair occurred while off level */
3458
3459     block_point(x, y);
3460     if (IS_DOOR(tmp_dam->typ)) {
3461         levl[x][y].doormask = D_CLOSED; /* arbitrary */
3462         newsym(x, y);
3463     } else {
3464         /* don't set doormask  - it is (hopefully) the same as it was
3465            if not, perhaps save it with the damage array... */
3466
3467         if (IS_WALL(tmp_dam->typ) && cansee(x, y)) {
3468             /* Player sees actual repair process, so they KNOW it's a wall */
3469             levl[x][y].seenv = SVALL;
3470             newsym(x, y);
3471         }
3472         /* Mark this wall as "repaired".  There currently is no code
3473            to do anything about repaired walls, so don't do it. */
3474     }
3475     for (i = 0; i < 9; i++)
3476         if (litter[i] & NEED_UPDATE)
3477             newsym(x + horiz(i), y + vert(i));
3478     return 2;
3479 #undef NEED_UPDATE
3480 #undef OPEN
3481 #undef INSHOP
3482 #undef vert
3483 #undef horiz
3484 }
3485
3486 /*
3487  * shk_move: return 1: moved  0: didn't  -1: let m_move do it  -2: died
3488  */
3489 int
3490 shk_move(shkp)
3491 register struct monst *shkp;
3492 {
3493     register xchar gx, gy, omx, omy;
3494     register int udist;
3495     register schar appr;
3496     register struct eshk *eshkp = ESHK(shkp);
3497     int z;
3498     boolean uondoor = FALSE, satdoor, avoid = FALSE, badinv;
3499
3500     omx = shkp->mx;
3501     omy = shkp->my;
3502
3503     if (inhishop(shkp))
3504         remove_damage(shkp, FALSE);
3505
3506     if ((udist = distu(omx, omy)) < 3 && (shkp->data != &mons[PM_GRID_BUG]
3507                                           || (omx == u.ux || omy == u.uy))) {
3508         if (ANGRY(shkp) || (Conflict && !resist(shkp, RING_CLASS, 0, 0))) {
3509             if (Displaced)
3510                 Your("displaced image doesn't fool %s!", mon_nam(shkp));
3511             (void) mattacku(shkp);
3512             return 0;
3513         }
3514         if (eshkp->following) {
3515             if (strncmp(eshkp->customer, plname, PL_NSIZ)) {
3516                 if (!muteshk(shkp))
3517                     verbalize("%s, %s!  I was looking for %s.", Hello(shkp),
3518                               plname, eshkp->customer);
3519                 eshkp->following = 0;
3520                 return 0;
3521             }
3522             if (moves > followmsg + 4) {
3523                 if (!muteshk(shkp))
3524                     verbalize("%s, %s!  Didn't you forget to pay?",
3525                               Hello(shkp), plname);
3526                 followmsg = moves;
3527                 if (!rn2(9)) {
3528                     pline("%s doesn't like customers who don't pay.",
3529                           Monnam(shkp));
3530                     rile_shk(shkp);
3531                 }
3532             }
3533             if (udist < 2)
3534                 return 0;
3535         }
3536     }
3537
3538     appr = 1;
3539     gx = eshkp->shk.x;
3540     gy = eshkp->shk.y;
3541     satdoor = (gx == omx && gy == omy);
3542     if (eshkp->following || ((z = holetime()) >= 0 && z * z <= udist)) {
3543         /* [This distance check used to apply regardless of
3544             whether the shk was following, but that resulted in
3545             m_move() sometimes taking the shk out of the shop if
3546             the player had fenced him in with boulders or traps.
3547             Such voluntary abandonment left unpaid objects in
3548             invent, triggering billing impossibilities on the
3549             next level once the character fell through the hole.] */
3550         if (udist > 4 && eshkp->following && !eshkp->billct)
3551             return -1; /* leave it to m_move */
3552         gx = u.ux;
3553         gy = u.uy;
3554     } else if (ANGRY(shkp)) {
3555         /* Move towards the hero if the shopkeeper can see him. */
3556         if (shkp->mcansee && m_canseeu(shkp)) {
3557             gx = u.ux;
3558             gy = u.uy;
3559         }
3560         avoid = FALSE;
3561     } else {
3562 #define GDIST(x, y) (dist2(x, y, gx, gy))
3563         if (Invis || u.usteed) {
3564             avoid = FALSE;
3565         } else {
3566             uondoor = (u.ux == eshkp->shd.x && u.uy == eshkp->shd.y);
3567             if (uondoor) {
3568                 badinv =
3569                     (carrying(PICK_AXE) || carrying(DWARVISH_MATTOCK)
3570                      || (Fast && (sobj_at(PICK_AXE, u.ux, u.uy)
3571                                   || sobj_at(DWARVISH_MATTOCK, u.ux, u.uy))));
3572                 if (satdoor && badinv)
3573                     return 0;
3574                 avoid = !badinv;
3575             } else {
3576                 avoid = (*u.ushops && distu(gx, gy) > 8);
3577                 badinv = FALSE;
3578             }
3579
3580             if (((!eshkp->robbed && !eshkp->billct && !eshkp->debit) || avoid)
3581                 && GDIST(omx, omy) < 3) {
3582                 if (!badinv && !onlineu(omx, omy))
3583                     return 0;
3584                 if (satdoor)
3585                     appr = gx = gy = 0;
3586             }
3587         }
3588     }
3589
3590     z = move_special(shkp, inhishop(shkp), appr, uondoor, avoid, omx, omy, gx,
3591                      gy);
3592     if (z > 0)
3593         after_shk_move(shkp);
3594
3595     return z;
3596 }
3597
3598 /* called after shopkeeper moves, in case themove causes re-entry into shop */
3599 void
3600 after_shk_move(shkp)
3601 struct monst *shkp;
3602 {
3603     struct eshk *eshkp = ESHK(shkp);
3604
3605     if (eshkp->bill_p == (struct bill_x *) -1000 && inhishop(shkp)) {
3606         /* reset bill_p, need to re-calc player's occupancy too */
3607         eshkp->bill_p = &eshkp->bill[0];
3608         check_special_room(FALSE);
3609     }
3610 }
3611
3612 /* for use in levl_follower (mondata.c) */
3613 boolean
3614 is_fshk(mtmp)
3615 register struct monst *mtmp;
3616 {
3617     return (boolean) (mtmp->isshk && ESHK(mtmp)->following);
3618 }
3619
3620 /* You are digging in the shop. */
3621 void
3622 shopdig(fall)
3623 register int fall;
3624 {
3625     register struct monst *shkp = shop_keeper(*u.ushops);
3626     int lang;
3627     const char *grabs = "grabs";
3628
3629     if (!shkp)
3630         return;
3631
3632     /* 0 == can't speak, 1 == makes animal noises, 2 == speaks */
3633     lang = 0;
3634     if (shkp->msleeping || !shkp->mcanmove || is_silent(shkp->data))
3635         ; /* lang stays 0 */
3636     else if (shkp->data->msound <= MS_ANIMAL)
3637         lang = 1;
3638     else if (shkp->data->msound >= MS_HUMANOID)
3639         lang = 2;
3640
3641     if (!inhishop(shkp)) {
3642         if (Role_if(PM_KNIGHT)) {
3643             You_feel("like a common thief.");
3644             adjalign(-sgn(u.ualign.type));
3645         }
3646         return;
3647     }
3648
3649     if (!fall) {
3650         if (lang == 2) {
3651             if (u.utraptype == TT_PIT)
3652                 verbalize(
3653                     "Be careful, %s, or you might fall through the floor.",
3654                     flags.female ? "madam" : "sir");
3655             else
3656                 verbalize("%s, do not damage the floor here!",
3657                           flags.female ? "Madam" : "Sir");
3658         }
3659         if (Role_if(PM_KNIGHT)) {
3660             You_feel("like a common thief.");
3661             adjalign(-sgn(u.ualign.type));
3662         }
3663     } else if (!um_dist(shkp->mx, shkp->my, 5)
3664                && !shkp->msleeping && shkp->mcanmove
3665                && (ESHK(shkp)->billct || ESHK(shkp)->debit)) {
3666         register struct obj *obj, *obj2;
3667
3668         if (nolimbs(shkp->data)) {
3669             grabs = "knocks off";
3670 #if 0
3671             /* This is what should happen, but for balance
3672              * reasons, it isn't currently.
3673              */
3674             if (lang == 2)
3675                 pline("%s curses %s inability to grab your backpack!",
3676                       shkname(shkp), mhim(shkp));
3677             rile_shk(shkp);
3678             return;
3679 #endif
3680         }
3681         if (distu(shkp->mx, shkp->my) > 2) {
3682             mnexto(shkp);
3683             /* for some reason the shopkeeper can't come next to you */
3684             if (distu(shkp->mx, shkp->my) > 2) {
3685                 if (lang == 2)
3686                     pline("%s curses you in anger and frustration!",
3687                           shkname(shkp));
3688                 else if (lang == 1)
3689                     growl(shkp);
3690                 rile_shk(shkp);
3691                 return;
3692             } else
3693                 pline("%s %s, and %s your backpack!", shkname(shkp),
3694                       makeplural(locomotion(shkp->data, "leap")), grabs);
3695         } else
3696             pline("%s %s your backpack!", shkname(shkp), grabs);
3697
3698         for (obj = invent; obj; obj = obj2) {
3699             obj2 = obj->nobj;
3700             if ((obj->owornmask & ~(W_SWAPWEP | W_QUIVER)) != 0
3701                 || (obj == uswapwep && u.twoweap)
3702                 || (obj->otyp == LEASH && obj->leashmon))
3703                 continue;
3704             if (obj == current_wand)
3705                 continue;
3706             setnotworn(obj);
3707             freeinv(obj);
3708             subfrombill(obj, shkp);
3709             (void) add_to_minv(shkp, obj); /* may free obj */
3710         }
3711     }
3712 }
3713
3714 STATIC_OVL void
3715 makekops(mm)
3716 coord *mm;
3717 {
3718     static const short k_mndx[4] = { PM_KEYSTONE_KOP, PM_KOP_SERGEANT,
3719                                      PM_KOP_LIEUTENANT, PM_KOP_KAPTAIN };
3720     int k_cnt[4], cnt, mndx, k;
3721
3722     k_cnt[0] = cnt = abs(depth(&u.uz)) + rnd(5);
3723     k_cnt[1] = (cnt / 3) + 1; /* at least one sarge */
3724     k_cnt[2] = (cnt / 6);     /* maybe a lieutenant */
3725     k_cnt[3] = (cnt / 9);     /* and maybe a kaptain */
3726
3727     for (k = 0; k < 4; k++) {
3728         if ((cnt = k_cnt[k]) == 0)
3729             break;
3730         mndx = k_mndx[k];
3731         if (mvitals[mndx].mvflags & G_GONE)
3732             continue;
3733
3734         while (cnt--)
3735             if (enexto(mm, mm->x, mm->y, &mons[mndx]))
3736                 (void) makemon(&mons[mndx], mm->x, mm->y, NO_MM_FLAGS);
3737     }
3738 }
3739
3740 void
3741 pay_for_damage(dmgstr, cant_mollify)
3742 const char *dmgstr;
3743 boolean cant_mollify;
3744 {
3745     register struct monst *shkp = (struct monst *) 0;
3746     char shops_affected[5];
3747     register boolean uinshp = (*u.ushops != '\0');
3748     char qbuf[80];
3749     register xchar x, y;
3750     boolean dugwall = (!strcmp(dmgstr, "dig into")    /* wand */
3751                        || !strcmp(dmgstr, "damage")); /* pick-axe */
3752     boolean animal, pursue;
3753     struct damage *tmp_dam, *appear_here = 0;
3754     /* any number >= (80*80)+(24*24) would do, actually */
3755     long cost_of_damage = 0L;
3756     unsigned int nearest_shk = 7000, nearest_damage = 7000;
3757     int picks = 0;
3758
3759     for (tmp_dam = level.damagelist;
3760          (tmp_dam && (tmp_dam->when == monstermoves));
3761          tmp_dam = tmp_dam->next) {
3762         char *shp;
3763
3764         if (!tmp_dam->cost)
3765             continue;
3766         cost_of_damage += tmp_dam->cost;
3767         Strcpy(shops_affected,
3768                in_rooms(tmp_dam->place.x, tmp_dam->place.y, SHOPBASE));
3769         for (shp = shops_affected; *shp; shp++) {
3770             struct monst *tmp_shk;
3771             unsigned int shk_distance;
3772
3773             if (!(tmp_shk = shop_keeper(*shp)))
3774                 continue;
3775             if (tmp_shk == shkp) {
3776                 unsigned int damage_distance =
3777                     distu(tmp_dam->place.x, tmp_dam->place.y);
3778
3779                 if (damage_distance < nearest_damage) {
3780                     nearest_damage = damage_distance;
3781                     appear_here = tmp_dam;
3782                 }
3783                 continue;
3784             }
3785             if (!inhishop(tmp_shk))
3786                 continue;
3787             shk_distance = distu(tmp_shk->mx, tmp_shk->my);
3788             if (shk_distance > nearest_shk)
3789                 continue;
3790             if ((shk_distance == nearest_shk) && picks) {
3791                 if (rn2(++picks))
3792                     continue;
3793             } else
3794                 picks = 1;
3795             shkp = tmp_shk;
3796             nearest_shk = shk_distance;
3797             appear_here = tmp_dam;
3798             nearest_damage = distu(tmp_dam->place.x, tmp_dam->place.y);
3799         }
3800     }
3801
3802     if (!cost_of_damage || !shkp)
3803         return;
3804
3805     animal = (shkp->data->msound <= MS_ANIMAL);
3806     pursue = FALSE;
3807     x = appear_here->place.x;
3808     y = appear_here->place.y;
3809
3810     /* not the best introduction to the shk... */
3811     (void) strncpy(ESHK(shkp)->customer, plname, PL_NSIZ);
3812
3813     /* if the shk is already on the war path, be sure it's all out */
3814     if (ANGRY(shkp) || ESHK(shkp)->following) {
3815         hot_pursuit(shkp);
3816         return;
3817     }
3818
3819     /* if the shk is not in their shop.. */
3820     if (!*in_rooms(shkp->mx, shkp->my, SHOPBASE)) {
3821         if (!cansee(shkp->mx, shkp->my))
3822             return;
3823         pursue = TRUE;
3824         goto getcad;
3825     }
3826
3827     if (uinshp) {
3828         if (um_dist(shkp->mx, shkp->my, 1)
3829             && !um_dist(shkp->mx, shkp->my, 3)) {
3830             pline("%s leaps towards you!", shkname(shkp));
3831             mnexto(shkp);
3832         }
3833         pursue = um_dist(shkp->mx, shkp->my, 1);
3834         if (pursue)
3835             goto getcad;
3836     } else {
3837         /*
3838          * Make shkp show up at the door.  Effect:  If there is a monster
3839          * in the doorway, have the hero hear the shopkeeper yell a bit,
3840          * pause, then have the shopkeeper appear at the door, having
3841          * yanked the hapless critter out of the way.
3842          */
3843         if (MON_AT(x, y)) {
3844             if (!Deaf && !animal) {
3845                 You_hear("an angry voice:");
3846                 verbalize("Out of my way, scum!");
3847                 wait_synch();
3848 #if defined(UNIX) || defined(VMS)
3849 #if defined(SYSV) || defined(ULTRIX) || defined(VMS)
3850                 (void)
3851 #endif
3852                     sleep(1);
3853 #endif
3854             } else {
3855                 growl(shkp);
3856             }
3857         }
3858         (void) mnearto(shkp, x, y, TRUE);
3859     }
3860
3861     if ((um_dist(x, y, 1) && !uinshp) || cant_mollify
3862         || (money_cnt(invent) + ESHK(shkp)->credit) < cost_of_damage
3863         || !rn2(50)) {
3864     getcad:
3865         if (muteshk(shkp)) {
3866             if (animal && shkp->mcanmove && !shkp->msleeping)
3867                 yelp(shkp);
3868         } else if (pursue || uinshp || !um_dist(x, y, 1)) {
3869             verbalize("How dare you %s my %s?", dmgstr,
3870                       dugwall ? "shop" : "door");
3871         } else {
3872             pline("%s shouts:", shkname(shkp));
3873             verbalize("Who dared %s my %s?", dmgstr,
3874                       dugwall ? "shop" : "door");
3875         }
3876         hot_pursuit(shkp);
3877         return;
3878     }
3879
3880     if (Invis)
3881         Your("invisibility does not fool %s!", shkname(shkp));
3882     Sprintf(qbuf, "%sYou did %ld %s worth of damage!%s  Pay?",
3883             !animal ? cad(TRUE) : "", cost_of_damage,
3884             currency(cost_of_damage), !animal ? "\"" : "");
3885     if (yn(qbuf) != 'n') {
3886         cost_of_damage = check_credit(cost_of_damage, shkp);
3887         money2mon(shkp, cost_of_damage);
3888         context.botl = 1;
3889         pline("Mollified, %s accepts your restitution.", shkname(shkp));
3890         /* move shk back to his home loc */
3891         home_shk(shkp, FALSE);
3892         pacify_shk(shkp);
3893     } else {
3894         if (!animal)
3895             verbalize("Oh, yes!  You'll pay!");
3896         else
3897             growl(shkp);
3898         hot_pursuit(shkp);
3899         adjalign(-sgn(u.ualign.type));
3900     }
3901 }
3902
3903 /* called in dokick.c when we kick an object that might be in a store */
3904 boolean
3905 costly_spot(x, y)
3906 register xchar x, y;
3907 {
3908     struct monst *shkp;
3909     struct eshk *eshkp;
3910
3911     if (!level.flags.has_shop)
3912         return FALSE;
3913     shkp = shop_keeper(*in_rooms(x, y, SHOPBASE));
3914     if (!shkp || !inhishop(shkp))
3915         return FALSE;
3916     eshkp = ESHK(shkp);
3917     return  (boolean) (inside_shop(x, y)
3918                        && !(x == eshkp->shk.x && y == eshkp->shk.y));
3919 }
3920
3921 /* called by dotalk(sounds.c) when #chatting; returns obj if location
3922    contains shop goods and shopkeeper is willing & able to speak */
3923 struct obj *
3924 shop_object(x, y)
3925 register xchar x, y;
3926 {
3927     register struct obj *otmp;
3928     register struct monst *shkp;
3929
3930     if (!(shkp = shop_keeper(*in_rooms(x, y, SHOPBASE))) || !inhishop(shkp))
3931         return (struct obj *) 0;
3932
3933     for (otmp = level.objects[x][y]; otmp; otmp = otmp->nexthere)
3934         if (otmp->oclass != COIN_CLASS)
3935             break;
3936     /* note: otmp might have ->no_charge set, but that's ok */
3937     return (otmp && costly_spot(x, y)
3938             && NOTANGRY(shkp) && shkp->mcanmove && !shkp->msleeping)
3939                ? otmp
3940                : (struct obj *) 0;
3941 }
3942
3943 /* give price quotes for all objects linked to this one (ie, on this spot) */
3944 void
3945 price_quote(first_obj)
3946 register struct obj *first_obj;
3947 {
3948     register struct obj *otmp;
3949     char buf[BUFSZ], price[40];
3950     long cost = 0L;
3951     int cnt = 0;
3952     boolean contentsonly = FALSE;
3953     winid tmpwin;
3954     struct monst *shkp = shop_keeper(inside_shop(u.ux, u.uy));
3955
3956     tmpwin = create_nhwindow(NHW_MENU);
3957     putstr(tmpwin, 0, "Fine goods for sale:");
3958     putstr(tmpwin, 0, "");
3959     for (otmp = first_obj; otmp; otmp = otmp->nexthere) {
3960         if (otmp->oclass == COIN_CLASS)
3961             continue;
3962         cost = (otmp->no_charge || otmp == uball || otmp == uchain)
3963                    ? 0L
3964                    : get_cost(otmp, (struct monst *) 0);
3965         contentsonly = !cost;
3966         if (Has_contents(otmp))
3967             cost += contained_cost(otmp, shkp, 0L, FALSE, FALSE);
3968         if (!cost) {
3969             Strcpy(price, "no charge");
3970             contentsonly = FALSE;
3971         } else {
3972             Sprintf(price, "%ld %s%s", cost, currency(cost),
3973                     (otmp->quan) > 1L ? " each" : "");
3974         }
3975         Sprintf(buf, "%s%s, %s", contentsonly ? the_contents_of : "",
3976                 doname(otmp), price);
3977         putstr(tmpwin, 0, buf), cnt++;
3978     }
3979     if (cnt > 1) {
3980         display_nhwindow(tmpwin, TRUE);
3981     } else if (cnt == 1) {
3982         if (!cost) {
3983             /* "<doname(obj)>, no charge" */
3984             pline("%s!", upstart(buf)); /* buf still contains the string */
3985         } else {
3986             /* print cost in slightly different format, so can't reuse buf;
3987                cost and contentsonly are already set up */
3988             Sprintf(buf, "%s%s", contentsonly ? the_contents_of : "",
3989                     doname(first_obj));
3990             pline("%s, price %ld %s%s%s", upstart(buf), cost, currency(cost),
3991                   (first_obj->quan > 1L) ? " each" : "",
3992                   contentsonly ? "." : shk_embellish(first_obj, cost));
3993         }
3994     }
3995     destroy_nhwindow(tmpwin);
3996 }
3997
3998 STATIC_OVL const char *
3999 shk_embellish(itm, cost)
4000 register struct obj *itm;
4001 long cost;
4002 {
4003     if (!rn2(3)) {
4004         register int o, choice = rn2(5);
4005         if (choice == 0)
4006             choice = (cost < 100L ? 1 : cost < 500L ? 2 : 3);
4007         switch (choice) {
4008         case 4:
4009             if (cost < 10L)
4010                 break;
4011             else
4012                 o = itm->oclass;
4013             if (o == FOOD_CLASS)
4014                 return ", gourmets' delight!";
4015             if (objects[itm->otyp].oc_name_known
4016                     ? objects[itm->otyp].oc_magic
4017                     : (o == AMULET_CLASS || o == RING_CLASS || o == WAND_CLASS
4018                        || o == POTION_CLASS || o == SCROLL_CLASS
4019                        || o == SPBOOK_CLASS))
4020                 return ", painstakingly developed!";
4021             return ", superb craftsmanship!";
4022         case 3:
4023             return ", finest quality.";
4024         case 2:
4025             return ", an excellent choice.";
4026         case 1:
4027             return ", a real bargain.";
4028         default:
4029             break;
4030         }
4031     } else if (itm->oartifact) {
4032         return ", one of a kind!";
4033     }
4034     return ".";
4035 }
4036
4037 /* First 4 supplied by Ronen and Tamar, remainder by development team */
4038 const char *Izchak_speaks[] = {
4039     "%s says: 'These shopping malls give me a headache.'",
4040     "%s says: 'Slow down.  Think clearly.'",
4041     "%s says: 'You need to take things one at a time.'",
4042     "%s says: 'I don't like poofy coffee... give me Columbian Supremo.'",
4043     "%s says that getting the devteam's agreement on anything is difficult.",
4044     "%s says that he has noticed those who serve their deity will prosper.",
4045     "%s says: 'Don't try to steal from me - I have friends in high places!'",
4046     "%s says: 'You may well need something from this shop in the future.'",
4047     "%s comments about the Valley of the Dead as being a gateway."
4048 };
4049
4050 void
4051 shk_chat(shkp)
4052 struct monst *shkp;
4053 {
4054     struct eshk *eshk;
4055     long shkmoney;
4056     if (!shkp->isshk) {
4057         /* The monster type is shopkeeper, but this monster is
4058            not actually a shk, which could happen if someone
4059            wishes for a shopkeeper statue and then animates it.
4060            (Note: shkname() would be "" in a case like this.) */
4061         pline("%s asks whether you've seen any untended shops recently.",
4062               Monnam(shkp));
4063         /* [Perhaps we ought to check whether this conversation
4064            is taking place inside an untended shop, but a shopless
4065            shk can probably be expected to be rather disoriented.] */
4066         return;
4067     }
4068
4069     eshk = ESHK(shkp);
4070     if (ANGRY(shkp)) {
4071         pline("%s mentions how much %s dislikes %s customers.",
4072               shkname(shkp), mhe(shkp), eshk->robbed ? "non-paying" : "rude");
4073     } else if (eshk->following) {
4074         if (strncmp(eshk->customer, plname, PL_NSIZ)) {
4075             verbalize("%s %s!  I was looking for %s.",
4076                       Hello(shkp), plname, eshk->customer);
4077             eshk->following = 0;
4078         } else {
4079             verbalize("%s %s!  Didn't you forget to pay?",
4080                       Hello(shkp), plname);
4081         }
4082     } else if (eshk->billct) {
4083         register long total = addupbill(shkp) + eshk->debit;
4084
4085         pline("%s says that your bill comes to %ld %s.",
4086               shkname(shkp), total, currency(total));
4087     } else if (eshk->debit) {
4088         pline("%s reminds you that you owe %s %ld %s.",
4089               shkname(shkp), mhim(shkp), eshk->debit, currency(eshk->debit));
4090     } else if (eshk->credit) {
4091         pline("%s encourages you to use your %ld %s of credit.",
4092               shkname(shkp), eshk->credit, currency(eshk->credit));
4093     } else if (eshk->robbed) {
4094         pline("%s complains about a recent robbery.", shkname(shkp));
4095     } else if ((shkmoney = money_cnt(shkp->minvent)) < 50) {
4096         pline("%s complains that business is bad.", shkname(shkp));
4097     } else if (shkmoney > 4000) {
4098         pline("%s says that business is good.", shkname(shkp));
4099     } else if (is_izchak(shkp, FALSE)) {
4100         pline(Izchak_speaks[rn2(SIZE(Izchak_speaks))], shkname(shkp));
4101     } else {
4102         pline("%s talks about the problem of shoplifters.", shkname(shkp));
4103     }
4104 }
4105
4106 STATIC_OVL void
4107 kops_gone(silent)
4108 boolean silent;
4109 {
4110     register int cnt = 0;
4111     register struct monst *mtmp, *mtmp2;
4112
4113     for (mtmp = fmon; mtmp; mtmp = mtmp2) {
4114         mtmp2 = mtmp->nmon;
4115         if (mtmp->data->mlet == S_KOP) {
4116             if (canspotmon(mtmp))
4117                 cnt++;
4118             mongone(mtmp);
4119         }
4120     }
4121     if (cnt && !silent)
4122         pline_The("Kop%s (disappointed) vanish%s into thin air.",
4123                   plur(cnt), (cnt == 1) ? "es" : "");
4124 }
4125
4126 STATIC_OVL long
4127 cost_per_charge(shkp, otmp, altusage)
4128 struct monst *shkp;
4129 struct obj *otmp;
4130 boolean altusage; /* some items have an "alternate" use with different cost */
4131 {
4132     long tmp = 0L;
4133
4134     if (!shkp || !inhishop(shkp))
4135         return 0L; /* insurance */
4136     tmp = get_cost(otmp, shkp);
4137
4138     /* The idea is to make the exhaustive use of an unpaid item
4139      * more expensive than buying it outright.
4140      */
4141     if (otmp->otyp == MAGIC_LAMP) { /* 1 */
4142         /* normal use (ie, as light source) of a magic lamp never
4143            degrades its value, but not charging anything would make
4144            identification too easy; charge an amount comparable to
4145            what is charged for an ordinary lamp (don't bother with
4146            angry shk surcharge) */
4147         if (!altusage)
4148             tmp = (long) objects[OIL_LAMP].oc_cost;
4149         else
4150             tmp += tmp / 3L;                 /* djinni is being released */
4151     } else if (otmp->otyp == MAGIC_MARKER) { /* 70 - 100 */
4152         /* No way to determine in advance how many charges will be
4153          * wasted.  So, arbitrarily, one half of the price per use.
4154          */
4155         tmp /= 2L;
4156     } else if (otmp->otyp == BAG_OF_TRICKS /* 1 - 20 */
4157                || otmp->otyp == HORN_OF_PLENTY) {
4158         /* altusage: emptying of all the contents at once */
4159         if (!altusage)
4160             tmp /= 5L;
4161     } else if (otmp->otyp == CRYSTAL_BALL               /* 1 - 5 */
4162                || otmp->otyp == OIL_LAMP                /* 1 - 10 */
4163                || otmp->otyp == BRASS_LANTERN
4164                || (otmp->otyp >= MAGIC_FLUTE
4165                    && otmp->otyp <= DRUM_OF_EARTHQUAKE) /* 5 - 9 */
4166                || otmp->oclass == WAND_CLASS) {         /* 3 - 11 */
4167         if (otmp->spe > 1)
4168             tmp /= 4L;
4169     } else if (otmp->oclass == SPBOOK_CLASS) {
4170         tmp -= tmp / 5L;
4171     } else if (otmp->otyp == CAN_OF_GREASE || otmp->otyp == TINNING_KIT
4172                || otmp->otyp == EXPENSIVE_CAMERA) {
4173         tmp /= 10L;
4174     } else if (otmp->otyp == POT_OIL) {
4175         tmp /= 5L;
4176     }
4177     return tmp;
4178 }
4179
4180 /* Charge the player for partial use of an unpaid object.
4181  *
4182  * Note that bill_dummy_object() should be used instead
4183  * when an object is completely used.
4184  */
4185 void
4186 check_unpaid_usage(otmp, altusage)
4187 struct obj *otmp;
4188 boolean altusage;
4189 {
4190     struct monst *shkp;
4191     const char *fmt, *arg1, *arg2;
4192     char buf[BUFSZ];
4193     long tmp;
4194
4195     if (!otmp->unpaid || !*u.ushops
4196         || (otmp->spe <= 0 && objects[otmp->otyp].oc_charged))
4197         return;
4198     if (!(shkp = shop_keeper(*u.ushops)) || !inhishop(shkp))
4199         return;
4200     if ((tmp = cost_per_charge(shkp, otmp, altusage)) == 0L)
4201         return;
4202
4203     arg1 = arg2 = "";
4204     if (otmp->oclass == SPBOOK_CLASS) {
4205         fmt = "%sYou owe%s %ld %s.";
4206         Sprintf(buf, "This is no free library, %s!  ", cad(FALSE));
4207         arg1 = rn2(2) ? buf : "";
4208         arg2 = ESHK(shkp)->debit > 0L ? " an additional" : "";
4209     } else if (otmp->otyp == POT_OIL) {
4210         fmt = "%s%sThat will cost you %ld %s (Yendorian Fuel Tax).";
4211     } else if (altusage && (otmp->otyp == BAG_OF_TRICKS
4212                             || otmp->otyp == HORN_OF_PLENTY)) {
4213         fmt = "%s%sEmptying that will cost you %ld %s.";
4214         if (!rn2(3))
4215             arg1 = "Whoa!  ";
4216         if (!rn2(3))
4217             arg1 = "Watch it!  ";
4218     } else {
4219         fmt = "%s%sUsage fee, %ld %s.";
4220         if (!rn2(3))
4221             arg1 = "Hey!  ";
4222         if (!rn2(3))
4223             arg2 = "Ahem.  ";
4224     }
4225
4226     if (!muteshk(shkp)) {
4227         verbalize(fmt, arg1, arg2, tmp, currency(tmp));
4228         exercise(A_WIS, TRUE); /* you just got info */
4229     }
4230     ESHK(shkp)->debit += tmp;
4231 }
4232
4233 /* for using charges of unpaid objects "used in the normal manner" */
4234 void
4235 check_unpaid(otmp)
4236 struct obj *otmp;
4237 {
4238     check_unpaid_usage(otmp, FALSE); /* normal item use */
4239 }
4240
4241 void
4242 costly_gold(x, y, amount)
4243 register xchar x, y;
4244 register long amount;
4245 {
4246     register long delta;
4247     register struct monst *shkp;
4248     register struct eshk *eshkp;
4249
4250     if (!costly_spot(x, y))
4251         return;
4252     /* shkp now guaranteed to exist by costly_spot() */
4253     shkp = shop_keeper(*in_rooms(x, y, SHOPBASE));
4254
4255     eshkp = ESHK(shkp);
4256     if (eshkp->credit >= amount) {
4257         if (eshkp->credit > amount)
4258             Your("credit is reduced by %ld %s.", amount, currency(amount));
4259         else
4260             Your("credit is erased.");
4261         eshkp->credit -= amount;
4262     } else {
4263         delta = amount - eshkp->credit;
4264         if (eshkp->credit)
4265             Your("credit is erased.");
4266         if (eshkp->debit)
4267             Your("debt increases by %ld %s.", delta, currency(delta));
4268         else
4269             You("owe %s %ld %s.", shkname(shkp), delta, currency(delta));
4270         eshkp->debit += delta;
4271         eshkp->loan += delta;
4272         eshkp->credit = 0L;
4273     }
4274 }
4275
4276 /* used in domove to block diagonal shop-exit */
4277 /* x,y should always be a door */
4278 boolean
4279 block_door(x, y)
4280 register xchar x, y;
4281 {
4282     register int roomno = *in_rooms(x, y, SHOPBASE);
4283     register struct monst *shkp;
4284
4285     if (roomno < 0 || !IS_SHOP(roomno))
4286         return FALSE;
4287     if (!IS_DOOR(levl[x][y].typ))
4288         return FALSE;
4289     if (roomno != *u.ushops)
4290         return FALSE;
4291
4292     if (!(shkp = shop_keeper((char) roomno)) || !inhishop(shkp))
4293         return FALSE;
4294
4295     if (shkp->mx == ESHK(shkp)->shk.x && shkp->my == ESHK(shkp)->shk.y
4296         /* Actually, the shk should be made to block _any_
4297          * door, including a door the player digs, if the
4298          * shk is within a 'jumping' distance.
4299          */
4300         && ESHK(shkp)->shd.x == x
4301         && ESHK(shkp)->shd.y == y
4302         && shkp->mcanmove && !shkp->msleeping
4303         && (ESHK(shkp)->debit || ESHK(shkp)->billct || ESHK(shkp)->robbed)) {
4304         pline("%s%s blocks your way!", shkname(shkp),
4305               Invis ? " senses your motion and" : "");
4306         return TRUE;
4307     }
4308     return FALSE;
4309 }
4310
4311 /* used in domove to block diagonal shop-entry;
4312    u.ux, u.uy should always be a door */
4313 boolean
4314 block_entry(x, y)
4315 register xchar x, y;
4316 {
4317     register xchar sx, sy;
4318     register int roomno;
4319     register struct monst *shkp;
4320
4321     if (!(IS_DOOR(levl[u.ux][u.uy].typ)
4322           && levl[u.ux][u.uy].doormask == D_BROKEN))
4323         return FALSE;
4324
4325     roomno = *in_rooms(x, y, SHOPBASE);
4326     if (roomno < 0 || !IS_SHOP(roomno))
4327         return FALSE;
4328     if (!(shkp = shop_keeper((char) roomno)) || !inhishop(shkp))
4329         return FALSE;
4330
4331     if (ESHK(shkp)->shd.x != u.ux || ESHK(shkp)->shd.y != u.uy)
4332         return FALSE;
4333
4334     sx = ESHK(shkp)->shk.x;
4335     sy = ESHK(shkp)->shk.y;
4336
4337     if (shkp->mx == sx && shkp->my == sy && shkp->mcanmove && !shkp->msleeping
4338         && (x == sx - 1 || x == sx + 1 || y == sy - 1 || y == sy + 1)
4339         && (Invis || carrying(PICK_AXE) || carrying(DWARVISH_MATTOCK)
4340             || u.usteed)) {
4341         pline("%s%s blocks your way!", shkname(shkp),
4342               Invis ? " senses your motion and" : "");
4343         return TRUE;
4344     }
4345     return FALSE;
4346 }
4347
4348 /* "your " or "Foobar's " (note the trailing space) */
4349 char *
4350 shk_your(buf, obj)
4351 char *buf;
4352 struct obj *obj;
4353 {
4354     if (!shk_owns(buf, obj) && !mon_owns(buf, obj))
4355         Strcpy(buf, the_your[carried(obj) ? 1 : 0]);
4356     return strcat(buf, " ");
4357 }
4358
4359 char *
4360 Shk_Your(buf, obj)
4361 char *buf;
4362 struct obj *obj;
4363 {
4364     (void) shk_your(buf, obj);
4365     *buf = highc(*buf);
4366     return buf;
4367 }
4368
4369 STATIC_OVL char *
4370 shk_owns(buf, obj)
4371 char *buf;
4372 struct obj *obj;
4373 {
4374     struct monst *shkp;
4375     xchar x, y;
4376
4377     if (get_obj_location(obj, &x, &y, 0)
4378         && (obj->unpaid || (obj->where == OBJ_FLOOR && !obj->no_charge
4379                             && costly_spot(x, y)))) {
4380         shkp = shop_keeper(inside_shop(x, y));
4381         return strcpy(buf, shkp ? s_suffix(shkname(shkp)) : the_your[0]);
4382     }
4383     return (char *) 0;
4384 }
4385
4386 STATIC_OVL char *
4387 mon_owns(buf, obj)
4388 char *buf;
4389 struct obj *obj;
4390 {
4391     if (obj->where == OBJ_MINVENT)
4392         return strcpy(buf, s_suffix(y_monnam(obj->ocarry)));
4393     return (char *) 0;
4394 }
4395
4396 STATIC_OVL const char *
4397 cad(altusage)
4398 boolean altusage; /* used as a verbalized exclamation:  \"Cad! ...\" */
4399 {
4400     const char *res = 0;
4401
4402     switch (is_demon(youmonst.data) ? 3 : poly_gender()) {
4403     case 0:
4404         res = "cad";
4405         break;
4406     case 1:
4407         res = "minx";
4408         break;
4409     case 2:
4410         res = "beast";
4411         break;
4412     case 3:
4413         res = "fiend";
4414         break;
4415     default:
4416         impossible("cad: unknown gender");
4417         res = "thing";
4418         break;
4419     }
4420     if (altusage) {
4421         char *cadbuf = mon_nam(&youmonst); /* snag an output buffer */
4422
4423         /* alternate usage adds a leading double quote and trailing
4424            exclamation point plus sentence separating spaces */
4425         Sprintf(cadbuf, "\"%s!  ", res);
4426         cadbuf[1] = highc(cadbuf[1]);
4427         res = cadbuf;
4428     }
4429     return res;
4430 }
4431
4432 #ifdef __SASC
4433 void
4434 sasc_bug(struct obj *op, unsigned x)
4435 {
4436     op->unpaid = x;
4437 }
4438 #endif
4439
4440 /*shk.c*/