About: Source:NetHack 2.3e/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.3e. To link to a particular line, write [[NetHack 2.3e/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.3e/shk.c
rdfs:comment
  • Below is the full text to shk.c from the source code of NetHack 2.3e. To link to a particular line, write [[NetHack 2.3e/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.3e. To link to a particular line, write [[NetHack 2.3e/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.3 88/01/24 2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3. 4. #include "hack.h" 5. #ifdef QUEST 6. int shlevel = 0; 7. struct monst *mkmon_at(), *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%s! Welcome%s to %s's %s!", 227. (Badged) ? "Officer " : "", 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. extern char *typename(); 551. if(!inshop() || 552. (u.ux == ESHK(shopkeeper)->shk.x && u.uy == ESHK(shopkeeper)->shk.y) || 553. (u.ux == ESHK(shopkeeper)->shd.x && u.uy == ESHK(shopkeeper)->shd.y) || 554. onbill(obj) /* perhaps we threw it away earlier */ 555. ) return; 556. if(ESHK(shopkeeper)->billct == BILLSZ){ 557. pline("You got that for free!"); 558. return; 559. } 560. #ifdef DGKMOD 561. /* To recognize objects the showkeeper is not interested in. -dgk 562. */ 563. if (obj->no_charge) { 564. obj->no_charge = 0; 565. return; 566. } 567. #endif 568. bp = &bill[ESHK(shopkeeper)->billct]; 569. bp->bo_id = obj->o_id; 570. bp->bquan = obj->quan; 571. bp->useup = 0; 572. bp->price = getprice(obj); 573. strcpy(buf, "For you, "); 574. if (ANGRY(shopkeeper)) strcat(buf, "scum "); 575. else { 576. switch(rnd(4) 577. #ifdef HARD 578. + u.udemigod 579. #endif 580. ) { 581. case 1: strcat(buf, "good"); 582. break; 583. case 2: strcat(buf, "honored"); 584. break; 585. case 3: strcat(buf, "most gracious"); 586. break; 587. case 4: strcat(buf, "esteemed"); 588. break; 589. case 5: strcat(buf, "holy"); 590. break; 591. } 592. if(u.usym != '@') strcat(buf, " creature"); 593. else strcat(buf, (flags.female) ? " lady" : " sir"); 594. } 595. pline("%s; only %d %s %s.", buf, bp->price, 596. (bp->bquan > 1) ? "per" : "for this", 597. typename((int)obj->otyp)); 598. 599. ESHK(shopkeeper)->billct++; 600. obj->unpaid = 1; 601. } 602. 603. splitbill(obj,otmp) register struct obj *obj, *otmp; { 604. /* otmp has been split off from obj */ 605. register struct bill_x *bp; 606. register int tmp; 607. bp = onbill(obj); 608. if(!bp) { 609. impossible("splitbill: not on bill?"); 610. return; 611. } 612. if(bp->bquan < otmp->quan) { 613. impossible("Negative quantity on bill??"); 614. } 615. if(bp->bquan == otmp->quan) { 616. impossible("Zero quantity on bill??"); 617. } 618. bp->bquan -= otmp->quan; 619. 620. /* addtobill(otmp); */ 621. if(ESHK(shopkeeper)->billct == BILLSZ) otmp->unpaid = 0; 622. else { 623. tmp = bp->price; 624. bp = &bill[ESHK(shopkeeper)->billct]; 625. bp->bo_id = otmp->o_id; 626. bp->bquan = otmp->quan; 627. bp->useup = 0; 628. bp->price = tmp; 629. ESHK(shopkeeper)->billct++; 630. } 631. } 632. 633. subfrombill(obj) register struct obj *obj; { 634. long ltmp; 635. register int tmp; 636. register struct obj *otmp; 637. register struct bill_x *bp; 638. if(!inshop() || (u.ux == ESHK(shopkeeper)->shk.x && u.uy == ESHK(shopkeeper)->shk.y) || 639. (u.ux == ESHK(shopkeeper)->shd.x && u.uy == ESHK(shopkeeper)->shd.y)) 640. return; 641. if((bp = onbill(obj)) != 0){ 642. obj->unpaid = 0; 643. if(bp->bquan > obj->quan){ 644. otmp = newobj(0); 645. *otmp = *obj; 646. bp->bo_id = otmp->o_id = flags.ident++; 647. otmp->quan = (bp->bquan -= obj->quan); 648. otmp->owt = 0; /* superfluous */ 649. otmp->onamelth = 0; 650. bp->useup = 1; 651. otmp->nobj = billobjs; 652. billobjs = otmp; 653. return; 654. } 655. ESHK(shopkeeper)->billct--; 656. *bp = bill[ESHK(shopkeeper)->billct]; 657. return; 658. } 659. if(obj->unpaid){ 660. pline("%s didn't notice.", Monnam(shopkeeper)); 661. obj->unpaid = 0; 662. return; /* %% */ 663. } 664. /* he dropped something of his own - probably wants to sell it */ 665. if(shopkeeper->msleep || shopkeeper->mfroz || 666. inroom(shopkeeper->mx,shopkeeper->my) != ESHK(shopkeeper)->shoproom) 667. return; 668. if(ESHK(shopkeeper)->billct == BILLSZ 669. || !saleable(rooms[ESHK(shopkeeper)->shoproom].rtype-SHOPBASE, obj) 670. /* 671. ((tmp = shtypes[rooms[ESHK(shopkeeper)->shoproom].rtype-SHOPBASE].symb) && tmp != obj->olet) 672. */ 673. || index("_0", obj->olet)) { 674. pline("%s seems not interested.", Monnam(shopkeeper)); 675. #ifdef DGKMOD 676. obj->no_charge = 1; 677. #endif 678. return; 679. } 680. ltmp = getprice(obj) * obj->quan; 681. if(ANGRY(shopkeeper)) { 682. ltmp /= 3; 683. NOTANGRY(shopkeeper) = 1; 684. } else ltmp /= 2; 685. if(ESHK(shopkeeper)->robbed){ 686. if((ESHK(shopkeeper)->robbed -= ltmp) < 0) 687. ESHK(shopkeeper)->robbed = 0; 688. pline("Thank you for your contribution to restock this recently plundered shop."); 689. return; 690. } 691. if(ltmp > shopkeeper->mgold) 692. ltmp = shopkeeper->mgold; 693. pay(-ltmp, shopkeeper); 694. if(!ltmp) { 695. pline("%s gladly accepts %s but cannot pay you at present.", 696. Monnam(shopkeeper), doname(obj)); 697. #ifdef DGKMOD 698. obj->no_charge = 1; 699. #endif 700. } else 701. pline("You sold %s and got %ld gold piece%s.", doname(obj), ltmp, 702. plur(ltmp)); 703. } 704. 705. doinvbill(mode) 706. int mode; /* 0: deliver count 1: paged */ 707. { 708. register struct bill_x *bp; 709. register struct obj *obj; 710. long totused, thisused; 711. char buf[BUFSZ]; 712. 713. if(mode == 0) { 714. register int cnt = 0; 715. 716. if(shopkeeper) 717. for(bp = bill; bp - bill < ESHK(shopkeeper)->billct; bp++) 718. if(bp->useup || 719. ((obj = bp_to_obj(bp)) && obj->quan < bp->bquan)) 720. cnt++; 721. return(cnt); 722. } 723. 724. if(!shopkeeper) { 725. impossible("doinvbill: no shopkeeper?"); 726. return(0); 727. } 728. 729. set_pager(0); 730. if(page_line("Unpaid articles already used up:") || page_line("")) 731. goto quit; 732. 733. totused = 0; 734. for(bp = bill; bp - bill < ESHK(shopkeeper)->billct; bp++) { 735. obj = bp_to_obj(bp); 736. if(!obj) { 737. impossible("Bad shopkeeper administration."); 738. goto quit; 739. } 740. if(bp->useup || bp->bquan > obj->quan) { 741. register int cnt, oquan, uquan; 742. 743. oquan = obj->quan; 744. uquan = (bp->useup ? bp->bquan : bp->bquan - oquan); 745. thisused = bp->price * uquan; 746. totused += thisused; 747. obj->quan = uquan; /* cheat doname */ 748. (void) sprintf(buf, "x - %s", doname(obj)); 749. obj->quan = oquan; /* restore value */ 750. for(cnt = 0; buf[cnt]; cnt++); 751. while(cnt < 50) 752. buf[cnt++] = ' '; 753. (void) sprintf(&buf[cnt], " %5ld zorkmids", thisused); 754. if(page_line(buf)) 755. goto quit; 756. } 757. } 758. (void) sprintf(buf, "Total:%50ld zorkmids", totused); 759. if(page_line("") || page_line(buf)) 760. goto quit; 761. set_pager(1); 762. return(0); 763. quit: 764. set_pager(2); 765. return(0); 766. } 767. 768. static 769. getprice(obj) register struct obj *obj; { 770. register int tmp, ac; 771. switch(obj->olet){ 772. case AMULET_SYM: 773. tmp = rn1(1500, 3500); 774. break; 775. case TOOL_SYM: 776. switch(obj->otyp) { 777. case EXPENSIVE_CAMERA: tmp = rn1(400, 200); 778. break; 779. #ifdef MARKER 780. case MAGIC_MARKER: tmp = rn1(100,50); 781. break; 782. #endif 783. #ifdef WALKIES 784. case LEASH: tmp = rn1(40,20); 785. break; 786. #endif 787. #ifdef RPH 788. case BLINDFOLD: tmp = rn1(40,20); 789. break; 790. case MIRROR: tmp = rn1(80,40); 791. break; 792. #endif 793. case STETHOSCOPE: tmp = rn1(100,80); 794. break; 795. case CAN_OPENER: tmp = rn1(50,30); 796. break; 797. default: tmp = rn1(20,10); 798. break; 799. } 800. break; 801. case RING_SYM: 802. tmp = rn1(200,100); 803. break; 804. case WAND_SYM: 805. tmp = rn1(300,150); 806. break; 807. case SCROLL_SYM: 808. #ifdef MAIL 809. if(obj->otyp == SCR_MAIL) 810. tmp = rn1(5,5); 811. else 812. #endif 813. tmp = rn1(200,100); 814. break; 815. case POTION_SYM: 816. tmp = rn1(200,100); 817. break; 818. #ifdef SPELLS 819. case SPBOOK_SYM: 820. tmp = rn1(500,500); 821. break; 822. #endif 823. case FOOD_SYM: 824. 825. tmp = (2000+objects[obj->otyp].nutrition)/realhunger(); 826. tmp = rn1((tmp < 10) ? 10 : tmp, 827. objects[obj->otyp].nutrition/20 + 5); 828. break; 829. case GEM_SYM: 830. tmp = rn1(120,60); 831. break; 832. case ARMOR_SYM: 833. ac = ARM_BONUS(obj); 834. if(ac <= -10) /* probably impossible */ 835. ac = -9; 836. tmp = ac*ac+10*rn1(10+ac,10); 837. break; 838. case WEAPON_SYM: 839. if(obj->otyp < BOOMERANG) 840. tmp = rn1(4,2); 841. else if(obj->otyp == BOOMERANG || 842. obj->otyp == DAGGER || 843. obj->otyp == CLUB || 844. obj->otyp == SLING) 845. tmp = rn1(50,50); 846. else if(obj->otyp == KATANA) 847. tmp = rn1(700,800); 848. else if(obj->otyp == LONG_SWORD || 849. obj->otyp == TWO_HANDED_SWORD || 850. obj->otyp == BROAD_SWORD) 851. tmp = rn1(500,500); 852. else tmp = rn1(150,100); 853. break; 854. case CHAIN_SYM: 855. pline("Strange ..., carrying a chain?"); 856. case BALL_SYM: 857. tmp = 10; 858. break; 859. default: 860. tmp = 10000; 861. } 862. return(tmp); 863. } 864. 865. static 866. realhunger(){ /* not completely foolproof */ 867. register tmp = u.uhunger; 868. register struct obj *otmp = invent; 869. while(otmp){ 870. if(otmp->olet == FOOD_SYM && !otmp->unpaid) 871. tmp += objects[otmp->otyp].nutrition; 872. otmp = otmp->nobj; 873. } 874. return((tmp <= 0) ? 1 : tmp); 875. } 876. 877. shkcatch(obj) 878. register struct obj *obj; 879. { 880. register struct monst *shkp = shopkeeper; 881. 882. if(u.uinshop && shkp && !shkp->mfroz && !shkp->msleep && 883. u.dx && u.dy && 884. inroom(u.ux+u.dx, u.uy+u.dy) + 1 == u.uinshop && 885. shkp->mx == ESHK(shkp)->shk.x && shkp->my == ESHK(shkp)->shk.y && 886. u.ux == ESHK(shkp)->shd.x && u.uy == ESHK(shkp)->shd.y) { 887. pline("%s nimbly catches the %s.", Monnam(shkp), xname(obj)); 888. obj->nobj = shkp->minvent; 889. shkp->minvent = obj; 890. return(1); 891. } 892. return(0); 893. } 894. 895. /* 896. * shk_move: return 1: he moved 0: he didnt -1: let m_move do it 897. */ 898. shk_move(shkp) 899. register struct monst *shkp; 900. { 901. register struct monst *mtmp; 902. register struct permonst *mdat = shkp->data; 903. register xchar gx,gy,omx,omy,nx,ny,nix,niy; 904. register schar appr,i; 905. register int udist; 906. int z; 907. schar shkroom,chi,chcnt,cnt; 908. boolean uondoor, satdoor, avoid, badinv; 909. coord poss[9]; 910. long info[9]; 911. struct obj *ib = 0; 912. 913. omx = shkp->mx; 914. omy = shkp->my; 915. 916. if((udist = dist(omx,omy)) < 3) { 917. if(ANGRY(shkp)) { 918. (void) hitu(shkp, d(mdat->damn, mdat->damd)+1); 919. return(0); 920. } 921. if(ESHK(shkp)->following) { 922. if(strncmp(ESHK(shkp)->customer, plname, PL_NSIZ)){ 923. pline("Hello %s%s! I was looking for %s.", 924. (Badged) ? "Officer " : "", 925. plname, ESHK(shkp)->customer); 926. ESHK(shkp)->following = 0; 927. return(0); 928. } 929. if(!ESHK(shkp)->robbed) { /* impossible? */ 930. ESHK(shkp)->following = 0; 931. return(0); 932. } 933. if(moves > followmsg+4) { 934. pline("Hello %s%s! Didn't you forget to pay?", 935. (Badged) ? "Officer " : "", plname); 936. followmsg = moves; 937. if (Badged) 938. pline ("You should be upholding the law!"); 939. #ifdef HARD 940. if (!rn2((Badged) ? 3 : 5)) { 941. pline ("%s doesn't like customers who don't pay.", Monnam(shkp)); 942. NOTANGRY(shkp) = 0; 943. } 944. #endif 945. } 946. if(udist < 2) 947. return(0); 948. } 949. } 950. 951. shkroom = inroom(omx,omy); 952. appr = 1; 953. gx = ESHK(shkp)->shk.x; 954. gy = ESHK(shkp)->shk.y; 955. satdoor = (gx == omx && gy == omy); 956. if(ESHK(shkp)->following || ((z = holetime()) >= 0 && z*z <= udist)){ 957. gx = u.ux; 958. gy = u.uy; 959. if(shkroom < 0 || shkroom != inroom(u.ux,u.uy)) 960. if(udist > 4) 961. return(-1); /* leave it to m_move */ 962. } else if(ANGRY(shkp)) { 963. long saveBlind = Blinded; 964. long saveBlindf = Blindfolded; 965. Blinded = Blindfolded = 0; 966. if(shkp->mcansee && !Invis && cansee(omx,omy)) { 967. gx = u.ux; 968. gy = u.uy; 969. } 970. Blinded = saveBlind; 971. Blindfolded = saveBlindf; 972. avoid = FALSE; 973. } else { 974. #define GDIST(x,y) ((x-gx)*(x-gx)+(y-gy)*(y-gy)) 975. if(Invis) 976. avoid = FALSE; 977. else { 978. uondoor = (u.ux == ESHK(shkp)->shd.x && 979. u.uy == ESHK(shkp)->shd.y); 980. if(uondoor) { 981. if(ESHK(shkp)->billct) 982. pline("Hello %s%s! Will you please pay before leaving?", 983. (Badged) ? "Officer " : "", plname); 984. badinv = (carrying(PICK_AXE) || carrying(ICE_BOX)); 985. if(satdoor && badinv) 986. return(0); 987. avoid = !badinv; 988. } else { 989. avoid = (u.uinshop && dist(gx,gy) > 8); 990. badinv = FALSE; 991. } 992. 993. if(((!ESHK(shkp)->robbed && !ESHK(shkp)->billct) || avoid) 994. && GDIST(omx,omy) < 3){ 995. if(!badinv && !online(omx,omy)) 996. return(0); 997. if(satdoor) 998. appr = gx = gy = 0; 999. } 1000. } 1001. } 1002. if(omx == gx && omy == gy) 1003. return(0); 1004. if(shkp->mconf) { 1005. avoid = FALSE; 1006. appr = 0; 1007. } 1008. nix = omx; 1009. niy = omy; 1010. cnt = mfndpos(shkp,poss,info,ALLOW_SSM); 1011. if(avoid && uondoor) { /* perhaps we cannot avoid him */ 1012. for(i=0; i 1013. if(!(info[i] & NOTONL)) goto notonl_ok; 1014. avoid = FALSE; 1015. notonl_ok: 1016. ; 1017. } 1018. chi = -1; 1019. chcnt = 0; 1020. for(i=0; i 1021. nx = poss[i].x; 1022. ny = poss[i].y; 1023. if(levl[nx][ny].typ == ROOM 1024. || shkroom != ESHK(shkp)->shoproom 1025. || ESHK(shkp)->following) { 1026. #ifdef STUPID 1027. /* cater for stupid compilers */ 1028. register int zz; 1029. #endif 1030. if(uondoor && (ib = sobj_at(ICE_BOX, nx, ny))) { 1031. nix = nx; niy = ny; chi = i; break; 1032. } 1033. if(avoid && (info[i] & NOTONL)) 1034. continue; 1035. if((!appr && !rn2(++chcnt)) || 1036. #ifdef STUPID 1037. (appr && (zz = GDIST(nix,niy)) && zz > GDIST(nx,ny)) 1038. #else 1039. (appr && GDIST(nx,ny) < GDIST(nix,niy)) 1040. #endif 1041. ) { 1042. nix = nx; 1043. niy = ny; 1044. chi = i; 1045. } 1046. } 1047. } 1048. if(nix != omx || niy != omy){ 1049. if(info[chi] & ALLOW_M){ 1050. mtmp = m_at(nix,niy); 1051. if(hitmm(shkp,mtmp) == 1 && rn2(3) && 1052. hitmm(mtmp,shkp) == 2) return(2); 1053. return(0); 1054. } else if(info[chi] & ALLOW_U){ 1055. (void) hitu(shkp, d(mdat->damn, mdat->damd)+1); 1056. return(0); 1057. } 1058. shkp->mx = nix; 1059. shkp->my = niy; 1060. pmon(shkp); 1061. if(ib) { 1062. freeobj(ib); 1063. mpickobj(shkp, ib); 1064. } 1065. return(1); 1066. } 1067. return(0); 1068. } 1069. #endif /* QUEST /**/ 1070. 1071. online(x,y) /* New version to speed things up. 1072. * Compiler dependant, may not always work. 1073. */ 1074. register xchar x, y; 1075. { 1076. return((x-=u.ux) == 0 || (y-=u.uy) == 0 || x == y || (x+=y) == 0); 1077. } 1078. 1079. /* Original version, just in case... 1080. *online(x,y) { 1081. * return(x==u.ux || y==u.uy || (x-u.ux)*(x-u.ux) == (y-u.uy)*(y-u.uy)); 1082. *} 1083. */ 1084. 1085. /* Does this monster follow me downstairs? */ 1086. follower(mtmp) 1087. register struct monst *mtmp; 1088. { 1089. return( mtmp->mtame || index("1TVWZi&, ", mtmp->data->mlet) || 1090. (mtmp->isshk && ESHK(mtmp)->following) ); 1091. } 1092. 1093. /* He is digging in the shop. */ 1094. shopdig(fall) 1095. register int fall; 1096. { 1097. if(!fall) { 1098. if(u.utraptype == TT_PIT) 1099. pline("\"Be careful, sir, or you might fall through the floor.\""); 1100. else 1101. pline("\"Please, do not damage the floor here.\""); 1102. } else if(dist(shopkeeper->mx, shopkeeper->my) < 3) { 1103. register struct obj *obj, *obj2; 1104. 1105. pline("%s grabs your backpack!", shkname(shopkeeper)); 1106. for(obj = invent; obj; obj = obj2) { 1107. obj2 = obj->nobj; 1108. if(obj->owornmask) continue; 1109. freeinv(obj); 1110. obj->nobj = shopkeeper->minvent; 1111. shopkeeper->minvent = obj; 1112. if(obj->unpaid) 1113. subfrombill(obj); 1114. } 1115. } 1116. }
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