About: Source:NetHack 3.0.0/invent.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 invent.c from the source code of NetHack 3.0.0. To link to a particular line, write [[NetHack 3.0.0/invent.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 3.0.0/invent.c
rdfs:comment
  • Below is the full text to invent.c from the source code of NetHack 3.0.0. To link to a particular line, write [[NetHack 3.0.0/invent.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 invent.c from the source code of NetHack 3.0.0. To link to a particular line, write [[NetHack 3.0.0/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 3.0 88/10/22 2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3. /* NetHack may be freely redistributed. See license for details. */ 4. 5. #include "hack.h" 6. 7. #ifdef WORM 8. #include "lev.h" 9. #include "wseg.h" 10. #endif 11. 12. #define NOINVSYM '#' 13. 14. static boolean mergable(); 15. 16. int lastinvnr = 51; /* 0 ... 51 */ 17. static char *xprname(); 18. 19. char inv_order[] = { 20. AMULET_SYM, WEAPON_SYM, ARMOR_SYM, FOOD_SYM, SCROLL_SYM, 21. #ifdef SPELLS 22. SPBOOK_SYM, 23. #endif 24. POTION_SYM, RING_SYM, WAND_SYM, TOOL_SYM, GEM_SYM, 25. ROCK_SYM, BALL_SYM, CHAIN_SYM, 0 }; 26. 27. static void 28. assigninvlet(otmp) 29. register struct obj *otmp; 30. { 31. boolean inuse[52]; 32. register int i; 33. register struct obj *obj; 34. 35. for(i = 0; i < 52; i++) inuse[i] = FALSE; 36. for(obj = invent; obj; obj = obj->nobj) if(obj != otmp) { 37. i = obj->invlet; 38. if('a' <= i && i <= 'z') inuse[i - 'a'] = TRUE; else 39. if('A' <= i && i <= 'Z') inuse[i - 'A' + 26] = TRUE; 40. if(i == otmp->invlet) otmp->invlet = 0; 41. } 42. if((i = otmp->invlet) && 43. (('a' <= i && i <= 'z') || ('A' <= i && i <= 'Z'))) 44. return; 45. for(i = lastinvnr+1; i != lastinvnr; i++) { 46. if(i == 52) { i = -1; continue; } 47. if(!inuse[i]) break; 48. } 49. otmp->invlet = (inuse[i] ? NOINVSYM : 50. (i < 26) ? ('a'+i) : ('A'+i-26)); 51. lastinvnr = i; 52. } 53. 54. /* merge obj with otmp and delete obj if types agree */ 55. static int 56. merged(otmp, obj, lose) 57. register struct obj *otmp, *obj; 58. register int lose; 59. { 60. if(mergable(otmp, obj)) { 61. /* Approximate age: we do it this way because if we were to 62. * do it "accurately" (merge only when ages are identical) 63. * we'd wind up never merging any corpses. 64. * otmp->age = otmp->age*(1-proportion) + obj->age*proportion; 65. */ 66. otmp->age = ((otmp->age*otmp->quan) + (obj->age*obj->quan)) 67. / (otmp->quan + obj->quan); 68. otmp->quan += obj->quan; 69. otmp->owt += obj->owt; 70. if(lose) freeobj(obj); 71. obfree(obj,otmp); /* free(obj), bill->otmp */ 72. return(1); 73. } else return(0); 74. } 75. 76. struct obj * 77. addinv(obj) 78. register struct obj *obj; 79. { 80. register struct obj *otmp; 81. 82. if (obj->otyp == AMULET_OF_YENDOR && !obj->spe) { 83. if (u.uhave_amulet) impossible ("already have amulet?"); 84. u.uhave_amulet = 1; 85. } 86. /* merge or attach to end of chain */ 87. if(!invent) { 88. invent = obj; 89. otmp = 0; 90. } else 91. for(otmp = invent; /* otmp */; otmp = otmp->nobj) { 92. if(merged(otmp, obj, 0)) { 93. obj = otmp; 94. goto added; 95. } 96. if(!otmp->nobj) { 97. otmp->nobj = obj; 98. break; 99. } 100. } 101. obj->nobj = 0; 102. 103. if(flags.invlet_constant) { 104. assigninvlet(obj); 105. /* 106. * The ordering of the chain is nowhere significant 107. * so in case you prefer some other order than the 108. * historical one, change the code below. 109. */ 110. if(otmp) { /* find proper place in chain */ 111. otmp->nobj = 0; 112. if((invent->invlet ^ 040) > (obj->invlet ^ 040)) { 113. obj->nobj = invent; 114. invent = obj; 115. } else 116. for(otmp = invent; ; otmp = otmp->nobj) { 117. if(!otmp->nobj || 118. (otmp->nobj->invlet ^ 040) > (obj->invlet ^ 040)){ 119. obj->nobj = otmp->nobj; 120. otmp->nobj = obj; 121. break; 122. } 123. } 124. } 125. } 126. 127. added: 128. if (obj->otyp == LUCKSTONE) { 129. /* new luckstone must be in inventory by this point 130. * for correct calculation */ 131. if (stone_luck(TRUE) >= 0) u.moreluck = LUCKADD; 132. else u.moreluck = -LUCKADD; 133. flags.botl = 1; 134. } 135. return(obj); 136. } 137. 138. void 139. useup(obj) 140. register struct obj *obj; 141. { 142. if(obj->quan > 1){ 143. obj->quan--; 144. obj->owt = weight(obj); 145. } else { 146. setnotworn(obj); 147. freeinv(obj); 148. obfree(obj, (struct obj *) 0); 149. } 150. } 151. 152. void 153. freeinv(obj) 154. register struct obj *obj; 155. { 156. register struct obj *otmp; 157. 158. if(obj == invent) 159. invent = invent->nobj; 160. else { 161. for(otmp = invent; otmp->nobj != obj; otmp = otmp->nobj) 162. if(!otmp->nobj) panic("freeinv"); 163. otmp->nobj = obj->nobj; 164. } 165. if (obj->otyp == AMULET_OF_YENDOR && !obj->spe) { 166. if (!u.uhave_amulet) impossible ("don't have amulet?"); 167. u.uhave_amulet = 0; 168. } 169. if (obj->otyp == LOADSTONE) 170. curse(obj); 171. if (obj->otyp == LUCKSTONE) { 172. if (!carrying(LUCKSTONE)) u.moreluck = 0; 173. else if (stone_luck(TRUE) >= 0) u.moreluck = LUCKADD; 174. else u.moreluck = -LUCKADD; 175. flags.botl = 1; 176. } 177. } 178. 179. /* destroy object in fobj chain (if unpaid, it remains on the bill) */ 180. void 181. delobj(obj) 182. register struct obj *obj; 183. { 184. #ifdef WALKIES 185. if(obj->otyp == LEASH && obj->leashmon != 0) o_unleash(obj); 186. #endif 187. freeobj(obj); 188. unpobj(obj); 189. 190. /* if contained in something else, decrease the container weight */ 191. if(obj->cobj) dec_cwt(obj->cobj, obj); 192. 193. obfree(obj, (struct obj *) 0); 194. } 195. 196. /* unlink obj from chain starting with fobj */ 197. void 198. freeobj(obj) 199. register struct obj *obj; 200. { 201. register struct obj *otmp; 202. register int found = 0; 203. register struct rm *lev = &levl[obj->ox][obj->oy]; 204. 205. lev->omask = 0; 206. 207. if(obj == fobj) { 208. fobj = fobj->nobj; 209. found = 1; 210. } 211. for(otmp = fobj; otmp; otmp = otmp->nobj) { 212. if (otmp->nobj == obj) { 213. otmp->nobj = obj->nobj; 214. found = 1; 215. } 216. if (otmp->ox == obj->ox && otmp->oy == obj->oy) { 217. lev->omask = 1; 218. } 219. } 220. if (!found) panic("error in freeobj"); 221. #ifdef POLYSELF 222. if (!levl[u.ux][u.uy].omask && !levl[u.ux][u.uy].gmask) { 223. u.uundetected = 0; 224. if (!Invisible) pru(); 225. } 226. #endif 227. } 228. 229. /* Note: freegold throws away its argument! */ 230. void 231. freegold(gold) 232. register struct gold *gold; 233. { 234. register struct gold *gtmp; 235. 236. levl[gold->gx][gold->gy].gmask = 0; 237. 238. if(gold == fgold) fgold = gold->ngold; 239. else { 240. for(gtmp = fgold; gtmp->ngold != gold; gtmp = gtmp->ngold) 241. if(!gtmp) panic("error in freegold"); 242. gtmp->ngold = gold->ngold; 243. } 244. free((genericptr_t) gold); 245. #ifdef POLYSELF 246. if (!levl[u.ux][u.uy].omask && !levl[u.ux][u.uy].gmask) { 247. u.uundetected = 0; 248. if (!Invisible) pru(); 249. } 250. #endif 251. } 252. 253. struct monst * 254. m_at(x,y) 255. register int x, y; 256. { 257. register struct monst *mtmp; 258. #ifdef WORM 259. register struct wseg *wtmp; 260. m_atseg = 0; 261. #endif 262. 263. for(mtmp = fmon; mtmp; mtmp = mtmp->nmon){ 264. if(mtmp->mx == x && mtmp->my == y) 265. return(mtmp); 266. #ifdef WORM 267. if(mtmp->wormno){ 268. for(wtmp = wsegs[mtmp->wormno]; wtmp; wtmp = wtmp->nseg) 269. if(wtmp->wx == x && wtmp->wy == y){ 270. m_atseg = wtmp; 271. return(mtmp); 272. } 273. } 274. #endif 275. } 276. return((struct monst *)0); 277. } 278. 279. struct obj * 280. o_at(x,y) 281. register int x, y; 282. { 283. register struct obj *otmp; 284. 285. for(otmp = fobj; otmp; otmp = otmp->nobj) 286. if(otmp->ox == x && otmp->oy == y) return(otmp); 287. return((struct obj *)0); 288. } 289. 290. struct obj * 291. sobj_at(n,x,y) 292. register int n, x, y; 293. { 294. register struct obj *otmp; 295. 296. if(levl[x][y].omask) 297. for(otmp = fobj; otmp; otmp = otmp->nobj) 298. if(otmp->ox == x && otmp->oy == y && otmp->otyp == n) 299. return(otmp); 300. return((struct obj *)0); 301. } 302. 303. int 304. carried(obj) 305. register struct obj *obj; 306. { 307. register struct obj *otmp; 308. 309. for(otmp = invent; otmp; otmp = otmp->nobj) 310. if(otmp == obj) return(1); 311. return(0); 312. } 313. 314. struct obj * 315. carrying(type) 316. register int type; 317. { 318. register struct obj *otmp; 319. 320. for(otmp = invent; otmp; otmp = otmp->nobj) 321. if(otmp->otyp == type) 322. return(otmp); 323. return((struct obj *) 0); 324. } 325. 326. struct obj * 327. o_on(id, objchn) 328. unsigned int id; 329. register struct obj *objchn; 330. { 331. while(objchn) { 332. if(objchn->o_id == id) return(objchn); 333. objchn = objchn->nobj; 334. } 335. return((struct obj *) 0); 336. } 337. 338. struct gold * 339. g_at(x,y) 340. register int x, y; 341. { 342. register struct gold *gold = fgold; 343. while(gold) { 344. if(gold->gx == x && gold->gy == y) return(gold); 345. gold = gold->ngold; 346. } 347. return((struct gold *)0); 348. } 349. 350. /* make dummy object structure containing gold - for temporary use only */ 351. static 352. struct obj * 353. mkgoldobj(q) 354. register long q; 355. { 356. register struct obj *otmp; 357. 358. otmp = newobj(0); 359. /* should set o_id etc. but otmp will be freed soon */ 360. otmp->olet = GOLD_SYM; 361. u.ugold -= q; 362. OGOLD(otmp) = q; 363. flags.botl = 1; 364. return(otmp); 365. } 366. 367. /* 368. * getobj returns: 369. * struct obj *xxx: object to do something with. 370. * (struct obj *) 0 error return: no object. 371. * &zeroobj explicitly no object (as in w-). 372. */ 373. struct obj * 374. getobj(let,word) 375. register char *let,*word; 376. { 377. register struct obj *otmp; 378. register char ilet,ilet1,ilet2; 379. char buf[BUFSZ]; 380. char lets[BUFSZ]; 381. register int foo = 0, foo2; 382. register char *bp = buf; 383. xchar allowcnt = 0; /* 0, 1 or 2 */ 384. boolean allowgold = FALSE, usegold = FALSE; 385. /* usegold is needed so that they are given a different message 386. * if gold is prohibited because it's inappropriate, or because 387. * it's appropriate if only they had any. 388. */ 389. boolean allowall = FALSE; 390. boolean allownone = FALSE; 391. xchar foox = 0; 392. long cnt; 393. 394. if(*let == '0') let++, allowcnt = 1; 395. if(*let == GOLD_SYM) let++, 396. usegold = TRUE, allowgold = (u.ugold ? TRUE : FALSE); 397. if(*let == '#') let++, allowall = TRUE; 398. if(*let == '-') let++, allownone = TRUE; 399. if(allownone) *bp++ = '-'; 400. if(allowgold) *bp++ = GOLD_SYM; 401. if(bp > buf && bp[-1] == '-') *bp++ = ' '; 402. 403. ilet = 'a'; 404. for(otmp = invent; otmp; otmp = otmp->nobj){ 405. if(!*let || index(let, otmp->olet)) { 406. bp[foo++] = flags.invlet_constant ? otmp->invlet : ilet; 407. 408. /* ugly check: remove inappropriate things */ 409. if((!strcmp(word, "take off") && 410. (!(otmp->owornmask & (W_ARMOR | W_RING | W_AMUL | W_TOOL)) 411. || (otmp==uarm && uarmc) 412. #ifdef SHIRT 413. || (otmp==uarmu && (uarm || uarmc)) 414. #endif 415. )) 416. || (!strcmp(word, "wear") && 417. (otmp->owornmask & (W_ARMOR | W_RING | W_AMUL | W_TOOL))) 418. /* already worn */ 419. || (!strcmp(word, "wield") && 420. (otmp->owornmask & W_WEP)) 421. ) { 422. foo--; 423. foox++; 424. } 425. 426. /* Second ugly check; unlike the first it won't trigger an 427. * "else" in "you don't have anything else to ___". 428. */ 429. if ((!strcmp(word, "wear") && 430. (otmp->olet == TOOL_SYM && otmp->otyp != BLINDFOLD)) 431. || (!strcmp(word, "can") && 432. (otmp->otyp != CORPSE)) 433. || (!strcmp(word, "write with") && 434. (otmp->olet == TOOL_SYM && otmp->otyp != MAGIC_MARKER)) 435. || (!strcmp(word, "rub") && 436. (otmp->olet == TOOL_SYM && 437. otmp->otyp != LAMP && otmp->otyp != MAGIC_LAMP)) 438. ) 439. foo--; 440. } 441. if(ilet == 'z') ilet = 'A'; else ilet++; 442. } 443. bp[foo] = 0; 444. if(foo == 0 && bp > buf && bp[-1] == ' ') *--bp = 0; 445. Strcpy(lets, bp); /* necessary since we destroy buf */ 446. if(foo > 5) { /* compactify string */ 447. foo = foo2 = 1; 448. ilet2 = bp[0]; 449. ilet1 = bp[1]; 450. while(ilet = bp[++foo2] = bp[++foo]){ 451. if(ilet == ilet1+1){ 452. if(ilet1 == ilet2+1) 453. bp[foo2 - 1] = ilet1 = '-'; 454. else if(ilet2 == '-') { 455. bp[--foo2] = ++ilet1; 456. continue; 457. } 458. } 459. ilet2 = ilet1; 460. ilet1 = ilet; 461. } 462. } 463. if(!foo && !allowall && !allowgold && !allownone) { 464. You("don't have anything %sto %s.", 465. foox ? "else " : "", word); 466. return((struct obj *)0); 467. } 468. for(;;) { 469. if(!buf[0]) { 470. #ifdef REDO 471. if(!in_doagain) 472. #endif 473. pline("What do you want to %s? [*] ", word); 474. } else { 475. #ifdef REDO 476. if(!in_doagain) 477. #endif 478. pline("What do you want to %s? [%s or ?*] ", 479. word, buf); 480. } 481. cnt = 0; 482. ilet = readchar(); 483. while(digit(ilet) && allowcnt) { 484. #ifdef REDO 485. if (ilet != '?' && ilet != '*') savech(ilet); 486. #endif 487. cnt = 10*cnt + (ilet - '0'); 488. allowcnt = 2; /* signal presence of cnt */ 489. ilet = readchar(); 490. } 491. if(digit(ilet)) { 492. pline("No count allowed with this command."); 493. continue; 494. } 495. if(index(quitchars,ilet)) { 496. if(flags.verbose) 497. pline("Never mind."); 498. return((struct obj *)0); 499. } 500. if(ilet == '-') { 501. return(allownone ? &zeroobj : (struct obj *) 0); 502. } 503. if(ilet == GOLD_SYM) { 504. if(!usegold){ 505. You("cannot %s gold.", word); 506. return(struct obj *)0; 507. } else if (!allowgold) { 508. You("are not carrying any gold."); 509. return(struct obj *)0; 510. } 511. if(!(allowcnt == 2 && cnt < u.ugold)) 512. cnt = u.ugold; 513. return(mkgoldobj(cnt)); 514. } 515. if(allowcnt == 2 && !strcmp(word,"throw")) { 516. /* permit counts for throwing gold, but don't accept 517. * counts for other things since the throw code will 518. * split off a single item anyway */ 519. allowcnt = 1; 520. if(cnt != 1) { 521. pline("You can only throw one item at a time."); 522. continue; 523. } 524. } 525. if(ilet == '?') { 526. doinv(lets); 527. if(!(ilet = morc)) continue; 528. /* he typed a letter (not a space) to more() */ 529. } else if(ilet == '*') { 530. doinv(NULL); 531. if(!(ilet = morc)) continue; 532. /* ... */ 533. } 534. #ifdef REDO 535. if (ilet != '?' && ilet != '*') savech(ilet); 536. #endif 537. if(flags.invlet_constant) { 538. for(otmp = invent; otmp; otmp = otmp->nobj) 539. if(otmp->invlet == ilet) break; 540. } else { 541. if(ilet >= 'A' && ilet <= 'Z') ilet += 'z'-'A'+1; 542. ilet -= 'a'; 543. for(otmp = invent; otmp && ilet; 544. ilet--, otmp = otmp->nobj) ; 545. } 546. if(!otmp) { 547. You("don't have that object."); 548. continue; 549. } 550. if(cnt < 0 || otmp->quan < cnt) { 551. You("don't have that many! You have only %u." 552. , otmp->quan); 553. continue; 554. } 555. break; 556. } 557. if(!allowall && let && !index(let,otmp->olet)) { 558. pline("That is a silly thing to %s.",word); 559. return((struct obj *)0); 560. } 561. if(allowcnt == 2) { /* cnt given */ 562. if(cnt == 0) return (struct obj *)0; 563. if(cnt != otmp->quan) { 564. register struct obj *obj; 565. #ifdef LINT /*splitobj for (long )cnt > 30000 && sizeof(int) == 2*/ 566. obj = (struct obj *)0; 567. #else 568. if (sizeof(int) == 2) 569. obj = splitobj(otmp, 570. (int )(cnt >30000 ? 30000 : cnt)); 571. else 572. obj = splitobj(otmp, (int) cnt); 573. #endif 574. if(otmp == uwep) setuwep(obj); 575. } 576. } 577. return(otmp); 578. } 579. 580. static int 581. ckunpaid(otmp) 582. register struct obj *otmp; 583. { 584. return((int)(otmp->unpaid)); 585. } 586. 587. static boolean 588. wearing_armor() { 589. return(uarm || uarmc || uarmf || uarmg || uarmh || uarms 590. #ifdef SHIRT 591. || uarmu 592. #endif 593. ); 594. } 595. 596. static boolean 597. is_worn(otmp) 598. register struct obj *otmp; 599. { 600. return(!!(otmp->owornmask & (W_ARMOR | W_RING | W_AMUL | W_TOOL | W_WEP))); 601. } 602. 603. static const char removeables[] = 604. { ARMOR_SYM, WEAPON_SYM, RING_SYM, AMULET_SYM, TOOL_SYM, ' ', 0 }; 605. 606. /* interactive version of getobj - used for Drop, Identify and */ 607. /* Takeoff (A). Return the number of times fn was called successfully */ 608. int 609. ggetobj(word, fn, mx) 610. register char *word; 611. register int (*fn)(), mx; 612. { 613. char buf[BUFSZ]; 614. register char *ip; 615. register char sym; 616. register int oletct = 0, iletct = 0; 617. register boolean allflag = FALSE; 618. char olets[20], ilets[20]; 619. int (*ckfn)() = (int (*)()) 0; 620. xchar allowgold = (u.ugold && !strcmp(word, "drop")) ? 1 : 0; /* BAH */ 621. register boolean takeoff = !strcmp(word, "take off"); 622. 623. if(takeoff && !wearing_armor() && !uwep && !uamul && 624. !uleft && !uright && !ublindf) { 625. You("are not wearing anything."); 626. return(0); 627. } 628. if(!invent && !allowgold){ 629. You("have nothing to %s.", word); 630. return(0); 631. } else { 632. register struct obj *otmp = invent; 633. register int uflg = 0; 634. 635. if(allowgold) ilets[iletct++] = GOLD_SYM; 636. ilets[iletct] = 0; 637. while(otmp) { 638. if(!index(ilets, otmp->olet)){ 639. if(!takeoff || is_worn(otmp)) 640. ilets[iletct++] = otmp->olet; 641. ilets[iletct] = 0; 642. } 643. if(otmp->unpaid) uflg = 1; 644. otmp = otmp->nobj; 645. } 646. ilets[iletct++] = ' '; 647. if(uflg && !takeoff) ilets[iletct++] = 'u'; 648. if(invent && !takeoff) ilets[iletct++] = 'a'; 649. ilets[iletct] = 0; 650. } 651. pline("What kinds of thing do you want to %s? [%s] ", 652. word, ilets); 653. getlin(buf); 654. if(buf[0] == '\033') { 655. clrlin(); 656. return(0); 657. } 658. ip = buf; 659. olets[0] = 0; 660. while(sym = *ip++){ 661. if(sym == ' ') continue; 662. if(takeoff) { 663. if(!index(removeables,sym)) { 664. pline("Not applicable."); 665. return(0); 666. } else if(sym == ARMOR_SYM && !wearing_armor()) { 667. You("are not wearing any armor."); 668. return(0); 669. } else if(sym == WEAPON_SYM && !uwep) { 670. You("are not wielding anything."); 671. return(0); 672. } else if(sym == RING_SYM && !uright && !uleft) { 673. You("are not wearing rings."); 674. return(0); 675. } else if(sym == AMULET_SYM && !uamul) { 676. You("are not wearing an amulet."); 677. return(0); 678. } else if(sym == TOOL_SYM && !ublindf) { 679. You("are not wearing a blindfold."); 680. return(0); 681. } 682. } 683. if(sym == GOLD_SYM) { 684. if(allowgold == 1) 685. (*fn)(mkgoldobj(u.ugold)); 686. else if(!u.ugold) 687. You("have no gold."); 688. allowgold = 2; 689. } else if(sym == 'a' || sym == 'A') 690. allflag = TRUE; 691. else if(sym == 'u' || sym == 'U') 692. ckfn = ckunpaid; 693. else if(index(inv_order, sym)) { 694. if(!index(olets, sym)) { 695. olets[oletct++] = sym; 696. olets[oletct] = 0; 697. } 698. } else You("don't have any %c's.", sym); 699. } 700. if(allowgold == 2 && !oletct) 701. return(1); /* he dropped gold (or at least tried to) */ 702. else 703. return(askchain(invent, TRUE, olets, allflag, fn, ckfn, mx, word)); 704. } 705. 706. /* 707. * Walk through the chain starting at objchn and ask for all objects 708. * with olet in olets (if nonNULL) and satisfying ckfn (if nonNULL) 709. * whether the action in question (i.e., fn) has to be performed. 710. * If allflag then no questions are asked. Max gives the max nr of 711. * objects to be treated. Return the number of objects treated. 712. * If ininv is TRUE, the objects are in the player's inventory. 713. */ 714. int 715. askchain(objchn, ininv, olets, allflag, fn, ckfn, mx, word) 716. register struct obj *objchn; 717. register int ininv, allflag, mx; 718. register char *olets, *word; 719. register int (*fn)(), (*ckfn)(); 720. { 721. register struct obj *otmp, *otmp2; 722. register char sym, ilet; 723. register int cnt = 0, dud = 0; 724. register boolean takeoff, nodot; 725. 726. takeoff = !strcmp(word, "take off"); 727. nodot = (!strcmp(word, "nodot") || !strcmp(word, "drop") || 728. !strcmp(word, "identify") || takeoff); 729. /* changes so the askchain is interrogated in the order specified. 730. * For example, if a person specifies =/ then first all rings will be 731. * asked about followed by all wands -dgk 732. */ 733. nextclass: 734. ilet = 'a'-1; 735. for(otmp = (ininv ? invent : objchn); otmp; otmp = otmp2){ 736. if(ilet == 'z') ilet = 'A'; else ilet++; 737. otmp2 = otmp->nobj; 738. if (olets && *olets && otmp->olet != *olets) continue; 739. if(takeoff && !is_worn(otmp)) continue; 740. if(ckfn && !(*ckfn)(otmp)) continue; 741. if(!allflag) { 742. if(ininv) { 743. if (nodot) 744. pline(xprname(otmp, ilet, FALSE)); 745. else pline(xprname(otmp, ilet, TRUE)); 746. } 747. else 748. pline(doname(otmp)); 749. addtopl("? "); 750. sym = nyaq(); 751. } 752. else sym = 'y'; 753. 754. switch(sym){ 755. case 'a': 756. allflag = 1; 757. case 'y': 758. cnt += (*fn)(otmp); 759. if(--mx == 0) goto ret; 760. case 'n': 761. if(nodot) dud++; 762. default: 763. break; 764. case 'q': 765. goto ret; 766. } 767. } 768. if (olets && *olets && *++olets) 769. goto nextclass; 770. if(!takeoff && (dud || cnt)) pline("That was all."); 771. else if(!dud && !cnt) pline("No applicable objects."); 772. ret: 773. return(cnt); 774. } 775. 776. static char 777. obj_to_let(obj) /* should of course only be called for things in invent */ 778. register struct obj *obj; 779. { 780. register struct obj *otmp; 781. register char ilet; 782. 783. if(flags.invlet_constant) 784. return(obj->invlet); 785. ilet = 'a'; 786. for(otmp = invent; otmp && otmp != obj; otmp = otmp->nobj) 787. if(++ilet > 'z') ilet = 'A'; 788. return(otmp ? ilet : NOINVSYM); 789. } 790. 791. void 792. prinv(obj) 793. register struct obj *obj; 794. { 795. pline(xprname(obj, obj_to_let(obj), TRUE)); 796. } 797. 798. static char * 799. xprname(obj,let,dot) 800. register struct obj *obj; 801. register char let; 802. register boolean dot; 803. { 804. #ifdef LINT /* handle static char li[BUFSZ]; */ 805. char li[BUFSZ]; 806. #else 807. static char li[BUFSZ]; 808. #endif 809. 810. Sprintf(li, "%c - %s", 811. (flags.invlet_constant ? obj->invlet : let), 812. doname(obj)); 813. if(dot) Sprintf(eos(li),"."); 814. return(li); 815. } 816. 817. int 818. ddoinv() 819. { 820. doinv(NULL); 821. return 0; 822. } 823. 824. /* called with 0 or "": all objects in inventory */ 825. /* otherwise: all objects with (serial) letter in lets */ 826. void 827. doinv(lets) 828. register char *lets; 829. { 830. register struct obj *otmp; 831. register char ilet; 832. int ct = 0; 833. char any[BUFSZ]; 834. char *invlet = inv_order; 835. int classcount = 0; 836. 837. morc = 0; /* just to be sure */ 838. 839. if(!invent){ 840. pline("Not carrying anything."); 841. return; 842. } 843. if (lets != NULL) { 844. for(ct=0; lets[ct]; ct++) { 845. if (ct >= 52) { 846. impossible("bad lets contents"); 847. break; 848. } 849. } 850. if (ct==1) { 851. ilet = 'a'; 852. for(otmp = invent; otmp; otmp = otmp->nobj) { 853. if(flags.invlet_constant) ilet = otmp->invlet; 854. 855. if (ilet == lets[0]) 856. pline(xprname(otmp, lets[0], TRUE)); 857. 858. if(!flags.invlet_constant) 859. if(++ilet > 'z') ilet = 'A'; 860. } 861. return; 862. } 863. } 864. ct = 0; 865. 866. cornline(0, NULL); 867. nextclass: 868. classcount = 0; 869. ilet = 'a'; 870. for(otmp = invent; otmp; otmp = otmp->nobj) { 871. if(flags.invlet_constant) ilet = otmp->invlet; 872. if(!lets || !*lets || index(lets, ilet)) { 873. if (!flags.sortpack || otmp->olet == *invlet) { 874. if (flags.sortpack && !classcount) { 875. cornline(1, let_to_name(*invlet)); 876. classcount++; 877. } 878. cornline(1, xprname(otmp, ilet, TRUE)); 879. any[ct++] = ilet; 880. } 881. } 882. if(!flags.invlet_constant) if(++ilet > 'z') ilet = 'A'; 883. } 884. if (flags.sortpack && *++invlet) goto nextclass; 885. any[ct] = 0; 886. cornline(2, any); 887. } 888. 889. int 890. dotypeinv() /* free after Robert Viduya */ 891. /* Changed to one type only, so he doesn't have to type cr */ 892. { 893. char c, ilet; 894. char stuff[BUFSZ]; 895. register int stct; 896. register struct obj *otmp; 897. boolean billx = inshop() && doinvbill(0); 898. boolean unpd = FALSE; 899. 900. if (!invent && !u.ugold && !billx) { 901. You("aren't carrying anything."); 902. return 0; 903. } 904. 905. stct = 0; 906. if(u.ugold) stuff[stct++] = GOLD_SYM; 907. stuff[stct] = 0; 908. for(otmp = invent; otmp; otmp = otmp->nobj) { 909. if (!index (stuff, otmp->olet)) { 910. stuff[stct++] = otmp->olet; 911. stuff[stct] = 0; 912. } 913. if(otmp->unpaid) 914. unpd = TRUE; 915. } 916. if(unpd) stuff[stct++] = 'u'; 917. if(billx) stuff[stct++] = 'x'; 918. stuff[stct] = 0; 919. 920. if(stct > 1) { 921. #ifdef REDO 922. if (!in_doagain) 923. #endif 924. pline ("What type of object do you want an inventory of? [%s] ", 925. stuff); 926. c = readchar(); 927. #ifdef REDO 928. savech(c); 929. #endif 930. if(index(quitchars,c)) { 931. clrlin(); 932. return 0; 933. } 934. } else 935. c = stuff[0]; 936. 937. if(c == GOLD_SYM) 938. return(doprgold()); 939. 940. if(c == 'x' || c == 'X') { 941. if(billx) 942. (void) doinvbill(1); 943. else 944. pline("No used-up objects on the shopping bill."); 945. return(0); 946. } 947. 948. if((c == 'u' || c == 'U') && !unpd) { 949. You("are not carrying any unpaid objects."); 950. return(0); 951. } 952. 953. stct = 0; 954. ilet = 'a'; 955. for (otmp = invent; otmp; otmp = otmp -> nobj) { 956. if(flags.invlet_constant) ilet = otmp->invlet; 957. if (c == otmp -> olet || (c == 'u' && otmp -> unpaid)) 958. stuff[stct++] = ilet; 959. if(!flags.invlet_constant) if(++ilet > 'z') ilet = 'A'; 960. } 961. stuff[stct] = '\0'; 962. if(stct == 0) 963. You("have no such objects."); 964. else 965. doinv (stuff); 966. 967. return(0); 968. } 969. 970. /* look at what is here */ 971. int 972. dolook() { 973. register struct obj *otmp, *otmp0; 974. register struct gold *gold; 975. char *verb = Blind ? "feel" : "see"; 976. int ct = 0; 977. int fd = 0; 978. 979. read_engr_at(u.ux, u.uy); /* Eric Backus */ 980. if(!u.uswallow) { 981. otmp0 = o_at(u.ux, u.uy); 982. gold = g_at(u.ux, u.uy); 983. } else { 984. You("%s no objects here.", verb); 985. return(!!Blind); 986. } 987. 988. if(IS_DOOR(levl[u.ux][u.uy].typ)) { 989. fd++; 990. switch(levl[u.ux][u.uy].doormask) { 991. case D_NODOOR: 992. pline("There is a doorway here."); break; 993. case D_ISOPEN: 994. pline("There is an open door here."); break; 995. case D_BROKEN: 996. pline("There is a broken door here."); break; 997. default: 998. pline("There is a closed door here."); 999. } 1000. } 1001. /* added by GAN 10/30/86 */ 1002. #ifdef FOUNTAINS 1003. if(IS_FOUNTAIN(levl[u.ux][u.uy].typ)) { 1004. fd++; 1005. pline("There is a fountain here."); 1006. } 1007. #endif 1008. #ifdef THRONES 1009. if(IS_THRONE(levl[u.ux][u.uy].typ)) { 1010. fd++; 1011. pline("There is an opulent throne here."); 1012. } 1013. #endif 1014. #ifdef SINKS 1015. if(IS_SINK(levl[u.ux][u.uy].typ)) { 1016. fd++; 1017. pline("There is a kitchen sink here."); 1018. } 1019. #endif 1020. #ifdef ALTARS 1021. if(IS_ALTAR(levl[u.ux][u.uy].typ)) { 1022. char *al; 1023. 1024. fd++; 1025. switch (levl[u.ux][u.uy].altarmask & ~A_SHRINE) { 1026. case 0: al = "chaotic"; break; 1027. case 1: al = "neutral"; break; 1028. default: al = "lawful"; break; 1029. } 1030. pline("There is an altar to %s here (%s).", a_gname(), al); 1031. } 1032. #endif 1033. 1034. if(u.ux == xupstair && u.uy == yupstair) { 1035. fd++; 1036. pline("There is a stairway up here."); 1037. } 1038. if(u.ux == xdnstair && u.uy == ydnstair) { 1039. fd++; 1040. pline("There is a stairway down here."); 1041. } 1042. #ifdef STRONGHOLD 1043. if(u.ux == xupladder && u.uy == yupladder) { 1044. fd++; 1045. pline("There is a ladder up here."); 1046. } 1047. if(u.ux == xdnladder && u.uy == ydnladder) { 1048. fd++; 1049. pline("There is a ladder down here."); 1050. } 1051. if (levl[u.ux][u.uy].typ == DRAWBRIDGE_DOWN) { 1052. fd++; 1053. pline("There is a lowered drawbridge here."); 1054. } 1055. #endif /* STRONGHOLD /**/ 1056. 1057. if(Blind) { 1058. You("try to feel what is lying here on the floor."); 1059. if(Levitation) { 1060. pline("But you can't reach it!"); 1061. return(0); 1062. } 1063. } 1064. 1065. if(!otmp0 && !gold) { 1066. if(Blind || !fd) 1067. You("%s no objects here.", verb); 1068. return(!!Blind); 1069. } 1070. 1071. cornline(0, "Things that are here:"); 1072. for(otmp = otmp0; otmp; otmp = otmp->nobj) { 1073. if(otmp->ox == u.ux && otmp->oy == u.uy) { 1074. ct++; 1075. cornline(1, doname(otmp)); 1076. 1077. if(Blind && !uarmg && 1078. #ifdef POLYSELF 1079. !resists_ston(uasmon) && 1080. #endif 1081. (otmp->otyp == CORPSE && otmp->corpsenm == PM_COCKATRICE)) { 1082. pline("Touching the dead cockatrice is a fatal mistake..."); 1083. You("turn to stone..."); 1084. killer = "dead cockatrice"; 1085. done("stoned"); 1086. } 1087. } 1088. } 1089. 1090. if(gold) { 1091. char gbuf[30]; 1092. 1093. Sprintf(gbuf, "%ld gold piece%s", 1094. gold->amount, plur(gold->amount)); 1095. if(!ct++) 1096. You("%s here %s.", verb, gbuf); 1097. else 1098. cornline(1, gbuf); 1099. } 1100. 1101. if(ct == 1 && !gold) { 1102. You("%s here %s.", verb, doname(otmp0)); 1103. cornline(3, NULL); 1104. } 1105. if(ct > 1) 1106. cornline(2, NULL); 1107. return(!!Blind); 1108. } 1109. 1110. void 1111. stackobj(obj) 1112. register struct obj *obj; 1113. { 1114. register struct obj *otmp = fobj; 1115. for(otmp = fobj; otmp; otmp = otmp->nobj) if(otmp != obj) 1116. if(otmp->ox == obj->ox && otmp->oy == obj->oy && 1117. merged(obj,otmp,1)) 1118. break; 1119. return; 1120. } 1121. 1122. static boolean 1123. mergable(otmp, obj) /* returns TRUE if obj & otmp can be merged */ 1124. register struct obj *otmp, *obj; 1125. { 1126. if(obj->otyp != otmp->otyp || obj->unpaid != otmp->unpaid || 1127. obj->spe != otmp->spe || obj->dknown != otmp->dknown || 1128. (obj->bknown != otmp->bknown && pl_character[0] != 'P') || 1129. obj->cursed != otmp->cursed || obj->blessed != otmp->blessed || 1130. obj->no_charge != otmp->no_charge || 1131. obj->otrapped != otmp->otrapped) 1132. return(FALSE); 1133. 1134. else if((obj->olet==WEAPON_SYM || obj->olet==ARMOR_SYM) && 1135. obj->rustfree != otmp->rustfree) return FALSE; 1136. 1137. else if(obj->otyp == CORPSE || obj->otyp == EGG || obj->otyp == TIN) 1138. return( (obj->corpsenm == otmp->corpsenm) && 1139. (!ONAME(obj) || !strcmp(ONAME(obj), ONAME(otmp))) ); 1140. 1141. else if(obj->known == otmp->known) { 1142. return(objects[obj->otyp].oc_merge); 1143. } else return(FALSE); 1144. } 1145. 1146. int 1147. doprgold(){ 1148. if(!u.ugold) 1149. You("do not carry any gold."); 1150. else 1151. You("are carrying %ld gold piece%s.", u.ugold, plur(u.ugold)); 1152. return 0; 1153. } 1154. 1155. int 1156. doprwep() 1157. { 1158. if(!uwep) You("are empty %s.", body_part(HANDED)); 1159. else prinv(uwep); 1160. return 0; 1161. } 1162. 1163. int 1164. doprarm(){ 1165. if(!wearing_armor()) 1166. You("are not wearing any armor."); 1167. else { 1168. #ifdef SHIRT 1169. char lets[8]; 1170. #else 1171. char lets[7]; 1172. #endif 1173. register int ct = 0; 1174. 1175. #ifdef SHIRT 1176. if(uarmu) lets[ct++] = obj_to_let(uarmu); 1177. #endif 1178. if(uarm) lets[ct++] = obj_to_let(uarm); 1179. if(uarmc) lets[ct++] = obj_to_let(uarmc); 1180. if(uarmh) lets[ct++] = obj_to_let(uarmh); 1181. if(uarms) lets[ct++] = obj_to_let(uarms); 1182. if(uarmg) lets[ct++] = obj_to_let(uarmg); 1183. if(uarmf) lets[ct++] = obj_to_let(uarmf); 1184. lets[ct] = 0; 1185. doinv(lets); 1186. } 1187. return 0; 1188. } 1189. 1190. int 1191. doprring(){ 1192. if(!uleft && !uright) 1193. You("are not wearing any rings."); 1194. else { 1195. char lets[3]; 1196. register int ct = 0; 1197. 1198. if(uleft) lets[ct++] = obj_to_let(uleft); 1199. if(uright) lets[ct++] = obj_to_let(uright); 1200. lets[ct] = 0; 1201. doinv(lets); 1202. } 1203. return 0; 1204. } 1205. 1206. int 1207. dopramulet(){ 1208. if (!uamul) 1209. You("are not wearing an amulet."); 1210. else 1211. prinv(uamul); 1212. return 0; 1213. } 1214. 1215. int 1216. doprtool(){ 1217. register struct obj *otmp; 1218. register int ct=0; 1219. char lets[3]; /* Maximum: pick-axe, blindfold */ 1220. 1221. for(otmp = invent; otmp; otmp = otmp->nobj) { 1222. if (((otmp->owornmask & W_TOOL) && otmp->olet==TOOL_SYM) 1223. || (otmp==uwep && 1224. (otmp->otyp==PICK_AXE || otmp->otyp==TIN_OPENER))) 1225. lets[ct++] = obj_to_let(otmp); 1226. } 1227. lets[ct] = 0; 1228. if (!ct) You("are not using any tools."); 1229. else doinv(lets); 1230. return 0; 1231. } 1232. 1233. int 1234. digit(c) 1235. char c; 1236. { 1237. return(c >= '0' && c <= '9'); 1238. } 1239. 1240. /* 1241. * useupf(obj) 1242. * uses up an object that's on the floor 1243. */ 1244. void 1245. useupf(obj) 1246. register struct obj *obj; 1247. { 1248. if(obj->quan > 1) { 1249. obj->quan--; 1250. obj->owt = weight(obj); 1251. } else delobj(obj); 1252. } 1253. 1254. /* 1255. * Convert from a symbol to a string for printing object classes 1256. * 1257. * Names from objects.h 1258. * char obj_symbols[] = { 1259. * ILLOBJ_SYM, AMULET_SYM, FOOD_SYM, WEAPON_SYM, TOOL_SYM, 1260. * BALL_SYM, CHAIN_SYM, ROCK_SYM, ARMOR_SYM, POTION_SYM, SCROLL_SYM, 1261. * WAND_SYM, [SPBOOK_SYM], RING_SYM, GEM_SYM, 0 }; 1262. */ 1263. 1264. static const char *names[] = { 1265. "Illegal objects", "Amulets", "Comestibles", "Weapons", 1266. "Tools", "Iron balls", "Chains", "Boulders/Statues", "Armor", 1267. "Potions", "Scrolls", "Wands", 1268. #ifdef SPELLS 1269. "Spellbooks", 1270. #endif 1271. "Rings", "Gems"}; 1272. 1273. char * 1274. let_to_name(let) 1275. char let; 1276. { 1277. char *pos = index(obj_symbols, let); 1278. /* arbitrary buffer size by Tom May (tom@uw-warp) */ 1279. static char *buf = NULL; 1280. 1281. if (buf == NULL) 1282. buf = (char *) alloc ((unsigned)(strlen(HI)+strlen(HE)+15+1)); 1283. 1284. if (pos == NULL) pos = obj_symbols; 1285. if (HI && HE) 1286. Sprintf(buf, "%s%s%s", HI, names[pos - obj_symbols], HE); 1287. else 1288. Sprintf(buf, "%s", names[pos - obj_symbols]); 1289. return (buf); 1290. } 1291. 1292. void 1293. reassign() 1294. { 1295. register int i; 1296. register struct obj *obj; 1297. 1298. for(obj = invent, i = 0; obj; obj = obj->nobj, i++) 1299. obj->invlet = (i < 26) ? ('a'+i) : ('A'+i-26); 1300. lastinvnr = i; 1301. }
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