]>
git.cameronkatri.com Git - bsdgames-darwin.git/blob - hack/hack.shk.c
2 * Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985.
6 static char rcsid
[] = "$NetBSD: hack.shk.c,v 1.3 1995/03/23 08:31:31 cgd Exp $";
12 struct monst
*shopkeeper
= 0;
13 struct obj
*billobjs
= 0;
14 obfree(obj
,merge
) register struct obj
*obj
, *merge
; {
17 inshop(){ return(0); }
24 doinvbill(){ return(0); }
26 shkcatch(){ return(0); }
27 shk_move(){ return(0); }
28 replshk(mtmp
,mtmp2
) struct monst
*mtmp
, *mtmp2
; {}
29 char *shkname(){ return(""); }
32 #include "hack.mfndpos.h"
33 #include "def.mkroom.h"
36 #define ESHK(mon) ((struct eshk *)(&(mon->mextra[0])))
37 #define NOTANGRY(mon) mon->mpeaceful
38 #define ANGRY(mon) !NOTANGRY(mon)
40 extern char plname
[], *xname();
41 extern struct obj
*o_on(), *bp_to_obj();
43 /* Descriptor of current shopkeeper. Note that the bill need not be
44 per-shopkeeper, since it is valid only when in a shop. */
45 static struct monst
*shopkeeper
= 0;
46 static struct bill_x
*bill
;
47 static int shlevel
= 0; /* level of this shopkeeper */
48 struct obj
*billobjs
; /* objects on bill with bp->useup */
49 /* only accessed here and by save & restore */
50 static long int total
; /* filled by addupbill() */
51 static long int followmsg
; /* last time of follow message */
54 invariants: obj->unpaid iff onbill(obj) [unless bp->useup]
55 obj->quan <= bp->bquan
59 char shtypes
[] = { /* 8 shoptypes: 7 specialized, 1 mixed */
60 RING_SYM
, WAND_SYM
, WEAPON_SYM
, FOOD_SYM
, SCROLL_SYM
,
61 POTION_SYM
, ARMOR_SYM
, 0
64 static char *shopnam
[] = {
65 "engagement ring", "walking cane", "antique weapon",
66 "delicatessen", "second hand book", "liquor",
67 "used armor", "assorted antiques"
71 shkname(mtmp
) /* called in do_name.c */
72 register struct monst
*mtmp
;
74 return(ESHK(mtmp
)->shknam
);
77 static void setpaid();
79 shkdead(mtmp
) /* called in mon.c */
80 register struct monst
*mtmp
;
82 register struct eshk
*eshk
= ESHK(mtmp
);
84 if(eshk
->shoplevel
== dlevel
)
85 rooms
[eshk
->shoproom
].rtype
= 0;
86 if(mtmp
== shopkeeper
) {
89 bill
= (struct bill_x
*) -1000; /* dump core when referenced */
94 register struct monst
*mtmp
, *mtmp2
;
96 if(mtmp
== shopkeeper
) {
98 bill
= &(ESHK(shopkeeper
)->bill
[0]);
103 setpaid(){ /* caller has checked that shopkeeper exists */
104 /* either we paid or left the shop or he just died */
105 register struct obj
*obj
;
106 register struct monst
*mtmp
;
107 for(obj
= invent
; obj
; obj
= obj
->nobj
)
109 for(obj
= fobj
; obj
; obj
= obj
->nobj
)
111 for(obj
= fcobj
; obj
; obj
= obj
->nobj
)
113 for(mtmp
= fmon
; mtmp
; mtmp
= mtmp
->nmon
)
114 for(obj
= mtmp
->minvent
; obj
; obj
= obj
->nobj
)
116 for(mtmp
= fallen_down
; mtmp
; mtmp
= mtmp
->nmon
)
117 for(obj
= mtmp
->minvent
; obj
; obj
= obj
->nobj
)
119 while(obj
= billobjs
){
120 billobjs
= obj
->nobj
;
123 ESHK(shopkeeper
)->billct
= 0;
127 addupbill(){ /* delivers result in total */
128 /* caller has checked that shopkeeper exists */
129 register ct
= ESHK(shopkeeper
)->billct
;
130 register struct bill_x
*bp
= bill
;
133 total
+= bp
->price
* bp
->bquan
;
139 register roomno
= inroom(u
.ux
,u
.uy
);
141 static void findshk();
143 /* Did we just leave a shop? */
145 (u
.uinshop
!= roomno
+ 1 || shlevel
!= dlevel
|| !shopkeeper
)) {
147 if(ESHK(shopkeeper
)->billct
) {
148 if(inroom(shopkeeper
->mx
, shopkeeper
->my
)
149 == u
.uinshop
- 1) /* ab@unido */
150 pline("Somehow you escaped the shop without paying!");
152 pline("You stole for a total worth of %ld zorkmids.",
154 ESHK(shopkeeper
)->robbed
+= total
;
156 if((rooms
[ESHK(shopkeeper
)->shoproom
].rtype
== GENERAL
)
158 ESHK(shopkeeper
)->following
= 1;
166 /* Did we just enter a zoo of some kind? */
168 register int rt
= rooms
[roomno
].rtype
;
169 register struct monst
*mtmp
;
171 pline("Welcome to David's treasure zoo!");
174 pline("It looks rather muddy down here.");
178 pline("Go away! Go away!");
180 pline("You get an uncanny feeling ...");
184 rooms
[roomno
].rtype
= 0;
185 for(mtmp
= fmon
; mtmp
; mtmp
= mtmp
->nmon
)
186 if(rt
!= ZOO
|| !rn2(3))
191 /* Did we just enter a shop? */
192 if(roomno
>= 0 && rooms
[roomno
].rtype
>= 8) {
193 if(shlevel
!= dlevel
|| !shopkeeper
194 || ESHK(shopkeeper
)->shoproom
!= roomno
)
197 rooms
[roomno
].rtype
= 0;
199 } else if(!u
.uinshop
){
200 if(!ESHK(shopkeeper
)->visitct
||
201 strncmp(ESHK(shopkeeper
)->customer
, plname
, PL_NSIZ
)){
203 /* He seems to be new here */
204 ESHK(shopkeeper
)->visitct
= 0;
205 ESHK(shopkeeper
)->following
= 0;
206 (void) strncpy(ESHK(shopkeeper
)->customer
,plname
,PL_NSIZ
);
207 NOTANGRY(shopkeeper
) = 1;
209 if(!ESHK(shopkeeper
)->following
) {
212 pline("Hello %s! Welcome%s to %s's %s shop!",
214 ESHK(shopkeeper
)->visitct
++ ? " again" : "",
216 shopnam
[rooms
[ESHK(shopkeeper
)->shoproom
].rtype
- 8] );
217 box
= carrying(ICE_BOX
);
218 pick
= carrying(PICK_AXE
);
220 if(dochug(shopkeeper
)) {
221 u
.uinshop
= 0; /* he died moving */
224 pline("Will you please leave your %s outside?",
225 (box
&& pick
) ? "box and pick-axe" :
226 box
? "box" : "pick-axe");
229 u
.uinshop
= roomno
+ 1;
239 register struct monst
*mtmp
;
240 for(mtmp
= fmon
; mtmp
; mtmp
= mtmp
->nmon
)
241 if(mtmp
->isshk
&& ESHK(mtmp
)->shoproom
== roomno
242 && ESHK(mtmp
)->shoplevel
== dlevel
) {
244 bill
= &(ESHK(shopkeeper
)->bill
[0]);
246 if(ANGRY(shopkeeper
) &&
247 strncmp(ESHK(shopkeeper
)->customer
,plname
,PL_NSIZ
))
248 NOTANGRY(shopkeeper
) = 1;
249 /* billobjs = 0; -- this is wrong if we save in a shop */
250 /* (and it is harmless to have too many things in billobjs) */
255 bill
= (struct bill_x
*) -1000; /* dump core when referenced */
258 static struct bill_x
*
259 onbill(obj
) register struct obj
*obj
; {
260 register struct bill_x
*bp
;
261 if(!shopkeeper
) return(0);
262 for(bp
= bill
; bp
< &bill
[ESHK(shopkeeper
)->billct
]; bp
++)
263 if(bp
->bo_id
== obj
->o_id
) {
264 if(!obj
->unpaid
) pline("onbill: paid obj on bill?");
267 if(obj
->unpaid
) pline("onbill: unpaid obj not on bill?");
271 /* called with two args on merge */
272 obfree(obj
,merge
) register struct obj
*obj
, *merge
; {
273 register struct bill_x
*bp
= onbill(obj
);
274 register struct bill_x
*bpm
;
278 obj
->unpaid
= 0; /* only for doinvbill */
279 obj
->nobj
= billobjs
;
285 /* this used to be a rename */
286 impossible("obfree: not on bill??");
289 /* this was a merger */
290 bpm
->bquan
+= bp
->bquan
;
291 ESHK(shopkeeper
)->billct
--;
292 *bp
= bill
[ESHK(shopkeeper
)->billct
];
301 register struct monst
*shkp
;
303 long robbed
= ESHK(shkp
)->robbed
;
310 if(robbed
< 0) robbed
= 0;
311 ESHK(shkp
)->robbed
= robbed
;
317 register struct bill_x
*bp
;
318 register struct monst
*shkp
;
321 static int dopayobj();
325 for(shkp
= fmon
; shkp
; shkp
= shkp
->nmon
)
326 if(shkp
->isshk
&& dist(shkp
->mx
,shkp
->my
) < 3)
328 if(!shkp
&& u
.uinshop
&&
329 inroom(shopkeeper
->mx
,shopkeeper
->my
) == ESHK(shopkeeper
)->shoproom
)
333 pline("There is nobody here to receive your payment.");
336 ltmp
= ESHK(shkp
)->robbed
;
337 if(shkp
!= shopkeeper
&& NOTANGRY(shkp
)) {
339 pline("You do not owe %s anything.", monnam(shkp
));
342 pline("You have no money.");
344 long ugold
= u
.ugold
;
347 pline("You give %s the %ld gold pieces he asked for.",
351 pline("You give %s all your gold.", monnam(shkp
));
355 pline("Unfortunately, he doesn't look satisfied.");
357 ESHK(shkp
)->robbed
= 0;
358 ESHK(shkp
)->following
= 0;
359 if(ESHK(shkp
)->shoplevel
!= dlevel
) {
360 /* For convenience's sake, let him disappear */
361 shkp
->minvent
= 0; /* %% */
370 if(!ESHK(shkp
)->billct
){
371 pline("You do not owe %s anything.", monnam(shkp
));
373 pline("Moreover, you have no money.");
376 if(ESHK(shkp
)->robbed
){
377 #define min(a,b) ((a<b)?a:b)
378 pline("But since his shop has been robbed recently,");
379 pline("you %srepay %s's expenses.",
380 (u
.ugold
< ESHK(shkp
)->robbed
) ? "partially " : "",
382 pay(min(u
.ugold
, ESHK(shkp
)->robbed
), shkp
);
383 ESHK(shkp
)->robbed
= 0;
387 pline("But in order to appease %s,",
388 amonnam(shkp
, "angry"));
391 pline(" you give him 1000 gold pieces.");
394 pline(" you give him all your money.");
397 if(strncmp(ESHK(shkp
)->customer
, plname
, PL_NSIZ
)
399 pline("%s calms down.", Monnam(shkp
));
401 } else pline("%s is as angry as ever.",
406 if(shkp
!= shopkeeper
) {
407 impossible("dopay: not to shopkeeper?");
408 if(shopkeeper
) setpaid();
411 for(pass
= 0; pass
<= 1; pass
++) {
413 while(tmp
< ESHK(shopkeeper
)->billct
) {
415 if(!pass
&& !bp
->useup
) {
419 if(!dopayobj(bp
)) return(1);
420 bill
[tmp
] = bill
[--ESHK(shopkeeper
)->billct
];
423 pline("Thank you for shopping in %s's %s store!",
425 shopnam
[rooms
[ESHK(shopkeeper
)->shoproom
].rtype
- 8]);
426 NOTANGRY(shopkeeper
) = 1;
430 /* return 1 if paid successfully */
431 /* 0 if not enough money */
432 /* -1 if object could not be found (but was paid) */
434 dopayobj(bp
) register struct bill_x
*bp
; {
435 register struct obj
*obj
;
438 /* find the object on one of the lists */
442 impossible("Shopkeeper administration out of order.");
443 setpaid(); /* be nice to the player */
447 if(!obj
->unpaid
&& !bp
->useup
){
448 impossible("Paid object on bill??");
452 ltmp
= bp
->price
* bp
->bquan
;
453 if(ANGRY(shopkeeper
)) ltmp
+= ltmp
/3;
455 pline("You don't have gold enough to pay %s.",
460 pay(ltmp
, shopkeeper
);
461 pline("You bought %s for %ld gold piece%s.",
462 doname(obj
), ltmp
, plur(ltmp
));
464 register struct obj
*otmp
= billobjs
;
466 billobjs
= obj
->nobj
;
468 while(otmp
&& otmp
->nobj
!= obj
) otmp
= otmp
->nobj
;
469 if(otmp
) otmp
->nobj
= obj
->nobj
;
470 else pline("Error in shopkeeper administration.");
477 /* routine called after dying (or quitting) with nonempty bill */
479 if(shlevel
== dlevel
&& shopkeeper
&& ESHK(shopkeeper
)->billct
){
482 shopkeeper
->mgold
+= u
.ugold
;
484 pline("%s comes and takes all your possessions.",
488 shopkeeper
->mgold
+= total
;
489 pline("%s comes and takes the %ld zorkmids you owed him.",
490 Monnam(shopkeeper
), total
);
492 setpaid(); /* in case we create bones */
496 /* find obj on one of the lists */
499 register struct bill_x
*bp
;
501 register struct obj
*obj
;
502 register struct monst
*mtmp
;
503 register unsigned id
= bp
->bo_id
;
506 obj
= o_on(id
, billobjs
);
507 else if(!(obj
= o_on(id
, invent
)) &&
508 !(obj
= o_on(id
, fobj
)) &&
509 !(obj
= o_on(id
, fcobj
))) {
510 for(mtmp
= fmon
; mtmp
; mtmp
= mtmp
->nmon
)
511 if(obj
= o_on(id
, mtmp
->minvent
))
513 for(mtmp
= fallen_down
; mtmp
; mtmp
= mtmp
->nmon
)
514 if(obj
= o_on(id
, mtmp
->minvent
))
520 static int getprice();
522 /* called in hack.c when we pickup an object */
523 addtobill(obj
) register struct obj
*obj
; {
524 register struct bill_x
*bp
;
526 (u
.ux
== ESHK(shopkeeper
)->shk
.x
&& u
.uy
== ESHK(shopkeeper
)->shk
.y
) ||
527 (u
.ux
== ESHK(shopkeeper
)->shd
.x
&& u
.uy
== ESHK(shopkeeper
)->shd
.y
) ||
528 onbill(obj
) /* perhaps we threw it away earlier */
530 if(ESHK(shopkeeper
)->billct
== BILLSZ
){
531 pline("You got that for free!");
534 bp
= &bill
[ESHK(shopkeeper
)->billct
];
535 bp
->bo_id
= obj
->o_id
;
536 bp
->bquan
= obj
->quan
;
538 bp
->price
= getprice(obj
);
539 ESHK(shopkeeper
)->billct
++;
543 splitbill(obj
,otmp
) register struct obj
*obj
, *otmp
; {
544 /* otmp has been split off from obj */
545 register struct bill_x
*bp
;
549 impossible("splitbill: not on bill?");
552 if(bp
->bquan
< otmp
->quan
) {
553 impossible("Negative quantity on bill??");
555 if(bp
->bquan
== otmp
->quan
) {
556 impossible("Zero quantity on bill??");
558 bp
->bquan
-= otmp
->quan
;
560 /* addtobill(otmp); */
561 if(ESHK(shopkeeper
)->billct
== BILLSZ
) otmp
->unpaid
= 0;
564 bp
= &bill
[ESHK(shopkeeper
)->billct
];
565 bp
->bo_id
= otmp
->o_id
;
566 bp
->bquan
= otmp
->quan
;
569 ESHK(shopkeeper
)->billct
++;
573 subfrombill(obj
) register struct obj
*obj
; {
576 register struct obj
*otmp
;
577 register struct bill_x
*bp
;
578 if(!inshop() || (u
.ux
== ESHK(shopkeeper
)->shk
.x
&& u
.uy
== ESHK(shopkeeper
)->shk
.y
) ||
579 (u
.ux
== ESHK(shopkeeper
)->shd
.x
&& u
.uy
== ESHK(shopkeeper
)->shd
.y
))
581 if((bp
= onbill(obj
)) != 0){
583 if(bp
->bquan
> obj
->quan
){
586 bp
->bo_id
= otmp
->o_id
= flags
.ident
++;
587 otmp
->quan
= (bp
->bquan
-= obj
->quan
);
588 otmp
->owt
= 0; /* superfluous */
591 otmp
->nobj
= billobjs
;
595 ESHK(shopkeeper
)->billct
--;
596 *bp
= bill
[ESHK(shopkeeper
)->billct
];
600 pline("%s didn't notice.", Monnam(shopkeeper
));
604 /* he dropped something of his own - probably wants to sell it */
605 if(shopkeeper
->msleep
|| shopkeeper
->mfroz
||
606 inroom(shopkeeper
->mx
,shopkeeper
->my
) != ESHK(shopkeeper
)->shoproom
)
608 if(ESHK(shopkeeper
)->billct
== BILLSZ
||
609 ((tmp
= shtypes
[rooms
[ESHK(shopkeeper
)->shoproom
].rtype
-8]) && tmp
!= obj
->olet
)
610 || index("_0", obj
->olet
)) {
611 pline("%s seems not interested.", Monnam(shopkeeper
));
614 ltmp
= getprice(obj
) * obj
->quan
;
615 if(ANGRY(shopkeeper
)) {
617 NOTANGRY(shopkeeper
) = 1;
619 if(ESHK(shopkeeper
)->robbed
){
620 if((ESHK(shopkeeper
)->robbed
-= ltmp
) < 0)
621 ESHK(shopkeeper
)->robbed
= 0;
622 pline("Thank you for your contribution to restock this recently plundered shop.");
625 if(ltmp
> shopkeeper
->mgold
)
626 ltmp
= shopkeeper
->mgold
;
627 pay(-ltmp
, shopkeeper
);
629 pline("%s gladly accepts %s but cannot pay you at present.",
630 Monnam(shopkeeper
), doname(obj
));
632 pline("You sold %s and got %ld gold piece%s.", doname(obj
), ltmp
,
637 int mode
; /* 0: deliver count 1: paged */
639 register struct bill_x
*bp
;
640 register struct obj
*obj
;
641 long totused
, thisused
;
645 register int cnt
= 0;
648 for(bp
= bill
; bp
- bill
< ESHK(shopkeeper
)->billct
; bp
++)
650 ((obj
= bp_to_obj(bp
)) && obj
->quan
< bp
->bquan
))
656 impossible("doinvbill: no shopkeeper?");
661 if(page_line("Unpaid articles already used up:") || page_line(""))
665 for(bp
= bill
; bp
- bill
< ESHK(shopkeeper
)->billct
; bp
++) {
668 impossible("Bad shopkeeper administration.");
671 if(bp
->useup
|| bp
->bquan
> obj
->quan
) {
672 register int cnt
, oquan
, uquan
;
675 uquan
= (bp
->useup
? bp
->bquan
: bp
->bquan
- oquan
);
676 thisused
= bp
->price
* uquan
;
678 obj
->quan
= uquan
; /* cheat doname */
679 (void) sprintf(buf
, "x - %s", doname(obj
));
680 obj
->quan
= oquan
; /* restore value */
681 for(cnt
= 0; buf
[cnt
]; cnt
++);
684 (void) sprintf(&buf
[cnt
], " %5ld zorkmids", thisused
);
689 (void) sprintf(buf
, "Total:%50ld zorkmids", totused
);
690 if(page_line("") || page_line(buf
))
700 getprice(obj
) register struct obj
*obj
; {
701 register int tmp
, ac
;
702 static int realhunger();
709 tmp
= 10*rnd((obj
->otyp
== EXPENSIVE_CAMERA
) ? 150 : 30);
720 if(obj
->otyp
== SCR_MAIL
)
728 tmp
= 10*rnd(5 + (2000/realhunger()));
735 if(ac
<= -10) /* probably impossible */
737 tmp
= 100 + ac
*ac
*rnd(10+ac
);
740 if(obj
->otyp
< BOOMERANG
)
742 else if(obj
->otyp
== LONG_SWORD
||
743 obj
->otyp
== TWO_HANDED_SWORD
)
745 else tmp
= 10*rnd(75);
748 pline("Strange ..., carrying a chain?");
759 realhunger(){ /* not completely foolproof */
760 register tmp
= u
.uhunger
;
761 register struct obj
*otmp
= invent
;
763 if(otmp
->olet
== FOOD_SYM
&& !otmp
->unpaid
)
764 tmp
+= objects
[otmp
->otyp
].nutrition
;
767 return((tmp
<= 0) ? 1 : tmp
);
771 register struct obj
*obj
;
773 register struct monst
*shkp
= shopkeeper
;
775 if(u
.uinshop
&& shkp
&& !shkp
->mfroz
&& !shkp
->msleep
&&
777 inroom(u
.ux
+u
.dx
, u
.uy
+u
.dy
) + 1 == u
.uinshop
&&
778 shkp
->mx
== ESHK(shkp
)->shk
.x
&& shkp
->my
== ESHK(shkp
)->shk
.y
&&
779 u
.ux
== ESHK(shkp
)->shd
.x
&& u
.uy
== ESHK(shkp
)->shd
.y
) {
780 pline("%s nimbly catches the %s.", Monnam(shkp
), xname(obj
));
781 obj
->nobj
= shkp
->minvent
;
789 * shk_move: return 1: he moved 0: he didnt -1: let m_move do it
792 register struct monst
*shkp
;
794 register struct monst
*mtmp
;
795 register struct permonst
*mdat
= shkp
->data
;
796 register xchar gx
,gy
,omx
,omy
,nx
,ny
,nix
,niy
;
797 register schar appr
,i
;
800 schar shkroom
,chi
,chcnt
,cnt
;
801 boolean uondoor
, satdoor
, avoid
, badinv
;
809 if((udist
= dist(omx
,omy
)) < 3) {
811 (void) hitu(shkp
, d(mdat
->damn
, mdat
->damd
)+1);
814 if(ESHK(shkp
)->following
) {
815 if(strncmp(ESHK(shkp
)->customer
, plname
, PL_NSIZ
)){
816 pline("Hello %s! I was looking for %s.",
817 plname
, ESHK(shkp
)->customer
);
818 ESHK(shkp
)->following
= 0;
821 if(!ESHK(shkp
)->robbed
) { /* impossible? */
822 ESHK(shkp
)->following
= 0;
825 if(moves
> followmsg
+4) {
826 pline("Hello %s! Didn't you forget to pay?",
835 shkroom
= inroom(omx
,omy
);
837 gx
= ESHK(shkp
)->shk
.x
;
838 gy
= ESHK(shkp
)->shk
.y
;
839 satdoor
= (gx
== omx
&& gy
== omy
);
840 if(ESHK(shkp
)->following
|| ((z
= holetime()) >= 0 && z
*z
<= udist
)){
843 if(shkroom
< 0 || shkroom
!= inroom(u
.ux
,u
.uy
))
845 return(-1); /* leave it to m_move */
846 } else if(ANGRY(shkp
)) {
847 long saveBlind
= Blind
;
849 if(shkp
->mcansee
&& !Invis
&& cansee(omx
,omy
)) {
856 #define GDIST(x,y) ((x-gx)*(x-gx)+(y-gy)*(y-gy))
860 uondoor
= (u
.ux
== ESHK(shkp
)->shd
.x
&&
861 u
.uy
== ESHK(shkp
)->shd
.y
);
863 if(ESHK(shkp
)->billct
)
864 pline("Hello %s! Will you please pay before leaving?",
866 badinv
= (carrying(PICK_AXE
) || carrying(ICE_BOX
));
867 if(satdoor
&& badinv
)
871 avoid
= (u
.uinshop
&& dist(gx
,gy
) > 8);
875 if(((!ESHK(shkp
)->robbed
&& !ESHK(shkp
)->billct
) || avoid
)
876 && GDIST(omx
,omy
) < 3){
877 if(!badinv
&& !online(omx
,omy
))
884 if(omx
== gx
&& omy
== gy
)
892 cnt
= mfndpos(shkp
,poss
,info
,ALLOW_SSM
);
893 if(avoid
&& uondoor
) { /* perhaps we cannot avoid him */
895 if(!(info
[i
] & NOTONL
)) goto notonl_ok
;
902 for(i
=0; i
<cnt
; i
++){
905 if(levl
[nx
][ny
].typ
== ROOM
906 || shkroom
!= ESHK(shkp
)->shoproom
907 || ESHK(shkp
)->following
) {
909 /* cater for stupid compilers */
912 if(uondoor
&& (ib
= sobj_at(ICE_BOX
, nx
, ny
))) {
913 nix
= nx
; niy
= ny
; chi
= i
; break;
915 if(avoid
&& (info
[i
] & NOTONL
))
917 if((!appr
&& !rn2(++chcnt
)) ||
919 (appr
&& (zz
= GDIST(nix
,niy
)) && zz
> GDIST(nx
,ny
))
921 (appr
&& GDIST(nx
,ny
) < GDIST(nix
,niy
))
930 if(nix
!= omx
|| niy
!= omy
){
931 if(info
[chi
] & ALLOW_M
){
932 mtmp
= m_at(nix
,niy
);
933 if(hitmm(shkp
,mtmp
) == 1 && rn2(3) &&
934 hitmm(mtmp
,shkp
) == 2) return(2);
936 } else if(info
[chi
] & ALLOW_U
){
937 (void) hitu(shkp
, d(mdat
->damn
, mdat
->damd
)+1);
952 /* He is digging in the shop. */
957 if(u
.utraptype
== TT_PIT
)
958 pline("\"Be careful, sir, or you might fall through the floor.\"");
960 pline("\"Please, do not damage the floor here.\"");
961 } else if(dist(shopkeeper
->mx
, shopkeeper
->my
) < 3) {
962 register struct obj
*obj
, *obj2
;
964 pline("%s grabs your backpack!", shkname(shopkeeper
));
965 for(obj
= invent
; obj
; obj
= obj2
) {
967 if(obj
->owornmask
) continue;
969 obj
->nobj
= shopkeeper
->minvent
;
970 shopkeeper
->minvent
= obj
;
979 return(x
==u
.ux
|| y
==u
.uy
||
980 (x
-u
.ux
)*(x
-u
.ux
) == (y
-u
.uy
)*(y
-u
.uy
));
983 /* Does this monster follow me downstairs? */
985 register struct monst
*mtmp
;
987 return( mtmp
->mtame
|| index("1TVWZi&, ", mtmp
->data
->mlet
)
989 || (mtmp
->isshk
&& ESHK(mtmp
)->following
)