Source:NetHack 3.0.0/shk.c

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

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

1.   /*	SCCS Id: @(#)shk.c	3.0	89/02/10 2.   /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3.    /* NetHack may be freely redistributed. See license for details. */ 4.     5.    /* block some unused #defines to avoid overloading some cpp's */ 6.   #define MONATTK_H 7.   #include "hack.h"  8. 9.   #include "eshk.h"  10. 11.  #ifdef KOPS 12.  static int makekops; 13.  static void kops_gone; 14.  #endif /* KOPS */ 15.   16.   #define	NOTANGRY(mon)	mon->mpeaceful 17.  #define	ANGRY(mon)	!NOTANGRY(mon) 18.   19.   /* Descriptor of current shopkeeper. Note that the bill need not be 20. per-shopkeeper, since it is valid only when in a shop. */ 21.   static struct monst *shopkeeper = 0; 22.  static struct bill_x *bill; 23.  static int shlevel = 0;	/* level of this shopkeeper */ 24.  /* struct obj *billobjs;	/* objects on bill with bp->useup */ 25.  				/* only accessed here and by save & restore */ 26.  static long int total;		/* filled by addupbill */ 27.  static long int followmsg;	/* last time of follow message */ 28.  static void setpaid, findshk P((int)); 29.  static int dopayobj P((struct bill_x *)), getprice P((struct obj *)); 30.  static struct obj *bp_to_obj P((struct bill_x *)); 31.   32.   /*  33.   	invariants: obj->unpaid iff onbill(obj) [unless bp->useup] 34.  		obj->quan <= bp->bquan 35.   */  36.    37.   char * 38.  shkname(mtmp)				/* called in do_name.c */ 39.  register struct monst *mtmp; 40.  {  41.   	return(ESHK(mtmp)->shknam); 42.  }  43.    44.   void 45.  shkdead(mtmp)				/* called in mon.c */ 46.  register struct monst *mtmp; 47.  {  48.   	register struct eshk *eshk = ESHK(mtmp); 49.   50.   	if(eshk->shoplevel == dlevel) 51.  		rooms[eshk->shoproom].rtype = OROOM; 52.  	if(mtmp == shopkeeper) { 53.  		setpaid; 54.  		shopkeeper = 0; 55.  		bill = (struct bill_x *) -1000;	/* dump core when referenced */ 56.  	}  57.   }  58.    59.   void 60.  replshk(mtmp,mtmp2) 61.  register struct monst *mtmp, *mtmp2; 62.  {  63.   	if(mtmp == shopkeeper) { 64.  		shopkeeper = mtmp2; 65.  		bill = &(ESHK(shopkeeper)->bill[0]); 66.  	}  67.   }  68.    69.   static void 70.  setpaid{	/* caller has checked that shopkeeper exists */ 71.  		/* either we paid or left the shop or he just died */ 72.  	register struct obj *obj; 73.  	register struct monst *mtmp; 74.  	for(obj = invent; obj; obj = obj->nobj) 75.  		obj->unpaid = 0; 76.  	for(obj = fobj; obj; obj = obj->nobj) 77.  		obj->unpaid = 0; 78.  	for(obj = fcobj; obj; obj = obj->nobj) 79.  		obj->unpaid = 0; 80.  	for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) 81.  		for(obj = mtmp->minvent; obj; obj = obj->nobj) 82.  			obj->unpaid = 0; 83.  	for(mtmp = fallen_down; mtmp; mtmp = mtmp->nmon) 84.  		for(obj = mtmp->minvent; obj; obj = obj->nobj) 85.  			obj->unpaid = 0; 86.  	while(obj = billobjs){ 87.  		billobjs = obj->nobj; 88.  		free((genericptr_t) obj); 89.  	}  90.   	if(shopkeeper) { 91.  		ESHK(shopkeeper)->billct = 0; 92.  		ESHK(shopkeeper)->credit = 0L; 93.  		ESHK(shopkeeper)->debit = 0L; 94.  	}  95.   }  96.    97.   static void 98.  addupbill{	/* delivers result in total */ 99.  		/* caller has checked that shopkeeper exists */ 100. 	register int ct = ESHK(shopkeeper)->billct; 101. 	register struct bill_x *bp = bill; 102. 	total = 0; 103. 	while(ct--){ 104. 		total += bp->price * bp->bquan; 105. 		bp++; 106. 	}  107.  }  108.   109.  int 110. inshop { 111. 	register int roomno = inroom(u.ux,u.uy); 112.  113.  	/* Did we just leave a shop? */ 114.  	if(u.uinshop &&  115.  	    (u.uinshop != roomno + 1 || shlevel != dlevel || !shopkeeper)) { 116.  117.  	/* This is part of the bugfix for shopkeepers not having their 118. 	 * bill paid. As reported by ab@unido -dgk 119. 	 * I made this standard due to the KOPS code below. -mrs 120. 	 */  121.  		if(shopkeeper) { 122. 		    if(ESHK(shopkeeper)->billct || ESHK(shopkeeper)->debit) { 123. 			if(inroom(shopkeeper->mx, shopkeeper->my)  124.  			    == u.uinshop - 1)	/* ab@unido */ 125. 			    You("escaped the shop without paying!"); 126. 			addupbill; 127. 			total += ESHK(shopkeeper)->debit; 128. 			You("stole %ld zorkmids worth of merchandise.",  129.  				total); 130. 			ESHK(shopkeeper)->robbed += total; 131. 			ESHK(shopkeeper)->credit = 0L; 132. 			ESHK(shopkeeper)->debit = 0L; 133. 			if (pl_character[0] != 'R') /* stealing is unlawful */ 134. 				adjalign(-sgn(u.ualigntyp)); 135. 			setpaid; 136. 			if((rooms[ESHK(shopkeeper)->shoproom].rtype == SHOPBASE)  137.  			    == (rn2(3) == 0)) 138. 			    ESHK(shopkeeper)->following = 1; 139. #ifdef KOPS 140. 		    {   /* Keystone Kops srt@ucla */ 141. 			coord mm; 142.  143.  			if (flags.soundok) 144. 			    pline("An alarm sounds throughout the dungeon!"); 145. 			if(flags.verbose) { 146. 			    if((mons[PM_KEYSTONE_KOP].geno & G_GENOD) &&  147.   			       (mons[PM_KOP_SERGEANT].geno & G_GENOD) &&  148.   			       (mons[PM_KOP_LIEUTENANT].geno & G_GENOD) &&  149.  			       (mons[PM_KOP_KAPTAIN].geno & G_GENOD)) { 150. 				if (flags.soundok) 151. 				    pline("But no one seems to respond to it."); 152. 			    } else 153. 				pline("The Keystone Kops are after you!"); 154. 			}  155.  			/* Create a swarm near the staircase */ 156. 			mm.x = xdnstair; 157. 			mm.y = ydnstair; 158. 			(void) makekops(&mm); 159. 			/* Create a swarm near the shopkeeper */ 160. 			mm.x = shopkeeper->mx; 161. 			mm.y = shopkeeper->my; 162. 			(void) makekops(&mm); 163. 		    }  164.  #endif 165. 		    }  166.  		    shopkeeper = 0; 167. 		    shlevel = 0; 168. 		}  169.  		u.uinshop = 0; 170. 	}  171.   172.  	/* Did we just enter a zoo of some kind? */ 173.  	/* This counts everything except shops and vaults 174. 	   -- vault.c insists that a vault remain a VAULT */ 175. 	if(roomno >= 0) { 176. 		register int rt = rooms[roomno].rtype; 177. 		register struct monst *mtmp; 178.  179.  		switch (rt) { 180. 		case ZOO: 181. 		    pline("Welcome to David's treasure zoo!"); 182. 		    break; 183. 		case SWAMP: 184. 		    pline("It looks rather muddy down here."); 185. 		    break; 186. #ifdef THRONES 187. 		case COURT: 188. 		    You("enter an opulent throne room!"); 189. 		    break; 190. #endif 191. 		case MORGUE: 192. 		    if(midnight) 193. 			pline("Run away!  Run away!"); 194. 		    else 195. 			You("have an uncanny feeling..."); 196. 		    break; 197. 		case BEEHIVE: 198. 		    You("enter a giant beehive!"); 199. 		    break; 200. #ifdef ARMY 201. 		case BARRACKS: 202. 		    if(!((mons[PM_SOLDIER].geno & G_GENOD) && 203. 		         (mons[PM_SERGEANT].geno & G_GENOD) && 204. 		         (mons[PM_LIEUTENANT].geno & G_GENOD) && 205. 		         (mons[PM_CAPTAIN].geno & G_GENOD))) 206. 		    	You("enter a military barracks!"); 207. 		    else You("enter an abandoned barracks."); 208. 		    break; 209. #endif 210. #ifdef ORACLE 211. 		case DELPHI: 212. 		    if(!(mons[PM_ORACLE].geno & G_GENOD)) 213. 		        pline("\"Hello, %s, welcome to Delphi!\"", plname); 214. 		    break; 215. #endif 216. 		default: 217. 		    rt = 0; 218. 		}  219.   220.  		if(rt != 0) { 221. 		    rooms[roomno].rtype = OROOM; 222. 		    if(rt==COURT || rt==SWAMP || rt==MORGUE || rt==ZOO) 223. 			for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) 224. 			    /* was if(rt != ZOO || !rn2(3)) -- why should ZOO 225. 			       be different from COURT or MORGUE? */ 226.  			    if(!Stealth && !rn2(3)) 227. 				mtmp->msleep = 0; 228. 		}  229.  	}  230.  #if defined(ALTARS) && defined(THEOLOGY) 231. 	if(roomno >= 0 && rooms[roomno].rtype == TEMPLE) { 232. 	    intemple; 233. 	}  234.  #endif 235. 	/* Did we just enter a shop? */ 236.  	if(roomno >= 0 && rooms[roomno].rtype >= SHOPBASE) { 237. 	    register int rt = rooms[roomno].rtype; 238.  239.  	    if(shlevel != dlevel || !shopkeeper  240.  				 || ESHK(shopkeeper)->shoproom != roomno) 241. 		findshk(roomno); 242. 	    if(!shopkeeper) { 243. 		rooms[roomno].rtype = OROOM; 244. 		u.uinshop = 0; 245. 	    } else if(!u.uinshop){ 246. 		if(!ESHK(shopkeeper)->visitct ||  247.  		   strncmp(ESHK(shopkeeper)->customer, plname, PL_NSIZ)) { 248. 		    /* He seems to be new here */ 249. 		    ESHK(shopkeeper)->visitct = 0; 250. 		    ESHK(shopkeeper)->following = 0; 251. 		    (void) strncpy(ESHK(shopkeeper)->customer,plname,PL_NSIZ); 252. 		    NOTANGRY(shopkeeper) = 1; 253. 		}  254.  		if(!ESHK(shopkeeper)->following && inhishop(shopkeeper)) { 255. 		    if(ANGRY(shopkeeper)) 256. 			pline("\"So, %s, you dare return to %s's %s?!\"",  257.  			    plname,  258.  			    shkname(shopkeeper),  259.  			    shtypes[rt - SHOPBASE].name); 260. 		    else 261. 		    if(ESHK(shopkeeper)->robbed) 262. 			pline("\"Beware, %s!  I am upset about missing stock!\"",  263.  			    plname); 264. 		    else 265. 			pline("\"Hello, %s!  Welcome%s to %s's %s!\"",  266.  			    plname,  267.  			    ESHK(shopkeeper)->visitct++ ? " again" : "",  268.  			    shkname(shopkeeper),  269.  			    shtypes[rt - SHOPBASE].name); 270. 		    if(carrying(PICK_AXE) != (struct obj *)0) { 271. 			pline(NOTANGRY(shopkeeper) ?  272.  			   "\"Will you please leave your pick-axe outside?\"" :  273.  			   "\"Leave the pick-axe outside.\""); 274. 			if(dochug(shopkeeper)) { 275. 			    u.uinshop = 0;	/* he died moving */ 276. 			    return(0); 277. 			}  278.  		    }  279.  		}  280.  		u.uinshop = (unsigned int)(roomno + 1); 281. 	    }  282.  	}  283.  	return (int)u.uinshop; 284. }  285.   286.  int 287. inhishop(mtmp) 288. register struct monst *mtmp; 289. {  290.  	return((ESHK(mtmp)->shoproom == inroom(mtmp->mx, mtmp->my) && 291. 		ESHK(mtmp)->shoplevel == dlevel)); 292. }  293.   294.  static void 295. findshk(roomno) 296. register int roomno; 297. {  298.  	register struct monst *mtmp; 299.  300.  	for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) 301. 	    if(mtmp->isshk && ESHK(mtmp)->shoproom == roomno  302.  			   && ESHK(mtmp)->shoplevel == dlevel) { 303. 		shopkeeper = mtmp; 304. 		bill = &(ESHK(shopkeeper)->bill[0]); 305. 		shlevel = dlevel; 306. 		if(ANGRY(shopkeeper) &&  307.  		   strncmp(ESHK(shopkeeper)->customer,plname,PL_NSIZ)) 308. 			NOTANGRY(shopkeeper) = 1; 309. 		/* billobjs = 0; -- this is wrong if we save in a shop */ 310. 		/* (and it is harmless to have too many things in billobjs) */ 311. 		return; 312. 	}  313.  	shopkeeper = 0; 314. 	shlevel = 0; 315. 	bill = (struct bill_x *) -1000;	/* dump core when referenced */ 316. }  317.   318.  static struct bill_x * 319. onbill(obj) 320. register struct obj *obj; 321. {  322.  	register struct bill_x *bp; 323. 	if(!shopkeeper) return (struct bill_x *)0; 324. 	for(bp = bill; bp < &bill[ESHK(shopkeeper)->billct]; bp++) 325. 		if(bp->bo_id == obj->o_id) { 326. 			if(!obj->unpaid) pline("onbill: paid obj on bill?"); 327. 			return(bp); 328. 		}  329.  	if(obj->unpaid) pline("onbill: unpaid obj not on bill?"); 330. 	return (struct bill_x *)0; 331. }  332.   333.  /* called with two args on merge */ 334. void 335. obfree(obj, merge) 336. register struct obj *obj, *merge; 337. {  338.  	register struct bill_x *bp = onbill(obj); 339. 	register struct bill_x *bpm; 340. 	if(bp) { 341. 		if(!merge){ 342. 			bp->useup = 1; 343. 			obj->unpaid = 0;	/* only for doinvbill */ 344. 			obj->nobj = billobjs; 345. 			billobjs = obj; 346. 			return; 347. 		}  348.  		bpm = onbill(merge); 349. 		if(!bpm){ 350. 			/* this used to be a rename */ 351. 			impossible("obfree: not on bill??"); 352. 			return; 353. 		} else { 354. 			/* this was a merger */ 355. 			bpm->bquan += bp->bquan; 356. 			ESHK(shopkeeper)->billct--; 357. 			*bp = bill[ESHK(shopkeeper)->billct]; 358. 		}  359.  	}  360.  	free((genericptr_t) obj); 361. }  362.   363.  static long 364. check_credit(tmp, shkp) 365. long tmp; 366. register struct monst *shkp; 367. {  368.  	long credit = ESHK(shkp)->credit; 369.  370.  	if(credit == 0L) return(tmp); 371. 	if(credit >= tmp) { 372. 		pline("The price is deducted from your credit."); 373. 		ESHK(shkp)->credit -=tmp; 374. 		tmp = 0L; 375. 	} else { 376. 		pline("The price is partially covered by your credit."); 377. 		ESHK(shkp)->credit = 0L; 378. 		tmp -= credit; 379. 	}  380.  	return(tmp); 381. }  382.   383.  static void 384. pay(tmp,shkp) 385. long tmp; 386. register struct monst *shkp; 387. {  388.  	long robbed = ESHK(shkp)->robbed; 389. 	long balance = ((tmp <= 0) ? tmp : check_credit(tmp, shkp)); 390.  391.  	u.ugold -= balance; 392. 	shkp->mgold += balance; 393. 	flags.botl = 1; 394. 	if(robbed) { 395. 		robbed -= tmp; 396. 		if(robbed < 0) robbed = 0; 397. 		ESHK(shkp)->robbed = robbed; 398. 	}  399.  }  400.   401.  /* return shkp to home position */ 402. void 403. home_shk(shkp) 404. register struct monst *shkp; 405. {  406.  	register xchar x = ESHK(shkp)->shk.x, y = ESHK(shkp)->shk.y;  407. if(levl[x][y].mmask) 408. 		mnearto(m_at(x,y), x, y, FALSE); 409. 	levl[shkp->mx][shkp->my].mmask = 0; 410. 	shkp->mx = x;  411. shkp->my = y; 412. levl[shkp->mx][shkp->my].mmask = 1; 413. 	unpmon(shkp); 414. }  415.   416.  void 417. make_happy_shk(shkp) 418. struct monst *shkp; 419. {  420.  	register boolean wasmad = ANGRY(shkp); 421.  422.  	NOTANGRY(shkp) = 1; 423. 	ESHK(shkp)->following = 0; 424. 	ESHK(shkp)->robbed = 0; 425. 	if (pl_character[0] != 'R') 426. 		adjalign(sgn(u.ualigntyp)); 427. 	if(!inhishop(shkp)) { 428. 		pline("Satisfied, %s suddenly disappears!", mon_nam(shkp)); 429. 		if(ESHK(shkp)->shoplevel == dlevel) 430. 			home_shk(shkp); 431. 		else 432. 			fall_down(shkp, ESHK(shkp)->shoplevel); 433. 	} else if(wasmad) 434. 		pline("%s calms down.", Monnam(shkp)); 435. #ifdef KOPS 436. 	kops_gone; 437. #endif 438. }  439.   440.  static const char no_money[] = "Moreover, you have no money."; 441.  442.  int 443. dopay 444. {  445.  	long ltmp; 446. 	register struct bill_x *bp; 447. 	register struct monst *shkp; 448. 	int pass, tmp; 449.  450.  	multi = 0; 451. 	(void) inshop; 452. 	for(shkp = fmon; shkp; shkp = shkp->nmon) 453. 		if(shkp->isshk && dist(shkp->mx,shkp->my) < 3) 454. 			break; 455. 	if(!shkp && u.uinshop && inhishop(shopkeeper)) 456. 		shkp = shopkeeper; 457.  458.  	if(!shkp) { 459. 		pline("There is nobody here to receive your payment."); 460. 		return(0); 461. 	}  462.  	ltmp = ESHK(shkp)->robbed; 463. 	if(shkp != shopkeeper && NOTANGRY(shkp)) { 464. 		if(!ltmp) 465. 		    You("do not owe %s anything.", mon_nam(shkp)); 466. 		else if(!u.ugold) 467. 		    You("have no money."); 468. 		else { 469. 		    long ugold = u.ugold; 470.  471.  		    if(ugold  > ltmp) { 472. 			You("give %s the %ld gold pieces %s asked for.",  473.  			    mon_nam(shkp), ltmp,  474.  			    ESHK(shkp)->ismale ? "he" : "she"); 475. 			pay(ltmp, shkp); 476. 		    } else { 477. 			You("give %s all your gold.", mon_nam(shkp)); 478. 			pay(u.ugold, shkp); 479. 		    }  480.  		    if(ugold < ltmp/2) 481. 			pline("Unfortunately, %s doesn't look satisfied.",  482.  			    ESHK(shkp)->ismale ? "he" : "she"); 483. 		    else 484. 			make_happy_shk(shkp); 485. 		}  486.  		return(1); 487. 	}  488.   489.  	/* ltmp is still ESHK(shkp)->robbed here */ 490. 	if(!ESHK(shkp)->billct) { 491. 		if(!ltmp && NOTANGRY(shkp)) { 492. 		    You("do not owe %s anything.", mon_nam(shkp)); 493. 		    if(!u.ugold) pline(no_money); 494. 		} else if(ltmp) { 495. 		    pline("%s is after blood, not money!", mon_nam(shkp)); 496. 		    if(u.ugold < ltmp/2) { 497. 			if(!u.ugold) pline(no_money); 498. 			else pline("Besides, you don't have enough to interest %s.",  499.  				ESHK(shkp)->ismale ? "him" : "her"); 500. 			return(1); 501. 		    }  502.  		    pline("But since %s shop has been robbed recently,",  503.  			ESHK(shkp)->ismale ? "his" : "her"); 504. 		    pline("you %scompensate %s for %s losses.",  505.  			(u.ugold < ltmp) ? "partially " : "",  506.  			mon_nam(shkp),  507.  			ESHK(shkp)->ismale ? "his" : "her"); 508. 		    pay(u.ugold < ltmp ? u.ugold : ltmp, shkp); 509. 		    make_happy_shk(shkp); 510. 		} else { 511. 		    /* shopkeeper is angry, but has not been robbed -- 512. 		     * door broken, attacked, etc. */ 513. 		    pline("%s is after your hide, not your money!",  514.  					mon_nam(shkp)); 515. 		    if(u.ugold < 1000) { 516. 			if(!u.ugold) pline(no_money); 517. 			else 518. 		pline("Besides, you don't have enough to interest %s.",  519.  				ESHK(shkp)->ismale ? "him" : "her"); 520. 			return(1); 521. 		    }  522.  		    You("try to appease %s by giving %s 1000 gold pieces.",  523.  				a_monnam(shkp, "angry"),  524.  				ESHK(shkp)->ismale ? "him" : "her"); 525. 		    pay(1000L,shkp); 526. 		    if(strncmp(ESHK(shkp)->customer, plname, PL_NSIZ)  527.  		    		|| rn2(3)) 528. 			make_happy_shk(shkp); 529. 		    else 530. 			pline("But %s is as angry as ever.", Monnam(shkp)); 531. 		}  532.  		return(1); 533. 	}  534.  	if(shkp != shopkeeper) { 535. 		impossible("dopay: not to shopkeeper?"); 536. 		if(shopkeeper) setpaid; 537. 		return(0); 538. 	}  539.  	/* pay debt, if any, first */ 540. 	if(ESHK(shopkeeper)->debit) { 541. 	        You("owe %s %ld zorkmids for the use of merchandise.",  542.  			shkname(shopkeeper), ESHK(shopkeeper)->debit); 543. 	        if(u.ugold + ESHK(shopkeeper)->credit <  544.  					ESHK(shopkeeper)->debit) { 545. 		    pline("But you don't have enough gold%s.",  546.  			ESHK(shopkeeper)->credit ? " or credit" : ""); 547. 		    return(1); 548. 	        } else { 549. 		    long dtmp = ESHK(shopkeeper)->debit; 550.  551.  		    if(ESHK(shopkeeper)->credit >= dtmp) { 552. 			ESHK(shopkeeper)->credit -= dtmp; 553. 			ESHK(shopkeeper)->debit = 0L; 554. 	                Your("debt is covered by your credit."); 555. 		    } else if(!ESHK(shopkeeper)->credit) { 556. 			u.ugold -= dtmp; 557. 			shopkeeper->mgold += dtmp; 558. 			ESHK(shopkeeper)->debit = 0L; 559. 			You("pay that debt."); 560. 			flags.botl = 1; 561. 		    } else { 562. 			dtmp -= ESHK(shopkeeper)->credit; 563. 			ESHK(shopkeeper)->credit = 0L; 564. 			u.ugold -= dtmp; 565. 			shopkeeper->mgold += dtmp; 566. 			ESHK(shopkeeper)->debit = 0L; 567. 			pline("That debt is partially offset by your credit."); 568. 			You("pay the remainder."); 569. 			flags.botl = 1; 570. 		    }  571.  		}  572.  	}  573.  	for(pass = 0; pass <= 1; pass++) { 574. 		tmp = 0; 575. 		while(tmp < ESHK(shopkeeper)->billct) { 576. 		    bp = &bill[tmp]; 577. 		    if(!pass && !bp->useup) { 578. 			tmp++; 579. 			continue; 580. 		    }  581.  		    if(!dopayobj(bp)) return(1); 582. #ifdef MSDOS 583. 		    *bp = bill[--ESHK(shopkeeper)->billct]; 584. #else 585. 		    bill[tmp] = bill[--ESHK(shopkeeper)->billct]; 586. #endif /* MSDOS /**/ 587. 		}  588.  	}  589.  	pline("\"Thank you for shopping in %s's %s!\"",  590.  		shkname(shopkeeper),  591.  		shtypes[rooms[ESHK(shopkeeper)->shoproom].rtype - SHOPBASE].name); 592. 	NOTANGRY(shopkeeper) = 1; 593. 	return(1); 594. }  595.   596.  /* return 1 if paid successfully */ 597. /*        0 if not enough money */ 598. /*       -1 if object could not be found (but was paid) */ 599. static int 600. dopayobj(bp) 601. register struct bill_x *bp; 602. {  603.  	register struct obj *obj; 604. 	long ltmp; 605.  606.  	/* find the object on one of the lists */ 607. 	obj = bp_to_obj(bp); 608.  609.  	if(!obj) { 610. 		impossible("Shopkeeper administration out of order."); 611. 		setpaid;	/* be nice to the player */ 612. 		return(0); 613. 	}  614.   615.  	if(!obj->unpaid && !bp->useup){ 616. 		impossible("Paid object on bill??"); 617. 		return(1); 618. 	}  619.  	obj->unpaid = 0; 620. 	ltmp = bp->price * bp->bquan; 621. 	if(ANGRY(shopkeeper)) ltmp += ltmp/3; 622. 	if(u.ugold + ESHK(shopkeeper)->credit < ltmp){ 623. 		You("don't have gold%s enough to pay for %s.",  624.  			(ESHK(shopkeeper)->credit > 0L) ? " or credit" : "",  625.  			doname(obj)); 626. 		obj->unpaid = 1; 627. 		return(0); 628. 	}  629.  	pay(ltmp, shopkeeper); 630. 	You("bought %s for %ld gold piece%s.",  631.  		doname(obj), ltmp, plur(ltmp)); 632. 	if(bp->useup) { 633. 		register struct obj *otmp = billobjs; 634. 		if(obj == billobjs) 635. 			billobjs = obj->nobj; 636. 		else { 637. 			while(otmp && otmp->nobj != obj) otmp = otmp->nobj; 638. 			if(otmp) otmp->nobj = obj->nobj; 639. 			else pline("Error in shopkeeper administration."); 640. 		}  641.  		free((genericptr_t) obj); 642. 	}  643.  	return(1); 644. }  645.   646.  /* routine called after dying (or quitting) with nonempty bill or upset shk */ 647. boolean 648. paybill{ 649. 	register struct monst *mtmp; 650. 	register int loss = 0; 651. 	register struct obj *otmp; 652. 	register xchar ox, oy; 653. 	register boolean take = FALSE; 654. 	register boolean taken = FALSE; 655.  656.  	for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) 657. 	    if(mtmp->isshk) { 658. 		/* for bones: we don't want a shopless shk around */ 659. 		if(ESHK(mtmp)->shoplevel != dlevel) mongone(mtmp); 660. 		else shopkeeper = mtmp; 661. 	    }  662.   663.  	if(!shopkeeper) return(FALSE); 664.  665.  	/* get one case out of the way: you die in the shop, the */ 666. 	/* shopkeeper is peaceful, nothing stolen, nothing owed. */ 667.  	if(in_shop(u.ux,u.uy) && !IS_DOOR(levl[u.ux][u.uy].typ) &&  668.  	    !ESHK(shopkeeper)->billct && !ESHK(shopkeeper)->robbed &&  669.  	    inhishop(shopkeeper) && NOTANGRY(shopkeeper) &&  670.  	    !ESHK(shopkeeper)->following) { 671. 		pline("%s gratefully inherits all your possessions.",  672.  				Monnam(shopkeeper)); 673. 		goto clear; 674. 	}  675.   676.  	if(ESHK(shopkeeper)->billct || ESHK(shopkeeper)->robbed) { 677. 		addupbill; 678. 		loss = ((total >= ESHK(shopkeeper)->robbed) ? total :  679.  				ESHK(shopkeeper)->robbed); 680. 		take = TRUE; 681. 	}  682.   683.  	if(ESHK(shopkeeper)->following || ANGRY(shopkeeper) || take) { 684. 		if((loss > u.ugold) || !loss) { 685. 			pline("%s comes and takes all your possessions.",  686.  					Monnam(shopkeeper)); 687. 			taken = TRUE; 688. 			shopkeeper->mgold += u.ugold; 689. 			u.ugold = 0; 690. 			/* in case bones: make it be for real... */ 691.  			if(!in_shop(u.ux, u.uy) || IS_DOOR(levl[u.ux][u.uy].typ)) { 692. 			    /* shk.x,shk.y is the position immediately in  693. * front of the door -- move in one more space 694. 			     */  695.  			    ox = ESHK(shopkeeper)->shk.x;  696. oy = ESHK(shopkeeper)->shk.y; 697. ox += sgn(ox - ESHK(shopkeeper)->shd.x); 698. 			    oy += sgn(oy - ESHK(shopkeeper)->shd.y); 699. 			} else { 700. 			    ox = u.ux; 701. 			    oy = u.uy; 702. 			}  703.   704.  			if (invent) { 705. 			    levl[ox][oy].omask = 1; 706. 			    for(otmp = invent; otmp; otmp = otmp->nobj) { 707. 				otmp->ox = ox; 708. 				otmp->oy = oy; 709. 				otmp->age = 0; 710. 			    }  711.   712.  			    /* add to main object list at end so invent is  713. still good */ 714. 			    if (fobj) { 715. 				otmp = fobj; 716. 				while(otmp->nobj) 717. 				    otmp = otmp->nobj; 718. 				otmp->nobj = invent; 719. 			    } else 720. 				fobj = invent; 721. 			}  722.  		} else { 723. 			u.ugold -= loss; 724. 			shopkeeper->mgold += loss; 725. 			pline("%s comes and takes %ld zorkmids %sowed %s.",  726.  			       Monnam(shopkeeper),  727.  			       loss,  728.  			       strncmp(ESHK(shopkeeper)->customer, plname, PL_NSIZ) ? "" : "you ",  729.  			       ESHK(shopkeeper)->ismale ? "him" : "her"); 730. 		}  731.   732.  		/* in case we create bones */ 733. 		if(!inhishop(shopkeeper)) 734. 			home_shk(shopkeeper); 735. 	}  736.  clear: 737. 	setpaid; 738. 	return(taken); 739. }  740.   741.  /* find obj on one of the lists */ 742. static struct obj * 743. bp_to_obj(bp) 744. register struct bill_x *bp; 745. {  746.  	register struct obj *obj; 747. 	register struct monst *mtmp; 748. 	register unsigned int id = bp->bo_id; 749.  750.  	if(bp->useup) 751. 		obj = o_on(id, billobjs); 752. 	else if(!(obj = o_on(id, invent)) &&  753.  		!(obj = o_on(id, fobj)) &&  754.  		!(obj = o_on(id, fcobj))) { 755. 		    for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) 756. 			if(obj = o_on(id, mtmp->minvent)) 757. 			    break; 758. 		    for(mtmp = fallen_down; mtmp; mtmp = mtmp->nmon) 759. 			if(obj = o_on(id, mtmp->minvent)) 760. 			    break; 761. 		}  762.  	return(obj); 763. }  764.   765.  static long 766. get_cost(obj) 767. register struct obj *obj; 768. {  769.  	register long tmp; 770.  771.  	tmp = getprice(obj); 772. 	if (!tmp) tmp = 5; 773. 	if (ANGRY(shopkeeper) ||  774.  		(pl_character[0] == 'T' && u.ulevel < (MAXULEV/2))  775.  #ifdef SHIRT  776.  	    || (uarmu && !uarm) /* wearing just a Hawaiian shirt */  777.  #endif  778.  	   ) 779. 		tmp += tmp/3; 780. 	if (ACURR(A_CHA) > 18)		tmp /= 2; 781. 	else if (ACURR(A_CHA) > 17)	tmp = (tmp * 2)/3; 782. 	else if (ACURR(A_CHA) > 15)	tmp = (tmp * 3)/4; 783. 	else if (ACURR(A_CHA) < 11)	tmp = (tmp * 4)/3; 784. 	else if (ACURR(A_CHA) < 8)	tmp = (tmp * 3)/2; 785. 	else if (ACURR(A_CHA) < 6)	tmp *= 2; 786. 	return(tmp); 787. }  788.   789.   790.  /* called in hack.c when we pickup an object */ 791. void 792. addtobill(obj, ininv) 793. register struct obj *obj; 794. register boolean ininv; 795. {  796.  	register struct bill_x *bp; 797. 	char	buf[40]; 798. 	if(!shopkeeper || !inhishop(shopkeeper)) return; 799.  800.  	if(!costly_spot(obj->ox,obj->oy) ||	/* either pickup or kick */  801.  		onbill(obj) /* perhaps we threw it away earlier */  802.  	      ) return; 803. 	if(ESHK(shopkeeper)->billct == BILLSZ) { 804. 		You("got that for free!"); 805. 		return; 806. 	}  807.  	/* To recognize objects the shopkeeper is not interested in. -dgk 808. 	 */  809.  	if (obj->no_charge) { 810. 		obj->no_charge = 0; 811. 		return; 812. 	}  813.  	bp = &bill[ESHK(shopkeeper)->billct]; 814. 	bp->bo_id = obj->o_id; 815. 	bp->bquan = obj->quan; 816. 	bp->useup = 0; 817. 	bp->price = get_cost(obj); 818. 	Strcpy(buf, "\"For you, ");  819.  	if (ANGRY(shopkeeper)) Strcat(buf, "scum ");  820.  	else {  821.  	    switch(rnd(4)  822.  #ifdef HARD  823.  		   + u.udemigod  824.  #endif  825.  				) {  826.  		case 1:	Strcat(buf, "good");  827.  			break;  828.  		case 2:	Strcat(buf, "honored");  829.  			break;  830.  		case 3:	Strcat(buf, "most gracious");  831.  			break;  832.  		case 4:	Strcat(buf, "esteemed");  833.  			break;  834.  		case 5: if (u.ualigntyp == U_CHAOTIC) Strcat(buf, "un");  835.  			Strcat(buf, "holy");  836.  			break;  837.  	    }  838.  #ifdef POLYSELF  839.  	    if(!is_human(uasmon)) Strcat(buf, " creature");  840.  	    else  841.  #endif  842.  		Strcat(buf, (flags.female) ? " lady" : " sir");  843.  	}  844.  	obj->dknown = 1; /* after all, the shk is telling you what it is */  845.  	if(ininv) {  846.  		obj->quan = 1; /* fool xname into giving singular */ 847. 		pline("%s; only %d %s %s.\"", buf, bp->price,  848.  			(bp->bquan > 1) ? "per" : "for this", xname(obj));  849.  		obj->quan = bp->bquan;  850.  	} else pline("The %s will cost you %d zorkmids%s.",  851.  			xname(obj), bp->price,  852.  			(bp->bquan > 1) ? " each" : "");  853.  	ESHK(shopkeeper)->billct++;  854.  	obj->unpaid = 1;  855.  }  856.   857.  void  858.  splitbill(obj, otmp)  859.  register struct obj *obj, *otmp;  860.  {  861.  	/* otmp has been split off from obj */  862.  	register struct bill_x *bp;  863.  	register int tmp;  864.  	bp = onbill(obj);  865.  	if(!bp) {  866.  		impossible("splitbill: not on bill?");  867.  		return;  868.  	}  869.  	if(bp->bquan < otmp->quan) {  870.  		impossible("Negative quantity on bill??");  871.  	}  872.  	if(bp->bquan == otmp->quan) {  873.  		impossible("Zero quantity on bill??");  874.  	}  875.  	bp->bquan -= otmp->quan; 876.  877.  	if(ESHK(shopkeeper)->billct == BILLSZ) otmp->unpaid = 0; 878. 	else { 879. 		tmp = bp->price; 880. 		bp = &bill[ESHK(shopkeeper)->billct]; 881. 		bp->bo_id = otmp->o_id; 882. 		bp->bquan = otmp->quan; 883. 		bp->useup = 0; 884. 		bp->price = tmp; 885. 		ESHK(shopkeeper)->billct++; 886. 	}  887.  }  888.   889.  void 890. subfrombill(obj) 891. register struct obj *obj; 892. {  893.  	long ltmp; 894. 	/* register int tmp;	/* use of tmp commented out below */ 895. 	register struct obj *otmp; 896. 	register struct bill_x *bp; 897. 	if(!costly_spot(u.ux,u.uy)) 898. 		return; 899. 	if((bp = onbill(obj)) != 0) { 900. 		obj->unpaid = 0; 901. 		if(bp->bquan > obj->quan){ 902. 			otmp = newobj(0); 903. 			*otmp = *obj; 904. 			bp->bo_id = otmp->o_id = flags.ident++; 905. 			otmp->quan = (bp->bquan -= obj->quan); 906. 			otmp->owt = 0;	/* superfluous */ 907. 			otmp->onamelth = 0; 908. 			bp->useup = 1; 909. 			otmp->nobj = billobjs; 910. 			billobjs = otmp; 911. 			return; 912. 		}  913.  		ESHK(shopkeeper)->billct--; 914. 		*bp = bill[ESHK(shopkeeper)->billct]; 915. 		return; 916. 	}  917.  	if(obj->unpaid) { 918. 		if(inhishop(shopkeeper)) 919. 		    pline("%s didn't notice.", Monnam(shopkeeper)); 920. 		obj->unpaid = 0; 921. 		return;		/* %% */ 922. 	}  923.  	/* he dropped something of his own - probably wants to sell it */ 924. 	if(shopkeeper->msleep || shopkeeper->mfroz || !inhishop(shopkeeper)) 925. 		return; 926. 	ltmp = getprice(obj) * obj->quan; 927. 	if(ESHK(shopkeeper)->billct == BILLSZ  928.  	   || !saleable(rooms[ESHK(shopkeeper)->shoproom].rtype-SHOPBASE, obj)  929.  	   || otmp->olet == BALL_SYM || ltmp == 0L) { 930. 		pline("%s seems not interested.", Monnam(shopkeeper)); 931. 		obj->no_charge = 1; 932. 		return; 933. 	}  934.  	if (ANGRY(shopkeeper) || (pl_character[0] == 'T' && u.ulevel < (MAXULEV/2))  935.  #ifdef SHIRT  936.  	    || (uarmu && !uarm) /* wearing just a Hawaiian shirt */  937.  #endif  938.  	   ) { 939. 		ltmp /= 3; 940. 		NOTANGRY(shopkeeper) = 1; 941. 	} else	ltmp /= 2; 942. 	if(ESHK(shopkeeper)->robbed) { 943. 		if((ESHK(shopkeeper)->robbed -= ltmp) < 0) 944. 			ESHK(shopkeeper)->robbed = 0; 945. pline("\"Thank you for your contribution to restock this recently plundered shop.\""); 946. 		return; 947. 	}  948.  	if(ltmp > shopkeeper->mgold) 949. 		ltmp = shopkeeper->mgold; 950. 	pay(-ltmp, shopkeeper); 951. 	if(!ltmp) { 952. 		pline("%s gladly accepts %s but cannot pay you at present.",  953.  			Monnam(shopkeeper), doname(obj)); 954. 			obj->no_charge = 1; 955. 	} else 956. 	You("sold %s for %ld gold piece%s.", doname(obj), ltmp,  957.  		plur(ltmp)); 958. }  959.   960.  int 961. doinvbill(mode) 962. int mode;		/* 0: deliver count 1: paged */ 963. {  964.  	register struct bill_x *bp; 965. 	register struct obj *obj; 966. 	long totused, thisused; 967. 	char buf[BUFSZ]; 968.  969.  	if(mode == 0) { 970. 	    register int cnt = 0; 971.  972.  	    if(shopkeeper) 973. 		for(bp = bill; bp - bill < ESHK(shopkeeper)->billct; bp++) 974. 		    if(bp->useup ||  975.  		      ((obj = bp_to_obj(bp)) && obj->quan < bp->bquan)) 976. 			cnt++; 977. 	    return(cnt); 978. 	}  979.   980.  	if(!shopkeeper) { 981. 		impossible("doinvbill: no shopkeeper?"); 982. 		return(0); 983. 	}  984.   985.  	set_pager(0); 986. 	if(page_line("Unpaid articles already used up:") || page_line("")) 987. 	    goto quit; 988.  989.  	totused = 0; 990. 	for(bp = bill; bp - bill < ESHK(shopkeeper)->billct; bp++) { 991. 	    obj = bp_to_obj(bp); 992. 	    if(!obj) { 993. 		impossible("Bad shopkeeper administration."); 994. 		goto quit; 995. 	    }  996.  	    if(bp->useup || bp->bquan > obj->quan) { 997. 		register int cnt, oquan, uquan; 998.  999.  		oquan = obj->quan; 1000. 		uquan = (bp->useup ? bp->bquan : bp->bquan - oquan); 1001. 		thisused = bp->price * uquan; 1002. 		totused += thisused; 1003. 		obj->quan = uquan;		/* cheat doname */ 1004. 		Sprintf(buf, "x - %s", doname(obj)); 1005. 		obj->quan = oquan;		/* restore value */ 1006. 		for(cnt = 0; buf[cnt]; cnt++); 1007. 		while(cnt < 50) 1008. 			buf[cnt++] = ' '; 1009. 		Sprintf(&buf[cnt], " %5ld zorkmids", thisused); 1010. 		if(page_line(buf)) 1011. 			goto quit; 1012. 	   }  1013. 	}  1014. 	Sprintf(buf, "Total:%50ld zorkmids", totused); 1015. 	if(page_line("") || page_line(buf)) 1016. 		goto quit; 1017. 	set_pager(1); 1018. 	return(0); 1019. quit: 1020. 	set_pager(2); 1021. 	return(0); 1022. } 1023.  1024. #define HUNGRY	2 1025. static int 1026. getprice(obj) 1027. register struct obj *obj; 1028. { 1029. 	register int tmp = objects[obj->otyp].oc_cost; 1030. 1031. 	switch(obj->olet) { 1032. 	case AMULET_SYM: 1033. 		if(obj->otyp == AMULET_OF_YENDOR) { 1034. 			/* don't let the player get rich selling fakes */ 1035. 			tmp = (obj->spe < 0 ? 0 : 3500); 1036. 		} 1037. 		break; 1038. 	case FOOD_SYM: 1039. 		/* simpler hunger check, (2-4)*cost */ 1040. 		if (u.uhs >= HUNGRY) tmp *= u.uhs; 1041. 		break; 1042. 	case WAND_SYM: 1043. 		if (obj->spe == -1) tmp = 0; 1044. 		break; 1045. 	case POTION_SYM: 1046. 		if (obj->otyp == POT_WATER && !obj->blessed && !obj->cursed) 1047. 			tmp = 0; 1048. 		break; 1049. 	case ARMOR_SYM: 1050. 		if (u.uac > 0) tmp += u.uac * 2; 1051. 	case WEAPON_SYM: 1052. 		if (obj->spe > 0) tmp += 10 * obj->spe; 1053. 		break; 1054. 	case CHAIN_SYM: 1055. 		pline("Strange... carrying a chain?"); 1056. 		break; 1057. 	} 1058. 	return(tmp); 1059. } 1060.  1061. int 1062. shkcatch(obj) 1063. register struct obj *obj; 1064. { 1065. 	register struct monst *shkp = shopkeeper; 1066. 1067. 	if(u.uinshop && shkp && !shkp->mfroz && !shkp->msleep &&  1068. 	    u.dx && u.dy &&  1069. 	    inroom(u.ux+u.dx, u.uy+u.dy) + 1 == u.uinshop &&  1070. 	    shkp->mx == ESHK(shkp)->shk.x && shkp->my == ESHK(shkp)->shk.y &&  1071. 	    u.ux == ESHK(shkp)->shd.x && u.uy == ESHK(shkp)->shd.y) { 1072. 		pline("%s nimbly catches the %s.", Monnam(shkp), xname(obj)); 1073. 		obj->nobj = shkp->minvent; 1074. 		shkp->minvent = obj; 1075. 		return(1); 1076. 	} 1077. 	return(0); 1078. } 1079.  1080. /*  1081.  * shk_move: return 1: he moved  0: he didn't  -1: let m_move do it  -2: died 1082. */  1083. int 1084. shk_move(shkp) 1085. register struct monst *shkp; 1086. { 1087. 	register xchar gx,gy,omx,omy; 1088. 	register int udist; 1089. 	register schar appr; 1090. 	int z; 1091. schar shkroom; 1092. 	boolean uondoor, satdoor, avoid, badinv; 1093. 1094. 	omx = shkp->mx; 1095. 	omy = shkp->my; 1096. 1097. 	if((udist = dist(omx,omy)) < 3) { 1098. 		if(ANGRY(shkp)) { 1099. 			if(Displaced) 1100. 			 Your("displaced image doesn't fool %s!",  1101. 				Monnam(shkp)); 1102. 			(void) mattacku(shkp); 1103. 			return(0); 1104. 		} 1105. 		if(ESHK(shkp)->following) { 1106. 			if(strncmp(ESHK(shkp)->customer, plname, PL_NSIZ)) { 1107. 			   pline("\"Hello, %s!  I was looking for %s.\"",  1108. 				    plname, ESHK(shkp)->customer); 1109. 				   ESHK(shkp)->following = 0; 1110. 			   return(0); 1111. 			} 1112. 			if(moves > followmsg+4) { 1113. 			   pline("\"Hello, %s!  Didn't you forget to pay?\"",  1114. 				    plname); 1115. 			   followmsg = moves; 1116. #ifdef HARD 1117. 			   if (!rn2(4)) { 1118. 	   pline ("%s doesn't like customers who don't pay.", Monnam(shkp)); 1119. 				NOTANGRY(shkp) = 0; 1120. 			   }  1121. #endif 1122. 			} 1123. 			if(udist < 2) 1124. 			   return(0); 1125. 		} 1126. 	}  1127.  1128. 	shkroom = inroom(omx,omy); 1129. 	appr = 1; 1130. 	gx = ESHK(shkp)->shk.x; 1131. gy = ESHK(shkp)->shk.y; 1132. satdoor = (gx == omx && gy == omy); 1133. 	if(ESHK(shkp)->following || ((z = holetime) >= 0 && z*z <= udist)){ 1134. 		gx = u.ux; 1135. 		gy = u.uy; 1136. 		if(shkroom < 0 || shkroom != inroom(u.ux,u.uy)) 1137. 		   if(udist > 4) 1138. 			return(-1);	/* leave it to m_move */ 1139. 	} else if(ANGRY(shkp)) { 1140. 		long saveBlind = Blinded; 1141. 		struct obj *saveUblindf = ublindf; 1142. 		Blinded = 0; 1143. 		ublindf = (struct obj *)0; 1144. 		if(shkp->mcansee && !Invis && cansee(omx,omy)) { 1145. 			gx = u.ux; 1146. 			gy = u.uy; 1147. 		} 1148. 		Blinded = saveBlind; 1149. 		ublindf = saveUblindf; 1150. 		avoid = FALSE; 1151. 	} else { 1152. #define	GDIST(x,y)	(dist2(x,y,gx,gy)) 1153. 		if(Invis) 1154. 		   avoid = FALSE; 1155. 		else { 1156. 		   uondoor = (u.ux == ESHK(shkp)->shd.x &&  1157. 				u.uy == ESHK(shkp)->shd.y); 1158. 		   if(uondoor) { 1159. 			if(ESHK(shkp)->billct && inhishop(shkp)) 1160. 			   pline(NOTANGRY(shkp) ?  1161. 				"\"Hello, %s!  Will you please pay before leaving?\"" :  1162. 				"\"Hey, %s!  Don't leave without paying!\"",  1163. 				plname); 1164. 			badinv = (!!carrying(PICK_AXE)); 1165. 			if(satdoor && badinv) 1166. 			   return(0); 1167. 			avoid = !badinv; 1168. 		   } else { 1169. 			avoid = (u.uinshop && dist(gx,gy) > 8); 1170. 			badinv = FALSE; 1171. 		   }  1172.  1173. 		    if(((!ESHK(shkp)->robbed && !ESHK(shkp)->billct) || avoid)  1174. 			&& GDIST(omx,omy) < 3) { 1175. 			if(!badinv && !online(omx,omy)) 1176. 			   return(0); 1177. 			if(satdoor) 1178. 			   appr = gx = gy = 0; 1179. 		   }  1180. 		}  1181. 	}  1182. 	  1183. 	return(move_special(shkp,shkroom,appr,uondoor,avoid,omx,omy,gx,gy)); 1184. } 1185.  1186. int 1187. online(x,y)		/*	New version to speed things up. 1188. 			 *	Compiler dependant, may not always work. 1189. 			 */ 1190. register xchar x, y;  1191. { 1192. 	return((x-=u.ux) == 0 || (y-=u.uy) == 0 || x == y || (x+=y) == 0); 1193. } 1194.  1195. /*			Original version, just in case...  1196. *online(x,y) { 1197. *	return(x==u.ux || y==u.uy || (x-u.ux)*(x-u.ux) == (y-u.uy)*(y-u.uy)); 1198. *}  1199.  */  1200.  1201. /* for use in levl_follower (mondata.c) */ 1202. boolean 1203. is_fshk(mtmp) 1204. register struct monst *mtmp; 1205. { 1206. 	return(mtmp->isshk && ESHK(mtmp)->following); 1207. } 1208.  1209. /* He is digging in the shop. */ 1210. void 1211. shopdig(fall) 1212. register int fall; 1213. { 1214.     if(!shopkeeper) return; 1215.    if(!inhishop(shopkeeper)) { 1216. 	if (pl_character[0] == 'K') adjalign(-sgn(u.ualigntyp)); 1217. 	return; 1218.    }  1219.  1220.     if(!fall) { 1221. 	if(u.utraptype == TT_PIT) 1222. 	   pline("\"Be careful, %s, or you might fall through the floor.\"",  1223. 		flags.female ? "madam" : "sir"); 1224. 	else 1225. 	   pline("\"%s, do not damage the floor here!\"",  1226. 			flags.female ? "Madam" : "Sir"); 1227. 	if (pl_character[0] == 'K') adjalign(-sgn(u.ualigntyp)); 1228.    } else if(um_dist(shopkeeper->mx, shopkeeper->my, 2)) { 1229. 	register struct obj *obj, *obj2; 1230. 1231. 	if(dist(shopkeeper->mx, shopkeeper->my) > 2) { 1232. 		mnexto(shopkeeper); 1233. 		/* for some reason he can't come next to you */ 1234. 		if(dist(shopkeeper->mx, shopkeeper->my) > 2) { 1235. 		   pline("%s curses you in anger and frustration!",  1236. 					shkname(shopkeeper)); 1237. 		   NOTANGRY(shopkeeper) = 0; 1238. 		   return; 1239. 		} else pline("%s leaps, and grabs your backpack!", 1240. 					shkname(shopkeeper)); 1241. 	} else pline("%s grabs your backpack!", shkname(shopkeeper)); 1242. 1243. 	for(obj = invent; obj; obj = obj2) { 1244. 		obj2 = obj->nobj; 1245. 		if(obj->owornmask) continue; 1246. 		freeinv(obj); 1247. 		obj->nobj = shopkeeper->minvent; 1248. 		shopkeeper->minvent = obj; 1249. 		if(obj->unpaid) 1250. 			subfrombill(obj); 1251. 	} 1252.     }  1253. }  1254.  1255. #ifdef KOPS 1256. static int 1257. makekops(mm)		/* returns the number of (all types of) Kops made */ 1258. coord *mm; 1259. { 1260. 	register int cnt = dlevel + rnd(5); 1261. 	register int scnt = (cnt / 3) + 1;	/* at least one sarge */ 1262. 	register int lcnt = (cnt / 6);		/* maybe a lieutenant */ 1263. 	register int kcnt = (cnt / 9);		/* and maybe a kaptain */ 1264. 1265. 	while(cnt--) { 1266. 	   enexto(mm, mm->x, mm->y); 1267. 	   (void) makemon(&mons[PM_KEYSTONE_KOP], mm->x, mm->y); 1268. 	} 1269. 	while(scnt--) { 1270. 	   enexto(mm, mm->x, mm->y); 1271. 	   (void) makemon(&mons[PM_KOP_SERGEANT], mm->x, mm->y); 1272. 	} 1273. 	while(lcnt--) { 1274. 	   enexto(mm, mm->x, mm->y); 1275. 	   (void) makemon(&mons[PM_KOP_LIEUTENANT], mm->x, mm->y); 1276. 	} 1277. 	while(kcnt--) { 1278. 	   enexto(mm, mm->x, mm->y); 1279. 	   (void) makemon(&mons[PM_KOP_KAPTAIN], mm->x, mm->y); 1280. 	} 1281. 	return(cnt + scnt + lcnt + kcnt); 1282. } 1283. #endif 1284. 1285. boolean 1286. in_shop(x,y) 1287. register int x, y; 1288. { 1289. 	register int roomno = inroom(x, y); 1290. 1291. 	if (roomno < 0) return(FALSE); 1292. 	return (IS_SHOP(rooms[roomno])); 1293. } 1294.  1295. void 1296. pay_for_door(x,y,dmgstr) 1297. register int x, y; 1298. register char *dmgstr; 1299. { 1300. 	register struct monst *mtmp; 1301. 	register int ox, oy; 1302. 	register int roomno = inroom(x, y); 1303. 	register int damage = (ACURR(A_STR) > 18) ? 400 : 20 * ACURR(A_STR); 1304. 1305. 	/* make sure this function is not used in the wrong place */ 1306. 	if(!(IS_DOOR(levl[x][y].typ) && in_shop(x, y))) return; 1307. 1308. 	for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) 1309. 	   if(mtmp->isshk && ESHK(mtmp)->shoproom == roomno  1310. 			   && ESHK(mtmp)->shoplevel == dlevel) { 1311. 		shopkeeper = mtmp; 1312. 	} 1313.  1314. 	if(!shopkeeper) return; 1315. 1316. 	/* not the best introduction to the shk... */ 1317. 	(void) strncpy(ESHK(shopkeeper)->customer,plname,PL_NSIZ); 1318. 1319. 	/* if he is already on the war path, be sure it's all out */ 1320. 	if(ANGRY(shopkeeper) || ESHK(shopkeeper)->following) { 1321. 		NOTANGRY(shopkeeper) = 0; 1322. 		ESHK(shopkeeper)->following = 1; 1323. 		return; 1324. 	} 1325.  1326. 	ox = shopkeeper->mx; 1327. 	oy = shopkeeper->my; 1328. 1329. 	/* if he's not in his shop.. */ 1330. 	if(!in_shop(ox, oy)) return; 1331. 1332. 	/* if a !shopkeeper shows up at the door, move him */ 1333. 	if(levl[x][y].mmask && (mtmp = m_at(x, y)) != shopkeeper) { 1334. 		if(flags.soundok) { 1335. 		   You("hear an angry voice: \"Out of my way, scum!\""); 1336. 		   (void) fflush(stdout); 1337. #if defined(SYSV) || defined(ULTRIX) 1338. 		   (void) 1339. #endif 1340. #ifdef UNIX 1341. 			sleep(1); 1342. #endif 1343. 		} 1344. 		mnearto(mtmp, x, y, FALSE); 1345. 	} 1346.  1347. 	/* make shk show up at the door */ 1348. 	levl[shopkeeper->mx][shopkeeper->my].mmask = 0; 1349. 	levl[x][y].mmask = 1; 1350. 	shopkeeper->mx = x; 1351. shopkeeper->my = y; 1352. pmon(shopkeeper); 1353. 1354. 	if(um_dist(x, y, 1)) goto chase; 1355. 1356. 	if(u.ugold < damage || !rn2(50)) { 1357. chase: 1358. 		if(um_dist(x, y, 1)) 1359. 		   pline("%s shouts: \"Who dared %s my door?\"",  1360. 				shkname(shopkeeper), dmgstr); 1361. 		else pline("\"How dare you %s my door?\"", dmgstr); 1362. 		NOTANGRY(shopkeeper) = 0; 1363. 		ESHK(shopkeeper)->following = 1; 1364. 		return; 1365. 	} 1366.  1367. 	pline("\"Cad!  You did %d zorkmids worth of damage!\"  Pay? ", damage); 1368. 	if(yn != 'n') { 1369. 		u.ugold -= damage; 1370. 		shopkeeper->mgold += damage; 1371. 		flags.botl = 1; 1372. 		pline("Mollified, %s accepts your restitution.", 1373. 			shkname(shopkeeper)); 1374. 1375. 		/* clear ox oy of another monster, if one got there somehow */ 1376. 		if(levl[ox][oy].mmask) mnearto(m_at(ox,oy),ox,oy,FALSE); 1377. 1378. 		/* move shk back to his orig loc */ 1379. 		levl[shopkeeper->mx][shopkeeper->my].mmask = 0; 1380. 		levl[ox][oy].mmask = 1; 1381. 		shopkeeper->mx = ox; 1382. 		shopkeeper->my = oy; 1383. 		unpmon(shopkeeper); 1384. 		NOTANGRY(shopkeeper) = 1; 1385. 	} 1386. 	else { 1387. 		pline("\"Oh, yes! You'll pay!\""); 1388. 		ESHK(shopkeeper)->following = 1; 1389. 		NOTANGRY(shopkeeper) = 0; 1390. 		adjalign(-sgn(u.ualigntyp)); 1391. 	} 1392. }  1393.  1394. /* called in dokick.c when we kick an object in a store */ 1395. boolean 1396. costly_spot(x, y) 1397. register int x, y; 1398. { 1399. 	register struct monst *shkp = shopkeeper; 1400. 	 1401. 	if(!shkp) return(FALSE); 1402. 1403. 	return(in_shop(x, y) && levl[x][y].typ != DOOR &&  1404. 		!(x == ESHK(shkp)->shk.x && y == ESHK(shkp)->shk.y)); 1405. } 1406.  1407. #ifdef KOPS 1408. static void 1409. kops_gone 1410. { 1411. 	register int cnt = 0; 1412. 	register struct monst *mtmp, *mtmp2; 1413. 1414. 	/* turn off automatic resurrection of kops */ 1415. 	allow_kops = FALSE; 1416. 1417. 	for(mtmp = fmon; mtmp; mtmp = mtmp2) { 1418. 		mtmp2 = mtmp->nmon; 1419. 		if(mtmp->data->mlet == S_KOP) { 1420. 			mongone(mtmp); 1421. 			cnt++; 1422. 		} 1423. 	}  1424. 	if(cnt) pline("The Kops (disappointed) disappear into thin air."); 1425. 	allow_kops = TRUE; 1426. } 1427. #endif 1428. 1429. static long 1430. cost_per_charge(otmp) 1431. register struct obj *otmp; 1432. { 1433. 	register long tmp = get_cost(otmp); 1434. 1435. 	/* The idea is to make the exhaustive use of */ 1436. 	/* an unpaid item more expansive than buying */ 1437. 	/* outright. */ 1438. 	if(otmp->otyp == MAGIC_LAMP) {			 /* 1 */ 1439. 		tmp += (tmp/3L); 1440. 	} else if(otmp->otyp == MAGIC_MARKER) { 	 /* 70 - 100 */ 1441. 		/* no way to determine in advance  */ 1442. 		/* how many charges will be wasted. */ 1443. 		/* so, arbitrarily, one half of the */ 1444. 		/* price per use. */ 1445. 		tmp = (tmp/2L); 1446. 	} else if(otmp->otyp == BAG_OF_TRICKS) { 	 /* 1 - 20 */ 1447. 		tmp = (tmp/5L); 1448. 	} else if(otmp->otyp == CRYSTAL_BALL || 	 /* 1 - 5 */  1449. 		  otmp->otyp == LAMP ||	                 /* 1-10 */  1450. #ifdef MUSIC  1451. 		 (otmp->otyp >= MAGIC_FLUTE && 1452. 		 otmp->otyp <= DRUM_OF_EARTHQUAKE) || 	 /* 5 - 9 */  1453. #endif  1454. 	  	  otmp->olet == WAND_SYM) {		 /* 3 - 11 */ 1455. 		if(otmp->spe == 1) tmp += (tmp/3L); 1456. 		else tmp = (tmp/4L); 1457. 	} 1458. 	else return(0L); 1459. 	return(tmp); 1460. } 1461.  1462. /* for using charges of unpaid objects */ 1463. void 1464. check_unpaid(otmp) 1465. register struct obj *otmp; 1466. { 1467. 	if(!in_shop(u.ux, u.uy)) return; 1468. 	 1469. 	if(otmp->spe <= 0) return; 1470. 1471. 	if(otmp->unpaid) { 1472. 		ESHK(shopkeeper)->debit += cost_per_charge(otmp); 1473. 	} 1474. }