abstract
| - Below is the full text to invent.c from the source code of NetHack 2.3e. To link to a particular line, write [[NetHack 2.3e/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 2.3 88/01/21 2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3. 4. #include 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. }
|