abstract
| - Below is the full text to invent.c from the source code of NetHack 1.3d. To link to a particular line, write [[NetHack 1.3d/invent.c#line123]], for example. Warning! This is the source code from an old release. For the latest release, see Source code 1. /* SCCS Id: @(#)invent.c 1.3 87/07/14 2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3. /* invent.c - version 1.0.3 */ 4. 5. #include 6. #include "hack.h" 7. extern struct obj *splitobj(); 8. extern struct obj zeroobj; 9. extern char morc; 10. extern char quitchars[]; 11. static char *xprname(); 12. 13. #ifndef NOWORM 14. #include "wseg.h" 15. extern struct wseg *wsegs[32]; 16. #endif 17. 18. #define NOINVSYM '#' 19. 20. int lastinvnr = 51; /* 0 ... 51 */ 21. 22. static 23. assigninvlet(otmp) 24. register struct obj *otmp; 25. { 26. boolean inuse[52]; 27. register int i; 28. register struct obj *obj; 29. 30. for(i = 0; i < 52; i++) inuse[i] = FALSE; 31. for(obj = invent; obj; obj = obj->nobj) if(obj != otmp) { 32. i = obj->invlet; 33. if('a' <= i && i <= 'z') inuse[i - 'a'] = TRUE; else 34. if('A' <= i && i <= 'Z') inuse[i - 'A' + 26] = TRUE; 35. if(i == otmp->invlet) otmp->invlet = 0; 36. } 37. if((i = otmp->invlet) && 38. (('a' <= i && i <= 'z') || ('A' <= i && i <= 'Z'))) 39. return; 40. for(i = lastinvnr+1; i != lastinvnr; i++) { 41. if(i == 52) { i = -1; continue; } 42. if(!inuse[i]) break; 43. } 44. otmp->invlet = (inuse[i] ? NOINVSYM : 45. (i < 26) ? ('a'+i) : ('A'+i-26)); 46. lastinvnr = i; 47. } 48. 49. struct obj * 50. addinv(obj) 51. register struct obj *obj; 52. { 53. register struct obj *otmp; 54. 55. /* merge or attach to end of chain */ 56. if(!invent) { 57. invent = obj; 58. otmp = 0; 59. } else 60. for(otmp = invent; /* otmp */; otmp = otmp->nobj) { 61. if(merged(otmp, obj, 0)) 62. return(otmp); 63. if(!otmp->nobj) { 64. otmp->nobj = obj; 65. break; 66. } 67. } 68. obj->nobj = 0; 69. 70. if(flags.invlet_constant) { 71. assigninvlet(obj); 72. /* 73. * The ordering of the chain is nowhere significant 74. * so in case you prefer some other order than the 75. * historical one, change the code below. 76. */ 77. if(otmp) { /* find proper place in chain */ 78. otmp->nobj = 0; 79. if((invent->invlet ^ 040) > (obj->invlet ^ 040)) { 80. obj->nobj = invent; 81. invent = obj; 82. } else 83. for(otmp = invent; ; otmp = otmp->nobj) { 84. if(!otmp->nobj || 85. (otmp->nobj->invlet ^ 040) > (obj->invlet ^ 040)){ 86. obj->nobj = otmp->nobj; 87. otmp->nobj = obj; 88. break; 89. } 90. } 91. } 92. } 93. 94. return(obj); 95. } 96. 97. useup(obj) 98. register struct obj *obj; 99. { 100. if(obj->quan > 1){ 101. obj->quan--; 102. obj->owt = weight(obj); 103. } else { 104. setnotworn(obj); 105. freeinv(obj); 106. obfree(obj, (struct obj *) 0); 107. } 108. } 109. 110. freeinv(obj) 111. register struct obj *obj; 112. { 113. register struct obj *otmp; 114. 115. if(obj == invent) 116. invent = invent->nobj; 117. else { 118. for(otmp = invent; otmp->nobj != obj; otmp = otmp->nobj) 119. if(!otmp->nobj) panic("freeinv"); 120. otmp->nobj = obj->nobj; 121. } 122. } 123. 124. /* destroy object in fobj chain (if unpaid, it remains on the bill) */ 125. delobj(obj) register struct obj *obj; { 126. freeobj(obj); 127. unpobj(obj); 128. obfree(obj, (struct obj *) 0); 129. } 130. 131. /* unlink obj from chain starting with fobj */ 132. freeobj(obj) register struct obj *obj; { 133. register struct obj *otmp; 134. 135. if(obj == fobj) fobj = fobj->nobj; 136. else { 137. for(otmp = fobj; otmp->nobj != obj; otmp = otmp->nobj) 138. if(!otmp) panic("error in freeobj"); 139. otmp->nobj = obj->nobj; 140. } 141. } 142. 143. /* Note: freegold throws away its argument! */ 144. freegold(gold) register struct gold *gold; { 145. register struct gold *gtmp; 146. 147. if(gold == fgold) fgold = gold->ngold; 148. else { 149. for(gtmp = fgold; gtmp->ngold != gold; gtmp = gtmp->ngold) 150. if(!gtmp) panic("error in freegold"); 151. gtmp->ngold = gold->ngold; 152. } 153. free((char *) gold); 154. } 155. 156. deltrap(trap) 157. register struct trap *trap; 158. { 159. register struct trap *ttmp; 160. 161. if(trap == ftrap) 162. ftrap = ftrap->ntrap; 163. else { 164. for(ttmp = ftrap; ttmp->ntrap != trap; ttmp = ttmp->ntrap) ; 165. ttmp->ntrap = trap->ntrap; 166. } 167. free((char *) trap); 168. } 169. 170. struct wseg *m_atseg; 171. 172. struct monst * 173. m_at(x,y) 174. register x,y; 175. { 176. register struct monst *mtmp; 177. #ifndef NOWORM 178. register struct wseg *wtmp; 179. #endif 180. 181. m_atseg = 0; 182. for(mtmp = fmon; mtmp; mtmp = mtmp->nmon){ 183. if(mtmp->mx == x && mtmp->my == y) 184. return(mtmp); 185. #ifndef NOWORM 186. if(mtmp->wormno){ 187. for(wtmp = wsegs[mtmp->wormno]; wtmp; wtmp = wtmp->nseg) 188. if(wtmp->wx == x && wtmp->wy == y){ 189. m_atseg = wtmp; 190. return(mtmp); 191. } 192. } 193. #endif 194. } 195. return(0); 196. } 197. 198. struct obj * 199. o_at(x,y) 200. register x,y; 201. { 202. register struct obj *otmp; 203. 204. for(otmp = fobj; otmp; otmp = otmp->nobj) 205. if(otmp->ox == x && otmp->oy == y) return(otmp); 206. return(0); 207. } 208. 209. struct obj * 210. sobj_at(n,x,y) 211. register n,x,y; 212. { 213. register struct obj *otmp; 214. 215. for(otmp = fobj; otmp; otmp = otmp->nobj) 216. if(otmp->ox == x && otmp->oy == y && otmp->otyp == n) 217. return(otmp); 218. return(0); 219. } 220. 221. carried(obj) register struct obj *obj; { 222. register struct obj *otmp; 223. for(otmp = invent; otmp; otmp = otmp->nobj) 224. if(otmp == obj) return(1); 225. return(0); 226. } 227. 228. struct obj * 229. carrying(type) 230. register int type; 231. { 232. register struct obj *otmp; 233. 234. for(otmp = invent; otmp; otmp = otmp->nobj) 235. if(otmp->otyp == type) 236. return(otmp); 237. return((struct obj *) 0); 238. } 239. 240. struct obj * 241. o_on(id, objchn) unsigned int id; register struct obj *objchn; { 242. while(objchn) { 243. if(objchn->o_id == id) return(objchn); 244. objchn = objchn->nobj; 245. } 246. return((struct obj *) 0); 247. } 248. 249. struct trap * 250. t_at(x,y) 251. register x,y; 252. { 253. register struct trap *trap = ftrap; 254. while(trap) { 255. if(trap->tx == x && trap->ty == y) return(trap); 256. trap = trap->ntrap; 257. } 258. return(0); 259. } 260. 261. struct gold * 262. g_at(x,y) 263. register x,y; 264. { 265. register struct gold *gold = fgold; 266. while(gold) { 267. if(gold->gx == x && gold->gy == y) return(gold); 268. gold = gold->ngold; 269. } 270. return(0); 271. } 272. 273. /* make dummy object structure containing gold - for temporary use only */ 274. struct obj * 275. mkgoldobj(q) 276. register long q; 277. { 278. register struct obj *otmp; 279. 280. otmp = newobj(0); 281. /* should set o_id etc. but otmp will be freed soon */ 282. otmp->olet = '$'; 283. u.ugold -= q; 284. OGOLD(otmp) = q; 285. flags.botl = 1; 286. return(otmp); 287. } 288. 289. /* 290. * getobj returns: 291. * struct obj *xxx: object to do something with. 292. * (struct obj *) 0 error return: no object. 293. * &zeroobj explicitly no object (as in w-). 294. */ 295. struct obj * 296. getobj(let,word) 297. register char *let,*word; 298. { 299. register struct obj *otmp; 300. register char ilet,ilet1,ilet2; 301. char buf[BUFSZ]; 302. char lets[BUFSZ]; 303. register int foo = 0, foo2; 304. register char *bp = buf; 305. xchar allowcnt = 0; /* 0, 1 or 2 */ 306. boolean allowgold = FALSE; 307. boolean allowall = FALSE; 308. boolean allownone = FALSE; 309. xchar foox = 0; 310. long cnt; 311. 312. if(*let == '0') let++, allowcnt = 1; 313. if(*let == '$') let++, allowgold = TRUE; 314. if(*let == '#') let++, allowall = TRUE; 315. if(*let == '-') let++, allownone = TRUE; 316. if(allownone) *bp++ = '-'; 317. if(allowgold) *bp++ = '$'; 318. if(bp > buf && bp[-1] == '-') *bp++ = ' '; 319. 320. ilet = 'a'; 321. for(otmp = invent; otmp; otmp = otmp->nobj){ 322. if(!*let || index(let, otmp->olet)) { 323. bp[foo++] = flags.invlet_constant ? otmp->invlet : ilet; 324. 325. /* ugly check: remove inappropriate things */ 326. if((!strcmp(word, "take off") && 327. !(otmp->owornmask & (W_ARMOR - W_ARM2))) 328. || (!strcmp(word, "wear") && 329. (otmp->owornmask & (W_ARMOR | W_RING))) 330. || (!strcmp(word, "wield") && 331. (otmp->owornmask & W_WEP)) 332. #ifdef MARKER 333. || (!strcmp(word, "write with") && 334. (otmp->olet == TOOL_SYM && otmp->otyp != MAGIC_MARKER)) 335. #endif 336. ) { 337. foo--; 338. foox++; 339. } 340. } 341. if(ilet == 'z') ilet = 'A'; else ilet++; 342. } 343. bp[foo] = 0; 344. if(foo == 0 && bp > buf && bp[-1] == ' ') *--bp = 0; 345. (void) strcpy(lets, bp); /* necessary since we destroy buf */ 346. if(foo > 5) { /* compactify string */ 347. foo = foo2 = 1; 348. ilet2 = bp[0]; 349. ilet1 = bp[1]; 350. while(ilet = bp[++foo2] = bp[++foo]){ 351. if(ilet == ilet1+1){ 352. if(ilet1 == ilet2+1) 353. bp[foo2 - 1] = ilet1 = '-'; 354. else if(ilet2 == '-') { 355. bp[--foo2] = ++ilet1; 356. continue; 357. } 358. } 359. ilet2 = ilet1; 360. ilet1 = ilet; 361. } 362. } 363. if(!foo && !allowall && !allowgold && !allownone) { 364. pline("You don't have anything %sto %s.", 365. foox ? "else " : "", word); 366. return(0); 367. } 368. for(;;) { 369. if(!buf[0]) 370. #ifdef REDO 371. if(!in_doagain) 372. #endif 373. pline("What do you want to %s [*]? ", word); 374. else 375. #ifdef REDO 376. if(!in_doagain) 377. #endif 378. pline("What do you want to %s [%s or ?*]? ", 379. word, buf); 380. 381. cnt = 0; 382. ilet = readchar(); 383. while(digit(ilet) && allowcnt) { 384. #ifdef REDO 385. if (ilet != '?' && ilet != '*') savech(ilet); 386. #endif 387. cnt = 10*cnt + (ilet - '0'); 388. allowcnt = 2; /* signal presence of cnt */ 389. ilet = readchar(); 390. } 391. if(digit(ilet)) { 392. pline("No count allowed with this command."); 393. continue; 394. } 395. if(index(quitchars,ilet)) 396. return((struct obj *)0); 397. if(ilet == '-') { 398. return(allownone ? &zeroobj : (struct obj *) 0); 399. } 400. if(ilet == '$') { 401. if(!allowgold){ 402. pline("You cannot %s gold.", word); 403. continue; 404. } 405. if(!(allowcnt == 2 && cnt < u.ugold)) 406. cnt = u.ugold; 407. return(mkgoldobj(cnt)); 408. } 409. if(ilet == '?') { 410. doinv(lets); 411. if(!(ilet = morc)) continue; 412. /* he typed a letter (not a space) to more() */ 413. } else if(ilet == '*') { 414. doinv((char *) 0); 415. if(!(ilet = morc)) continue; 416. /* ... */ 417. } 418. #ifdef REDO 419. if (ilet != '?' && ilet != '*') savech(ilet); 420. #endif 421. if(flags.invlet_constant) { 422. for(otmp = invent; otmp; otmp = otmp->nobj) 423. if(otmp->invlet == ilet) break; 424. } else { 425. if(ilet >= 'A' && ilet <= 'Z') ilet += 'z'-'A'+1; 426. ilet -= 'a'; 427. for(otmp = invent; otmp && ilet; 428. ilet--, otmp = otmp->nobj) ; 429. } 430. if(!otmp) { 431. pline("You don't have that object."); 432. continue; 433. } 434. if(cnt < 0 || otmp->quan < cnt) { 435. pline("You don't have that many! [You have %u]" 436. , otmp->quan); 437. continue; 438. } 439. break; 440. } 441. if(!allowall && let && !index(let,otmp->olet)) { 442. pline("That is a silly thing to %s.",word); 443. return(0); 444. } 445. if(allowcnt == 2) { /* cnt given */ 446. if(cnt == 0) return(0); 447. if(cnt != otmp->quan) { 448. register struct obj *obj; 449. obj = splitobj(otmp, (int) cnt); 450. if(otmp == uwep) setuwep(obj); 451. } 452. } 453. return(otmp); 454. } 455. 456. ckunpaid(otmp) register struct obj *otmp; { 457. return( otmp->unpaid ); 458. } 459. 460. /* interactive version of getobj - used for Drop and Identify */ 461. /* return the number of times fn was called successfully */ 462. ggetobj(word, fn, max) 463. char *word; 464. int (*fn)(), max; 465. { 466. char buf[BUFSZ]; 467. register char *ip; 468. register char sym; 469. register int oletct = 0, iletct = 0; 470. register boolean allflag = FALSE; 471. char olets[20], ilets[20]; 472. int (*ckfn)() = (int (*)()) 0; 473. xchar allowgold = (u.ugold && !strcmp(word, "drop")) ? 1 : 0; /* BAH */ 474. if(!invent && !allowgold){ 475. pline("You have nothing to %s.", word); 476. return(0); 477. } else { 478. register struct obj *otmp = invent; 479. register int uflg = 0; 480. 481. if(allowgold) ilets[iletct++] = '$'; 482. ilets[iletct] = 0; 483. while(otmp) { 484. if(!index(ilets, otmp->olet)){ 485. ilets[iletct++] = otmp->olet; 486. ilets[iletct] = 0; 487. } 488. if(otmp->unpaid) uflg = 1; 489. otmp = otmp->nobj; 490. } 491. ilets[iletct++] = ' '; 492. if(uflg) ilets[iletct++] = 'u'; 493. if(invent) ilets[iletct++] = 'a'; 494. ilets[iletct] = 0; 495. } 496. pline("What kinds of thing do you want to %s? [%s] ", 497. word, ilets); 498. getlin(buf); 499. if(buf[0] == '\033') { 500. clrlin(); 501. return(0); 502. } 503. ip = buf; 504. olets[0] = 0; 505. while(sym = *ip++){ 506. if(sym == ' ') continue; 507. if(sym == '$') { 508. if(allowgold == 1) 509. (*fn)(mkgoldobj(u.ugold)); 510. else if(!u.ugold) 511. pline("You have no gold."); 512. allowgold = 2; 513. } else 514. if(sym == 'a' || sym == 'A') allflag = TRUE; else 515. if(sym == 'u' || sym == 'U') ckfn = ckunpaid; else 516. #ifdef SPELLS 517. if(index("!%?[()=*/+\"0", sym)){ 518. #else 519. if(index("!%?[()=*/\"0", sym)){ 520. #endif 521. if(!index(olets, sym)){ 522. olets[oletct++] = sym; 523. olets[oletct] = 0; 524. } 525. } 526. else pline("You don't have any %c's.", sym); 527. } 528. if(allowgold == 2 && !oletct) 529. return(1); /* he dropped gold (or at least tried to) */ 530. else 531. return(askchain(invent, olets, allflag, fn, ckfn, max)); 532. } 533. 534. /* 535. * Walk through the chain starting at objchn and ask for all objects 536. * with olet in olets (if nonNULL) and satisfying ckfn (if nonNULL) 537. * whether the action in question (i.e., fn) has to be performed. 538. * If allflag then no questions are asked. Max gives the max nr of 539. * objects to be treated. Return the number of objects treated. 540. */ 541. askchain(objchn, olets, allflag, fn, ckfn, max) 542. struct obj *objchn; 543. register char *olets; 544. int allflag; 545. int (*fn)(), (*ckfn)(); 546. int max; 547. { 548. register struct obj *otmp, *otmp2; 549. register char sym, ilet; 550. register int cnt = 0; 551. #ifdef SORTING 552. /* changes so the askchain is interrogated in the order specified. 553. * For example, if a person specifies =/ then first all rings will be 554. * asked about followed by all wands -dgk 555. */ 556. nextclass: 557. #endif 558. ilet = 'a'-1; 559. for(otmp = objchn; otmp; otmp = otmp2){ 560. if(ilet == 'z') ilet = 'A'; else ilet++; 561. otmp2 = otmp->nobj; 562. #ifdef SORTING 563. if (olets && *olets && otmp->olet != *olets) continue; 564. #else 565. if(olets && *olets && !index(olets, otmp->olet)) continue; 566. #endif 567. if(ckfn && !(*ckfn)(otmp)) continue; 568. if(!allflag) { 569. pline(xprname(otmp, ilet)); 570. addtopl(" [nyaq]? "); 571. sym = readchar(); 572. } 573. else sym = 'y'; 574. 575. switch(sym){ 576. case 'a': 577. allflag = 1; 578. case 'y': 579. cnt += (*fn)(otmp); 580. if(--max == 0) goto ret; 581. case 'n': 582. default: 583. break; 584. case 'q': 585. goto ret; 586. } 587. } 588. #ifdef SORTING 589. if (olets && *olets && *++olets) 590. goto nextclass; 591. #endif 592. pline(cnt ? "That was all." : "No applicable objects."); 593. ret: 594. return(cnt); 595. } 596. 597. obj_to_let(obj) /* should of course only be called for things in invent */ 598. register struct obj *obj; 599. { 600. register struct obj *otmp; 601. register char ilet; 602. 603. if(flags.invlet_constant) 604. return(obj->invlet); 605. ilet = 'a'; 606. for(otmp = invent; otmp && otmp != obj; otmp = otmp->nobj) 607. if(++ilet > 'z') ilet = 'A'; 608. return(otmp ? ilet : NOINVSYM); 609. } 610. 611. prinv(obj) 612. register struct obj *obj; 613. { 614. pline(xprname(obj, obj_to_let(obj))); 615. } 616. 617. static char * 618. xprname(obj,let) 619. register struct obj *obj; 620. register char let; 621. { 622. static char li[BUFSZ]; 623. 624. (void) sprintf(li, "%c - %s.", 625. flags.invlet_constant ? obj->invlet : let, 626. doname(obj)); 627. return(li); 628. } 629. 630. ddoinv() 631. { 632. doinv((char *) 0); 633. return(0); 634. } 635. 636. #ifdef SORTING 637. # ifdef SPELLS 638. char inv_order[] = "\")[%?+/=!(*0_`"; /* to be safe, include _ and ` */ 639. # else 640. char inv_order[] = "\")[%?/=!(*0_`"; 641. # endif 642. extern char *let_to_name(); 643. #endif 644. 645. /* called with 0 or "": all objects in inventory */ 646. /* otherwise: all objects with (serial) letter in lets */ 647. doinv(lets) 648. register char *lets; 649. { 650. register struct obj *otmp; 651. register char ilet; 652. int ct = 0; 653. char any[BUFSZ]; 654. #ifdef SORTING 655. char *invlet = inv_order; 656. int classcount = 0; 657. #endif /* SORTING /**/ 658. 659. morc = 0; /* just to be sure */ 660. 661. if(!invent){ 662. pline("Not carrying anything."); 663. return; 664. } 665. 666. cornline(0, (char *) 0); 667. #ifdef SORTING 668. nextclass: 669. classcount = 0; 670. ilet = 'a'; 671. for(otmp = invent; otmp; otmp = otmp->nobj) { 672. if(flags.invlet_constant) ilet = otmp->invlet; 673. if(!lets || !*lets || index(lets, ilet)) { 674. if (!flags.sortpack || otmp->olet == *invlet) { 675. if (flags.sortpack && !classcount) { 676. cornline(1, let_to_name(*invlet)); 677. classcount++; 678. } 679. cornline(1, xprname(otmp, ilet)); 680. any[ct++] = ilet; 681. } 682. } 683. if(!flags.invlet_constant) if(++ilet > 'z') ilet = 'A'; 684. } 685. if (flags.sortpack && *++invlet) goto nextclass; 686. #else 687. ilet = 'a'; 688. for(otmp = invent; otmp; otmp = otmp->nobj) { 689. if(flags.invlet_constant) ilet = otmp->invlet; 690. if(!lets || !*lets || index(lets, ilet)) { 691. cornline(1, xprname(otmp, ilet)); 692. any[ct++] = ilet; 693. } 694. if(!flags.invlet_constant) if(++ilet > 'z') ilet = 'A'; 695. } 696. #endif /* SORTING /**/ 697. any[ct] = 0; 698. cornline(2, any); 699. } 700. 701. dotypeinv () /* free after Robert Viduya */ 702. /* Changed to one type only, so he doesnt have to type cr */ 703. { 704. char c, ilet; 705. char stuff[BUFSZ]; 706. register int stct; 707. register struct obj *otmp; 708. boolean billx = inshop() && doinvbill(0); 709. boolean unpd = FALSE; 710. 711. if (!invent && !u.ugold && !billx) { 712. pline ("You aren't carrying anything."); 713. return(0); 714. } 715. 716. stct = 0; 717. if(u.ugold) stuff[stct++] = '$'; 718. stuff[stct] = 0; 719. for(otmp = invent; otmp; otmp = otmp->nobj) { 720. if (!index (stuff, otmp->olet)) { 721. stuff[stct++] = otmp->olet; 722. stuff[stct] = 0; 723. } 724. if(otmp->unpaid) 725. unpd = TRUE; 726. } 727. if(unpd) stuff[stct++] = 'u'; 728. if(billx) stuff[stct++] = 'x'; 729. stuff[stct] = 0; 730. 731. if(stct > 1) { 732. #ifdef REDO 733. if (!in_doagain) 734. #endif 735. pline ("What type of object [%s] do you want an inventory of? ", 736. stuff); 737. c = readchar(); 738. #ifdef REDO 739. savech(c); 740. #endif 741. if(index(quitchars,c)) return(0); 742. } else 743. c = stuff[0]; 744. 745. if(c == '$') 746. return(doprgold()); 747. 748. if(c == 'x' || c == 'X') { 749. if(billx) 750. (void) doinvbill(1); 751. else 752. pline("No used-up objects on the shopping bill."); 753. return(0); 754. } 755. 756. if((c == 'u' || c == 'U') && !unpd) { 757. pline("You are not carrying any unpaid objects."); 758. return(0); 759. } 760. 761. stct = 0; 762. ilet = 'a'; 763. for (otmp = invent; otmp; otmp = otmp -> nobj) { 764. if(flags.invlet_constant) ilet = otmp->invlet; 765. if (c == otmp -> olet || (c == 'u' && otmp -> unpaid)) 766. stuff[stct++] = ilet; 767. if(!flags.invlet_constant) if(++ilet > 'z') ilet = 'A'; 768. } 769. stuff[stct] = '\0'; 770. if(stct == 0) 771. pline("You have no such objects."); 772. else 773. doinv (stuff); 774. 775. return(0); 776. } 777. 778. /* look at what is here */ 779. dolook() { 780. register struct obj *otmp, *otmp0; 781. register struct gold *gold; 782. char *verb = Blind ? "feel" : "see"; 783. int ct = 0; 784. int fd = 0; 785. 786. #ifdef KAA 787. if(!Blind) read_engr_at(u.ux, u.uy); /* Eric Backus */ 788. #endif 789. if(!u.uswallow) { 790. otmp0 = o_at(u.ux, u.uy); 791. gold = g_at(u.ux, u.uy); 792. } else { 793. pline("You %s no objects here.", verb); 794. return(!!Blind); 795. } 796. 797. /* added by GAN 10/30/86 */ 798. #ifdef FOUNTAINS 799. if(IS_FOUNTAIN(levl[u.ux][u.uy].typ)) { 800. fd++; 801. pline("There is a fountain here."); 802. } 803. #endif 804. #ifdef NEWCLASS 805. if(IS_THRONE(levl[u.ux][u.uy].typ)) { 806. fd++; 807. pline("There is an opulent throne here."); 808. } 809. #endif 810. if(u.ux == xupstair && u.uy == yupstair) { 811. fd++; 812. pline("There is a stairway up here."); 813. } 814. if(u.ux == xdnstair && u.uy == ydnstair) { 815. fd++; 816. cornline(1, "There is a stairway down here."); 817. } 818. if(Blind) { 819. pline("You try to feel what is lying here on the floor."); 820. if(Levitation) { 821. pline("But you can't reach it!"); 822. return(0); 823. } 824. } 825. 826. if(!otmp0 && !gold) { 827. if(Blind || !fd) 828. pline("You %s no objects here.", verb); 829. return(!!Blind); 830. } 831. 832. cornline(0, "Things that are here:"); 833. for(otmp = otmp0; otmp; otmp = otmp->nobj) { 834. if(otmp->ox == u.ux && otmp->oy == u.uy) { 835. ct++; 836. cornline(1, doname(otmp)); 837. if(Blind && otmp->otyp == DEAD_COCKATRICE && !uarmg) { 838. pline("Touching the dead cockatrice is a fatal mistake ..."); 839. pline("You die ..."); 840. killer = "dead cockatrice"; 841. done("died"); 842. } 843. } 844. } 845. 846. if(gold) { 847. char gbuf[30]; 848. 849. (void) sprintf(gbuf, "%ld gold piece%s", 850. gold->amount, plur(gold->amount)); 851. if(!ct++) 852. pline("You %s here %s.", verb, gbuf); 853. else 854. cornline(1, gbuf); 855. } 856. 857. if(ct == 1 && !gold) { 858. pline("You %s here %s.", verb, doname(otmp0)); 859. cornline(3, (char *) 0); 860. } 861. if(ct > 1) 862. cornline(2, (char *) 0); 863. return(!!Blind); 864. } 865. 866. stackobj(obj) register struct obj *obj; { 867. register struct obj *otmp = fobj; 868. for(otmp = fobj; otmp; otmp = otmp->nobj) if(otmp != obj) 869. if(otmp->ox == obj->ox && otmp->oy == obj->oy && 870. merged(obj,otmp,1)) 871. return; 872. } 873. 874. /* merge obj with otmp and delete obj if types agree */ 875. merged(otmp,obj,lose) register struct obj *otmp, *obj; { 876. if(obj->otyp == otmp->otyp && 877. obj->unpaid == otmp->unpaid && 878. obj->spe == otmp->spe && 879. obj->dknown == otmp->dknown && 880. obj->cursed == otmp->cursed && 881. #ifdef SPELLS 882. (index("%*?!+", obj->olet) || 883. #else 884. (index("%*?!", obj->olet) || 885. #endif 886. (obj->known == otmp->known && 887. (obj->olet == WEAPON_SYM && obj->otyp < BOOMERANG)))) { 888. otmp->quan += obj->quan; 889. otmp->owt += obj->owt; 890. if(lose) freeobj(obj); 891. obfree(obj,otmp); /* free(obj), bill->otmp */ 892. return(1); 893. } else return(0); 894. } 895. 896. /* 897. * Gold is no longer displayed; in fact, when you have a lot of money, 898. * it may take a while before you have counted it all. 899. * [Bug: d$ and pickup still tell you how much it was.] 900. */ 901. extern int (*occupation)(); 902. extern char *occtxt; 903. static long goldcounted; 904. 905. countgold(){ 906. if((goldcounted += 100*(u.ulevel + 1)) >= u.ugold) { 907. long eps = 0; 908. if(!rn2(2)) eps = rnd((int) (u.ugold/100 + 1)); 909. pline("You probably have about %ld gold pieces.", 910. u.ugold + eps); 911. return(0); /* done */ 912. } 913. return(1); /* continue */ 914. } 915. 916. doprgold(){ 917. if(!u.ugold) 918. pline("You do not carry any gold."); 919. else if(u.ugold <= 500) 920. pline("You are carrying %ld gold piece%s.", u.ugold, plur(u.ugold)); 921. else { 922. pline("You sit down in order to count your gold pieces."); 923. goldcounted = 500; 924. occupation = countgold; 925. occtxt = "counting your gold"; 926. } 927. return(1); 928. } 929. 930. /* --- end of gold counting section --- */ 931. 932. doprwep(){ 933. if(!uwep) pline("You are empty handed."); 934. else prinv(uwep); 935. return(0); 936. } 937. 938. doprarm(){ 939. if(!uarm && !uarmg && !uarms && !uarmh) 940. pline("You are not wearing any armor."); 941. else { 942. char lets[6]; 943. register int ct = 0; 944. 945. if(uarm) lets[ct++] = obj_to_let(uarm); 946. if(uarm2) lets[ct++] = obj_to_let(uarm2); 947. if(uarmh) lets[ct++] = obj_to_let(uarmh); 948. if(uarms) lets[ct++] = obj_to_let(uarms); 949. if(uarmg) lets[ct++] = obj_to_let(uarmg); 950. lets[ct] = 0; 951. doinv(lets); 952. } 953. return(0); 954. } 955. 956. doprring(){ 957. if(!uleft && !uright) 958. pline("You are not wearing any rings."); 959. else { 960. char lets[3]; 961. register int ct = 0; 962. 963. if(uleft) lets[ct++] = obj_to_let(uleft); 964. if(uright) lets[ct++] = obj_to_let(uright); 965. lets[ct] = 0; 966. doinv(lets); 967. } 968. return(0); 969. } 970. 971. digit(c) char c; { 972. return(c >= '0' && c <= '9'); 973. } 974. 975. /* 976. * useupf(obj) 977. * uses up an object that's on the floor 978. */ 979. useupf(obj) 980. register struct obj *obj; 981. { 982. if(obj->quan > 1) { 983. obj->quan--; 984. obj->owt = weight(obj); 985. } else delobj(obj); 986. } 987. 988. #ifdef SORTING 989. /* 990. * Convert from a symbol to a string for printing object classes 991. * 992. * Names from objects.h 993. * char obj_symbols[] = { 994. * ILLOBJ_SYM, AMULET_SYM, FOOD_SYM, WEAPON_SYM, TOOL_SYM, 995. * BALL_SYM, CHAIN_SYM, ROCK_SYM, ARMOR_SYM, POTION_SYM, SCROLL_SYM, 996. * WAND_SYM, [SPBOOK_SYM], RING_SYM, GEM_SYM, 0 }; 997. */ 998. #define Sprintf (void) sprintf 999. 1000. extern char obj_symbols[]; 1001. static char *names[] = {"Illegal objects", "Amulets", "Comestibles", "Weapons", 1002. "Tools", "Iron balls", "Chains", "Rocks", "Armor", 1003. "Potions", "Scrolls", "Wands", 1004. #ifdef SPELLS 1005. "Spellbooks", 1006. #endif 1007. "Rings", "Gems"}; 1008. char * 1009. let_to_name(let) 1010. char let; 1011. { 1012. char *pos = index(obj_symbols, let); 1013. extern char *HI, *HE; 1014. /* buffer size is len(HI) + len(HE) + max(len(names[])) + 1 */ 1015. static char buf[4 + 4 + 15 + 1]; 1016. 1017. if (pos == NULL) pos = obj_symbols; 1018. Sprintf(buf, "%s%s%s", HI, names[pos - obj_symbols], HE); 1019. return (buf); 1020. } 1021. #endif /* SORTING /**/
|