1 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
2 /* hack.shk.c - version 1.0.3 */
3 /* $FreeBSD: src/games/hack/hack.shk.c,v 1.5 1999/11/16 10:26:37 marcel Exp $ */
4 /* $DragonFly: src/games/hack/hack.shk.c,v 1.5 2005/05/22 03:37:05 y0netan1 Exp $ */
9 struct monst
*shopkeeper
= 0;
10 struct obj
*billobjs
= 0;
11 obfree(obj
,merge
) struct obj
*obj
, *merge
; {
14 inshop(){ return(0); }
21 doinvbill(){ return(0); }
23 shkcatch(){ return(0); }
24 shk_move(){ return(0); }
25 replshk(mtmp
,mtmp2
) struct monst
*mtmp
, *mtmp2
; {}
26 char *shkname(){ return(""); }
29 #include "hack.mfndpos.h"
30 #include "def.mkroom.h"
33 #define ESHK(mon) ((struct eshk *)(&(mon->mextra[0])))
34 #define NOTANGRY(mon) mon->mpeaceful
35 #define ANGRY(mon) !NOTANGRY(mon)
37 extern char plname
[], *xname();
38 extern struct obj
*o_on(), *bp_to_obj();
40 /* Descriptor of current shopkeeper. Note that the bill need not be
41 per-shopkeeper, since it is valid only when in a shop. */
42 static struct monst
*shopkeeper
= 0;
43 static struct bill_x
*bill
;
44 static int shlevel
= 0; /* level of this shopkeeper */
45 struct obj
*billobjs
; /* objects on bill with bp->useup */
46 /* only accessed here and by save & restore */
47 static long int total
; /* filled by addupbill() */
48 static long int followmsg
; /* last time of follow message */
51 invariants: obj->unpaid iff onbill(obj) [unless bp->useup]
52 obj->quan <= bp->bquan
56 char shtypes
[] = { /* 8 shoptypes: 7 specialized, 1 mixed */
57 RING_SYM
, WAND_SYM
, WEAPON_SYM
, FOOD_SYM
, SCROLL_SYM
,
58 POTION_SYM
, ARMOR_SYM
, 0
61 static const char *shopnam
[] = {
62 "engagement ring", "walking cane", "antique weapon",
63 "delicatessen", "second hand book", "liquor",
64 "used armor", "assorted antiques"
68 shkname(mtmp
) /* called in do_name.c */
71 return(ESHK(mtmp
)->shknam
);
74 static void setpaid();
76 shkdead(mtmp
) /* called in mon.c */
79 struct eshk
*eshk
= ESHK(mtmp
);
81 if(eshk
->shoplevel
== dlevel
)
82 rooms
[eshk
->shoproom
].rtype
= 0;
83 if(mtmp
== shopkeeper
) {
86 bill
= (struct bill_x
*) -1000; /* dump core when referenced */
91 struct monst
*mtmp
, *mtmp2
;
93 if(mtmp
== shopkeeper
) {
95 bill
= &(ESHK(shopkeeper
)->bill
[0]);
100 setpaid(){ /* caller has checked that shopkeeper exists */
101 /* either we paid or left the shop or he just died */
104 for(obj
= invent
; obj
; obj
= obj
->nobj
)
106 for(obj
= fobj
; obj
; obj
= obj
->nobj
)
108 for(obj
= fcobj
; obj
; obj
= obj
->nobj
)
110 for(mtmp
= fmon
; mtmp
; mtmp
= mtmp
->nmon
)
111 for(obj
= mtmp
->minvent
; obj
; obj
= obj
->nobj
)
113 for(mtmp
= fallen_down
; mtmp
; mtmp
= mtmp
->nmon
)
114 for(obj
= mtmp
->minvent
; obj
; obj
= obj
->nobj
)
116 while(obj
= billobjs
){
117 billobjs
= obj
->nobj
;
120 ESHK(shopkeeper
)->billct
= 0;
124 addupbill(){ /* delivers result in total */
125 /* caller has checked that shopkeeper exists */
126 int ct
= ESHK(shopkeeper
)->billct
;
127 struct bill_x
*bp
= bill
;
130 total
+= bp
->price
* bp
->bquan
;
135 static void findshk(int);
138 int roomno
= inroom(u
.ux
,u
.uy
);
140 /* Did we just leave a shop? */
142 (u
.uinshop
!= roomno
+ 1 || shlevel
!= dlevel
|| !shopkeeper
)) {
144 if(ESHK(shopkeeper
)->billct
) {
145 if(inroom(shopkeeper
->mx
, shopkeeper
->my
)
146 == u
.uinshop
- 1) /* ab@unido */
147 pline("Somehow you escaped the shop without paying!");
149 pline("You stole for a total worth of %ld zorkmids.",
151 ESHK(shopkeeper
)->robbed
+= total
;
153 if((rooms
[ESHK(shopkeeper
)->shoproom
].rtype
== GENERAL
)
155 ESHK(shopkeeper
)->following
= 1;
163 /* Did we just enter a zoo of some kind? */
165 int rt
= rooms
[roomno
].rtype
;
168 pline("Welcome to David's treasure zoo!");
171 pline("It looks rather muddy down here.");
175 pline("Go away! Go away!");
177 pline("You get an uncanny feeling ...");
181 rooms
[roomno
].rtype
= 0;
182 for(mtmp
= fmon
; mtmp
; mtmp
= mtmp
->nmon
)
183 if(rt
!= ZOO
|| !rn2(3))
188 /* Did we just enter a shop? */
189 if(roomno
>= 0 && rooms
[roomno
].rtype
>= 8) {
190 if(shlevel
!= dlevel
|| !shopkeeper
191 || ESHK(shopkeeper
)->shoproom
!= roomno
)
194 rooms
[roomno
].rtype
= 0;
196 } else if(!u
.uinshop
){
197 if(!ESHK(shopkeeper
)->visitct
||
198 strncmp(ESHK(shopkeeper
)->customer
, plname
, PL_NSIZ
)){
200 /* He seems to be new here */
201 ESHK(shopkeeper
)->visitct
= 0;
202 ESHK(shopkeeper
)->following
= 0;
203 (void) strncpy(ESHK(shopkeeper
)->customer
,plname
,PL_NSIZ
);
204 NOTANGRY(shopkeeper
) = 1;
206 if(!ESHK(shopkeeper
)->following
) {
209 pline("Hello %s! Welcome%s to %s's %s shop!",
211 ESHK(shopkeeper
)->visitct
++ ? " again" : "",
213 shopnam
[rooms
[ESHK(shopkeeper
)->shoproom
].rtype
- 8] );
214 box
= carrying(ICE_BOX
);
215 pick
= carrying(PICK_AXE
);
217 if(dochug(shopkeeper
)) {
218 u
.uinshop
= 0; /* he died moving */
221 pline("Will you please leave your %s outside?",
222 (box
&& pick
) ? "box and pick-axe" :
223 box
? "box" : "pick-axe");
226 u
.uinshop
= roomno
+ 1;
237 for(mtmp
= fmon
; mtmp
; mtmp
= mtmp
->nmon
)
238 if(mtmp
->isshk
&& ESHK(mtmp
)->shoproom
== roomno
239 && ESHK(mtmp
)->shoplevel
== dlevel
) {
241 bill
= &(ESHK(shopkeeper
)->bill
[0]);
243 if(ANGRY(shopkeeper
) &&
244 strncmp(ESHK(shopkeeper
)->customer
,plname
,PL_NSIZ
))
245 NOTANGRY(shopkeeper
) = 1;
246 /* billobjs = 0; -- this is wrong if we save in a shop */
247 /* (and it is harmless to have too many things in billobjs) */
252 bill
= (struct bill_x
*) -1000; /* dump core when referenced */
255 static struct bill_x
*
256 onbill(obj
) struct obj
*obj
; {
258 if(!shopkeeper
) return(0);
259 for(bp
= bill
; bp
< &bill
[ESHK(shopkeeper
)->billct
]; bp
++)
260 if(bp
->bo_id
== obj
->o_id
) {
261 if(!obj
->unpaid
) pline("onbill: paid obj on bill?");
264 if(obj
->unpaid
) pline("onbill: unpaid obj not on bill?");
268 /* called with two args on merge */
269 obfree(obj
,merge
) struct obj
*obj
, *merge
; {
270 struct bill_x
*bp
= onbill(obj
);
275 obj
->unpaid
= 0; /* only for doinvbill */
276 obj
->nobj
= billobjs
;
282 /* this used to be a rename */
283 impossible("obfree: not on bill??");
286 /* this was a merger */
287 bpm
->bquan
+= bp
->bquan
;
288 ESHK(shopkeeper
)->billct
--;
289 *bp
= bill
[ESHK(shopkeeper
)->billct
];
300 long robbed
= ESHK(shkp
)->robbed
;
307 if(robbed
< 0) robbed
= 0;
308 ESHK(shkp
)->robbed
= robbed
;
312 static int dopayobj(struct bill_x
*);
322 for(shkp
= fmon
; shkp
; shkp
= shkp
->nmon
)
323 if(shkp
->isshk
&& dist(shkp
->mx
,shkp
->my
) < 3)
325 if(!shkp
&& u
.uinshop
&&
326 inroom(shopkeeper
->mx
,shopkeeper
->my
) == ESHK(shopkeeper
)->shoproom
)
330 pline("There is nobody here to receive your payment.");
333 ltmp
= ESHK(shkp
)->robbed
;
334 if(shkp
!= shopkeeper
&& NOTANGRY(shkp
)) {
336 pline("You do not owe %s anything.", monnam(shkp
));
339 pline("You have no money.");
341 long ugold
= u
.ugold
;
344 pline("You give %s the %ld gold pieces he asked for.",
348 pline("You give %s all your gold.", monnam(shkp
));
352 pline("Unfortunately, he doesn't look satisfied.");
354 ESHK(shkp
)->robbed
= 0;
355 ESHK(shkp
)->following
= 0;
356 if(ESHK(shkp
)->shoplevel
!= dlevel
) {
357 /* For convenience's sake, let him disappear */
358 shkp
->minvent
= 0; /* %% */
367 if(!ESHK(shkp
)->billct
){
368 pline("You do not owe %s anything.", monnam(shkp
));
370 pline("Moreover, you have no money.");
373 if(ESHK(shkp
)->robbed
){
374 #define min(a,b) ((a<b)?a:b)
375 pline("But since his shop has been robbed recently,");
376 pline("you %srepay %s's expenses.",
377 (u
.ugold
< ESHK(shkp
)->robbed
) ? "partially " : "",
379 pay(min(u
.ugold
, ESHK(shkp
)->robbed
), shkp
);
380 ESHK(shkp
)->robbed
= 0;
384 pline("But in order to appease %s,",
385 amonnam(shkp
, "angry"));
388 pline(" you give him 1000 gold pieces.");
391 pline(" you give him all your money.");
394 if(strncmp(ESHK(shkp
)->customer
, plname
, PL_NSIZ
)
396 pline("%s calms down.", Monnam(shkp
));
398 } else pline("%s is as angry as ever.",
403 if(shkp
!= shopkeeper
) {
404 impossible("dopay: not to shopkeeper?");
405 if(shopkeeper
) setpaid();
408 for(pass
= 0; pass
<= 1; pass
++) {
410 while(tmp
< ESHK(shopkeeper
)->billct
) {
412 if(!pass
&& !bp
->useup
) {
416 if(!dopayobj(bp
)) return(1);
417 bill
[tmp
] = bill
[--ESHK(shopkeeper
)->billct
];
420 pline("Thank you for shopping in %s's %s store!",
422 shopnam
[rooms
[ESHK(shopkeeper
)->shoproom
].rtype
- 8]);
423 NOTANGRY(shopkeeper
) = 1;
427 /* return 1 if paid successfully */
428 /* 0 if not enough money */
429 /* -1 if object could not be found (but was paid) */
431 dopayobj(bp
) struct bill_x
*bp
; {
435 /* find the object on one of the lists */
439 impossible("Shopkeeper administration out of order.");
440 setpaid(); /* be nice to the player */
444 if(!obj
->unpaid
&& !bp
->useup
){
445 impossible("Paid object on bill??");
449 ltmp
= bp
->price
* bp
->bquan
;
450 if(ANGRY(shopkeeper
)) ltmp
+= ltmp
/3;
452 pline("You don't have gold enough to pay %s.",
457 pay(ltmp
, shopkeeper
);
458 pline("You bought %s for %ld gold piece%s.",
459 doname(obj
), ltmp
, plur(ltmp
));
461 struct obj
*otmp
= billobjs
;
463 billobjs
= obj
->nobj
;
465 while(otmp
&& otmp
->nobj
!= obj
) otmp
= otmp
->nobj
;
466 if(otmp
) otmp
->nobj
= obj
->nobj
;
467 else pline("Error in shopkeeper administration.");
474 /* routine called after dying (or quitting) with nonempty bill */
476 if(shlevel
== dlevel
&& shopkeeper
&& ESHK(shopkeeper
)->billct
){
479 shopkeeper
->mgold
+= u
.ugold
;
481 pline("%s comes and takes all your possessions.",
485 shopkeeper
->mgold
+= total
;
486 pline("%s comes and takes the %ld zorkmids you owed him.",
487 Monnam(shopkeeper
), total
);
489 setpaid(); /* in case we create bones */
493 /* find obj on one of the lists */
500 unsigned id
= bp
->bo_id
;
503 obj
= o_on(id
, billobjs
);
504 else if(!(obj
= o_on(id
, invent
)) &&
505 !(obj
= o_on(id
, fobj
)) &&
506 !(obj
= o_on(id
, fcobj
))) {
507 for(mtmp
= fmon
; mtmp
; mtmp
= mtmp
->nmon
)
508 if(obj
= o_on(id
, mtmp
->minvent
))
510 for(mtmp
= fallen_down
; mtmp
; mtmp
= mtmp
->nmon
)
511 if(obj
= o_on(id
, mtmp
->minvent
))
517 static int getprice();
519 /* called in hack.c when we pickup an object */
520 addtobill(obj
) struct obj
*obj
; {
523 (u
.ux
== ESHK(shopkeeper
)->shk
.x
&& u
.uy
== ESHK(shopkeeper
)->shk
.y
) ||
524 (u
.ux
== ESHK(shopkeeper
)->shd
.x
&& u
.uy
== ESHK(shopkeeper
)->shd
.y
) ||
525 onbill(obj
) /* perhaps we threw it away earlier */
527 if(ESHK(shopkeeper
)->billct
== BILLSZ
){
528 pline("You got that for free!");
531 bp
= &bill
[ESHK(shopkeeper
)->billct
];
532 bp
->bo_id
= obj
->o_id
;
533 bp
->bquan
= obj
->quan
;
535 bp
->price
= getprice(obj
);
536 ESHK(shopkeeper
)->billct
++;
540 splitbill(obj
,otmp
) struct obj
*obj
, *otmp
; {
541 /* otmp has been split off from obj */
546 impossible("splitbill: not on bill?");
549 if(bp
->bquan
< otmp
->quan
) {
550 impossible("Negative quantity on bill??");
552 if(bp
->bquan
== otmp
->quan
) {
553 impossible("Zero quantity on bill??");
555 bp
->bquan
-= otmp
->quan
;
557 /* addtobill(otmp); */
558 if(ESHK(shopkeeper
)->billct
== BILLSZ
) otmp
->unpaid
= 0;
561 bp
= &bill
[ESHK(shopkeeper
)->billct
];
562 bp
->bo_id
= otmp
->o_id
;
563 bp
->bquan
= otmp
->quan
;
566 ESHK(shopkeeper
)->billct
++;
570 subfrombill(obj
) struct obj
*obj
; {
575 if(!inshop() || (u
.ux
== ESHK(shopkeeper
)->shk
.x
&& u
.uy
== ESHK(shopkeeper
)->shk
.y
) ||
576 (u
.ux
== ESHK(shopkeeper
)->shd
.x
&& u
.uy
== ESHK(shopkeeper
)->shd
.y
))
578 if((bp
= onbill(obj
)) != 0){
580 if(bp
->bquan
> obj
->quan
){
583 bp
->bo_id
= otmp
->o_id
= flags
.ident
++;
584 otmp
->quan
= (bp
->bquan
-= obj
->quan
);
585 otmp
->owt
= 0; /* superfluous */
588 otmp
->nobj
= billobjs
;
592 ESHK(shopkeeper
)->billct
--;
593 *bp
= bill
[ESHK(shopkeeper
)->billct
];
597 pline("%s didn't notice.", Monnam(shopkeeper
));
601 /* he dropped something of his own - probably wants to sell it */
602 if(shopkeeper
->msleep
|| shopkeeper
->mfroz
||
603 inroom(shopkeeper
->mx
,shopkeeper
->my
) != ESHK(shopkeeper
)->shoproom
)
605 if(ESHK(shopkeeper
)->billct
== BILLSZ
||
606 ((tmp
= shtypes
[rooms
[ESHK(shopkeeper
)->shoproom
].rtype
-8]) && tmp
!= obj
->olet
)
607 || index("_0", obj
->olet
)) {
608 pline("%s seems not interested.", Monnam(shopkeeper
));
611 ltmp
= getprice(obj
) * obj
->quan
;
612 if(ANGRY(shopkeeper
)) {
614 NOTANGRY(shopkeeper
) = 1;
616 if(ESHK(shopkeeper
)->robbed
){
617 if((ESHK(shopkeeper
)->robbed
-= ltmp
) < 0)
618 ESHK(shopkeeper
)->robbed
= 0;
619 pline("Thank you for your contribution to restock this recently plundered shop.");
622 if(ltmp
> shopkeeper
->mgold
)
623 ltmp
= shopkeeper
->mgold
;
624 pay(-ltmp
, shopkeeper
);
626 pline("%s gladly accepts %s but cannot pay you at present.",
627 Monnam(shopkeeper
), doname(obj
));
629 pline("You sold %s and got %ld gold piece%s.", doname(obj
), ltmp
,
634 int mode
; /* 0: deliver count 1: paged */
638 long totused
, thisused
;
645 for(bp
= bill
; bp
- bill
< ESHK(shopkeeper
)->billct
; bp
++)
647 ((obj
= bp_to_obj(bp
)) && obj
->quan
< bp
->bquan
))
653 impossible("doinvbill: no shopkeeper?");
658 if(page_line("Unpaid articles already used up:") || page_line(""))
662 for(bp
= bill
; bp
- bill
< ESHK(shopkeeper
)->billct
; bp
++) {
665 impossible("Bad shopkeeper administration.");
668 if(bp
->useup
|| bp
->bquan
> obj
->quan
) {
669 int cnt
, oquan
, uquan
;
672 uquan
= (bp
->useup
? bp
->bquan
: bp
->bquan
- oquan
);
673 thisused
= bp
->price
* uquan
;
675 obj
->quan
= uquan
; /* cheat doname */
676 (void) sprintf(buf
, "x - %s", doname(obj
));
677 obj
->quan
= oquan
; /* restore value */
678 for(cnt
= 0; buf
[cnt
]; cnt
++);
681 (void) sprintf(&buf
[cnt
], " %5ld zorkmids", thisused
);
686 (void) sprintf(buf
, "Total:%50ld zorkmids", totused
);
687 if(page_line("") || page_line(buf
))
696 static int realhunger(void);
699 getprice(obj
) struct obj
*obj
; {
706 tmp
= 10*rnd((obj
->otyp
== EXPENSIVE_CAMERA
) ? 150 : 30);
717 if(obj
->otyp
== SCR_MAIL
)
725 tmp
= 10*rnd(5 + (2000/realhunger()));
732 if(ac
<= -10) /* probably impossible */
734 tmp
= 100 + ac
*ac
*rnd(10+ac
);
737 if(obj
->otyp
< BOOMERANG
)
739 else if(obj
->otyp
== LONG_SWORD
||
740 obj
->otyp
== TWO_HANDED_SWORD
)
742 else tmp
= 10*rnd(75);
745 pline("Strange ..., carrying a chain?");
756 realhunger(){ /* not completely foolproof */
758 struct obj
*otmp
= invent
;
760 if(otmp
->olet
== FOOD_SYM
&& !otmp
->unpaid
)
761 tmp
+= objects
[otmp
->otyp
].nutrition
;
764 return((tmp
<= 0) ? 1 : tmp
);
770 struct monst
*shkp
= shopkeeper
;
772 if(u
.uinshop
&& shkp
&& !shkp
->mfroz
&& !shkp
->msleep
&&
774 inroom(u
.ux
+u
.dx
, u
.uy
+u
.dy
) + 1 == u
.uinshop
&&
775 shkp
->mx
== ESHK(shkp
)->shk
.x
&& shkp
->my
== ESHK(shkp
)->shk
.y
&&
776 u
.ux
== ESHK(shkp
)->shd
.x
&& u
.uy
== ESHK(shkp
)->shd
.y
) {
777 pline("%s nimbly catches the %s.", Monnam(shkp
), xname(obj
));
778 obj
->nobj
= shkp
->minvent
;
786 * shk_move: return 1: he moved 0: he didnt -1: let m_move do it
792 struct permonst
*mdat
= shkp
->data
;
793 xchar gx
,gy
,omx
,omy
,nx
,ny
,nix
,niy
;
797 schar shkroom
,chi
,chcnt
,cnt
;
798 boolean uondoor
, satdoor
, avoid
, badinv
;
806 if((udist
= dist(omx
,omy
)) < 3) {
808 (void) hitu(shkp
, d(mdat
->damn
, mdat
->damd
)+1);
811 if(ESHK(shkp
)->following
) {
812 if(strncmp(ESHK(shkp
)->customer
, plname
, PL_NSIZ
)){
813 pline("Hello %s! I was looking for %s.",
814 plname
, ESHK(shkp
)->customer
);
815 ESHK(shkp
)->following
= 0;
818 if(!ESHK(shkp
)->robbed
) { /* impossible? */
819 ESHK(shkp
)->following
= 0;
822 if(moves
> followmsg
+4) {
823 pline("Hello %s! Didn't you forget to pay?",
832 shkroom
= inroom(omx
,omy
);
834 gx
= ESHK(shkp
)->shk
.x
;
835 gy
= ESHK(shkp
)->shk
.y
;
836 satdoor
= (gx
== omx
&& gy
== omy
);
837 if(ESHK(shkp
)->following
|| ((z
= holetime()) >= 0 && z
*z
<= udist
)){
840 if(shkroom
< 0 || shkroom
!= inroom(u
.ux
,u
.uy
))
842 return(-1); /* leave it to m_move */
843 } else if(ANGRY(shkp
)) {
844 long saveBlind
= Blind
;
846 if(shkp
->mcansee
&& !Invis
&& cansee(omx
,omy
)) {
853 #define GDIST(x,y) ((x-gx)*(x-gx)+(y-gy)*(y-gy))
857 uondoor
= (u
.ux
== ESHK(shkp
)->shd
.x
&&
858 u
.uy
== ESHK(shkp
)->shd
.y
);
860 if(ESHK(shkp
)->billct
)
861 pline("Hello %s! Will you please pay before leaving?",
863 badinv
= (carrying(PICK_AXE
) || carrying(ICE_BOX
));
864 if(satdoor
&& badinv
)
868 avoid
= (u
.uinshop
&& dist(gx
,gy
) > 8);
872 if(((!ESHK(shkp
)->robbed
&& !ESHK(shkp
)->billct
) || avoid
)
873 && GDIST(omx
,omy
) < 3){
874 if(!badinv
&& !online(omx
,omy
))
881 if(omx
== gx
&& omy
== gy
)
889 cnt
= mfndpos(shkp
,poss
,info
,ALLOW_SSM
);
890 if(avoid
&& uondoor
) { /* perhaps we cannot avoid him */
892 if(!(info
[i
] & NOTONL
)) goto notonl_ok
;
899 for(i
=0; i
<cnt
; i
++){
902 if(levl
[nx
][ny
].typ
== ROOM
903 || shkroom
!= ESHK(shkp
)->shoproom
904 || ESHK(shkp
)->following
) {
906 /* cater for stupid compilers */
909 if(uondoor
&& (ib
= sobj_at(ICE_BOX
, nx
, ny
))) {
910 nix
= nx
; niy
= ny
; chi
= i
; break;
912 if(avoid
&& (info
[i
] & NOTONL
))
914 if((!appr
&& !rn2(++chcnt
)) ||
916 (appr
&& (zz
= GDIST(nix
,niy
)) && zz
> GDIST(nx
,ny
))
918 (appr
&& GDIST(nx
,ny
) < GDIST(nix
,niy
))
927 if(nix
!= omx
|| niy
!= omy
){
928 if(info
[chi
] & ALLOW_M
){
929 mtmp
= m_at(nix
,niy
);
930 if(hitmm(shkp
,mtmp
) == 1 && rn2(3) &&
931 hitmm(mtmp
,shkp
) == 2) return(2);
933 } else if(info
[chi
] & ALLOW_U
){
934 (void) hitu(shkp
, d(mdat
->damn
, mdat
->damd
)+1);
949 /* He is digging in the shop. */
954 if(u
.utraptype
== TT_PIT
)
955 pline("\"Be careful, sir, or you might fall through the floor.\"");
957 pline("\"Please, do not damage the floor here.\"");
958 } else if(dist(shopkeeper
->mx
, shopkeeper
->my
) < 3) {
959 struct obj
*obj
, *obj2
;
961 pline("%s grabs your backpack!", shkname(shopkeeper
));
962 for(obj
= invent
; obj
; obj
= obj2
) {
964 if(obj
->owornmask
) continue;
966 obj
->nobj
= shopkeeper
->minvent
;
967 shopkeeper
->minvent
= obj
;
976 return(x
==u
.ux
|| y
==u
.uy
||
977 (x
-u
.ux
)*(x
-u
.ux
) == (y
-u
.uy
)*(y
-u
.uy
));
980 /* Does this monster follow me downstairs? */
984 return( mtmp
->mtame
|| index("1TVWZi&, ", mtmp
->data
->mlet
)
986 || (mtmp
->isshk
&& ESHK(mtmp
)->following
)