OSDN Git Service

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