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