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