About: Source:NetHack 1.4f/shk.c   Sponge Permalink

An Entity of Type : owl:Thing, within Data Space : 134.155.108.49:8890 associated with source dataset(s)

Below is the full text to shk.c from the source code of NetHack 1.4f. To link to a particular line, write [[NetHack 1.4f/shk.c#line123]], for example. Warning! This is the source code from an old release. For the latest release, see Source code

AttributesValues
rdfs:label
  • Source:NetHack 1.4f/shk.c
rdfs:comment
  • Below is the full text to shk.c from the source code of NetHack 1.4f. To link to a particular line, write [[NetHack 1.4f/shk.c#line123]], for example. Warning! This is the source code from an old release. For the latest release, see Source code
dcterms:subject
dbkwik:nethack/pro...iPageUsesTemplate
abstract
  • Below is the full text to shk.c from the source code of NetHack 1.4f. To link to a particular line, write [[NetHack 1.4f/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 1.4 87/08/08 2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3. /* shk.c - version 1.0.3 */ 4. 5. #include "hack.h" 6. #ifdef QUEST 7. int shlevel = 0; 8. struct monst *shopkeeper = 0; 9. struct obj *billobjs = 0; 10. obfree(obj,merge) register struct obj *obj, *merge; { 11. free((char *) obj); 12. } 13. inshop(){ return(0); } 14. addtobill(){} 15. subfrombill(){} 16. splitbill(){} 17. dopay(){ return(0); } 18. paybill(){} 19. doinvbill(){ return(0); } 20. shkdead(){} 21. shkcatch(){ return(0); } 22. shk_move(){ return(0); } 23. replshk(mtmp,mtmp2) struct monst *mtmp, *mtmp2; {} 24. char *shkname(){ return(""); } 25. 26. #else 27. #include "mfndpos.h" 28. #include "mkroom.h" 29. #include "eshk.h" 30. 31. #define ESHK(mon) ((struct eshk *)(&(mon->mextra[0]))) 32. #define NOTANGRY(mon) mon->mpeaceful 33. #define ANGRY(mon) !NOTANGRY(mon) 34. 35. extern char plname[], *xname(); 36. extern struct obj *o_on(), *bp_to_obj(); 37. 38. /* Descriptor of current shopkeeper. Note that the bill need not be 39. per-shopkeeper, since it is valid only when in a shop. */ 40. static struct monst *shopkeeper = 0; 41. static struct bill_x *bill; 42. static int shlevel = 0; /* level of this shopkeeper */ 43. struct obj *billobjs; /* objects on bill with bp->useup */ 44. /* only accessed here and by save & restore */ 45. static long int total; /* filled by addupbill() */ 46. static long int followmsg; /* last time of follow message */ 47. static setpaid(), findshk(), dopayobj(), getprice(), realhunger(); 48. 49. /* 50. invariants: obj->unpaid iff onbill(obj) [unless bp->useup] 51. obj->quan <= bp->bquan 52. */ 53. 54. 55. char shtypes[] = { /* 9 shoptypes: 8 specialized, 1 mixed */ 56. RING_SYM, WAND_SYM, 57. #ifdef SPELLS 58. SPBOOK_SYM, 59. #endif 60. WEAPON_SYM, FOOD_SYM, SCROLL_SYM, POTION_SYM, ARMOR_SYM, 0 61. }; 62. char *shopnam[] = { 63. "engagement ring", "walking cane", 64. #ifdef SPELLS 65. "rare book", 66. #endif 67. "antique weapon", "delicatessen", "second hand book", 68. "liquor", "used armor", "assorted antiques" 69. }; 70. 71. char * 72. shkname(mtmp) /* called in do_name.c */ 73. register struct monst *mtmp; 74. { 75. return(ESHK(mtmp)->shknam); 76. } 77. 78. shkdead(mtmp) /* called in mon.c */ 79. register struct monst *mtmp; 80. { 81. register struct eshk *eshk = ESHK(mtmp); 82. 83. if(eshk->shoplevel == dlevel) 84. rooms[eshk->shoproom].rtype = 0; 85. if(mtmp == shopkeeper) { 86. setpaid(); 87. shopkeeper = 0; 88. bill = (struct bill_x *) -1000; /* dump core when referenced */ 89. } 90. } 91. 92. replshk(mtmp,mtmp2) 93. register struct monst *mtmp, *mtmp2; 94. { 95. if(mtmp == shopkeeper) { 96. shopkeeper = mtmp2; 97. bill = &(ESHK(shopkeeper)->bill[0]); 98. } 99. } 100. 101. static 102. setpaid(){ /* caller has checked that shopkeeper exists */ 103. /* either we paid or left the shop or he just died */ 104. register struct obj *obj; 105. register struct monst *mtmp; 106. for(obj = invent; obj; obj = obj->nobj) 107. obj->unpaid = 0; 108. for(obj = fobj; obj; obj = obj->nobj) 109. obj->unpaid = 0; 110. for(obj = fcobj; obj; obj = obj->nobj) 111. obj->unpaid = 0; 112. for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) 113. for(obj = mtmp->minvent; obj; obj = obj->nobj) 114. obj->unpaid = 0; 115. for(mtmp = fallen_down; mtmp; mtmp = mtmp->nmon) 116. for(obj = mtmp->minvent; obj; obj = obj->nobj) 117. obj->unpaid = 0; 118. while(obj = billobjs){ 119. billobjs = obj->nobj; 120. free((char *) obj); 121. } 122. ESHK(shopkeeper)->billct = 0; 123. } 124. 125. static 126. addupbill(){ /* delivers result in total */ 127. /* caller has checked that shopkeeper exists */ 128. register ct = ESHK(shopkeeper)->billct; 129. register struct bill_x *bp = bill; 130. total = 0; 131. while(ct--){ 132. total += bp->price * bp->bquan; 133. bp++; 134. } 135. } 136. 137. inshop(){ 138. register roomno = inroom(u.ux,u.uy); 139. 140. /* Did we just leave a shop? */ 141. if(u.uinshop && 142. (u.uinshop != roomno + 1 || shlevel != dlevel || !shopkeeper)) { 143. 144. /* This is part of the bugfix for shopkeepers not having their 145. * bill paid. As reported by ab@unido -dgk 146. * I made this standard due to the KOPS code below. -mrs 147. */ 148. if(shopkeeper) { 149. if(ESHK(shopkeeper)->billct) { 150. if(inroom(shopkeeper->mx, shopkeeper->my) 151. == u.uinshop - 1) /* ab@unido */ 152. pline("Somehow you escaped the shop without paying!"); 153. addupbill(); 154. pline("You stole for a total worth of %ld zorkmids.", 155. total); 156. ESHK(shopkeeper)->robbed += total; 157. #ifdef KOPS 158. /* Keystone Kops srt@ucla */ 159. pline("An alarm sounds throughout the dungeon!"); 160. pline("The Kops are after you!"); 161. #endif 162. setpaid(); 163. if((rooms[ESHK(shopkeeper)->shoproom].rtype == GENERAL) 164. == (rn2(3) == 0)) 165. ESHK(shopkeeper)->following = 1; 166. #ifdef KOPS 167. { 168. coord enexto(); 169. coord mm; 170. register int cnt = dlevel + rnd(3); 171. /* Create a swarm near the staircase */ 172. mm.x = xdnstair; 173. mm.y = ydnstair; 174. while(cnt--) { 175. mm = enexto(mm.x, mm.y); 176. (void) mkmon_at('K', mm.x, mm.y); 177. } 178. /* Create a swarm near the shopkeeper */ 179. cnt = dlevel + rnd(3); 180. mm.x = shopkeeper->mx; 181. mm.y = shopkeeper->my; 182. while(cnt--) { 183. mm = enexto(mm.x, mm.y); 184. (void) mkmon_at('K', mm.x, mm.y); 185. } 186. } 187. #endif 188. } 189. shopkeeper = 0; 190. shlevel = 0; 191. } 192. u.uinshop = 0; 193. } 194. 195. /* Did we just enter a zoo of some kind? */ 196. if(roomno >= 0) { 197. register int rt = rooms[roomno].rtype; 198. register struct monst *mtmp; 199. if(rt == ZOO) { 200. pline("Welcome to David's treasure zoo!"); 201. } else 202. if(rt == SWAMP) { 203. pline("It looks rather muddy down here."); 204. } else 205. if(rt == COURT) { 206. pline("You are in an opulant throne room!"); 207. } else 208. if(rt == MORGUE) { 209. if(midnight()) 210. pline("Go away! Go away!"); 211. else 212. pline("You get an uncanny feeling ..."); 213. } else 214. rt = 0; 215. if(rt != 0) { 216. rooms[roomno].rtype = 0; 217. for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) 218. if(rt != ZOO || !rn2(3)) 219. mtmp->msleep = 0; 220. } 221. } 222. 223. /* Did we just enter a shop? */ 224. if(roomno >= 0 && rooms[roomno].rtype >= 8) { 225. if(shlevel != dlevel || !shopkeeper 226. || ESHK(shopkeeper)->shoproom != roomno) 227. findshk(roomno); 228. if(!shopkeeper) { 229. rooms[roomno].rtype = 0; 230. u.uinshop = 0; 231. } else if(!u.uinshop){ 232. if(!ESHK(shopkeeper)->visitct || 233. strncmp(ESHK(shopkeeper)->customer, plname, PL_NSIZ)){ 234. 235. /* He seems to be new here */ 236. ESHK(shopkeeper)->visitct = 0; 237. ESHK(shopkeeper)->following = 0; 238. (void) strncpy(ESHK(shopkeeper)->customer,plname,PL_NSIZ); 239. NOTANGRY(shopkeeper) = 1; 240. } 241. if(!ESHK(shopkeeper)->following) { 242. boolean box, pick; 243. struct obj *carrying(); 244. 245. pline("Hello %s! Welcome%s to %s's %s shop!", 246. plname, 247. ESHK(shopkeeper)->visitct++ ? " again" : "", 248. shkname(shopkeeper), 249. shopnam[rooms[ESHK(shopkeeper)->shoproom].rtype - 8] ); 250. box = carrying(ICE_BOX) != (struct obj *)0; 251. pick = carrying(PICK_AXE) != (struct obj *)0; 252. if(box || pick) { 253. if(dochug(shopkeeper)) { 254. u.uinshop = 0; /* he died moving */ 255. return(0); 256. } 257. pline("Will you please leave your %s outside?", 258. (box && pick) ? "box and pick-axe" : 259. box ? "box" : "pick-axe"); 260. } 261. } 262. u.uinshop = roomno + 1; 263. } 264. } 265. return(u.uinshop); 266. } 267. 268. static 269. findshk(roomno) 270. register roomno; 271. { 272. register struct monst *mtmp; 273. for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) 274. if(mtmp->isshk && ESHK(mtmp)->shoproom == roomno 275. && ESHK(mtmp)->shoplevel == dlevel) { 276. shopkeeper = mtmp; 277. bill = &(ESHK(shopkeeper)->bill[0]); 278. shlevel = dlevel; 279. if(ANGRY(shopkeeper) && 280. strncmp(ESHK(shopkeeper)->customer,plname,PL_NSIZ)) 281. NOTANGRY(shopkeeper) = 1; 282. /* billobjs = 0; -- this is wrong if we save in a shop */ 283. /* (and it is harmless to have too many things in billobjs) */ 284. return; 285. } 286. shopkeeper = 0; 287. shlevel = 0; 288. bill = (struct bill_x *) -1000; /* dump core when referenced */ 289. } 290. 291. static struct bill_x * 292. onbill(obj) register struct obj *obj; { 293. register struct bill_x *bp; 294. if(!shopkeeper) return(0); 295. for(bp = bill; bp < &bill[ESHK(shopkeeper)->billct]; bp++) 296. if(bp->bo_id == obj->o_id) { 297. if(!obj->unpaid) pline("onbill: paid obj on bill?"); 298. return(bp); 299. } 300. if(obj->unpaid) pline("onbill: unpaid obj not on bill?"); 301. return(0); 302. } 303. 304. /* called with two args on merge */ 305. obfree(obj,merge) register struct obj *obj, *merge; { 306. register struct bill_x *bp = onbill(obj); 307. register struct bill_x *bpm; 308. if(bp) { 309. if(!merge){ 310. bp->useup = 1; 311. obj->unpaid = 0; /* only for doinvbill */ 312. obj->nobj = billobjs; 313. billobjs = obj; 314. return; 315. } 316. bpm = onbill(merge); 317. if(!bpm){ 318. /* this used to be a rename */ 319. impossible("obfree: not on bill??"); 320. return; 321. } else { 322. /* this was a merger */ 323. bpm->bquan += bp->bquan; 324. ESHK(shopkeeper)->billct--; 325. *bp = bill[ESHK(shopkeeper)->billct]; 326. } 327. } 328. free((char *) obj); 329. } 330. 331. static 332. pay(tmp,shkp) 333. long tmp; 334. register struct monst *shkp; 335. { 336. long robbed = ESHK(shkp)->robbed; 337. 338. u.ugold -= tmp; 339. shkp->mgold += tmp; 340. flags.botl = 1; 341. if(robbed) { 342. robbed -= tmp; 343. if(robbed < 0) robbed = 0; 344. ESHK(shkp)->robbed = robbed; 345. } 346. } 347. 348. dopay(){ 349. long ltmp; 350. register struct bill_x *bp; 351. register struct monst *shkp; 352. int pass, tmp; 353. 354. multi = 0; 355. (void) inshop(); 356. for(shkp = fmon; shkp; shkp = shkp->nmon) 357. if(shkp->isshk && dist(shkp->mx,shkp->my) < 3) 358. break; 359. if(!shkp && u.uinshop && 360. inroom(shopkeeper->mx,shopkeeper->my) == ESHK(shopkeeper)->shoproom) 361. shkp = shopkeeper; 362. 363. if(!shkp) { 364. pline("There is nobody here to receive your payment."); 365. return(0); 366. } 367. ltmp = ESHK(shkp)->robbed; 368. if(shkp != shopkeeper && NOTANGRY(shkp)) { 369. if(!ltmp) { 370. pline("You do not owe %s anything.", monnam(shkp)); 371. } else 372. if(!u.ugold) { 373. pline("You have no money."); 374. } else { 375. long ugold = u.ugold; 376. 377. if(u.ugold > ltmp) { 378. pline("You give %s the %ld gold pieces %s asked for.", 379. monnam(shkp), ltmp, index("@CGHKLOQTVWZ&ehimt", shkp->data->mlet) 380. ? "he" : (index("nN", shkp->data->mlet) ? "she" : "it")); 381. pay(ltmp, shkp); 382. } else { 383. pline("You give %s all your gold.", monnam(shkp)); 384. pay(u.ugold, shkp); 385. } 386. if(ugold < ltmp/2) { 387. pline("Unfortunately, %s doesn't look satisfied.", 388. index("@CGHKLOQTVWZ&ehimt", shkp->data->mlet) 389. ? "he" : (index("nN", shkp->data->mlet) ? "she" : "it")); 390. } else { 391. ESHK(shkp)->robbed = 0; 392. ESHK(shkp)->following = 0; 393. if(ESHK(shkp)->shoplevel != dlevel) { 394. /* For convenience's sake, let him disappear */ 395. shkp->minvent = 0; /* %% */ 396. shkp->mgold = 0; 397. mondead(shkp); 398. } 399. } 400. } 401. return(1); 402. } 403. 404. if(!ESHK(shkp)->billct){ 405. pline("You do not owe %s anything.", monnam(shkp)); 406. if(!u.ugold){ 407. pline("Moreover, you have no money."); 408. return(1); 409. } 410. if(ESHK(shkp)->robbed){ 411. pline("But since %s shop has been robbed recently,", 412. index("@CGHKLOQTVWZ&ehimt", shkp->data->mlet) 413. ? "his" : (index("nN", shkp->data->mlet) ? "her" : "its")); 414. pline("you %srepay %s's expenses.", 415. (u.ugold < ESHK(shkp)->robbed) ? "partially " : "", 416. monnam(shkp)); 417. pay(min(u.ugold, ESHK(shkp)->robbed), shkp); 418. ESHK(shkp)->robbed = 0; 419. return(1); 420. } 421. if(ANGRY(shkp)){ 422. pline("But in order to appease %s,", 423. amonnam(shkp, "angry")); 424. if(u.ugold >= 1000){ 425. ltmp = 1000; 426. pline(" you give %s 1000 gold pieces.", 427. index("@CGHKLOQTVWZ&ehimt", shkp->data->mlet) 428. ? "him" : (index("nN", shkp->data->mlet) ? "her" : "it")); 429. } else { 430. ltmp = u.ugold; 431. pline(" you give %s all your money.", 432. index("@CGHKLOQTVWZ&ehimt", shkp->data->mlet) 433. ? "him" : (index("nN", shkp->data->mlet) ? "her" : "it")); 434. } 435. pay(ltmp, shkp); 436. if(strncmp(ESHK(shkp)->customer, plname, PL_NSIZ) 437. || rn2(3)){ 438. pline("%s calms down.", Monnam(shkp)); 439. NOTANGRY(shkp) = 1; 440. } else pline("%s is as angry as ever.", 441. Monnam(shkp)); 442. } 443. return(1); 444. } 445. if(shkp != shopkeeper) { 446. impossible("dopay: not to shopkeeper?"); 447. if(shopkeeper) setpaid(); 448. return(0); 449. } 450. for(pass = 0; pass <= 1; pass++) { 451. tmp = 0; 452. while(tmp < ESHK(shopkeeper)->billct) { 453. bp = &bill[tmp]; 454. if(!pass && !bp->useup) { 455. tmp++; 456. continue; 457. } 458. if(!dopayobj(bp)) return(1); 459. #ifdef MSDOS 460. *bp = bill[--ESHK(shopkeeper)->billct]; 461. #else 462. bill[tmp] = bill[--ESHK(shopkeeper)->billct]; 463. #endif /* MSDOS /**/ 464. } 465. } 466. pline("Thank you for shopping in %s's %s store!", 467. shkname(shopkeeper), 468. shopnam[rooms[ESHK(shopkeeper)->shoproom].rtype - 8]); 469. NOTANGRY(shopkeeper) = 1; 470. return(1); 471. } 472. 473. /* return 1 if paid successfully */ 474. /* 0 if not enough money */ 475. /* -1 if object could not be found (but was paid) */ 476. static 477. dopayobj(bp) register struct bill_x *bp; { 478. register struct obj *obj; 479. long ltmp; 480. 481. /* find the object on one of the lists */ 482. obj = bp_to_obj(bp); 483. 484. if(!obj) { 485. impossible("Shopkeeper administration out of order."); 486. setpaid(); /* be nice to the player */ 487. return(0); 488. } 489. 490. if(!obj->unpaid && !bp->useup){ 491. impossible("Paid object on bill??"); 492. return(1); 493. } 494. obj->unpaid = 0; 495. ltmp = bp->price * bp->bquan; 496. if(ANGRY(shopkeeper)) ltmp += ltmp/3; 497. if(u.ugold < ltmp){ 498. pline("You don't have gold enough to pay %s.", 499. doname(obj)); 500. obj->unpaid = 1; 501. return(0); 502. } 503. pay(ltmp, shopkeeper); 504. pline("You bought %s for %ld gold piece%s.", 505. doname(obj), ltmp, plur(ltmp)); 506. if(bp->useup) { 507. register struct obj *otmp = billobjs; 508. if(obj == billobjs) 509. billobjs = obj->nobj; 510. else { 511. while(otmp && otmp->nobj != obj) otmp = otmp->nobj; 512. if(otmp) otmp->nobj = obj->nobj; 513. else pline("Error in shopkeeper administration."); 514. } 515. free((char *) obj); 516. } 517. return(1); 518. } 519. 520. /* routine called after dying (or quitting) with nonempty bill */ 521. paybill(){ 522. if(shlevel == dlevel && shopkeeper && ESHK(shopkeeper)->billct){ 523. addupbill(); 524. if(total > u.ugold){ 525. shopkeeper->mgold += u.ugold; 526. u.ugold = 0; 527. pline("%s comes and takes all your possessions.", 528. Monnam(shopkeeper)); 529. } else { 530. u.ugold -= total; 531. shopkeeper->mgold += total; 532. pline("%s comes and takes the %ld zorkmids you owed him.", 533. Monnam(shopkeeper), total); 534. } 535. setpaid(); /* in case we create bones */ 536. } 537. } 538. 539. /* find obj on one of the lists */ 540. struct obj * 541. bp_to_obj(bp) 542. register struct bill_x *bp; 543. { 544. register struct obj *obj; 545. register struct monst *mtmp; 546. register unsigned id = bp->bo_id; 547. 548. if(bp->useup) 549. obj = o_on(id, billobjs); 550. else if(!(obj = o_on(id, invent)) && 551. !(obj = o_on(id, fobj)) && 552. !(obj = o_on(id, fcobj))) { 553. for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) 554. if(obj = o_on(id, mtmp->minvent)) 555. break; 556. for(mtmp = fallen_down; mtmp; mtmp = mtmp->nmon) 557. if(obj = o_on(id, mtmp->minvent)) 558. break; 559. } 560. return(obj); 561. } 562. 563. /* called in hack.c when we pickup an object */ 564. addtobill(obj) register struct obj *obj; { 565. register struct bill_x *bp; 566. if(!inshop() || 567. (u.ux == ESHK(shopkeeper)->shk.x && u.uy == ESHK(shopkeeper)->shk.y) || 568. (u.ux == ESHK(shopkeeper)->shd.x && u.uy == ESHK(shopkeeper)->shd.y) || 569. onbill(obj) /* perhaps we threw it away earlier */ 570. ) return; 571. if(ESHK(shopkeeper)->billct == BILLSZ){ 572. pline("You got that for free!"); 573. return; 574. } 575. #ifdef DGKMOD 576. /* To recognize objects the showkeeper is not interested in. -dgk 577. */ 578. if (obj->no_charge) { 579. obj->no_charge = 0; 580. return; 581. } 582. #endif 583. bp = &bill[ESHK(shopkeeper)->billct]; 584. bp->bo_id = obj->o_id; 585. bp->bquan = obj->quan; 586. bp->useup = 0; 587. bp->price = getprice(obj); 588. ESHK(shopkeeper)->billct++; 589. obj->unpaid = 1; 590. } 591. 592. splitbill(obj,otmp) register struct obj *obj, *otmp; { 593. /* otmp has been split off from obj */ 594. register struct bill_x *bp; 595. register int tmp; 596. bp = onbill(obj); 597. if(!bp) { 598. impossible("splitbill: not on bill?"); 599. return; 600. } 601. if(bp->bquan < otmp->quan) { 602. impossible("Negative quantity on bill??"); 603. } 604. if(bp->bquan == otmp->quan) { 605. impossible("Zero quantity on bill??"); 606. } 607. bp->bquan -= otmp->quan; 608. 609. /* addtobill(otmp); */ 610. if(ESHK(shopkeeper)->billct == BILLSZ) otmp->unpaid = 0; 611. else { 612. tmp = bp->price; 613. bp = &bill[ESHK(shopkeeper)->billct]; 614. bp->bo_id = otmp->o_id; 615. bp->bquan = otmp->quan; 616. bp->useup = 0; 617. bp->price = tmp; 618. ESHK(shopkeeper)->billct++; 619. } 620. } 621. 622. subfrombill(obj) register struct obj *obj; { 623. long ltmp; 624. register int tmp; 625. register struct obj *otmp; 626. register struct bill_x *bp; 627. if(!inshop() || (u.ux == ESHK(shopkeeper)->shk.x && u.uy == ESHK(shopkeeper)->shk.y) || 628. (u.ux == ESHK(shopkeeper)->shd.x && u.uy == ESHK(shopkeeper)->shd.y)) 629. return; 630. if((bp = onbill(obj)) != 0){ 631. obj->unpaid = 0; 632. if(bp->bquan > obj->quan){ 633. otmp = newobj(0); 634. *otmp = *obj; 635. bp->bo_id = otmp->o_id = flags.ident++; 636. otmp->quan = (bp->bquan -= obj->quan); 637. otmp->owt = 0; /* superfluous */ 638. otmp->onamelth = 0; 639. bp->useup = 1; 640. otmp->nobj = billobjs; 641. billobjs = otmp; 642. return; 643. } 644. ESHK(shopkeeper)->billct--; 645. *bp = bill[ESHK(shopkeeper)->billct]; 646. return; 647. } 648. if(obj->unpaid){ 649. pline("%s didn't notice.", Monnam(shopkeeper)); 650. obj->unpaid = 0; 651. return; /* %% */ 652. } 653. /* he dropped something of his own - probably wants to sell it */ 654. if(shopkeeper->msleep || shopkeeper->mfroz || 655. inroom(shopkeeper->mx,shopkeeper->my) != ESHK(shopkeeper)->shoproom) 656. return; 657. if(ESHK(shopkeeper)->billct == BILLSZ || 658. ((tmp = shtypes[rooms[ESHK(shopkeeper)->shoproom].rtype-8]) && tmp != obj->olet) 659. || index("_0", obj->olet)) { 660. pline("%s seems not interested.", Monnam(shopkeeper)); 661. #ifdef DGKMOD 662. obj->no_charge = 1; 663. #endif 664. return; 665. } 666. ltmp = getprice(obj) * obj->quan; 667. if(ANGRY(shopkeeper)) { 668. ltmp /= 3; 669. NOTANGRY(shopkeeper) = 1; 670. } else ltmp /= 2; 671. if(ESHK(shopkeeper)->robbed){ 672. if((ESHK(shopkeeper)->robbed -= ltmp) < 0) 673. ESHK(shopkeeper)->robbed = 0; 674. pline("Thank you for your contribution to restock this recently plundered shop."); 675. return; 676. } 677. if(ltmp > shopkeeper->mgold) 678. ltmp = shopkeeper->mgold; 679. pay(-ltmp, shopkeeper); 680. if(!ltmp) { 681. pline("%s gladly accepts %s but cannot pay you at present.", 682. Monnam(shopkeeper), doname(obj)); 683. #ifdef DGKMOD 684. obj->no_charge = 1; 685. #endif 686. } else 687. pline("You sold %s and got %ld gold piece%s.", doname(obj), ltmp, 688. plur(ltmp)); 689. } 690. 691. doinvbill(mode) 692. int mode; /* 0: deliver count 1: paged */ 693. { 694. register struct bill_x *bp; 695. register struct obj *obj; 696. long totused, thisused; 697. char buf[BUFSZ]; 698. 699. if(mode == 0) { 700. register int cnt = 0; 701. 702. if(shopkeeper) 703. for(bp = bill; bp - bill < ESHK(shopkeeper)->billct; bp++) 704. if(bp->useup || 705. ((obj = bp_to_obj(bp)) && obj->quan < bp->bquan)) 706. cnt++; 707. return(cnt); 708. } 709. 710. if(!shopkeeper) { 711. impossible("doinvbill: no shopkeeper?"); 712. return(0); 713. } 714. 715. set_pager(0); 716. if(page_line("Unpaid articles already used up:") || page_line("")) 717. goto quit; 718. 719. totused = 0; 720. for(bp = bill; bp - bill < ESHK(shopkeeper)->billct; bp++) { 721. obj = bp_to_obj(bp); 722. if(!obj) { 723. impossible("Bad shopkeeper administration."); 724. goto quit; 725. } 726. if(bp->useup || bp->bquan > obj->quan) { 727. register int cnt, oquan, uquan; 728. 729. oquan = obj->quan; 730. uquan = (bp->useup ? bp->bquan : bp->bquan - oquan); 731. thisused = bp->price * uquan; 732. totused += thisused; 733. obj->quan = uquan; /* cheat doname */ 734. (void) sprintf(buf, "x - %s", doname(obj)); 735. obj->quan = oquan; /* restore value */ 736. for(cnt = 0; buf[cnt]; cnt++); 737. while(cnt < 50) 738. buf[cnt++] = ' '; 739. (void) sprintf(&buf[cnt], " %5ld zorkmids", thisused); 740. if(page_line(buf)) 741. goto quit; 742. } 743. } 744. (void) sprintf(buf, "Total:%50ld zorkmids", totused); 745. if(page_line("") || page_line(buf)) 746. goto quit; 747. set_pager(1); 748. return(0); 749. quit: 750. set_pager(2); 751. return(0); 752. } 753. 754. static 755. getprice(obj) register struct obj *obj; { 756. register int tmp, ac; 757. switch(obj->olet){ 758. case AMULET_SYM: 759. tmp = 10*rnd(500); 760. break; 761. case TOOL_SYM: 762. tmp = 10*rnd((obj->otyp == EXPENSIVE_CAMERA) ? 150 : 763. #ifdef MARKER 764. (obj->otyp == MAGIC_MARKER) ? 100 : 765. #endif 766. 30); 767. break; 768. case RING_SYM: 769. tmp = 10*rnd(100); 770. break; 771. case WAND_SYM: 772. tmp = 10*rnd(100); 773. break; 774. case SCROLL_SYM: 775. tmp = 10*rnd(50); 776. #ifdef MAIL 777. if(obj->otyp == SCR_MAIL) 778. tmp = rnd(5); 779. #endif 780. break; 781. case POTION_SYM: 782. tmp = 10*rnd(50); 783. break; 784. #ifdef SPELLS 785. case SPBOOK_SYM: 786. tmp = 10*rnd(200); 787. break; 788. #endif 789. case FOOD_SYM: 790. tmp = 10*rnd(5 + (2000/realhunger())); 791. break; 792. case GEM_SYM: 793. tmp = 10*rnd(20); 794. break; 795. case ARMOR_SYM: 796. ac = ARM_BONUS(obj); 797. if(ac <= -10) /* probably impossible */ 798. ac = -9; 799. tmp = 100 + ac*ac*rnd(10+ac); 800. break; 801. case WEAPON_SYM: 802. if(obj->otyp < BOOMERANG) 803. tmp = 5*rnd(10); 804. else if(obj->otyp == KATANA) 805. tmp = 10*rnd(200); 806. else if(obj->otyp == LONG_SWORD || 807. obj->otyp == TWO_HANDED_SWORD) 808. tmp = 10*rnd(150); 809. else tmp = 10*rnd(75); 810. break; 811. case CHAIN_SYM: 812. pline("Strange ..., carrying a chain?"); 813. case BALL_SYM: 814. tmp = 10; 815. break; 816. default: 817. tmp = 10000; 818. } 819. return(tmp); 820. } 821. 822. static 823. realhunger(){ /* not completely foolproof */ 824. register tmp = u.uhunger; 825. register struct obj *otmp = invent; 826. while(otmp){ 827. if(otmp->olet == FOOD_SYM && !otmp->unpaid) 828. tmp += objects[otmp->otyp].nutrition; 829. otmp = otmp->nobj; 830. } 831. return((tmp <= 0) ? 1 : tmp); 832. } 833. 834. shkcatch(obj) 835. register struct obj *obj; 836. { 837. register struct monst *shkp = shopkeeper; 838. 839. if(u.uinshop && shkp && !shkp->mfroz && !shkp->msleep && 840. u.dx && u.dy && 841. inroom(u.ux+u.dx, u.uy+u.dy) + 1 == u.uinshop && 842. shkp->mx == ESHK(shkp)->shk.x && shkp->my == ESHK(shkp)->shk.y && 843. u.ux == ESHK(shkp)->shd.x && u.uy == ESHK(shkp)->shd.y) { 844. pline("%s nimbly catches the %s.", Monnam(shkp), xname(obj)); 845. obj->nobj = shkp->minvent; 846. shkp->minvent = obj; 847. return(1); 848. } 849. return(0); 850. } 851. 852. /* 853. * shk_move: return 1: he moved 0: he didnt -1: let m_move do it 854. */ 855. shk_move(shkp) 856. register struct monst *shkp; 857. { 858. register struct monst *mtmp; 859. register struct permonst *mdat = shkp->data; 860. register xchar gx,gy,omx,omy,nx,ny,nix,niy; 861. register schar appr,i; 862. register int udist; 863. int z; 864. schar shkroom,chi,chcnt,cnt; 865. boolean uondoor, satdoor, avoid, badinv; 866. coord poss[9]; 867. long info[9]; 868. struct obj *ib = 0; 869. 870. omx = shkp->mx; 871. omy = shkp->my; 872. 873. if((udist = dist(omx,omy)) < 3) { 874. if(ANGRY(shkp)) { 875. (void) hitu(shkp, d(mdat->damn, mdat->damd)+1); 876. return(0); 877. } 878. if(ESHK(shkp)->following) { 879. if(strncmp(ESHK(shkp)->customer, plname, PL_NSIZ)){ 880. pline("Hello %s! I was looking for %s.", 881. plname, ESHK(shkp)->customer); 882. ESHK(shkp)->following = 0; 883. return(0); 884. } 885. if(!ESHK(shkp)->robbed) { /* impossible? */ 886. ESHK(shkp)->following = 0; 887. return(0); 888. } 889. if(moves > followmsg+4) { 890. pline("Hello %s! Didn't you forget to pay?", 891. plname); 892. followmsg = moves; 893. } 894. if(udist < 2) 895. return(0); 896. } 897. } 898. 899. shkroom = inroom(omx,omy); 900. appr = 1; 901. gx = ESHK(shkp)->shk.x; 902. gy = ESHK(shkp)->shk.y; 903. satdoor = (gx == omx && gy == omy); 904. if(ESHK(shkp)->following || ((z = holetime()) >= 0 && z*z <= udist)){ 905. gx = u.ux; 906. gy = u.uy; 907. if(shkroom < 0 || shkroom != inroom(u.ux,u.uy)) 908. if(udist > 4) 909. return(-1); /* leave it to m_move */ 910. } else if(ANGRY(shkp)) { 911. long saveBlind = Blind; 912. Blind = 0; 913. if(shkp->mcansee && !Invis && cansee(omx,omy)) { 914. gx = u.ux; 915. gy = u.uy; 916. } 917. Blind = saveBlind; 918. avoid = FALSE; 919. } else { 920. #define GDIST(x,y) ((x-gx)*(x-gx)+(y-gy)*(y-gy)) 921. if(Invis) 922. avoid = FALSE; 923. else { 924. uondoor = (u.ux == ESHK(shkp)->shd.x && 925. u.uy == ESHK(shkp)->shd.y); 926. if(uondoor) { 927. if(ESHK(shkp)->billct) 928. pline("Hello %s! Will you please pay before leaving?", 929. plname); 930. badinv = (carrying(PICK_AXE) || carrying(ICE_BOX)); 931. if(satdoor && badinv) 932. return(0); 933. avoid = !badinv; 934. } else { 935. avoid = (u.uinshop && dist(gx,gy) > 8); 936. badinv = FALSE; 937. } 938. 939. if(((!ESHK(shkp)->robbed && !ESHK(shkp)->billct) || avoid) 940. && GDIST(omx,omy) < 3){ 941. if(!badinv && !online(omx,omy)) 942. return(0); 943. if(satdoor) 944. appr = gx = gy = 0; 945. } 946. } 947. } 948. if(omx == gx && omy == gy) 949. return(0); 950. if(shkp->mconf) { 951. avoid = FALSE; 952. appr = 0; 953. } 954. nix = omx; 955. niy = omy; 956. cnt = mfndpos(shkp,poss,info,ALLOW_SSM); 957. if(avoid && uondoor) { /* perhaps we cannot avoid him */ 958. for(i=0; i 959. if(!(info[i] & NOTONL)) goto notonl_ok; 960. avoid = FALSE; 961. notonl_ok: 962. ; 963. } 964. chi = -1; 965. chcnt = 0; 966. for(i=0; i 967. nx = poss[i].x; 968. ny = poss[i].y; 969. if(levl[nx][ny].typ == ROOM 970. || shkroom != ESHK(shkp)->shoproom 971. || ESHK(shkp)->following) { 972. #ifdef STUPID 973. /* cater for stupid compilers */ 974. register int zz; 975. #endif 976. if(uondoor && (ib = sobj_at(ICE_BOX, nx, ny))) { 977. nix = nx; niy = ny; chi = i; break; 978. } 979. if(avoid && (info[i] & NOTONL)) 980. continue; 981. if((!appr && !rn2(++chcnt)) || 982. #ifdef STUPID 983. (appr && (zz = GDIST(nix,niy)) && zz > GDIST(nx,ny)) 984. #else 985. (appr && GDIST(nx,ny) < GDIST(nix,niy)) 986. #endif 987. ) { 988. nix = nx; 989. niy = ny; 990. chi = i; 991. } 992. } 993. } 994. if(nix != omx || niy != omy){ 995. if(info[chi] & ALLOW_M){ 996. mtmp = m_at(nix,niy); 997. if(hitmm(shkp,mtmp) == 1 && rn2(3) && 998. hitmm(mtmp,shkp) == 2) return(2); 999. return(0); 1000. } else if(info[chi] & ALLOW_U){ 1001. (void) hitu(shkp, d(mdat->damn, mdat->damd)+1); 1002. return(0); 1003. } 1004. shkp->mx = nix; 1005. shkp->my = niy; 1006. pmon(shkp); 1007. if(ib) { 1008. freeobj(ib); 1009. mpickobj(shkp, ib); 1010. } 1011. return(1); 1012. } 1013. return(0); 1014. } 1015. #endif /* QUEST /**/ 1016. 1017. online(x,y) { 1018. return(x==u.ux || y==u.uy || 1019. (x-u.ux)*(x-u.ux) == (y-u.uy)*(y-u.uy)); 1020. } 1021. 1022. /* Does this monster follow me downstairs? */ 1023. follower(mtmp) 1024. register struct monst *mtmp; 1025. { 1026. return( mtmp->mtame || index("1TVWZi&, ", mtmp->data->mlet) || 1027. (mtmp->isshk && ESHK(mtmp)->following) ); 1028. } 1029. 1030. /* He is digging in the shop. */ 1031. shopdig(fall) 1032. register int fall; 1033. { 1034. if(!fall) { 1035. if(u.utraptype == TT_PIT) 1036. pline("\"Be careful, sir, or you might fall through the floor.\""); 1037. else 1038. pline("\"Please, do not damage the floor here.\""); 1039. } else if(dist(shopkeeper->mx, shopkeeper->my) < 3) { 1040. register struct obj *obj, *obj2; 1041. 1042. pline("%s grabs your backpack!", shkname(shopkeeper)); 1043. for(obj = invent; obj; obj = obj2) { 1044. obj2 = obj->nobj; 1045. if(obj->owornmask) continue; 1046. freeinv(obj); 1047. obj->nobj = shopkeeper->minvent; 1048. shopkeeper->minvent = obj; 1049. if(obj->unpaid) 1050. subfrombill(obj); 1051. } 1052. } 1053. }
Alternative Linked Data Views: ODE     Raw Data in: CXML | CSV | RDF ( N-Triples N3/Turtle JSON XML ) | OData ( Atom JSON ) | Microdata ( JSON HTML) | JSON-LD    About   
This material is Open Knowledge   W3C Semantic Web Technology [RDF Data] Valid XHTML + RDFa
OpenLink Virtuoso version 07.20.3217, on Linux (x86_64-pc-linux-gnu), Standard Edition
Data on this page belongs to its respective rights holders.
Virtuoso Faceted Browser Copyright © 2009-2012 OpenLink Software