Fandom

Wikihack

Source:NetHack 3.1.0/shk.c

2,034pages on
this wiki
Add New Page
Talk0

Ad blocker interference detected!


Wikia is a free-to-use site that makes money from advertising. We have a modified experience for viewers using ad blockers

Wikia is not accessible if you’ve made further modifications. Remove the custom ad blocker rule(s) and the page will load as expected.

Below is the full text to shk.c from the source code of NetHack 3.1.0. To link to a particular line, write [[NetHack 3.1.0/shk.c#line123]], for example.

Warning! This is the source code from an old release. For the latest release, see Source code

The NetHack General Public License applies to screenshots, source code and other content from NetHack.
1.    /*	SCCS Id: @(#)shk.c	3.1	93/01/12	*/
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 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.   
28.   STATIC_VAR long int NEARDATA followmsg;	/* last time of follow message */
29.   
30.   STATIC_DCL void FDECL(setpaid, (struct monst *));
31.   STATIC_DCL long FDECL(addupbill, (struct monst *));
32.   STATIC_DCL void FDECL(pacify_shk, (struct monst *));
33.   
34.   #ifdef OVLB
35.   
36.   static void FDECL(clear_unpaid,(struct obj *));
37.   static struct bill_x *FDECL(onbill, (struct obj *, struct monst *, BOOLEAN_P));
38.   static long FDECL(check_credit, (long, struct monst *));
39.   static void FDECL(pay, (long, struct monst *));
40.   static long FDECL(get_cost, (struct obj *, struct monst *));
41.   static long FDECL(set_cost, (struct obj *, struct monst *));
42.   static const char *FDECL(shk_embellish, (struct obj *, long));
43.   static long FDECL(cost_per_charge, (struct obj *));
44.   static long FDECL(cheapest_item, (struct monst *));
45.   static int FDECL(dopayobj, (struct monst *, struct bill_x *,
46.   			    struct obj *, int, BOOLEAN_P));
47.   static long FDECL(stolen_container, (struct obj *, struct monst *, long,
48.   				     BOOLEAN_P));
49.   static long FDECL(getprice, (struct obj *));
50.   static struct obj *FDECL(bp_to_obj, (struct bill_x *));
51.   static boolean FDECL(inherits, (struct monst *, int, BOOLEAN_P));
52.   static struct monst *FDECL(next_shkp, (struct monst *, BOOLEAN_P));
53.   static boolean NDECL(angry_shk_exists);
54.   static void FDECL(rile_shk, (struct monst *));
55.   static void FDECL(remove_damage, (struct monst *, BOOLEAN_P));
56.   static void FDECL(sub_one_frombill, (struct obj *, struct monst *));
57.   static void FDECL(add_one_tobill, (struct obj *, BOOLEAN_P));
58.   static void FDECL(dropped_container, (struct obj *));
59.   static void FDECL(bill_box_content, (struct obj *, BOOLEAN_P, BOOLEAN_P,
60.   				     struct monst *));
61.   
62.   /*
63.   	invariants: obj->unpaid iff onbill(obj) [unless bp->useup]
64.   		obj->quan <= bp->bquan
65.    */
66.   
67.   static struct monst *
68.   next_shkp(shkp, withbill)
69.   register struct monst *shkp;
70.   register boolean withbill;
71.   {
72.   	for (; shkp; shkp = shkp->nmon)
73.   	    if (shkp->isshk)
74.   		if (ESHK(shkp)->billct || !withbill) break;
75.   
76.   	if (shkp) {
77.   	    if (NOTANGRY(shkp)) {
78.   		if (ESHK(shkp)->surcharge) pacify_shk(shkp);
79.   	    } else {
80.   		if (!ESHK(shkp)->surcharge) rile_shk(shkp);
81.   	    }
82.   	}
83.   	return(shkp);
84.   }
85.   
86.   char *
87.   shkname(mtmp)				/* called in do_name.c */
88.   register struct monst *mtmp;
89.   {
90.   	return(ESHK(mtmp)->shknam);
91.   }
92.   
93.   void
94.   shkgone(mtmp)				/* called in mon.c */
95.   register struct monst *mtmp;
96.   {
97.   	register struct eshk *eshk = ESHK(mtmp);
98.   
99.   	if(on_level(&(eshk->shoplevel), &u.uz)) {
100.  		remove_damage(mtmp, TRUE);
101.  		rooms[eshk->shoproom - ROOMOFFSET].resident
102.  						  = (struct monst *)0;
103.  		if(!search_special(ANY_SHOP))
104.  		    level.flags.has_shop = 0;
105.  	}
106.  	/* make sure bill is set only when the
107.  	 * dead shk is the resident shk.	*/
108.  	if(*u.ushops == eshk->shoproom) {
109.  	    setpaid(mtmp);
110.  	    /* dump core when referenced */
111.  	    ESHK(mtmp)->bill_p = (struct bill_x *) -1000;
112.  	    u.ushops[0] = '\0';
113.  	}
114.  }
115.  
116.  void
117.  set_residency(shkp, zero_out)
118.  register struct monst *shkp;
119.  register boolean zero_out;
120.  {
121.  	if (on_level(&(ESHK(shkp)->shoplevel), &u.uz))
122.  	    rooms[ESHK(shkp)->shoproom - ROOMOFFSET].resident =
123.  		(zero_out)? (struct monst *)0 : shkp;
124.  }
125.  
126.  void
127.  replshk(mtmp,mtmp2)
128.  register struct monst *mtmp, *mtmp2;
129.  {
130.  	if(inhishop(mtmp) && *u.ushops == ESHK(mtmp)->shoproom) {
131.  		ESHK(mtmp2)->bill_p = &(ESHK(mtmp2)->bill[0]);
132.  	}
133.  }
134.  
135.  /* do shopkeeper specific structure munging -dlc */
136.  void
137.  restshk(mtmp)
138.  register struct monst *mtmp;
139.  {
140.      if(ESHK(mtmp)->bill_p != (struct bill_x *) -1000)
141.  	ESHK(mtmp)->bill_p = &(ESHK(mtmp)->bill[0]);
142.  }
143.  
144.  /* Clear the unpaid bit on all of the objects in the list. */
145.  static void
146.  clear_unpaid(list)
147.  register struct obj *list;
148.  {
149.      while (list) {
150.  	if (Is_container(list)) clear_unpaid(list->cobj);
151.  	list->unpaid = 0;
152.  	list = list->nobj;
153.      }
154.  }
155.  
156.  STATIC_OVL void
157.  setpaid(shkp)	/* either you paid or left the shop or the shopkeeper died */
158.  register struct monst *shkp;
159.  {
160.  	register struct obj *obj;
161.  	register struct monst *mtmp;
162.  
163.  	clear_unpaid(invent);
164.  	clear_unpaid(fobj);
165.  	for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
166.  		clear_unpaid(mtmp->minvent);
167.  	for(mtmp = migrating_mons; mtmp; mtmp = mtmp->nmon)
168.  		clear_unpaid(mtmp->minvent);
169.  
170.  	while ((obj = billobjs) != 0) {
171.  		billobjs = obj->nobj;
172.  		dealloc_obj(obj);
173.  	}
174.  	if(shkp) {
175.  		ESHK(shkp)->billct = 0;
176.  		ESHK(shkp)->credit = 0L;
177.  		ESHK(shkp)->debit = 0L;
178.  		ESHK(shkp)->loan = 0L;
179.  	}
180.  }
181.  
182.  STATIC_OVL long
183.  addupbill(shkp)
184.  register struct monst *shkp;
185.  {
186.  	register int ct = ESHK(shkp)->billct;
187.  	register struct bill_x *bp = ESHK(shkp)->bill_p;
188.  	register long total = 0L;
189.  
190.  	while(ct--){
191.  		total += bp->price * bp->bquan;
192.  		bp++;
193.  	}
194.  	return(total);
195.  }
196.  
197.  #endif /* OVLB */
198.  #ifdef OVL1
199.  
200.  #ifdef KOPS
201.  STATIC_OVL void
202.  call_kops(shkp, nearshop)
203.  register struct monst *shkp;
204.  register boolean nearshop;
205.  {
206.  	/* Keystone Kops srt@ucla */
207.  	register boolean nokops;
208.  
209.  	if(!shkp) return;
210.  
211.  	if (flags.soundok)
212.  	    pline("An alarm sounds!");
213.  
214.  	nokops = ((mons[PM_KEYSTONE_KOP].geno & (G_GENOD | G_EXTINCT)) &&
215.  		  (mons[PM_KOP_SERGEANT].geno & (G_GENOD | G_EXTINCT)) &&
216.  		  (mons[PM_KOP_LIEUTENANT].geno & (G_GENOD | G_EXTINCT)) &&
217.  		  (mons[PM_KOP_KAPTAIN].geno & (G_GENOD | G_EXTINCT)));
218.  
219.  	if(!angry_guards(!flags.soundok) && nokops) {
220.  	    if(flags.verbose && flags.soundok)
221.  		pline("But no one seems to respond to it.");
222.  	    return;
223.  	}
224.  
225.  	if(nokops) return;
226.  
227.  	{
228.  	    coord mm;
229.  
230.  	    if (nearshop) {
231.  		/* Create swarm around you, if you merely "stepped out" */
232.  		if (flags.verbose)
233.  		    pline("The Keystone Kops appear!");
234.  		mm.x = u.ux;
235.  		mm.y = u.uy;
236.  		makekops(&mm);
237.  		return;
238.  	    }
239.  	    if (flags.verbose)
240.  		 pline("The Keystone Kops are after you!");
241.  	    /* Create swarm near down staircase (hinders return to level) */
242.  	    mm.x = xdnstair;
243.  	    mm.y = ydnstair;
244.  	    makekops(&mm);
245.  	    /* Create swarm near shopkeeper (hinders return to shop) */
246.  	    mm.x = shkp->mx;
247.  	    mm.y = shkp->my;
248.  	    makekops(&mm);
249.  	}
250.  }
251.  #endif	/* KOPS */
252.  
253.  /* x,y is strictly inside shop */
254.  char
255.  inside_shop(x, y)
256.  register xchar x, y;
257.  {
258.  	register char rno;
259.  
260.  	rno = levl[x][y].roomno;
261.  	if ((rno < ROOMOFFSET) || levl[x][y].edge || !IS_SHOP(rno-ROOMOFFSET))
262.  	    return(NO_ROOM);
263.  	else
264.  	    return(rno);
265.  }
266.  
267.  void
268.  u_left_shop(leavestring, newlev)
269.  register char *leavestring;
270.  register boolean newlev;
271.  {
272.  	register struct monst *shkp;
273.  	register struct eshk *eshkp;
274.  	register long total;
275.  
276.  	/*
277.  	 * IF player
278.  	 * ((didn't leave outright) AND
279.  	 *  ((he is now strictly-inside the shop) OR
280.  	 *   (he wasn't strictly-inside last turn anyway)))
281.  	 * THEN (there's nothing to do, so just return)
282.  	 */
283.  	if(!*leavestring &&
284.  	   (!levl[u.ux][u.uy].edge || levl[u.ux0][u.uy0].edge))
285.  	    return;
286.  
287.  	shkp = shop_keeper(*u.ushops0);
288.  
289.  	if(!shkp || !inhishop(shkp))
290.  				/* shk died, teleported, changed levels... */
291.  	    return;
292.  
293.  	eshkp = ESHK(shkp);
294.  
295.  	if(!eshkp->billct && !eshkp->debit)	/* bill is settled */
296.  	    return;
297.  
298.  	if(!*leavestring) {
299.  	    /*
300.  	     * Player just stepped onto shop-boundary (known from above logic).
301.  	     * Try to intimidate him into paying his bill
302.  	     */
303.  
304.  	    verbalize(NOTANGRY(shkp) ?
305.  		      "%s!  Please pay before leaving." :
306.  		      "%s!  Don't you leave without paying!",
307.  		      plname);
308.  	    return;
309.  	}
310.  		/* by this point, we know an actual robbery has taken place */
311.  	You("escaped the shop without paying!");
312.  	total = (addupbill(shkp) + eshkp->debit);
313.  	eshkp->robbed += total;
314.  	eshkp->credit = 0L;
315.  	eshkp->debit = 0L;
316.  	setpaid(shkp);
317.  	You("stole %ld zorkmid%s worth of merchandise.",
318.  	    total, plur(total));
319.  	if (pl_character[0] != 'R') /* stealing is unlawful */
320.  	    adjalign(-sgn(u.ualign.type));
321.  
322.  	hot_pursuit(shkp);
323.  #ifdef KOPS
324.  	call_kops(shkp, (!newlev && levl[u.ux0][u.uy0].edge));
325.  #else
326.  	(void) angry_guards(FALSE);
327.  #endif
328.  }
329.  
330.  void
331.  u_entered_shop(enterstring)
332.  register char *enterstring;
333.  {
334.  
335.  	register int rt;
336.  	register struct monst *shkp;
337.  	register struct eshk *eshkp;
338.  	static const char no_shk[] = "This shop appears to be deserted.";
339.  	static char empty_shops[5];
340.  
341.  	if(!*enterstring)
342.  		return;
343.  
344.  	if(!(shkp = shop_keeper(*enterstring))) {
345.  	    if (!index(empty_shops, *enterstring) &&
346.  		in_rooms(u.ux, u.uy, SHOPBASE) !=
347.  				  in_rooms(u.ux0, u.uy0, SHOPBASE))
348.  		pline(no_shk);
349.  	    Strcpy(empty_shops, u.ushops);
350.  	    u.ushops[0] = '\0';
351.  	    return;
352.  	}
353.  
354.  	eshkp = ESHK(shkp);
355.  
356.  	if (!inhishop(shkp)) {
357.  	    /* dump core when referenced */
358.  	    eshkp->bill_p = (struct bill_x *) -1000;
359.  	    if (!index(empty_shops, *enterstring))
360.  		pline(no_shk);
361.  	    Strcpy(empty_shops, u.ushops);
362.  	    u.ushops[0] = '\0';
363.  	    return;
364.  	}
365.  
366.  	eshkp->bill_p = &(eshkp->bill[0]);
367.  
368.  	if (!eshkp->visitct || strncmpi(eshkp->customer, plname, PL_NSIZ)) {
369.  	    /* You seem to be new here */
370.  	    eshkp->visitct = 0;
371.  	    eshkp->following = 0;
372.  	    (void) strncpy(eshkp->customer,plname,PL_NSIZ);
373.  	    pacify_shk(shkp);
374.  	}
375.  
376.  	if (eshkp->following)
377.  	    return;
378.  
379.  	if (Invis) {
380.  	    pline("%s senses your presence.", shkname(shkp));
381.  	    verbalize("Invisible customers are not welcome!");
382.  	    return;
383.  	}
384.  
385.  	rt = rooms[*enterstring - ROOMOFFSET].rtype;
386.  
387.  	if (ANGRY(shkp)) {
388.  	    verbalize("So, %s, you dare return to %s %s?!",
389.  		      plname,
390.  		      s_suffix(shkname(shkp)),
391.  		      shtypes[rt - SHOPBASE].name);
392.  	} else if (eshkp->robbed) {
393.  	    verbalize("Beware, %s!  I am upset about missing stock!",
394.  		      plname);
395.  	} else {
396.  	    verbalize("Hello, %s!  Welcome%s to %s %s!",
397.  		      plname,
398.  		      eshkp->visitct++ ? " again" : "",
399.  		      s_suffix(shkname(shkp)),
400.  		      shtypes[rt - SHOPBASE].name);
401.  	}
402.  	if(carrying(PICK_AXE) != (struct obj *)0 &&
403.  				 /* can't do anything if teleported in */
404.  				 !inside_shop(u.ux, u.uy)) {
405.  	    verbalize(NOTANGRY(shkp) ?
406.  		      "Will you please leave your pick-axe outside?" :
407.  		      "Leave the pick-axe outside.");
408.  	    (void) dochug(shkp);
409.  	}
410.  	return;
411.  }
412.  
413.  #endif /* OVL1 */
414.  #ifdef OVLB
415.  
416.  int
417.  inhishop(mtmp)
418.  register struct monst *mtmp;
419.  {
420.  	return(index(in_rooms(mtmp->mx, mtmp->my, SHOPBASE),
421.  		     ESHK(mtmp)->shoproom) &&
422.  		on_level(&(ESHK(mtmp)->shoplevel), &u.uz));
423.  }
424.  
425.  struct monst *
426.  shop_keeper(rmno)
427.  register char rmno;
428.  {
429.  	struct monst *shkp = rmno >= ROOMOFFSET ?
430.  				rooms[rmno - ROOMOFFSET].resident : 0;
431.  
432.  	if (shkp) {
433.  	    if (NOTANGRY(shkp)) {
434.  		if (ESHK(shkp)->surcharge) pacify_shk(shkp);
435.  	    } else {
436.  		if (!ESHK(shkp)->surcharge) rile_shk(shkp);
437.  	    }
438.  	}
439.  	return shkp;
440.  }
441.  
442.  #ifdef SOUNDS
443.  boolean
444.  tended_shop(sroom)
445.  register struct mkroom *sroom;
446.  {
447.  	register struct monst *mtmp = sroom->resident;
448.  
449.  	if (!mtmp)
450.  		return(FALSE);
451.  	else
452.  		return(inhishop(mtmp));
453.  }
454.  #endif	/* SOUNDS */
455.  
456.  static struct bill_x *
457.  onbill(obj, shkp, silent)
458.  register struct obj *obj;
459.  register struct monst *shkp;
460.  register boolean silent;
461.  {
462.  	if (shkp) {
463.  		register struct bill_x *bp = ESHK(shkp)->bill_p;
464.  		register int ct = ESHK(shkp)->billct;
465.  
466.  		while (--ct >= 0)
467.  		    if (bp->bo_id == obj->o_id) {
468.  			if (!obj->unpaid) pline("onbill: paid obj on bill?");
469.  			return bp;
470.  		    } else bp++;
471.  	}
472.  	if(obj->unpaid & !silent) pline("onbill: unpaid obj not on bill?");
473.  	return (struct bill_x *)0;
474.  }
475.  
476.  /* Delete the contents of the given object. */
477.  void
478.  delete_contents(obj)
479.  register struct obj *obj;
480.  {
481.  	register struct obj *curr, *next;
482.  
483.  	for (curr = obj->cobj; curr; curr = next) {
484.  		next = curr->nobj;
485.  		obfree(curr, (struct obj *)0);
486.  	}
487.  	obj->cobj = (struct obj *) 0;
488.  }
489.  
490.  /* called with two args on merge */
491.  void
492.  obfree(obj, merge)
493.  register struct obj *obj, *merge;
494.  {
495.  	register struct bill_x *bp;
496.  	register struct bill_x *bpm;
497.  	register struct monst *shkp;
498.  
499.  	if(obj->oclass == FOOD_CLASS) food_disappears(obj);
500.  
501.  	if (obj->cobj) delete_contents(obj);
502.  
503.  	shkp = shop_keeper(*u.ushops);
504.  
505.  	if ((bp = onbill(obj, shkp, FALSE)) != 0) {
506.  		if(!merge){
507.  			bp->useup = 1;
508.  			obj->unpaid = 0;	/* only for doinvbill */
509.  			obj->nobj = billobjs;
510.  			billobjs = obj;
511.  			return;
512.  		}
513.  		bpm = onbill(merge, shkp, FALSE);
514.  		if(!bpm){
515.  			/* this used to be a rename */
516.  			impossible("obfree: not on bill??");
517.  			return;
518.  		} else {
519.  			/* this was a merger */
520.  			bpm->bquan += bp->bquan;
521.  			ESHK(shkp)->billct--;
522.  #ifdef DUMB
523.  			{
524.  			/* DRS/NS 2.2.6 messes up -- Peter Kendell */
525.  				int indx = ESHK(shkp)->billct;
526.  				*bp = ESHK(shkp)->bill_p[indx];
527.  			}
528.  #else
529.  			*bp = ESHK(shkp)->bill_p[ESHK(shkp)->billct];
530.  #endif
531.  		}
532.  	}
533.  	dealloc_obj(obj);
534.  }
535.  
536.  static long
537.  check_credit(tmp, shkp)
538.  long tmp;
539.  register struct monst *shkp;
540.  {
541.  	long credit = ESHK(shkp)->credit;
542.  
543.  	if(credit == 0L) return(tmp);
544.  	if(credit >= tmp) {
545.  		pline("The price is deducted from your credit.");
546.  		ESHK(shkp)->credit -=tmp;
547.  		tmp = 0L;
548.  	} else {
549.  		pline("The price is partially covered by your credit.");
550.  		ESHK(shkp)->credit = 0L;
551.  		tmp -= credit;
552.  	}
553.  	return(tmp);
554.  }
555.  
556.  static void
557.  pay(tmp,shkp)
558.  long tmp;
559.  register struct monst *shkp;
560.  {
561.  	long robbed = ESHK(shkp)->robbed;
562.  	long balance = ((tmp <= 0L) ? tmp : check_credit(tmp, shkp));
563.  
564.  	u.ugold -= balance;
565.  	shkp->mgold += balance;
566.  	flags.botl = 1;
567.  	if(robbed) {
568.  		robbed -= tmp;
569.  		if(robbed < 0) robbed = 0L;
570.  		ESHK(shkp)->robbed = robbed;
571.  	}
572.  }
573.  
574.  /* return shkp to home position */
575.  void
576.  home_shk(shkp, killkops)
577.  register struct monst *shkp;
578.  register boolean killkops;
579.  {
580.  	register xchar x = ESHK(shkp)->shk.x, y = ESHK(shkp)->shk.y;
581.  
582.  	(void) mnearto(shkp, x, y, TRUE);
583.  	level.flags.has_shop = 1;
584.  	if (killkops) {
585.  #ifdef KOPS
586.  		kops_gone(TRUE);
587.  #else
588.  		You("feel vaguely apprehensive.");
589.  #endif
590.  		pacify_guards();
591.  	}
592.  }
593.  
594.  static boolean
595.  angry_shk_exists()
596.  {
597.  	register struct monst *shkp;
598.  
599.  	for (shkp = next_shkp(fmon, FALSE);
600.  		shkp; shkp = next_shkp(shkp->nmon, FALSE))
601.  	    if (ANGRY(shkp)) return(TRUE);
602.  	return(FALSE);
603.  }
604.  
605.  /* remove previously applied surcharge from all billed items */
606.  STATIC_OVL void
607.  pacify_shk(shkp)
608.  register struct monst *shkp;
609.  {
610.  	NOTANGRY(shkp) = TRUE;	/* make peaceful */
611.  	if (ESHK(shkp)->surcharge) {
612.  		register struct bill_x *bp = ESHK(shkp)->bill_p;
613.  		register int ct = ESHK(shkp)->billct;
614.  
615.  		ESHK(shkp)->surcharge = FALSE;
616.  		while (ct-- > 0) {
617.  			register long reduction = (bp->price + 3L) / 4L;
618.  			bp->price -= reduction;		/* undo 33% increase */
619.  			bp++;
620.  		}
621.  	}
622.  }
623.  
624.  /* add aggravation surcharge to all billed items */
625.  static void
626.  rile_shk(shkp)
627.  register struct monst *shkp;
628.  {
629.  	NOTANGRY(shkp) = FALSE;	/* make angry */
630.  	if (!ESHK(shkp)->surcharge) {
631.  		register struct bill_x *bp = ESHK(shkp)->bill_p;
632.  		register int ct = ESHK(shkp)->billct;
633.  
634.  		ESHK(shkp)->surcharge = TRUE;
635.  		while (ct-- > 0) {
636.  			register long surcharge = (bp->price + 2L) / 3L;
637.  			bp->price += surcharge;
638.  			bp++;
639.  		}
640.  	}
641.  }
642.  
643.  void
644.  make_happy_shk(shkp, silentkops)
645.  register struct monst *shkp;
646.  register boolean silentkops;
647.  {
648.  	register boolean wasmad = ANGRY(shkp);
649.  
650.  	pacify_shk(shkp);
651.  	ESHK(shkp)->following = 0;
652.  	ESHK(shkp)->robbed = 0L;
653.  	if (pl_character[0] != 'R')
654.  		adjalign(sgn(u.ualign.type));
655.  	if(!inhishop(shkp)) {
656.  		pline("Satisfied, %s suddenly disappears!", mon_nam(shkp));
657.  		if(on_level(&(ESHK(shkp)->shoplevel), &u.uz))
658.  			home_shk(shkp, FALSE);
659.  		else
660.  			migrate_to_level(shkp,
661.  				 ledger_no(&(ESHK(shkp)->shoplevel)), 0);
662.  	} else if(wasmad)
663.  		pline("%s calms down.", Monnam(shkp));
664.  
665.  	if(!angry_shk_exists()) {
666.  #ifdef KOPS
667.  		kops_gone(silentkops);
668.  #endif
669.  		pacify_guards();
670.  	}
671.  }
672.  
673.  void
674.  hot_pursuit(shkp)
675.  register struct monst *shkp;
676.  {
677.  	if(!shkp->isshk) return;
678.  
679.  	rile_shk(shkp);
680.  	ESHK(shkp)->following = 1;
681.  }
682.  
683.  /* used when the shkp is teleported out of his shop,
684.   * or when the player is not on a costly_spot and he
685.   * damages something inside the shop.  these conditions
686.   * must be checked by the calling function.
687.   */
688.  void
689.  make_angry_shk(shkp, ox, oy)
690.  register struct monst *shkp;
691.  register xchar ox,oy;
692.  {
693.  	if(index(in_rooms(ox, oy, SHOPBASE), ESHK(shkp)->shoproom) &&
694.  	    !ANGRY(shkp)) {
695.  		ESHK(shkp)->robbed += (addupbill(shkp) +
696.  				       ESHK(shkp)->debit + ESHK(shkp)->loan);
697.  		ESHK(shkp)->robbed -= ESHK(shkp)->credit;
698.  		if(ESHK(shkp)->robbed < 0L)
699.  		    ESHK(shkp)->robbed = 0L;
700.  		ESHK(shkp)->credit = 0L;
701.  		setpaid(shkp);
702.  	}
703.  	if(!ANGRY(shkp)) pline("%s gets angry!", Monnam(shkp));
704.  	else pline("%s is furious!", Monnam(shkp));
705.  	hot_pursuit(shkp);
706.  }
707.  
708.  static const char no_money[] = "Moreover, you%s have no money.";
709.  
710.  static long
711.  cheapest_item(shkp)   /* delivers the cheapest item on the list */
712.  register struct monst *shkp;
713.  {
714.  	register int ct = ESHK(shkp)->billct;
715.  	register struct bill_x *bp = ESHK(shkp)->bill_p;
716.  	register long gmin = (bp->price * bp->bquan);
717.  
718.  	while(ct--){
719.  		if(bp->price * bp->bquan < gmin)
720.  			gmin = bp->price * bp->bquan;
721.  		bp++;
722.  	}
723.  	return(gmin);
724.  }
725.  
726.  int
727.  dopay()
728.  {
729.  	long ltmp;
730.  	register struct monst *nxtm = (struct monst *)0;
731.  	register struct monst *shkp, *resident = (struct monst *)0;
732.  	register struct eshk *eshkp;
733.  	int pass, tmp, sk = 0, seensk = 0;
734.  	register boolean paid = FALSE, stashed_gold = (hidden_gold() > 0L);
735.  
736.  	multi = 0;
737.  
738.  	/* find how many shk's there are, how many are in */
739.  	/* sight, and are you in a shop room with one.    */
740.  	for (shkp = next_shkp(fmon, FALSE);
741.  		shkp; shkp = next_shkp(shkp->nmon, FALSE)) {
742.  	    sk++;
743.  	    if (ANGRY(shkp) && distu(shkp->mx, shkp->my) <= 2) nxtm = shkp;
744.  	    if (canseemon(shkp) || sensemon(shkp)) seensk++;
745.  	    if (inhishop(shkp) && (*u.ushops == ESHK(shkp)->shoproom))
746.  		resident = shkp;
747.  	}
748.  
749.  	if (nxtm) {			/* Player should always appease an */
750.  	     shkp = nxtm;		/* irate shk standing next to them. */
751.  	     goto proceed;
752.  	}
753.  
754.  	if ((!sk && (!Blind || Telepat)) || (!Blind && !seensk)) {
755.        pline("There appears to be no shopkeeper here to receive your payment.");
756.  		return(0);
757.  	}
758.  
759.  	if(!seensk) {
760.  		You("can't see...");
761.  		return(0);
762.  	}
763.  
764.  	/* the usual case.  allow paying at a distance when */
765.  	/* inside a tended shop.  should we change that?    */
766.  	if(sk == 1 && resident) {
767.  		shkp = resident;
768.  		goto proceed;
769.  	}
770.  
771.  	if (seensk == 1) {
772.  		for (shkp = next_shkp(fmon, FALSE);
773.  			shkp; shkp = next_shkp(shkp->nmon, FALSE))
774.  		    if (canseemon(shkp) || sensemon(shkp)) break;
775.  		if (shkp != resident && distu(shkp->mx, shkp->my) > 2) {
776.  		    pline("%s is not near enough to receive your payment.",
777.  					     Monnam(shkp));
778.  		    return(0);
779.  		}
780.  	} else {
781.  		struct monst *mtmp;
782.  		coord cc;
783.  		int cx, cy;
784.  
785.  		pline("Pay whom?");
786.  		cc.x = u.ux;
787.  		cc.y = u.uy;
788.  		getpos(&cc, TRUE, "the creature you want to pay");
789.  		cx = cc.x;
790.  		cy = cc.y;
791.  		if(cx == -10) return(0); /* player pressed esc */
792.  		if(cx < 0) {
793.  		     pline("Try again...");
794.  		     return(0);
795.  		}
796.  		if(u.ux == cx && u.uy == cy) {
797.  		     You("are generous to yourself.");
798.  		     return(0);
799.  		}
800.  		mtmp = m_at(cx, cy);
801.  		if(!mtmp) {
802.  		     pline("There is no one there to receive your payment.");
803.  		     return(0);
804.  		}
805.  		if(!mtmp->isshk) {
806.  		     pline("%s is not interested in your payment.",
807.  				    Monnam(mtmp));
808.  		     return(0);
809.  		}
810.  		if (mtmp != resident && distu(mtmp->mx, mtmp->my) > 2) {
811.  		     pline("%s is too far to receive your payment.",
812.  				    Monnam(mtmp));
813.  		     return(0);
814.  		}
815.  		shkp = mtmp;
816.  	}
817.  
818.  	if(!shkp) {
819.  #ifdef DEBUG
820.  		pline("dopay: null shkp.");
821.  #endif
822.  		return(0);
823.  	}
824.  proceed:
825.  	eshkp = ESHK(shkp);
826.  
827.  	ltmp = eshkp->robbed;
828.  	if(shkp != resident && NOTANGRY(shkp)) {
829.  		if(!ltmp)
830.  		    You("do not owe %s anything.", mon_nam(shkp));
831.  		else if(!u.ugold) {
832.  		    You("%shave no money.", stashed_gold ? "seem to " : "");
833.  		    if(stashed_gold)
834.  			pline("But you have some gold stashed away.");
835.  		} else {
836.  		    const char *pronoun = shkp->female ? "she" : "he";
837.  		    long ugold = u.ugold;
838.  
839.  		    if(ugold > ltmp) {
840.  			You("give %s the %ld gold piece%s %s asked for.",
841.  			    mon_nam(shkp), ltmp, plur(ltmp), pronoun);
842.  			pay(ltmp, shkp);
843.  		    } else {
844.  			You("give %s all your%s gold.", mon_nam(shkp),
845.  					stashed_gold ? " openly kept" : "");
846.  			pay(u.ugold, shkp);
847.  			if (stashed_gold) pline("But you have hidden gold!");
848.  		    }
849.  		    if((ugold < ltmp/2L) || (ugold < ltmp && stashed_gold))
850.  			pline("Unfortunately, %s doesn't look satisfied.",
851.  			    pronoun);
852.  		    else
853.  			make_happy_shk(shkp, FALSE);
854.  		}
855.  		return(1);
856.  	}
857.  
858.  	/* ltmp is still eshkp->robbed here */
859.  	if (!eshkp->billct && !eshkp->debit) {
860.  		const char *pronoun = shkp->female ? "her" : "him";
861.  		const char *possessive = shkp->female ? "her" : "his";
862.  
863.  		if(!ltmp && NOTANGRY(shkp)) {
864.  		    You("do not owe %s anything.", mon_nam(shkp));
865.  		    if(!u.ugold) pline(no_money, stashed_gold ?
866.  					   " seem to" : "");
867.  		} else if(ltmp) {
868.  		    pline("%s is after blood, not money!", Monnam(shkp));
869.  		    if(u.ugold < ltmp/2L ||
870.  				(u.ugold < ltmp && stashed_gold)) {
871.  			if(!u.ugold) pline(no_money, stashed_gold ?
872.  						       " seem to" : "");
873.  			else pline("Besides, you don't have enough to interest %s.",
874.  				pronoun);
875.  			return(1);
876.  		    }
877.  		    pline("But since %s shop has been robbed recently,",
878.  			possessive);
879.  		    pline("you %scompensate %s for %s losses.",
880.  			(u.ugold < ltmp) ? "partially " : "",
881.  			mon_nam(shkp), possessive);
882.  		    pay(u.ugold < ltmp ? u.ugold : ltmp, shkp);
883.  		    make_happy_shk(shkp, FALSE);
884.  		} else {
885.  		    /* shopkeeper is angry, but has not been robbed --
886.  		     * door broken, attacked, etc. */
887.  		    pline("%s is after your hide, not your money!",
888.  							 mon_nam(shkp));
889.  		    if(u.ugold < 1000L) {
890.  			if(!u.ugold) pline(no_money, stashed_gold ?
891.  					     " seem to" : "");
892.  			else pline("Besides, you don't have enough to interest %s.",
893.  				    pronoun);
894.  			return(1);
895.  		    }
896.  		    You("try to appease %s by giving %s 1000 gold pieces.",
897.  			x_monnam(shkp, 1, "angry", 0), pronoun);
898.  		    pay(1000L,shkp);
899.  		    if (strncmp(eshkp->customer, plname, PL_NSIZ) || rn2(3))
900.  			make_happy_shk(shkp, FALSE);
901.  		    else
902.  			pline("But %s is as angry as ever.", mon_nam(shkp));
903.  		}
904.  		return(1);
905.  	}
906.  	if(shkp != resident) {
907.  		impossible("dopay: not to shopkeeper?");
908.  		if(resident) setpaid(resident);
909.  		return(0);
910.  	}
911.  	/* pay debt, if any, first */
912.  	if(eshkp->debit) {
913.  		long dtmp = eshkp->debit;
914.  		long loan = eshkp->loan;
915.  		char sbuf[BUFSZ];
916.  
917.  		Sprintf(sbuf, "You owe %s %ld zorkmid%s ",
918.  					   shkname(shkp), dtmp, plur(dtmp));
919.  		if(loan) {
920.  		    if(loan == dtmp)
921.  			Strcat(sbuf, "you picked up in the store.");
922.  		    else Strcat(sbuf,
923.  			   "for gold picked up and the use of merchandise.");
924.  		} else Strcat(sbuf, "for the use of merchandise.");
925.  		pline(sbuf);
926.  		if (u.ugold + eshkp->credit < dtmp) {
927.  		    pline("But you don't%s have enough gold%s.",
928.  			stashed_gold ? " seem to" : "",
929.  			eshkp->credit ? " or credit" : "");
930.  		    return(1);
931.  		} else {
932.  		    if (eshkp->credit >= dtmp) {
933.  			eshkp->credit -= dtmp;
934.  			eshkp->debit = 0L;
935.  			eshkp->loan = 0L;
936.  			Your("debt is covered by your credit.");
937.  		    } else if (!eshkp->credit) {
938.  			u.ugold -= dtmp;
939.  			shkp->mgold += dtmp;
940.  			eshkp->debit = 0L;
941.  			eshkp->loan = 0L;
942.  			You("pay that debt.");
943.  			flags.botl = 1;
944.  		    } else {
945.  			dtmp -= eshkp->credit;
946.  			eshkp->credit = 0L;
947.  			u.ugold -= dtmp;
948.  			shkp->mgold += dtmp;
949.  			eshkp->debit = 0L;
950.  			eshkp->loan = 0L;
951.  			pline("That debt is partially offset by your credit.");
952.  			You("pay the remainder.");
953.  			flags.botl = 1;
954.  		    }
955.  		    paid = TRUE;
956.  		}
957.  	}
958.  	/* now check items on bill */
959.  	if (eshkp->billct) {
960.  	    register boolean itemize;
961.  
962.  	    if (!u.ugold && !eshkp->credit) {
963.  		You("%shave no money or credit%s.",
964.  				    stashed_gold ? "seem to " : "",
965.  				    paid ? " left" : "");
966.  		return(0);
967.  	    }
968.  	    if ((u.ugold + eshkp->credit) < cheapest_item(shkp)) {
969.  		You("don't have enough money to buy%s the item%s you picked.",
970.  		    eshkp->billct > 1 ? " any of" : "", plur(eshkp->billct));
971.  		if(stashed_gold)
972.  		    pline("Maybe you have some gold stashed away?");
973.  		return(0);
974.  	    }
975.  
976.  	    /* this isn't quite right; it itemizes without asking if the
977.  	     * single item on the bill is partly used up and partly unpaid */
978.  	    itemize = (eshkp->billct > 1 ? yn("Itemized billing?") == 'y' : 1);
979.  
980.  	    for (pass = 0; pass <= 1; pass++) {
981.  		tmp = 0;
982.  		while (tmp < eshkp->billct) {
983.  		    register struct obj *otmp;
984.  		    register struct bill_x *bp = &(eshkp->bill_p[tmp]);
985.  
986.  		    /* find the object on one of the lists */
987.  		    if (!(otmp = bp_to_obj(bp))) {
988.  			impossible("Shopkeeper administration out of order.");
989.  			setpaid(shkp);	/* be nice to the player */
990.  			return 1;
991.  		    }
992.  		    if (pass == bp->useup && otmp->quan == bp->bquan) {
993.  			/* pay for used-up items on first pass and others
994.  			 * on second, so player will be stuck in the store
995.  			 * less often; things which are partly used up
996.  			 * are processed on both passes */
997.  			tmp++;
998.  		    } else {
999.  			switch (dopayobj(shkp, bp, otmp, pass, itemize)) {
1000. 			  case PAY_CANT:
1001. 				return 1;	/*break*/
1002. 			  case PAY_BROKE:
1003. 				paid = TRUE;
1004. 				goto thanks;	/*break*/
1005. 			  case PAY_SKIP:
1006. 				tmp++;
1007. 				continue;	/*break*/
1008. 			  case PAY_SOME:
1009. 				paid = TRUE;
1010. 				if (itemize) bot();
1011. 				continue;	/*break*/
1012. 			  case PAY_BUY:
1013. 				paid = TRUE;
1014. 				break;
1015. 			}
1016. 			if (itemize) bot();
1017. 			*bp = eshkp->bill_p[--eshkp->billct];
1018. 		    }
1019. 		}
1020. 	    }
1021. 	}
1022. thanks:
1023. 	if(!ANGRY(shkp) && paid)
1024. 	    verbalize("Thank you for shopping in %s %s!",
1025. 		s_suffix(shkname(shkp)),
1026. 		shtypes[rooms[eshkp->shoproom - ROOMOFFSET].rtype - SHOPBASE].name);
1027. 	return(1);
1028. }
1029. 
1030. /* return 2 if used-up portion paid */
1031. /*	  1 if paid successfully    */
1032. /*	  0 if not enough money     */
1033. /*	 -1 if skip this object     */
1034. /*	 -2 if no money/credit left */
1035. static int
1036. dopayobj(shkp, bp, obj, which, itemize)
1037. register struct monst *shkp;
1038. register struct bill_x *bp;
1039. register struct obj *obj;
1040. int	which;		/* 0 => used-up item, 1 => other (unpaid or lost) */
1041. boolean itemize;
1042. {
1043. 	long ltmp, quan, save_quan;
1044. 	int buy;
1045. 	boolean stashed_gold = (hidden_gold() > 0L),
1046. 		consumed = (which == 0);
1047. 
1048. 	if(!obj->unpaid && !bp->useup){
1049. 		impossible("Paid object on bill??");
1050. 		return PAY_BUY;
1051. 	}
1052. 	if(itemize && u.ugold + ESHK(shkp)->credit == 0L){
1053. 		You("%shave no money or credit left.",
1054. 			     stashed_gold ? "seem to " : "");
1055. 		return PAY_BROKE;
1056. 	}
1057. 	/* we may need to temporarily adjust the object, if part of the
1058. 	   original quantity has been used up but part remains unpaid  */
1059. 	save_quan = obj->quan;
1060. 	if (consumed) {
1061. 	    /* either completely used up (simple), or split needed */
1062. 	    quan = bp->bquan;
1063. 	    if (quan > obj->quan)	/* difference is amount used up */
1064. 		quan -= obj->quan;
1065. 	} else {
1066. 	    /* dealing with ordinary unpaid item */
1067. 	    quan = obj->quan;
1068. 	}
1069. 	obj->quan = quan;	/* to be used by doname() */
1070. 	obj->unpaid = 0;	/* ditto */
1071. 	ltmp = bp->price * quan;
1072. 	buy = PAY_BUY;		/* flag; if changed then return early */
1073. 
1074. 	if (itemize) {
1075. 	    char qbuf[BUFSZ];
1076. 	    Sprintf(qbuf,"%s for %ld zorkmid%s.  Pay?", quan == 1L ?
1077. 		    Doname2(obj) : doname(obj), ltmp, plur(ltmp));
1078. 	    if (yn(qbuf) == 'n') {
1079. 		buy = PAY_SKIP;		/* don't want to buy */
1080. 	    } else if (quan < bp->bquan && !consumed) { /* partly used goods */
1081. 		obj->quan = bp->bquan - save_quan;	/* used up amount */
1082. 		verbalize("%s for the other %s before buying %s.",
1083. 			  ANGRY(shkp) ? "Pay" : "Please pay", xname(obj),
1084. 			  save_quan > 1L ? "these" : "this one");
1085. 		buy = PAY_SKIP;		/* shk won't sell */
1086. 	    }
1087. 	}
1088. 	if (buy == PAY_BUY && u.ugold + ESHK(shkp)->credit < ltmp) {
1089. 	    You("don't%s have gold%s enough to pay for %s.",
1090. 		stashed_gold ? " seem to" : "",
1091. 		(ESHK(shkp)->credit > 0L) ? " or credit" : "",
1092. 		doname(obj));
1093. 	    buy = itemize ? PAY_SKIP : PAY_CANT;
1094. 	}
1095. 
1096. 	if (buy != PAY_BUY) {
1097. 	    /* restore unpaid object to original state */
1098. 	    obj->quan = save_quan;
1099. 	    obj->unpaid = 1;
1100. 	    return buy;
1101. 	}
1102. 
1103. 	pay(ltmp, shkp);
1104. 	You("bought %s for %ld gold piece%s.",
1105. 		doname(obj), ltmp, plur(ltmp));
1106. 	obj->quan = save_quan;		/* restore original count */
1107. 	/* quan => amount just bought, save_quan => remaining unpaid count */
1108. 	if (consumed) {
1109. 	    if (quan != save_quan) {
1110. 		/* eliminate used-up portion; remainder is still unpaid */
1111. 		bp->bquan = obj->quan;
1112. 		obj->unpaid = 1;
1113. 		bp->useup = 0;
1114. 	    } else {	/* completely used-up, so get rid of it */
1115. 		register struct obj *otmp = billobjs;
1116. 		if(obj == billobjs)
1117. 			billobjs = obj->nobj;
1118. 		else {
1119. 			while(otmp && otmp->nobj != obj) otmp = otmp->nobj;
1120. 			if(otmp) otmp->nobj = obj->nobj;
1121. 			else impossible("Error in shopkeeper administration.");
1122. 		}
1123. 		dealloc_obj(obj);
1124. 	    }
1125. 	}
1126. 	return quan != save_quan ? PAY_SOME : PAY_BUY;
1127. }
1128. 
1129. /* routine called after dying (or quitting) */
1130. boolean
1131. paybill(croaked)
1132. register boolean croaked;
1133. {
1134. 	register struct monst *mtmp, *mtmp2, *resident= (struct monst *)0;
1135. 	register boolean taken = FALSE;
1136. 	register int numsk = 0;
1137. 
1138. 	/* give shopkeeper first crack */
1139. 	if ((mtmp = shop_keeper(*u.ushops)) && inhishop(mtmp)) {
1140. 	    numsk++;
1141. 	    resident = mtmp;
1142. 	    taken = inherits(resident, numsk, croaked);
1143. 	}
1144. 	for (mtmp = next_shkp(fmon, FALSE);
1145. 		mtmp; mtmp = next_shkp(mtmp2, FALSE)) {
1146. 	    mtmp2 = mtmp->nmon;
1147. 	    if (mtmp != resident) {
1148. 		/* for bones: we don't want a shopless shk around */
1149. 		if(!on_level(&(ESHK(mtmp)->shoplevel), &u.uz))
1150. 			mongone(mtmp);
1151. 		else {
1152. 		    numsk++;
1153. 		    taken |= inherits(mtmp, numsk, croaked);
1154. 		}
1155. 	    }
1156. 	}
1157. 	if(numsk == 0) return(FALSE);
1158. 	return(taken);
1159. }
1160. 
1161. static boolean
1162. inherits(shkp, numsk, croaked)
1163. register struct monst *shkp;
1164. register int numsk;
1165. register boolean croaked;
1166. {
1167. 	register long loss = 0L;
1168. 	register struct obj *otmp;
1169. 	register struct eshk *eshkp = ESHK(shkp);
1170. 	register xchar ox, oy;
1171. 	register boolean take = FALSE, taken = FALSE;
1172. 	register int roomno = *u.ushops;
1173. 
1174. 	/* the simplifying principle is that first-come */
1175. 	/* already took everything you had.		*/
1176. 	if(numsk > 1) {
1177. 	    if(cansee(shkp->mx, shkp->my) && croaked)
1178. 		pline("%s %slooks at your corpse%s%s", Monnam(shkp),
1179. 		     (shkp->msleep || shkp->mfrozen) ?
1180. 				   "wakes up, " : "",
1181. 		     !rn2(2) ? (shkp->female ? ", shakes her head," :
1182. 				 ", shakes his head,") : "",
1183. 		     !inhishop(shkp) ? " and disappears. " : " and sighs.");
1184. 	    taken = (roomno == eshkp->shoproom);
1185. 	    goto skip;
1186. 	}
1187. 
1188. 	/* get one case out of the way: you die in the shop, the */
1189. 	/* shopkeeper is peaceful, nothing stolen, nothing owed. */
1190. 	if(roomno == eshkp->shoproom && inhishop(shkp) &&
1191. 	    !IS_DOOR(levl[u.ux][u.uy].typ) && !eshkp->billct &&
1192. 	    !eshkp->robbed && !eshkp->debit &&
1193. 	     NOTANGRY(shkp) && !eshkp->following) {
1194. 		if (invent)
1195. 			pline("%s gratefully inherits all your possessions.",
1196. 				shkname(shkp));
1197. 		goto clear;
1198. 	}
1199. 
1200. 	if (eshkp->billct || eshkp->debit || eshkp->robbed) {
1201. 		register long total = 0L;
1202. 
1203. 		if(roomno == eshkp->shoproom && inhishop(shkp))
1204. 		    total = (addupbill(shkp) + eshkp->debit);
1205. 		loss = ((total >= eshkp->robbed) ? total : eshkp->robbed);
1206. 		take = TRUE;
1207. 	}
1208. 
1209. 	if (eshkp->following || ANGRY(shkp) || take) {
1210. 
1211. 		if(!invent && !u.ugold) goto skip;
1212. 
1213. 		if((loss > u.ugold) || !loss) {
1214. 			pline("%s %s%stakes all your possessions.",
1215. 				shkname(shkp),
1216. 				(shkp->msleep || shkp->mfrozen) ?
1217. 				   "wakes up and " : "",
1218. 				(distu(shkp->mx, shkp->my) > 2) ?
1219. 				    "comes and " : "");
1220. 			taken = TRUE;
1221. 			shkp->mgold += u.ugold;
1222. 			u.ugold = 0L;
1223. 			/* in case bones: make it be for real... */
1224. 			if(!*u.ushops ||
1225. 			     IS_DOOR(levl[u.ux][u.uy].typ)) {
1226. 			    /* shk.x,shk.y is the position immediately in
1227. 			     * front of the door -- move in one more space
1228. 			     */
1229. 			    ox = eshkp->shk.x;
1230. 			    oy = eshkp->shk.y;
1231. 			    ox += sgn(ox - eshkp->shd.x);
1232. 			    oy += sgn(oy - eshkp->shd.y);
1233. 			} else {
1234. 			    ox = u.ux;
1235. 			    oy = u.uy;
1236. 			}
1237. 
1238. 			if (invent) {
1239. 			    for(otmp = invent; otmp; otmp = otmp->nobj)
1240. 				place_object(otmp, ox, oy);
1241. 
1242. 			    /* add to main object list at end so invent is
1243. 			       still good */
1244. 			    if (fobj) {
1245. 				otmp = fobj;
1246. 				while(otmp->nobj)
1247. 				    otmp = otmp->nobj;
1248. 				otmp->nobj = invent;
1249. 			    } else
1250. 				fobj = invent;
1251. 			}
1252. 		} else {
1253. 			u.ugold -= loss;
1254. 			shkp->mgold += loss;
1255. 			pline("%s %sand takes %ld zorkmid%s %sowed %s.",
1256. 			      Monnam(shkp),
1257. 			      (shkp->msleep || shkp->mfrozen) ?
1258. 					"wakes up " : "comes ",
1259. 			      loss, plur(loss),
1260. 			      strncmp(eshkp->customer,
1261. 					   plname, PL_NSIZ) ? "" : "you ",
1262. 			      shkp->female ? "her" : "him");
1263. 		}
1264. skip:
1265. 		/* in case we create bones */
1266. 		if(!inhishop(shkp))
1267. 			home_shk(shkp, FALSE);
1268. 	}
1269. clear:
1270. 	setpaid(shkp);
1271. 	return(taken);
1272. }
1273. 
1274. /* find obj on one of the lists */
1275. static struct obj *
1276. bp_to_obj(bp)
1277. register struct bill_x *bp;
1278. {
1279. 	register struct obj *obj;
1280. 	register struct monst *mtmp;
1281. 	register unsigned int id = bp->bo_id;
1282. 
1283. 	if(bp->useup)
1284. 		obj = o_on(id, billobjs);
1285. 	else if(!(obj = o_on(id, invent)) &&
1286. 		!(obj = o_on(id, fobj)) &&
1287. 		!(obj = o_on(id, migrating_objs))) {
1288. 		    for (mtmp = fmon; mtmp; mtmp = mtmp->nmon)
1289. 			if ((obj = o_on(id, mtmp->minvent)) != 0)
1290. 			    return obj;
1291. 		    for (mtmp = migrating_mons; mtmp; mtmp = mtmp->nmon)
1292. 			if ((obj = o_on(id, mtmp->minvent)) != 0)
1293. 			    return obj;
1294. 		}
1295. 	return(obj);
1296. }
1297. 
1298. /* calculate the value that the shk will charge for [one of] an object */
1299. static long
1300. get_cost(obj, shkp)
1301. register struct obj *obj;
1302. register struct monst *shkp;	/* if angry, impose a surcharge */
1303. {
1304. 	register long tmp = getprice(obj);
1305. 
1306. 	if (!tmp) tmp = 5L;
1307. 	/* shopkeeper may notice if the player isn't very knowledgeable -
1308. 	   especially when gem prices are concerned */
1309. 	if (!objects[obj->otyp].oc_name_known)
1310. 		if (obj->oclass == GEM_CLASS) {
1311. 			/* all gems are priced high - real or not */
1312. 			if (objects[obj->otyp].oc_material == GLASS) {
1313. 				/* real gem's cost (worthless gems come
1314. 				   after jade but before luckstone) */
1315. 				tmp = (long)objects[
1316. 					obj->otyp - LUCKSTONE + JADE + 1].oc_cost;
1317. 			}
1318. 		} else if (!(obj->o_id % 4)) /* arbitrarily impose surcharge */
1319. 			tmp += tmp / 3L;
1320. #ifdef TOURIST
1321. 	if((pl_character[0] == 'T' && u.ulevel < (MAXULEV/2))
1322. 	    || (uarmu && !uarm && !uarmc))	/* Hawaiian shirt visible */
1323. 		tmp += tmp / 3L;
1324. #endif
1325. 	if (ACURR(A_CHA) > 18)		tmp /= 2L;
1326. 	else if (ACURR(A_CHA) > 17)	tmp -= tmp / 3L;
1327. 	else if (ACURR(A_CHA) > 15)	tmp -= tmp / 4L;
1328. 	else if (ACURR(A_CHA) < 6)	tmp *= 2L;
1329. 	else if (ACURR(A_CHA) < 8)	tmp += tmp / 2L;
1330. 	else if (ACURR(A_CHA) < 11)	tmp += tmp / 3L;
1331. 	if (tmp <= 0L) tmp = 1L;
1332. 	else if (obj->oartifact) tmp *= 4L;
1333. 	/* anger surcharge should match rile_shk's */
1334. 	if (shkp && ESHK(shkp)->surcharge) tmp += (tmp + 2L) / 3L;
1335. 	return tmp;
1336. }
1337. 
1338. /* returns the price of a container's content.  the price
1339.  * of the "top" container is added in the calling functions.
1340.  * a different price quoted for selling as vs. buying.
1341.  */
1342. long
1343. contained_cost(obj, shkp, price, usell)
1344. register struct obj *obj;
1345. register struct monst *shkp;
1346. long price;
1347. register boolean usell;
1348. {
1349. 	register struct obj *otmp;
1350. 
1351. 	/* the price of contained objects */
1352. 	for(otmp = obj->cobj; otmp; otmp = otmp->nobj) {
1353. 	    register boolean goods = saleable(rooms[ESHK(shkp)->shoproom -
1354. 					   ROOMOFFSET].rtype-SHOPBASE, otmp);
1355. 
1356. 	    if(otmp->otyp == GOLD_PIECE) continue;
1357. 
1358. 	    /* the "top" container is evaluated by caller */
1359. 	    if(usell) {
1360. 		if(goods && !otmp->unpaid &&
1361. 			otmp->oclass != BALL_CLASS &&
1362. 			!(otmp->oclass == FOOD_CLASS && otmp->oeaten) &&
1363. 			!(Is_candle(otmp) && otmp->age <
1364. 				20L * (long)objects[otmp->otyp].oc_cost))
1365. 		    price += set_cost(otmp, shkp);
1366. 	    } else if(!otmp->no_charge) {
1367. 		    price += get_cost(otmp, shkp);
1368. 	    }
1369. 
1370. 	    if(Is_container(otmp))
1371. 		    price += contained_cost(otmp, shkp, price, usell);
1372. 	}
1373. 
1374. 	return(price);
1375. }
1376. 
1377. long
1378. contained_gold(obj)
1379. register struct obj *obj;
1380. {
1381. 	register struct obj *otmp;
1382. 	register long value = 0L;
1383. 
1384. 	/* accumulate contained gold */
1385. 	for (otmp = obj->cobj; otmp; otmp = otmp->nobj)
1386. 	    if (otmp->otyp == GOLD_PIECE)
1387. 		value += otmp->quan;
1388. 	    else if (Is_container(otmp))
1389. 		value += contained_gold(otmp);
1390. 
1391. 	return(value);
1392. }
1393. 
1394. static void
1395. dropped_container(obj)
1396. register struct obj *obj;
1397. {
1398. 	register struct obj *otmp;
1399. 
1400. 	/* the "top" container is treated in the calling fn */
1401. 	for(otmp = obj->cobj; otmp; otmp = otmp->nobj) {
1402. 
1403. 	    if(otmp->otyp == GOLD_PIECE) continue;
1404. 
1405. 	    if(!otmp->unpaid)
1406. 		otmp->no_charge = 1;
1407. 
1408. 	    if(Is_container(otmp))
1409. 		dropped_container(otmp);
1410. 	}
1411. }
1412. 
1413. void
1414. picked_container(obj)
1415. register struct obj *obj;
1416. {
1417. 	register struct obj *otmp;
1418. 
1419. 	/* the "top" container is treated in the calling fn */
1420. 	for(otmp = obj->cobj; otmp; otmp = otmp->nobj) {
1421. 
1422. 	    if(otmp->otyp == GOLD_PIECE) continue;
1423. 
1424. 	    if(otmp->no_charge)
1425. 		otmp->no_charge = 0;
1426. 
1427. 	    if(Is_container(otmp))
1428. 		picked_container(otmp);
1429. 	}
1430. }
1431. 
1432. /* calculate how much the shk will pay when buying [all of] an object */
1433. static long
1434. set_cost(obj, shkp)
1435. register struct obj *obj;
1436. register struct monst *shkp;
1437. {
1438. 	long tmp = getprice(obj) * obj->quan;
1439. 
1440. #ifdef TOURIST
1441. 	if ((pl_character[0] == 'T' && u.ulevel < (MAXULEV/2))
1442. 	    || (uarmu && !uarm && !uarmc))	/* Hawaiian shirt visible */
1443. 		tmp /= 3L;
1444. 	else
1445. #endif
1446. 		tmp /= 2L;
1447. 	/* shopkeeper may notice if the player isn't very knowledgeable -
1448. 	   especially when gem prices are concerned */
1449. 	if (!objects[obj->otyp].oc_name_known) {
1450. 		if (obj->oclass == GEM_CLASS) {
1451. 			/* different shop keepers give different prices */
1452. 			if (objects[obj->otyp].oc_material == GEMSTONE ||
1453. 			    objects[obj->otyp].oc_material == GLASS) {
1454. 				tmp = (obj->otyp % (6 - shkp->m_id % 3));
1455. 				tmp = (tmp + 3) * obj->quan;
1456. 			}
1457. 		} else if (tmp > 1L && !rn2(4))
1458. 			tmp -= tmp / 4L;
1459. 	}
1460. 	return tmp;
1461. }
1462. 
1463. /* called from doinv(invent.c) for inventory of unpaid objects */
1464. long
1465. unpaid_cost(unp_obj)
1466. register struct obj *unp_obj;	/* known to be unpaid */
1467. {
1468. 	register struct bill_x *bp = (struct bill_x *)0;
1469. 	register struct monst *shkp;
1470. 
1471. 	for(shkp = next_shkp(fmon, TRUE); shkp;
1472. 					shkp = next_shkp(shkp->nmon, TRUE))
1473. 	    if ((bp = onbill(unp_obj, shkp, TRUE)) != 0) break;
1474. 
1475. 	/* onbill() gave no message if unexpected problem occurred */
1476. 	if(!bp) impossible("unpaid_cost: object wasn't on any bill!");
1477. 
1478. 	return bp ? unp_obj->quan * bp->price : 0L;
1479. }
1480. 
1481. static void
1482. add_one_tobill(obj, dummy)
1483. register struct obj *obj;
1484. register boolean dummy;
1485. {
1486. 	register struct monst *shkp;
1487. 	register struct bill_x *bp;
1488. 	register int bct;
1489. 	register char roomno = *u.ushops;
1490. 
1491. 	if(!*u.ushops) return;
1492. 
1493. 	if(!(shkp = shop_keeper(roomno))) return;
1494. 
1495. 	if(!inhishop(shkp)) return;
1496. 
1497. 	if(onbill(obj, shkp, FALSE) || /* perhaps thrown away earlier */
1498. 		    (obj->oclass == FOOD_CLASS && obj->oeaten))
1499. 		return;
1500. 
1501. 	if(ESHK(shkp)->billct == BILLSZ) {
1502. 		You("got that for free!");
1503. 		return;
1504. 	}
1505. 
1506. 	/* To recognize objects the shopkeeper is not interested in. -dgk
1507. 	 */
1508. 	if (obj->no_charge) {
1509. 		obj->no_charge = 0;
1510. 		return;
1511. 	}
1512. 
1513. 	bct = ESHK(shkp)->billct;
1514. 	bp = &(ESHK(shkp)->bill_p[bct]);
1515. 	bp->bo_id = obj->o_id;
1516. 	bp->bquan = obj->quan;
1517. 	if(dummy) {		  /* a dummy object must be inserted into  */
1518. 	    bp->useup = 1;	  /* the billobjs chain here.  crucial for */
1519. 	    obj->nobj = billobjs; /* eating floorfood in shop.  see eat.c  */
1520. 	    billobjs = obj;
1521. 	} else	bp->useup = 0;
1522. 	bp->price = get_cost(obj, shkp);
1523. 	ESHK(shkp)->billct++;
1524. 	obj->unpaid = 1;
1525. }
1526. 
1527. /* recursive billing of objects within containers. */
1528. static void
1529. bill_box_content(obj, ininv, dummy, shkp)
1530. register struct obj *obj;
1531. register boolean ininv, dummy;
1532. register struct monst *shkp;
1533. {
1534. 	register struct obj *otmp;
1535. 
1536. 	for(otmp = obj->cobj; otmp; otmp = otmp->nobj) {
1537. 
1538. 		if(obj->otyp == GOLD_PIECE) continue;
1539. 		/* the "top" box is added in addtobill() */
1540. 		if(!otmp->no_charge)
1541. 		    add_one_tobill(otmp, dummy);
1542. 		if(Is_container(otmp))
1543. 		    bill_box_content(otmp, ininv, dummy, shkp);
1544. 	}
1545. 
1546. }
1547. 
1548. void
1549. addtobill(obj, ininv, dummy, silent)
1550. register struct obj *obj;
1551. register boolean ininv, dummy, silent;
1552. {
1553. 	register struct monst *shkp;
1554. 	register char roomno = *u.ushops;
1555. 	long ltmp = 0L, cltmp = 0L, gltmp = 0L;
1556. 	register boolean container = Is_container(obj);
1557. 
1558. 	if(!*u.ushops) return;
1559. 
1560. 	if(!(shkp = shop_keeper(roomno))) return;
1561. 
1562. 	if(!inhishop(shkp)) return;
1563. 
1564. 	if(/* perhaps we threw it away earlier */
1565. 		 onbill(obj, shkp, FALSE) ||
1566. 		 (obj->oclass == FOOD_CLASS && obj->oeaten)
1567. 	      ) return;
1568. 
1569. 	if(ESHK(shkp)->billct == BILLSZ) {
1570. 		You("got that for free!");
1571. 		return;
1572. 	}
1573. 
1574. 	if(obj->oclass == GOLD_CLASS) {
1575. 		costly_gold(obj->ox, obj->oy, obj->quan);
1576. 		return;
1577. 	}
1578. 
1579. 	if(!obj->no_charge) ltmp = get_cost(obj, shkp);
1580. 
1581. 	if (obj->no_charge && !container) {
1582. 		obj->no_charge = 0;
1583. 		return;
1584. 	}
1585. 
1586. 	if(container) {
1587. 	    if(obj->cobj == (struct obj *)0) {
1588. 		if(obj->no_charge) {
1589. 		    obj->no_charge = 0;
1590. 		    return;
1591. 		} else {
1592. 		    add_one_tobill(obj, dummy);
1593. 		    goto speak;
1594. 		}
1595. 	    } else {
1596. 		cltmp += contained_cost(obj, shkp, cltmp, FALSE);
1597. 		gltmp += contained_gold(obj);
1598. 	    }
1599. 
1600. 	    if(ltmp) add_one_tobill(obj, dummy);
1601. 	    if(cltmp) bill_box_content(obj, ininv, dummy, shkp);
1602. 	    picked_container(obj); /* reset contained obj->no_charge */
1603. 
1604. 	    ltmp += cltmp;
1605. 
1606. 	    if(gltmp) {
1607. 		costly_gold(obj->ox, obj->oy, gltmp);
1608. 		if(!ltmp) return;
1609. 	    }
1610. 
1611. 	    if(obj->no_charge)
1612. 		obj->no_charge = 0;
1613. 
1614. 	} else /* i.e., !container */
1615. 	    add_one_tobill(obj, dummy);
1616. speak:
1617. 	if(!shkp->msleep && !shkp->mfrozen && !silent) {
1618. 	    char buf[BUFSZ];
1619. 
1620. 	    if(!ltmp) {
1621. 		pline("%s has no interest in %s.", Monnam(shkp),
1622. 					     the(xname(obj)));
1623. 		return;
1624. 	    }
1625. 	    Strcpy(buf, "\"For you, ");
1626. 	    if (ANGRY(shkp)) Strcat(buf, "scum ");
1627. 	    else {
1628. 		switch(rnd(4) + u.uevent.udemigod) {
1629. 		  case 1: Strcat(buf, "good");
1630. 			  break;
1631. 		  case 2: Strcat(buf, "honored");
1632. 			  break;
1633. 		  case 3: Strcat(buf, "most gracious");
1634. 			  break;
1635. 		  case 4: Strcat(buf, "esteemed");
1636. 			  break;
1637. 		  case 5: Strcat(buf, "most renowned and sacred");
1638. 			  break;
1639. 		}
1640. #ifdef POLYSELF
1641. 		if(!is_human(uasmon)) Strcat(buf, " creature");
1642. 		else
1643. #endif
1644. 		    Strcat(buf, (flags.female) ? " lady" : " sir");
1645. 	    }
1646. 	    /* after all, the shk is telling you what it is */
1647. 	    obj->dknown = 1;
1648. 	    exercise(A_WIS, TRUE);
1649. 	    if(ininv) {
1650. 		long quan = obj->quan;
1651. 		obj->quan = 1L; /* fool xname() into giving singular */
1652. 		pline("%s; only %ld %s %s.\"", buf, ltmp,
1653. 			(quan > 1L) ? "per" : "for this", xname(obj));
1654. 		obj->quan = quan;
1655. 	    } else
1656. 		pline("%s will cost you %ld zorkmid%s%s.",
1657. 			The(xname(obj)), ltmp, plur(ltmp),
1658. 			(obj->quan > 1L) ? " each" : "");
1659. 	} else if(!silent) {
1660. 	    if(ltmp) pline("The list price of %s is %ld zorkmid%s%s.",
1661. 				   the(xname(obj)), ltmp, plur(ltmp),
1662. 				   (obj->quan > 1L) ? " each" : "");
1663. 	    else pline("%s does not notice.", Monnam(shkp));
1664. 	}
1665. }
1666. 
1667. void
1668. splitbill(obj, otmp)
1669. register struct obj *obj, *otmp;
1670. {
1671. 	/* otmp has been split off from obj */
1672. 	register struct bill_x *bp;
1673. 	register long tmp;
1674. 	register struct monst *shkp = shop_keeper(*u.ushops);
1675. 
1676. 	if(!shkp || !inhishop(shkp)) {
1677. 		impossible("splitbill: no resident shopkeeper??");
1678. 		return;
1679. 	}
1680. 	bp = onbill(obj, shkp, FALSE);
1681. 	if(!bp) {
1682. 		impossible("splitbill: not on bill?");
1683. 		return;
1684. 	}
1685. 	if(bp->bquan < otmp->quan) {
1686. 		impossible("Negative quantity on bill??");
1687. 	}
1688. 	if(bp->bquan == otmp->quan) {
1689. 		impossible("Zero quantity on bill??");
1690. 	}
1691. 	bp->bquan -= otmp->quan;
1692. 
1693. 	if(ESHK(shkp)->billct == BILLSZ) otmp->unpaid = 0;
1694. 	else {
1695. 		tmp = bp->price;
1696. 		bp = &(ESHK(shkp)->bill_p[ESHK(shkp)->billct]);
1697. 		bp->bo_id = otmp->o_id;
1698. 		bp->bquan = otmp->quan;
1699. 		bp->useup = 0;
1700. 		bp->price = tmp;
1701. 		ESHK(shkp)->billct++;
1702. 	}
1703. }
1704. 
1705. static void
1706. sub_one_frombill(obj, shkp)
1707. register struct obj *obj;
1708. register struct monst *shkp;
1709. {
1710. 	register struct bill_x *bp;
1711. 
1712. 	if((bp = onbill(obj, shkp, FALSE)) != 0) {
1713. 		register struct obj *otmp;
1714. 
1715. 		obj->unpaid = 0;
1716. 		if(bp->bquan > obj->quan){
1717. 			otmp = newobj(0);
1718. 			*otmp = *obj;
1719. 			bp->bo_id = otmp->o_id = flags.ident++;
1720. 			otmp->quan = (bp->bquan -= obj->quan);
1721. 			otmp->owt = 0;	/* superfluous */
1722. 			otmp->onamelth = 0;
1723. 			bp->useup = 1;
1724. 			otmp->nobj = billobjs;
1725. 			billobjs = otmp;
1726. 			return;
1727. 		}
1728. 		ESHK(shkp)->billct--;
1729. #ifdef DUMB
1730. 		{
1731. 		/* DRS/NS 2.2.6 messes up -- Peter Kendell */
1732. 			int indx = ESHK(shkp)->billct;
1733. 			*bp = ESHK(shkp)->bill_p[indx];
1734. 		}
1735. #else
1736. 		*bp = ESHK(shkp)->bill_p[ESHK(shkp)->billct];
1737. #endif
1738. 		return;
1739. 	} else if (obj->unpaid) {
1740. 		impossible("sub_one_frombill: unpaid object not on bill");
1741. 		obj->unpaid = 0;
1742. 	}
1743. }
1744. 
1745. /* recursive check of unpaid objects within nested containers. */
1746. void
1747. subfrombill(obj, shkp)
1748. register struct obj *obj;
1749. register struct monst *shkp;
1750. {
1751. 	register struct obj *otmp;
1752. 
1753. 	sub_one_frombill(obj, shkp);
1754. 
1755. 	if(Is_container(obj))
1756. 	    for(otmp = obj->cobj; otmp; otmp = otmp->nobj) {
1757. 		if(otmp->otyp == GOLD_PIECE) continue;
1758. 
1759. 		if(Is_container(otmp))
1760. 		    subfrombill(otmp, shkp);
1761. 		else
1762. 		    sub_one_frombill(otmp, shkp);
1763. 	    }
1764. }
1765. 
1766. static long
1767. stolen_container(obj, shkp, price, ininv)
1768. register struct obj *obj;
1769. register struct monst *shkp;
1770. long price;
1771. register boolean ininv;
1772. {
1773. 	register struct obj *otmp;
1774. 
1775. 	if(ininv && obj->unpaid)
1776. 	    price += get_cost(obj, shkp);
1777. 	else {
1778. 	    if(!obj->no_charge)
1779. 		price += get_cost(obj, shkp);
1780. 	    obj->no_charge = 0;
1781. 	}
1782. 
1783. 	/* the price of contained objects, if any */
1784. 	for(otmp = obj->cobj; otmp; otmp = otmp->nobj) {
1785. 
1786. 	    if(otmp->otyp == GOLD_PIECE) continue;
1787. 
1788. 	    if(!Is_container(otmp)) {
1789. 		if(ininv) {
1790. 		    if(otmp->unpaid)
1791. 			price += get_cost(otmp, shkp);
1792. 		} else {
1793. 		    if(!otmp->no_charge) {
1794. 			if(!(otmp->oclass == BALL_CLASS ||
1795. 			    (otmp->oclass == FOOD_CLASS && otmp->oeaten) ||
1796. 			    (Is_candle(otmp) && otmp->age <
1797. 				  20L * (long)objects[otmp->otyp].oc_cost))
1798. 			  ) price += get_cost(otmp, shkp);
1799. 		    }
1800. 		    otmp->no_charge = 0;
1801. 		}
1802. 	    } else
1803. 		price += stolen_container(otmp, shkp, price, ininv);
1804. 	}
1805. 
1806. 	return(price);
1807. }
1808. 
1809. long
1810. stolen_value(obj, x, y, peaceful, silent)
1811. register struct obj *obj;
1812. register xchar x, y;
1813. register boolean peaceful, silent;
1814. {
1815. 	register long value = 0L, gvalue = 0L;
1816. 	register struct monst *shkp;
1817. 	register boolean goods;
1818. 
1819. 	shkp = shop_keeper(*in_rooms(x, y, SHOPBASE));
1820. 
1821. 	if (!shkp || !inhishop(shkp))
1822. 	    return (0L);
1823. 
1824. 	goods = saleable(rooms[ESHK(shkp)->shoproom -
1825. 				   ROOMOFFSET].rtype-SHOPBASE, obj);
1826. 	goods = (goods && !obj->no_charge);
1827. 
1828. 	if(obj->otyp == GOLD_PIECE) {
1829. 	    gvalue += obj->quan;
1830. 	} else if(Is_container(obj)) {
1831. 	    register boolean ininv = !!count_unpaid(obj->cobj);
1832. 
1833. 	    value += stolen_container(obj, shkp, value, ininv);
1834. 	    if(!ininv) gvalue += contained_gold(obj);
1835. 	} else if(goods) {
1836. 	    value += get_cost(obj, shkp);
1837. 	}
1838. 
1839. 	if(gvalue + value == 0L) return(0L);
1840. 
1841. 	value += gvalue;
1842. 
1843. 	if(peaceful) {
1844. 	    value = check_credit(value, shkp);
1845. 	    ESHK(shkp)->debit += value;
1846. 
1847. 	    if(!silent) {
1848. 		if(obj->otyp == GOLD_PIECE)
1849. 		    You("owe %s %ld zorkmids!", mon_nam(shkp), value);
1850. 		else You("owe %s %ld zorkmids for %s!",
1851. 			mon_nam(shkp),
1852. 			value,
1853. 			obj->quan > 1L ? "them" : "it");
1854. 	    }
1855. 	} else {
1856. 	    ESHK(shkp)->robbed += value;
1857. 
1858. 	    if(!silent) {
1859. 		if(cansee(shkp->mx, shkp->my)) {
1860. 		    if(ESHK(shkp)->customer[0] == 0)
1861. 			(void) strncpy(ESHK(shkp)->customer,plname,PL_NSIZ);
1862. 		    Norep("%s booms: \"%s, you are a thief!\"",
1863. 				Monnam(shkp), plname);
1864. 		} else  Norep("You hear a scream, \"Thief!\"");
1865. 	    }
1866. 	    hot_pursuit(shkp);
1867. 	    (void) angry_guards(FALSE);
1868. 	}
1869. 	return(value);
1870. }
1871. 
1872. /* auto-response flag for/from "sell foo?" 'a' => 'y', 'q' => 'n' */
1873. static char sell_response = 'a';
1874. 
1875. void
1876. sellobj_state(deliberate)	/* called from dodrop(do.c) and doddrop() */
1877. register boolean deliberate;
1878. {
1879. 	/* If we're deliberately dropping something, there's no automatic
1880. 	response to the shopkeeper's "want to sell" query; however, if we
1881. 	accidentally drop anything, the shk will buy it/them without asking.
1882. 	This retains the old pre-query risk that slippery fingers while in
1883. 	shops entailed:  you drop it, you've lost it.
1884. 	 */
1885. 	sell_response = deliberate ? '\0' : 'a';
1886. }
1887. 
1888. void
1889. sellobj(obj, x, y)
1890. register struct obj *obj;
1891. register xchar x, y;
1892. {
1893. 	register struct monst *shkp;
1894. 	register struct eshk *eshkp;
1895. 	register long ltmp = 0L, cltmp = 0L, gltmp = 0L, offer;
1896. 	boolean saleitem, cgold = FALSE, container = Is_container(obj);
1897. 	boolean isgold = (obj->oclass == GOLD_CLASS);
1898. 
1899. 	if(!(shkp = shop_keeper(*in_rooms(x, y, SHOPBASE))) ||
1900. 	   !inhishop(shkp)) return;
1901. 	if(!costly_spot(x, y))	return;
1902. 	if(!*u.ushops) return;
1903. 
1904. 	saleitem = saleable(rooms[ESHK(shkp)->shoproom -
1905. 					ROOMOFFSET].rtype-SHOPBASE, obj);
1906. 
1907. 	if(obj->unpaid && !container && !isgold) {
1908. 	    sub_one_frombill(obj, shkp);
1909. 	    return;
1910. 	}
1911. 	if(container) {
1912. 	    if(obj->cobj == (struct obj *)0) {
1913. 		if(obj->unpaid) {
1914. 		    sub_one_frombill(obj, shkp);
1915. 		    return;
1916. 		}
1917. 	    } else {
1918. 		/* find the price of content before subfrombill */
1919. 		cltmp += contained_cost(obj, shkp, cltmp, TRUE);
1920. 		/* find the value of contained gold */
1921. 		gltmp += contained_gold(obj);
1922. 		cgold = (gltmp > 0L);
1923. 	    }
1924. 	}
1925. 
1926. 	if(!isgold && !obj->unpaid && saleitem)
1927. 	    ltmp = set_cost(obj, shkp);
1928. 
1929. 	offer = ltmp + cltmp;
1930. 
1931. 	if(!isgold && (offer + gltmp) == 0L) {
1932. 		register boolean unpaid = (obj->unpaid ||
1933. 				  (container && count_unpaid(obj->cobj)));
1934. 
1935. 		if(container) {
1936. 		    if(obj->cobj != (struct obj *)0) {
1937. 			dropped_container(obj);
1938. 			if(obj->unpaid || count_unpaid(obj->cobj))
1939. 			    subfrombill(obj, shkp);
1940. 		    } else obj->no_charge = 1;
1941. 		} else obj->no_charge = 1;
1942. 
1943. 		if(!unpaid)
1944. 		    pline("%s seems uninterested.", Monnam(shkp));
1945. 		return;
1946. 	}
1947. 
1948. 	/* you dropped something of your own - probably want to sell it */
1949. 	if(shkp->msleep || !shkp->mcanmove) {
1950. 		if(container && obj->cobj != (struct obj *)0) {
1951. 		    dropped_container(obj);
1952. 		}
1953. 		if(!shkp->mcanmove) {
1954. 		    if(ANGRY(shkp) && !rn2(4))
1955. 			pline("%s utters a curse.", Monnam(shkp));
1956. 		    else pline("%s is indisposed.", Monnam(shkp));
1957. 		} else if(!rn2(3)) {
1958. 		    pline("%s snores indifferently.", Monnam(shkp));
1959. 		}
1960. 		subfrombill(obj, shkp);
1961. 		return;
1962. 	}
1963. 
1964. 	eshkp = ESHK(shkp);
1965. 
1966. 	if(isgold || cgold) {
1967. 		if(ANGRY(shkp)) {
1968. 		    if(!offer) {
1969. 			 pline("%s is not appeased.", Monnam(shkp));
1970. 			 if(cgold) subfrombill(obj, shkp);
1971. 			 return;
1972. 		    } else goto move_on;
1973. 		}
1974. 
1975. 		if(!cgold) gltmp = obj->quan;
1976. 
1977. 		if(eshkp->debit >= gltmp) {
1978. 		    if(eshkp->loan) { /* you carry shop's gold */
1979. 			 if(eshkp->loan >= gltmp)
1980. 			     eshkp->loan -= gltmp;
1981. 			 else eshkp->loan = 0L;
1982. 		    }
1983. 		    eshkp->debit -= gltmp;
1984. 		    Your("debt is %spaid off.",
1985. 				eshkp->debit ? "partially " : "");
1986. 		} else {
1987. 		    long delta = gltmp - eshkp->debit;
1988. 
1989. 		    eshkp->credit += delta;
1990. 		    if(eshkp->debit) {
1991. 			eshkp->debit = 0L;
1992. 			eshkp->loan = 0L;
1993. 			Your("debt is paid off.");
1994. 		    }
1995. 		    pline("%ld zorkmid%s added to your credit.",
1996. 				delta, delta > 1L ? "s are" : " is");
1997. 		}
1998. 		if(offer) goto move_on;
1999. 		else {
2000. 		    if(container && obj->cobj != (struct obj *)0) {
2001. 			dropped_container(obj);
2002. 		    }
2003. 		    subfrombill(obj, shkp);
2004. 		    obj->no_charge = 1;
2005. 		    return;
2006. 		}
2007. 	}
2008. move_on:
2009. 	if (ANGRY(shkp)) { /* they become shop-objects, no pay */
2010. 		pline("Thank you, scum!");
2011. 		subfrombill(obj, shkp);
2012. 		return;
2013. 	}
2014. 
2015. 	if((!saleitem && !(container && cltmp > 0L))
2016. 	   || eshkp->billct == BILLSZ
2017. 	   || obj->oclass == BALL_CLASS || offer == 0L
2018. 	   || (obj->oclass == FOOD_CLASS && obj->oeaten)
2019. 	   || (Is_candle(obj) &&
2020. 		   obj->age < 20L * (long)objects[obj->otyp].oc_cost)) {
2021. 		pline("%s seems not interested%s.", Monnam(shkp),
2022. 					   cgold ? " in the rest" : "");
2023. 		if(container && obj->cobj != (struct obj *)0) {
2024. 		    dropped_container(obj);
2025. 		}
2026. 		obj->no_charge = 1;
2027. 		return;
2028. 	}
2029. 
2030. 	if(eshkp->robbed) {  /* shkp is not angry? */
2031. 		if((eshkp->robbed -= offer < 0L))
2032. 			eshkp->robbed = 0L;
2033. 		verbalize(
2034.   "Thank you for your contribution to restock this recently plundered shop.");
2035. 		subfrombill(obj, shkp);
2036. 		return;
2037. 	}
2038. 
2039. 	if(!shkp->mgold) {
2040. 		long tmpcr = (ltmp + cltmp) * 2L;
2041. 
2042. 		pline("%s cannot pay you at present.", Monnam(shkp));
2043. 		pline("Will you accept %ld zorkmids in credit for %s? ",
2044. 					 tmpcr, doname(obj));
2045. 		/* cannot use a yn function here */
2046. 		if (readchar() == 'y') {
2047. 		    You("have %ld zorkmids in %scredit.", tmpcr,
2048. 				ESHK(shkp)->credit > 0L ? "additional " : "");
2049. 		    ESHK(shkp)->credit += tmpcr;
2050. 		    subfrombill(obj, shkp);
2051. 		} else {
2052. 		    if(container && obj->cobj != (struct obj *)0) {
2053. 				dropped_container(obj);
2054. 		    }
2055. 		    subfrombill(obj, shkp);
2056. 		    obj->no_charge = 1;
2057. 		}
2058. 	} else {
2059. 		int qlen;
2060. 		char qbuf[BUFSZ];
2061. 		boolean short_funds = (offer > shkp->mgold);
2062. 
2063. 		if (short_funds) offer = shkp->mgold;
2064. 
2065. 		if (!sell_response) {
2066. 		    Sprintf(qbuf,
2067. 			    "%s offers%s %ld gold piece%s for%s your %s.",
2068. 			    Monnam(shkp), short_funds ? " only" : "",
2069. 			    offer, plur(offer),
2070. 			    (!ltmp && cltmp) ? " the contents of" : "",
2071. 			    xname(obj));
2072. 		    qlen = strlen(qbuf);
2073. 		    /*  Will the prompt fit on the topline? (or would
2074. 		     *	"--more--" force line wrap anyway?)  If so, combine
2075. 		     *	the message and prompt; otherwise, flush message
2076. 		     *	and prompt separately.
2077. 		     */
2078. 		    if (qlen > COLNO - 24 && qlen <= COLNO - 8)
2079. 			pline(qbuf),  qbuf[0] = '\0';
2080. 		    else  Strcat(qbuf, "  ");
2081. 		    Strcat(strcat(qbuf, "Sell "),
2082. 			    (obj->quan == 1L ? "it?" : "them?"));
2083. 		} else  qbuf[0] = '\0';		/* just to pacify lint */
2084. 
2085. 		switch (sell_response ? sell_response : ynaq(qbuf)) {
2086. 		 case 'q':  sell_response = 'n';
2087. 		 case 'n':  if(container && obj->cobj != (struct obj *)0) {
2088. 				dropped_container(obj);
2089. 			    }
2090. 			    subfrombill(obj, shkp);
2091. 			    obj->no_charge = 1;
2092. 			    break;
2093. 		 case 'a':  sell_response = 'y';
2094. 		 case 'y':  subfrombill(obj, shkp);
2095. 			    pay(-offer, shkp);
2096. 			    You("sold %s for %ld gold piece%s.", doname(obj),
2097. 				offer, plur(offer));
2098. 			    break;
2099. 		 default:   impossible("invalid sell response");
2100. 		}
2101. 	}
2102. }
2103. 
2104. int
2105. doinvbill(mode)
2106. int mode;		/* 0: deliver count 1: paged */
2107. {
2108. 	register struct monst* shkp;
2109. 	register struct bill_x *bp, *end_bp;
2110. 	register struct obj *obj;
2111. 	long totused;
2112. 	char *buf_p;
2113. 	winid datawin;
2114. 
2115. 	shkp = shop_keeper(*u.ushops);
2116. 
2117. 	if(mode == 0) {
2118. 	    register int cnt = 0;
2119. 
2120. 	    if(shkp && inhishop(shkp))
2121. 		for (bp = ESHK(shkp)->bill_p,
2122. 			end_bp = &(ESHK(shkp)->bill_p[ESHK(shkp)->billct]);
2123. 			bp < end_bp; bp++)
2124. 		    if(bp->useup ||
2125. 		       ((obj = bp_to_obj(bp)) && obj->quan < bp->bquan))
2126. 			cnt++;
2127. 	    return(cnt);
2128. 	}
2129. 
2130. 	if(!shkp || !inhishop(shkp)) {
2131. 		impossible("doinvbill: no shopkeeper?");
2132. 		return(0);
2133. 	}
2134. 
2135. 	datawin = create_nhwindow(NHW_MENU);
2136. 	putstr(datawin, 0, "Unpaid articles already used up:");
2137. 	putstr(datawin, 0, "");
2138. 
2139. 	totused = 0L;
2140. 	for (bp = ESHK(shkp)->bill_p,
2141. 		end_bp = &(ESHK(shkp)->bill_p[ESHK(shkp)->billct]);
2142. 		bp < end_bp; bp++) {
2143. 	    obj = bp_to_obj(bp);
2144. 	    if(!obj) {
2145. 		impossible("Bad shopkeeper administration.");
2146. 		goto quit;
2147. 	    }
2148. 	    if(bp->useup || bp->bquan > obj->quan) {
2149. 		register long oquan, uquan;
2150. 		long thisused;
2151. 
2152. 		oquan = obj->quan;
2153. 		uquan = (bp->useup ? bp->bquan : bp->bquan - oquan);
2154. 		thisused = bp->price * uquan;
2155. 		totused += thisused;
2156. 		obj->quan = uquan;		/* cheat doname */
2157. 		buf_p = xprname(obj, ' ', FALSE, thisused);
2158. 		obj->quan = oquan;		/* restore value */
2159. 		putstr(datawin, 0, buf_p);
2160. 	    }
2161. 	}
2162. 	buf_p = xprname((struct obj *)0, '*', FALSE, totused);
2163. 	putstr(datawin, 0, "");
2164. 	putstr(datawin, 0, buf_p);
2165. 	display_nhwindow(datawin, FALSE);
2166.     quit:
2167. 	destroy_nhwindow(datawin);
2168. 	return(0);
2169. }
2170. 
2171. #define HUNGRY	2
2172. 
2173. static long
2174. getprice(obj)
2175. register struct obj *obj;
2176. {
2177. 	register long tmp = (long) objects[obj->otyp].oc_cost;
2178. 
2179. 	switch(obj->oclass) {
2180. 	case FOOD_CLASS:
2181. 		/* simpler hunger check, (2-4)*cost */
2182. 		if (u.uhs >= HUNGRY) tmp *= (long) u.uhs;
2183. 		if (obj->oeaten) tmp = 0L;
2184. 		break;
2185. 	case WAND_CLASS:
2186. 		if (obj->spe == -1) tmp = 0L;
2187. 		break;
2188. 	case POTION_CLASS:
2189. 		if (obj->otyp == POT_WATER && !obj->blessed && !obj->cursed)
2190. 			tmp = 0L;
2191. 		break;
2192. 	case ARMOR_CLASS:
2193. 	case WEAPON_CLASS:
2194. 		if (obj->spe > 0) tmp += 10L * (long) obj->spe;
2195. 		break;
2196. 	case CHAIN_CLASS:
2197. 		pline("Strange... carrying a chain?");
2198. 		break;
2199. 	case TOOL_CLASS:
2200. 		if (Is_candle(obj) &&
2201. 			obj->age < 20L * (long)objects[obj->otyp].oc_cost)
2202. 		    tmp /= 2L;
2203. 		break;
2204. 	}
2205. 	if (obj->oartifact) tmp *= 25L;
2206. 	return tmp;
2207. }
2208. 
2209. int
2210. shkcatch(obj, x, y)
2211. register struct obj *obj;
2212. register xchar x, y;
2213. {
2214. 	register struct monst *shkp;
2215. 
2216. 	if (!(shkp = shop_keeper(inside_shop(x, y))) ||
2217. 	    !inhishop(shkp)) return(0);
2218. 
2219. 	if (shkp->mcanmove && !shkp->msleep &&
2220. 	    (*u.ushops != ESHK(shkp)->shoproom || !inside_shop(u.ux, u.uy)) &&
2221. 	    dist2(shkp->mx, shkp->my, x, y) < 3 &&
2222. 	    /* if it is the shk's pos, you hit and anger him */
2223. 	    (shkp->mx != x || shkp->my != y)) {
2224. 		if (mnearto(shkp, x, y, TRUE))
2225. 		    verbalize("Out of my way, scum!");
2226. 		pline("%s nimbly catches %s.", Monnam(shkp), the(xname(obj)));
2227. 		mpickobj(shkp, obj);
2228. 		subfrombill(obj, shkp);
2229. 		return(1);
2230. 	}
2231. 	return(0);
2232. }
2233. 
2234. void
2235. add_damage(x, y, cost)
2236. register xchar x, y;
2237. long cost;
2238. {
2239. 	struct damage *tmp_dam;
2240. 	char *shops;
2241. 
2242. 	if (IS_DOOR(levl[x][y].typ))
2243. 	    /* Don't schedule for repair unless it's a real shop entrance */
2244. 	    for (shops = in_rooms(x, y, SHOPBASE); *shops; shops++) {
2245. 		struct monst *mtmp = shop_keeper(*shops);
2246. 
2247. 		if (!mtmp)
2248. 		    continue;
2249. 		if ((x != ESHK(mtmp)->shd.x) || (y != ESHK(mtmp)->shd.y))
2250. 		    return;
2251. 	    }
2252. 	tmp_dam = (struct damage *)alloc((unsigned)sizeof(struct damage));
2253. 	tmp_dam->when = monstermoves;
2254. 	tmp_dam->place.x = x;
2255. 	tmp_dam->place.y = y;
2256. 	tmp_dam->cost = cost;
2257. 	tmp_dam->typ = levl[x][y].typ;
2258. 	tmp_dam->next = level.damagelist;
2259. 	level.damagelist = tmp_dam;
2260. 	/* If player saw damage, display as a wall forever */
2261. 	if (cansee(x, y))
2262. 	    levl[x][y].seen = 1;
2263. }
2264. 
2265. /*
2266.  * Do something about damage. Either (!croaked) try to repair it, or
2267.  * (croaked) just discard damage structs for non-shared locations, since
2268.  * they'll never get repaired. Assume that shared locations will get
2269.  * repaired eventually by the other shopkeeper(s). This might be an erroneous
2270.  * assumption (they might all be dead too), but we have no reasonable way of
2271.  * telling that.
2272.  */
2273. static
2274. void
2275. remove_damage(shkp, croaked)
2276. register struct monst *shkp;
2277. register boolean croaked;
2278. {
2279. 	register struct damage *tmp_dam, *tmp2_dam;
2280. 	register boolean did_repair = FALSE, saw_door = FALSE;
2281. 	register boolean saw_floor = FALSE, stop_picking = FALSE;
2282. 	uchar saw_walls = 0;
2283. 
2284. 	tmp_dam = level.damagelist;
2285. 	tmp2_dam = 0;
2286. 	while (tmp_dam) {
2287. 	    register xchar x = tmp_dam->place.x, y = tmp_dam->place.y;
2288. 	    char shops[5];
2289. 	    uchar disposition;
2290. 
2291. 	    disposition = 0;
2292. 	    Strcpy(shops, in_rooms(x, y, SHOPBASE));
2293. 	    if (index(shops, ESHK(shkp)->shoproom)) {
2294. 		if (croaked)
2295. 		    disposition = (shops[1])? 0 : 1;
2296. 		else if (stop_picking)
2297. 		    disposition = repair_damage(shkp, tmp_dam);
2298. 		else {
2299. 		    /* Defer the stop_occupation() until after repair msgs */
2300. 		    if (closed_door(x, y))
2301. 			stop_picking = picking_at(x, y);
2302. 		    disposition = repair_damage(shkp, tmp_dam);
2303. 		    if (!disposition)
2304. 			stop_picking = FALSE;
2305. 		}
2306. 	    }
2307. 
2308. 	    if (!disposition) {
2309. 		tmp2_dam = tmp_dam;
2310. 		tmp_dam = tmp_dam->next;
2311. 		continue;
2312. 	    }
2313. 
2314. 	    if (disposition > 1) {
2315. 		did_repair = TRUE;
2316. 		if (cansee(x, y)) {
2317. 		    if (IS_WALL(levl[x][y].typ))
2318. 			saw_walls++;
2319. 		    else if (IS_DOOR(levl[x][y].typ))
2320. 			saw_door = TRUE;
2321. 		    else
2322. 			saw_floor = TRUE;
2323. 		}
2324. 	    }
2325. 
2326. 	    tmp_dam = tmp_dam->next;
2327. 	    if (!tmp2_dam) {
2328. 		free((genericptr_t)level.damagelist);
2329. 		level.damagelist = tmp_dam;
2330. 	    } else {
2331. 		free((genericptr_t)tmp2_dam->next);
2332. 		tmp2_dam->next = tmp_dam;
2333. 	    }
2334. 	}
2335. 	if (!did_repair)
2336. 	    return;
2337. 	if (saw_walls) {
2338. 	    pline("Suddenly, %s section%s of wall close%s up!",
2339. 		  (saw_walls == 1) ? "a" : (saw_walls <= 3) ?
2340. 						  "some" : "several",
2341. 		  (saw_walls == 1) ? "" : "s", (saw_walls == 1) ? "s" : "");
2342. 	    if (saw_door)
2343. 		pline("The shop door reappears!");
2344. 	    if (saw_floor)
2345. 		pline("The floor is repaired!");
2346. 	} else {
2347. 	    if (saw_door)
2348. 		pline("Suddenly, the shop door reappears!");
2349. 	    else if (saw_floor)
2350. 		pline("Suddenly, the floor damage is gone!");
2351. 	    else if (inside_shop(u.ux, u.uy) == ESHK(shkp)->shoproom)
2352. 		You("feel more claustrophobic than before.");
2353. 	    else if (flags.soundok && !rn2(10))
2354. 		Norep("The dungeon acoustics noticeably change.");
2355. 	}
2356. 	if (stop_picking)
2357. 		stop_occupation();
2358. }
2359. 
2360. /*
2361.  * 0: repair postponed, 1: silent repair (no messages), 2: normal repair
2362.  */
2363. char
2364. repair_damage(shkp, tmp_dam)
2365. register struct monst *shkp;
2366. register struct damage *tmp_dam;
2367. {
2368. 	register xchar x, y, i;
2369. 	xchar litter[9];
2370. 	register struct monst *mtmp;
2371. 	register struct obj *otmp;
2372. 	register struct trap *ttmp;
2373. 
2374. 	if ((monstermoves - tmp_dam->when) < REPAIR_DELAY)
2375. 	    return(0);
2376. 	if (ESHK(shkp)->following)
2377. 	    return(0);
2378. 	x = tmp_dam->place.x;
2379. 	y = tmp_dam->place.y;
2380. 	if (!IS_ROOM(tmp_dam->typ)) {
2381. 	    if ((x == u.ux) && (y == u.uy))
2382. #ifdef POLYSELF
2383. 		if (!passes_walls(uasmon))
2384. #endif
2385. 		    return(0);
2386. 	    if ((x == shkp->mx) && (y == shkp->my))
2387. 		return(0);
2388. 	    if ((mtmp = m_at(x, y)) && (!passes_walls(mtmp->data)))
2389. 		return(0);
2390. 	}
2391. 	if ((ttmp = t_at(x, y)) != 0)
2392. 	    deltrap(ttmp);
2393. 	if (IS_ROOM(tmp_dam->typ)) {
2394. 	    /* No messages if player already filled trapdoor */
2395. 	    if (!ttmp)
2396. 		return(1);
2397. 	    newsym(x, y);
2398. 	    return(2);
2399. 	}
2400. 	if (!ttmp && (tmp_dam->typ == levl[x][y].typ) &&
2401. 	    (!IS_DOOR(tmp_dam->typ) || (levl[x][y].doormask > D_BROKEN)))
2402. 	    /* No messages if player already replaced shop door */
2403. 	    return(1);
2404. 	levl[x][y].typ = tmp_dam->typ;
2405. 	(void) memset((genericptr_t)litter, 0, sizeof(litter));
2406. 	if ((otmp = level.objects[x][y]) != 0) {
2407. 	    /* Scatter objects haphazardly into the shop */
2408. #define NEED_UPDATE 1
2409. #define OPEN	    2
2410. #define INSHOP	    4
2411. #define horiz(i) ((i%3)-1)
2412. #define vert(i)  ((i/3)-1)
2413. 	    for (i = 0; i < 9; i++) {
2414. 		if ((i == 4) || (!ZAP_POS(levl[x+horiz(i)][y+vert(i)].typ)))
2415. 		    continue;
2416. 		litter[i] = OPEN;
2417. 		if (inside_shop(x+horiz(i),
2418. 				y+vert(i)) == ESHK(shkp)->shoproom)
2419. 		    litter[i] |= INSHOP;
2420. 	    }
2421. 	    if (Punished && ((uchain->ox == x && uchain->oy == y) ||
2422. 					(uball->ox == x && uball->oy == y))) {
2423. 		/*
2424. 		 * Either the ball or chain is in the repair location.
2425. 		 *
2426. 		 * Take the easy way out and put ball&chain under hero.
2427. 		 */
2428. 		verbalize("Get your junk out of my wall!");
2429. 		unplacebc();	/* pick 'em up */
2430. 		placebc();	/* put 'em down */
2431. 	    }
2432. 	    while ((otmp = level.objects[x][y]) != 0)
2433. 		/* Don't mess w/ boulders -- just merge into wall */
2434. 		if ((otmp->otyp == BOULDER) || (otmp->otyp == ROCK)) {
2435. 		    freeobj(otmp);
2436. 		    obfree(otmp, (struct obj *)0);
2437. 		} else {
2438. 		    while (!(litter[i = rn2(9)] & INSHOP));
2439. 			remove_object(otmp);
2440. 			place_object(otmp, x+horiz(i), y+vert(i));
2441. 			litter[i] |= NEED_UPDATE;
2442. 		}
2443. 	}
2444. 	block_point(x, y);
2445. 	if(IS_DOOR(tmp_dam->typ)) {
2446. 	    levl[x][y].doormask = D_CLOSED; /* arbitrary */
2447. 	    newsym(x, y);
2448. 	} else {
2449. 	    levl[x][y].doormask = D_NODOOR;
2450. 	    if (IS_WALL(tmp_dam->typ) && cansee(x, y)) {
2451. 	    /* Player sees actual repair process, so they KNOW it's a wall */
2452. 		levl[x][y].seen = 1;
2453. 		newsym(x, y);
2454. 	    } else if (levl[x][y].seen) {
2455. 		/* Force a display update */
2456. 		levl[x][y].diggable |= W_REPAIRED;
2457. 	    }
2458. 	}
2459. 	for (i = 0; i < 9; i++)
2460. 	    if (litter[i] & NEED_UPDATE)
2461. 		newsym(x+horiz(i), y+vert(i));
2462. 	return(2);
2463. #undef NEED_UPDATE
2464. #undef OPEN
2465. #undef INSHOP
2466. #undef vert
2467. #undef horiz
2468. }
2469. 
2470. /*
2471.  * shk_move: return 1: moved  0: didn't  -1: let m_move do it  -2: died
2472.  */
2473. int
2474. shk_move(shkp)
2475. register struct monst *shkp;
2476. {
2477. 	register xchar gx,gy,omx,omy;
2478. 	register int udist;
2479. 	register schar appr;
2480. 	register struct eshk *eshkp = ESHK(shkp);
2481. 	int z;
2482. 	boolean uondoor = FALSE, satdoor, avoid = FALSE, badinv;
2483. 
2484. 	omx = shkp->mx;
2485. 	omy = shkp->my;
2486. 
2487. 	if (inhishop(shkp))
2488. 	    remove_damage(shkp, FALSE);
2489. 
2490. 	if((udist = distu(omx,omy)) < 3 &&
2491. 	   (shkp->data != &mons[PM_GRID_BUG] || (omx==u.ux || omy==u.uy))) {
2492. 		if(ANGRY(shkp) ||
2493. 		   (Conflict && !resist(shkp, RING_CLASS, 0, 0))) {
2494. 			if(Displaced)
2495. 			  Your("displaced image doesn't fool %s!",
2496. 				mon_nam(shkp));
2497. 			(void) mattacku(shkp);
2498. 			return(0);
2499. 		}
2500. 		if(eshkp->following) {
2501. 			if(strncmp(eshkp->customer, plname, PL_NSIZ)) {
2502. 			    verbalize("Hello, %s!  I was looking for %s.",
2503. 				    plname, eshkp->customer);
2504. 				    eshkp->following = 0;
2505. 			    return(0);
2506. 			}
2507. 			if(moves > followmsg+4) {
2508. 			    verbalize("Hello, %s!  Didn't you forget to pay?",
2509. 				    plname);
2510. 			    followmsg = moves;
2511. 			    if (!rn2(4)) {
2512. 	    pline ("%s doesn't like customers who don't pay.", Monnam(shkp));
2513. 				rile_shk(shkp);
2514. 			    }
2515. 			}
2516. 			if(udist < 2)
2517. 			    return(0);
2518. 		}
2519. 	}
2520. 
2521. 	appr = 1;
2522. 	gx = eshkp->shk.x;
2523. 	gy = eshkp->shk.y;
2524. 	satdoor = (gx == omx && gy == omy);
2525. 	if(eshkp->following || ((z = holetime()) >= 0 && z*z <= udist)){
2526. 		if(udist > 4)
2527. 		    return(-1);	/* leave it to m_move */
2528. 		gx = u.ux;
2529. 		gy = u.uy;
2530. 	} else if(ANGRY(shkp)) {
2531. 		/* Move towards the hero if the shopkeeper can see him. */
2532. 		if(shkp->mcansee && m_canseeu(shkp)) {
2533. 			gx = u.ux;
2534. 			gy = u.uy;
2535. 		}
2536. 		avoid = FALSE;
2537. 	} else {
2538. #define	GDIST(x,y)	(dist2(x,y,gx,gy))
2539. 		if(Invis) {
2540. 		    avoid = FALSE;
2541. 		} else {
2542. 		    uondoor = (u.ux == eshkp->shd.x && u.uy == eshkp->shd.y);
2543. 		    if(uondoor) {
2544. 			badinv = (!!carrying(PICK_AXE));
2545. 			if(satdoor && badinv)
2546. 			    return(0);
2547. 			avoid = !badinv;
2548. 		    } else {
2549. 			avoid = (*u.ushops && distu(gx,gy) > 8);
2550. 			badinv = FALSE;
2551. 		    }
2552. 
2553. 		    if(((!eshkp->robbed && !eshkp->billct && !eshkp->debit)
2554. 			|| avoid) && GDIST(omx,omy) < 3) {
2555. 			if (!badinv && !onlineu(omx,omy))
2556. 			    return(0);
2557. 			if(satdoor)
2558. 			    appr = gx = gy = 0;
2559. 		    }
2560. 		}
2561. 	}
2562. 
2563. 	return(move_special(shkp,inhishop(shkp),
2564. 			    appr,uondoor,avoid,omx,omy,gx,gy));
2565. }
2566. 
2567. /* for use in levl_follower (mondata.c) */
2568. boolean
2569. is_fshk(mtmp)
2570. register struct monst *mtmp;
2571. {
2572. 	return(mtmp->isshk && ESHK(mtmp)->following);
2573. }
2574. 
2575. /* You are digging in the shop. */
2576. void
2577. shopdig(fall)
2578. register int fall;
2579. {
2580.     register struct monst *shkp = shop_keeper(*u.ushops);
2581. 
2582.     if(!shkp) return;
2583. 
2584.     if(!inhishop(shkp)) {
2585. 	if (pl_character[0] == 'K') adjalign(-sgn(u.ualign.type));
2586. 	return;
2587.     }
2588. 
2589.     if(!fall) {
2590. 	if(u.utraptype == TT_PIT)
2591. 	    verbalize("Be careful, %s, or you might fall through the floor.",
2592. 		flags.female ? "madam" : "sir");
2593. 	else
2594. 	    verbalize("%s, do not damage the floor here!",
2595. 			flags.female ? "Madam" : "Sir");
2596. 	if (pl_character[0] == 'K') adjalign(-sgn(u.ualign.type));
2597.     } else if(!um_dist(shkp->mx, shkp->my, 5) &&
2598. 		!shkp->msleep && shkp->mcanmove &&
2599. 		(ESHK(shkp)->billct || ESHK(shkp)->debit)) {
2600. 	    register struct obj *obj, *obj2;
2601. 
2602. 	    if (distu(shkp->mx, shkp->my) > 2) {
2603. 		mnexto(shkp);
2604. 		/* for some reason the shopkeeper can't come next to you */
2605. 		if (distu(shkp->mx, shkp->my) > 2) {
2606. 		    pline("%s curses you in anger and frustration!",
2607. 					shkname(shkp));
2608. 		    rile_shk(shkp);
2609. 		    return;
2610. 		} else pline("%s leaps, and grabs your backpack!",
2611. 					shkname(shkp));
2612. 	    } else pline("%s grabs your backpack!", shkname(shkp));
2613. 
2614. 	    for(obj = invent; obj; obj = obj2) {
2615. 		obj2 = obj->nobj;
2616. 		if(obj->owornmask) continue;
2617. #ifdef WALKIES
2618. 		if(obj->otyp == LEASH && obj->leashmon) continue;
2619. #endif
2620. 		freeinv(obj);
2621. 		obj->nobj = shkp->minvent;
2622. 		shkp->minvent = obj;
2623. 		subfrombill(obj, shkp);
2624. 	    }
2625.     }
2626. }
2627. 
2628. #ifdef KOPS
2629. STATIC_OVL void
2630. makekops(mm)		/* returns the number of (all types of) Kops  made */
2631. coord *mm;
2632. {
2633. 	register int cnt = depth(&u.uz) + rnd(5);
2634. 	register int scnt = (cnt / 3) + 1;	/* at least one sarge */
2635. 	register int lcnt = (cnt / 6);		/* maybe a lieutenant */
2636. 	register int kcnt = (cnt / 9);		/* and maybe a kaptain */
2637. 
2638. 	if (!(mons[PM_KEYSTONE_KOP].geno & G_EXTINCT)) {
2639. 	    while(cnt--) {
2640. 		if (enexto(mm, mm->x, mm->y, &mons[PM_KEYSTONE_KOP]))
2641. 			(void) makemon(&mons[PM_KEYSTONE_KOP], mm->x, mm->y);
2642. 	    }
2643. 	}
2644. 	if (!(mons[PM_KOP_SERGEANT].geno & G_EXTINCT)) {
2645. 	    while(scnt--) {
2646. 		if (enexto(mm, mm->x, mm->y, &mons[PM_KOP_SERGEANT]))
2647. 			(void) makemon(&mons[PM_KOP_SERGEANT], mm->x, mm->y);
2648. 	    }
2649. 	}
2650. 	if (!(mons[PM_KOP_LIEUTENANT].geno & G_EXTINCT)) {
2651. 	    while(lcnt--) {
2652. 		if (enexto(mm, mm->x, mm->y, &mons[PM_KOP_LIEUTENANT]))
2653. 		    (void) makemon(&mons[PM_KOP_LIEUTENANT], mm->x, mm->y);
2654. 	    }
2655. 	}
2656. 	if (!(mons[PM_KOP_KAPTAIN].geno & G_EXTINCT)) {
2657. 	    while(kcnt--) {
2658. 		if (enexto(mm, mm->x, mm->y, &mons[PM_KOP_KAPTAIN]))
2659. 		    (void) makemon(&mons[PM_KOP_KAPTAIN], mm->x, mm->y);
2660. 	    }
2661. 	}
2662. }
2663. #endif	/* KOPS */
2664. 
2665. void
2666. pay_for_damage(dmgstr)
2667. const char *dmgstr;
2668. {
2669. 	register struct monst *shkp = (struct monst *)0;
2670. 	char shops_affected[5];
2671. 	register boolean uinshp = (*u.ushops != '\0');
2672. 	char qbuf[80];
2673. 	register xchar x, y;
2674. 	register boolean dugwall = !strcmp(dmgstr, "dig into");
2675. 	struct damage *tmp_dam, *appear_here = 0;
2676. 	/* any number >= (80*80)+(24*24) would do, actually */
2677. 	long cost_of_damage = 0L;
2678. 	unsigned int nearest_shk = 7000, nearest_damage = 7000;
2679. 	int picks = 0;
2680. 
2681. 	for (tmp_dam = level.damagelist;
2682. 	     (tmp_dam && (tmp_dam->when == monstermoves));
2683. 	     tmp_dam = tmp_dam->next) {
2684. 	    char *shp;
2685. 
2686. 	    if (!tmp_dam->cost)
2687. 		continue;
2688. 	    cost_of_damage += tmp_dam->cost;
2689. 	    Strcpy(shops_affected,
2690. 		   in_rooms(tmp_dam->place.x, tmp_dam->place.y, SHOPBASE));
2691. 	    for (shp = shops_affected; *shp; shp++) {
2692. 		struct monst *tmp_shk;
2693. 		unsigned int shk_distance;
2694. 
2695. 		if (!(tmp_shk = shop_keeper(*shp)))
2696. 		    continue;
2697. 		if (tmp_shk == shkp) {
2698. 		    unsigned int damage_distance =
2699. 				   distu(tmp_dam->place.x, tmp_dam->place.y);
2700. 
2701. 		    if (damage_distance < nearest_damage) {
2702. 			nearest_damage = damage_distance;
2703. 			appear_here = tmp_dam;
2704. 		    }
2705. 		    continue;
2706. 		}
2707. 		if (!inhishop(tmp_shk))
2708. 		    continue;
2709. 		shk_distance = distu(tmp_shk->mx, tmp_shk->my);
2710. 		if (shk_distance > nearest_shk)
2711. 		    continue;
2712. 		if ((shk_distance == nearest_shk) && picks) {
2713. 		    if (rn2(++picks))
2714. 			continue;
2715. 		} else
2716. 		    picks = 1;
2717. 		shkp = tmp_shk;
2718. 		nearest_shk = shk_distance;
2719. 		appear_here = tmp_dam;
2720. 		nearest_damage = distu(tmp_dam->place.x, tmp_dam->place.y);
2721. 	    }
2722. 	}
2723. 
2724. 	if (!cost_of_damage || !shkp)
2725. 	    return;
2726. 
2727. 	x = appear_here->place.x;
2728. 	y = appear_here->place.y;
2729. 
2730. 	/* not the best introduction to the shk... */
2731. 	(void) strncpy(ESHK(shkp)->customer,plname,PL_NSIZ);
2732. 
2733. 	/* if the shk is already on the war path, be sure it's all out */
2734. 	if(ANGRY(shkp) || ESHK(shkp)->following) {
2735. 		hot_pursuit(shkp);
2736. 		return;
2737. 	}
2738. 
2739. 	/* if the shk is not in their shop.. */
2740. 	if(!*in_rooms(shkp->mx,shkp->my,SHOPBASE)) {
2741. 		if(!cansee(shkp->mx, shkp->my))
2742. 			return;
2743. 		goto getcad;
2744. 	}
2745. 
2746. 	if(uinshp) {
2747. 		if(um_dist(shkp->mx, shkp->my, 1) &&
2748. 			!um_dist(shkp->mx, shkp->my, 3)) {
2749. 		    pline("%s leaps towards you!", shkname(shkp));
2750. 		    mnexto(shkp);
2751. 		}
2752. 		if(um_dist(shkp->mx, shkp->my, 1)) goto getcad;
2753. 	} else {
2754. 	    /*
2755. 	     * Make shkp show up at the door.  Effect:  If there is a monster
2756. 	     * in the doorway, have the hero hear the shopkeeper yell a bit,
2757. 	     * pause, then have the shopkeeper appear at the door, having
2758. 	     * yanked the hapless critter out of the way.
2759. 	     */
2760. 	    if (MON_AT(x, y)) {
2761. 		if(flags.soundok) {
2762. 		    You("hear an angry voice:");
2763. 		    verbalize("Out of my way, scum!");
2764. 		    wait_synch();
2765. #if defined(UNIX) || defined(VMS)
2766. # if defined(SYSV) || defined(ULTRIX) || defined(VMS)
2767. 		    (void)
2768. # endif
2769. 			sleep(1);
2770. #endif
2771. 		}
2772. 	    }
2773. 	    (void) mnearto(shkp, x, y, TRUE);
2774. 	}
2775. 
2776. 	if((um_dist(x, y, 1) && !uinshp) ||
2777. 			(u.ugold + ESHK(shkp)->credit) < cost_of_damage
2778. 				|| !rn2(50)) {
2779. 		if(um_dist(x, y, 1) && !uinshp) {
2780. 		    pline("%s shouts:", shkname(shkp));
2781. 		    verbalize("Who dared %s my %s?", dmgstr,
2782. 					 dugwall ? "shop" : "door");
2783. 		} else {
2784. getcad:
2785. 		    verbalize("How dare you %s my %s?", dmgstr,
2786. 					 dugwall ? "shop" : "door");
2787. 		}
2788. 		hot_pursuit(shkp);
2789. 		return;
2790. 	}
2791. 
2792. 	if(Invis) Your("invisibility does not fool %s!", shkname(shkp));
2793. 	Sprintf(qbuf,"\"Cad!  You did %ld zorkmids worth of damage!\"  Pay? ",
2794. 		 cost_of_damage);
2795. 	if(yn(qbuf) != 'n') {
2796. 		cost_of_damage = check_credit(cost_of_damage, shkp);
2797. 		u.ugold -= cost_of_damage;
2798. 		shkp->mgold += cost_of_damage;
2799. 		flags.botl = 1;
2800. 		pline("Mollified, %s accepts your restitution.",
2801. 			shkname(shkp));
2802. 		/* move shk back to his home loc */
2803. 		home_shk(shkp, FALSE);
2804. 		pacify_shk(shkp);
2805. 	} else {
2806. 		verbalize("Oh, yes!  You'll pay!");
2807. 		hot_pursuit(shkp);
2808. 		adjalign(-sgn(u.ualign.type));
2809. 	}
2810. }
2811. 
2812. /* called in dokick.c when we kick an object that might be in a store */
2813. boolean
2814. costly_spot(x, y)
2815. register xchar x, y;
2816. {
2817. 	register struct monst *shkp;
2818. 
2819. 	if (!level.flags.has_shop) return FALSE;
2820. 	shkp = shop_keeper(*in_rooms(x, y, SHOPBASE));
2821. 	if(!shkp || !inhishop(shkp)) return(FALSE);
2822. 
2823. 	return(inside_shop(x, y) &&
2824. 		!(x == ESHK(shkp)->shk.x &&
2825. 			y == ESHK(shkp)->shk.y));
2826. }
2827. 
2828. /* called by dotalk(sounds.c) when #chatting; returns obj if location
2829.    contains shop goods and shopkeeper is willing & able to speak */
2830. struct obj *
2831. shop_object(x, y)
2832. register xchar x, y;
2833. {
2834.     register struct obj *otmp;
2835.     register struct monst *shkp;
2836. 
2837.     if(!(shkp = shop_keeper(*in_rooms(x, y, SHOPBASE))) || !inhishop(shkp))
2838. 	return(struct obj *)0;
2839. 
2840.     for (otmp = level.objects[x][y]; otmp; otmp = otmp->nexthere)
2841. 	if (otmp->otyp != GOLD_PIECE)
2842. 	    break;
2843.     /* note: otmp might have ->no_charge set, but that's ok */
2844.     return (otmp && costly_spot(x, y) && NOTANGRY(shkp)
2845. 	    && !shkp->msleep && !shkp->mfrozen)
2846. 		? otmp : (struct obj *)0;
2847. }
2848. 
2849. /* give price quotes for all objects linked to this one (ie, on this spot) */
2850. void
2851. price_quote(first_obj)
2852. register struct obj *first_obj;
2853. {
2854.     register struct obj *otmp;
2855.     char buf[BUFSZ], price[40];
2856.     long cost;
2857.     int cnt = 0;
2858.     winid tmpwin;
2859. 
2860.     tmpwin = create_nhwindow(NHW_MENU);
2861.     putstr(tmpwin, 0, "Fine goods for sale:");
2862.     putstr(tmpwin, 0, "");
2863.     for (otmp = first_obj; otmp; otmp = otmp->nexthere) {
2864. 	if (otmp->otyp == GOLD_PIECE) {
2865. 	 /* if (otmp == first_obj)  first_obj = otmp->nexthere; */
2866. 	    continue;	/* don't quote a price on this */
2867. 	} else if (otmp->no_charge) {
2868. 	    Strcpy(price, "no charge");
2869. 	} else {
2870. 	    cost = get_cost(otmp, (struct monst *)0);
2871. 	    Sprintf(price, "%ld zorkmid%s%s", cost, plur(cost),
2872. 		    otmp->quan > 1L ? " each" : "");
2873. 	}
2874. 	Sprintf(buf, "%s, %s", doname(otmp), price);
2875. 	putstr(tmpwin, 0, buf),  cnt++;
2876.     }
2877.     if (cnt > 1) {
2878. 	display_nhwindow(tmpwin, TRUE);
2879.     } else if (cnt == 1) {
2880. 	cost = get_cost(first_obj, (struct monst *)0);
2881. 	pline("%s, price %ld zorkmid%s%s%s", doname(first_obj),
2882. 		cost, plur(cost), first_obj->quan > 1L ? " each" : "",
2883. 		shk_embellish(first_obj, cost));
2884.     }
2885.     destroy_nhwindow(tmpwin);
2886. }
2887. 
2888. static const char *
2889. shk_embellish(itm, cost)
2890. register struct obj *itm;
2891. long cost;
2892. {
2893.     if (!rn2(3)) {
2894. 	register int o, choice = rn2(5);
2895. 	if (choice == 0) choice = (cost < 100L ? 1 : cost < 500L ? 2 : 3);
2896. 	switch (choice) {
2897. 	    case 4:
2898. 		if (cost < 10L) break; else o = itm->oclass;
2899. 		if (o == FOOD_CLASS) return ", gourmets' delight!";
2900. 		if (objects[itm->otyp].oc_name_known
2901. 		    ? objects[itm->otyp].oc_magic
2902. 		    : (o == AMULET_CLASS || o == RING_CLASS   ||
2903. 		       o == WAND_CLASS   || o == POTION_CLASS ||
2904. 		       o == SCROLL_CLASS || o == SPBOOK_CLASS))
2905. 		    return ", painstakingly developed!";
2906. 		return ", superb craftsmanship!";
2907. 	    case 3: return ", finest quality.";
2908. 	    case 2: return ", an excellent choice.";
2909. 	    case 1: return ", a real bargain.";
2910. 	   default: break;
2911. 	}
2912.     } else if (itm->oartifact) {
2913. 	return ", one of a kind!";
2914.     }
2915.     return ".";
2916. }
2917. 
2918. #ifdef KOPS
2919. static void
2920. kops_gone(silent)
2921. register boolean silent;
2922. {
2923. 	register int cnt = 0;
2924. 	register struct monst *mtmp, *mtmp2;
2925. 
2926. 	/* turn off automatic resurrection of kops */
2927. 	allow_kops = FALSE;
2928. 
2929. 	for(mtmp = fmon; mtmp; mtmp = mtmp2) {
2930. 		mtmp2 = mtmp->nmon;
2931. 		if(mtmp->data->mlet == S_KOP) {
2932. 			mongone(mtmp);
2933. 			cnt++;
2934. 		}
2935. 	}
2936. 	if(cnt && !silent)
2937. 		pline("The Kops (disappointed) disappear into thin air.");
2938. 	allow_kops = TRUE;
2939. }
2940. #endif	/* KOPS */
2941. 
2942. static long
2943. cost_per_charge(otmp)
2944. register struct obj *otmp;
2945. {
2946. 	register long tmp = 0L;
2947. 	register struct monst *shkp = shop_keeper(*u.ushops);
2948. 
2949. 	if(!shkp || !inhishop(shkp)) return(0L); /* insurance */
2950. 	tmp = get_cost(otmp, shkp);
2951. 
2952. 	/* The idea is to make the exhaustive use of */
2953. 	/* an unpaid item more expensive than buying */
2954. 	/* it outright.				     */
2955. 	if(otmp->otyp == MAGIC_LAMP) {			 /* 1 */
2956. 		tmp += tmp / 3L;
2957. 	} else if(otmp->otyp == MAGIC_MARKER) {		 /* 70 - 100 */
2958. 		/* no way to determine in advance   */
2959. 		/* how many charges will be wasted. */
2960. 		/* so, arbitrarily, one half of the */
2961. 		/* price per use.		    */
2962. 		tmp /= 2L;
2963. 	} else if(otmp->otyp == BAG_OF_TRICKS ||	 /* 1 - 20 */
2964. 		  otmp->otyp == HORN_OF_PLENTY) {
2965. 		tmp /= 5L;
2966. 	} else if(otmp->otyp == CRYSTAL_BALL ||		 /* 1 - 5 */
2967. 		  otmp->otyp == OIL_LAMP ||		 /* 1 - 10 */
2968. 		  otmp->otyp == BRASS_LANTERN ||
2969. 		 (otmp->otyp >= MAGIC_FLUTE &&
2970. 		  otmp->otyp <= DRUM_OF_EARTHQUAKE) ||	 /* 5 - 9 */
2971. 		  otmp->oclass == WAND_CLASS) {		 /* 3 - 11 */
2972. 		    if (otmp->spe > 1) tmp /= 4L;
2973. 	} else if (otmp->oclass == SPBOOK_CLASS) {
2974. 		    tmp -= tmp / 5L;
2975. 	}
2976. 	return(tmp);
2977. }
2978. 
2979. /* for using charges of unpaid objects */
2980. void
2981. check_unpaid(otmp)
2982. register struct obj *otmp;
2983. {
2984. 	if(!*u.ushops) return;
2985. 
2986. 	if(otmp->oclass != SPBOOK_CLASS && otmp->spe <= 0) return;
2987. 
2988. 	if(otmp->unpaid) {
2989. 		register long tmp = cost_per_charge(otmp);
2990. 		register struct monst *shkp = shop_keeper(*u.ushops);
2991. 
2992. 		if(!shkp || !inhishop(shkp)) return;
2993. 
2994. 		if(otmp->oclass == SPBOOK_CLASS && tmp > 0L)
2995. 		    pline("\"%sYou owe%s %ld zorkmids.\"",
2996. 			rn2(2) ? "This is no free library, cad!  " : "",
2997. 			ESHK(shkp)->debit > 0L ? " additional" : "", tmp);
2998. 		ESHK(shkp)->debit += tmp;
2999. 		exercise(A_WIS, TRUE);		/* you just got info */
3000. 	}
3001. }
3002. 
3003. void
3004. costly_gold(x, y, amount)
3005. register xchar x, y;
3006. register long amount;
3007. {
3008. 	register long delta;
3009. 	register struct monst *shkp;
3010. 	register struct eshk *eshkp;
3011. 
3012. 	if(!costly_spot(x, y)) return;
3013. 	/* shkp now guaranteed to exist by costly_spot() */
3014. 	shkp = shop_keeper(*in_rooms(x, y, SHOPBASE));
3015. 
3016. 	eshkp = ESHK(shkp);
3017. 	if(eshkp->credit >= amount) {
3018. 	    if(eshkp->credit > amount)
3019. 		Your("credit is reduced by %ld zorkmid%s.",
3020. 					amount, plur(amount));
3021. 	    else Your("credit is erased.");
3022. 	    eshkp->credit -= amount;
3023. 	} else {
3024. 	    delta = amount - eshkp->credit;
3025. 	    if(eshkp->credit)
3026. 		Your("credit is erased.");
3027. 	    if(eshkp->debit)
3028. 		Your("debt increases by %ld zorkmid%s.",
3029. 					delta, plur(delta));
3030. 	    else You("owe %s %ld zorkmid%s.",
3031. 				shkname(shkp), delta, plur(delta));
3032. 	    eshkp->debit += delta;
3033. 	    eshkp->loan += delta;
3034. 	    eshkp->credit = 0L;
3035. 	}
3036. }
3037. 
3038. /* used in domove to block diagonal shop-exit */
3039. /* x,y should always be a door */
3040. boolean
3041. block_door(x,y)
3042. register xchar x, y;
3043. {
3044. 	register int roomno = *in_rooms(x, y, SHOPBASE);
3045. 	register struct monst *shkp;
3046. 
3047. 	if(roomno < 0 || !IS_SHOP(roomno)) return(FALSE);
3048. 	if(!IS_DOOR(levl[x][y].typ)) return(FALSE);
3049. 	if(roomno != *u.ushops) return(FALSE);
3050. 
3051. 	if(!(shkp = shop_keeper((char)roomno)) || !inhishop(shkp))
3052. 		return(FALSE);
3053. 
3054. 	if(shkp->mx == ESHK(shkp)->shk.x && shkp->my == ESHK(shkp)->shk.y
3055. 	    /* Actually, the shk should be made to block _any_
3056. 	     * door, including a door the player digs, if the
3057. 	     * shk is within a 'jumping' distance.
3058. 	     */
3059. 	    && ESHK(shkp)->shd.x == x && ESHK(shkp)->shd.y == y
3060. 	    && shkp->mcanmove && !shkp->msleep
3061. 	    && (ESHK(shkp)->debit || ESHK(shkp)->billct ||
3062. 		ESHK(shkp)->robbed)) {
3063. 		pline("%s%s blocks your way!", shkname(shkp),
3064. 				Invis ? " senses your motion and" : "");
3065. 		return(TRUE);
3066. 	}
3067. 	return(FALSE);
3068. }
3069. 
3070. /* used in domove to block diagonal shop-entry */
3071. /* u.ux, u.uy should always be a door */
3072. boolean
3073. block_entry(x,y)
3074. register xchar x, y;
3075. {
3076. 	register xchar sx, sy;
3077. 	register int roomno;
3078. 	register struct monst *shkp;
3079. 
3080. 	if(!(IS_DOOR(levl[u.ux][u.uy].typ) &&
3081. 		levl[u.ux][u.uy].doormask == D_BROKEN)) return(FALSE);
3082. 
3083. 	roomno = *in_rooms(x, y, SHOPBASE);
3084. 	if(roomno < 0 || !IS_SHOP(roomno)) return(FALSE);
3085. 	if(!(shkp = shop_keeper((char)roomno)) || !inhishop(shkp))
3086. 		return(FALSE);
3087. 
3088. 	if(ESHK(shkp)->shd.x != u.ux || ESHK(shkp)->shd.y != u.uy)
3089. 		return(FALSE);
3090. 
3091. 	sx = ESHK(shkp)->shk.x;
3092. 	sy = ESHK(shkp)->shk.y;
3093. 
3094. 	if(shkp->mx == sx && shkp->my == sy
3095. 		&& shkp->mcanmove && !shkp->msleep
3096. 		&& (x == sx-1 || x == sx+1 || y == sy-1 || y == sy+1)
3097. 		&& (Invis || carrying(PICK_AXE))
3098. 	  ) {
3099. 		pline("%s%s blocks your way!", shkname(shkp),
3100. 				Invis ? " senses your motion and" : "");
3101. 		return(TRUE);
3102. 	}
3103. 	return(FALSE);
3104. }
3105. 
3106. #endif /* OVLB */
3107. 
3108. /*shk.c*/

Also on Fandom

Random Wiki