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.6 2006/08/21 19:45:32 pavalos Exp $ */
9 struct monst
*shopkeeper
= 0;
10 struct obj
*billobjs
= 0;
13 obfree(struct obj
*obj
, struct obj
*merge
)
79 replshk(struct monst
*mtmp
, struct monst
*mtmp2
)
90 #include "hack.mfndpos.h"
93 #define ESHK(mon) ((struct eshk *)(&(mon->mextra[0])))
94 #define NOTANGRY(mon) mon->mpeaceful
95 #define ANGRY(mon) !NOTANGRY(mon)
97 /* Descriptor of current shopkeeper. Note that the bill need not be
98 per-shopkeeper, since it is valid only when in a shop. */
99 static struct monst
*shopkeeper
= 0;
100 static struct bill_x
*bill
;
101 static int shlevel
= 0; /* level of this shopkeeper */
102 struct obj
*billobjs
; /* objects on bill with bp->useup */
103 /* only accessed here and by save & restore */
104 static long int total
; /* filled by addupbill() */
105 static long int followmsg
; /* last time of follow message */
108 invariants: obj->unpaid iff onbill(obj) [unless bp->useup]
109 obj->quan <= bp->bquan
113 char shtypes
[] = { /* 8 shoptypes: 7 specialized, 1 mixed */
114 RING_SYM
, WAND_SYM
, WEAPON_SYM
, FOOD_SYM
, SCROLL_SYM
,
115 POTION_SYM
, ARMOR_SYM
, 0
118 static const char *shopnam
[] = {
119 "engagement ring", "walking cane", "antique weapon",
120 "delicatessen", "second hand book", "liquor",
121 "used armor", "assorted antiques"
124 static void setpaid(void);
125 static void addupbill(void);
126 static void findshk(int);
127 static struct bill_x
*onbill(struct obj
*);
128 static void pay(long, struct monst
*);
129 static int dopayobj(struct bill_x
*);
130 static struct obj
*bp_to_obj(struct bill_x
*);
131 static int getprice(struct obj
*);
132 static int realhunger(void);
135 shkname(struct monst
*mtmp
) /* called in do_name.c */
137 return(ESHK(mtmp
)->shknam
);
141 shkdead(struct monst
*mtmp
) /* called in mon.c */
143 struct eshk
*eshk
= ESHK(mtmp
);
145 if(eshk
->shoplevel
== dlevel
)
146 rooms
[eshk
->shoproom
].rtype
= 0;
147 if(mtmp
== shopkeeper
) {
150 bill
= (struct bill_x
*) -1000; /* dump core when referenced */
155 replshk(struct monst
*mtmp
, struct monst
*mtmp2
)
157 if(mtmp
== shopkeeper
) {
159 bill
= &(ESHK(shopkeeper
)->bill
[0]);
164 setpaid(void) /* caller has checked that shopkeeper exists */
165 /* either we paid or left the shop or he just died */
169 for(obj
= invent
; obj
; obj
= obj
->nobj
)
171 for(obj
= fobj
; obj
; obj
= obj
->nobj
)
173 for(obj
= fcobj
; obj
; obj
= obj
->nobj
)
175 for(mtmp
= fmon
; mtmp
; mtmp
= mtmp
->nmon
)
176 for(obj
= mtmp
->minvent
; obj
; obj
= obj
->nobj
)
178 for(mtmp
= fallen_down
; mtmp
; mtmp
= mtmp
->nmon
)
179 for(obj
= mtmp
->minvent
; obj
; obj
= obj
->nobj
)
181 while((obj
= billobjs
)){
182 billobjs
= obj
->nobj
;
185 ESHK(shopkeeper
)->billct
= 0;
189 addupbill(void) /* delivers result in total */
190 /* caller has checked that shopkeeper exists */
192 int ct
= ESHK(shopkeeper
)->billct
;
193 struct bill_x
*bp
= bill
;
196 total
+= bp
->price
* bp
->bquan
;
204 int roomno
= inroom(u
.ux
,u
.uy
);
206 /* Did we just leave a shop? */
208 (u
.uinshop
!= roomno
+ 1 || shlevel
!= dlevel
|| !shopkeeper
)) {
210 if(ESHK(shopkeeper
)->billct
) {
211 if(inroom(shopkeeper
->mx
, shopkeeper
->my
)
212 == u
.uinshop
- 1) /* ab@unido */
213 pline("Somehow you escaped the shop without paying!");
215 pline("You stole for a total worth of %ld zorkmids.",
217 ESHK(shopkeeper
)->robbed
+= total
;
219 if((rooms
[ESHK(shopkeeper
)->shoproom
].rtype
== GENERAL
)
221 ESHK(shopkeeper
)->following
= 1;
229 /* Did we just enter a zoo of some kind? */
231 int rt
= rooms
[roomno
].rtype
;
234 pline("Welcome to David's treasure zoo!");
237 pline("It looks rather muddy down here.");
241 pline("Go away! Go away!");
243 pline("You get an uncanny feeling ...");
247 rooms
[roomno
].rtype
= 0;
248 for(mtmp
= fmon
; mtmp
; mtmp
= mtmp
->nmon
)
249 if(rt
!= ZOO
|| !rn2(3))
254 /* Did we just enter a shop? */
255 if(roomno
>= 0 && rooms
[roomno
].rtype
>= 8) {
256 if(shlevel
!= dlevel
|| !shopkeeper
257 || ESHK(shopkeeper
)->shoproom
!= roomno
)
260 rooms
[roomno
].rtype
= 0;
262 } else if(!u
.uinshop
){
263 if(!ESHK(shopkeeper
)->visitct
||
264 strncmp(ESHK(shopkeeper
)->customer
, plname
, PL_NSIZ
)){
266 /* He seems to be new here */
267 ESHK(shopkeeper
)->visitct
= 0;
268 ESHK(shopkeeper
)->following
= 0;
269 strncpy(ESHK(shopkeeper
)->customer
,plname
,PL_NSIZ
);
270 NOTANGRY(shopkeeper
) = 1;
272 if(!ESHK(shopkeeper
)->following
) {
275 pline("Hello %s! Welcome%s to %s's %s shop!",
277 ESHK(shopkeeper
)->visitct
++ ? " again" : "",
279 shopnam
[rooms
[ESHK(shopkeeper
)->shoproom
].rtype
- 8] );
280 box
= carrying(ICE_BOX
);
281 pick
= carrying(PICK_AXE
);
283 if(dochug(shopkeeper
)) {
284 u
.uinshop
= 0; /* he died moving */
287 pline("Will you please leave your %s outside?",
288 (box
&& pick
) ? "box and pick-axe" :
289 box
? "box" : "pick-axe");
292 u
.uinshop
= roomno
+ 1;
302 for(mtmp
= fmon
; mtmp
; mtmp
= mtmp
->nmon
)
303 if(mtmp
->isshk
&& ESHK(mtmp
)->shoproom
== roomno
304 && ESHK(mtmp
)->shoplevel
== dlevel
) {
306 bill
= &(ESHK(shopkeeper
)->bill
[0]);
308 if(ANGRY(shopkeeper
) &&
309 strncmp(ESHK(shopkeeper
)->customer
,plname
,PL_NSIZ
))
310 NOTANGRY(shopkeeper
) = 1;
311 /* billobjs = 0; -- this is wrong if we save in a shop */
312 /* (and it is harmless to have too many things in billobjs) */
317 bill
= (struct bill_x
*) -1000; /* dump core when referenced */
320 static struct bill_x
*
321 onbill(struct obj
*obj
)
324 if(!shopkeeper
) return(0);
325 for(bp
= bill
; bp
< &bill
[ESHK(shopkeeper
)->billct
]; bp
++)
326 if(bp
->bo_id
== obj
->o_id
) {
327 if(!obj
->unpaid
) pline("onbill: paid obj on bill?");
330 if(obj
->unpaid
) pline("onbill: unpaid obj not on bill?");
334 /* called with two args on merge */
336 obfree(struct obj
*obj
, struct obj
*merge
)
338 struct bill_x
*bp
= onbill(obj
);
343 obj
->unpaid
= 0; /* only for doinvbill */
344 obj
->nobj
= billobjs
;
350 /* this used to be a rename */
351 impossible("obfree: not on bill??");
354 /* this was a merger */
355 bpm
->bquan
+= bp
->bquan
;
356 ESHK(shopkeeper
)->billct
--;
357 *bp
= bill
[ESHK(shopkeeper
)->billct
];
364 pay(long tmp
, struct monst
*shkp
)
366 long robbed
= ESHK(shkp
)->robbed
;
373 if(robbed
< 0) robbed
= 0;
374 ESHK(shkp
)->robbed
= robbed
;
388 for(shkp
= fmon
; shkp
; shkp
= shkp
->nmon
)
389 if(shkp
->isshk
&& dist(shkp
->mx
,shkp
->my
) < 3)
391 if(!shkp
&& u
.uinshop
&&
392 inroom(shopkeeper
->mx
,shopkeeper
->my
) == ESHK(shopkeeper
)->shoproom
)
396 pline("There is nobody here to receive your payment.");
399 ltmp
= ESHK(shkp
)->robbed
;
400 if(shkp
!= shopkeeper
&& NOTANGRY(shkp
)) {
402 pline("You do not owe %s anything.", monnam(shkp
));
405 pline("You have no money.");
407 long ugold
= u
.ugold
;
410 pline("You give %s the %ld gold pieces he asked for.",
414 pline("You give %s all your gold.", monnam(shkp
));
418 pline("Unfortunately, he doesn't look satisfied.");
420 ESHK(shkp
)->robbed
= 0;
421 ESHK(shkp
)->following
= 0;
422 if(ESHK(shkp
)->shoplevel
!= dlevel
) {
423 /* For convenience's sake, let him disappear */
424 shkp
->minvent
= 0; /* %% */
433 if(!ESHK(shkp
)->billct
){
434 pline("You do not owe %s anything.", monnam(shkp
));
436 pline("Moreover, you have no money.");
439 if(ESHK(shkp
)->robbed
){
440 #define min(a,b) ((a<b)?a:b)
441 pline("But since his shop has been robbed recently,");
442 pline("you %srepay %s's expenses.",
443 (u
.ugold
< ESHK(shkp
)->robbed
) ? "partially " : "",
445 pay(min(u
.ugold
, ESHK(shkp
)->robbed
), shkp
);
446 ESHK(shkp
)->robbed
= 0;
450 pline("But in order to appease %s,",
451 amonnam(shkp
, "angry"));
454 pline(" you give him 1000 gold pieces.");
457 pline(" you give him all your money.");
460 if(strncmp(ESHK(shkp
)->customer
, plname
, PL_NSIZ
)
462 pline("%s calms down.", Monnam(shkp
));
464 } else pline("%s is as angry as ever.",
469 if(shkp
!= shopkeeper
) {
470 impossible("dopay: not to shopkeeper?");
471 if(shopkeeper
) setpaid();
474 for(pass
= 0; pass
<= 1; pass
++) {
476 while(tmp
< ESHK(shopkeeper
)->billct
) {
478 if(!pass
&& !bp
->useup
) {
482 if(!dopayobj(bp
)) return(1);
483 bill
[tmp
] = bill
[--ESHK(shopkeeper
)->billct
];
486 pline("Thank you for shopping in %s's %s store!",
488 shopnam
[rooms
[ESHK(shopkeeper
)->shoproom
].rtype
- 8]);
489 NOTANGRY(shopkeeper
) = 1;
493 /* return 1 if paid successfully */
494 /* 0 if not enough money */
495 /* -1 if object could not be found (but was paid) */
497 dopayobj(struct bill_x
*bp
)
502 /* find the object on one of the lists */
506 impossible("Shopkeeper administration out of order.");
507 setpaid(); /* be nice to the player */
511 if(!obj
->unpaid
&& !bp
->useup
){
512 impossible("Paid object on bill??");
516 ltmp
= bp
->price
* bp
->bquan
;
517 if(ANGRY(shopkeeper
)) ltmp
+= ltmp
/3;
519 pline("You don't have gold enough to pay %s.",
524 pay(ltmp
, shopkeeper
);
525 pline("You bought %s for %ld gold piece%s.",
526 doname(obj
), ltmp
, plur(ltmp
));
528 struct obj
*otmp
= billobjs
;
530 billobjs
= obj
->nobj
;
532 while(otmp
&& otmp
->nobj
!= obj
) otmp
= otmp
->nobj
;
533 if(otmp
) otmp
->nobj
= obj
->nobj
;
534 else pline("Error in shopkeeper administration.");
541 /* routine called after dying (or quitting) with nonempty bill */
545 if(shlevel
== dlevel
&& shopkeeper
&& ESHK(shopkeeper
)->billct
){
548 shopkeeper
->mgold
+= u
.ugold
;
550 pline("%s comes and takes all your possessions.",
554 shopkeeper
->mgold
+= total
;
555 pline("%s comes and takes the %ld zorkmids you owed him.",
556 Monnam(shopkeeper
), total
);
558 setpaid(); /* in case we create bones */
562 /* find obj on one of the lists */
564 bp_to_obj(struct bill_x
*bp
)
568 unsigned id
= bp
->bo_id
;
571 obj
= o_on(id
, billobjs
);
572 else if(!(obj
= o_on(id
, invent
)) &&
573 !(obj
= o_on(id
, fobj
)) &&
574 !(obj
= o_on(id
, fcobj
))) {
575 for(mtmp
= fmon
; mtmp
; mtmp
= mtmp
->nmon
)
576 if((obj
= o_on(id
, mtmp
->minvent
)))
578 for(mtmp
= fallen_down
; mtmp
; mtmp
= mtmp
->nmon
)
579 if((obj
= o_on(id
, mtmp
->minvent
)))
585 /* called in hack.c when we pickup an object */
587 addtobill(struct obj
*obj
)
591 (u
.ux
== ESHK(shopkeeper
)->shk
.x
&& u
.uy
== ESHK(shopkeeper
)->shk
.y
) ||
592 (u
.ux
== ESHK(shopkeeper
)->shd
.x
&& u
.uy
== ESHK(shopkeeper
)->shd
.y
) ||
593 onbill(obj
) /* perhaps we threw it away earlier */
595 if(ESHK(shopkeeper
)->billct
== BILLSZ
){
596 pline("You got that for free!");
599 bp
= &bill
[ESHK(shopkeeper
)->billct
];
600 bp
->bo_id
= obj
->o_id
;
601 bp
->bquan
= obj
->quan
;
603 bp
->price
= getprice(obj
);
604 ESHK(shopkeeper
)->billct
++;
609 splitbill(struct obj
*obj
, struct obj
*otmp
)
611 /* otmp has been split off from obj */
616 impossible("splitbill: not on bill?");
619 if(bp
->bquan
< otmp
->quan
) {
620 impossible("Negative quantity on bill??");
622 if(bp
->bquan
== otmp
->quan
) {
623 impossible("Zero quantity on bill??");
625 bp
->bquan
-= otmp
->quan
;
627 if(ESHK(shopkeeper
)->billct
== BILLSZ
) otmp
->unpaid
= 0;
630 bp
= &bill
[ESHK(shopkeeper
)->billct
];
631 bp
->bo_id
= otmp
->o_id
;
632 bp
->bquan
= otmp
->quan
;
635 ESHK(shopkeeper
)->billct
++;
640 subfrombill(struct obj
*obj
)
646 if(!inshop() || (u
.ux
== ESHK(shopkeeper
)->shk
.x
&& u
.uy
== ESHK(shopkeeper
)->shk
.y
) ||
647 (u
.ux
== ESHK(shopkeeper
)->shd
.x
&& u
.uy
== ESHK(shopkeeper
)->shd
.y
))
649 if((bp
= onbill(obj
)) != 0){
651 if(bp
->bquan
> obj
->quan
){
654 bp
->bo_id
= otmp
->o_id
= flags
.ident
++;
655 otmp
->quan
= (bp
->bquan
-= obj
->quan
);
656 otmp
->owt
= 0; /* superfluous */
659 otmp
->nobj
= billobjs
;
663 ESHK(shopkeeper
)->billct
--;
664 *bp
= bill
[ESHK(shopkeeper
)->billct
];
668 pline("%s didn't notice.", Monnam(shopkeeper
));
672 /* he dropped something of his own - probably wants to sell it */
673 if(shopkeeper
->msleep
|| shopkeeper
->mfroz
||
674 inroom(shopkeeper
->mx
,shopkeeper
->my
) != ESHK(shopkeeper
)->shoproom
)
676 if(ESHK(shopkeeper
)->billct
== BILLSZ
||
677 ((tmp
= shtypes
[rooms
[ESHK(shopkeeper
)->shoproom
].rtype
-8]) && tmp
!= obj
->olet
)
678 || index("_0", obj
->olet
)) {
679 pline("%s seems not interested.", Monnam(shopkeeper
));
682 ltmp
= getprice(obj
) * obj
->quan
;
683 if(ANGRY(shopkeeper
)) {
685 NOTANGRY(shopkeeper
) = 1;
687 if(ESHK(shopkeeper
)->robbed
){
688 if((ESHK(shopkeeper
)->robbed
-= ltmp
) < 0)
689 ESHK(shopkeeper
)->robbed
= 0;
690 pline("Thank you for your contribution to restock this recently plundered shop.");
693 if(ltmp
> shopkeeper
->mgold
)
694 ltmp
= shopkeeper
->mgold
;
695 pay(-ltmp
, shopkeeper
);
697 pline("%s gladly accepts %s but cannot pay you at present.",
698 Monnam(shopkeeper
), doname(obj
));
700 pline("You sold %s and got %ld gold piece%s.", doname(obj
), ltmp
,
705 doinvbill(int mode
) /* 0: deliver count 1: paged */
709 long totused
, thisused
;
716 for(bp
= bill
; bp
- bill
< ESHK(shopkeeper
)->billct
; bp
++)
718 ((obj
= bp_to_obj(bp
)) && obj
->quan
< bp
->bquan
))
724 impossible("doinvbill: no shopkeeper?");
729 if(page_line("Unpaid articles already used up:") || page_line(""))
733 for(bp
= bill
; bp
- bill
< ESHK(shopkeeper
)->billct
; bp
++) {
736 impossible("Bad shopkeeper administration.");
739 if(bp
->useup
|| bp
->bquan
> obj
->quan
) {
740 int cnt
, oquan
, uquan
;
743 uquan
= (bp
->useup
? bp
->bquan
: bp
->bquan
- oquan
);
744 thisused
= bp
->price
* uquan
;
746 obj
->quan
= uquan
; /* cheat doname */
747 sprintf(buf
, "x - %s", doname(obj
));
748 obj
->quan
= oquan
; /* restore value */
749 for(cnt
= 0; buf
[cnt
]; cnt
++);
752 sprintf(&buf
[cnt
], " %5ld zorkmids", thisused
);
757 sprintf(buf
, "Total:%50ld zorkmids", totused
);
758 if(page_line("") || page_line(buf
))
769 getprice(struct obj
*obj
)
777 tmp
= 10*rnd((obj
->otyp
== EXPENSIVE_CAMERA
) ? 150 : 30);
788 if(obj
->otyp
== SCR_MAIL
)
796 tmp
= 10*rnd(5 + (2000/realhunger()));
803 if(ac
<= -10) /* probably impossible */
805 tmp
= 100 + ac
*ac
*rnd(10+ac
);
808 if(obj
->otyp
< BOOMERANG
)
810 else if(obj
->otyp
== LONG_SWORD
||
811 obj
->otyp
== TWO_HANDED_SWORD
)
813 else tmp
= 10*rnd(75);
816 pline("Strange ..., carrying a chain?");
827 realhunger(void) /* not completely foolproof */
830 struct obj
*otmp
= invent
;
832 if(otmp
->olet
== FOOD_SYM
&& !otmp
->unpaid
)
833 tmp
+= objects
[otmp
->otyp
].nutrition
;
836 return((tmp
<= 0) ? 1 : tmp
);
840 shkcatch(struct obj
*obj
)
842 struct monst
*shkp
= shopkeeper
;
844 if(u
.uinshop
&& shkp
&& !shkp
->mfroz
&& !shkp
->msleep
&&
846 inroom(u
.ux
+u
.dx
, u
.uy
+u
.dy
) + 1 == u
.uinshop
&&
847 shkp
->mx
== ESHK(shkp
)->shk
.x
&& shkp
->my
== ESHK(shkp
)->shk
.y
&&
848 u
.ux
== ESHK(shkp
)->shd
.x
&& u
.uy
== ESHK(shkp
)->shd
.y
) {
849 pline("%s nimbly catches the %s.", Monnam(shkp
), xname(obj
));
850 obj
->nobj
= shkp
->minvent
;
858 * shk_move: return 1: he moved 0: he didnt -1: let m_move do it
861 shk_move(struct monst
*shkp
)
864 struct permonst
*mdat
= shkp
->data
;
865 xchar gx
,gy
,omx
,omy
,nx
,ny
,nix
,niy
;
869 schar shkroom
,chi
,chcnt
,cnt
;
870 boolean uondoor
= 0, satdoor
, avoid
= 0, badinv
;
878 if((udist
= dist(omx
,omy
)) < 3) {
880 hitu(shkp
, d(mdat
->damn
, mdat
->damd
)+1);
883 if(ESHK(shkp
)->following
) {
884 if(strncmp(ESHK(shkp
)->customer
, plname
, PL_NSIZ
)){
885 pline("Hello %s! I was looking for %s.",
886 plname
, ESHK(shkp
)->customer
);
887 ESHK(shkp
)->following
= 0;
890 if(!ESHK(shkp
)->robbed
) { /* impossible? */
891 ESHK(shkp
)->following
= 0;
894 if(moves
> followmsg
+4) {
895 pline("Hello %s! Didn't you forget to pay?",
904 shkroom
= inroom(omx
,omy
);
906 gx
= ESHK(shkp
)->shk
.x
;
907 gy
= ESHK(shkp
)->shk
.y
;
908 satdoor
= (gx
== omx
&& gy
== omy
);
909 if(ESHK(shkp
)->following
|| ((z
= holetime()) >= 0 && z
*z
<= udist
)){
912 if(shkroom
< 0 || shkroom
!= inroom(u
.ux
,u
.uy
))
914 return(-1); /* leave it to m_move */
915 } else if(ANGRY(shkp
)) {
916 long saveBlind
= Blind
;
918 if(shkp
->mcansee
&& !Invis
&& cansee(omx
,omy
)) {
925 #define GDIST(x,y) ((x-gx)*(x-gx)+(y-gy)*(y-gy))
929 uondoor
= (u
.ux
== ESHK(shkp
)->shd
.x
&&
930 u
.uy
== ESHK(shkp
)->shd
.y
);
932 if(ESHK(shkp
)->billct
)
933 pline("Hello %s! Will you please pay before leaving?",
935 badinv
= (carrying(PICK_AXE
) || carrying(ICE_BOX
));
936 if(satdoor
&& badinv
)
940 avoid
= (u
.uinshop
&& dist(gx
,gy
) > 8);
944 if(((!ESHK(shkp
)->robbed
&& !ESHK(shkp
)->billct
) || avoid
)
945 && GDIST(omx
,omy
) < 3){
946 if(!badinv
&& !online(omx
,omy
))
953 if(omx
== gx
&& omy
== gy
)
961 cnt
= mfndpos(shkp
,poss
,info
,ALLOW_SSM
);
962 if(avoid
&& uondoor
) { /* perhaps we cannot avoid him */
964 if(!(info
[i
] & NOTONL
)) goto notonl_ok
;
971 for(i
=0; i
<cnt
; i
++){
974 if(levl
[nx
][ny
].typ
== ROOM
975 || shkroom
!= ESHK(shkp
)->shoproom
976 || ESHK(shkp
)->following
) {
978 /* cater for stupid compilers */
981 if(uondoor
&& (ib
= sobj_at(ICE_BOX
, nx
, ny
))) {
982 nix
= nx
; niy
= ny
; chi
= i
; break;
984 if(avoid
&& (info
[i
] & NOTONL
))
986 if((!appr
&& !rn2(++chcnt
)) ||
988 (appr
&& (zz
= GDIST(nix
,niy
)) && zz
> GDIST(nx
,ny
))
990 (appr
&& GDIST(nx
,ny
) < GDIST(nix
,niy
))
999 if(nix
!= omx
|| niy
!= omy
){
1000 if(info
[chi
] & ALLOW_M
){
1001 mtmp
= m_at(nix
,niy
);
1002 if(hitmm(shkp
,mtmp
) == 1 && rn2(3) &&
1003 hitmm(mtmp
,shkp
) == 2) return(2);
1005 } else if(info
[chi
] & ALLOW_U
){
1006 hitu(shkp
, d(mdat
->damn
, mdat
->damd
)+1);
1021 /* He is digging in the shop. */
1026 if(u
.utraptype
== TT_PIT
)
1027 pline("\"Be careful, sir, or you might fall through the floor.\"");
1029 pline("\"Please, do not damage the floor here.\"");
1030 } else if(dist(shopkeeper
->mx
, shopkeeper
->my
) < 3) {
1031 struct obj
*obj
, *obj2
;
1033 pline("%s grabs your backpack!", shkname(shopkeeper
));
1034 for(obj
= invent
; obj
; obj
= obj2
) {
1036 if(obj
->owornmask
) continue;
1038 obj
->nobj
= shopkeeper
->minvent
;
1039 shopkeeper
->minvent
= obj
;
1048 online(int x
, int y
)
1050 return(x
==u
.ux
|| y
==u
.uy
||
1051 (x
-u
.ux
)*(x
-u
.ux
) == (y
-u
.uy
)*(y
-u
.uy
));
1054 /* Does this monster follow me downstairs? */
1056 follower(struct monst
*mtmp
)
1058 return( mtmp
->mtame
|| index("1TVWZi&, ", mtmp
->data
->mlet
)
1060 || (mtmp
->isshk
&& ESHK(mtmp
)->following
)