Source:NetHack 2.3e/invent.c
Jump to navigation
Jump to search
Below is the full text to invent.c from the source code of NetHack 2.3e.
Warning! This is the source code from an old release. For newer releases, see Source code
Screenshots and source code from Hack are used under the CWI license.
1. /* SCCS Id: @(#)invent.c 2.3 88/01/21 2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3. 4. #include <stdio.h> 5. #include "hack.h" 6. extern struct obj *splitobj(); 7. extern struct obj zeroobj; 8. extern void savech(); 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 = GOLD_SYM; 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 == GOLD_SYM) let++, allowgold = TRUE; 314. if(*let == '#') let++, allowall = TRUE; 315. if(*let == '-') let++, allownone = TRUE; 316. if(allownone) *bp++ = '-'; 317. if(allowgold) *bp++ = GOLD_SYM; 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. pline("Never mind."); 397. return((struct obj *)0); 398. } 399. if(ilet == '-') { 400. return(allownone ? &zeroobj : (struct obj *) 0); 401. } 402. if(ilet == GOLD_SYM) { 403. if(!allowgold){ 404. pline("You cannot %s gold.", word); 405. continue; 406. } 407. if(!(allowcnt == 2 && cnt < u.ugold)) 408. cnt = u.ugold; 409. return(mkgoldobj(cnt)); 410. } 411. if(ilet == '?') { 412. doinv(lets); 413. if(!(ilet = morc)) continue; 414. /* he typed a letter (not a space) to more() */ 415. } else if(ilet == '*') { 416. doinv((char *) 0); 417. if(!(ilet = morc)) continue; 418. /* ... */ 419. } 420. #ifdef REDO 421. if (ilet != '?' && ilet != '*') savech(ilet); 422. #endif 423. if(flags.invlet_constant) { 424. for(otmp = invent; otmp; otmp = otmp->nobj) 425. if(otmp->invlet == ilet) break; 426. } else { 427. if(ilet >= 'A' && ilet <= 'Z') ilet += 'z'-'A'+1; 428. ilet -= 'a'; 429. for(otmp = invent; otmp && ilet; 430. ilet--, otmp = otmp->nobj) ; 431. } 432. if(!otmp) { 433. pline("You don't have that object."); 434. continue; 435. } 436. if(cnt < 0 || otmp->quan < cnt) { 437. pline("You don't have that many! [You have %u]" 438. , otmp->quan); 439. continue; 440. } 441. break; 442. } 443. if(!allowall && let && !index(let,otmp->olet)) { 444. pline("That is a silly thing to %s.",word); 445. return(0); 446. } 447. if(allowcnt == 2) { /* cnt given */ 448. if(cnt == 0) return(0); 449. if(cnt != otmp->quan) { 450. register struct obj *obj; 451. obj = splitobj(otmp, (int) cnt); 452. if(otmp == uwep) setuwep(obj); 453. } 454. } 455. return(otmp); 456. } 457. 458. ckunpaid(otmp) register struct obj *otmp; { 459. return( otmp->unpaid ); 460. } 461. 462. /* interactive version of getobj - used for Drop and Identify */ 463. /* return the number of times fn was called successfully */ 464. ggetobj(word, fn, max) 465. char *word; 466. int (*fn)(), max; 467. { 468. char buf[BUFSZ]; 469. register char *ip; 470. register char sym; 471. register int oletct = 0, iletct = 0; 472. register boolean allflag = FALSE; 473. char olets[20], ilets[20]; 474. int (*ckfn)() = (int (*)()) 0; 475. xchar allowgold = (u.ugold && !strcmp(word, "drop")) ? 1 : 0; /* BAH */ 476. if(!invent && !allowgold){ 477. pline("You have nothing to %s.", word); 478. return(0); 479. } else { 480. register struct obj *otmp = invent; 481. register int uflg = 0; 482. 483. if(allowgold) ilets[iletct++] = GOLD_SYM; 484. ilets[iletct] = 0; 485. while(otmp) { 486. if(!index(ilets, otmp->olet)){ 487. ilets[iletct++] = otmp->olet; 488. ilets[iletct] = 0; 489. } 490. if(otmp->unpaid) uflg = 1; 491. otmp = otmp->nobj; 492. } 493. ilets[iletct++] = ' '; 494. if(uflg) ilets[iletct++] = 'u'; 495. if(invent) ilets[iletct++] = 'a'; 496. ilets[iletct] = 0; 497. } 498. pline("What kinds of thing do you want to %s? [%s] ", 499. word, ilets); 500. getlin(buf); 501. if(buf[0] == '\033') { 502. clrlin(); 503. return(0); 504. } 505. ip = buf; 506. olets[0] = 0; 507. while(sym = *ip++){ 508. if(sym == ' ') continue; 509. if(sym == GOLD_SYM) { 510. if(allowgold == 1) 511. (*fn)(mkgoldobj(u.ugold)); 512. else if(!u.ugold) 513. pline("You have no gold."); 514. allowgold = 2; 515. } else 516. if(sym == 'a' || sym == 'A') allflag = TRUE; else 517. if(sym == 'u' || sym == 'U') ckfn = ckunpaid; else 518. #ifdef SPELLS 519. if(index("!%?[()=*/+\"0", sym)){ 520. #else 521. if(index("!%?[()=*/\"0", sym)){ 522. #endif 523. if(!index(olets, sym)){ 524. olets[oletct++] = sym; 525. olets[oletct] = 0; 526. } 527. } 528. else pline("You don't have any %c's.", sym); 529. } 530. if(allowgold == 2 && !oletct) 531. return(1); /* he dropped gold (or at least tried to) */ 532. else 533. return(askchain(invent, olets, allflag, fn, ckfn, max)); 534. } 535. 536. /* 537. * Walk through the chain starting at objchn and ask for all objects 538. * with olet in olets (if nonNULL) and satisfying ckfn (if nonNULL) 539. * whether the action in question (i.e., fn) has to be performed. 540. * If allflag then no questions are asked. Max gives the max nr of 541. * objects to be treated. Return the number of objects treated. 542. */ 543. askchain(objchn, olets, allflag, fn, ckfn, max) 544. struct obj *objchn; 545. register char *olets; 546. int allflag; 547. int (*fn)(), (*ckfn)(); 548. int max; 549. { 550. register struct obj *otmp, *otmp2; 551. register char sym, ilet; 552. register int cnt = 0; 553. #ifdef SORTING 554. /* changes so the askchain is interrogated in the order specified. 555. * For example, if a person specifies =/ then first all rings will be 556. * asked about followed by all wands -dgk 557. */ 558. nextclass: 559. #endif 560. ilet = 'a'-1; 561. for(otmp = objchn; otmp; otmp = otmp2){ 562. if(ilet == 'z') ilet = 'A'; else ilet++; 563. otmp2 = otmp->nobj; 564. #ifdef SORTING 565. if (olets && *olets && otmp->olet != *olets) continue; 566. #else 567. if(olets && *olets && !index(olets, otmp->olet)) continue; 568. #endif 569. if(ckfn && !(*ckfn)(otmp)) continue; 570. if(!allflag) { 571. pline(xprname(otmp, ilet)); 572. addtopl(" [nyaq]? "); 573. sym = readchar(); 574. } 575. else sym = 'y'; 576. 577. switch(sym){ 578. case 'a': 579. allflag = 1; 580. case 'y': 581. cnt += (*fn)(otmp); 582. if(--max == 0) goto ret; 583. case 'n': 584. default: 585. break; 586. case 'q': 587. goto ret; 588. } 589. } 590. #ifdef SORTING 591. if (olets && *olets && *++olets) 592. goto nextclass; 593. #endif 594. pline(cnt ? "That was all." : "No applicable objects."); 595. ret: 596. return(cnt); 597. } 598. 599. obj_to_let(obj) /* should of course only be called for things in invent */ 600. register struct obj *obj; 601. { 602. register struct obj *otmp; 603. register char ilet; 604. 605. if(flags.invlet_constant) 606. return(obj->invlet); 607. ilet = 'a'; 608. for(otmp = invent; otmp && otmp != obj; otmp = otmp->nobj) 609. if(++ilet > 'z') ilet = 'A'; 610. return(otmp ? ilet : NOINVSYM); 611. } 612. 613. prinv(obj) 614. register struct obj *obj; 615. { 616. pline(xprname(obj, obj_to_let(obj))); 617. } 618. 619. static char * 620. xprname(obj,let) 621. register struct obj *obj; 622. register char let; 623. { 624. static char li[BUFSZ]; 625. 626. (void) sprintf(li, "%c - %s.", 627. flags.invlet_constant ? obj->invlet : let, 628. doname(obj)); 629. return(li); 630. } 631. 632. ddoinv() 633. { 634. doinv((char *) 0); 635. return(0); 636. } 637. 638. #ifdef SORTING 639. # ifdef SPELLS 640. char inv_order[] = "\")[%?+/=!(*0_`"; /* to be safe, include _ and ` */ 641. # else 642. char inv_order[] = "\")[%?/=!(*0_`"; 643. # endif 644. extern char *let_to_name(); 645. #endif 646. 647. /* called with 0 or "": all objects in inventory */ 648. /* otherwise: all objects with (serial) letter in lets */ 649. doinv(lets) 650. register char *lets; 651. { 652. register struct obj *otmp; 653. register char ilet; 654. int ct = 0; 655. char any[BUFSZ]; 656. #ifdef SORTING 657. char *invlet = inv_order; 658. int classcount = 0; 659. #endif /* SORTING /**/ 660. 661. morc = 0; /* just to be sure */ 662. 663. if(!invent){ 664. pline("Not carrying anything."); 665. return; 666. } 667. 668. cornline(0, (char *) 0); 669. #ifdef SORTING 670. nextclass: 671. classcount = 0; 672. ilet = 'a'; 673. for(otmp = invent; otmp; otmp = otmp->nobj) { 674. if(flags.invlet_constant) ilet = otmp->invlet; 675. if(!lets || !*lets || index(lets, ilet)) { 676. if (!flags.sortpack || otmp->olet == *invlet) { 677. if (flags.sortpack && !classcount) { 678. cornline(1, let_to_name(*invlet)); 679. classcount++; 680. } 681. cornline(1, xprname(otmp, ilet)); 682. any[ct++] = ilet; 683. } 684. } 685. if(!flags.invlet_constant) if(++ilet > 'z') ilet = 'A'; 686. } 687. if (flags.sortpack && *++invlet) goto nextclass; 688. #else 689. ilet = 'a'; 690. for(otmp = invent; otmp; otmp = otmp->nobj) { 691. if(flags.invlet_constant) ilet = otmp->invlet; 692. if(!lets || !*lets || index(lets, ilet)) { 693. cornline(1, xprname(otmp, ilet)); 694. any[ct++] = ilet; 695. } 696. if(!flags.invlet_constant) if(++ilet > 'z') ilet = 'A'; 697. } 698. #endif /* SORTING /**/ 699. any[ct] = 0; 700. cornline(2, any); 701. } 702. 703. dotypeinv () /* free after Robert Viduya */ 704. /* Changed to one type only, so he doesnt have to type cr */ 705. { 706. char c, ilet; 707. char stuff[BUFSZ]; 708. register int stct; 709. register struct obj *otmp; 710. boolean billx = inshop() && doinvbill(0); 711. boolean unpd = FALSE; 712. 713. if (!invent && !u.ugold && !billx) { 714. pline ("You aren't carrying anything."); 715. return(0); 716. } 717. 718. stct = 0; 719. if(u.ugold) stuff[stct++] = GOLD_SYM; 720. stuff[stct] = 0; 721. for(otmp = invent; otmp; otmp = otmp->nobj) { 722. if (!index (stuff, otmp->olet)) { 723. stuff[stct++] = otmp->olet; 724. stuff[stct] = 0; 725. } 726. if(otmp->unpaid) 727. unpd = TRUE; 728. } 729. if(unpd) stuff[stct++] = 'u'; 730. if(billx) stuff[stct++] = 'x'; 731. stuff[stct] = 0; 732. 733. if(stct > 1) { 734. #ifdef REDO 735. if (!in_doagain) 736. #endif 737. pline ("What type of object [%s] do you want an inventory of? ", 738. stuff); 739. c = readchar(); 740. #ifdef REDO 741. savech(c); 742. #endif 743. if(index(quitchars,c)) { 744. clrlin(); 745. return(0); 746. } 747. } else 748. c = stuff[0]; 749. 750. if(c == GOLD_SYM) 751. return(doprgold()); 752. 753. if(c == 'x' || c == 'X') { 754. if(billx) 755. (void) doinvbill(1); 756. else 757. pline("No used-up objects on the shopping bill."); 758. return(0); 759. } 760. 761. if((c == 'u' || c == 'U') && !unpd) { 762. pline("You are not carrying any unpaid objects."); 763. return(0); 764. } 765. 766. stct = 0; 767. ilet = 'a'; 768. for (otmp = invent; otmp; otmp = otmp -> nobj) { 769. if(flags.invlet_constant) ilet = otmp->invlet; 770. if (c == otmp -> olet || (c == 'u' && otmp -> unpaid)) 771. stuff[stct++] = ilet; 772. if(!flags.invlet_constant) if(++ilet > 'z') ilet = 'A'; 773. } 774. stuff[stct] = '\0'; 775. if(stct == 0) 776. pline("You have no such objects."); 777. else 778. doinv (stuff); 779. 780. return(0); 781. } 782. 783. /* look at what is here */ 784. dolook() { 785. register struct obj *otmp, *otmp0; 786. register struct gold *gold; 787. char *verb = Blind ? "feel" : "see"; 788. int ct = 0; 789. int fd = 0; 790. 791. #ifdef KAA 792. read_engr_at(u.ux, u.uy); /* Eric Backus */ 793. #endif 794. if(!u.uswallow) { 795. otmp0 = o_at(u.ux, u.uy); 796. gold = g_at(u.ux, u.uy); 797. } else { 798. pline("You %s no objects here.", verb); 799. return(!!Blind); 800. } 801. 802. /* added by GAN 10/30/86 */ 803. #ifdef FOUNTAINS 804. if(IS_FOUNTAIN(levl[u.ux][u.uy].typ)) { 805. fd++; 806. pline("There is a fountain here."); 807. } 808. #endif 809. #ifdef NEWCLASS 810. if(IS_THRONE(levl[u.ux][u.uy].typ)) { 811. fd++; 812. pline("There is an opulent throne here."); 813. } 814. #endif 815. #ifdef SINKS 816. if(IS_SINK(levl[u.ux][u.uy].typ)) { 817. fd++; 818. pline("There is a kitchen sink here."); 819. } 820. #endif 821. if(u.ux == xupstair && u.uy == yupstair) { 822. fd++; 823. pline("There is a stairway up here."); 824. } 825. if(u.ux == xdnstair && u.uy == ydnstair) { 826. fd++; 827. pline("There is a stairway down here."); 828. } 829. if(Blind) { 830. pline("You try to feel what is lying here on the floor."); 831. if(Levitation) { 832. pline("But you can't reach it!"); 833. return(0); 834. } 835. } 836. 837. if(!otmp0 && !gold) { 838. if(Blind || !fd) 839. pline("You %s no objects here.", verb); 840. return(!!Blind); 841. } 842. 843. cornline(0, "Things that are here:"); 844. for(otmp = otmp0; otmp; otmp = otmp->nobj) { 845. if(otmp->ox == u.ux && otmp->oy == u.uy) { 846. ct++; 847. cornline(1, doname(otmp)); 848. 849. if(Blind && otmp->otyp == DEAD_COCKATRICE && !uarmg) { 850. pline("Touching the dead cockatrice is a fatal mistake ..."); 851. pline("You die ..."); 852. killer = "dead cockatrice"; 853. done("died"); 854. } 855. } 856. } 857. 858. if(gold) { 859. char gbuf[30]; 860. 861. (void) sprintf(gbuf, "%ld gold piece%s", 862. gold->amount, plur(gold->amount)); 863. if(!ct++) 864. pline("You %s here %s.", verb, gbuf); 865. else 866. cornline(1, gbuf); 867. } 868. 869. if(ct == 1 && !gold) { 870. pline("You %s here %s.", verb, doname(otmp0)); 871. cornline(3, (char *) 0); 872. } 873. if(ct > 1) 874. cornline(2, (char *) 0); 875. return(!!Blind); 876. } 877. 878. stackobj(obj) register struct obj *obj; { 879. register struct obj *otmp = fobj; 880. for(otmp = fobj; otmp; otmp = otmp->nobj) if(otmp != obj) 881. if(otmp->ox == obj->ox && otmp->oy == obj->oy && 882. merged(obj,otmp,1)) 883. return; 884. } 885. 886. /* merge obj with otmp and delete obj if types agree */ 887. merged(otmp,obj,lose) register struct obj *otmp, *obj; { 888. if(obj->otyp == otmp->otyp && 889. obj->unpaid == otmp->unpaid && 890. obj->spe == otmp->spe && 891. obj->dknown == otmp->dknown && 892. obj->cursed == otmp->cursed && 893. #ifdef SPELLS 894. (index("%*?!+", obj->olet) || 895. #else 896. (index("%*?!", obj->olet) || 897. #endif 898. (obj->known == otmp->known && 899. (obj->olet == WEAPON_SYM && obj->otyp < BOOMERANG)))) { 900. otmp->quan += obj->quan; 901. otmp->owt += obj->owt; 902. if(lose) freeobj(obj); 903. obfree(obj,otmp); /* free(obj), bill->otmp */ 904. return(1); 905. } else return(0); 906. } 907. 908. /* 909. * Gold is no longer displayed; in fact, when you have a lot of money, 910. * it may take a while before you have counted it all. 911. * [Bug: d$ and pickup still tell you how much it was.] 912. */ 913. extern int (*occupation)(); 914. extern char *occtxt; 915. static long goldcounted; 916. 917. countgold(){ 918. if((goldcounted += 100*(u.ulevel + 1)) >= u.ugold) { 919. long eps = 0; 920. if(!rn2(2)) eps = rnd((int) (u.ugold/100 + 1)); 921. pline("You probably have about %ld gold pieces.", 922. u.ugold + eps); 923. return(0); /* done */ 924. } 925. return(1); /* continue */ 926. } 927. 928. doprgold(){ 929. if(!u.ugold) 930. pline("You do not carry any gold."); 931. else if(u.ugold <= 500) 932. pline("You are carrying %ld gold piece%s.", u.ugold, plur(u.ugold)); 933. else { 934. pline("You sit down in order to count your gold pieces."); 935. goldcounted = 500; 936. occupation = countgold; 937. occtxt = "counting your gold"; 938. } 939. return(1); 940. } 941. 942. /* --- end of gold counting section --- */ 943. 944. doprwep(){ 945. if(!uwep) pline("You are empty handed."); 946. else prinv(uwep); 947. return(0); 948. } 949. 950. doprarm(){ 951. #ifdef SHIRT 952. if(!uarm && !uarmg && !uarms && !uarmh && !uarmu) 953. #else 954. if(!uarm && !uarmg && !uarms && !uarmh) 955. #endif 956. pline("You are not wearing any armor."); 957. else { 958. #ifdef SHIRT 959. char lets[7]; 960. #else 961. char lets[6]; 962. #endif 963. register int ct = 0; 964. 965. #ifdef SHIRT 966. if(uarmu) lets[ct++] = obj_to_let(uarmu); 967. #endif 968. if(uarm) lets[ct++] = obj_to_let(uarm); 969. if(uarm2) lets[ct++] = obj_to_let(uarm2); 970. if(uarmh) lets[ct++] = obj_to_let(uarmh); 971. if(uarms) lets[ct++] = obj_to_let(uarms); 972. if(uarmg) lets[ct++] = obj_to_let(uarmg); 973. lets[ct] = 0; 974. doinv(lets); 975. } 976. return(0); 977. } 978. 979. doprring(){ 980. if(!uleft && !uright) 981. pline("You are not wearing any rings."); 982. else { 983. char lets[3]; 984. register int ct = 0; 985. 986. if(uleft) lets[ct++] = obj_to_let(uleft); 987. if(uright) lets[ct++] = obj_to_let(uright); 988. lets[ct] = 0; 989. doinv(lets); 990. } 991. return(0); 992. } 993. 994. digit(c) char c; { 995. return(c >= '0' && c <= '9'); 996. } 997. 998. /* 999. * useupf(obj) 1000. * uses up an object that's on the floor 1001. */ 1002. useupf(obj) 1003. register struct obj *obj; 1004. { 1005. if(obj->quan > 1) { 1006. obj->quan--; 1007. obj->owt = weight(obj); 1008. } else delobj(obj); 1009. } 1010. 1011. #ifdef SORTING 1012. /* 1013. * Convert from a symbol to a string for printing object classes 1014. * 1015. * Names from objects.h 1016. * char obj_symbols[] = { 1017. * ILLOBJ_SYM, AMULET_SYM, FOOD_SYM, WEAPON_SYM, TOOL_SYM, 1018. * BALL_SYM, CHAIN_SYM, ROCK_SYM, ARMOR_SYM, POTION_SYM, SCROLL_SYM, 1019. * WAND_SYM, [SPBOOK_SYM], RING_SYM, GEM_SYM, 0 }; 1020. */ 1021. #define Sprintf (void) sprintf 1022. 1023. extern char obj_symbols[]; 1024. static char *names[] = {"Illegal objects", "Amulets", "Comestibles", "Weapons", 1025. "Tools", "Iron balls", "Chains", "Rocks", "Armor", 1026. "Potions", "Scrolls", "Wands", 1027. #ifdef SPELLS 1028. "Spellbooks", 1029. #endif 1030. "Rings", "Gems"}; 1031. char * 1032. let_to_name(let) 1033. char let; 1034. { 1035. char *pos = index(obj_symbols, let); 1036. extern char *HI, *HE; 1037. /* arbitrary buffer size by Tom May (tom@uw-warp) */ 1038. static char *buf = NULL; 1039. 1040. if (buf == NULL) 1041. buf = (char *) alloc ((unsigned)(strlen(HI)+strlen(HE)+15+1)); 1042. 1043. if (pos == NULL) pos = obj_symbols; 1044. if (HI && HE) 1045. Sprintf(buf, "%s%s%s", HI, names[pos - obj_symbols], HE); 1046. else 1047. Sprintf(buf, "%s", names[pos - obj_symbols]); 1048. return (buf); 1049. } 1050. #endif /* SORTING /**/ 1051. 1052. reassign () 1053. { 1054. register int i; 1055. register struct obj *obj; 1056. 1057. for(obj = invent, i = 0; obj; obj = obj->nobj, i++) 1058. obj->invlet = (i < 26) ? ('a'+i) : ('A'+i-26); 1059. lastinvnr = i; 1060. }